diff options
Diffstat (limited to 'thirdparty')
826 files changed, 111739 insertions, 44956 deletions
diff --git a/thirdparty/README.md b/thirdparty/README.md index 383ee3197b..f883a3a6da 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -17,10 +17,22 @@ Files extracted from upstream source: - `license.txt` +## astcenc + +- Upstream: https://github.com/ARM-software/astc-encoder +- Version: 4.3.0 (ec83dda79fcefe07f69cdae7ed980d169bf2c4d4, 2023) +- License: Apache 2.0 + +Files extracted from upstream source: + +- `astcenc_*` and `astcenc.h` files from `Source` +- `LICENSE.txt` + + ## basis_universal - Upstream: https://github.com/BinomialLLC/basis_universal -- Version: git (1531cfaf9ed5232248a0a45736686a849ca3befc, 2022) +- Version: git (a91e94c8495d7f470d3df326a364d49324cfd4a3, 2022) - License: Apache 2.0 Files extracted from upstream source: @@ -44,14 +56,14 @@ Files extracted from upstream source: ## certs - Upstream: Mozilla, via https://github.com/bagder/ca-bundle -- Version: git (7f33e7eb8472dbcf31fdcf50cd216c89a282825d, 2022) +- Version: git (b2f7415648411b6fd7c298c6c92d6552f0165f60, 2022) - License: MPL 2.0 ## cvtt - Upstream: https://github.com/elasota/ConvectionKernels -- Version: git (dc2dbbe0ae2cf2be06ef56d1021e2222a56c7fe2, 2021) +- Version: git (350416daa4e98f1c17ffc273b134d0120a2ef230, 2022) - License: MIT Files extracted from upstream source: @@ -74,7 +86,7 @@ Files extracted from upstream source: ## embree - Upstream: https://github.com/embree/embree -- Version: 3.13.1 (12b99393438a4cc9e478e33459eed78bec6233fd, 2021) +- Version: 3.13.5 (698442324ccddd11725fb8875275dc1384f7fb40, 2022) - License: Apache 2.0 Files extracted from upstream: @@ -164,6 +176,7 @@ Files extracted from upstream source: - `src/` folder, minus the `dlg` and `tools` subfolders * These files can be removed: `.dat`, `.diff`, `.mk`, `.rc`, `README*` + * In `src/gzip/`, remove zlib files (everything but `ftgzip.c` and `ftzconf.h`) - `include/` folder, minus the `dlg` subfolder - `LICENSE.TXT` and `docs/FTL.TXT` @@ -173,6 +186,23 @@ comments. Apply the patches in the `patches/` folder when syncing on newer upstr commits. +## glad + +- Upstream: https://github.com/Dav1dde/glad +- Version: 2.0.2 (f237a2bfcec0d9b82b90ec9af4af265c40de7183, 2022) +- License: CC0 1.0 and Apache 2.0 + +Files extracted from upstream source: +- `LICENSE` + +Files generated from [upstream web instance](https://gen.glad.sh/): +- `KHR/khrplatform.h` +- `gl.c` +- `glad/gl.h` +- `glx.c` +- `glad/glx.h` + + ## glslang - Upstream: https://github.com/KhronosGroup/glslang @@ -200,8 +230,8 @@ Files extracted from upstream source: ## graphite - Upstream: https://github.com/silnrsi/graphite -- Version: 1.3.14 (80c52493ef42e6fe605a69dcddd2a691cd8a1380, 2021) -- License: MPL-2.0 +- Version: 1.3.14 (27572742003b93dc53dc02c01c237b72c6c25f54, 2022) +- License: MIT Files extracted from upstream source: @@ -213,7 +243,7 @@ Files extracted from upstream source: ## harfbuzz - Upstream: https://github.com/harfbuzz/harfbuzz -- Version: 5.3.1 (970321db7bddbe8c579b73751fc655a924ea3ce6, 2022) +- Version: 6.0.0 (afcae83a064843d71d47624bc162e121cc56c08b, 2022) - License: MIT Files extracted from upstream source: @@ -290,18 +320,15 @@ Files extracted from upstream source: ## libtheora - Upstream: https://www.theora.org -- Version: 1.1.1 (2010) +- Version: git (7180717276af1ebc7da15c83162d6c5d6203aabf, 2020) - License: BSD-3-Clause Files extracted from upstream source: -- all .c, .h in lib/ +- all .c, .h in lib/, except arm/ and c64x/ folders - all .h files in include/theora/ as theora/ - COPYING and LICENSE -Upstream patches included in the `patches` directory have been applied -on top of the 1.1.1 source (not included in any stable release yet). - ## libvorbis @@ -319,7 +346,7 @@ Files extracted from upstream source: ## libwebp - Upstream: https://chromium.googlesource.com/webm/libwebp/ -- Version: 1.2.4 (0d1f12546bd803099a60c070517a552483f3790e, 2022) +- Version: 1.3.0 (b557776962a3dcc985d83bd4ed94e1e2e50d0fa2, 2022) - License: BSD-3-Clause Files extracted from upstream source: @@ -331,7 +358,7 @@ Files extracted from upstream source: ## mbedtls - Upstream: https://github.com/Mbed-TLS/mbedtls -- Version: 2.18.1 (dd79db10014d85b26d11fe57218431f2e5ede6f2, 2022) +- Version: 2.18.2 (89f040a5c938985c5f30728baed21e49d0846a53, 2022) - License: Apache 2.0 File extracted from upstream release tarball: @@ -341,17 +368,15 @@ File extracted from upstream release tarball: - The `LICENSE` file. - Applied the patch in `patches/1453.diff` (upstream PR: https://github.com/ARMmbed/mbedtls/pull/1453). + Applied the patch in `patches/windows-arm64-hardclock.diff` - Added 2 files `godot_core_mbedtls_platform.c` and `godot_core_mbedtls_config.h` providing configuration for light bundling with core. -Some changes have been made in order to fix Windows on ARM build errors. -They are marked with `// -- GODOT start --` and `// -- GODOT end --` - ## meshoptimizer - Upstream: https://github.com/zeux/meshoptimizer -- Version: git (ea4558d1c0f217f1d67ed7fe0b07896ece88ae18, 2022) +- Version: git (4a287848fd664ae1c3fc8e5e008560534ceeb526, 2022) - License: MIT Files extracted from upstream repository: @@ -384,7 +409,7 @@ to solve some MSVC warnings. See the patches in the `patches` directory. ## miniupnpc - Upstream: https://github.com/miniupnp/miniupnp -- Version: 2.2.3 (2df8120326ed4246e049a7a6de707539604cd514, 2021) +- Version: 2.2.4 (7d1d8bc3868b08ad003bad235eee57562b95b76d, 2022) - License: BSD-3-Clause Files extracted from upstream source: @@ -402,12 +427,14 @@ that file when upgrading. ## minizip - Upstream: https://www.zlib.net -- Version: 1.2.12 (zlib contrib, 2022) +- Version: 1.2.13 (zlib contrib, 2022) - License: zlib Files extracted from the upstream source: -- contrib/minizip/{crypt.h,ioapi.{c,h},unzip.{c,h},zip.{c,h}} +- From `contrib/minizip`: + `{crypt.h,ioapi.{c,h},unzip.{c,h},zip.{c,h}}` + `MiniZip64_info.txt` Important: Some files have Godot-made changes for use in core/io. They are marked with `/* GODOT start */` and `/* GODOT end */` @@ -534,7 +561,7 @@ Patch files are provided in `oidn/patches/`. ## openxr - Upstream: https://github.com/KhronosGroup/OpenXR-SDK -- Version: 1.0.25 (c16a18c99740ea5dd251e3af117e0e5aea4ceaa9, 2022) +- Version: 1.0.26 (e2da9ce83a4388c9622da328bf48548471261290, 2022) - License: Apache 2.0 Files extracted from upstream source: @@ -577,7 +604,7 @@ in 10.40, it can be found in the `patches` folder. ## recastnavigation - Upstream: https://github.com/recastnavigation/recastnavigation -- Version: git (5a870d427e47abd4a8e4ce58a95582ec049434d5, 2022) +- Version: git (4fef0446609b23d6ac180ed822817571525528a1, 2022) - License: zlib Files extracted from upstream source: @@ -654,7 +681,7 @@ instead of `miniz.h` as an external dependency. ## thorvg - Upstream: https://github.com/Samsung/thorvg -- Version: 0.8.2 (496796f1e5e85bd5fbba36dae987edb1b3945592, 2022) +- Version: 0.8.3 (a0fcf51f80a75f63a066df085f60cdaf715188b6, 2022) - License: MIT Files extracted from upstream source: @@ -754,12 +781,13 @@ Files extracted from upstream source: ## zlib - Upstream: https://www.zlib.net -- Version: 1.2.12 (2022) +- Version: 1.2.13 (2022) - License: zlib Files extracted from upstream source: -- all .c and .h files +- All `*.c` and `*.h` files +- `LICENSE` ## zstd diff --git a/thirdparty/astcenc/LICENSE.txt b/thirdparty/astcenc/LICENSE.txt new file mode 100644 index 0000000000..b82735a310 --- /dev/null +++ b/thirdparty/astcenc/LICENSE.txt @@ -0,0 +1,175 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. diff --git a/thirdparty/astcenc/astcenc.h b/thirdparty/astcenc/astcenc.h new file mode 100644 index 0000000000..70ae783373 --- /dev/null +++ b/thirdparty/astcenc/astcenc.h @@ -0,0 +1,815 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2020-2023 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief The core astcenc codec library interface. + * + * This interface is the entry point to the core astcenc codec. It aims to be easy to use for + * non-experts, but also to allow experts to have fine control over the compressor heuristics if + * needed. The core codec only handles compression and decompression, transferring all inputs and + * outputs via memory buffers. To catch obvious input/output buffer sizing issues, which can cause + * security and stability problems, all transfer buffers are explicitly sized. + * + * While the aim is that we keep this interface mostly stable, it should be viewed as a mutable + * interface tied to a specific source version. We are not trying to maintain backwards + * compatibility across codec versions. + * + * The API state management is based around an explicit context object, which is the context for all + * allocated memory resources needed to compress and decompress a single image. A context can be + * used to sequentially compress multiple images using the same configuration, allowing setup + * overheads to be amortized over multiple images, which is particularly important when images are + * small. + * + * Multi-threading can be used two ways. + * + * * An application wishing to process multiple images in parallel can allocate multiple + * contexts and assign each context to a thread. + * * An application wishing to process a single image in using multiple threads can configure + * contexts for multi-threaded use, and invoke astcenc_compress/decompress() once per thread + * for faster processing. The caller is responsible for creating the worker threads, and + * synchronizing between images. + * + * Threading + * ========= + * + * In pseudo-code, the usage for manual user threading looks like this: + * + * // Configure the compressor run + * astcenc_config my_config; + * astcenc_config_init(..., &my_config); + * + * // Power users can tweak <my_config> settings here ... + * + * // Allocate working state given config and thread_count + * astcenc_context* my_context; + * astcenc_context_alloc(&my_config, thread_count, &my_context); + * + * // Compress each image using these config settings + * foreach image: + * // For each thread in the thread pool + * for i in range(0, thread_count): + * astcenc_compress_image(my_context, &my_input, my_output, i); + * + * astcenc_compress_reset(my_context); + * + * // Clean up + * astcenc_context_free(my_context); + * + * Images + * ====== + * + * The codec supports compressing single images, which can be either 2D images or volumetric 3D + * images. Calling code is responsible for any handling of aggregate types, such as mipmap chains, + * texture arrays, or sliced 3D textures. + * + * Images are passed in as an astcenc_image structure. Inputs can be either 8-bit unorm, 16-bit + * half-float, or 32-bit float, as indicated by the data_type field. + * + * Images can be any dimension; there is no requirement to be a multiple of the ASTC block size. + * + * Data is always passed in as 4 color components, and accessed as an array of 2D image slices. Data + * within an image slice is always tightly packed without padding. Addressing looks like this: + * + * data[z_coord][y_coord * x_dim * 4 + x_coord * 4 ] // Red + * data[z_coord][y_coord * x_dim * 4 + x_coord * 4 + 1] // Green + * data[z_coord][y_coord * x_dim * 4 + x_coord * 4 + 2] // Blue + * data[z_coord][y_coord * x_dim * 4 + x_coord * 4 + 3] // Alpha + * + * Common compressor usage + * ======================= + * + * One of the most important things for coding image quality is to align the input data component + * count with the ASTC color endpoint mode. This avoids wasting bits encoding components you don't + * actually need in the endpoint colors. + * + * | Input data | Encoding swizzle | Sampling swizzle | + * | ------------ | ---------------- | ---------------- | + * | 1 component | RRR1 | .[rgb] | + * | 2 components | RRRG | .[rgb]a | + * | 3 components | RGB1 | .rgb | + * | 4 components | RGBA | .rgba | + * + * The 1 and 2 component modes recommend sampling from "g" to recover the luminance value as this + * provide best compatibility with other texture formats where the green component may be stored at + * higher precision than the others, such as RGB565. For ASTC any of the RGB components can be used; + * the luminance endpoint component will be returned for all three. + * + * When using the normal map compression mode ASTC will store normals as a two component X+Y map. + * Input images must contain unit-length normalized and should be passed in using a two component + * swizzle. The astcenc command line tool defaults to an RRRG swizzle, but some developers prefer + * to use GGGR for compatability with BC5n which will work just as well. The Z component can be + * recovered programmatically in shader code, using knowledge that the vector is unit length and + * that Z must be positive for a tangent-space normal map. + * + * Decompress-only usage + * ===================== + * + * For some use cases it is useful to have a cut-down context and/or library which supports + * decompression but not compression. + * + * A context can be made decompress-only using the ASTCENC_FLG_DECOMPRESS_ONLY flag when the context + * is allocated. These contexts have lower dynamic memory footprint than a full context. + * + * The entire library can be made decompress-only by building the files with the define + * ASTCENC_DECOMPRESS_ONLY set. In this build the context will be smaller, and the library will + * exclude the functionality which is only needed for compression. This reduces the binary size by + * ~180KB. For these builds contexts must be created with the ASTCENC_FLG_DECOMPRESS_ONLY flag. + * + * Note that context structures returned by a library built as decompress-only are incompatible with + * a library built with compression included, and visa versa, as they have different sizes and + * memory layout. + * + * Self-decompress-only usage + * ========================== + * + * ASTC is a complex format with a large search space. The parts of this search space that are + * searched is determined by heuristics that are, in part, tied to the quality level used when + * creating the context. + * + * A normal context is capable of decompressing any ASTC texture, including those generated by other + * compressors with unknown heuristics. This is the most flexible implementation, but forces the + * data tables used by the codec to include entries that are not needed during compression. This + * can slow down context creation by a significant amount, especially for the faster compression + * modes where few data table entries are actually used. To optimize this use case the context can + * be created with the ASTCENC_FLG_SELF_DECOMPRESS_ONLY flag. This tells the compressor that it will + * only be asked to decompress images that it compressed itself, allowing the data tables to + * exclude entries that are not needed by the current compression configuration. This reduces the + * size of the context data tables in memory and improves context creation performance. Note that, + * as of the 3.6 release, this flag no longer affects compression performance. + * + * Using this flag while attempting to decompress an valid image which was created by another + * compressor, or even another astcenc compressor version or configuration, may result in blocks + * returning as solid magenta or NaN value error blocks. + */ + +#ifndef ASTCENC_INCLUDED +#define ASTCENC_INCLUDED + +#include <cstddef> +#include <cstdint> + +#if defined(ASTCENC_DYNAMIC_LIBRARY) + #if defined(_MSC_VER) + #define ASTCENC_PUBLIC extern "C" __declspec(dllexport) + #else + #define ASTCENC_PUBLIC extern "C" __attribute__ ((visibility ("default"))) + #endif +#else + #define ASTCENC_PUBLIC +#endif + +/* ============================================================================ + Data declarations +============================================================================ */ + +/** + * @brief An opaque structure; see astcenc_internal.h for definition. + */ +struct astcenc_context; + +/** + * @brief A codec API error code. + */ +enum astcenc_error { + /** @brief The call was successful. */ + ASTCENC_SUCCESS = 0, + /** @brief The call failed due to low memory, or undersized I/O buffers. */ + ASTCENC_ERR_OUT_OF_MEM, + /** @brief The call failed due to the build using fast math. */ + ASTCENC_ERR_BAD_CPU_FLOAT, + /** @brief The call failed due to the build using an unsupported ISA. */ + ASTCENC_ERR_BAD_CPU_ISA, + /** @brief The call failed due to an out-of-spec parameter. */ + ASTCENC_ERR_BAD_PARAM, + /** @brief The call failed due to an out-of-spec block size. */ + ASTCENC_ERR_BAD_BLOCK_SIZE, + /** @brief The call failed due to an out-of-spec color profile. */ + ASTCENC_ERR_BAD_PROFILE, + /** @brief The call failed due to an out-of-spec quality value. */ + ASTCENC_ERR_BAD_QUALITY, + /** @brief The call failed due to an out-of-spec component swizzle. */ + ASTCENC_ERR_BAD_SWIZZLE, + /** @brief The call failed due to an out-of-spec flag set. */ + ASTCENC_ERR_BAD_FLAGS, + /** @brief The call failed due to the context not supporting the operation. */ + ASTCENC_ERR_BAD_CONTEXT, + /** @brief The call failed due to unimplemented functionality. */ + ASTCENC_ERR_NOT_IMPLEMENTED, +#if defined(ASTCENC_DIAGNOSTICS) + /** @brief The call failed due to an issue with diagnostic tracing. */ + ASTCENC_ERR_DTRACE_FAILURE, +#endif +}; + +/** + * @brief A codec color profile. + */ +enum astcenc_profile { + /** @brief The LDR sRGB color profile. */ + ASTCENC_PRF_LDR_SRGB = 0, + /** @brief The LDR linear color profile. */ + ASTCENC_PRF_LDR, + /** @brief The HDR RGB with LDR alpha color profile. */ + ASTCENC_PRF_HDR_RGB_LDR_A, + /** @brief The HDR RGBA color profile. */ + ASTCENC_PRF_HDR +}; + +/** @brief The fastest, lowest quality, search preset. */ +static const float ASTCENC_PRE_FASTEST = 0.0f; + +/** @brief The fast search preset. */ +static const float ASTCENC_PRE_FAST = 10.0f; + +/** @brief The medium quality search preset. */ +static const float ASTCENC_PRE_MEDIUM = 60.0f; + +/** @brief The thorough quality search preset. */ +static const float ASTCENC_PRE_THOROUGH = 98.0f; + +/** @brief The thorough quality search preset. */ +static const float ASTCENC_PRE_VERYTHOROUGH = 99.0f; + +/** @brief The exhaustive, highest quality, search preset. */ +static const float ASTCENC_PRE_EXHAUSTIVE = 100.0f; + +/** + * @brief A codec component swizzle selector. + */ +enum astcenc_swz +{ + /** @brief Select the red component. */ + ASTCENC_SWZ_R = 0, + /** @brief Select the green component. */ + ASTCENC_SWZ_G = 1, + /** @brief Select the blue component. */ + ASTCENC_SWZ_B = 2, + /** @brief Select the alpha component. */ + ASTCENC_SWZ_A = 3, + /** @brief Use a constant zero component. */ + ASTCENC_SWZ_0 = 4, + /** @brief Use a constant one component. */ + ASTCENC_SWZ_1 = 5, + /** @brief Use a reconstructed normal vector Z component. */ + ASTCENC_SWZ_Z = 6 +}; + +/** + * @brief A texel component swizzle. + */ +struct astcenc_swizzle +{ + /** @brief The red component selector. */ + astcenc_swz r; + /** @brief The green component selector. */ + astcenc_swz g; + /** @brief The blue component selector. */ + astcenc_swz b; + /** @brief The alpha component selector. */ + astcenc_swz a; +}; + +/** + * @brief A texel component data format. + */ +enum astcenc_type +{ + /** @brief Unorm 8-bit data per component. */ + ASTCENC_TYPE_U8 = 0, + /** @brief 16-bit float per component. */ + ASTCENC_TYPE_F16 = 1, + /** @brief 32-bit float per component. */ + ASTCENC_TYPE_F32 = 2 +}; + +/** + * @brief Enable normal map compression. + * + * Input data will be treated a two component normal map, storing X and Y, and the codec will + * optimize for angular error rather than simple linear PSNR. In this mode the input swizzle should + * be e.g. rrrg (the default ordering for ASTC normals on the command line) or gggr (the ordering + * used by BC5n). + */ +static const unsigned int ASTCENC_FLG_MAP_NORMAL = 1 << 0; + +/** + * @brief Enable alpha weighting. + * + * The input alpha value is used for transparency, so errors in the RGB components are weighted by + * the transparency level. This allows the codec to more accurately encode the alpha value in areas + * where the color value is less significant. + */ +static const unsigned int ASTCENC_FLG_USE_ALPHA_WEIGHT = 1 << 2; + +/** + * @brief Enable perceptual error metrics. + * + * This mode enables perceptual compression mode, which will optimize for perceptual error rather + * than best PSNR. Only some input modes support perceptual error metrics. + */ +static const unsigned int ASTCENC_FLG_USE_PERCEPTUAL = 1 << 3; + +/** + * @brief Create a decompression-only context. + * + * This mode disables support for compression. This enables context allocation to skip some + * transient buffer allocation, resulting in lower memory usage. + */ +static const unsigned int ASTCENC_FLG_DECOMPRESS_ONLY = 1 << 4; + +/** + * @brief Create a self-decompression context. + * + * This mode configures the compressor so that it is only guaranteed to be able to decompress images + * that were actually created using the current context. This is the common case for compression use + * cases, and setting this flag enables additional optimizations, but does mean that the context + * cannot reliably decompress arbitrary ASTC images. + */ +static const unsigned int ASTCENC_FLG_SELF_DECOMPRESS_ONLY = 1 << 5; + +/** + * @brief Enable RGBM map compression. + * + * Input data will be treated as HDR data that has been stored in an LDR RGBM-encoded wrapper + * format. Data must be preprocessed by the user to be in LDR RGBM format before calling the + * compression function, this flag is only used to control the use of RGBM-specific heuristics and + * error metrics. + * + * IMPORTANT: The ASTC format is prone to bad failure modes with unconstrained RGBM data; very small + * M values can round to zero due to quantization and result in black or white pixels. It is highly + * recommended that the minimum value of M used in the encoding is kept above a lower threshold (try + * 16 or 32). Applying this threshold reduces the number of very dark colors that can be + * represented, but is still higher precision than 8-bit LDR. + * + * When this flag is set the value of @c rgbm_m_scale in the context must be set to the RGBM scale + * factor used during reconstruction. This defaults to 5 when in RGBM mode. + * + * It is recommended that the value of @c cw_a_weight is set to twice the value of the multiplier + * scale, ensuring that the M value is accurately encoded. This defaults to 10 when in RGBM mode, + * matching the default scale factor. + */ +static const unsigned int ASTCENC_FLG_MAP_RGBM = 1 << 6; + +/** + * @brief The bit mask of all valid flags. + */ +static const unsigned int ASTCENC_ALL_FLAGS = + ASTCENC_FLG_MAP_NORMAL | + ASTCENC_FLG_MAP_RGBM | + ASTCENC_FLG_USE_ALPHA_WEIGHT | + ASTCENC_FLG_USE_PERCEPTUAL | + ASTCENC_FLG_DECOMPRESS_ONLY | + ASTCENC_FLG_SELF_DECOMPRESS_ONLY; + +/** + * @brief The config structure. + * + * This structure will initially be populated by a call to astcenc_config_init, but power users may + * modify it before calling astcenc_context_alloc. See astcenccli_toplevel_help.cpp for full user + * documentation of the power-user settings. + * + * Note for any settings which are associated with a specific color component, the value in the + * config applies to the component that exists after any compression data swizzle is applied. + */ +struct astcenc_config +{ + /** @brief The color profile. */ + astcenc_profile profile; + + /** @brief The set of set flags. */ + unsigned int flags; + + /** @brief The ASTC block size X dimension. */ + unsigned int block_x; + + /** @brief The ASTC block size Y dimension. */ + unsigned int block_y; + + /** @brief The ASTC block size Z dimension. */ + unsigned int block_z; + + /** @brief The red component weight scale for error weighting (-cw). */ + float cw_r_weight; + + /** @brief The green component weight scale for error weighting (-cw). */ + float cw_g_weight; + + /** @brief The blue component weight scale for error weighting (-cw). */ + float cw_b_weight; + + /** @brief The alpha component weight scale for error weighting (-cw). */ + float cw_a_weight; + + /** + * @brief The radius for any alpha-weight scaling (-a). + * + * It is recommended that this is set to 1 when using FLG_USE_ALPHA_WEIGHT on a texture that + * will be sampled using linear texture filtering to minimize color bleed out of transparent + * texels that are adjacent to non-transparent texels. + */ + unsigned int a_scale_radius; + + /** @brief The RGBM scale factor for the shared multiplier (-rgbm). */ + float rgbm_m_scale; + + /** + * @brief The maximum number of partitions searched (-partitioncountlimit). + * + * Valid values are between 1 and 4. + */ + unsigned int tune_partition_count_limit; + + /** + * @brief The maximum number of partitions searched (-2partitionindexlimit). + * + * Valid values are between 1 and 1024. + */ + unsigned int tune_2partition_index_limit; + + /** + * @brief The maximum number of partitions searched (-3partitionindexlimit). + * + * Valid values are between 1 and 1024. + */ + unsigned int tune_3partition_index_limit; + + /** + * @brief The maximum number of partitions searched (-4partitionindexlimit). + * + * Valid values are between 1 and 1024. + */ + unsigned int tune_4partition_index_limit; + + /** + * @brief The maximum centile for block modes searched (-blockmodelimit). + * + * Valid values are between 1 and 100. + */ + unsigned int tune_block_mode_limit; + + /** + * @brief The maximum iterative refinements applied (-refinementlimit). + * + * Valid values are between 1 and N; there is no technical upper limit + * but little benefit is expected after N=4. + */ + unsigned int tune_refinement_limit; + + /** + * @brief The number of trial candidates per mode search (-candidatelimit). + * + * Valid values are between 1 and TUNE_MAX_TRIAL_CANDIDATES (default 4). + */ + unsigned int tune_candidate_limit; + + /** + * @brief The number of trial partitionings per search (-2partitioncandidatelimit). + * + * Valid values are between 1 and TUNE_MAX_PARTITIONING_CANDIDATES. + */ + unsigned int tune_2partitioning_candidate_limit; + + /** + * @brief The number of trial partitionings per search (-3partitioncandidatelimit). + * + * Valid values are between 1 and TUNE_MAX_PARTITIONING_CANDIDATES. + */ + unsigned int tune_3partitioning_candidate_limit; + + /** + * @brief The number of trial partitionings per search (-4partitioncandidatelimit). + * + * Valid values are between 1 and TUNE_MAX_PARTITIONING_CANDIDATES. + */ + unsigned int tune_4partitioning_candidate_limit; + + /** + * @brief The dB threshold for stopping block search (-dblimit). + * + * This option is ineffective for HDR textures. + */ + float tune_db_limit; + + /** + * @brief The amount of MSE overshoot needed to early-out trials. + * + * The first early-out is for 1 partition, 1 plane trials, where we try a minimal encode using + * the high probability block modes. This can short-cut compression for simple blocks. + * + * The second early-out is for refinement trials, where we can exit refinement once quality is + * reached. + */ + float tune_mse_overshoot; + + /** + * @brief The threshold for skipping 3.1/4.1 trials (-2partitionlimitfactor). + * + * This option is further scaled for normal maps, so it skips less often. + */ + float tune_2_partition_early_out_limit_factor; + + /** + * @brief The threshold for skipping 4.1 trials (-3partitionlimitfactor). + * + * This option is further scaled for normal maps, so it skips less often. + */ + float tune_3_partition_early_out_limit_factor; + + /** + * @brief The threshold for skipping two weight planes (-2planelimitcorrelation). + * + * This option is ineffective for normal maps. + */ + float tune_2_plane_early_out_limit_correlation; + +#if defined(ASTCENC_DIAGNOSTICS) + /** + * @brief The path to save the diagnostic trace data to. + * + * This option is not part of the public API, and requires special builds + * of the library. + */ + const char* trace_file_path; +#endif +}; + +/** + * @brief An uncompressed 2D or 3D image. + * + * 3D image are passed in as an array of 2D slices. Each slice has identical + * size and color format. + */ +struct astcenc_image +{ + /** @brief The X dimension of the image, in texels. */ + unsigned int dim_x; + + /** @brief The Y dimension of the image, in texels. */ + unsigned int dim_y; + + /** @brief The Z dimension of the image, in texels. */ + unsigned int dim_z; + + /** @brief The data type per component. */ + astcenc_type data_type; + + /** @brief The array of 2D slices, of length @c dim_z. */ + void** data; +}; + +/** + * @brief A block encoding metadata query result. + * + * If the block is an error block or a constant color block or an error block all fields other than + * the profile, block dimensions, and error/constant indicator will be zero. + */ +struct astcenc_block_info +{ + /** @brief The block encoding color profile. */ + astcenc_profile profile; + + /** @brief The number of texels in the X dimension. */ + unsigned int block_x; + + /** @brief The number of texels in the Y dimension. */ + unsigned int block_y; + + /** @brief The number of texel in the Z dimension. */ + unsigned int block_z; + + /** @brief The number of texels in the block. */ + unsigned int texel_count; + + /** @brief True if this block is an error block. */ + bool is_error_block; + + /** @brief True if this block is a constant color block. */ + bool is_constant_block; + + /** @brief True if this block is an HDR block. */ + bool is_hdr_block; + + /** @brief True if this block uses two weight planes. */ + bool is_dual_plane_block; + + /** @brief The number of partitions if not constant color. */ + unsigned int partition_count; + + /** @brief The partition index if 2 - 4 partitions used. */ + unsigned int partition_index; + + /** @brief The component index of the second plane if dual plane. */ + unsigned int dual_plane_component; + + /** @brief The color endpoint encoding mode for each partition. */ + unsigned int color_endpoint_modes[4]; + + /** @brief The number of color endpoint quantization levels. */ + unsigned int color_level_count; + + /** @brief The number of weight quantization levels. */ + unsigned int weight_level_count; + + /** @brief The number of weights in the X dimension. */ + unsigned int weight_x; + + /** @brief The number of weights in the Y dimension. */ + unsigned int weight_y; + + /** @brief The number of weights in the Z dimension. */ + unsigned int weight_z; + + /** @brief The unpacked color endpoints for each partition. */ + float color_endpoints[4][2][4]; + + /** @brief The per-texel interpolation weights for the block. */ + float weight_values_plane1[216]; + + /** @brief The per-texel interpolation weights for the block. */ + float weight_values_plane2[216]; + + /** @brief The per-texel partition assignments for the block. */ + uint8_t partition_assignment[216]; +}; + +/** + * Populate a codec config based on default settings. + * + * Power users can edit the returned config struct to fine tune before allocating the context. + * + * @param profile Color profile. + * @param block_x ASTC block size X dimension. + * @param block_y ASTC block size Y dimension. + * @param block_z ASTC block size Z dimension. + * @param quality Search quality preset / effort level. Either an + * @c ASTCENC_PRE_* value, or a effort level between 0 + * and 100. Performance is not linear between 0 and 100. + + * @param flags A valid set of @c ASTCENC_FLG_* flag bits. + * @param[out] config Output config struct to populate. + * + * @return @c ASTCENC_SUCCESS on success, or an error if the inputs are invalid + * either individually, or in combination. + */ +ASTCENC_PUBLIC astcenc_error astcenc_config_init( + astcenc_profile profile, + unsigned int block_x, + unsigned int block_y, + unsigned int block_z, + float quality, + unsigned int flags, + astcenc_config* config); + +/** + * @brief Allocate a new codec context based on a config. + * + * This function allocates all of the memory resources and threads needed by the codec. This can be + * slow, so it is recommended that contexts are reused to serially compress or decompress multiple + * images to amortize setup cost. + * + * Contexts can be allocated to support only decompression using the @c ASTCENC_FLG_DECOMPRESS_ONLY + * flag when creating the configuration. The compression functions will fail if invoked. For a + * decompress-only library build the @c ASTCENC_FLG_DECOMPRESS_ONLY flag must be set when creating + * any context. + * + * @param[in] config Codec config. + * @param thread_count Thread count to configure for. + * @param[out] context Location to store an opaque context pointer. + * + * @return @c ASTCENC_SUCCESS on success, or an error if context creation failed. + */ +ASTCENC_PUBLIC astcenc_error astcenc_context_alloc( + const astcenc_config* config, + unsigned int thread_count, + astcenc_context** context); + +/** + * @brief Compress an image. + * + * A single context can only compress or decompress a single image at a time. + * + * For a context configured for multi-threading, any set of the N threads can call this function. + * Work will be dynamically scheduled across the threads available. Each thread must have a unique + * @c thread_index. + * + * @param context Codec context. + * @param[in,out] image An input image, in 2D slices. + * @param swizzle Compression data swizzle, applied before compression. + * @param[out] data_out Pointer to output data array. + * @param data_len Length of the output data array. + * @param thread_index Thread index [0..N-1] of calling thread. + * + * @return @c ASTCENC_SUCCESS on success, or an error if compression failed. + */ +ASTCENC_PUBLIC astcenc_error astcenc_compress_image( + astcenc_context* context, + astcenc_image* image, + const astcenc_swizzle* swizzle, + uint8_t* data_out, + size_t data_len, + unsigned int thread_index); + +/** + * @brief Reset the codec state for a new compression. + * + * The caller is responsible for synchronizing threads in the worker thread pool. This function must + * only be called when all threads have exited the @c astcenc_compress_image() function for image N, + * but before any thread enters it for image N + 1. + * + * Calling this is not required (but won't hurt), if the context is created for single threaded use. + * + * @param context Codec context. + * + * @return @c ASTCENC_SUCCESS on success, or an error if reset failed. + */ +ASTCENC_PUBLIC astcenc_error astcenc_compress_reset( + astcenc_context* context); + +/** + * @brief Decompress an image. + * + * @param context Codec context. + * @param[in] data Pointer to compressed data. + * @param data_len Length of the compressed data, in bytes. + * @param[in,out] image_out Output image. + * @param swizzle Decompression data swizzle, applied after decompression. + * @param thread_index Thread index [0..N-1] of calling thread. + * + * @return @c ASTCENC_SUCCESS on success, or an error if decompression failed. + */ +ASTCENC_PUBLIC astcenc_error astcenc_decompress_image( + astcenc_context* context, + const uint8_t* data, + size_t data_len, + astcenc_image* image_out, + const astcenc_swizzle* swizzle, + unsigned int thread_index); + +/** + * @brief Reset the codec state for a new decompression. + * + * The caller is responsible for synchronizing threads in the worker thread pool. This function must + * only be called when all threads have exited the @c astcenc_decompress_image() function for image + * N, but before any thread enters it for image N + 1. + * + * Calling this is not required (but won't hurt), if the context is created for single threaded use. + * + * @param context Codec context. + * + * @return @c ASTCENC_SUCCESS on success, or an error if reset failed. + */ +ASTCENC_PUBLIC astcenc_error astcenc_decompress_reset( + astcenc_context* context); + +/** + * Free the compressor context. + * + * @param context The codec context. + */ +ASTCENC_PUBLIC void astcenc_context_free( + astcenc_context* context); + +/** + * @brief Provide a high level summary of a block's encoding. + * + * This feature is primarily useful for codec developers but may be useful for developers building + * advanced content packaging pipelines. + * + * @param context Codec context. + * @param data One block of compressed ASTC data. + * @param info The output info structure to populate. + * + * @return @c ASTCENC_SUCCESS if the block was decoded, or an error otherwise. Note that this + * function will return success even if the block itself was an error block encoding, as the + * decode was correctly handled. + */ +ASTCENC_PUBLIC astcenc_error astcenc_get_block_info( + astcenc_context* context, + const uint8_t data[16], + astcenc_block_info* info); + +/** + * @brief Get a printable string for specific status code. + * + * @param status The status value. + * + * @return A human readable nul-terminated string. + */ +ASTCENC_PUBLIC const char* astcenc_get_error_string( + astcenc_error status); + +#endif diff --git a/thirdparty/astcenc/astcenc_averages_and_directions.cpp b/thirdparty/astcenc/astcenc_averages_and_directions.cpp new file mode 100644 index 0000000000..d1f003844a --- /dev/null +++ b/thirdparty/astcenc/astcenc_averages_and_directions.cpp @@ -0,0 +1,995 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2022 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief Functions for finding dominant direction of a set of colors. + */ +#if !defined(ASTCENC_DECOMPRESS_ONLY) + +#include "astcenc_internal.h" + +#include <cassert> + +/** + * @brief Compute the average RGB color of each partition. + * + * The algorithm here uses a vectorized sequential scan and per-partition + * color accumulators, using select() to mask texel lanes in other partitions. + * + * We only accumulate sums for N-1 partitions during the scan; the value for + * the last partition can be computed given that we know the block-wide average + * already. + * + * Because of this we could reduce the loop iteration count so it "just" spans + * the max texel index needed for the N-1 partitions, which could need fewer + * iterations than the full block texel count. However, this makes the loop + * count erratic and causes more branch mispredictions so is a net loss. + * + * @param pi The partitioning to use. + * @param blk The block data to process. + * @param[out] averages The output averages. Unused partition indices will + * not be initialized, and lane<3> will be zero. + */ +static void compute_partition_averages_rgb( + const partition_info& pi, + const image_block& blk, + vfloat4 averages[BLOCK_MAX_PARTITIONS] +) { + unsigned int partition_count = pi.partition_count; + unsigned int texel_count = blk.texel_count; + promise(texel_count > 0); + + // For 1 partition just use the precomputed mean + if (partition_count == 1) + { + averages[0] = blk.data_mean.swz<0, 1, 2>(); + } + // For 2 partitions scan results for partition 0, compute partition 1 + else if (partition_count == 2) + { + vfloatacc pp_avg_rgb[3] {}; + + vint lane_id = vint::lane_id(); + for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) + { + vint texel_partition(pi.partition_of_texel + i); + + vmask lane_mask = lane_id < vint(texel_count); + lane_id += vint(ASTCENC_SIMD_WIDTH); + + vmask p0_mask = lane_mask & (texel_partition == vint(0)); + + vfloat data_r = loada(blk.data_r + i); + haccumulate(pp_avg_rgb[0], data_r, p0_mask); + + vfloat data_g = loada(blk.data_g + i); + haccumulate(pp_avg_rgb[1], data_g, p0_mask); + + vfloat data_b = loada(blk.data_b + i); + haccumulate(pp_avg_rgb[2], data_b, p0_mask); + } + + vfloat4 block_total = blk.data_mean.swz<0, 1, 2>() * static_cast<float>(blk.texel_count); + + vfloat4 p0_total = vfloat3(hadd_s(pp_avg_rgb[0]), + hadd_s(pp_avg_rgb[1]), + hadd_s(pp_avg_rgb[2])); + + vfloat4 p1_total = block_total - p0_total; + + averages[0] = p0_total / static_cast<float>(pi.partition_texel_count[0]); + averages[1] = p1_total / static_cast<float>(pi.partition_texel_count[1]); + } + // For 3 partitions scan results for partition 0/1, compute partition 2 + else if (partition_count == 3) + { + vfloatacc pp_avg_rgb[2][3] {}; + + vint lane_id = vint::lane_id(); + for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) + { + vint texel_partition(pi.partition_of_texel + i); + + vmask lane_mask = lane_id < vint(texel_count); + lane_id += vint(ASTCENC_SIMD_WIDTH); + + vmask p0_mask = lane_mask & (texel_partition == vint(0)); + vmask p1_mask = lane_mask & (texel_partition == vint(1)); + + vfloat data_r = loada(blk.data_r + i); + haccumulate(pp_avg_rgb[0][0], data_r, p0_mask); + haccumulate(pp_avg_rgb[1][0], data_r, p1_mask); + + vfloat data_g = loada(blk.data_g + i); + haccumulate(pp_avg_rgb[0][1], data_g, p0_mask); + haccumulate(pp_avg_rgb[1][1], data_g, p1_mask); + + vfloat data_b = loada(blk.data_b + i); + haccumulate(pp_avg_rgb[0][2], data_b, p0_mask); + haccumulate(pp_avg_rgb[1][2], data_b, p1_mask); + } + + vfloat4 block_total = blk.data_mean.swz<0, 1, 2>() * static_cast<float>(blk.texel_count); + + vfloat4 p0_total = vfloat3(hadd_s(pp_avg_rgb[0][0]), + hadd_s(pp_avg_rgb[0][1]), + hadd_s(pp_avg_rgb[0][2])); + + vfloat4 p1_total = vfloat3(hadd_s(pp_avg_rgb[1][0]), + hadd_s(pp_avg_rgb[1][1]), + hadd_s(pp_avg_rgb[1][2])); + + vfloat4 p2_total = block_total - p0_total - p1_total; + + averages[0] = p0_total / static_cast<float>(pi.partition_texel_count[0]); + averages[1] = p1_total / static_cast<float>(pi.partition_texel_count[1]); + averages[2] = p2_total / static_cast<float>(pi.partition_texel_count[2]); + } + else + { + // For 4 partitions scan results for partition 0/1/2, compute partition 3 + vfloatacc pp_avg_rgb[3][3] {}; + + vint lane_id = vint::lane_id(); + for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) + { + vint texel_partition(pi.partition_of_texel + i); + + vmask lane_mask = lane_id < vint(texel_count); + lane_id += vint(ASTCENC_SIMD_WIDTH); + + vmask p0_mask = lane_mask & (texel_partition == vint(0)); + vmask p1_mask = lane_mask & (texel_partition == vint(1)); + vmask p2_mask = lane_mask & (texel_partition == vint(2)); + + vfloat data_r = loada(blk.data_r + i); + haccumulate(pp_avg_rgb[0][0], data_r, p0_mask); + haccumulate(pp_avg_rgb[1][0], data_r, p1_mask); + haccumulate(pp_avg_rgb[2][0], data_r, p2_mask); + + vfloat data_g = loada(blk.data_g + i); + haccumulate(pp_avg_rgb[0][1], data_g, p0_mask); + haccumulate(pp_avg_rgb[1][1], data_g, p1_mask); + haccumulate(pp_avg_rgb[2][1], data_g, p2_mask); + + vfloat data_b = loada(blk.data_b + i); + haccumulate(pp_avg_rgb[0][2], data_b, p0_mask); + haccumulate(pp_avg_rgb[1][2], data_b, p1_mask); + haccumulate(pp_avg_rgb[2][2], data_b, p2_mask); + } + + vfloat4 block_total = blk.data_mean.swz<0, 1, 2>() * static_cast<float>(blk.texel_count); + + vfloat4 p0_total = vfloat3(hadd_s(pp_avg_rgb[0][0]), + hadd_s(pp_avg_rgb[0][1]), + hadd_s(pp_avg_rgb[0][2])); + + vfloat4 p1_total = vfloat3(hadd_s(pp_avg_rgb[1][0]), + hadd_s(pp_avg_rgb[1][1]), + hadd_s(pp_avg_rgb[1][2])); + + vfloat4 p2_total = vfloat3(hadd_s(pp_avg_rgb[2][0]), + hadd_s(pp_avg_rgb[2][1]), + hadd_s(pp_avg_rgb[2][2])); + + vfloat4 p3_total = block_total - p0_total - p1_total- p2_total; + + averages[0] = p0_total / static_cast<float>(pi.partition_texel_count[0]); + averages[1] = p1_total / static_cast<float>(pi.partition_texel_count[1]); + averages[2] = p2_total / static_cast<float>(pi.partition_texel_count[2]); + averages[3] = p3_total / static_cast<float>(pi.partition_texel_count[3]); + } +} + +/** + * @brief Compute the average RGBA color of each partition. + * + * The algorithm here uses a vectorized sequential scan and per-partition + * color accumulators, using select() to mask texel lanes in other partitions. + * + * We only accumulate sums for N-1 partitions during the scan; the value for + * the last partition can be computed given that we know the block-wide average + * already. + * + * Because of this we could reduce the loop iteration count so it "just" spans + * the max texel index needed for the N-1 partitions, which could need fewer + * iterations than the full block texel count. However, this makes the loop + * count erratic and causes more branch mispredictions so is a net loss. + * + * @param pi The partitioning to use. + * @param blk The block data to process. + * @param[out] averages The output averages. Unused partition indices will + * not be initialized. + */ +static void compute_partition_averages_rgba( + const partition_info& pi, + const image_block& blk, + vfloat4 averages[BLOCK_MAX_PARTITIONS] +) { + unsigned int partition_count = pi.partition_count; + unsigned int texel_count = blk.texel_count; + promise(texel_count > 0); + + // For 1 partition just use the precomputed mean + if (partition_count == 1) + { + averages[0] = blk.data_mean; + } + // For 2 partitions scan results for partition 0, compute partition 1 + else if (partition_count == 2) + { + vfloat4 pp_avg_rgba[4] {}; + + vint lane_id = vint::lane_id(); + for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) + { + vint texel_partition(pi.partition_of_texel + i); + + vmask lane_mask = lane_id < vint(texel_count); + lane_id += vint(ASTCENC_SIMD_WIDTH); + + vmask p0_mask = lane_mask & (texel_partition == vint(0)); + + vfloat data_r = loada(blk.data_r + i); + haccumulate(pp_avg_rgba[0], data_r, p0_mask); + + vfloat data_g = loada(blk.data_g + i); + haccumulate(pp_avg_rgba[1], data_g, p0_mask); + + vfloat data_b = loada(blk.data_b + i); + haccumulate(pp_avg_rgba[2], data_b, p0_mask); + + vfloat data_a = loada(blk.data_a + i); + haccumulate(pp_avg_rgba[3], data_a, p0_mask); + } + + vfloat4 block_total = blk.data_mean * static_cast<float>(blk.texel_count); + + vfloat4 p0_total = vfloat4(hadd_s(pp_avg_rgba[0]), + hadd_s(pp_avg_rgba[1]), + hadd_s(pp_avg_rgba[2]), + hadd_s(pp_avg_rgba[3])); + + vfloat4 p1_total = block_total - p0_total; + + averages[0] = p0_total / static_cast<float>(pi.partition_texel_count[0]); + averages[1] = p1_total / static_cast<float>(pi.partition_texel_count[1]); + } + // For 3 partitions scan results for partition 0/1, compute partition 2 + else if (partition_count == 3) + { + vfloat4 pp_avg_rgba[2][4] {}; + + vint lane_id = vint::lane_id(); + for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) + { + vint texel_partition(pi.partition_of_texel + i); + + vmask lane_mask = lane_id < vint(texel_count); + lane_id += vint(ASTCENC_SIMD_WIDTH); + + vmask p0_mask = lane_mask & (texel_partition == vint(0)); + vmask p1_mask = lane_mask & (texel_partition == vint(1)); + + vfloat data_r = loada(blk.data_r + i); + haccumulate(pp_avg_rgba[0][0], data_r, p0_mask); + haccumulate(pp_avg_rgba[1][0], data_r, p1_mask); + + vfloat data_g = loada(blk.data_g + i); + haccumulate(pp_avg_rgba[0][1], data_g, p0_mask); + haccumulate(pp_avg_rgba[1][1], data_g, p1_mask); + + vfloat data_b = loada(blk.data_b + i); + haccumulate(pp_avg_rgba[0][2], data_b, p0_mask); + haccumulate(pp_avg_rgba[1][2], data_b, p1_mask); + + vfloat data_a = loada(blk.data_a + i); + haccumulate(pp_avg_rgba[0][3], data_a, p0_mask); + haccumulate(pp_avg_rgba[1][3], data_a, p1_mask); + } + + vfloat4 block_total = blk.data_mean * static_cast<float>(blk.texel_count); + + vfloat4 p0_total = vfloat4(hadd_s(pp_avg_rgba[0][0]), + hadd_s(pp_avg_rgba[0][1]), + hadd_s(pp_avg_rgba[0][2]), + hadd_s(pp_avg_rgba[0][3])); + + vfloat4 p1_total = vfloat4(hadd_s(pp_avg_rgba[1][0]), + hadd_s(pp_avg_rgba[1][1]), + hadd_s(pp_avg_rgba[1][2]), + hadd_s(pp_avg_rgba[1][3])); + + vfloat4 p2_total = block_total - p0_total - p1_total; + + averages[0] = p0_total / static_cast<float>(pi.partition_texel_count[0]); + averages[1] = p1_total / static_cast<float>(pi.partition_texel_count[1]); + averages[2] = p2_total / static_cast<float>(pi.partition_texel_count[2]); + } + else + { + // For 4 partitions scan results for partition 0/1/2, compute partition 3 + vfloat4 pp_avg_rgba[3][4] {}; + + vint lane_id = vint::lane_id(); + for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) + { + vint texel_partition(pi.partition_of_texel + i); + + vmask lane_mask = lane_id < vint(texel_count); + lane_id += vint(ASTCENC_SIMD_WIDTH); + + vmask p0_mask = lane_mask & (texel_partition == vint(0)); + vmask p1_mask = lane_mask & (texel_partition == vint(1)); + vmask p2_mask = lane_mask & (texel_partition == vint(2)); + + vfloat data_r = loada(blk.data_r + i); + haccumulate(pp_avg_rgba[0][0], data_r, p0_mask); + haccumulate(pp_avg_rgba[1][0], data_r, p1_mask); + haccumulate(pp_avg_rgba[2][0], data_r, p2_mask); + + vfloat data_g = loada(blk.data_g + i); + haccumulate(pp_avg_rgba[0][1], data_g, p0_mask); + haccumulate(pp_avg_rgba[1][1], data_g, p1_mask); + haccumulate(pp_avg_rgba[2][1], data_g, p2_mask); + + vfloat data_b = loada(blk.data_b + i); + haccumulate(pp_avg_rgba[0][2], data_b, p0_mask); + haccumulate(pp_avg_rgba[1][2], data_b, p1_mask); + haccumulate(pp_avg_rgba[2][2], data_b, p2_mask); + + vfloat data_a = loada(blk.data_a + i); + haccumulate(pp_avg_rgba[0][3], data_a, p0_mask); + haccumulate(pp_avg_rgba[1][3], data_a, p1_mask); + haccumulate(pp_avg_rgba[2][3], data_a, p2_mask); + } + + vfloat4 block_total = blk.data_mean * static_cast<float>(blk.texel_count); + + vfloat4 p0_total = vfloat4(hadd_s(pp_avg_rgba[0][0]), + hadd_s(pp_avg_rgba[0][1]), + hadd_s(pp_avg_rgba[0][2]), + hadd_s(pp_avg_rgba[0][3])); + + vfloat4 p1_total = vfloat4(hadd_s(pp_avg_rgba[1][0]), + hadd_s(pp_avg_rgba[1][1]), + hadd_s(pp_avg_rgba[1][2]), + hadd_s(pp_avg_rgba[1][3])); + + vfloat4 p2_total = vfloat4(hadd_s(pp_avg_rgba[2][0]), + hadd_s(pp_avg_rgba[2][1]), + hadd_s(pp_avg_rgba[2][2]), + hadd_s(pp_avg_rgba[2][3])); + + vfloat4 p3_total = block_total - p0_total - p1_total- p2_total; + + averages[0] = p0_total / static_cast<float>(pi.partition_texel_count[0]); + averages[1] = p1_total / static_cast<float>(pi.partition_texel_count[1]); + averages[2] = p2_total / static_cast<float>(pi.partition_texel_count[2]); + averages[3] = p3_total / static_cast<float>(pi.partition_texel_count[3]); + } +} + +/* See header for documentation. */ +void compute_avgs_and_dirs_4_comp( + const partition_info& pi, + const image_block& blk, + partition_metrics pm[BLOCK_MAX_PARTITIONS] +) { + int partition_count = pi.partition_count; + promise(partition_count > 0); + + // Pre-compute partition_averages + vfloat4 partition_averages[BLOCK_MAX_PARTITIONS]; + compute_partition_averages_rgba(pi, blk, partition_averages); + + for (int partition = 0; partition < partition_count; partition++) + { + const uint8_t *texel_indexes = pi.texels_of_partition[partition]; + unsigned int texel_count = pi.partition_texel_count[partition]; + promise(texel_count > 0); + + vfloat4 average = partition_averages[partition]; + pm[partition].avg = average; + + vfloat4 sum_xp = vfloat4::zero(); + vfloat4 sum_yp = vfloat4::zero(); + vfloat4 sum_zp = vfloat4::zero(); + vfloat4 sum_wp = vfloat4::zero(); + + for (unsigned int i = 0; i < texel_count; i++) + { + unsigned int iwt = texel_indexes[i]; + vfloat4 texel_datum = blk.texel(iwt); + texel_datum = texel_datum - average; + + vfloat4 zero = vfloat4::zero(); + + vmask4 tdm0 = texel_datum.swz<0,0,0,0>() > zero; + sum_xp += select(zero, texel_datum, tdm0); + + vmask4 tdm1 = texel_datum.swz<1,1,1,1>() > zero; + sum_yp += select(zero, texel_datum, tdm1); + + vmask4 tdm2 = texel_datum.swz<2,2,2,2>() > zero; + sum_zp += select(zero, texel_datum, tdm2); + + vmask4 tdm3 = texel_datum.swz<3,3,3,3>() > zero; + sum_wp += select(zero, texel_datum, tdm3); + } + + vfloat4 prod_xp = dot(sum_xp, sum_xp); + vfloat4 prod_yp = dot(sum_yp, sum_yp); + vfloat4 prod_zp = dot(sum_zp, sum_zp); + vfloat4 prod_wp = dot(sum_wp, sum_wp); + + vfloat4 best_vector = sum_xp; + vfloat4 best_sum = prod_xp; + + vmask4 mask = prod_yp > best_sum; + best_vector = select(best_vector, sum_yp, mask); + best_sum = select(best_sum, prod_yp, mask); + + mask = prod_zp > best_sum; + best_vector = select(best_vector, sum_zp, mask); + best_sum = select(best_sum, prod_zp, mask); + + mask = prod_wp > best_sum; + best_vector = select(best_vector, sum_wp, mask); + + pm[partition].dir = best_vector; + } +} + +/* See header for documentation. */ +void compute_avgs_and_dirs_3_comp( + const partition_info& pi, + const image_block& blk, + unsigned int omitted_component, + partition_metrics pm[BLOCK_MAX_PARTITIONS] +) { + // Pre-compute partition_averages + vfloat4 partition_averages[BLOCK_MAX_PARTITIONS]; + compute_partition_averages_rgba(pi, blk, partition_averages); + + const float* data_vr = blk.data_r; + const float* data_vg = blk.data_g; + const float* data_vb = blk.data_b; + + // TODO: Data-driven permute would be useful to avoid this ... + if (omitted_component == 0) + { + partition_averages[0] = partition_averages[0].swz<1, 2, 3>(); + partition_averages[1] = partition_averages[1].swz<1, 2, 3>(); + partition_averages[2] = partition_averages[2].swz<1, 2, 3>(); + partition_averages[3] = partition_averages[3].swz<1, 2, 3>(); + + data_vr = blk.data_g; + data_vg = blk.data_b; + data_vb = blk.data_a; + } + else if (omitted_component == 1) + { + partition_averages[0] = partition_averages[0].swz<0, 2, 3>(); + partition_averages[1] = partition_averages[1].swz<0, 2, 3>(); + partition_averages[2] = partition_averages[2].swz<0, 2, 3>(); + partition_averages[3] = partition_averages[3].swz<0, 2, 3>(); + + data_vg = blk.data_b; + data_vb = blk.data_a; + } + else if (omitted_component == 2) + { + partition_averages[0] = partition_averages[0].swz<0, 1, 3>(); + partition_averages[1] = partition_averages[1].swz<0, 1, 3>(); + partition_averages[2] = partition_averages[2].swz<0, 1, 3>(); + partition_averages[3] = partition_averages[3].swz<0, 1, 3>(); + + data_vb = blk.data_a; + } + else + { + partition_averages[0] = partition_averages[0].swz<0, 1, 2>(); + partition_averages[1] = partition_averages[1].swz<0, 1, 2>(); + partition_averages[2] = partition_averages[2].swz<0, 1, 2>(); + partition_averages[3] = partition_averages[3].swz<0, 1, 2>(); + } + + unsigned int partition_count = pi.partition_count; + promise(partition_count > 0); + + for (unsigned int partition = 0; partition < partition_count; partition++) + { + const uint8_t *texel_indexes = pi.texels_of_partition[partition]; + unsigned int texel_count = pi.partition_texel_count[partition]; + promise(texel_count > 0); + + vfloat4 average = partition_averages[partition]; + pm[partition].avg = average; + + vfloat4 sum_xp = vfloat4::zero(); + vfloat4 sum_yp = vfloat4::zero(); + vfloat4 sum_zp = vfloat4::zero(); + + for (unsigned int i = 0; i < texel_count; i++) + { + unsigned int iwt = texel_indexes[i]; + + vfloat4 texel_datum = vfloat3(data_vr[iwt], + data_vg[iwt], + data_vb[iwt]); + texel_datum = texel_datum - average; + + vfloat4 zero = vfloat4::zero(); + + vmask4 tdm0 = texel_datum.swz<0,0,0,0>() > zero; + sum_xp += select(zero, texel_datum, tdm0); + + vmask4 tdm1 = texel_datum.swz<1,1,1,1>() > zero; + sum_yp += select(zero, texel_datum, tdm1); + + vmask4 tdm2 = texel_datum.swz<2,2,2,2>() > zero; + sum_zp += select(zero, texel_datum, tdm2); + } + + vfloat4 prod_xp = dot(sum_xp, sum_xp); + vfloat4 prod_yp = dot(sum_yp, sum_yp); + vfloat4 prod_zp = dot(sum_zp, sum_zp); + + vfloat4 best_vector = sum_xp; + vfloat4 best_sum = prod_xp; + + vmask4 mask = prod_yp > best_sum; + best_vector = select(best_vector, sum_yp, mask); + best_sum = select(best_sum, prod_yp, mask); + + mask = prod_zp > best_sum; + best_vector = select(best_vector, sum_zp, mask); + + pm[partition].dir = best_vector; + } +} + +/* See header for documentation. */ +void compute_avgs_and_dirs_3_comp_rgb( + const partition_info& pi, + const image_block& blk, + partition_metrics pm[BLOCK_MAX_PARTITIONS] +) { + unsigned int partition_count = pi.partition_count; + promise(partition_count > 0); + + // Pre-compute partition_averages + vfloat4 partition_averages[BLOCK_MAX_PARTITIONS]; + compute_partition_averages_rgb(pi, blk, partition_averages); + + for (unsigned int partition = 0; partition < partition_count; partition++) + { + const uint8_t *texel_indexes = pi.texels_of_partition[partition]; + unsigned int texel_count = pi.partition_texel_count[partition]; + promise(texel_count > 0); + + vfloat4 average = partition_averages[partition]; + pm[partition].avg = average; + + vfloat4 sum_xp = vfloat4::zero(); + vfloat4 sum_yp = vfloat4::zero(); + vfloat4 sum_zp = vfloat4::zero(); + + for (unsigned int i = 0; i < texel_count; i++) + { + unsigned int iwt = texel_indexes[i]; + + vfloat4 texel_datum = blk.texel3(iwt); + texel_datum = texel_datum - average; + + vfloat4 zero = vfloat4::zero(); + + vmask4 tdm0 = texel_datum.swz<0,0,0,0>() > zero; + sum_xp += select(zero, texel_datum, tdm0); + + vmask4 tdm1 = texel_datum.swz<1,1,1,1>() > zero; + sum_yp += select(zero, texel_datum, tdm1); + + vmask4 tdm2 = texel_datum.swz<2,2,2,2>() > zero; + sum_zp += select(zero, texel_datum, tdm2); + } + + vfloat4 prod_xp = dot(sum_xp, sum_xp); + vfloat4 prod_yp = dot(sum_yp, sum_yp); + vfloat4 prod_zp = dot(sum_zp, sum_zp); + + vfloat4 best_vector = sum_xp; + vfloat4 best_sum = prod_xp; + + vmask4 mask = prod_yp > best_sum; + best_vector = select(best_vector, sum_yp, mask); + best_sum = select(best_sum, prod_yp, mask); + + mask = prod_zp > best_sum; + best_vector = select(best_vector, sum_zp, mask); + + pm[partition].dir = best_vector; + } +} + +/* See header for documentation. */ +void compute_avgs_and_dirs_2_comp( + const partition_info& pt, + const image_block& blk, + unsigned int component1, + unsigned int component2, + partition_metrics pm[BLOCK_MAX_PARTITIONS] +) { + vfloat4 average; + + const float* data_vr = nullptr; + const float* data_vg = nullptr; + + if (component1 == 0 && component2 == 1) + { + average = blk.data_mean.swz<0, 1>(); + + data_vr = blk.data_r; + data_vg = blk.data_g; + } + else if (component1 == 0 && component2 == 2) + { + average = blk.data_mean.swz<0, 2>(); + + data_vr = blk.data_r; + data_vg = blk.data_b; + } + else // (component1 == 1 && component2 == 2) + { + assert(component1 == 1 && component2 == 2); + + average = blk.data_mean.swz<1, 2>(); + + data_vr = blk.data_g; + data_vg = blk.data_b; + } + + unsigned int partition_count = pt.partition_count; + promise(partition_count > 0); + + for (unsigned int partition = 0; partition < partition_count; partition++) + { + const uint8_t *texel_indexes = pt.texels_of_partition[partition]; + unsigned int texel_count = pt.partition_texel_count[partition]; + promise(texel_count > 0); + + // Only compute a partition mean if more than one partition + if (partition_count > 1) + { + average = vfloat4::zero(); + for (unsigned int i = 0; i < texel_count; i++) + { + unsigned int iwt = texel_indexes[i]; + average += vfloat2(data_vr[iwt], data_vg[iwt]); + } + + average = average / static_cast<float>(texel_count); + } + + pm[partition].avg = average; + + vfloat4 sum_xp = vfloat4::zero(); + vfloat4 sum_yp = vfloat4::zero(); + + for (unsigned int i = 0; i < texel_count; i++) + { + unsigned int iwt = texel_indexes[i]; + vfloat4 texel_datum = vfloat2(data_vr[iwt], data_vg[iwt]); + texel_datum = texel_datum - average; + + vfloat4 zero = vfloat4::zero(); + + vmask4 tdm0 = texel_datum.swz<0,0,0,0>() > zero; + sum_xp += select(zero, texel_datum, tdm0); + + vmask4 tdm1 = texel_datum.swz<1,1,1,1>() > zero; + sum_yp += select(zero, texel_datum, tdm1); + } + + vfloat4 prod_xp = dot(sum_xp, sum_xp); + vfloat4 prod_yp = dot(sum_yp, sum_yp); + + vfloat4 best_vector = sum_xp; + vfloat4 best_sum = prod_xp; + + vmask4 mask = prod_yp > best_sum; + best_vector = select(best_vector, sum_yp, mask); + + pm[partition].dir = best_vector; + } +} + +/* See header for documentation. */ +void compute_error_squared_rgba( + const partition_info& pi, + const image_block& blk, + const processed_line4 uncor_plines[BLOCK_MAX_PARTITIONS], + const processed_line4 samec_plines[BLOCK_MAX_PARTITIONS], + float uncor_lengths[BLOCK_MAX_PARTITIONS], + float samec_lengths[BLOCK_MAX_PARTITIONS], + float& uncor_error, + float& samec_error +) { + unsigned int partition_count = pi.partition_count; + promise(partition_count > 0); + + vfloatacc uncor_errorsumv = vfloatacc::zero(); + vfloatacc samec_errorsumv = vfloatacc::zero(); + + for (unsigned int partition = 0; partition < partition_count; partition++) + { + const uint8_t *texel_indexes = pi.texels_of_partition[partition]; + + float uncor_loparam = 1e10f; + float uncor_hiparam = -1e10f; + + float samec_loparam = 1e10f; + float samec_hiparam = -1e10f; + + processed_line4 l_uncor = uncor_plines[partition]; + processed_line4 l_samec = samec_plines[partition]; + + unsigned int texel_count = pi.partition_texel_count[partition]; + promise(texel_count > 0); + + // Vectorize some useful scalar inputs + vfloat l_uncor_bs0(l_uncor.bs.lane<0>()); + vfloat l_uncor_bs1(l_uncor.bs.lane<1>()); + vfloat l_uncor_bs2(l_uncor.bs.lane<2>()); + vfloat l_uncor_bs3(l_uncor.bs.lane<3>()); + + vfloat l_uncor_amod0(l_uncor.amod.lane<0>()); + vfloat l_uncor_amod1(l_uncor.amod.lane<1>()); + vfloat l_uncor_amod2(l_uncor.amod.lane<2>()); + vfloat l_uncor_amod3(l_uncor.amod.lane<3>()); + + vfloat l_samec_bs0(l_samec.bs.lane<0>()); + vfloat l_samec_bs1(l_samec.bs.lane<1>()); + vfloat l_samec_bs2(l_samec.bs.lane<2>()); + vfloat l_samec_bs3(l_samec.bs.lane<3>()); + + assert(all(l_samec.amod == vfloat4(0.0f))); + + vfloat uncor_loparamv(1e10f); + vfloat uncor_hiparamv(-1e10f); + + vfloat samec_loparamv(1e10f); + vfloat samec_hiparamv(-1e10f); + + vfloat ew_r(blk.channel_weight.lane<0>()); + vfloat ew_g(blk.channel_weight.lane<1>()); + vfloat ew_b(blk.channel_weight.lane<2>()); + vfloat ew_a(blk.channel_weight.lane<3>()); + + // This implementation over-shoots, but this is safe as we initialize the texel_indexes + // array to extend the last value. This means min/max are not impacted, but we need to mask + // out the dummy values when we compute the line weighting. + vint lane_ids = vint::lane_id(); + for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) + { + vmask mask = lane_ids < vint(texel_count); + vint texel_idxs(texel_indexes + i); + + vfloat data_r = gatherf(blk.data_r, texel_idxs); + vfloat data_g = gatherf(blk.data_g, texel_idxs); + vfloat data_b = gatherf(blk.data_b, texel_idxs); + vfloat data_a = gatherf(blk.data_a, texel_idxs); + + vfloat uncor_param = (data_r * l_uncor_bs0) + + (data_g * l_uncor_bs1) + + (data_b * l_uncor_bs2) + + (data_a * l_uncor_bs3); + + uncor_loparamv = min(uncor_param, uncor_loparamv); + uncor_hiparamv = max(uncor_param, uncor_hiparamv); + + vfloat uncor_dist0 = (l_uncor_amod0 - data_r) + + (uncor_param * l_uncor_bs0); + vfloat uncor_dist1 = (l_uncor_amod1 - data_g) + + (uncor_param * l_uncor_bs1); + vfloat uncor_dist2 = (l_uncor_amod2 - data_b) + + (uncor_param * l_uncor_bs2); + vfloat uncor_dist3 = (l_uncor_amod3 - data_a) + + (uncor_param * l_uncor_bs3); + + vfloat uncor_err = (ew_r * uncor_dist0 * uncor_dist0) + + (ew_g * uncor_dist1 * uncor_dist1) + + (ew_b * uncor_dist2 * uncor_dist2) + + (ew_a * uncor_dist3 * uncor_dist3); + + haccumulate(uncor_errorsumv, uncor_err, mask); + + // Process samechroma data + vfloat samec_param = (data_r * l_samec_bs0) + + (data_g * l_samec_bs1) + + (data_b * l_samec_bs2) + + (data_a * l_samec_bs3); + + samec_loparamv = min(samec_param, samec_loparamv); + samec_hiparamv = max(samec_param, samec_hiparamv); + + vfloat samec_dist0 = samec_param * l_samec_bs0 - data_r; + vfloat samec_dist1 = samec_param * l_samec_bs1 - data_g; + vfloat samec_dist2 = samec_param * l_samec_bs2 - data_b; + vfloat samec_dist3 = samec_param * l_samec_bs3 - data_a; + + vfloat samec_err = (ew_r * samec_dist0 * samec_dist0) + + (ew_g * samec_dist1 * samec_dist1) + + (ew_b * samec_dist2 * samec_dist2) + + (ew_a * samec_dist3 * samec_dist3); + + haccumulate(samec_errorsumv, samec_err, mask); + + lane_ids += vint(ASTCENC_SIMD_WIDTH); + } + + uncor_loparam = hmin_s(uncor_loparamv); + uncor_hiparam = hmax_s(uncor_hiparamv); + + samec_loparam = hmin_s(samec_loparamv); + samec_hiparam = hmax_s(samec_hiparamv); + + float uncor_linelen = uncor_hiparam - uncor_loparam; + float samec_linelen = samec_hiparam - samec_loparam; + + // Turn very small numbers and NaNs into a small number + uncor_lengths[partition] = astc::max(uncor_linelen, 1e-7f); + samec_lengths[partition] = astc::max(samec_linelen, 1e-7f); + } + + uncor_error = hadd_s(uncor_errorsumv); + samec_error = hadd_s(samec_errorsumv); +} + +/* See header for documentation. */ +void compute_error_squared_rgb( + const partition_info& pi, + const image_block& blk, + partition_lines3 plines[BLOCK_MAX_PARTITIONS], + float& uncor_error, + float& samec_error +) { + unsigned int partition_count = pi.partition_count; + promise(partition_count > 0); + + vfloatacc uncor_errorsumv = vfloatacc::zero(); + vfloatacc samec_errorsumv = vfloatacc::zero(); + + for (unsigned int partition = 0; partition < partition_count; partition++) + { + partition_lines3& pl = plines[partition]; + const uint8_t *texel_indexes = pi.texels_of_partition[partition]; + unsigned int texel_count = pi.partition_texel_count[partition]; + promise(texel_count > 0); + + float uncor_loparam = 1e10f; + float uncor_hiparam = -1e10f; + + float samec_loparam = 1e10f; + float samec_hiparam = -1e10f; + + processed_line3 l_uncor = pl.uncor_pline; + processed_line3 l_samec = pl.samec_pline; + + // This implementation is an example vectorization of this function. + // It works for - the codec is a 2-4% faster than not vectorizing - but + // the benefit is limited by the use of gathers and register pressure + + // Vectorize some useful scalar inputs + vfloat l_uncor_bs0(l_uncor.bs.lane<0>()); + vfloat l_uncor_bs1(l_uncor.bs.lane<1>()); + vfloat l_uncor_bs2(l_uncor.bs.lane<2>()); + + vfloat l_uncor_amod0(l_uncor.amod.lane<0>()); + vfloat l_uncor_amod1(l_uncor.amod.lane<1>()); + vfloat l_uncor_amod2(l_uncor.amod.lane<2>()); + + vfloat l_samec_bs0(l_samec.bs.lane<0>()); + vfloat l_samec_bs1(l_samec.bs.lane<1>()); + vfloat l_samec_bs2(l_samec.bs.lane<2>()); + + assert(all(l_samec.amod == vfloat4(0.0f))); + + vfloat uncor_loparamv(1e10f); + vfloat uncor_hiparamv(-1e10f); + + vfloat samec_loparamv(1e10f); + vfloat samec_hiparamv(-1e10f); + + vfloat ew_r(blk.channel_weight.lane<0>()); + vfloat ew_g(blk.channel_weight.lane<1>()); + vfloat ew_b(blk.channel_weight.lane<2>()); + + // This implementation over-shoots, but this is safe as we initialize the weights array + // to extend the last value. This means min/max are not impacted, but we need to mask + // out the dummy values when we compute the line weighting. + vint lane_ids = vint::lane_id(); + for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) + { + vmask mask = lane_ids < vint(texel_count); + vint texel_idxs(texel_indexes + i); + + vfloat data_r = gatherf(blk.data_r, texel_idxs); + vfloat data_g = gatherf(blk.data_g, texel_idxs); + vfloat data_b = gatherf(blk.data_b, texel_idxs); + + vfloat uncor_param = (data_r * l_uncor_bs0) + + (data_g * l_uncor_bs1) + + (data_b * l_uncor_bs2); + + uncor_loparamv = min(uncor_param, uncor_loparamv); + uncor_hiparamv = max(uncor_param, uncor_hiparamv); + + vfloat uncor_dist0 = (l_uncor_amod0 - data_r) + + (uncor_param * l_uncor_bs0); + vfloat uncor_dist1 = (l_uncor_amod1 - data_g) + + (uncor_param * l_uncor_bs1); + vfloat uncor_dist2 = (l_uncor_amod2 - data_b) + + (uncor_param * l_uncor_bs2); + + vfloat uncor_err = (ew_r * uncor_dist0 * uncor_dist0) + + (ew_g * uncor_dist1 * uncor_dist1) + + (ew_b * uncor_dist2 * uncor_dist2); + + haccumulate(uncor_errorsumv, uncor_err, mask); + + // Process samechroma data + vfloat samec_param = (data_r * l_samec_bs0) + + (data_g * l_samec_bs1) + + (data_b * l_samec_bs2); + + samec_loparamv = min(samec_param, samec_loparamv); + samec_hiparamv = max(samec_param, samec_hiparamv); + + vfloat samec_dist0 = samec_param * l_samec_bs0 - data_r; + vfloat samec_dist1 = samec_param * l_samec_bs1 - data_g; + vfloat samec_dist2 = samec_param * l_samec_bs2 - data_b; + + vfloat samec_err = (ew_r * samec_dist0 * samec_dist0) + + (ew_g * samec_dist1 * samec_dist1) + + (ew_b * samec_dist2 * samec_dist2); + + haccumulate(samec_errorsumv, samec_err, mask); + + lane_ids += vint(ASTCENC_SIMD_WIDTH); + } + + uncor_loparam = hmin_s(uncor_loparamv); + uncor_hiparam = hmax_s(uncor_hiparamv); + + samec_loparam = hmin_s(samec_loparamv); + samec_hiparam = hmax_s(samec_hiparamv); + + float uncor_linelen = uncor_hiparam - uncor_loparam; + float samec_linelen = samec_hiparam - samec_loparam; + + // Turn very small numbers and NaNs into a small number + pl.uncor_line_len = astc::max(uncor_linelen, 1e-7f); + pl.samec_line_len = astc::max(samec_linelen, 1e-7f); + } + + uncor_error = hadd_s(uncor_errorsumv); + samec_error = hadd_s(samec_errorsumv); +} + +#endif diff --git a/thirdparty/astcenc/astcenc_block_sizes.cpp b/thirdparty/astcenc/astcenc_block_sizes.cpp new file mode 100644 index 0000000000..1c22d06a5c --- /dev/null +++ b/thirdparty/astcenc/astcenc_block_sizes.cpp @@ -0,0 +1,1184 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2023 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief Functions to generate block size descriptor and decimation tables. + */ + +#include "astcenc_internal.h" + +/** + * @brief Decode the properties of an encoded 2D block mode. + * + * @param block_mode The encoded block mode. + * @param[out] x_weights The number of weights in the X dimension. + * @param[out] y_weights The number of weights in the Y dimension. + * @param[out] is_dual_plane True if this block mode has two weight planes. + * @param[out] quant_mode The quantization level for the weights. + * @param[out] weight_bits The storage bit count for the weights. + * + * @return Returns true if a valid mode, false otherwise. + */ +static bool decode_block_mode_2d( + unsigned int block_mode, + unsigned int& x_weights, + unsigned int& y_weights, + bool& is_dual_plane, + unsigned int& quant_mode, + unsigned int& weight_bits +) { + unsigned int base_quant_mode = (block_mode >> 4) & 1; + unsigned int H = (block_mode >> 9) & 1; + unsigned int D = (block_mode >> 10) & 1; + unsigned int A = (block_mode >> 5) & 0x3; + + x_weights = 0; + y_weights = 0; + + if ((block_mode & 3) != 0) + { + base_quant_mode |= (block_mode & 3) << 1; + unsigned int B = (block_mode >> 7) & 3; + switch ((block_mode >> 2) & 3) + { + case 0: + x_weights = B + 4; + y_weights = A + 2; + break; + case 1: + x_weights = B + 8; + y_weights = A + 2; + break; + case 2: + x_weights = A + 2; + y_weights = B + 8; + break; + case 3: + B &= 1; + if (block_mode & 0x100) + { + x_weights = B + 2; + y_weights = A + 2; + } + else + { + x_weights = A + 2; + y_weights = B + 6; + } + break; + } + } + else + { + base_quant_mode |= ((block_mode >> 2) & 3) << 1; + if (((block_mode >> 2) & 3) == 0) + { + return false; + } + + unsigned int B = (block_mode >> 9) & 3; + switch ((block_mode >> 7) & 3) + { + case 0: + x_weights = 12; + y_weights = A + 2; + break; + case 1: + x_weights = A + 2; + y_weights = 12; + break; + case 2: + x_weights = A + 6; + y_weights = B + 6; + D = 0; + H = 0; + break; + case 3: + switch ((block_mode >> 5) & 3) + { + case 0: + x_weights = 6; + y_weights = 10; + break; + case 1: + x_weights = 10; + y_weights = 6; + break; + case 2: + case 3: + return false; + } + break; + } + } + + unsigned int weight_count = x_weights * y_weights * (D + 1); + quant_mode = (base_quant_mode - 2) + 6 * H; + is_dual_plane = D != 0; + + weight_bits = get_ise_sequence_bitcount(weight_count, static_cast<quant_method>(quant_mode)); + return (weight_count <= BLOCK_MAX_WEIGHTS && + weight_bits >= BLOCK_MIN_WEIGHT_BITS && + weight_bits <= BLOCK_MAX_WEIGHT_BITS); +} + +/** + * @brief Decode the properties of an encoded 3D block mode. + * + * @param block_mode The encoded block mode. + * @param[out] x_weights The number of weights in the X dimension. + * @param[out] y_weights The number of weights in the Y dimension. + * @param[out] z_weights The number of weights in the Z dimension. + * @param[out] is_dual_plane True if this block mode has two weight planes. + * @param[out] quant_mode The quantization level for the weights. + * @param[out] weight_bits The storage bit count for the weights. + * + * @return Returns true if a valid mode, false otherwise. + */ +static bool decode_block_mode_3d( + unsigned int block_mode, + unsigned int& x_weights, + unsigned int& y_weights, + unsigned int& z_weights, + bool& is_dual_plane, + unsigned int& quant_mode, + unsigned int& weight_bits +) { + unsigned int base_quant_mode = (block_mode >> 4) & 1; + unsigned int H = (block_mode >> 9) & 1; + unsigned int D = (block_mode >> 10) & 1; + unsigned int A = (block_mode >> 5) & 0x3; + + x_weights = 0; + y_weights = 0; + z_weights = 0; + + if ((block_mode & 3) != 0) + { + base_quant_mode |= (block_mode & 3) << 1; + unsigned int B = (block_mode >> 7) & 3; + unsigned int C = (block_mode >> 2) & 0x3; + x_weights = A + 2; + y_weights = B + 2; + z_weights = C + 2; + } + else + { + base_quant_mode |= ((block_mode >> 2) & 3) << 1; + if (((block_mode >> 2) & 3) == 0) + { + return false; + } + + int B = (block_mode >> 9) & 3; + if (((block_mode >> 7) & 3) != 3) + { + D = 0; + H = 0; + } + switch ((block_mode >> 7) & 3) + { + case 0: + x_weights = 6; + y_weights = B + 2; + z_weights = A + 2; + break; + case 1: + x_weights = A + 2; + y_weights = 6; + z_weights = B + 2; + break; + case 2: + x_weights = A + 2; + y_weights = B + 2; + z_weights = 6; + break; + case 3: + x_weights = 2; + y_weights = 2; + z_weights = 2; + switch ((block_mode >> 5) & 3) + { + case 0: + x_weights = 6; + break; + case 1: + y_weights = 6; + break; + case 2: + z_weights = 6; + break; + case 3: + return false; + } + break; + } + } + + unsigned int weight_count = x_weights * y_weights * z_weights * (D + 1); + quant_mode = (base_quant_mode - 2) + 6 * H; + is_dual_plane = D != 0; + + weight_bits = get_ise_sequence_bitcount(weight_count, static_cast<quant_method>(quant_mode)); + return (weight_count <= BLOCK_MAX_WEIGHTS && + weight_bits >= BLOCK_MIN_WEIGHT_BITS && + weight_bits <= BLOCK_MAX_WEIGHT_BITS); +} + +/** + * @brief Create a 2D decimation entry for a block-size and weight-decimation pair. + * + * @param x_texels The number of texels in the X dimension. + * @param y_texels The number of texels in the Y dimension. + * @param x_weights The number of weights in the X dimension. + * @param y_weights The number of weights in the Y dimension. + * @param[out] di The decimation info structure to populate. + * @param[out] wb The decimation table init scratch working buffers. + */ +static void init_decimation_info_2d( + unsigned int x_texels, + unsigned int y_texels, + unsigned int x_weights, + unsigned int y_weights, + decimation_info& di, + dt_init_working_buffers& wb +) { + unsigned int texels_per_block = x_texels * y_texels; + unsigned int weights_per_block = x_weights * y_weights; + + uint8_t max_texel_count_of_weight = 0; + + promise(weights_per_block > 0); + promise(texels_per_block > 0); + promise(x_texels > 0); + promise(y_texels > 0); + + for (unsigned int i = 0; i < weights_per_block; i++) + { + wb.texel_count_of_weight[i] = 0; + } + + for (unsigned int i = 0; i < texels_per_block; i++) + { + wb.weight_count_of_texel[i] = 0; + } + + for (unsigned int y = 0; y < y_texels; y++) + { + for (unsigned int x = 0; x < x_texels; x++) + { + unsigned int texel = y * x_texels + x; + + unsigned int x_weight = (((1024 + x_texels / 2) / (x_texels - 1)) * x * (x_weights - 1) + 32) >> 6; + unsigned int y_weight = (((1024 + y_texels / 2) / (y_texels - 1)) * y * (y_weights - 1) + 32) >> 6; + + unsigned int x_weight_frac = x_weight & 0xF; + unsigned int y_weight_frac = y_weight & 0xF; + unsigned int x_weight_int = x_weight >> 4; + unsigned int y_weight_int = y_weight >> 4; + + unsigned int qweight[4]; + qweight[0] = x_weight_int + y_weight_int * x_weights; + qweight[1] = qweight[0] + 1; + qweight[2] = qweight[0] + x_weights; + qweight[3] = qweight[2] + 1; + + // Truncated-precision bilinear interpolation + unsigned int prod = x_weight_frac * y_weight_frac; + + unsigned int weight[4]; + weight[3] = (prod + 8) >> 4; + weight[1] = x_weight_frac - weight[3]; + weight[2] = y_weight_frac - weight[3]; + weight[0] = 16 - x_weight_frac - y_weight_frac + weight[3]; + + for (unsigned int i = 0; i < 4; i++) + { + if (weight[i] != 0) + { + wb.grid_weights_of_texel[texel][wb.weight_count_of_texel[texel]] = static_cast<uint8_t>(qweight[i]); + wb.weights_of_texel[texel][wb.weight_count_of_texel[texel]] = static_cast<uint8_t>(weight[i]); + wb.weight_count_of_texel[texel]++; + wb.texels_of_weight[qweight[i]][wb.texel_count_of_weight[qweight[i]]] = static_cast<uint8_t>(texel); + wb.texel_weights_of_weight[qweight[i]][wb.texel_count_of_weight[qweight[i]]] = static_cast<uint8_t>(weight[i]); + wb.texel_count_of_weight[qweight[i]]++; + max_texel_count_of_weight = astc::max(max_texel_count_of_weight, wb.texel_count_of_weight[qweight[i]]); + } + } + } + } + + uint8_t max_texel_weight_count = 0; + for (unsigned int i = 0; i < texels_per_block; i++) + { + di.texel_weight_count[i] = wb.weight_count_of_texel[i]; + max_texel_weight_count = astc::max(max_texel_weight_count, di.texel_weight_count[i]); + + for (unsigned int j = 0; j < wb.weight_count_of_texel[i]; j++) + { + di.texel_weight_contribs_int_tr[j][i] = wb.weights_of_texel[i][j]; + di.texel_weight_contribs_float_tr[j][i] = static_cast<float>(wb.weights_of_texel[i][j]) * (1.0f / WEIGHTS_TEXEL_SUM); + di.texel_weights_tr[j][i] = wb.grid_weights_of_texel[i][j]; + } + + // Init all 4 entries so we can rely on zeros for vectorization + for (unsigned int j = wb.weight_count_of_texel[i]; j < 4; j++) + { + di.texel_weight_contribs_int_tr[j][i] = 0; + di.texel_weight_contribs_float_tr[j][i] = 0.0f; + di.texel_weights_tr[j][i] = 0; + } + } + + di.max_texel_weight_count = max_texel_weight_count; + + for (unsigned int i = 0; i < weights_per_block; i++) + { + unsigned int texel_count_wt = wb.texel_count_of_weight[i]; + di.weight_texel_count[i] = static_cast<uint8_t>(texel_count_wt); + + for (unsigned int j = 0; j < texel_count_wt; j++) + { + uint8_t texel = wb.texels_of_weight[i][j]; + + // Create transposed versions of these for better vectorization + di.weight_texels_tr[j][i] = texel; + di.weights_texel_contribs_tr[j][i] = static_cast<float>(wb.texel_weights_of_weight[i][j]); + + // Store the per-texel contribution of this weight for each texel it contributes to + di.texel_contrib_for_weight[j][i] = 0.0f; + for (unsigned int k = 0; k < 4; k++) + { + uint8_t dttw = di.texel_weights_tr[k][texel]; + float dttwf = di.texel_weight_contribs_float_tr[k][texel]; + if (dttw == i && dttwf != 0.0f) + { + di.texel_contrib_for_weight[j][i] = di.texel_weight_contribs_float_tr[k][texel]; + break; + } + } + } + + // Initialize array tail so we can over-fetch with SIMD later to avoid loop tails + // Match last texel in active lane in SIMD group, for better gathers + uint8_t last_texel = di.weight_texels_tr[texel_count_wt - 1][i]; + for (unsigned int j = texel_count_wt; j < max_texel_count_of_weight; j++) + { + di.weight_texels_tr[j][i] = last_texel; + di.weights_texel_contribs_tr[j][i] = 0.0f; + } + } + + // Initialize array tail so we can over-fetch with SIMD later to avoid loop tails + unsigned int texels_per_block_simd = round_up_to_simd_multiple_vla(texels_per_block); + for (unsigned int i = texels_per_block; i < texels_per_block_simd; i++) + { + di.texel_weight_count[i] = 0; + + for (unsigned int j = 0; j < 4; j++) + { + di.texel_weight_contribs_float_tr[j][i] = 0; + di.texel_weights_tr[j][i] = 0; + di.texel_weight_contribs_int_tr[j][i] = 0; + } + } + + // Initialize array tail so we can over-fetch with SIMD later to avoid loop tails + // Match last texel in active lane in SIMD group, for better gathers + unsigned int last_texel_count_wt = wb.texel_count_of_weight[weights_per_block - 1]; + uint8_t last_texel = di.weight_texels_tr[last_texel_count_wt - 1][weights_per_block - 1]; + + unsigned int weights_per_block_simd = round_up_to_simd_multiple_vla(weights_per_block); + for (unsigned int i = weights_per_block; i < weights_per_block_simd; i++) + { + di.weight_texel_count[i] = 0; + + for (unsigned int j = 0; j < max_texel_count_of_weight; j++) + { + di.weight_texels_tr[j][i] = last_texel; + di.weights_texel_contribs_tr[j][i] = 0.0f; + } + } + + di.texel_count = static_cast<uint8_t>(texels_per_block); + di.weight_count = static_cast<uint8_t>(weights_per_block); + di.weight_x = static_cast<uint8_t>(x_weights); + di.weight_y = static_cast<uint8_t>(y_weights); + di.weight_z = 1; +} + +/** + * @brief Create a 3D decimation entry for a block-size and weight-decimation pair. + * + * @param x_texels The number of texels in the X dimension. + * @param y_texels The number of texels in the Y dimension. + * @param z_texels The number of texels in the Z dimension. + * @param x_weights The number of weights in the X dimension. + * @param y_weights The number of weights in the Y dimension. + * @param z_weights The number of weights in the Z dimension. + * @param[out] di The decimation info structure to populate. + @param[out] wb The decimation table init scratch working buffers. + */ +static void init_decimation_info_3d( + unsigned int x_texels, + unsigned int y_texels, + unsigned int z_texels, + unsigned int x_weights, + unsigned int y_weights, + unsigned int z_weights, + decimation_info& di, + dt_init_working_buffers& wb +) { + unsigned int texels_per_block = x_texels * y_texels * z_texels; + unsigned int weights_per_block = x_weights * y_weights * z_weights; + + uint8_t max_texel_count_of_weight = 0; + + promise(weights_per_block > 0); + promise(texels_per_block > 0); + + for (unsigned int i = 0; i < weights_per_block; i++) + { + wb.texel_count_of_weight[i] = 0; + } + + for (unsigned int i = 0; i < texels_per_block; i++) + { + wb.weight_count_of_texel[i] = 0; + } + + for (unsigned int z = 0; z < z_texels; z++) + { + for (unsigned int y = 0; y < y_texels; y++) + { + for (unsigned int x = 0; x < x_texels; x++) + { + int texel = (z * y_texels + y) * x_texels + x; + + int x_weight = (((1024 + x_texels / 2) / (x_texels - 1)) * x * (x_weights - 1) + 32) >> 6; + int y_weight = (((1024 + y_texels / 2) / (y_texels - 1)) * y * (y_weights - 1) + 32) >> 6; + int z_weight = (((1024 + z_texels / 2) / (z_texels - 1)) * z * (z_weights - 1) + 32) >> 6; + + int x_weight_frac = x_weight & 0xF; + int y_weight_frac = y_weight & 0xF; + int z_weight_frac = z_weight & 0xF; + int x_weight_int = x_weight >> 4; + int y_weight_int = y_weight >> 4; + int z_weight_int = z_weight >> 4; + int qweight[4]; + int weight[4]; + qweight[0] = (z_weight_int * y_weights + y_weight_int) * x_weights + x_weight_int; + qweight[3] = ((z_weight_int + 1) * y_weights + (y_weight_int + 1)) * x_weights + (x_weight_int + 1); + + // simplex interpolation + int fs = x_weight_frac; + int ft = y_weight_frac; + int fp = z_weight_frac; + + int cas = ((fs > ft) << 2) + ((ft > fp) << 1) + ((fs > fp)); + int N = x_weights; + int NM = x_weights * y_weights; + + int s1, s2, w0, w1, w2, w3; + switch (cas) + { + case 7: + s1 = 1; + s2 = N; + w0 = 16 - fs; + w1 = fs - ft; + w2 = ft - fp; + w3 = fp; + break; + case 3: + s1 = N; + s2 = 1; + w0 = 16 - ft; + w1 = ft - fs; + w2 = fs - fp; + w3 = fp; + break; + case 5: + s1 = 1; + s2 = NM; + w0 = 16 - fs; + w1 = fs - fp; + w2 = fp - ft; + w3 = ft; + break; + case 4: + s1 = NM; + s2 = 1; + w0 = 16 - fp; + w1 = fp - fs; + w2 = fs - ft; + w3 = ft; + break; + case 2: + s1 = N; + s2 = NM; + w0 = 16 - ft; + w1 = ft - fp; + w2 = fp - fs; + w3 = fs; + break; + case 0: + s1 = NM; + s2 = N; + w0 = 16 - fp; + w1 = fp - ft; + w2 = ft - fs; + w3 = fs; + break; + default: + s1 = NM; + s2 = N; + w0 = 16 - fp; + w1 = fp - ft; + w2 = ft - fs; + w3 = fs; + break; + } + + qweight[1] = qweight[0] + s1; + qweight[2] = qweight[1] + s2; + weight[0] = w0; + weight[1] = w1; + weight[2] = w2; + weight[3] = w3; + + for (unsigned int i = 0; i < 4; i++) + { + if (weight[i] != 0) + { + wb.grid_weights_of_texel[texel][wb.weight_count_of_texel[texel]] = static_cast<uint8_t>(qweight[i]); + wb.weights_of_texel[texel][wb.weight_count_of_texel[texel]] = static_cast<uint8_t>(weight[i]); + wb.weight_count_of_texel[texel]++; + wb.texels_of_weight[qweight[i]][wb.texel_count_of_weight[qweight[i]]] = static_cast<uint8_t>(texel); + wb.texel_weights_of_weight[qweight[i]][wb.texel_count_of_weight[qweight[i]]] = static_cast<uint8_t>(weight[i]); + wb.texel_count_of_weight[qweight[i]]++; + max_texel_count_of_weight = astc::max(max_texel_count_of_weight, wb.texel_count_of_weight[qweight[i]]); + } + } + } + } + } + + uint8_t max_texel_weight_count = 0; + for (unsigned int i = 0; i < texels_per_block; i++) + { + di.texel_weight_count[i] = wb.weight_count_of_texel[i]; + max_texel_weight_count = astc::max(max_texel_weight_count, di.texel_weight_count[i]); + + // Init all 4 entries so we can rely on zeros for vectorization + for (unsigned int j = 0; j < 4; j++) + { + di.texel_weight_contribs_int_tr[j][i] = 0; + di.texel_weight_contribs_float_tr[j][i] = 0.0f; + di.texel_weights_tr[j][i] = 0; + } + + for (unsigned int j = 0; j < wb.weight_count_of_texel[i]; j++) + { + di.texel_weight_contribs_int_tr[j][i] = wb.weights_of_texel[i][j]; + di.texel_weight_contribs_float_tr[j][i] = static_cast<float>(wb.weights_of_texel[i][j]) * (1.0f / WEIGHTS_TEXEL_SUM); + di.texel_weights_tr[j][i] = wb.grid_weights_of_texel[i][j]; + } + } + + di.max_texel_weight_count = max_texel_weight_count; + + for (unsigned int i = 0; i < weights_per_block; i++) + { + unsigned int texel_count_wt = wb.texel_count_of_weight[i]; + di.weight_texel_count[i] = static_cast<uint8_t>(texel_count_wt); + + for (unsigned int j = 0; j < texel_count_wt; j++) + { + unsigned int texel = wb.texels_of_weight[i][j]; + + // Create transposed versions of these for better vectorization + di.weight_texels_tr[j][i] = static_cast<uint8_t>(texel); + di.weights_texel_contribs_tr[j][i] = static_cast<float>(wb.texel_weights_of_weight[i][j]); + + // Store the per-texel contribution of this weight for each texel it contributes to + di.texel_contrib_for_weight[j][i] = 0.0f; + for (unsigned int k = 0; k < 4; k++) + { + uint8_t dttw = di.texel_weights_tr[k][texel]; + float dttwf = di.texel_weight_contribs_float_tr[k][texel]; + if (dttw == i && dttwf != 0.0f) + { + di.texel_contrib_for_weight[j][i] = di.texel_weight_contribs_float_tr[k][texel]; + break; + } + } + } + + // Initialize array tail so we can over-fetch with SIMD later to avoid loop tails + // Match last texel in active lane in SIMD group, for better gathers + uint8_t last_texel = di.weight_texels_tr[texel_count_wt - 1][i]; + for (unsigned int j = texel_count_wt; j < max_texel_count_of_weight; j++) + { + di.weight_texels_tr[j][i] = last_texel; + di.weights_texel_contribs_tr[j][i] = 0.0f; + } + } + + // Initialize array tail so we can over-fetch with SIMD later to avoid loop tails + unsigned int texels_per_block_simd = round_up_to_simd_multiple_vla(texels_per_block); + for (unsigned int i = texels_per_block; i < texels_per_block_simd; i++) + { + di.texel_weight_count[i] = 0; + + for (unsigned int j = 0; j < 4; j++) + { + di.texel_weight_contribs_float_tr[j][i] = 0; + di.texel_weights_tr[j][i] = 0; + di.texel_weight_contribs_int_tr[j][i] = 0; + } + } + + // Initialize array tail so we can over-fetch with SIMD later to avoid loop tails + // Match last texel in active lane in SIMD group, for better gathers + int last_texel_count_wt = wb.texel_count_of_weight[weights_per_block - 1]; + uint8_t last_texel = di.weight_texels_tr[last_texel_count_wt - 1][weights_per_block - 1]; + + unsigned int weights_per_block_simd = round_up_to_simd_multiple_vla(weights_per_block); + for (unsigned int i = weights_per_block; i < weights_per_block_simd; i++) + { + di.weight_texel_count[i] = 0; + + for (int j = 0; j < max_texel_count_of_weight; j++) + { + di.weight_texels_tr[j][i] = last_texel; + di.weights_texel_contribs_tr[j][i] = 0.0f; + } + } + + di.texel_count = static_cast<uint8_t>(texels_per_block); + di.weight_count = static_cast<uint8_t>(weights_per_block); + di.weight_x = static_cast<uint8_t>(x_weights); + di.weight_y = static_cast<uint8_t>(y_weights); + di.weight_z = static_cast<uint8_t>(z_weights); +} + +/** + * @brief Assign the texels to use for kmeans clustering. + * + * The max limit is @c BLOCK_MAX_KMEANS_TEXELS; above this a random selection is used. + * The @c bsd.texel_count is an input and must be populated beforehand. + * + * @param[in,out] bsd The block size descriptor to populate. + */ +static void assign_kmeans_texels( + block_size_descriptor& bsd +) { + // Use all texels for kmeans on a small block + if (bsd.texel_count <= BLOCK_MAX_KMEANS_TEXELS) + { + for (uint8_t i = 0; i < bsd.texel_count; i++) + { + bsd.kmeans_texels[i] = i; + } + + return; + } + + // Select a random subset of BLOCK_MAX_KMEANS_TEXELS for kmeans on a large block + uint64_t rng_state[2]; + astc::rand_init(rng_state); + + // Initialize array used for tracking used indices + bool seen[BLOCK_MAX_TEXELS]; + for (uint8_t i = 0; i < bsd.texel_count; i++) + { + seen[i] = false; + } + + // Assign 64 random indices, retrying if we see repeats + unsigned int arr_elements_set = 0; + while (arr_elements_set < BLOCK_MAX_KMEANS_TEXELS) + { + uint8_t texel = static_cast<uint8_t>(astc::rand(rng_state)); + texel = texel % bsd.texel_count; + if (!seen[texel]) + { + bsd.kmeans_texels[arr_elements_set++] = texel; + seen[texel] = true; + } + } +} + +/** + * @brief Allocate a single 2D decimation table entry. + * + * @param x_texels The number of texels in the X dimension. + * @param y_texels The number of texels in the Y dimension. + * @param x_weights The number of weights in the X dimension. + * @param y_weights The number of weights in the Y dimension. + * @param bsd The block size descriptor we are populating. + * @param wb The decimation table init scratch working buffers. + * @param index The packed array index to populate. + */ +static void construct_dt_entry_2d( + unsigned int x_texels, + unsigned int y_texels, + unsigned int x_weights, + unsigned int y_weights, + block_size_descriptor& bsd, + dt_init_working_buffers& wb, + unsigned int index +) { + unsigned int weight_count = x_weights * y_weights; + assert(weight_count <= BLOCK_MAX_WEIGHTS); + + bool try_2planes = (2 * weight_count) <= BLOCK_MAX_WEIGHTS; + + decimation_info& di = bsd.decimation_tables[index]; + init_decimation_info_2d(x_texels, y_texels, x_weights, y_weights, di, wb); + + int maxprec_1plane = -1; + int maxprec_2planes = -1; + for (int i = 0; i < 12; i++) + { + unsigned int bits_1plane = get_ise_sequence_bitcount(weight_count, static_cast<quant_method>(i)); + if (bits_1plane >= BLOCK_MIN_WEIGHT_BITS && bits_1plane <= BLOCK_MAX_WEIGHT_BITS) + { + maxprec_1plane = i; + } + + if (try_2planes) + { + unsigned int bits_2planes = get_ise_sequence_bitcount(2 * weight_count, static_cast<quant_method>(i)); + if (bits_2planes >= BLOCK_MIN_WEIGHT_BITS && bits_2planes <= BLOCK_MAX_WEIGHT_BITS) + { + maxprec_2planes = i; + } + } + } + + // At least one of the two should be valid ... + assert(maxprec_1plane >= 0 || maxprec_2planes >= 0); + bsd.decimation_modes[index].maxprec_1plane = static_cast<int8_t>(maxprec_1plane); + bsd.decimation_modes[index].maxprec_2planes = static_cast<int8_t>(maxprec_2planes); + bsd.decimation_modes[index].refprec_1_plane = 0; + bsd.decimation_modes[index].refprec_2_planes = 0; +} + +/** + * @brief Allocate block modes and decimation tables for a single 2D block size. + * + * @param x_texels The number of texels in the X dimension. + * @param y_texels The number of texels in the Y dimension. + * @param can_omit_modes Can we discard modes that astcenc won't use, even if legal? + * @param mode_cutoff Percentile cutoff in range [0,1]. Low values more likely to be used. + * @param[out] bsd The block size descriptor to populate. + */ +static void construct_block_size_descriptor_2d( + unsigned int x_texels, + unsigned int y_texels, + bool can_omit_modes, + float mode_cutoff, + block_size_descriptor& bsd +) { + // Store a remap table for storing packed decimation modes. + // Indexing uses [Y * 16 + X] and max size for each axis is 12. + static const unsigned int MAX_DMI = 12 * 16 + 12; + int decimation_mode_index[MAX_DMI]; + + dt_init_working_buffers* wb = new dt_init_working_buffers; + + bsd.xdim = static_cast<uint8_t>(x_texels); + bsd.ydim = static_cast<uint8_t>(y_texels); + bsd.zdim = 1; + bsd.texel_count = static_cast<uint8_t>(x_texels * y_texels); + + for (unsigned int i = 0; i < MAX_DMI; i++) + { + decimation_mode_index[i] = -1; + } + + // Gather all the decimation grids that can be used with the current block +#if !defined(ASTCENC_DECOMPRESS_ONLY) + const float *percentiles = get_2d_percentile_table(x_texels, y_texels); + float always_cutoff = 0.0f; +#else + // Unused in decompress-only builds + (void)can_omit_modes; + (void)mode_cutoff; +#endif + + // Construct the list of block formats referencing the decimation tables + unsigned int packed_bm_idx = 0; + unsigned int packed_dm_idx = 0; + + // Trackers + unsigned int bm_counts[4] { 0 }; + unsigned int dm_counts[4] { 0 }; + + // Clear the list to a known-bad value + for (unsigned int i = 0; i < WEIGHTS_MAX_BLOCK_MODES; i++) + { + bsd.block_mode_packed_index[i] = BLOCK_BAD_BLOCK_MODE; + } + + // Iterate four times to build a usefully ordered list: + // - Pass 0 - keep selected single plane "always" block modes + // - Pass 1 - keep selected single plane "non-always" block modes + // - Pass 2 - keep select dual plane block modes + // - Pass 3 - keep everything else that's legal + unsigned int limit = can_omit_modes ? 3 : 4; + for (unsigned int j = 0; j < limit; j ++) + { + for (unsigned int i = 0; i < WEIGHTS_MAX_BLOCK_MODES; i++) + { + // Skip modes we've already included in a previous pass + if (bsd.block_mode_packed_index[i] != BLOCK_BAD_BLOCK_MODE) + { + continue; + } + + // Decode parameters + unsigned int x_weights; + unsigned int y_weights; + bool is_dual_plane; + unsigned int quant_mode; + unsigned int weight_bits; + bool valid = decode_block_mode_2d(i, x_weights, y_weights, is_dual_plane, quant_mode, weight_bits); + + // Always skip invalid encodings for the current block size + if (!valid || (x_weights > x_texels) || (y_weights > y_texels)) + { + continue; + } + + // Selectively skip dual plane encodings + if (((j <= 1) && is_dual_plane) || (j == 2 && !is_dual_plane)) + { + continue; + } + + // Always skip encodings we can't physically encode based on + // generic encoding bit availability + if (is_dual_plane) + { + // This is the only check we need as only support 1 partition + if ((109 - weight_bits) <= 0) + { + continue; + } + } + else + { + // This is conservative - fewer bits may be available for > 1 partition + if ((111 - weight_bits) <= 0) + { + continue; + } + } + + // Selectively skip encodings based on percentile + bool percentile_hit = false; + #if !defined(ASTCENC_DECOMPRESS_ONLY) + if (j == 0) + { + percentile_hit = percentiles[i] <= always_cutoff; + } + else + { + percentile_hit = percentiles[i] <= mode_cutoff; + } + #endif + + if (j != 3 && !percentile_hit) + { + continue; + } + + // Allocate and initialize the decimation table entry if we've not used it yet + int decimation_mode = decimation_mode_index[y_weights * 16 + x_weights]; + if (decimation_mode < 0) + { + construct_dt_entry_2d(x_texels, y_texels, x_weights, y_weights, bsd, *wb, packed_dm_idx); + decimation_mode_index[y_weights * 16 + x_weights] = packed_dm_idx; + decimation_mode = packed_dm_idx; + + dm_counts[j]++; + packed_dm_idx++; + } + + auto& bm = bsd.block_modes[packed_bm_idx]; + + bm.decimation_mode = static_cast<uint8_t>(decimation_mode); + bm.quant_mode = static_cast<uint8_t>(quant_mode); + bm.is_dual_plane = static_cast<uint8_t>(is_dual_plane); + bm.weight_bits = static_cast<uint8_t>(weight_bits); + bm.mode_index = static_cast<uint16_t>(i); + + auto& dm = bsd.decimation_modes[decimation_mode]; + + if (is_dual_plane) + { + dm.set_ref_2_plane(bm.get_weight_quant_mode()); + } + else + { + dm.set_ref_1_plane(bm.get_weight_quant_mode()); + } + + bsd.block_mode_packed_index[i] = static_cast<uint16_t>(packed_bm_idx); + + packed_bm_idx++; + bm_counts[j]++; + } + } + + bsd.block_mode_count_1plane_always = bm_counts[0]; + bsd.block_mode_count_1plane_selected = bm_counts[0] + bm_counts[1]; + bsd.block_mode_count_1plane_2plane_selected = bm_counts[0] + bm_counts[1] + bm_counts[2]; + bsd.block_mode_count_all = bm_counts[0] + bm_counts[1] + bm_counts[2] + bm_counts[3]; + + bsd.decimation_mode_count_always = dm_counts[0]; + bsd.decimation_mode_count_selected = dm_counts[0] + dm_counts[1] + dm_counts[2]; + bsd.decimation_mode_count_all = dm_counts[0] + dm_counts[1] + dm_counts[2] + dm_counts[3]; + +#if !defined(ASTCENC_DECOMPRESS_ONLY) + assert(bsd.block_mode_count_1plane_always > 0); + assert(bsd.decimation_mode_count_always > 0); + + delete[] percentiles; +#endif + + // Ensure the end of the array contains valid data (should never get read) + for (unsigned int i = bsd.decimation_mode_count_all; i < WEIGHTS_MAX_DECIMATION_MODES; i++) + { + bsd.decimation_modes[i].maxprec_1plane = -1; + bsd.decimation_modes[i].maxprec_2planes = -1; + bsd.decimation_modes[i].refprec_1_plane = 0; + bsd.decimation_modes[i].refprec_2_planes = 0; + } + + // Determine the texels to use for kmeans clustering. + assign_kmeans_texels(bsd); + + delete wb; +} + +/** + * @brief Allocate block modes and decimation tables for a single 3D block size. + * + * TODO: This function doesn't include all of the heuristics that we use for 2D block sizes such as + * the percentile mode cutoffs. If 3D becomes more widely used we should look at this. + * + * @param x_texels The number of texels in the X dimension. + * @param y_texels The number of texels in the Y dimension. + * @param z_texels The number of texels in the Z dimension. + * @param[out] bsd The block size descriptor to populate. + */ +static void construct_block_size_descriptor_3d( + unsigned int x_texels, + unsigned int y_texels, + unsigned int z_texels, + block_size_descriptor& bsd +) { + // Store a remap table for storing packed decimation modes. + // Indexing uses [Z * 64 + Y * 8 + X] and max size for each axis is 6. + static constexpr unsigned int MAX_DMI = 6 * 64 + 6 * 8 + 6; + int decimation_mode_index[MAX_DMI]; + unsigned int decimation_mode_count = 0; + + dt_init_working_buffers* wb = new dt_init_working_buffers; + + bsd.xdim = static_cast<uint8_t>(x_texels); + bsd.ydim = static_cast<uint8_t>(y_texels); + bsd.zdim = static_cast<uint8_t>(z_texels); + bsd.texel_count = static_cast<uint8_t>(x_texels * y_texels * z_texels); + + for (unsigned int i = 0; i < MAX_DMI; i++) + { + decimation_mode_index[i] = -1; + } + + // gather all the infill-modes that can be used with the current block size + for (unsigned int x_weights = 2; x_weights <= x_texels; x_weights++) + { + for (unsigned int y_weights = 2; y_weights <= y_texels; y_weights++) + { + for (unsigned int z_weights = 2; z_weights <= z_texels; z_weights++) + { + unsigned int weight_count = x_weights * y_weights * z_weights; + if (weight_count > BLOCK_MAX_WEIGHTS) + { + continue; + } + + decimation_info& di = bsd.decimation_tables[decimation_mode_count]; + decimation_mode_index[z_weights * 64 + y_weights * 8 + x_weights] = decimation_mode_count; + init_decimation_info_3d(x_texels, y_texels, z_texels, x_weights, y_weights, z_weights, di, *wb); + + int maxprec_1plane = -1; + int maxprec_2planes = -1; + for (unsigned int i = 0; i < 12; i++) + { + unsigned int bits_1plane = get_ise_sequence_bitcount(weight_count, static_cast<quant_method>(i)); + if (bits_1plane >= BLOCK_MIN_WEIGHT_BITS && bits_1plane <= BLOCK_MAX_WEIGHT_BITS) + { + maxprec_1plane = i; + } + + unsigned int bits_2planes = get_ise_sequence_bitcount(2 * weight_count, static_cast<quant_method>(i)); + if (bits_2planes >= BLOCK_MIN_WEIGHT_BITS && bits_2planes <= BLOCK_MAX_WEIGHT_BITS) + { + maxprec_2planes = i; + } + } + + if ((2 * weight_count) > BLOCK_MAX_WEIGHTS) + { + maxprec_2planes = -1; + } + + bsd.decimation_modes[decimation_mode_count].maxprec_1plane = static_cast<int8_t>(maxprec_1plane); + bsd.decimation_modes[decimation_mode_count].maxprec_2planes = static_cast<int8_t>(maxprec_2planes); + bsd.decimation_modes[decimation_mode_count].refprec_1_plane = maxprec_1plane == -1 ? 0 : 0xFFFF; + bsd.decimation_modes[decimation_mode_count].refprec_2_planes = maxprec_2planes == -1 ? 0 : 0xFFFF; + decimation_mode_count++; + } + } + } + + // Ensure the end of the array contains valid data (should never get read) + for (unsigned int i = decimation_mode_count; i < WEIGHTS_MAX_DECIMATION_MODES; i++) + { + bsd.decimation_modes[i].maxprec_1plane = -1; + bsd.decimation_modes[i].maxprec_2planes = -1; + bsd.decimation_modes[i].refprec_1_plane = 0; + bsd.decimation_modes[i].refprec_2_planes = 0; + } + + bsd.decimation_mode_count_always = 0; // Skipped for 3D modes + bsd.decimation_mode_count_selected = decimation_mode_count; + bsd.decimation_mode_count_all = decimation_mode_count; + + // Construct the list of block formats referencing the decimation tables + + // Clear the list to a known-bad value + for (unsigned int i = 0; i < WEIGHTS_MAX_BLOCK_MODES; i++) + { + bsd.block_mode_packed_index[i] = BLOCK_BAD_BLOCK_MODE; + } + + unsigned int packed_idx = 0; + unsigned int bm_counts[2] { 0 }; + + // Iterate two times to build a usefully ordered list: + // - Pass 0 - keep valid single plane block modes + // - Pass 1 - keep valid dual plane block modes + for (unsigned int j = 0; j < 2; j++) + { + for (unsigned int i = 0; i < WEIGHTS_MAX_BLOCK_MODES; i++) + { + // Skip modes we've already included in a previous pass + if (bsd.block_mode_packed_index[i] != BLOCK_BAD_BLOCK_MODE) + { + continue; + } + + unsigned int x_weights; + unsigned int y_weights; + unsigned int z_weights; + bool is_dual_plane; + unsigned int quant_mode; + unsigned int weight_bits; + + bool valid = decode_block_mode_3d(i, x_weights, y_weights, z_weights, is_dual_plane, quant_mode, weight_bits); + // Skip invalid encodings + if (!valid || x_weights > x_texels || y_weights > y_texels || z_weights > z_texels) + { + continue; + } + + // Skip encodings in the wrong iteration + if ((j == 0 && is_dual_plane) || (j == 1 && !is_dual_plane)) + { + continue; + } + + // Always skip encodings we can't physically encode based on bit availability + if (is_dual_plane) + { + // This is the only check we need as only support 1 partition + if ((109 - weight_bits) <= 0) + { + continue; + } + } + else + { + // This is conservative - fewer bits may be available for > 1 partition + if ((111 - weight_bits) <= 0) + { + continue; + } + } + + int decimation_mode = decimation_mode_index[z_weights * 64 + y_weights * 8 + x_weights]; + bsd.block_modes[packed_idx].decimation_mode = static_cast<uint8_t>(decimation_mode); + bsd.block_modes[packed_idx].quant_mode = static_cast<uint8_t>(quant_mode); + bsd.block_modes[packed_idx].weight_bits = static_cast<uint8_t>(weight_bits); + bsd.block_modes[packed_idx].is_dual_plane = static_cast<uint8_t>(is_dual_plane); + bsd.block_modes[packed_idx].mode_index = static_cast<uint16_t>(i); + + bsd.block_mode_packed_index[i] = static_cast<uint16_t>(packed_idx); + bm_counts[j]++; + packed_idx++; + } + } + + bsd.block_mode_count_1plane_always = 0; // Skipped for 3D modes + bsd.block_mode_count_1plane_selected = bm_counts[0]; + bsd.block_mode_count_1plane_2plane_selected = bm_counts[0] + bm_counts[1]; + bsd.block_mode_count_all = bm_counts[0] + bm_counts[1]; + + // Determine the texels to use for kmeans clustering. + assign_kmeans_texels(bsd); + + delete wb; +} + +/* See header for documentation. */ +void init_block_size_descriptor( + unsigned int x_texels, + unsigned int y_texels, + unsigned int z_texels, + bool can_omit_modes, + unsigned int partition_count_cutoff, + float mode_cutoff, + block_size_descriptor& bsd +) { + if (z_texels > 1) + { + construct_block_size_descriptor_3d(x_texels, y_texels, z_texels, bsd); + } + else + { + construct_block_size_descriptor_2d(x_texels, y_texels, can_omit_modes, mode_cutoff, bsd); + } + + init_partition_tables(bsd, can_omit_modes, partition_count_cutoff); +} diff --git a/thirdparty/astcenc/astcenc_color_quantize.cpp b/thirdparty/astcenc/astcenc_color_quantize.cpp new file mode 100644 index 0000000000..edcfe4f853 --- /dev/null +++ b/thirdparty/astcenc/astcenc_color_quantize.cpp @@ -0,0 +1,2071 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2021 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +#if !defined(ASTCENC_DECOMPRESS_ONLY) + +/** + * @brief Functions for color quantization. + * + * The design of the color quantization functionality requires the caller to use higher level error + * analysis to determine the base encoding that should be used. This earlier analysis will select + * the basic type of the endpoint that should be used: + * + * * Mode: LDR or HDR + * * Quantization level + * * Channel count: L, LA, RGB, or RGBA + * * Endpoint 2 type: Direct color endcode, or scaled from endpoint 1. + * + * However, this leaves a number of decisions about exactly how to pack the endpoints open. In + * particular we need to determine if blue contraction can be used, or/and if delta encoding can be + * used. If they can be applied these will allow us to maintain higher precision in the endpoints + * without needing additional storage. + */ + +#include <stdio.h> +#include <assert.h> + +#include "astcenc_internal.h" + +/** + * @brief Determine the quantized value given a quantization level. + * + * @param quant_level The quantization level to use. + * @param value The value to convert. This may be outside of the 0-255 range and will be + * clamped before the value is looked up. + * + * @return The encoded quantized value. These are not necessarily in order; the compressor + * scrambles the values slightly to make hardware implementation easier. + */ +static inline uint8_t quant_color( + quant_method quant_level, + int value +) { + return color_unquant_to_uquant_tables[quant_level - QUANT_6][value]; +} + +/** + * @brief Quantize an LDR RGB color. + * + * Since this is a fall-back encoding, we cannot actually fail but must produce a sensible result. + * For this encoding @c color0 cannot be larger than @c color1. If @c color0 is actually larger + * than @c color1, @c color0 is reduced and @c color1 is increased until the constraint is met. + * + * @param color0 The input unquantized color0 endpoint. + * @param color1 The input unquantized color1 endpoint. + * @param[out] output The output endpoints, returned as (r0, r1, g0, g1, b0, b1). + * @param quant_level The quantization level to use. + */ +static void quantize_rgb( + vfloat4 color0, + vfloat4 color1, + uint8_t output[6], + quant_method quant_level +) { + float scale = 1.0f / 257.0f; + + float r0 = astc::clamp255f(color0.lane<0>() * scale); + float g0 = astc::clamp255f(color0.lane<1>() * scale); + float b0 = astc::clamp255f(color0.lane<2>() * scale); + + float r1 = astc::clamp255f(color1.lane<0>() * scale); + float g1 = astc::clamp255f(color1.lane<1>() * scale); + float b1 = astc::clamp255f(color1.lane<2>() * scale); + + int ri0, gi0, bi0, ri1, gi1, bi1; + float rgb0_addon = 0.5f; + float rgb1_addon = 0.5f; + do + { + ri0 = quant_color(quant_level, astc::max(astc::flt2int_rd(r0 + rgb0_addon), 0)); + gi0 = quant_color(quant_level, astc::max(astc::flt2int_rd(g0 + rgb0_addon), 0)); + bi0 = quant_color(quant_level, astc::max(astc::flt2int_rd(b0 + rgb0_addon), 0)); + ri1 = quant_color(quant_level, astc::min(astc::flt2int_rd(r1 + rgb1_addon), 255)); + gi1 = quant_color(quant_level, astc::min(astc::flt2int_rd(g1 + rgb1_addon), 255)); + bi1 = quant_color(quant_level, astc::min(astc::flt2int_rd(b1 + rgb1_addon), 255)); + + rgb0_addon -= 0.2f; + rgb1_addon += 0.2f; + } while (ri0 + gi0 + bi0 > ri1 + gi1 + bi1); + + output[0] = static_cast<uint8_t>(ri0); + output[1] = static_cast<uint8_t>(ri1); + output[2] = static_cast<uint8_t>(gi0); + output[3] = static_cast<uint8_t>(gi1); + output[4] = static_cast<uint8_t>(bi0); + output[5] = static_cast<uint8_t>(bi1); +} + +/** + * @brief Quantize an LDR RGBA color. + * + * Since this is a fall-back encoding, we cannot actually fail but must produce a sensible result. + * For this encoding @c color0.rgb cannot be larger than @c color1.rgb (this indicates blue + * contraction). If @c color0.rgb is actually larger than @c color1.rgb, @c color0.rgb is reduced + * and @c color1.rgb is increased until the constraint is met. + * + * @param color0 The input unquantized color0 endpoint. + * @param color1 The input unquantized color1 endpoint. + * @param[out] output The output endpoints, returned as (r0, r1, g0, g1, b0, b1, a0, a1). + * @param quant_level The quantization level to use. + */ +static void quantize_rgba( + vfloat4 color0, + vfloat4 color1, + uint8_t output[8], + quant_method quant_level +) { + float scale = 1.0f / 257.0f; + + float a0 = astc::clamp255f(color0.lane<3>() * scale); + float a1 = astc::clamp255f(color1.lane<3>() * scale); + + output[6] = quant_color(quant_level, astc::flt2int_rtn(a0)); + output[7] = quant_color(quant_level, astc::flt2int_rtn(a1)); + + quantize_rgb(color0, color1, output, quant_level); +} + +/** + * @brief Try to quantize an LDR RGB color using blue-contraction. + * + * Blue-contraction is only usable if encoded color 1 is larger than color 0. + * + * @param color0 The input unquantized color0 endpoint. + * @param color1 The input unquantized color1 endpoint. + * @param[out] output The output endpoints, returned as (r1, r0, g1, g0, b1, b0). + * @param quant_level The quantization level to use. + * + * @return Returns @c false on failure, @c true on success. + */ +static bool try_quantize_rgb_blue_contract( + vfloat4 color0, + vfloat4 color1, + uint8_t output[6], + quant_method quant_level +) { + float scale = 1.0f / 257.0f; + + float r0 = color0.lane<0>() * scale; + float g0 = color0.lane<1>() * scale; + float b0 = color0.lane<2>() * scale; + + float r1 = color1.lane<0>() * scale; + float g1 = color1.lane<1>() * scale; + float b1 = color1.lane<2>() * scale; + + // Apply inverse blue-contraction. This can produce an overflow; which means BC cannot be used. + r0 += (r0 - b0); + g0 += (g0 - b0); + r1 += (r1 - b1); + g1 += (g1 - b1); + + if (r0 < 0.0f || r0 > 255.0f || g0 < 0.0f || g0 > 255.0f || b0 < 0.0f || b0 > 255.0f || + r1 < 0.0f || r1 > 255.0f || g1 < 0.0f || g1 > 255.0f || b1 < 0.0f || b1 > 255.0f) + { + return false; + } + + // Quantize the inverse-blue-contracted color + int ri0 = quant_color(quant_level, astc::flt2int_rtn(r0)); + int gi0 = quant_color(quant_level, astc::flt2int_rtn(g0)); + int bi0 = quant_color(quant_level, astc::flt2int_rtn(b0)); + + int ri1 = quant_color(quant_level, astc::flt2int_rtn(r1)); + int gi1 = quant_color(quant_level, astc::flt2int_rtn(g1)); + int bi1 = quant_color(quant_level, astc::flt2int_rtn(b1)); + + // If color #1 is not larger than color #0 then blue-contraction cannot be used. Note that + // blue-contraction and quantization change this order, which is why we must test afterwards. + if (ri1 + gi1 + bi1 <= ri0 + gi0 + bi0) + { + return false; + } + + output[0] = static_cast<uint8_t>(ri1); + output[1] = static_cast<uint8_t>(ri0); + output[2] = static_cast<uint8_t>(gi1); + output[3] = static_cast<uint8_t>(gi0); + output[4] = static_cast<uint8_t>(bi1); + output[5] = static_cast<uint8_t>(bi0); + + return true; +} + +/** + * @brief Try to quantize an LDR RGBA color using blue-contraction. + * + * Blue-contraction is only usable if encoded color 1 RGB is larger than color 0 RGB. + * + * @param color0 The input unquantized color0 endpoint. + * @param color1 The input unquantized color1 endpoint. + * @param[out] output The output endpoints, returned as (r1, r0, g1, g0, b1, b0, a1, a0). + * @param quant_level The quantization level to use. + * + * @return Returns @c false on failure, @c true on success. + */ +static int try_quantize_rgba_blue_contract( + vfloat4 color0, + vfloat4 color1, + uint8_t output[8], + quant_method quant_level +) { + float scale = 1.0f / 257.0f; + + float a0 = astc::clamp255f(color0.lane<3>() * scale); + float a1 = astc::clamp255f(color1.lane<3>() * scale); + + output[6] = quant_color(quant_level, astc::flt2int_rtn(a1)); + output[7] = quant_color(quant_level, astc::flt2int_rtn(a0)); + + return try_quantize_rgb_blue_contract(color0, color1, output, quant_level); +} + +/** + * @brief Try to quantize an LDR RGB color using delta encoding. + * + * At decode time we move one bit from the offset to the base and seize another bit as a sign bit; + * we then unquantize both values as if they contain one extra bit. If the sum of the offsets is + * non-negative, then we encode a regular delta. + * + * @param color0 The input unquantized color0 endpoint. + * @param color1 The input unquantized color1 endpoint. + * @param[out] output The output endpoints, returned as (r0, r1, g0, g1, b0, b1). + * @param quant_level The quantization level to use. + * + * @return Returns @c false on failure, @c true on success. + */ +static bool try_quantize_rgb_delta( + vfloat4 color0, + vfloat4 color1, + uint8_t output[6], + quant_method quant_level +) { + float scale = 1.0f / 257.0f; + + float r0 = astc::clamp255f(color0.lane<0>() * scale); + float g0 = astc::clamp255f(color0.lane<1>() * scale); + float b0 = astc::clamp255f(color0.lane<2>() * scale); + + float r1 = astc::clamp255f(color1.lane<0>() * scale); + float g1 = astc::clamp255f(color1.lane<1>() * scale); + float b1 = astc::clamp255f(color1.lane<2>() * scale); + + // Transform r0 to unorm9 + int r0a = astc::flt2int_rtn(r0); + int g0a = astc::flt2int_rtn(g0); + int b0a = astc::flt2int_rtn(b0); + + r0a <<= 1; + g0a <<= 1; + b0a <<= 1; + + // Mask off the top bit + int r0b = r0a & 0xFF; + int g0b = g0a & 0xFF; + int b0b = b0a & 0xFF; + + // Quantize then unquantize in order to get a value that we take differences against + int r0be = quant_color(quant_level, r0b); + int g0be = quant_color(quant_level, g0b); + int b0be = quant_color(quant_level, b0b); + + r0b = r0be | (r0a & 0x100); + g0b = g0be | (g0a & 0x100); + b0b = b0be | (b0a & 0x100); + + // Get hold of the second value + int r1d = astc::flt2int_rtn(r1); + int g1d = astc::flt2int_rtn(g1); + int b1d = astc::flt2int_rtn(b1); + + r1d <<= 1; + g1d <<= 1; + b1d <<= 1; + + // ... and take differences + r1d -= r0b; + g1d -= g0b; + b1d -= b0b; + + // Check if the difference is too large to be encodable + if (r1d > 63 || g1d > 63 || b1d > 63 || r1d < -64 || g1d < -64 || b1d < -64) + { + return false; + } + + // Insert top bit of the base into the offset + r1d &= 0x7F; + g1d &= 0x7F; + b1d &= 0x7F; + + r1d |= (r0b & 0x100) >> 1; + g1d |= (g0b & 0x100) >> 1; + b1d |= (b0b & 0x100) >> 1; + + // Then quantize and unquantize; if this causes either top two bits to flip, then encoding fails + // since we have then corrupted either the top bit of the base or the sign bit of the offset + int r1de = quant_color(quant_level, r1d); + int g1de = quant_color(quant_level, g1d); + int b1de = quant_color(quant_level, b1d); + + if (((r1d ^ r1de) | (g1d ^ g1de) | (b1d ^ b1de)) & 0xC0) + { + return false; + } + + // If the sum of offsets triggers blue-contraction then encoding fails + vint4 ep0(r0be, g0be, b0be, 0); + vint4 ep1(r1de, g1de, b1de, 0); + bit_transfer_signed(ep1, ep0); + if (hadd_rgb_s(ep1) < 0) + { + return false; + } + + // Check that the offsets produce legitimate sums as well + ep0 = ep0 + ep1; + if (any((ep0 < vint4(0)) | (ep0 > vint4(0xFF)))) + { + return false; + } + + output[0] = static_cast<uint8_t>(r0be); + output[1] = static_cast<uint8_t>(r1de); + output[2] = static_cast<uint8_t>(g0be); + output[3] = static_cast<uint8_t>(g1de); + output[4] = static_cast<uint8_t>(b0be); + output[5] = static_cast<uint8_t>(b1de); + + return true; +} + +static bool try_quantize_rgb_delta_blue_contract( + vfloat4 color0, + vfloat4 color1, + uint8_t output[6], + quant_method quant_level +) { + // Note: Switch around endpoint colors already at start + float scale = 1.0f / 257.0f; + + float r1 = color0.lane<0>() * scale; + float g1 = color0.lane<1>() * scale; + float b1 = color0.lane<2>() * scale; + + float r0 = color1.lane<0>() * scale; + float g0 = color1.lane<1>() * scale; + float b0 = color1.lane<2>() * scale; + + // Apply inverse blue-contraction. This can produce an overflow; which means BC cannot be used. + r0 += (r0 - b0); + g0 += (g0 - b0); + r1 += (r1 - b1); + g1 += (g1 - b1); + + if (r0 < 0.0f || r0 > 255.0f || g0 < 0.0f || g0 > 255.0f || b0 < 0.0f || b0 > 255.0f || + r1 < 0.0f || r1 > 255.0f || g1 < 0.0f || g1 > 255.0f || b1 < 0.0f || b1 > 255.0f) + { + return false; + } + + // Transform r0 to unorm9 + int r0a = astc::flt2int_rtn(r0); + int g0a = astc::flt2int_rtn(g0); + int b0a = astc::flt2int_rtn(b0); + r0a <<= 1; + g0a <<= 1; + b0a <<= 1; + + // Mask off the top bit + int r0b = r0a & 0xFF; + int g0b = g0a & 0xFF; + int b0b = b0a & 0xFF; + + // Quantize, then unquantize in order to get a value that we take differences against. + int r0be = quant_color(quant_level, r0b); + int g0be = quant_color(quant_level, g0b); + int b0be = quant_color(quant_level, b0b); + + r0b = r0be | (r0a & 0x100); + g0b = g0be | (g0a & 0x100); + b0b = b0be | (b0a & 0x100); + + // Get hold of the second value + int r1d = astc::flt2int_rtn(r1); + int g1d = astc::flt2int_rtn(g1); + int b1d = astc::flt2int_rtn(b1); + + r1d <<= 1; + g1d <<= 1; + b1d <<= 1; + + // .. and take differences! + r1d -= r0b; + g1d -= g0b; + b1d -= b0b; + + // Check if the difference is too large to be encodable + if (r1d > 63 || g1d > 63 || b1d > 63 || r1d < -64 || g1d < -64 || b1d < -64) + { + return false; + } + + // Insert top bit of the base into the offset + r1d &= 0x7F; + g1d &= 0x7F; + b1d &= 0x7F; + + r1d |= (r0b & 0x100) >> 1; + g1d |= (g0b & 0x100) >> 1; + b1d |= (b0b & 0x100) >> 1; + + // Then quantize and unquantize; if this causes any of the top two bits to flip, + // then encoding fails, since we have then corrupted either the top bit of the base + // or the sign bit of the offset. + int r1de = quant_color(quant_level, r1d); + int g1de = quant_color(quant_level, g1d); + int b1de = quant_color(quant_level, b1d); + + if (((r1d ^ r1de) | (g1d ^ g1de) | (b1d ^ b1de)) & 0xC0) + { + return false; + } + + // If the sum of offsets does not trigger blue-contraction then encoding fails + vint4 ep0(r0be, g0be, b0be, 0); + vint4 ep1(r1de, g1de, b1de, 0); + bit_transfer_signed(ep1, ep0); + if (hadd_rgb_s(ep1) >= 0) + { + return false; + } + + // Check that the offsets produce legitimate sums as well + ep0 = ep0 + ep1; + if (any((ep0 < vint4(0)) | (ep0 > vint4(0xFF)))) + { + return false; + } + + output[0] = static_cast<uint8_t>(r0be); + output[1] = static_cast<uint8_t>(r1de); + output[2] = static_cast<uint8_t>(g0be); + output[3] = static_cast<uint8_t>(g1de); + output[4] = static_cast<uint8_t>(b0be); + output[5] = static_cast<uint8_t>(b1de); + + return true; +} + +/** + * @brief Try to quantize an LDR A color using delta encoding. + * + * At decode time we move one bit from the offset to the base and seize another bit as a sign bit; + * we then unquantize both values as if they contain one extra bit. If the sum of the offsets is + * non-negative, then we encode a regular delta. + * + * This function only compressed the alpha - the other elements in the output array are not touched. + * + * @param color0 The input unquantized color0 endpoint. + * @param color1 The input unquantized color1 endpoint. + * @param[out] output The output endpoints, returned as (x, x, x, x, x, x, a0, a1). + * @param quant_level The quantization level to use. + * + * @return Returns @c false on failure, @c true on success. + */ +static bool try_quantize_alpha_delta( + vfloat4 color0, + vfloat4 color1, + uint8_t output[8], + quant_method quant_level +) { + float scale = 1.0f / 257.0f; + + float a0 = astc::clamp255f(color0.lane<3>() * scale); + float a1 = astc::clamp255f(color1.lane<3>() * scale); + + int a0a = astc::flt2int_rtn(a0); + a0a <<= 1; + int a0b = a0a & 0xFF; + int a0be = quant_color(quant_level, a0b); + a0b = a0be; + a0b |= a0a & 0x100; + int a1d = astc::flt2int_rtn(a1); + a1d <<= 1; + a1d -= a0b; + + if (a1d > 63 || a1d < -64) + { + return false; + } + + a1d &= 0x7F; + a1d |= (a0b & 0x100) >> 1; + + int a1de = quant_color(quant_level, a1d); + int a1du = a1de; + if ((a1d ^ a1du) & 0xC0) + { + return false; + } + + a1du &= 0x7F; + if (a1du & 0x40) + { + a1du -= 0x80; + } + + a1du += a0b; + if (a1du < 0 || a1du > 0x1FF) + { + return false; + } + + output[6] = static_cast<uint8_t>(a0be); + output[7] = static_cast<uint8_t>(a1de); + + return true; +} + +/** + * @brief Try to quantize an LDR LA color using delta encoding. + * + * At decode time we move one bit from the offset to the base and seize another bit as a sign bit; + * we then unquantize both values as if they contain one extra bit. If the sum of the offsets is + * non-negative, then we encode a regular delta. + * + * This function only compressed the alpha - the other elements in the output array are not touched. + * + * @param color0 The input unquantized color0 endpoint. + * @param color1 The input unquantized color1 endpoint. + * @param[out] output The output endpoints, returned as (l0, l1, a0, a1). + * @param quant_level The quantization level to use. + * + * @return Returns @c false on failure, @c true on success. + */ +static bool try_quantize_luminance_alpha_delta( + vfloat4 color0, + vfloat4 color1, + uint8_t output[4], + quant_method quant_level +) { + float scale = 1.0f / 257.0f; + + float l0 = astc::clamp255f(hadd_rgb_s(color0) * ((1.0f / 3.0f) * scale)); + float l1 = astc::clamp255f(hadd_rgb_s(color1) * ((1.0f / 3.0f) * scale)); + + float a0 = astc::clamp255f(color0.lane<3>() * scale); + float a1 = astc::clamp255f(color1.lane<3>() * scale); + + int l0a = astc::flt2int_rtn(l0); + int a0a = astc::flt2int_rtn(a0); + l0a <<= 1; + a0a <<= 1; + + int l0b = l0a & 0xFF; + int a0b = a0a & 0xFF; + int l0be = quant_color(quant_level, l0b); + int a0be = quant_color(quant_level, a0b); + l0b = l0be; + a0b = a0be; + l0b |= l0a & 0x100; + a0b |= a0a & 0x100; + + int l1d = astc::flt2int_rtn(l1); + int a1d = astc::flt2int_rtn(a1); + l1d <<= 1; + a1d <<= 1; + l1d -= l0b; + a1d -= a0b; + + if (l1d > 63 || l1d < -64) + { + return false; + } + + if (a1d > 63 || a1d < -64) + { + return false; + } + + l1d &= 0x7F; + a1d &= 0x7F; + l1d |= (l0b & 0x100) >> 1; + a1d |= (a0b & 0x100) >> 1; + + int l1de = quant_color(quant_level, l1d); + int a1de = quant_color(quant_level, a1d); + int l1du = l1de; + int a1du = a1de; + + if ((l1d ^ l1du) & 0xC0) + { + return false; + } + + if ((a1d ^ a1du) & 0xC0) + { + return false; + } + + l1du &= 0x7F; + a1du &= 0x7F; + + if (l1du & 0x40) + { + l1du -= 0x80; + } + + if (a1du & 0x40) + { + a1du -= 0x80; + } + + l1du += l0b; + a1du += a0b; + + if (l1du < 0 || l1du > 0x1FF) + { + return false; + } + + if (a1du < 0 || a1du > 0x1FF) + { + return false; + } + + output[0] = static_cast<uint8_t>(l0be); + output[1] = static_cast<uint8_t>(l1de); + output[2] = static_cast<uint8_t>(a0be); + output[3] = static_cast<uint8_t>(a1de); + + return true; +} + +/** + * @brief Try to quantize an LDR RGBA color using delta encoding. + * + * At decode time we move one bit from the offset to the base and seize another bit as a sign bit; + * we then unquantize both values as if they contain one extra bit. If the sum of the offsets is + * non-negative, then we encode a regular delta. + * + * This function only compressed the alpha - the other elements in the output array are not touched. + * + * @param color0 The input unquantized color0 endpoint. + * @param color1 The input unquantized color1 endpoint. + * @param[out] output The output endpoints, returned as (r0, r1, b0, b1, g0, g1, a0, a1). + * @param quant_level The quantization level to use. + * + * @return Returns @c false on failure, @c true on success. + */ +static bool try_quantize_rgba_delta( + vfloat4 color0, + vfloat4 color1, + uint8_t output[8], + quant_method quant_level +) { + return try_quantize_rgb_delta(color0, color1, output, quant_level) && + try_quantize_alpha_delta(color0, color1, output, quant_level); +} + + +/** + * @brief Try to quantize an LDR RGBA color using delta and blue contract encoding. + * + * At decode time we move one bit from the offset to the base and seize another bit as a sign bit; + * we then unquantize both values as if they contain one extra bit. If the sum of the offsets is + * non-negative, then we encode a regular delta. + * + * This function only compressed the alpha - the other elements in the output array are not touched. + * + * @param color0 The input unquantized color0 endpoint. + * @param color1 The input unquantized color1 endpoint. + * @param[out] output The output endpoints, returned as (r0, r1, b0, b1, g0, g1, a0, a1). + * @param quant_level The quantization level to use. + * + * @return Returns @c false on failure, @c true on success. + */ +static bool try_quantize_rgba_delta_blue_contract( + vfloat4 color0, + vfloat4 color1, + uint8_t output[8], + quant_method quant_level +) { + // Note that we swap the color0 and color1 ordering for alpha to match RGB blue-contract + return try_quantize_rgb_delta_blue_contract(color0, color1, output, quant_level) && + try_quantize_alpha_delta(color1, color0, output, quant_level); +} + +/** + * @brief Quantize an LDR RGB color using scale encoding. + * + * @param color The input unquantized color endpoint and scale factor. + * @param[out] output The output endpoints, returned as (r0, g0, b0, s). + * @param quant_level The quantization level to use. + */ +static void quantize_rgbs( + vfloat4 color, + uint8_t output[4], + quant_method quant_level +) { + float scale = 1.0f / 257.0f; + + float r = astc::clamp255f(color.lane<0>() * scale); + float g = astc::clamp255f(color.lane<1>() * scale); + float b = astc::clamp255f(color.lane<2>() * scale); + + int ri = quant_color(quant_level, astc::flt2int_rtn(r)); + int gi = quant_color(quant_level, astc::flt2int_rtn(g)); + int bi = quant_color(quant_level, astc::flt2int_rtn(b)); + + float oldcolorsum = hadd_rgb_s(color) * scale; + float newcolorsum = static_cast<float>(ri + gi + bi); + + float scalea = astc::clamp1f(color.lane<3>() * (oldcolorsum + 1e-10f) / (newcolorsum + 1e-10f)); + int scale_idx = astc::flt2int_rtn(scalea * 256.0f); + scale_idx = astc::clamp(scale_idx, 0, 255); + + output[0] = static_cast<uint8_t>(ri); + output[1] = static_cast<uint8_t>(gi); + output[2] = static_cast<uint8_t>(bi); + output[3] = quant_color(quant_level, scale_idx); +} + +/** + * @brief Quantize an LDR RGBA color using scale encoding. + * + * @param color The input unquantized color endpoint and scale factor. + * @param[out] output The output endpoints, returned as (r0, g0, b0, s, a0, a1). + * @param quant_level The quantization level to use. + */ +static void quantize_rgbs_alpha( + vfloat4 color0, + vfloat4 color1, + vfloat4 color, + uint8_t output[6], + quant_method quant_level +) { + float scale = 1.0f / 257.0f; + + float a0 = astc::clamp255f(color0.lane<3>() * scale); + float a1 = astc::clamp255f(color1.lane<3>() * scale); + + output[4] = quant_color(quant_level, astc::flt2int_rtn(a0)); + output[5] = quant_color(quant_level, astc::flt2int_rtn(a1)); + + quantize_rgbs(color, output, quant_level); +} + +/** + * @brief Quantize a LDR L color. + * + * @param color0 The input unquantized color0 endpoint. + * @param color1 The input unquantized color1 endpoint. + * @param[out] output The output endpoints, returned as (l0, l1). + * @param quant_level The quantization level to use. + */ +static void quantize_luminance( + vfloat4 color0, + vfloat4 color1, + uint8_t output[2], + quant_method quant_level +) { + float scale = 1.0f / 257.0f; + + color0 = color0 * scale; + color1 = color1 * scale; + + float lum0 = astc::clamp255f(hadd_rgb_s(color0) * (1.0f / 3.0f)); + float lum1 = astc::clamp255f(hadd_rgb_s(color1) * (1.0f / 3.0f)); + + if (lum0 > lum1) + { + float avg = (lum0 + lum1) * 0.5f; + lum0 = avg; + lum1 = avg; + } + + output[0] = quant_color(quant_level, astc::flt2int_rtn(lum0)); + output[1] = quant_color(quant_level, astc::flt2int_rtn(lum1)); +} + +/** + * @brief Quantize a LDR LA color. + * + * @param color0 The input unquantized color0 endpoint. + * @param color1 The input unquantized color1 endpoint. + * @param[out] output The output endpoints, returned as (l0, l1, a0, a1). + * @param quant_level The quantization level to use. + */ +static void quantize_luminance_alpha( + vfloat4 color0, + vfloat4 color1, + uint8_t output[4], + quant_method quant_level +) { + float scale = 1.0f / 257.0f; + + color0 = color0 * scale; + color1 = color1 * scale; + + float lum0 = astc::clamp255f(hadd_rgb_s(color0) * (1.0f / 3.0f)); + float lum1 = astc::clamp255f(hadd_rgb_s(color1) * (1.0f / 3.0f)); + + float a0 = astc::clamp255f(color0.lane<3>()); + float a1 = astc::clamp255f(color1.lane<3>()); + + // If endpoints are close then pull apart slightly; this gives > 8 bit normal map precision. + if (quant_level > 18) + { + if (fabsf(lum0 - lum1) < 3.0f) + { + if (lum0 < lum1) + { + lum0 -= 0.5f; + lum1 += 0.5f; + } + else + { + lum0 += 0.5f; + lum1 -= 0.5f; + } + + lum0 = astc::clamp255f(lum0); + lum1 = astc::clamp255f(lum1); + } + + if (fabsf(a0 - a1) < 3.0f) + { + if (a0 < a1) + { + a0 -= 0.5f; + a1 += 0.5f; + } + else + { + a0 += 0.5f; + a1 -= 0.5f; + } + + a0 = astc::clamp255f(a0); + a1 = astc::clamp255f(a1); + } + } + + output[0] = quant_color(quant_level, astc::flt2int_rtn(lum0)); + output[1] = quant_color(quant_level, astc::flt2int_rtn(lum1)); + output[2] = quant_color(quant_level, astc::flt2int_rtn(a0)); + output[3] = quant_color(quant_level, astc::flt2int_rtn(a1)); +} + +/** + * @brief Quantize and unquantize a value ensuring top two bits are the same. + * + * @param quant_level The quantization level to use. + * @param value The input unquantized value. + * @param[out] quant_value The quantized value. + */ +static inline void quantize_and_unquantize_retain_top_two_bits( + quant_method quant_level, + uint8_t value, + uint8_t& quant_value +) { + int perform_loop; + uint8_t quantval; + + do + { + quantval = quant_color(quant_level, value); + + // Perform looping if the top two bits were modified by quant/unquant + perform_loop = (value & 0xC0) != (quantval & 0xC0); + + if ((quantval & 0xC0) > (value & 0xC0)) + { + // Quant/unquant rounded UP so that the top two bits changed; + // decrement the input in hopes that this will avoid rounding up. + value--; + } + else if ((quantval & 0xC0) < (value & 0xC0)) + { + // Quant/unquant rounded DOWN so that the top two bits changed; + // decrement the input in hopes that this will avoid rounding down. + value--; + } + } while (perform_loop); + + quant_value = quantval; +} + +/** + * @brief Quantize and unquantize a value ensuring top four bits are the same. + * + * @param quant_level The quantization level to use. + * @param value The input unquantized value. + * @param[out] quant_value The quantized value in 0-255 range. + */ +static inline void quantize_and_unquantize_retain_top_four_bits( + quant_method quant_level, + uint8_t value, + uint8_t& quant_value +) { + uint8_t perform_loop; + uint8_t quantval; + + do + { + quantval = quant_color(quant_level, value); + // Perform looping if the top four bits were modified by quant/unquant + perform_loop = (value & 0xF0) != (quantval & 0xF0); + + if ((quantval & 0xF0) > (value & 0xF0)) + { + // Quant/unquant rounded UP so that the top four bits changed; + // decrement the input value in hopes that this will avoid rounding up. + value--; + } + else if ((quantval & 0xF0) < (value & 0xF0)) + { + // Quant/unquant rounded DOWN so that the top four bits changed; + // decrement the input value in hopes that this will avoid rounding down. + value--; + } + } while (perform_loop); + + quant_value = quantval; +} + +/** + * @brief Quantize a HDR RGB color using RGB + offset. + * + * @param color The input unquantized color endpoint and offset. + * @param[out] output The output endpoints, returned as packed RGBS with some mode bits. + * @param quant_level The quantization level to use. + */ +static void quantize_hdr_rgbo( + vfloat4 color, + uint8_t output[4], + quant_method quant_level +) { + color.set_lane<0>(color.lane<0>() + color.lane<3>()); + color.set_lane<1>(color.lane<1>() + color.lane<3>()); + color.set_lane<2>(color.lane<2>() + color.lane<3>()); + + color = clamp(0.0f, 65535.0f, color); + + vfloat4 color_bak = color; + + int majcomp; + if (color.lane<0>() > color.lane<1>() && color.lane<0>() > color.lane<2>()) + { + majcomp = 0; // red is largest component + } + else if (color.lane<1>() > color.lane<2>()) + { + majcomp = 1; // green is largest component + } + else + { + majcomp = 2; // blue is largest component + } + + // swap around the red component and the largest component. + switch (majcomp) + { + case 1: + color = color.swz<1, 0, 2, 3>(); + break; + case 2: + color = color.swz<2, 1, 0, 3>(); + break; + default: + break; + } + + static const int mode_bits[5][3] { + {11, 5, 7}, + {11, 6, 5}, + {10, 5, 8}, + {9, 6, 7}, + {8, 7, 6} + }; + + static const float mode_cutoffs[5][2] { + {1024, 4096}, + {2048, 1024}, + {2048, 16384}, + {8192, 16384}, + {32768, 16384} + }; + + static const float mode_rscales[5] { + 32.0f, + 32.0f, + 64.0f, + 128.0f, + 256.0f, + }; + + static const float mode_scales[5] { + 1.0f / 32.0f, + 1.0f / 32.0f, + 1.0f / 64.0f, + 1.0f / 128.0f, + 1.0f / 256.0f, + }; + + float r_base = color.lane<0>(); + float g_base = color.lane<0>() - color.lane<1>() ; + float b_base = color.lane<0>() - color.lane<2>() ; + float s_base = color.lane<3>() ; + + for (int mode = 0; mode < 5; mode++) + { + if (g_base > mode_cutoffs[mode][0] || b_base > mode_cutoffs[mode][0] || s_base > mode_cutoffs[mode][1]) + { + continue; + } + + // Encode the mode into a 4-bit vector + int mode_enc = mode < 4 ? (mode | (majcomp << 2)) : (majcomp | 0xC); + + float mode_scale = mode_scales[mode]; + float mode_rscale = mode_rscales[mode]; + + int gb_intcutoff = 1 << mode_bits[mode][1]; + int s_intcutoff = 1 << mode_bits[mode][2]; + + // Quantize and unquantize R + int r_intval = astc::flt2int_rtn(r_base * mode_scale); + + int r_lowbits = r_intval & 0x3f; + + r_lowbits |= (mode_enc & 3) << 6; + + uint8_t r_quantval; + quantize_and_unquantize_retain_top_two_bits( + quant_level, static_cast<uint8_t>(r_lowbits), r_quantval); + + r_intval = (r_intval & ~0x3f) | (r_quantval & 0x3f); + float r_fval = static_cast<float>(r_intval) * mode_rscale; + + // Recompute G and B, then quantize and unquantize them + float g_fval = r_fval - color.lane<1>() ; + float b_fval = r_fval - color.lane<2>() ; + + g_fval = astc::clamp(g_fval, 0.0f, 65535.0f); + b_fval = astc::clamp(b_fval, 0.0f, 65535.0f); + + int g_intval = astc::flt2int_rtn(g_fval * mode_scale); + int b_intval = astc::flt2int_rtn(b_fval * mode_scale); + + if (g_intval >= gb_intcutoff || b_intval >= gb_intcutoff) + { + continue; + } + + int g_lowbits = g_intval & 0x1f; + int b_lowbits = b_intval & 0x1f; + + int bit0 = 0; + int bit1 = 0; + int bit2 = 0; + int bit3 = 0; + + switch (mode) + { + case 0: + case 2: + bit0 = (r_intval >> 9) & 1; + break; + case 1: + case 3: + bit0 = (r_intval >> 8) & 1; + break; + case 4: + case 5: + bit0 = (g_intval >> 6) & 1; + break; + } + + switch (mode) + { + case 0: + case 1: + case 2: + case 3: + bit2 = (r_intval >> 7) & 1; + break; + case 4: + case 5: + bit2 = (b_intval >> 6) & 1; + break; + } + + switch (mode) + { + case 0: + case 2: + bit1 = (r_intval >> 8) & 1; + break; + case 1: + case 3: + case 4: + case 5: + bit1 = (g_intval >> 5) & 1; + break; + } + + switch (mode) + { + case 0: + bit3 = (r_intval >> 10) & 1; + break; + case 2: + bit3 = (r_intval >> 6) & 1; + break; + case 1: + case 3: + case 4: + case 5: + bit3 = (b_intval >> 5) & 1; + break; + } + + g_lowbits |= (mode_enc & 0x4) << 5; + b_lowbits |= (mode_enc & 0x8) << 4; + + g_lowbits |= bit0 << 6; + g_lowbits |= bit1 << 5; + b_lowbits |= bit2 << 6; + b_lowbits |= bit3 << 5; + + uint8_t g_quantval; + uint8_t b_quantval; + + quantize_and_unquantize_retain_top_four_bits( + quant_level, static_cast<uint8_t>(g_lowbits), g_quantval); + quantize_and_unquantize_retain_top_four_bits( + quant_level, static_cast<uint8_t>(b_lowbits), b_quantval); + + g_intval = (g_intval & ~0x1f) | (g_quantval & 0x1f); + b_intval = (b_intval & ~0x1f) | (b_quantval & 0x1f); + + g_fval = static_cast<float>(g_intval) * mode_rscale; + b_fval = static_cast<float>(b_intval) * mode_rscale; + + // Recompute the scale value, based on the errors introduced to red, green and blue + + // If the error is positive, then the R,G,B errors combined have raised the color + // value overall; as such, the scale value needs to be increased. + float rgb_errorsum = (r_fval - color.lane<0>() ) + (r_fval - g_fval - color.lane<1>() ) + (r_fval - b_fval - color.lane<2>() ); + + float s_fval = s_base + rgb_errorsum * (1.0f / 3.0f); + s_fval = astc::clamp(s_fval, 0.0f, 1e9f); + + int s_intval = astc::flt2int_rtn(s_fval * mode_scale); + + if (s_intval >= s_intcutoff) + { + continue; + } + + int s_lowbits = s_intval & 0x1f; + + int bit4; + int bit5; + int bit6; + switch (mode) + { + case 1: + bit6 = (r_intval >> 9) & 1; + break; + default: + bit6 = (s_intval >> 5) & 1; + break; + } + + switch (mode) + { + case 4: + bit5 = (r_intval >> 7) & 1; + break; + case 1: + bit5 = (r_intval >> 10) & 1; + break; + default: + bit5 = (s_intval >> 6) & 1; + break; + } + + switch (mode) + { + case 2: + bit4 = (s_intval >> 7) & 1; + break; + default: + bit4 = (r_intval >> 6) & 1; + break; + } + + s_lowbits |= bit6 << 5; + s_lowbits |= bit5 << 6; + s_lowbits |= bit4 << 7; + + uint8_t s_quantval; + + quantize_and_unquantize_retain_top_four_bits( + quant_level, static_cast<uint8_t>(s_lowbits), s_quantval); + + output[0] = r_quantval; + output[1] = g_quantval; + output[2] = b_quantval; + output[3] = s_quantval; + return; + } + + // Failed to encode any of the modes above? In that case encode using mode #5 + float vals[4]; + vals[0] = color_bak.lane<0>(); + vals[1] = color_bak.lane<1>(); + vals[2] = color_bak.lane<2>(); + vals[3] = color_bak.lane<3>(); + + int ivals[4]; + float cvals[3]; + + for (int i = 0; i < 3; i++) + { + vals[i] = astc::clamp(vals[i], 0.0f, 65020.0f); + ivals[i] = astc::flt2int_rtn(vals[i] * (1.0f / 512.0f)); + cvals[i] = static_cast<float>(ivals[i]) * 512.0f; + } + + float rgb_errorsum = (cvals[0] - vals[0]) + (cvals[1] - vals[1]) + (cvals[2] - vals[2]); + vals[3] += rgb_errorsum * (1.0f / 3.0f); + + vals[3] = astc::clamp(vals[3], 0.0f, 65020.0f); + ivals[3] = astc::flt2int_rtn(vals[3] * (1.0f / 512.0f)); + + int encvals[4]; + encvals[0] = (ivals[0] & 0x3f) | 0xC0; + encvals[1] = (ivals[1] & 0x7f) | 0x80; + encvals[2] = (ivals[2] & 0x7f) | 0x80; + encvals[3] = (ivals[3] & 0x7f) | ((ivals[0] & 0x40) << 1); + + for (uint8_t i = 0; i < 4; i++) + { + quantize_and_unquantize_retain_top_four_bits( + quant_level, static_cast<uint8_t>(encvals[i]), output[i]); + } + + return; +} + +/** + * @brief Quantize a HDR RGB color using direct RGB encoding. + * + * @param color0 The input unquantized color0 endpoint. + * @param color1 The input unquantized color1 endpoint. + * @param[out] output The output endpoints, returned as packed RGB+RGB pairs with mode bits. + * @param quant_level The quantization level to use. + */ +static void quantize_hdr_rgb( + vfloat4 color0, + vfloat4 color1, + uint8_t output[6], + quant_method quant_level +) { + // Note: color*.lane<3> is not used so we can ignore it + color0 = clamp(0.0f, 65535.0f, color0); + color1 = clamp(0.0f, 65535.0f, color1); + + vfloat4 color0_bak = color0; + vfloat4 color1_bak = color1; + + int majcomp; + if (color1.lane<0>() > color1.lane<1>() && color1.lane<0>() > color1.lane<2>()) + { + majcomp = 0; + } + else if (color1.lane<1>() > color1.lane<2>()) + { + majcomp = 1; + } + else + { + majcomp = 2; + } + + // Swizzle the components + switch (majcomp) + { + case 1: // red-green swap + color0 = color0.swz<1, 0, 2, 3>(); + color1 = color1.swz<1, 0, 2, 3>(); + break; + case 2: // red-blue swap + color0 = color0.swz<2, 1, 0, 3>(); + color1 = color1.swz<2, 1, 0, 3>(); + break; + default: + break; + } + + float a_base = color1.lane<0>(); + a_base = astc::clamp(a_base, 0.0f, 65535.0f); + + float b0_base = a_base - color1.lane<1>(); + float b1_base = a_base - color1.lane<2>(); + float c_base = a_base - color0.lane<0>(); + float d0_base = a_base - b0_base - c_base - color0.lane<1>(); + float d1_base = a_base - b1_base - c_base - color0.lane<2>(); + + // Number of bits in the various fields in the various modes + static const int mode_bits[8][4] { + {9, 7, 6, 7}, + {9, 8, 6, 6}, + {10, 6, 7, 7}, + {10, 7, 7, 6}, + {11, 8, 6, 5}, + {11, 6, 8, 6}, + {12, 7, 7, 5}, + {12, 6, 7, 6} + }; + + // Cutoffs to use for the computed values of a,b,c,d, assuming the + // range 0..65535 are LNS values corresponding to fp16. + static const float mode_cutoffs[8][4] { + {16384, 8192, 8192, 8}, // mode 0: 9,7,6,7 + {32768, 8192, 4096, 8}, // mode 1: 9,8,6,6 + {4096, 8192, 4096, 4}, // mode 2: 10,6,7,7 + {8192, 8192, 2048, 4}, // mode 3: 10,7,7,6 + {8192, 2048, 512, 2}, // mode 4: 11,8,6,5 + {2048, 8192, 1024, 2}, // mode 5: 11,6,8,6 + {2048, 2048, 256, 1}, // mode 6: 12,7,7,5 + {1024, 2048, 512, 1}, // mode 7: 12,6,7,6 + }; + + static const float mode_scales[8] { + 1.0f / 128.0f, + 1.0f / 128.0f, + 1.0f / 64.0f, + 1.0f / 64.0f, + 1.0f / 32.0f, + 1.0f / 32.0f, + 1.0f / 16.0f, + 1.0f / 16.0f, + }; + + // Scaling factors when going from what was encoded in the mode to 16 bits. + static const float mode_rscales[8] { + 128.0f, + 128.0f, + 64.0f, + 64.0f, + 32.0f, + 32.0f, + 16.0f, + 16.0f + }; + + // Try modes one by one, with the highest-precision mode first. + for (int mode = 7; mode >= 0; mode--) + { + // For each mode, test if we can in fact accommodate the computed b, c, and d values. + // If we clearly can't, then we skip to the next mode. + + float b_cutoff = mode_cutoffs[mode][0]; + float c_cutoff = mode_cutoffs[mode][1]; + float d_cutoff = mode_cutoffs[mode][2]; + + if (b0_base > b_cutoff || b1_base > b_cutoff || c_base > c_cutoff || fabsf(d0_base) > d_cutoff || fabsf(d1_base) > d_cutoff) + { + continue; + } + + float mode_scale = mode_scales[mode]; + float mode_rscale = mode_rscales[mode]; + + int b_intcutoff = 1 << mode_bits[mode][1]; + int c_intcutoff = 1 << mode_bits[mode][2]; + int d_intcutoff = 1 << (mode_bits[mode][3] - 1); + + // Quantize and unquantize A, with the assumption that its high bits can be handled safely. + int a_intval = astc::flt2int_rtn(a_base * mode_scale); + int a_lowbits = a_intval & 0xFF; + + int a_quantval = quant_color(quant_level, a_lowbits); + int a_uquantval = a_quantval; + a_intval = (a_intval & ~0xFF) | a_uquantval; + float a_fval = static_cast<float>(a_intval) * mode_rscale; + + // Recompute C, then quantize and unquantize it + float c_fval = a_fval - color0.lane<0>(); + c_fval = astc::clamp(c_fval, 0.0f, 65535.0f); + + int c_intval = astc::flt2int_rtn(c_fval * mode_scale); + + if (c_intval >= c_intcutoff) + { + continue; + } + + int c_lowbits = c_intval & 0x3f; + + c_lowbits |= (mode & 1) << 7; + c_lowbits |= (a_intval & 0x100) >> 2; + + uint8_t c_quantval; + + quantize_and_unquantize_retain_top_two_bits( + quant_level, static_cast<uint8_t>(c_lowbits), c_quantval); + + c_intval = (c_intval & ~0x3F) | (c_quantval & 0x3F); + c_fval = static_cast<float>(c_intval) * mode_rscale; + + // Recompute B0 and B1, then quantize and unquantize them + float b0_fval = a_fval - color1.lane<1>(); + float b1_fval = a_fval - color1.lane<2>(); + + b0_fval = astc::clamp(b0_fval, 0.0f, 65535.0f); + b1_fval = astc::clamp(b1_fval, 0.0f, 65535.0f); + int b0_intval = astc::flt2int_rtn(b0_fval * mode_scale); + int b1_intval = astc::flt2int_rtn(b1_fval * mode_scale); + + if (b0_intval >= b_intcutoff || b1_intval >= b_intcutoff) + { + continue; + } + + int b0_lowbits = b0_intval & 0x3f; + int b1_lowbits = b1_intval & 0x3f; + + int bit0 = 0; + int bit1 = 0; + switch (mode) + { + case 0: + case 1: + case 3: + case 4: + case 6: + bit0 = (b0_intval >> 6) & 1; + break; + case 2: + case 5: + case 7: + bit0 = (a_intval >> 9) & 1; + break; + } + + switch (mode) + { + case 0: + case 1: + case 3: + case 4: + case 6: + bit1 = (b1_intval >> 6) & 1; + break; + case 2: + bit1 = (c_intval >> 6) & 1; + break; + case 5: + case 7: + bit1 = (a_intval >> 10) & 1; + break; + } + + b0_lowbits |= bit0 << 6; + b1_lowbits |= bit1 << 6; + + b0_lowbits |= ((mode >> 1) & 1) << 7; + b1_lowbits |= ((mode >> 2) & 1) << 7; + + uint8_t b0_quantval; + uint8_t b1_quantval; + + quantize_and_unquantize_retain_top_two_bits( + quant_level, static_cast<uint8_t>(b0_lowbits), b0_quantval); + quantize_and_unquantize_retain_top_two_bits( + quant_level, static_cast<uint8_t>(b1_lowbits), b1_quantval); + + b0_intval = (b0_intval & ~0x3f) | (b0_quantval & 0x3f); + b1_intval = (b1_intval & ~0x3f) | (b1_quantval & 0x3f); + b0_fval = static_cast<float>(b0_intval) * mode_rscale; + b1_fval = static_cast<float>(b1_intval) * mode_rscale; + + // Recompute D0 and D1, then quantize and unquantize them + float d0_fval = a_fval - b0_fval - c_fval - color0.lane<1>(); + float d1_fval = a_fval - b1_fval - c_fval - color0.lane<2>(); + + d0_fval = astc::clamp(d0_fval, -65535.0f, 65535.0f); + d1_fval = astc::clamp(d1_fval, -65535.0f, 65535.0f); + + int d0_intval = astc::flt2int_rtn(d0_fval * mode_scale); + int d1_intval = astc::flt2int_rtn(d1_fval * mode_scale); + + if (abs(d0_intval) >= d_intcutoff || abs(d1_intval) >= d_intcutoff) + { + continue; + } + + int d0_lowbits = d0_intval & 0x1f; + int d1_lowbits = d1_intval & 0x1f; + + int bit2 = 0; + int bit3 = 0; + int bit4; + int bit5; + switch (mode) + { + case 0: + case 2: + bit2 = (d0_intval >> 6) & 1; + break; + case 1: + case 4: + bit2 = (b0_intval >> 7) & 1; + break; + case 3: + bit2 = (a_intval >> 9) & 1; + break; + case 5: + bit2 = (c_intval >> 7) & 1; + break; + case 6: + case 7: + bit2 = (a_intval >> 11) & 1; + break; + } + switch (mode) + { + case 0: + case 2: + bit3 = (d1_intval >> 6) & 1; + break; + case 1: + case 4: + bit3 = (b1_intval >> 7) & 1; + break; + case 3: + case 5: + case 6: + case 7: + bit3 = (c_intval >> 6) & 1; + break; + } + + switch (mode) + { + case 4: + case 6: + bit4 = (a_intval >> 9) & 1; + bit5 = (a_intval >> 10) & 1; + break; + default: + bit4 = (d0_intval >> 5) & 1; + bit5 = (d1_intval >> 5) & 1; + break; + } + + d0_lowbits |= bit2 << 6; + d1_lowbits |= bit3 << 6; + d0_lowbits |= bit4 << 5; + d1_lowbits |= bit5 << 5; + + d0_lowbits |= (majcomp & 1) << 7; + d1_lowbits |= ((majcomp >> 1) & 1) << 7; + + uint8_t d0_quantval; + uint8_t d1_quantval; + + quantize_and_unquantize_retain_top_four_bits( + quant_level, static_cast<uint8_t>(d0_lowbits), d0_quantval); + quantize_and_unquantize_retain_top_four_bits( + quant_level, static_cast<uint8_t>(d1_lowbits), d1_quantval); + + output[0] = static_cast<uint8_t>(a_quantval); + output[1] = c_quantval; + output[2] = b0_quantval; + output[3] = b1_quantval; + output[4] = d0_quantval; + output[5] = d1_quantval; + return; + } + + // If neither of the modes fit we will use a flat representation for storing data, using 8 bits + // for red and green, and 7 bits for blue. This gives color accuracy roughly similar to LDR + // 4:4:3 which is not at all great but usable. This representation is used if the light color is + // more than 4x the color value of the dark color. + float vals[6]; + vals[0] = color0_bak.lane<0>(); + vals[1] = color1_bak.lane<0>(); + vals[2] = color0_bak.lane<1>(); + vals[3] = color1_bak.lane<1>(); + vals[4] = color0_bak.lane<2>(); + vals[5] = color1_bak.lane<2>(); + + for (int i = 0; i < 6; i++) + { + vals[i] = astc::clamp(vals[i], 0.0f, 65020.0f); + } + + for (int i = 0; i < 4; i++) + { + int idx = astc::flt2int_rtn(vals[i] * 1.0f / 256.0f); + output[i] = quant_color(quant_level, idx); + } + + for (int i = 4; i < 6; i++) + { + int idx = astc::flt2int_rtn(vals[i] * 1.0f / 512.0f) + 128; + quantize_and_unquantize_retain_top_two_bits( + quant_level, static_cast<uint8_t>(idx), output[i]); + } + + return; +} + +/** + * @brief Quantize a HDR RGB + LDR A color using direct RGBA encoding. + * + * @param color0 The input unquantized color0 endpoint. + * @param color1 The input unquantized color1 endpoint. + * @param[out] output The output endpoints, returned as packed RGBA+RGBA pairs with mode bits. + * @param quant_level The quantization level to use. + */ +static void quantize_hdr_rgb_ldr_alpha( + vfloat4 color0, + vfloat4 color1, + uint8_t output[8], + quant_method quant_level +) { + float scale = 1.0f / 257.0f; + + float a0 = astc::clamp255f(color0.lane<3>() * scale); + float a1 = astc::clamp255f(color1.lane<3>() * scale); + + output[6] = quant_color(quant_level, astc::flt2int_rtn(a0)); + output[7] = quant_color(quant_level, astc::flt2int_rtn(a1)); + + quantize_hdr_rgb(color0, color1, output, quant_level); +} + +/** + * @brief Quantize a HDR L color using the large range encoding. + * + * @param color0 The input unquantized color0 endpoint. + * @param color1 The input unquantized color1 endpoint. + * @param[out] output The output endpoints, returned as packed (l0, l1). + * @param quant_level The quantization level to use. + */ +static void quantize_hdr_luminance_large_range( + vfloat4 color0, + vfloat4 color1, + uint8_t output[2], + quant_method quant_level +) { + float lum0 = hadd_rgb_s(color0) * (1.0f / 3.0f); + float lum1 = hadd_rgb_s(color1) * (1.0f / 3.0f); + + if (lum1 < lum0) + { + float avg = (lum0 + lum1) * 0.5f; + lum0 = avg; + lum1 = avg; + } + + int ilum1 = astc::flt2int_rtn(lum1); + int ilum0 = astc::flt2int_rtn(lum0); + + // Find the closest encodable point in the upper half of the code-point space + int upper_v0 = (ilum0 + 128) >> 8; + int upper_v1 = (ilum1 + 128) >> 8; + + upper_v0 = astc::clamp(upper_v0, 0, 255); + upper_v1 = astc::clamp(upper_v1, 0, 255); + + // Find the closest encodable point in the lower half of the code-point space + int lower_v0 = (ilum1 + 256) >> 8; + int lower_v1 = ilum0 >> 8; + + lower_v0 = astc::clamp(lower_v0, 0, 255); + lower_v1 = astc::clamp(lower_v1, 0, 255); + + // Determine the distance between the point in code-point space and the input value + int upper0_dec = upper_v0 << 8; + int upper1_dec = upper_v1 << 8; + int lower0_dec = (lower_v1 << 8) + 128; + int lower1_dec = (lower_v0 << 8) - 128; + + int upper0_diff = upper0_dec - ilum0; + int upper1_diff = upper1_dec - ilum1; + int lower0_diff = lower0_dec - ilum0; + int lower1_diff = lower1_dec - ilum1; + + int upper_error = (upper0_diff * upper0_diff) + (upper1_diff * upper1_diff); + int lower_error = (lower0_diff * lower0_diff) + (lower1_diff * lower1_diff); + + int v0, v1; + if (upper_error < lower_error) + { + v0 = upper_v0; + v1 = upper_v1; + } + else + { + v0 = lower_v0; + v1 = lower_v1; + } + + // OK; encode + output[0] = quant_color(quant_level, v0); + output[1] = quant_color(quant_level, v1); +} + +/** + * @brief Quantize a HDR L color using the small range encoding. + * + * @param color0 The input unquantized color0 endpoint. + * @param color1 The input unquantized color1 endpoint. + * @param[out] output The output endpoints, returned as packed (l0, l1) with mode bits. + * @param quant_level The quantization level to use. + * + * @return Returns @c false on failure, @c true on success. + */ +static bool try_quantize_hdr_luminance_small_range( + vfloat4 color0, + vfloat4 color1, + uint8_t output[2], + quant_method quant_level +) { + float lum0 = hadd_rgb_s(color0) * (1.0f / 3.0f); + float lum1 = hadd_rgb_s(color1) * (1.0f / 3.0f); + + if (lum1 < lum0) + { + float avg = (lum0 + lum1) * 0.5f; + lum0 = avg; + lum1 = avg; + } + + int ilum1 = astc::flt2int_rtn(lum1); + int ilum0 = astc::flt2int_rtn(lum0); + + // Difference of more than a factor-of-2 results in immediate failure + if (ilum1 - ilum0 > 2048) + { + return false; + } + + int lowval, highval, diffval; + int v0, v1; + int v0e, v1e; + int v0d, v1d; + + // Try to encode the high-precision submode + lowval = (ilum0 + 16) >> 5; + highval = (ilum1 + 16) >> 5; + + lowval = astc::clamp(lowval, 0, 2047); + highval = astc::clamp(highval, 0, 2047); + + v0 = lowval & 0x7F; + v0e = quant_color(quant_level, v0); + v0d = v0e; + + if (v0d < 0x80) + { + lowval = (lowval & ~0x7F) | v0d; + diffval = highval - lowval; + if (diffval >= 0 && diffval <= 15) + { + v1 = ((lowval >> 3) & 0xF0) | diffval; + v1e = quant_color(quant_level, v1); + v1d = v1e; + if ((v1d & 0xF0) == (v1 & 0xF0)) + { + output[0] = static_cast<uint8_t>(v0e); + output[1] = static_cast<uint8_t>(v1e); + return true; + } + } + } + + // Try to encode the low-precision submode + lowval = (ilum0 + 32) >> 6; + highval = (ilum1 + 32) >> 6; + + lowval = astc::clamp(lowval, 0, 1023); + highval = astc::clamp(highval, 0, 1023); + + v0 = (lowval & 0x7F) | 0x80; + v0e = quant_color(quant_level, v0); + v0d = v0e; + if ((v0d & 0x80) == 0) + { + return false; + } + + lowval = (lowval & ~0x7F) | (v0d & 0x7F); + diffval = highval - lowval; + if (diffval < 0 || diffval > 31) + { + return false; + } + + v1 = ((lowval >> 2) & 0xE0) | diffval; + v1e = quant_color(quant_level, v1); + v1d = v1e; + if ((v1d & 0xE0) != (v1 & 0xE0)) + { + return false; + } + + output[0] = static_cast<uint8_t>(v0e); + output[1] = static_cast<uint8_t>(v1e); + return true; +} + +/** + * @brief Quantize a HDR A color using either delta or direct RGBA encoding. + * + * @param alpha0 The input unquantized color0 endpoint. + * @param alpha1 The input unquantized color1 endpoint. + * @param[out] output The output endpoints, returned as packed RGBA+RGBA pairs with mode bits. + * @param quant_level The quantization level to use. + */ +static void quantize_hdr_alpha( + float alpha0, + float alpha1, + uint8_t output[2], + quant_method quant_level +) { + alpha0 = astc::clamp(alpha0, 0.0f, 65280.0f); + alpha1 = astc::clamp(alpha1, 0.0f, 65280.0f); + + int ialpha0 = astc::flt2int_rtn(alpha0); + int ialpha1 = astc::flt2int_rtn(alpha1); + + int val0, val1, diffval; + int v6, v7; + int v6e, v7e; + int v6d, v7d; + + // Try to encode one of the delta submodes, in decreasing-precision order + for (int i = 2; i >= 0; i--) + { + val0 = (ialpha0 + (128 >> i)) >> (8 - i); + val1 = (ialpha1 + (128 >> i)) >> (8 - i); + + v6 = (val0 & 0x7F) | ((i & 1) << 7); + v6e = quant_color(quant_level, v6); + v6d = v6e; + + if ((v6 ^ v6d) & 0x80) + { + continue; + } + + val0 = (val0 & ~0x7f) | (v6d & 0x7f); + diffval = val1 - val0; + int cutoff = 32 >> i; + int mask = 2 * cutoff - 1; + + if (diffval < -cutoff || diffval >= cutoff) + { + continue; + } + + v7 = ((i & 2) << 6) | ((val0 >> 7) << (6 - i)) | (diffval & mask); + v7e = quant_color(quant_level, v7); + v7d = v7e; + + static const int testbits[3] { 0xE0, 0xF0, 0xF8 }; + + if ((v7 ^ v7d) & testbits[i]) + { + continue; + } + + output[0] = static_cast<uint8_t>(v6e); + output[1] = static_cast<uint8_t>(v7e); + return; + } + + // Could not encode any of the delta modes; instead encode a flat value + val0 = (ialpha0 + 256) >> 9; + val1 = (ialpha1 + 256) >> 9; + v6 = val0 | 0x80; + v7 = val1 | 0x80; + + output[0] = quant_color(quant_level, v6); + output[1] = quant_color(quant_level, v7); + + return; +} + +/** + * @brief Quantize a HDR RGBA color using either delta or direct RGBA encoding. + * + * @param color0 The input unquantized color0 endpoint. + * @param color1 The input unquantized color1 endpoint. + * @param[out] output The output endpoints, returned as packed RGBA+RGBA pairs with mode bits. + * @param quant_level The quantization level to use. + */ +static void quantize_hdr_rgb_alpha( + vfloat4 color0, + vfloat4 color1, + uint8_t output[8], + quant_method quant_level +) { + quantize_hdr_rgb(color0, color1, output, quant_level); + quantize_hdr_alpha(color0.lane<3>(), color1.lane<3>(), output + 6, quant_level); +} + +/* See header for documentation. */ +uint8_t pack_color_endpoints( + vfloat4 color0, + vfloat4 color1, + vfloat4 rgbs_color, + vfloat4 rgbo_color, + int format, + uint8_t* output, + quant_method quant_level +) { + assert(QUANT_6 <= quant_level && quant_level <= QUANT_256); + + // We do not support negative colors + color0 = max(color0, 0.0f); + color1 = max(color1, 0.0f); + + uint8_t retval = 0; + + switch (format) + { + case FMT_RGB: + if (quant_level <= QUANT_160) + { + if (try_quantize_rgb_delta_blue_contract(color0, color1, output, quant_level)) + { + retval = FMT_RGB_DELTA; + break; + } + if (try_quantize_rgb_delta(color0, color1, output, quant_level)) + { + retval = FMT_RGB_DELTA; + break; + } + } + if (quant_level < QUANT_256 && try_quantize_rgb_blue_contract(color0, color1, output, quant_level)) + { + retval = FMT_RGB; + break; + } + quantize_rgb(color0, color1, output, quant_level); + retval = FMT_RGB; + break; + + case FMT_RGBA: + if (quant_level <= QUANT_160) + { + if (try_quantize_rgba_delta_blue_contract(color0, color1, output, quant_level)) + { + retval = FMT_RGBA_DELTA; + break; + } + if (try_quantize_rgba_delta(color0, color1, output, quant_level)) + { + retval = FMT_RGBA_DELTA; + break; + } + } + if (quant_level < QUANT_256 && try_quantize_rgba_blue_contract(color0, color1, output, quant_level)) + { + retval = FMT_RGBA; + break; + } + quantize_rgba(color0, color1, output, quant_level); + retval = FMT_RGBA; + break; + + case FMT_RGB_SCALE: + quantize_rgbs(rgbs_color, output, quant_level); + retval = FMT_RGB_SCALE; + break; + + case FMT_HDR_RGB_SCALE: + quantize_hdr_rgbo(rgbo_color, output, quant_level); + retval = FMT_HDR_RGB_SCALE; + break; + + case FMT_HDR_RGB: + quantize_hdr_rgb(color0, color1, output, quant_level); + retval = FMT_HDR_RGB; + break; + + case FMT_RGB_SCALE_ALPHA: + quantize_rgbs_alpha(color0, color1, rgbs_color, output, quant_level); + retval = FMT_RGB_SCALE_ALPHA; + break; + + case FMT_HDR_LUMINANCE_SMALL_RANGE: + case FMT_HDR_LUMINANCE_LARGE_RANGE: + if (try_quantize_hdr_luminance_small_range(color0, color1, output, quant_level)) + { + retval = FMT_HDR_LUMINANCE_SMALL_RANGE; + break; + } + quantize_hdr_luminance_large_range(color0, color1, output, quant_level); + retval = FMT_HDR_LUMINANCE_LARGE_RANGE; + break; + + case FMT_LUMINANCE: + quantize_luminance(color0, color1, output, quant_level); + retval = FMT_LUMINANCE; + break; + + case FMT_LUMINANCE_ALPHA: + if (quant_level <= 18) + { + if (try_quantize_luminance_alpha_delta(color0, color1, output, quant_level)) + { + retval = FMT_LUMINANCE_ALPHA_DELTA; + break; + } + } + quantize_luminance_alpha(color0, color1, output, quant_level); + retval = FMT_LUMINANCE_ALPHA; + break; + + case FMT_HDR_RGB_LDR_ALPHA: + quantize_hdr_rgb_ldr_alpha(color0, color1, output, quant_level); + retval = FMT_HDR_RGB_LDR_ALPHA; + break; + + case FMT_HDR_RGBA: + quantize_hdr_rgb_alpha(color0, color1, output, quant_level); + retval = FMT_HDR_RGBA; + break; + } + + return retval; +} + +#endif diff --git a/thirdparty/astcenc/astcenc_color_unquantize.cpp b/thirdparty/astcenc/astcenc_color_unquantize.cpp new file mode 100644 index 0000000000..d31895a627 --- /dev/null +++ b/thirdparty/astcenc/astcenc_color_unquantize.cpp @@ -0,0 +1,941 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2021 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +#include <utility> + +/** + * @brief Functions for color unquantization. + */ + +#include "astcenc_internal.h" + +/** + * @brief Un-blue-contract a color. + * + * This function reverses any applied blue contraction. + * + * @param input The input color that has been blue-contracted. + * + * @return The uncontracted color. + */ +static ASTCENC_SIMD_INLINE vint4 uncontract_color( + vint4 input +) { + vmask4 mask(true, true, false, false); + vint4 bc0 = asr<1>(input + input.lane<2>()); + return select(input, bc0, mask); +} + +/** + * @brief Unpack an LDR RGBA color that uses delta encoding. + * + * @param input0 The packed endpoint 0 color. + * @param input1 The packed endpoint 1 color deltas. + * @param[out] output0 The unpacked endpoint 0 color. + * @param[out] output1 The unpacked endpoint 1 color. + */ +static void rgba_delta_unpack( + vint4 input0, + vint4 input1, + vint4& output0, + vint4& output1 +) { + // Apply bit transfer + bit_transfer_signed(input1, input0); + + // Apply blue-uncontraction if needed + int rgb_sum = hadd_rgb_s(input1); + input1 = input1 + input0; + if (rgb_sum < 0) + { + input0 = uncontract_color(input0); + input1 = uncontract_color(input1); + std::swap(input0, input1); + } + + output0 = clamp(0, 255, input0); + output1 = clamp(0, 255, input1); +} + +/** + * @brief Unpack an LDR RGB color that uses delta encoding. + * + * Output alpha set to 255. + * + * @param input0 The packed endpoint 0 color. + * @param input1 The packed endpoint 1 color deltas. + * @param[out] output0 The unpacked endpoint 0 color. + * @param[out] output1 The unpacked endpoint 1 color. + */ +static void rgb_delta_unpack( + vint4 input0, + vint4 input1, + vint4& output0, + vint4& output1 +) { + rgba_delta_unpack(input0, input1, output0, output1); + output0.set_lane<3>(255); + output1.set_lane<3>(255); +} + +/** + * @brief Unpack an LDR RGBA color that uses direct encoding. + * + * @param input0 The packed endpoint 0 color. + * @param input1 The packed endpoint 1 color. + * @param[out] output0 The unpacked endpoint 0 color. + * @param[out] output1 The unpacked endpoint 1 color. + */ +static void rgba_unpack( + vint4 input0, + vint4 input1, + vint4& output0, + vint4& output1 +) { + // Apply blue-uncontraction if needed + if (hadd_rgb_s(input0) > hadd_rgb_s(input1)) + { + input0 = uncontract_color(input0); + input1 = uncontract_color(input1); + std::swap(input0, input1); + } + + output0 = input0; + output1 = input1; +} + +/** + * @brief Unpack an LDR RGB color that uses direct encoding. + * + * Output alpha set to 255. + * + * @param input0 The packed endpoint 0 color. + * @param input1 The packed endpoint 1 color. + * @param[out] output0 The unpacked endpoint 0 color. + * @param[out] output1 The unpacked endpoint 1 color. + */ +static void rgb_unpack( + vint4 input0, + vint4 input1, + vint4& output0, + vint4& output1 +) { + rgba_unpack(input0, input1, output0, output1); + output0.set_lane<3>(255); + output1.set_lane<3>(255); +} + +/** + * @brief Unpack an LDR RGBA color that uses scaled encoding. + * + * Note only the RGB channels use the scaled encoding, alpha uses direct. + * + * @param input0 The packed endpoint 0 color. + * @param alpha1 The packed endpoint 1 alpha value. + * @param scale The packed quantized scale. + * @param[out] output0 The unpacked endpoint 0 color. + * @param[out] output1 The unpacked endpoint 1 color. + */ +static void rgb_scale_alpha_unpack( + vint4 input0, + uint8_t alpha1, + uint8_t scale, + vint4& output0, + vint4& output1 +) { + output1 = input0; + output1.set_lane<3>(alpha1); + + output0 = asr<8>(input0 * scale); + output0.set_lane<3>(input0.lane<3>()); +} + +/** + * @brief Unpack an LDR RGB color that uses scaled encoding. + * + * Output alpha is 255. + * + * @param input0 The packed endpoint 0 color. + * @param scale The packed scale. + * @param[out] output0 The unpacked endpoint 0 color. + * @param[out] output1 The unpacked endpoint 1 color. + */ +static void rgb_scale_unpack( + vint4 input0, + int scale, + vint4& output0, + vint4& output1 +) { + output1 = input0; + output1.set_lane<3>(255); + + output0 = asr<8>(input0 * scale); + output0.set_lane<3>(255); +} + +/** + * @brief Unpack an LDR L color that uses direct encoding. + * + * Output alpha is 255. + * + * @param input The packed endpoints. + * @param[out] output0 The unpacked endpoint 0 color. + * @param[out] output1 The unpacked endpoint 1 color. + */ +static void luminance_unpack( + const uint8_t input[2], + vint4& output0, + vint4& output1 +) { + int lum0 = input[0]; + int lum1 = input[1]; + output0 = vint4(lum0, lum0, lum0, 255); + output1 = vint4(lum1, lum1, lum1, 255); +} + +/** + * @brief Unpack an LDR L color that uses delta encoding. + * + * Output alpha is 255. + * + * @param input The packed endpoints (L0, L1). + * @param[out] output0 The unpacked endpoint 0 color. + * @param[out] output1 The unpacked endpoint 1 color. + */ +static void luminance_delta_unpack( + const uint8_t input[2], + vint4& output0, + vint4& output1 +) { + int v0 = input[0]; + int v1 = input[1]; + int l0 = (v0 >> 2) | (v1 & 0xC0); + int l1 = l0 + (v1 & 0x3F); + + l1 = astc::min(l1, 255); + + output0 = vint4(l0, l0, l0, 255); + output1 = vint4(l1, l1, l1, 255); +} + +/** + * @brief Unpack an LDR LA color that uses direct encoding. + * + * @param input The packed endpoints (L0, L1, A0, A1). + * @param[out] output0 The unpacked endpoint 0 color. + * @param[out] output1 The unpacked endpoint 1 color. + */ +static void luminance_alpha_unpack( + const uint8_t input[4], + vint4& output0, + vint4& output1 +) { + int lum0 = input[0]; + int lum1 = input[1]; + int alpha0 = input[2]; + int alpha1 = input[3]; + output0 = vint4(lum0, lum0, lum0, alpha0); + output1 = vint4(lum1, lum1, lum1, alpha1); +} + +/** + * @brief Unpack an LDR LA color that uses delta encoding. + * + * @param input The packed endpoints (L0, L1, A0, A1). + * @param[out] output0 The unpacked endpoint 0 color. + * @param[out] output1 The unpacked endpoint 1 color. + */ +static void luminance_alpha_delta_unpack( + const uint8_t input[4], + vint4& output0, + vint4& output1 +) { + int lum0 = input[0]; + int lum1 = input[1]; + int alpha0 = input[2]; + int alpha1 = input[3]; + + lum0 |= (lum1 & 0x80) << 1; + alpha0 |= (alpha1 & 0x80) << 1; + lum1 &= 0x7F; + alpha1 &= 0x7F; + + if (lum1 & 0x40) + { + lum1 -= 0x80; + } + + if (alpha1 & 0x40) + { + alpha1 -= 0x80; + } + + lum0 >>= 1; + lum1 >>= 1; + alpha0 >>= 1; + alpha1 >>= 1; + lum1 += lum0; + alpha1 += alpha0; + + lum1 = astc::clamp(lum1, 0, 255); + alpha1 = astc::clamp(alpha1, 0, 255); + + output0 = vint4(lum0, lum0, lum0, alpha0); + output1 = vint4(lum1, lum1, lum1, alpha1); +} + +/** + * @brief Unpack an HDR RGB + offset encoding. + * + * @param input The packed endpoints (packed and modal). + * @param[out] output0 The unpacked endpoint 0 color. + * @param[out] output1 The unpacked endpoint 1 color. + */ +static void hdr_rgbo_unpack( + const uint8_t input[4], + vint4& output0, + vint4& output1 +) { + int v0 = input[0]; + int v1 = input[1]; + int v2 = input[2]; + int v3 = input[3]; + + int modeval = ((v0 & 0xC0) >> 6) | (((v1 & 0x80) >> 7) << 2) | (((v2 & 0x80) >> 7) << 3); + + int majcomp; + int mode; + if ((modeval & 0xC) != 0xC) + { + majcomp = modeval >> 2; + mode = modeval & 3; + } + else if (modeval != 0xF) + { + majcomp = modeval & 3; + mode = 4; + } + else + { + majcomp = 0; + mode = 5; + } + + int red = v0 & 0x3F; + int green = v1 & 0x1F; + int blue = v2 & 0x1F; + int scale = v3 & 0x1F; + + int bit0 = (v1 >> 6) & 1; + int bit1 = (v1 >> 5) & 1; + int bit2 = (v2 >> 6) & 1; + int bit3 = (v2 >> 5) & 1; + int bit4 = (v3 >> 7) & 1; + int bit5 = (v3 >> 6) & 1; + int bit6 = (v3 >> 5) & 1; + + int ohcomp = 1 << mode; + + if (ohcomp & 0x30) + green |= bit0 << 6; + if (ohcomp & 0x3A) + green |= bit1 << 5; + if (ohcomp & 0x30) + blue |= bit2 << 6; + if (ohcomp & 0x3A) + blue |= bit3 << 5; + + if (ohcomp & 0x3D) + scale |= bit6 << 5; + if (ohcomp & 0x2D) + scale |= bit5 << 6; + if (ohcomp & 0x04) + scale |= bit4 << 7; + + if (ohcomp & 0x3B) + red |= bit4 << 6; + if (ohcomp & 0x04) + red |= bit3 << 6; + + if (ohcomp & 0x10) + red |= bit5 << 7; + if (ohcomp & 0x0F) + red |= bit2 << 7; + + if (ohcomp & 0x05) + red |= bit1 << 8; + if (ohcomp & 0x0A) + red |= bit0 << 8; + + if (ohcomp & 0x05) + red |= bit0 << 9; + if (ohcomp & 0x02) + red |= bit6 << 9; + + if (ohcomp & 0x01) + red |= bit3 << 10; + if (ohcomp & 0x02) + red |= bit5 << 10; + + // expand to 12 bits. + static const int shamts[6] { 1, 1, 2, 3, 4, 5 }; + int shamt = shamts[mode]; + red <<= shamt; + green <<= shamt; + blue <<= shamt; + scale <<= shamt; + + // on modes 0 to 4, the values stored for "green" and "blue" are differentials, + // not absolute values. + if (mode != 5) + { + green = red - green; + blue = red - blue; + } + + // switch around components. + int temp; + switch (majcomp) + { + case 1: + temp = red; + red = green; + green = temp; + break; + case 2: + temp = red; + red = blue; + blue = temp; + break; + default: + break; + } + + int red0 = red - scale; + int green0 = green - scale; + int blue0 = blue - scale; + + // clamp to [0,0xFFF]. + if (red < 0) + red = 0; + if (green < 0) + green = 0; + if (blue < 0) + blue = 0; + + if (red0 < 0) + red0 = 0; + if (green0 < 0) + green0 = 0; + if (blue0 < 0) + blue0 = 0; + + output0 = vint4(red0 << 4, green0 << 4, blue0 << 4, 0x7800); + output1 = vint4(red << 4, green << 4, blue << 4, 0x7800); +} + +/** + * @brief Unpack an HDR RGB direct encoding. + * + * @param input The packed endpoints (packed and modal). + * @param[out] output0 The unpacked endpoint 0 color. + * @param[out] output1 The unpacked endpoint 1 color. + */ +static void hdr_rgb_unpack( + const uint8_t input[6], + vint4& output0, + vint4& output1 +) { + + int v0 = input[0]; + int v1 = input[1]; + int v2 = input[2]; + int v3 = input[3]; + int v4 = input[4]; + int v5 = input[5]; + + // extract all the fixed-placement bitfields + int modeval = ((v1 & 0x80) >> 7) | (((v2 & 0x80) >> 7) << 1) | (((v3 & 0x80) >> 7) << 2); + + int majcomp = ((v4 & 0x80) >> 7) | (((v5 & 0x80) >> 7) << 1); + + if (majcomp == 3) + { + output0 = vint4(v0 << 8, v2 << 8, (v4 & 0x7F) << 9, 0x7800); + output1 = vint4(v1 << 8, v3 << 8, (v5 & 0x7F) << 9, 0x7800); + return; + } + + int a = v0 | ((v1 & 0x40) << 2); + int b0 = v2 & 0x3f; + int b1 = v3 & 0x3f; + int c = v1 & 0x3f; + int d0 = v4 & 0x7f; + int d1 = v5 & 0x7f; + + // get hold of the number of bits in 'd0' and 'd1' + static const int dbits_tab[8] { 7, 6, 7, 6, 5, 6, 5, 6 }; + int dbits = dbits_tab[modeval]; + + // extract six variable-placement bits + int bit0 = (v2 >> 6) & 1; + int bit1 = (v3 >> 6) & 1; + int bit2 = (v4 >> 6) & 1; + int bit3 = (v5 >> 6) & 1; + int bit4 = (v4 >> 5) & 1; + int bit5 = (v5 >> 5) & 1; + + // and prepend the variable-placement bits depending on mode. + int ohmod = 1 << modeval; // one-hot-mode + if (ohmod & 0xA4) + a |= bit0 << 9; + if (ohmod & 0x8) + a |= bit2 << 9; + if (ohmod & 0x50) + a |= bit4 << 9; + + if (ohmod & 0x50) + a |= bit5 << 10; + if (ohmod & 0xA0) + a |= bit1 << 10; + + if (ohmod & 0xC0) + a |= bit2 << 11; + + if (ohmod & 0x4) + c |= bit1 << 6; + if (ohmod & 0xE8) + c |= bit3 << 6; + + if (ohmod & 0x20) + c |= bit2 << 7; + + if (ohmod & 0x5B) + { + b0 |= bit0 << 6; + b1 |= bit1 << 6; + } + + if (ohmod & 0x12) + { + b0 |= bit2 << 7; + b1 |= bit3 << 7; + } + + if (ohmod & 0xAF) + { + d0 |= bit4 << 5; + d1 |= bit5 << 5; + } + + if (ohmod & 0x5) + { + d0 |= bit2 << 6; + d1 |= bit3 << 6; + } + + // sign-extend 'd0' and 'd1' + // note: this code assumes that signed right-shift actually sign-fills, not zero-fills. + int32_t d0x = d0; + int32_t d1x = d1; + int sx_shamt = 32 - dbits; + d0x <<= sx_shamt; + d0x >>= sx_shamt; + d1x <<= sx_shamt; + d1x >>= sx_shamt; + d0 = d0x; + d1 = d1x; + + // expand all values to 12 bits, with left-shift as needed. + int val_shamt = (modeval >> 1) ^ 3; + a <<= val_shamt; + b0 <<= val_shamt; + b1 <<= val_shamt; + c <<= val_shamt; + d0 <<= val_shamt; + d1 <<= val_shamt; + + // then compute the actual color values. + int red1 = a; + int green1 = a - b0; + int blue1 = a - b1; + int red0 = a - c; + int green0 = a - b0 - c - d0; + int blue0 = a - b1 - c - d1; + + // clamp the color components to [0,2^12 - 1] + red0 = astc::clamp(red0, 0, 4095); + green0 = astc::clamp(green0, 0, 4095); + blue0 = astc::clamp(blue0, 0, 4095); + + red1 = astc::clamp(red1, 0, 4095); + green1 = astc::clamp(green1, 0, 4095); + blue1 = astc::clamp(blue1, 0, 4095); + + // switch around the color components + int temp0, temp1; + switch (majcomp) + { + case 1: // switch around red and green + temp0 = red0; + temp1 = red1; + red0 = green0; + red1 = green1; + green0 = temp0; + green1 = temp1; + break; + case 2: // switch around red and blue + temp0 = red0; + temp1 = red1; + red0 = blue0; + red1 = blue1; + blue0 = temp0; + blue1 = temp1; + break; + case 0: // no switch + break; + } + + output0 = vint4(red0 << 4, green0 << 4, blue0 << 4, 0x7800); + output1 = vint4(red1 << 4, green1 << 4, blue1 << 4, 0x7800); +} + +/** + * @brief Unpack an HDR RGB + LDR A direct encoding. + * + * @param input The packed endpoints (packed and modal). + * @param[out] output0 The unpacked endpoint 0 color. + * @param[out] output1 The unpacked endpoint 1 color. + */ +static void hdr_rgb_ldr_alpha_unpack( + const uint8_t input[8], + vint4& output0, + vint4& output1 +) { + hdr_rgb_unpack(input, output0, output1); + + int v6 = input[6]; + int v7 = input[7]; + output0.set_lane<3>(v6); + output1.set_lane<3>(v7); +} + +/** + * @brief Unpack an HDR L (small range) direct encoding. + * + * @param input The packed endpoints (packed and modal). + * @param[out] output0 The unpacked endpoint 0 color. + * @param[out] output1 The unpacked endpoint 1 color. + */ +static void hdr_luminance_small_range_unpack( + const uint8_t input[2], + vint4& output0, + vint4& output1 +) { + int v0 = input[0]; + int v1 = input[1]; + + int y0, y1; + if (v0 & 0x80) + { + y0 = ((v1 & 0xE0) << 4) | ((v0 & 0x7F) << 2); + y1 = (v1 & 0x1F) << 2; + } + else + { + y0 = ((v1 & 0xF0) << 4) | ((v0 & 0x7F) << 1); + y1 = (v1 & 0xF) << 1; + } + + y1 += y0; + if (y1 > 0xFFF) + { + y1 = 0xFFF; + } + + output0 = vint4(y0 << 4, y0 << 4, y0 << 4, 0x7800); + output1 = vint4(y1 << 4, y1 << 4, y1 << 4, 0x7800); +} + +/** + * @brief Unpack an HDR L (large range) direct encoding. + * + * @param input The packed endpoints (packed and modal). + * @param[out] output0 The unpacked endpoint 0 color. + * @param[out] output1 The unpacked endpoint 1 color. + */ +static void hdr_luminance_large_range_unpack( + const uint8_t input[2], + vint4& output0, + vint4& output1 +) { + int v0 = input[0]; + int v1 = input[1]; + + int y0, y1; + if (v1 >= v0) + { + y0 = v0 << 4; + y1 = v1 << 4; + } + else + { + y0 = (v1 << 4) + 8; + y1 = (v0 << 4) - 8; + } + + output0 = vint4(y0 << 4, y0 << 4, y0 << 4, 0x7800); + output1 = vint4(y1 << 4, y1 << 4, y1 << 4, 0x7800); +} + +/** + * @brief Unpack an HDR A direct encoding. + * + * @param input The packed endpoints (packed and modal). + * @param[out] output0 The unpacked endpoint 0 color. + * @param[out] output1 The unpacked endpoint 1 color. + */ +static void hdr_alpha_unpack( + const uint8_t input[2], + int& output0, + int& output1 +) { + + int v6 = input[0]; + int v7 = input[1]; + + int selector = ((v6 >> 7) & 1) | ((v7 >> 6) & 2); + v6 &= 0x7F; + v7 &= 0x7F; + if (selector == 3) + { + output0 = v6 << 5; + output1 = v7 << 5; + } + else + { + v6 |= (v7 << (selector + 1)) & 0x780; + v7 &= (0x3f >> selector); + v7 ^= 32 >> selector; + v7 -= 32 >> selector; + v6 <<= (4 - selector); + v7 <<= (4 - selector); + v7 += v6; + + if (v7 < 0) + { + v7 = 0; + } + else if (v7 > 0xFFF) + { + v7 = 0xFFF; + } + + output0 = v6; + output1 = v7; + } + + output0 <<= 4; + output1 <<= 4; +} + +/** + * @brief Unpack an HDR RGBA direct encoding. + * + * @param input The packed endpoints (packed and modal). + * @param[out] output0 The unpacked endpoint 0 color. + * @param[out] output1 The unpacked endpoint 1 color. + */ +static void hdr_rgb_hdr_alpha_unpack( + const uint8_t input[8], + vint4& output0, + vint4& output1 +) { + hdr_rgb_unpack(input, output0, output1); + + int alpha0, alpha1; + hdr_alpha_unpack(input + 6, alpha0, alpha1); + + output0.set_lane<3>(alpha0); + output1.set_lane<3>(alpha1); +} + +/* See header for documentation. */ +void unpack_color_endpoints( + astcenc_profile decode_mode, + int format, + const uint8_t* input, + bool& rgb_hdr, + bool& alpha_hdr, + vint4& output0, + vint4& output1 +) { + // Assume no NaNs and LDR endpoints unless set later + rgb_hdr = false; + alpha_hdr = false; + + bool alpha_hdr_default = false; + + switch (format) + { + case FMT_LUMINANCE: + luminance_unpack(input, output0, output1); + break; + + case FMT_LUMINANCE_DELTA: + luminance_delta_unpack(input, output0, output1); + break; + + case FMT_HDR_LUMINANCE_SMALL_RANGE: + rgb_hdr = true; + alpha_hdr_default = true; + hdr_luminance_small_range_unpack(input, output0, output1); + break; + + case FMT_HDR_LUMINANCE_LARGE_RANGE: + rgb_hdr = true; + alpha_hdr_default = true; + hdr_luminance_large_range_unpack(input, output0, output1); + break; + + case FMT_LUMINANCE_ALPHA: + luminance_alpha_unpack(input, output0, output1); + break; + + case FMT_LUMINANCE_ALPHA_DELTA: + luminance_alpha_delta_unpack(input, output0, output1); + break; + + case FMT_RGB_SCALE: + { + vint4 input0q(input[0], input[1], input[2], 0); + uint8_t scale = input[3]; + rgb_scale_unpack(input0q, scale, output0, output1); + } + break; + + case FMT_RGB_SCALE_ALPHA: + { + vint4 input0q(input[0], input[1], input[2], input[4]); + uint8_t alpha1q = input[5]; + uint8_t scaleq = input[3]; + rgb_scale_alpha_unpack(input0q, alpha1q, scaleq, output0, output1); + } + break; + + case FMT_HDR_RGB_SCALE: + rgb_hdr = true; + alpha_hdr_default = true; + hdr_rgbo_unpack(input, output0, output1); + break; + + case FMT_RGB: + { + vint4 input0q(input[0], input[2], input[4], 0); + vint4 input1q(input[1], input[3], input[5], 0); + rgb_unpack(input0q, input1q, output0, output1); + } + break; + + case FMT_RGB_DELTA: + { + vint4 input0q(input[0], input[2], input[4], 0); + vint4 input1q(input[1], input[3], input[5], 0); + rgb_delta_unpack(input0q, input1q, output0, output1); + } + break; + + case FMT_HDR_RGB: + rgb_hdr = true; + alpha_hdr_default = true; + hdr_rgb_unpack(input, output0, output1); + break; + + case FMT_RGBA: + { + vint4 input0q(input[0], input[2], input[4], input[6]); + vint4 input1q(input[1], input[3], input[5], input[7]); + rgba_unpack(input0q, input1q, output0, output1); + } + break; + + case FMT_RGBA_DELTA: + { + vint4 input0q(input[0], input[2], input[4], input[6]); + vint4 input1q(input[1], input[3], input[5], input[7]); + rgba_delta_unpack(input0q, input1q, output0, output1); + } + break; + + case FMT_HDR_RGB_LDR_ALPHA: + rgb_hdr = true; + hdr_rgb_ldr_alpha_unpack(input, output0, output1); + break; + + case FMT_HDR_RGBA: + rgb_hdr = true; + alpha_hdr = true; + hdr_rgb_hdr_alpha_unpack(input, output0, output1); + break; + } + + // Assign a correct default alpha + if (alpha_hdr_default) + { + if (decode_mode == ASTCENC_PRF_HDR) + { + output0.set_lane<3>(0x7800); + output1.set_lane<3>(0x7800); + alpha_hdr = true; + } + else + { + output0.set_lane<3>(0x00FF); + output1.set_lane<3>(0x00FF); + alpha_hdr = false; + } + } + + vint4 ldr_scale(257); + vint4 hdr_scale(1); + vint4 output_scale = ldr_scale; + + // An LDR profile image + if ((decode_mode == ASTCENC_PRF_LDR) || + (decode_mode == ASTCENC_PRF_LDR_SRGB)) + { + // Also matches HDR alpha, as cannot have HDR alpha without HDR RGB + if (rgb_hdr == true) + { + output0 = vint4(0xFF00, 0x0000, 0xFF00, 0xFF00); + output1 = vint4(0xFF00, 0x0000, 0xFF00, 0xFF00); + output_scale = hdr_scale; + + rgb_hdr = false; + alpha_hdr = false; + } + } + // An HDR profile image + else + { + vmask4 hdr_lanes(rgb_hdr, rgb_hdr, rgb_hdr, alpha_hdr); + output_scale = select(ldr_scale, hdr_scale, hdr_lanes); + } + + output0 = output0 * output_scale; + output1 = output1 * output_scale; +} diff --git a/thirdparty/astcenc/astcenc_compress_symbolic.cpp b/thirdparty/astcenc/astcenc_compress_symbolic.cpp new file mode 100644 index 0000000000..afb76246e7 --- /dev/null +++ b/thirdparty/astcenc/astcenc_compress_symbolic.cpp @@ -0,0 +1,1455 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2023 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +#if !defined(ASTCENC_DECOMPRESS_ONLY) + +/** + * @brief Functions to compress a symbolic block. + */ + +#include "astcenc_internal.h" +#include "astcenc_diagnostic_trace.h" + +#include <cassert> + +/** + * @brief Merge two planes of endpoints into a single vector. + * + * @param ep_plane1 The endpoints for plane 1. + * @param ep_plane2 The endpoints for plane 2. + * @param component_plane2 The color component for plane 2. + * @param[out] result The merged output. + */ +static void merge_endpoints( + const endpoints& ep_plane1, + const endpoints& ep_plane2, + unsigned int component_plane2, + endpoints& result +) { + unsigned int partition_count = ep_plane1.partition_count; + assert(partition_count == 1); + + vmask4 sep_mask = vint4::lane_id() == vint4(component_plane2); + + result.partition_count = partition_count; + result.endpt0[0] = select(ep_plane1.endpt0[0], ep_plane2.endpt0[0], sep_mask); + result.endpt1[0] = select(ep_plane1.endpt1[0], ep_plane2.endpt1[0], sep_mask); +} + +/** + * @brief Attempt to improve weights given a chosen configuration. + * + * Given a fixed weight grid decimation and weight value quantization, iterate over all weights (per + * partition and per plane) and attempt to improve image quality by moving each weight up by one or + * down by one quantization step. + * + * This is a specialized function which only supports operating on undecimated weight grids, + * therefore primarily improving the performance of 4x4 and 5x5 blocks where grid decimation + * is needed less often. + * + * @param decode_mode The decode mode (LDR, HDR). + * @param bsd The block size information. + * @param blk The image block color data to compress. + * @param[out] scb The symbolic compressed block output. + */ +static bool realign_weights_undecimated( + astcenc_profile decode_mode, + const block_size_descriptor& bsd, + const image_block& blk, + symbolic_compressed_block& scb +) { + // Get the partition descriptor + unsigned int partition_count = scb.partition_count; + const auto& pi = bsd.get_partition_info(partition_count, scb.partition_index); + + // Get the quantization table + const block_mode& bm = bsd.get_block_mode(scb.block_mode); + unsigned int weight_quant_level = bm.quant_mode; + const quant_and_transfer_table& qat = quant_and_xfer_tables[weight_quant_level]; + + unsigned int max_plane = bm.is_dual_plane; + int plane2_component = scb.plane2_component; + vmask4 plane_mask = vint4::lane_id() == vint4(plane2_component); + + // Decode the color endpoints + bool rgb_hdr; + bool alpha_hdr; + vint4 endpnt0[BLOCK_MAX_PARTITIONS]; + vint4 endpnt1[BLOCK_MAX_PARTITIONS]; + vfloat4 endpnt0f[BLOCK_MAX_PARTITIONS]; + vfloat4 offset[BLOCK_MAX_PARTITIONS]; + + promise(partition_count > 0); + + for (unsigned int pa_idx = 0; pa_idx < partition_count; pa_idx++) + { + unpack_color_endpoints(decode_mode, + scb.color_formats[pa_idx], + scb.color_values[pa_idx], + rgb_hdr, alpha_hdr, + endpnt0[pa_idx], + endpnt1[pa_idx]); + } + + uint8_t* dec_weights_uquant = scb.weights; + bool adjustments = false; + + // For each plane and partition ... + for (unsigned int pl_idx = 0; pl_idx <= max_plane; pl_idx++) + { + for (unsigned int pa_idx = 0; pa_idx < partition_count; pa_idx++) + { + // Compute the endpoint delta for all components in current plane + vint4 epd = endpnt1[pa_idx] - endpnt0[pa_idx]; + epd = select(epd, vint4::zero(), plane_mask); + + endpnt0f[pa_idx] = int_to_float(endpnt0[pa_idx]); + offset[pa_idx] = int_to_float(epd) * (1.0f / 64.0f); + } + + // For each weight compute previous, current, and next errors + promise(bsd.texel_count > 0); + for (unsigned int texel = 0; texel < bsd.texel_count; texel++) + { + int uqw = dec_weights_uquant[texel]; + + uint32_t prev_and_next = qat.prev_next_values[uqw]; + int uqw_down = prev_and_next & 0xFF; + int uqw_up = (prev_and_next >> 8) & 0xFF; + + // Interpolate the colors to create the diffs + float weight_base = static_cast<float>(uqw); + float weight_down = static_cast<float>(uqw_down - uqw); + float weight_up = static_cast<float>(uqw_up - uqw); + + unsigned int partition = pi.partition_of_texel[texel]; + vfloat4 color_offset = offset[partition]; + vfloat4 color_base = endpnt0f[partition]; + + vfloat4 color = color_base + color_offset * weight_base; + vfloat4 orig_color = blk.texel(texel); + vfloat4 error_weight = blk.channel_weight; + + vfloat4 color_diff = color - orig_color; + vfloat4 color_diff_down = color_diff + color_offset * weight_down; + vfloat4 color_diff_up = color_diff + color_offset * weight_up; + + float error_base = dot_s(color_diff * color_diff, error_weight); + float error_down = dot_s(color_diff_down * color_diff_down, error_weight); + float error_up = dot_s(color_diff_up * color_diff_up, error_weight); + + // Check if the prev or next error is better, and if so use it + if ((error_up < error_base) && (error_up < error_down) && (uqw < 64)) + { + dec_weights_uquant[texel] = static_cast<uint8_t>(uqw_up); + adjustments = true; + } + else if ((error_down < error_base) && (uqw > 0)) + { + dec_weights_uquant[texel] = static_cast<uint8_t>(uqw_down); + adjustments = true; + } + } + + // Prepare iteration for plane 2 + dec_weights_uquant += WEIGHTS_PLANE2_OFFSET; + plane_mask = ~plane_mask; + } + + return adjustments; +} + +/** + * @brief Attempt to improve weights given a chosen configuration. + * + * Given a fixed weight grid decimation and weight value quantization, iterate over all weights (per + * partition and per plane) and attempt to improve image quality by moving each weight up by one or + * down by one quantization step. + * + * @param decode_mode The decode mode (LDR, HDR). + * @param bsd The block size information. + * @param blk The image block color data to compress. + * @param[out] scb The symbolic compressed block output. + */ +static bool realign_weights_decimated( + astcenc_profile decode_mode, + const block_size_descriptor& bsd, + const image_block& blk, + symbolic_compressed_block& scb +) { + // Get the partition descriptor + unsigned int partition_count = scb.partition_count; + const auto& pi = bsd.get_partition_info(partition_count, scb.partition_index); + + // Get the quantization table + const block_mode& bm = bsd.get_block_mode(scb.block_mode); + unsigned int weight_quant_level = bm.quant_mode; + const quant_and_transfer_table& qat = quant_and_xfer_tables[weight_quant_level]; + + // Get the decimation table + const decimation_info& di = bsd.get_decimation_info(bm.decimation_mode); + unsigned int weight_count = di.weight_count; + assert(weight_count != bsd.texel_count); + + unsigned int max_plane = bm.is_dual_plane; + int plane2_component = scb.plane2_component; + vmask4 plane_mask = vint4::lane_id() == vint4(plane2_component); + + // Decode the color endpoints + bool rgb_hdr; + bool alpha_hdr; + vint4 endpnt0[BLOCK_MAX_PARTITIONS]; + vint4 endpnt1[BLOCK_MAX_PARTITIONS]; + vfloat4 endpnt0f[BLOCK_MAX_PARTITIONS]; + vfloat4 offset[BLOCK_MAX_PARTITIONS]; + + promise(partition_count > 0); + promise(weight_count > 0); + + for (unsigned int pa_idx = 0; pa_idx < partition_count; pa_idx++) + { + unpack_color_endpoints(decode_mode, + scb.color_formats[pa_idx], + scb.color_values[pa_idx], + rgb_hdr, alpha_hdr, + endpnt0[pa_idx], + endpnt1[pa_idx]); + } + + uint8_t* dec_weights_uquant = scb.weights; + bool adjustments = false; + + // For each plane and partition ... + for (unsigned int pl_idx = 0; pl_idx <= max_plane; pl_idx++) + { + for (unsigned int pa_idx = 0; pa_idx < partition_count; pa_idx++) + { + // Compute the endpoint delta for all components in current plane + vint4 epd = endpnt1[pa_idx] - endpnt0[pa_idx]; + epd = select(epd, vint4::zero(), plane_mask); + + endpnt0f[pa_idx] = int_to_float(endpnt0[pa_idx]); + offset[pa_idx] = int_to_float(epd) * (1.0f / 64.0f); + } + + // Create an unquantized weight grid for this decimation level + alignas(ASTCENC_VECALIGN) float uq_weightsf[BLOCK_MAX_WEIGHTS]; + for (unsigned int we_idx = 0; we_idx < weight_count; we_idx += ASTCENC_SIMD_WIDTH) + { + vint unquant_value(dec_weights_uquant + we_idx); + vfloat unquant_valuef = int_to_float(unquant_value); + storea(unquant_valuef, uq_weightsf + we_idx); + } + + // For each weight compute previous, current, and next errors + for (unsigned int we_idx = 0; we_idx < weight_count; we_idx++) + { + int uqw = dec_weights_uquant[we_idx]; + uint32_t prev_and_next = qat.prev_next_values[uqw]; + + float uqw_base = uq_weightsf[we_idx]; + float uqw_down = static_cast<float>(prev_and_next & 0xFF); + float uqw_up = static_cast<float>((prev_and_next >> 8) & 0xFF); + + float uqw_diff_down = uqw_down - uqw_base; + float uqw_diff_up = uqw_up - uqw_base; + + vfloat4 error_basev = vfloat4::zero(); + vfloat4 error_downv = vfloat4::zero(); + vfloat4 error_upv = vfloat4::zero(); + + // Interpolate the colors to create the diffs + unsigned int texels_to_evaluate = di.weight_texel_count[we_idx]; + promise(texels_to_evaluate > 0); + for (unsigned int te_idx = 0; te_idx < texels_to_evaluate; te_idx++) + { + unsigned int texel = di.weight_texels_tr[te_idx][we_idx]; + + float tw_base = di.texel_contrib_for_weight[te_idx][we_idx]; + + float weight_base = (uq_weightsf[di.texel_weights_tr[0][texel]] * di.texel_weight_contribs_float_tr[0][texel] + + uq_weightsf[di.texel_weights_tr[1][texel]] * di.texel_weight_contribs_float_tr[1][texel]) + + (uq_weightsf[di.texel_weights_tr[2][texel]] * di.texel_weight_contribs_float_tr[2][texel] + + uq_weightsf[di.texel_weights_tr[3][texel]] * di.texel_weight_contribs_float_tr[3][texel]); + + // Ideally this is integer rounded, but IQ gain it isn't worth the overhead + // float weight = astc::flt_rd(weight_base + 0.5f); + // float weight_down = astc::flt_rd(weight_base + 0.5f + uqw_diff_down * tw_base) - weight; + // float weight_up = astc::flt_rd(weight_base + 0.5f + uqw_diff_up * tw_base) - weight; + float weight_down = weight_base + uqw_diff_down * tw_base - weight_base; + float weight_up = weight_base + uqw_diff_up * tw_base - weight_base; + + unsigned int partition = pi.partition_of_texel[texel]; + vfloat4 color_offset = offset[partition]; + vfloat4 color_base = endpnt0f[partition]; + + vfloat4 color = color_base + color_offset * weight_base; + vfloat4 orig_color = blk.texel(texel); + + vfloat4 color_diff = color - orig_color; + vfloat4 color_down_diff = color_diff + color_offset * weight_down; + vfloat4 color_up_diff = color_diff + color_offset * weight_up; + + error_basev += color_diff * color_diff; + error_downv += color_down_diff * color_down_diff; + error_upv += color_up_diff * color_up_diff; + } + + vfloat4 error_weight = blk.channel_weight; + float error_base = hadd_s(error_basev * error_weight); + float error_down = hadd_s(error_downv * error_weight); + float error_up = hadd_s(error_upv * error_weight); + + // Check if the prev or next error is better, and if so use it + if ((error_up < error_base) && (error_up < error_down) && (uqw < 64)) + { + uq_weightsf[we_idx] = uqw_up; + dec_weights_uquant[we_idx] = static_cast<uint8_t>(uqw_up); + adjustments = true; + } + else if ((error_down < error_base) && (uqw > 0)) + { + uq_weightsf[we_idx] = uqw_down; + dec_weights_uquant[we_idx] = static_cast<uint8_t>(uqw_down); + adjustments = true; + } + } + + // Prepare iteration for plane 2 + dec_weights_uquant += WEIGHTS_PLANE2_OFFSET; + plane_mask = ~plane_mask; + } + + return adjustments; +} + +/** + * @brief Compress a block using a chosen partitioning and 1 plane of weights. + * + * @param config The compressor configuration. + * @param bsd The block size information. + * @param blk The image block color data to compress. + * @param only_always True if we only use "always" percentile block modes. + * @param tune_errorval_threshold The error value threshold. + * @param partition_count The partition count. + * @param partition_index The partition index if @c partition_count is 2-4. + * @param[out] scb The symbolic compressed block output. + * @param[out] tmpbuf The quantized weights for plane 1. + */ +static float compress_symbolic_block_for_partition_1plane( + const astcenc_config& config, + const block_size_descriptor& bsd, + const image_block& blk, + bool only_always, + float tune_errorval_threshold, + unsigned int partition_count, + unsigned int partition_index, + symbolic_compressed_block& scb, + compression_working_buffers& tmpbuf, + int quant_limit +) { + promise(partition_count > 0); + promise(config.tune_candidate_limit > 0); + promise(config.tune_refinement_limit > 0); + + int max_weight_quant = astc::min(static_cast<int>(QUANT_32), quant_limit); + + auto compute_difference = &compute_symbolic_block_difference_1plane; + if ((partition_count == 1) && !(config.flags & ASTCENC_FLG_MAP_RGBM)) + { + compute_difference = &compute_symbolic_block_difference_1plane_1partition; + } + + const auto& pi = bsd.get_partition_info(partition_count, partition_index); + + // Compute ideal weights and endpoint colors, with no quantization or decimation + endpoints_and_weights& ei = tmpbuf.ei1; + compute_ideal_colors_and_weights_1plane(blk, pi, ei); + + // Compute ideal weights and endpoint colors for every decimation + float* dec_weights_ideal = tmpbuf.dec_weights_ideal; + uint8_t* dec_weights_uquant = tmpbuf.dec_weights_uquant; + + // For each decimation mode, compute an ideal set of weights with no quantization + unsigned int max_decimation_modes = only_always ? bsd.decimation_mode_count_always + : bsd.decimation_mode_count_selected; + promise(max_decimation_modes > 0); + for (unsigned int i = 0; i < max_decimation_modes; i++) + { + const auto& dm = bsd.get_decimation_mode(i); + if (!dm.is_ref_1_plane(static_cast<quant_method>(max_weight_quant))) + { + continue; + } + + const auto& di = bsd.get_decimation_info(i); + + compute_ideal_weights_for_decimation( + ei, + di, + dec_weights_ideal + i * BLOCK_MAX_WEIGHTS); + } + + // Compute maximum colors for the endpoints and ideal weights, then for each endpoint and ideal + // weight pair, compute the smallest weight that will result in a color value greater than 1 + vfloat4 min_ep(10.0f); + for (unsigned int i = 0; i < partition_count; i++) + { + vfloat4 ep = (vfloat4(1.0f) - ei.ep.endpt0[i]) / (ei.ep.endpt1[i] - ei.ep.endpt0[i]); + + vmask4 use_ep = (ep > vfloat4(0.5f)) & (ep < min_ep); + min_ep = select(min_ep, ep, use_ep); + } + + float min_wt_cutoff = hmin_s(min_ep); + + // For each mode, use the angular method to compute a shift + compute_angular_endpoints_1plane( + only_always, bsd, dec_weights_ideal, max_weight_quant, tmpbuf); + + float* weight_low_value = tmpbuf.weight_low_value1; + float* weight_high_value = tmpbuf.weight_high_value1; + int8_t* qwt_bitcounts = tmpbuf.qwt_bitcounts; + float* qwt_errors = tmpbuf.qwt_errors; + + // For each mode (which specifies a decimation and a quantization): + // * Compute number of bits needed for the quantized weights + // * Generate an optimized set of quantized weights + // * Compute quantization errors for the mode + + + static const int8_t free_bits_for_partition_count[4] { + 115 - 4, 111 - 4 - PARTITION_INDEX_BITS, 108 - 4 - PARTITION_INDEX_BITS, 105 - 4 - PARTITION_INDEX_BITS + }; + + unsigned int max_block_modes = only_always ? bsd.block_mode_count_1plane_always + : bsd.block_mode_count_1plane_selected; + promise(max_block_modes > 0); + for (unsigned int i = 0; i < max_block_modes; i++) + { + const block_mode& bm = bsd.block_modes[i]; + + if (bm.quant_mode > max_weight_quant) + { + qwt_errors[i] = 1e38f; + continue; + } + + assert(!bm.is_dual_plane); + int bitcount = free_bits_for_partition_count[partition_count - 1] - bm.weight_bits; + if (bitcount <= 0) + { + qwt_errors[i] = 1e38f; + continue; + } + + if (weight_high_value[i] > 1.02f * min_wt_cutoff) + { + weight_high_value[i] = 1.0f; + } + + int decimation_mode = bm.decimation_mode; + const auto& di = bsd.get_decimation_info(decimation_mode); + + qwt_bitcounts[i] = static_cast<int8_t>(bitcount); + + alignas(ASTCENC_VECALIGN) float dec_weights_uquantf[BLOCK_MAX_WEIGHTS]; + + // Generate the optimized set of weights for the weight mode + compute_quantized_weights_for_decimation( + di, + weight_low_value[i], weight_high_value[i], + dec_weights_ideal + BLOCK_MAX_WEIGHTS * decimation_mode, + dec_weights_uquantf, + dec_weights_uquant + BLOCK_MAX_WEIGHTS * i, + bm.get_weight_quant_mode()); + + // Compute weight quantization errors for the block mode + qwt_errors[i] = compute_error_of_weight_set_1plane( + ei, + di, + dec_weights_uquantf); + } + + // Decide the optimal combination of color endpoint encodings and weight encodings + uint8_t partition_format_specifiers[TUNE_MAX_TRIAL_CANDIDATES][BLOCK_MAX_PARTITIONS]; + int block_mode_index[TUNE_MAX_TRIAL_CANDIDATES]; + + quant_method color_quant_level[TUNE_MAX_TRIAL_CANDIDATES]; + quant_method color_quant_level_mod[TUNE_MAX_TRIAL_CANDIDATES]; + + unsigned int candidate_count = compute_ideal_endpoint_formats( + pi, blk, ei.ep, qwt_bitcounts, qwt_errors, + config.tune_candidate_limit, 0, max_block_modes, + partition_format_specifiers, block_mode_index, + color_quant_level, color_quant_level_mod, tmpbuf); + + // Iterate over the N believed-to-be-best modes to find out which one is actually best + float best_errorval_in_mode = ERROR_CALC_DEFAULT; + float best_errorval_in_scb = scb.errorval; + + for (unsigned int i = 0; i < candidate_count; i++) + { + TRACE_NODE(node0, "candidate"); + + const int bm_packed_index = block_mode_index[i]; + assert(bm_packed_index >= 0 && bm_packed_index < static_cast<int>(bsd.block_mode_count_1plane_selected)); + const block_mode& qw_bm = bsd.block_modes[bm_packed_index]; + + int decimation_mode = qw_bm.decimation_mode; + const auto& di = bsd.get_decimation_info(decimation_mode); + promise(di.weight_count > 0); + + trace_add_data("weight_x", di.weight_x); + trace_add_data("weight_y", di.weight_y); + trace_add_data("weight_z", di.weight_z); + trace_add_data("weight_quant", qw_bm.quant_mode); + + // Recompute the ideal color endpoints before storing them + vfloat4 rgbs_colors[BLOCK_MAX_PARTITIONS]; + vfloat4 rgbo_colors[BLOCK_MAX_PARTITIONS]; + + symbolic_compressed_block workscb; + endpoints workep = ei.ep; + + uint8_t* u8_weight_src = dec_weights_uquant + BLOCK_MAX_WEIGHTS * bm_packed_index; + + for (unsigned int j = 0; j < di.weight_count; j++) + { + workscb.weights[j] = u8_weight_src[j]; + } + + for (unsigned int l = 0; l < config.tune_refinement_limit; l++) + { + recompute_ideal_colors_1plane( + blk, pi, di, workscb.weights, + workep, rgbs_colors, rgbo_colors); + + // Quantize the chosen color, tracking if worth trying the mod value + bool all_same = color_quant_level[i] != color_quant_level_mod[i]; + for (unsigned int j = 0; j < partition_count; j++) + { + workscb.color_formats[j] = pack_color_endpoints( + workep.endpt0[j], + workep.endpt1[j], + rgbs_colors[j], + rgbo_colors[j], + partition_format_specifiers[i][j], + workscb.color_values[j], + color_quant_level[i]); + + all_same = all_same && workscb.color_formats[j] == workscb.color_formats[0]; + } + + // If all the color endpoint modes are the same, we get a few more bits to store colors; + // let's see if we can take advantage of this: requantize all the colors and see if the + // endpoint modes remain the same. + workscb.color_formats_matched = 0; + if (partition_count >= 2 && all_same) + { + uint8_t colorvals[BLOCK_MAX_PARTITIONS][12]; + uint8_t color_formats_mod[BLOCK_MAX_PARTITIONS] { 0 }; + bool all_same_mod = true; + for (unsigned int j = 0; j < partition_count; j++) + { + color_formats_mod[j] = pack_color_endpoints( + workep.endpt0[j], + workep.endpt1[j], + rgbs_colors[j], + rgbo_colors[j], + partition_format_specifiers[i][j], + colorvals[j], + color_quant_level_mod[i]); + + // Early out as soon as it's no longer possible to use mod + if (color_formats_mod[j] != color_formats_mod[0]) + { + all_same_mod = false; + break; + } + } + + if (all_same_mod) + { + workscb.color_formats_matched = 1; + for (unsigned int j = 0; j < BLOCK_MAX_PARTITIONS; j++) + { + for (unsigned int k = 0; k < 8; k++) + { + workscb.color_values[j][k] = colorvals[j][k]; + } + + workscb.color_formats[j] = color_formats_mod[j]; + } + } + } + + // Store header fields + workscb.partition_count = static_cast<uint8_t>(partition_count); + workscb.partition_index = static_cast<uint16_t>(partition_index); + workscb.plane2_component = -1; + workscb.quant_mode = workscb.color_formats_matched ? color_quant_level_mod[i] : color_quant_level[i]; + workscb.block_mode = qw_bm.mode_index; + workscb.block_type = SYM_BTYPE_NONCONST; + + // Pre-realign test + if (l == 0) + { + float errorval = compute_difference(config, bsd, workscb, blk); + if (errorval == -ERROR_CALC_DEFAULT) + { + errorval = -errorval; + workscb.block_type = SYM_BTYPE_ERROR; + } + + trace_add_data("error_prerealign", errorval); + best_errorval_in_mode = astc::min(errorval, best_errorval_in_mode); + + // Average refinement improvement is 3.5% per iteration (allow 4.5%), but the first + // iteration can help more so we give it a extra 8% leeway. Use this knowledge to + // drive a heuristic to skip blocks that are unlikely to catch up with the best + // block we have already. + unsigned int iters_remaining = config.tune_refinement_limit - l; + float threshold = (0.045f * static_cast<float>(iters_remaining)) + 1.08f; + if (errorval > (threshold * best_errorval_in_scb)) + { + break; + } + + if (errorval < best_errorval_in_scb) + { + best_errorval_in_scb = errorval; + workscb.errorval = errorval; + scb = workscb; + + if (errorval < tune_errorval_threshold) + { + // Skip remaining candidates - this is "good enough" + i = candidate_count; + break; + } + } + } + + bool adjustments; + if (di.weight_count != bsd.texel_count) + { + adjustments = realign_weights_decimated( + config.profile, bsd, blk, workscb); + } + else + { + adjustments = realign_weights_undecimated( + config.profile, bsd, blk, workscb); + } + + // Post-realign test + float errorval = compute_difference(config, bsd, workscb, blk); + if (errorval == -ERROR_CALC_DEFAULT) + { + errorval = -errorval; + workscb.block_type = SYM_BTYPE_ERROR; + } + + trace_add_data("error_postrealign", errorval); + best_errorval_in_mode = astc::min(errorval, best_errorval_in_mode); + + // Average refinement improvement is 3.5% per iteration, so skip blocks that are + // unlikely to catch up with the best block we have already. Assume a 4.5% per step to + // give benefit of the doubt ... + unsigned int iters_remaining = config.tune_refinement_limit - 1 - l; + float threshold = (0.045f * static_cast<float>(iters_remaining)) + 1.0f; + if (errorval > (threshold * best_errorval_in_scb)) + { + break; + } + + if (errorval < best_errorval_in_scb) + { + best_errorval_in_scb = errorval; + workscb.errorval = errorval; + scb = workscb; + + if (errorval < tune_errorval_threshold) + { + // Skip remaining candidates - this is "good enough" + i = candidate_count; + break; + } + } + + if (!adjustments) + { + break; + } + } + } + + return best_errorval_in_mode; +} + +/** + * @brief Compress a block using a chosen partitioning and 2 planes of weights. + * + * @param config The compressor configuration. + * @param bsd The block size information. + * @param blk The image block color data to compress. + * @param tune_errorval_threshold The error value threshold. + * @param plane2_component The component index for the second plane of weights. + * @param[out] scb The symbolic compressed block output. + * @param[out] tmpbuf The quantized weights for plane 1. + */ +static float compress_symbolic_block_for_partition_2planes( + const astcenc_config& config, + const block_size_descriptor& bsd, + const image_block& blk, + float tune_errorval_threshold, + unsigned int plane2_component, + symbolic_compressed_block& scb, + compression_working_buffers& tmpbuf, + int quant_limit +) { + promise(config.tune_candidate_limit > 0); + promise(config.tune_refinement_limit > 0); + promise(bsd.decimation_mode_count_selected > 0); + + int max_weight_quant = astc::min(static_cast<int>(QUANT_32), quant_limit); + + // Compute ideal weights and endpoint colors, with no quantization or decimation + endpoints_and_weights& ei1 = tmpbuf.ei1; + endpoints_and_weights& ei2 = tmpbuf.ei2; + + compute_ideal_colors_and_weights_2planes(bsd, blk, plane2_component, ei1, ei2); + + // Compute ideal weights and endpoint colors for every decimation + float* dec_weights_ideal = tmpbuf.dec_weights_ideal; + uint8_t* dec_weights_uquant = tmpbuf.dec_weights_uquant; + + // For each decimation mode, compute an ideal set of weights with no quantization + for (unsigned int i = 0; i < bsd.decimation_mode_count_selected; i++) + { + const auto& dm = bsd.get_decimation_mode(i); + if (!dm.is_ref_2_plane(static_cast<quant_method>(max_weight_quant))) + { + continue; + } + + const auto& di = bsd.get_decimation_info(i); + + compute_ideal_weights_for_decimation( + ei1, + di, + dec_weights_ideal + i * BLOCK_MAX_WEIGHTS); + + compute_ideal_weights_for_decimation( + ei2, + di, + dec_weights_ideal + i * BLOCK_MAX_WEIGHTS + WEIGHTS_PLANE2_OFFSET); + } + + // Compute maximum colors for the endpoints and ideal weights, then for each endpoint and ideal + // weight pair, compute the smallest weight that will result in a color value greater than 1 + vfloat4 min_ep1(10.0f); + vfloat4 min_ep2(10.0f); + + vfloat4 ep1 = (vfloat4(1.0f) - ei1.ep.endpt0[0]) / (ei1.ep.endpt1[0] - ei1.ep.endpt0[0]); + vmask4 use_ep1 = (ep1 > vfloat4(0.5f)) & (ep1 < min_ep1); + min_ep1 = select(min_ep1, ep1, use_ep1); + + vfloat4 ep2 = (vfloat4(1.0f) - ei2.ep.endpt0[0]) / (ei2.ep.endpt1[0] - ei2.ep.endpt0[0]); + vmask4 use_ep2 = (ep2 > vfloat4(0.5f)) & (ep2 < min_ep2); + min_ep2 = select(min_ep2, ep2, use_ep2); + + vfloat4 err_max(ERROR_CALC_DEFAULT); + vmask4 err_mask = vint4::lane_id() == vint4(plane2_component); + + // Set the plane2 component to max error in ep1 + min_ep1 = select(min_ep1, err_max, err_mask); + + float min_wt_cutoff1 = hmin_s(min_ep1); + + // Set the minwt2 to the plane2 component min in ep2 + float min_wt_cutoff2 = hmin_s(select(err_max, min_ep2, err_mask)); + + compute_angular_endpoints_2planes( + bsd, dec_weights_ideal, max_weight_quant, tmpbuf); + + // For each mode (which specifies a decimation and a quantization): + // * Compute number of bits needed for the quantized weights + // * Generate an optimized set of quantized weights + // * Compute quantization errors for the mode + + float* weight_low_value1 = tmpbuf.weight_low_value1; + float* weight_high_value1 = tmpbuf.weight_high_value1; + float* weight_low_value2 = tmpbuf.weight_low_value2; + float* weight_high_value2 = tmpbuf.weight_high_value2; + + int8_t* qwt_bitcounts = tmpbuf.qwt_bitcounts; + float* qwt_errors = tmpbuf.qwt_errors; + + unsigned int start_2plane = bsd.block_mode_count_1plane_selected; + unsigned int end_2plane = bsd.block_mode_count_1plane_2plane_selected; + + for (unsigned int i = start_2plane; i < end_2plane; i++) + { + const block_mode& bm = bsd.block_modes[i]; + assert(bm.is_dual_plane); + + if (bm.quant_mode > max_weight_quant) + { + qwt_errors[i] = 1e38f; + continue; + } + + qwt_bitcounts[i] = static_cast<int8_t>(109 - bm.weight_bits); + + if (weight_high_value1[i] > 1.02f * min_wt_cutoff1) + { + weight_high_value1[i] = 1.0f; + } + + if (weight_high_value2[i] > 1.02f * min_wt_cutoff2) + { + weight_high_value2[i] = 1.0f; + } + + unsigned int decimation_mode = bm.decimation_mode; + const auto& di = bsd.get_decimation_info(decimation_mode); + + alignas(ASTCENC_VECALIGN) float dec_weights_uquantf[BLOCK_MAX_WEIGHTS]; + + // Generate the optimized set of weights for the mode + compute_quantized_weights_for_decimation( + di, + weight_low_value1[i], + weight_high_value1[i], + dec_weights_ideal + BLOCK_MAX_WEIGHTS * decimation_mode, + dec_weights_uquantf, + dec_weights_uquant + BLOCK_MAX_WEIGHTS * i, + bm.get_weight_quant_mode()); + + compute_quantized_weights_for_decimation( + di, + weight_low_value2[i], + weight_high_value2[i], + dec_weights_ideal + BLOCK_MAX_WEIGHTS * decimation_mode + WEIGHTS_PLANE2_OFFSET, + dec_weights_uquantf + WEIGHTS_PLANE2_OFFSET, + dec_weights_uquant + BLOCK_MAX_WEIGHTS * i + WEIGHTS_PLANE2_OFFSET, + bm.get_weight_quant_mode()); + + // Compute weight quantization errors for the block mode + qwt_errors[i] = compute_error_of_weight_set_2planes( + ei1, + ei2, + di, + dec_weights_uquantf, + dec_weights_uquantf + WEIGHTS_PLANE2_OFFSET); + } + + // Decide the optimal combination of color endpoint encodings and weight encodings + uint8_t partition_format_specifiers[TUNE_MAX_TRIAL_CANDIDATES][BLOCK_MAX_PARTITIONS]; + int block_mode_index[TUNE_MAX_TRIAL_CANDIDATES]; + + quant_method color_quant_level[TUNE_MAX_TRIAL_CANDIDATES]; + quant_method color_quant_level_mod[TUNE_MAX_TRIAL_CANDIDATES]; + + endpoints epm; + merge_endpoints(ei1.ep, ei2.ep, plane2_component, epm); + + const auto& pi = bsd.get_partition_info(1, 0); + unsigned int candidate_count = compute_ideal_endpoint_formats( + pi, blk, epm, qwt_bitcounts, qwt_errors, + config.tune_candidate_limit, + bsd.block_mode_count_1plane_selected, bsd.block_mode_count_1plane_2plane_selected, + partition_format_specifiers, block_mode_index, + color_quant_level, color_quant_level_mod, tmpbuf); + + // Iterate over the N believed-to-be-best modes to find out which one is actually best + float best_errorval_in_mode = ERROR_CALC_DEFAULT; + float best_errorval_in_scb = scb.errorval; + + for (unsigned int i = 0; i < candidate_count; i++) + { + TRACE_NODE(node0, "candidate"); + + const int bm_packed_index = block_mode_index[i]; + assert(bm_packed_index >= static_cast<int>(bsd.block_mode_count_1plane_selected) && + bm_packed_index < static_cast<int>(bsd.block_mode_count_1plane_2plane_selected)); + const block_mode& qw_bm = bsd.block_modes[bm_packed_index]; + + int decimation_mode = qw_bm.decimation_mode; + const auto& di = bsd.get_decimation_info(decimation_mode); + promise(di.weight_count > 0); + + trace_add_data("weight_x", di.weight_x); + trace_add_data("weight_y", di.weight_y); + trace_add_data("weight_z", di.weight_z); + trace_add_data("weight_quant", qw_bm.quant_mode); + + vfloat4 rgbs_color; + vfloat4 rgbo_color; + + symbolic_compressed_block workscb; + endpoints workep = epm; + + uint8_t* u8_weight1_src = dec_weights_uquant + BLOCK_MAX_WEIGHTS * bm_packed_index; + uint8_t* u8_weight2_src = dec_weights_uquant + BLOCK_MAX_WEIGHTS * bm_packed_index + WEIGHTS_PLANE2_OFFSET; + + for (int j = 0; j < di.weight_count; j++) + { + workscb.weights[j] = u8_weight1_src[j]; + workscb.weights[j + WEIGHTS_PLANE2_OFFSET] = u8_weight2_src[j]; + } + + for (unsigned int l = 0; l < config.tune_refinement_limit; l++) + { + recompute_ideal_colors_2planes( + blk, bsd, di, + workscb.weights, workscb.weights + WEIGHTS_PLANE2_OFFSET, + workep, rgbs_color, rgbo_color, plane2_component); + + // Quantize the chosen color + workscb.color_formats[0] = pack_color_endpoints( + workep.endpt0[0], + workep.endpt1[0], + rgbs_color, rgbo_color, + partition_format_specifiers[i][0], + workscb.color_values[0], + color_quant_level[i]); + + // Store header fields + workscb.partition_count = 1; + workscb.partition_index = 0; + workscb.quant_mode = color_quant_level[i]; + workscb.color_formats_matched = 0; + workscb.block_mode = qw_bm.mode_index; + workscb.plane2_component = static_cast<int8_t>(plane2_component); + workscb.block_type = SYM_BTYPE_NONCONST; + + // Pre-realign test + if (l == 0) + { + float errorval = compute_symbolic_block_difference_2plane(config, bsd, workscb, blk); + if (errorval == -ERROR_CALC_DEFAULT) + { + errorval = -errorval; + workscb.block_type = SYM_BTYPE_ERROR; + } + + trace_add_data("error_prerealign", errorval); + best_errorval_in_mode = astc::min(errorval, best_errorval_in_mode); + + // Average refinement improvement is 3.5% per iteration (allow 4.5%), but the first + // iteration can help more so we give it a extra 8% leeway. Use this knowledge to + // drive a heuristic to skip blocks that are unlikely to catch up with the best + // block we have already. + unsigned int iters_remaining = config.tune_refinement_limit - l; + float threshold = (0.045f * static_cast<float>(iters_remaining)) + 1.08f; + if (errorval > (threshold * best_errorval_in_scb)) + { + break; + } + + if (errorval < best_errorval_in_scb) + { + best_errorval_in_scb = errorval; + workscb.errorval = errorval; + scb = workscb; + + if (errorval < tune_errorval_threshold) + { + // Skip remaining candidates - this is "good enough" + i = candidate_count; + break; + } + } + } + + // Perform a final pass over the weights to try to improve them. + bool adjustments; + if (di.weight_count != bsd.texel_count) + { + adjustments = realign_weights_decimated( + config.profile, bsd, blk, workscb); + } + else + { + adjustments = realign_weights_undecimated( + config.profile, bsd, blk, workscb); + } + + // Post-realign test + float errorval = compute_symbolic_block_difference_2plane(config, bsd, workscb, blk); + if (errorval == -ERROR_CALC_DEFAULT) + { + errorval = -errorval; + workscb.block_type = SYM_BTYPE_ERROR; + } + + trace_add_data("error_postrealign", errorval); + best_errorval_in_mode = astc::min(errorval, best_errorval_in_mode); + + // Average refinement improvement is 3.5% per iteration, so skip blocks that are + // unlikely to catch up with the best block we have already. Assume a 4.5% per step to + // give benefit of the doubt ... + unsigned int iters_remaining = config.tune_refinement_limit - 1 - l; + float threshold = (0.045f * static_cast<float>(iters_remaining)) + 1.0f; + if (errorval > (threshold * best_errorval_in_scb)) + { + break; + } + + if (errorval < best_errorval_in_scb) + { + best_errorval_in_scb = errorval; + workscb.errorval = errorval; + scb = workscb; + + if (errorval < tune_errorval_threshold) + { + // Skip remaining candidates - this is "good enough" + i = candidate_count; + break; + } + } + + if (!adjustments) + { + break; + } + } + } + + return best_errorval_in_mode; +} + +/** + * @brief Determine the lowest cross-channel correlation factor. + * + * @param texels_per_block The number of texels in a block. + * @param blk The image block color data to compress. + * + * @return Return the lowest correlation factor. + */ +static float prepare_block_statistics( + int texels_per_block, + const image_block& blk +) { + // Compute covariance matrix, as a collection of 10 scalars that form the upper-triangular row + // of the matrix. The matrix is symmetric, so this is all we need for this use case. + float rs = 0.0f; + float gs = 0.0f; + float bs = 0.0f; + float as = 0.0f; + float rr_var = 0.0f; + float gg_var = 0.0f; + float bb_var = 0.0f; + float aa_var = 0.0f; + float rg_cov = 0.0f; + float rb_cov = 0.0f; + float ra_cov = 0.0f; + float gb_cov = 0.0f; + float ga_cov = 0.0f; + float ba_cov = 0.0f; + + float weight_sum = 0.0f; + + promise(texels_per_block > 0); + for (int i = 0; i < texels_per_block; i++) + { + float weight = hadd_s(blk.channel_weight) / 4.0f; + assert(weight >= 0.0f); + weight_sum += weight; + + float r = blk.data_r[i]; + float g = blk.data_g[i]; + float b = blk.data_b[i]; + float a = blk.data_a[i]; + + float rw = r * weight; + rs += rw; + rr_var += r * rw; + rg_cov += g * rw; + rb_cov += b * rw; + ra_cov += a * rw; + + float gw = g * weight; + gs += gw; + gg_var += g * gw; + gb_cov += b * gw; + ga_cov += a * gw; + + float bw = b * weight; + bs += bw; + bb_var += b * bw; + ba_cov += a * bw; + + float aw = a * weight; + as += aw; + aa_var += a * aw; + } + + float rpt = 1.0f / astc::max(weight_sum, 1e-7f); + + rr_var -= rs * (rs * rpt); + rg_cov -= gs * (rs * rpt); + rb_cov -= bs * (rs * rpt); + ra_cov -= as * (rs * rpt); + + gg_var -= gs * (gs * rpt); + gb_cov -= bs * (gs * rpt); + ga_cov -= as * (gs * rpt); + + bb_var -= bs * (bs * rpt); + ba_cov -= as * (bs * rpt); + + aa_var -= as * (as * rpt); + + // These will give a NaN if a channel is constant - these are fixed up in the next step + rg_cov *= astc::rsqrt(rr_var * gg_var); + rb_cov *= astc::rsqrt(rr_var * bb_var); + ra_cov *= astc::rsqrt(rr_var * aa_var); + gb_cov *= astc::rsqrt(gg_var * bb_var); + ga_cov *= astc::rsqrt(gg_var * aa_var); + ba_cov *= astc::rsqrt(bb_var * aa_var); + + if (astc::isnan(rg_cov)) rg_cov = 1.0f; + if (astc::isnan(rb_cov)) rb_cov = 1.0f; + if (astc::isnan(ra_cov)) ra_cov = 1.0f; + if (astc::isnan(gb_cov)) gb_cov = 1.0f; + if (astc::isnan(ga_cov)) ga_cov = 1.0f; + if (astc::isnan(ba_cov)) ba_cov = 1.0f; + + float lowest_correlation = astc::min(fabsf(rg_cov), fabsf(rb_cov)); + lowest_correlation = astc::min(lowest_correlation, fabsf(ra_cov)); + lowest_correlation = astc::min(lowest_correlation, fabsf(gb_cov)); + lowest_correlation = astc::min(lowest_correlation, fabsf(ga_cov)); + lowest_correlation = astc::min(lowest_correlation, fabsf(ba_cov)); + + // Diagnostic trace points + trace_add_data("min_r", blk.data_min.lane<0>()); + trace_add_data("max_r", blk.data_max.lane<0>()); + trace_add_data("min_g", blk.data_min.lane<1>()); + trace_add_data("max_g", blk.data_max.lane<1>()); + trace_add_data("min_b", blk.data_min.lane<2>()); + trace_add_data("max_b", blk.data_max.lane<2>()); + trace_add_data("min_a", blk.data_min.lane<3>()); + trace_add_data("max_a", blk.data_max.lane<3>()); + trace_add_data("cov_rg", fabsf(rg_cov)); + trace_add_data("cov_rb", fabsf(rb_cov)); + trace_add_data("cov_ra", fabsf(ra_cov)); + trace_add_data("cov_gb", fabsf(gb_cov)); + trace_add_data("cov_ga", fabsf(ga_cov)); + trace_add_data("cov_ba", fabsf(ba_cov)); + + return lowest_correlation; +} + +/* See header for documentation. */ +void compress_block( + const astcenc_contexti& ctx, + const image_block& blk, + physical_compressed_block& pcb, + compression_working_buffers& tmpbuf) +{ + astcenc_profile decode_mode = ctx.config.profile; + symbolic_compressed_block scb; + const block_size_descriptor& bsd = *ctx.bsd; + float lowest_correl; + + TRACE_NODE(node0, "block"); + trace_add_data("pos_x", blk.xpos); + trace_add_data("pos_y", blk.ypos); + trace_add_data("pos_z", blk.zpos); + + // Set stricter block targets for luminance data as we have more bits to play with + bool block_is_l = blk.is_luminance(); + float block_is_l_scale = block_is_l ? 1.0f / 1.5f : 1.0f; + + // Set slightly stricter block targets for lumalpha data as we have more bits to play with + bool block_is_la = blk.is_luminancealpha(); + float block_is_la_scale = block_is_la ? 1.0f / 1.05f : 1.0f; + + bool block_skip_two_plane = false; + int max_partitions = ctx.config.tune_partition_count_limit; + + unsigned int requested_partition_indices[3] { + ctx.config.tune_2partition_index_limit, + ctx.config.tune_3partition_index_limit, + ctx.config.tune_4partition_index_limit + }; + + unsigned int requested_partition_trials[3] { + ctx.config.tune_2partitioning_candidate_limit, + ctx.config.tune_3partitioning_candidate_limit, + ctx.config.tune_4partitioning_candidate_limit + }; + +#if defined(ASTCENC_DIAGNOSTICS) + // Do this early in diagnostic builds so we can dump uniform metrics + // for every block. Do it later in release builds to avoid redundant work! + float error_weight_sum = hadd_s(blk.channel_weight) * bsd.texel_count; + float error_threshold = ctx.config.tune_db_limit + * error_weight_sum + * block_is_l_scale + * block_is_la_scale; + + lowest_correl = prepare_block_statistics(bsd.texel_count, blk); + trace_add_data("lowest_correl", lowest_correl); + trace_add_data("tune_error_threshold", error_threshold); +#endif + + // Detected a constant-color block + if (all(blk.data_min == blk.data_max)) + { + TRACE_NODE(node1, "pass"); + trace_add_data("partition_count", 0); + trace_add_data("plane_count", 1); + + scb.partition_count = 0; + + // Encode as FP16 if using HDR + if ((decode_mode == ASTCENC_PRF_HDR) || + (decode_mode == ASTCENC_PRF_HDR_RGB_LDR_A)) + { + scb.block_type = SYM_BTYPE_CONST_F16; + vint4 color_f16 = float_to_float16(blk.origin_texel); + store(color_f16, scb.constant_color); + } + // Encode as UNORM16 if NOT using HDR + else + { + scb.block_type = SYM_BTYPE_CONST_U16; + vfloat4 color_f32 = clamp(0.0f, 1.0f, blk.origin_texel) * 65535.0f; + vint4 color_u16 = float_to_int_rtn(color_f32); + store(color_u16, scb.constant_color); + } + + trace_add_data("exit", "quality hit"); + + symbolic_to_physical(bsd, scb, pcb); + return; + } + +#if !defined(ASTCENC_DIAGNOSTICS) + float error_weight_sum = hadd_s(blk.channel_weight) * bsd.texel_count; + float error_threshold = ctx.config.tune_db_limit + * error_weight_sum + * block_is_l_scale + * block_is_la_scale; +#endif + + // Set SCB and mode errors to a very high error value + scb.errorval = ERROR_CALC_DEFAULT; + scb.block_type = SYM_BTYPE_ERROR; + + float best_errorvals_for_pcount[BLOCK_MAX_PARTITIONS] { + ERROR_CALC_DEFAULT, ERROR_CALC_DEFAULT, ERROR_CALC_DEFAULT, ERROR_CALC_DEFAULT + }; + + float exit_thresholds_for_pcount[BLOCK_MAX_PARTITIONS] { + 0.0f, + ctx.config.tune_2_partition_early_out_limit_factor, + ctx.config.tune_3_partition_early_out_limit_factor, + 0.0f + }; + + // Trial using 1 plane of weights and 1 partition. + + // Most of the time we test it twice, first with a mode cutoff of 0 and then with the specified + // mode cutoff. This causes an early-out that speeds up encoding of easy blocks. However, this + // optimization is disabled for 4x4 and 5x4 blocks where it nearly always slows down the + // compression and slightly reduces image quality. + + float errorval_mult[2] { + 1.0f / ctx.config.tune_mse_overshoot, + 1.0f + }; + + static const float errorval_overshoot = 1.0f / ctx.config.tune_mse_overshoot; + + // Only enable MODE0 fast path (trial 0) if 2D, and more than 25 texels + int start_trial = 1; + if ((bsd.texel_count >= TUNE_MIN_TEXELS_MODE0_FASTPATH) && (bsd.zdim == 1)) + { + start_trial = 0; + } + + int quant_limit = QUANT_32; + for (int i = start_trial; i < 2; i++) + { + TRACE_NODE(node1, "pass"); + trace_add_data("partition_count", 1); + trace_add_data("plane_count", 1); + trace_add_data("search_mode", i); + + float errorval = compress_symbolic_block_for_partition_1plane( + ctx.config, bsd, blk, i == 0, + error_threshold * errorval_mult[i] * errorval_overshoot, + 1, 0, scb, tmpbuf, QUANT_32); + + // Record the quant level so we can use the filter later searches + const auto& bm = bsd.get_block_mode(scb.block_mode); + quant_limit = bm.get_weight_quant_mode(); + + best_errorvals_for_pcount[0] = astc::min(best_errorvals_for_pcount[0], errorval); + if (errorval < (error_threshold * errorval_mult[i])) + { + trace_add_data("exit", "quality hit"); + goto END_OF_TESTS; + } + } + +#if !defined(ASTCENC_DIAGNOSTICS) + lowest_correl = prepare_block_statistics(bsd.texel_count, blk); +#endif + + block_skip_two_plane = lowest_correl > ctx.config.tune_2_plane_early_out_limit_correlation; + + // Test the four possible 1-partition, 2-planes modes. Do this in reverse, as + // alpha is the most likely to be non-correlated if it is present in the data. + for (int i = BLOCK_MAX_COMPONENTS - 1; i >= 0; i--) + { + TRACE_NODE(node1, "pass"); + trace_add_data("partition_count", 1); + trace_add_data("plane_count", 2); + trace_add_data("plane_component", i); + + if (block_skip_two_plane) + { + trace_add_data("skip", "tune_2_plane_early_out_limit_correlation"); + continue; + } + + if (blk.grayscale && i != 3) + { + trace_add_data("skip", "grayscale block"); + continue; + } + + if (blk.is_constant_channel(i)) + { + trace_add_data("skip", "constant component"); + continue; + } + + float errorval = compress_symbolic_block_for_partition_2planes( + ctx.config, bsd, blk, error_threshold * errorval_overshoot, + i, scb, tmpbuf, quant_limit); + + // If attempting two planes is much worse than the best one plane result + // then further two plane searches are unlikely to help so move on ... + if (errorval > (best_errorvals_for_pcount[0] * 1.85f)) + { + break; + } + + if (errorval < error_threshold) + { + trace_add_data("exit", "quality hit"); + goto END_OF_TESTS; + } + } + + // Find best blocks for 2, 3 and 4 partitions + for (int partition_count = 2; partition_count <= max_partitions; partition_count++) + { + unsigned int partition_indices[TUNE_MAX_PARTITIONING_CANDIDATES]; + + unsigned int requested_indices = requested_partition_indices[partition_count - 2]; + + unsigned int requested_trials = requested_partition_trials[partition_count - 2]; + requested_trials = astc::min(requested_trials, requested_indices); + + unsigned int actual_trials = find_best_partition_candidates( + bsd, blk, partition_count, requested_indices, partition_indices, requested_trials); + + float best_error_in_prev = best_errorvals_for_pcount[partition_count - 2]; + + for (unsigned int i = 0; i < actual_trials; i++) + { + TRACE_NODE(node1, "pass"); + trace_add_data("partition_count", partition_count); + trace_add_data("partition_index", partition_indices[i]); + trace_add_data("plane_count", 1); + trace_add_data("search_mode", i); + + float errorval = compress_symbolic_block_for_partition_1plane( + ctx.config, bsd, blk, false, + error_threshold * errorval_overshoot, + partition_count, partition_indices[i], + scb, tmpbuf, quant_limit); + + best_errorvals_for_pcount[partition_count - 1] = astc::min(best_errorvals_for_pcount[partition_count - 1], errorval); + + // If using N partitions doesn't improve much over using N-1 partitions then skip trying + // N+1. Error can dramatically improve if the data is correlated or non-correlated and + // aligns with a partitioning that suits that encoding, so for this inner loop check add + // a large error scale because the "other" trial could be a lot better. + float best_error = best_errorvals_for_pcount[partition_count - 1]; + float best_error_scale = exit_thresholds_for_pcount[partition_count - 1] * 1.85f; + if (best_error > (best_error_in_prev * best_error_scale)) + { + trace_add_data("skip", "tune_partition_early_out_limit_factor"); + goto END_OF_TESTS; + } + + if (errorval < error_threshold) + { + trace_add_data("exit", "quality hit"); + goto END_OF_TESTS; + } + } + + // If using N partitions doesn't improve much over using N-1 partitions then skip trying N+1 + float best_error = best_errorvals_for_pcount[partition_count - 1]; + float best_error_scale = exit_thresholds_for_pcount[partition_count - 1]; + if (best_error > (best_error_in_prev * best_error_scale)) + { + trace_add_data("skip", "tune_partition_early_out_limit_factor"); + goto END_OF_TESTS; + } + } + + trace_add_data("exit", "quality not hit"); + +END_OF_TESTS: + // If we still have an error block then convert to something we can encode + // TODO: Do something more sensible here, such as average color block + if (scb.block_type == SYM_BTYPE_ERROR) + { +#if defined(ASTCENC_DIAGNOSTICS) + static bool printed_once = false; + if (!printed_once) + { + printed_once = true; + printf("WARN: At least one block failed to find a valid encoding.\n" + " Try increasing compression quality settings.\n\n"); + } +#endif + + scb.block_type = SYM_BTYPE_CONST_U16; + vfloat4 color_f32 = clamp(0.0f, 1.0f, blk.origin_texel) * 65535.0f; + vint4 color_u16 = float_to_int_rtn(color_f32); + store(color_u16, scb.constant_color); + } + + // Compress to a physical block + symbolic_to_physical(bsd, scb, pcb); +} + +#endif diff --git a/thirdparty/astcenc/astcenc_compute_variance.cpp b/thirdparty/astcenc/astcenc_compute_variance.cpp new file mode 100644 index 0000000000..48a4af8cef --- /dev/null +++ b/thirdparty/astcenc/astcenc_compute_variance.cpp @@ -0,0 +1,472 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2022 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +#if !defined(ASTCENC_DECOMPRESS_ONLY) + +/** + * @brief Functions to calculate variance per component in a NxN footprint. + * + * We need N to be parametric, so the routine below uses summed area tables in order to execute in + * O(1) time independent of how big N is. + * + * The addition uses a Brent-Kung-based parallel prefix adder. This uses the prefix tree to first + * perform a binary reduction, and then distributes the results. This method means that there is no + * serial dependency between a given element and the next one, and also significantly improves + * numerical stability allowing us to use floats rather than doubles. + */ + +#include "astcenc_internal.h" + +#include <cassert> + +/** + * @brief Generate a prefix-sum array using the Brent-Kung algorithm. + * + * This will take an input array of the form: + * v0, v1, v2, ... + * ... and modify in-place to turn it into a prefix-sum array of the form: + * v0, v0+v1, v0+v1+v2, ... + * + * @param d The array to prefix-sum. + * @param items The number of items in the array. + * @param stride The item spacing in the array; i.e. dense arrays should use 1. + */ +static void brent_kung_prefix_sum( + vfloat4* d, + size_t items, + int stride +) { + if (items < 2) + return; + + size_t lc_stride = 2; + size_t log2_stride = 1; + + // The reduction-tree loop + do { + size_t step = lc_stride >> 1; + size_t start = lc_stride - 1; + size_t iters = items >> log2_stride; + + vfloat4 *da = d + (start * stride); + ptrdiff_t ofs = -static_cast<ptrdiff_t>(step * stride); + size_t ofs_stride = stride << log2_stride; + + while (iters) + { + *da = *da + da[ofs]; + da += ofs_stride; + iters--; + } + + log2_stride += 1; + lc_stride <<= 1; + } while (lc_stride <= items); + + // The expansion-tree loop + do { + log2_stride -= 1; + lc_stride >>= 1; + + size_t step = lc_stride >> 1; + size_t start = step + lc_stride - 1; + size_t iters = (items - step) >> log2_stride; + + vfloat4 *da = d + (start * stride); + ptrdiff_t ofs = -static_cast<ptrdiff_t>(step * stride); + size_t ofs_stride = stride << log2_stride; + + while (iters) + { + *da = *da + da[ofs]; + da += ofs_stride; + iters--; + } + } while (lc_stride > 2); +} + +/* See header for documentation. */ +void compute_pixel_region_variance( + astcenc_contexti& ctx, + const pixel_region_args& arg +) { + // Unpack the memory structure into local variables + const astcenc_image* img = arg.img; + astcenc_swizzle swz = arg.swz; + bool have_z = arg.have_z; + + int size_x = arg.size_x; + int size_y = arg.size_y; + int size_z = arg.size_z; + + int offset_x = arg.offset_x; + int offset_y = arg.offset_y; + int offset_z = arg.offset_z; + + int alpha_kernel_radius = arg.alpha_kernel_radius; + + float* input_alpha_averages = ctx.input_alpha_averages; + vfloat4* work_memory = arg.work_memory; + + // Compute memory sizes and dimensions that we need + int kernel_radius = alpha_kernel_radius; + int kerneldim = 2 * kernel_radius + 1; + int kernel_radius_xy = kernel_radius; + int kernel_radius_z = have_z ? kernel_radius : 0; + + int padsize_x = size_x + kerneldim; + int padsize_y = size_y + kerneldim; + int padsize_z = size_z + (have_z ? kerneldim : 0); + int sizeprod = padsize_x * padsize_y * padsize_z; + + int zd_start = have_z ? 1 : 0; + + vfloat4 *varbuf1 = work_memory; + vfloat4 *varbuf2 = work_memory + sizeprod; + + // Scaling factors to apply to Y and Z for accesses into the work buffers + int yst = padsize_x; + int zst = padsize_x * padsize_y; + + // Scaling factors to apply to Y and Z for accesses into result buffers + int ydt = img->dim_x; + int zdt = img->dim_x * img->dim_y; + + // Macros to act as accessor functions for the work-memory + #define VARBUF1(z, y, x) varbuf1[z * zst + y * yst + x] + #define VARBUF2(z, y, x) varbuf2[z * zst + y * yst + x] + + // Load N and N^2 values into the work buffers + if (img->data_type == ASTCENC_TYPE_U8) + { + // Swizzle data structure 4 = ZERO, 5 = ONE + uint8_t data[6]; + data[ASTCENC_SWZ_0] = 0; + data[ASTCENC_SWZ_1] = 255; + + for (int z = zd_start; z < padsize_z; z++) + { + int z_src = (z - zd_start) + offset_z - kernel_radius_z; + z_src = astc::clamp(z_src, 0, static_cast<int>(img->dim_z - 1)); + uint8_t* data8 = static_cast<uint8_t*>(img->data[z_src]); + + for (int y = 1; y < padsize_y; y++) + { + int y_src = (y - 1) + offset_y - kernel_radius_xy; + y_src = astc::clamp(y_src, 0, static_cast<int>(img->dim_y - 1)); + + for (int x = 1; x < padsize_x; x++) + { + int x_src = (x - 1) + offset_x - kernel_radius_xy; + x_src = astc::clamp(x_src, 0, static_cast<int>(img->dim_x - 1)); + + data[0] = data8[(4 * img->dim_x * y_src) + (4 * x_src )]; + data[1] = data8[(4 * img->dim_x * y_src) + (4 * x_src + 1)]; + data[2] = data8[(4 * img->dim_x * y_src) + (4 * x_src + 2)]; + data[3] = data8[(4 * img->dim_x * y_src) + (4 * x_src + 3)]; + + uint8_t r = data[swz.r]; + uint8_t g = data[swz.g]; + uint8_t b = data[swz.b]; + uint8_t a = data[swz.a]; + + vfloat4 d = vfloat4 (r * (1.0f / 255.0f), + g * (1.0f / 255.0f), + b * (1.0f / 255.0f), + a * (1.0f / 255.0f)); + + VARBUF1(z, y, x) = d; + VARBUF2(z, y, x) = d * d; + } + } + } + } + else if (img->data_type == ASTCENC_TYPE_F16) + { + // Swizzle data structure 4 = ZERO, 5 = ONE (in FP16) + uint16_t data[6]; + data[ASTCENC_SWZ_0] = 0; + data[ASTCENC_SWZ_1] = 0x3C00; + + for (int z = zd_start; z < padsize_z; z++) + { + int z_src = (z - zd_start) + offset_z - kernel_radius_z; + z_src = astc::clamp(z_src, 0, static_cast<int>(img->dim_z - 1)); + uint16_t* data16 = static_cast<uint16_t*>(img->data[z_src]); + + for (int y = 1; y < padsize_y; y++) + { + int y_src = (y - 1) + offset_y - kernel_radius_xy; + y_src = astc::clamp(y_src, 0, static_cast<int>(img->dim_y - 1)); + + for (int x = 1; x < padsize_x; x++) + { + int x_src = (x - 1) + offset_x - kernel_radius_xy; + x_src = astc::clamp(x_src, 0, static_cast<int>(img->dim_x - 1)); + + data[0] = data16[(4 * img->dim_x * y_src) + (4 * x_src )]; + data[1] = data16[(4 * img->dim_x * y_src) + (4 * x_src + 1)]; + data[2] = data16[(4 * img->dim_x * y_src) + (4 * x_src + 2)]; + data[3] = data16[(4 * img->dim_x * y_src) + (4 * x_src + 3)]; + + vint4 di(data[swz.r], data[swz.g], data[swz.b], data[swz.a]); + vfloat4 d = float16_to_float(di); + + VARBUF1(z, y, x) = d; + VARBUF2(z, y, x) = d * d; + } + } + } + } + else // if (img->data_type == ASTCENC_TYPE_F32) + { + assert(img->data_type == ASTCENC_TYPE_F32); + + // Swizzle data structure 4 = ZERO, 5 = ONE (in FP16) + float data[6]; + data[ASTCENC_SWZ_0] = 0.0f; + data[ASTCENC_SWZ_1] = 1.0f; + + for (int z = zd_start; z < padsize_z; z++) + { + int z_src = (z - zd_start) + offset_z - kernel_radius_z; + z_src = astc::clamp(z_src, 0, static_cast<int>(img->dim_z - 1)); + float* data32 = static_cast<float*>(img->data[z_src]); + + for (int y = 1; y < padsize_y; y++) + { + int y_src = (y - 1) + offset_y - kernel_radius_xy; + y_src = astc::clamp(y_src, 0, static_cast<int>(img->dim_y - 1)); + + for (int x = 1; x < padsize_x; x++) + { + int x_src = (x - 1) + offset_x - kernel_radius_xy; + x_src = astc::clamp(x_src, 0, static_cast<int>(img->dim_x - 1)); + + data[0] = data32[(4 * img->dim_x * y_src) + (4 * x_src )]; + data[1] = data32[(4 * img->dim_x * y_src) + (4 * x_src + 1)]; + data[2] = data32[(4 * img->dim_x * y_src) + (4 * x_src + 2)]; + data[3] = data32[(4 * img->dim_x * y_src) + (4 * x_src + 3)]; + + float r = data[swz.r]; + float g = data[swz.g]; + float b = data[swz.b]; + float a = data[swz.a]; + + vfloat4 d(r, g, b, a); + + VARBUF1(z, y, x) = d; + VARBUF2(z, y, x) = d * d; + } + } + } + } + + // Pad with an extra layer of 0s; this forms the edge of the SAT tables + vfloat4 vbz = vfloat4::zero(); + for (int z = 0; z < padsize_z; z++) + { + for (int y = 0; y < padsize_y; y++) + { + VARBUF1(z, y, 0) = vbz; + VARBUF2(z, y, 0) = vbz; + } + + for (int x = 0; x < padsize_x; x++) + { + VARBUF1(z, 0, x) = vbz; + VARBUF2(z, 0, x) = vbz; + } + } + + if (have_z) + { + for (int y = 0; y < padsize_y; y++) + { + for (int x = 0; x < padsize_x; x++) + { + VARBUF1(0, y, x) = vbz; + VARBUF2(0, y, x) = vbz; + } + } + } + + // Generate summed-area tables for N and N^2; this is done in-place, using + // a Brent-Kung parallel-prefix based algorithm to minimize precision loss + for (int z = zd_start; z < padsize_z; z++) + { + for (int y = 1; y < padsize_y; y++) + { + brent_kung_prefix_sum(&(VARBUF1(z, y, 1)), padsize_x - 1, 1); + brent_kung_prefix_sum(&(VARBUF2(z, y, 1)), padsize_x - 1, 1); + } + } + + for (int z = zd_start; z < padsize_z; z++) + { + for (int x = 1; x < padsize_x; x++) + { + brent_kung_prefix_sum(&(VARBUF1(z, 1, x)), padsize_y - 1, yst); + brent_kung_prefix_sum(&(VARBUF2(z, 1, x)), padsize_y - 1, yst); + } + } + + if (have_z) + { + for (int y = 1; y < padsize_y; y++) + { + for (int x = 1; x < padsize_x; x++) + { + brent_kung_prefix_sum(&(VARBUF1(1, y, x)), padsize_z - 1, zst); + brent_kung_prefix_sum(&(VARBUF2(1, y, x)), padsize_z - 1, zst); + } + } + } + + // Compute a few constants used in the variance-calculation. + float alpha_kdim = static_cast<float>(2 * alpha_kernel_radius + 1); + float alpha_rsamples; + + if (have_z) + { + alpha_rsamples = 1.0f / (alpha_kdim * alpha_kdim * alpha_kdim); + } + else + { + alpha_rsamples = 1.0f / (alpha_kdim * alpha_kdim); + } + + // Use the summed-area tables to compute variance for each neighborhood + if (have_z) + { + for (int z = 0; z < size_z; z++) + { + int z_src = z + kernel_radius_z; + int z_dst = z + offset_z; + int z_low = z_src - alpha_kernel_radius; + int z_high = z_src + alpha_kernel_radius + 1; + + for (int y = 0; y < size_y; y++) + { + int y_src = y + kernel_radius_xy; + int y_dst = y + offset_y; + int y_low = y_src - alpha_kernel_radius; + int y_high = y_src + alpha_kernel_radius + 1; + + for (int x = 0; x < size_x; x++) + { + int x_src = x + kernel_radius_xy; + int x_dst = x + offset_x; + int x_low = x_src - alpha_kernel_radius; + int x_high = x_src + alpha_kernel_radius + 1; + + // Summed-area table lookups for alpha average + float vasum = ( VARBUF1(z_high, y_low, x_low).lane<3>() + - VARBUF1(z_high, y_low, x_high).lane<3>() + - VARBUF1(z_high, y_high, x_low).lane<3>() + + VARBUF1(z_high, y_high, x_high).lane<3>()) - + ( VARBUF1(z_low, y_low, x_low).lane<3>() + - VARBUF1(z_low, y_low, x_high).lane<3>() + - VARBUF1(z_low, y_high, x_low).lane<3>() + + VARBUF1(z_low, y_high, x_high).lane<3>()); + + int out_index = z_dst * zdt + y_dst * ydt + x_dst; + input_alpha_averages[out_index] = (vasum * alpha_rsamples); + } + } + } + } + else + { + for (int y = 0; y < size_y; y++) + { + int y_src = y + kernel_radius_xy; + int y_dst = y + offset_y; + int y_low = y_src - alpha_kernel_radius; + int y_high = y_src + alpha_kernel_radius + 1; + + for (int x = 0; x < size_x; x++) + { + int x_src = x + kernel_radius_xy; + int x_dst = x + offset_x; + int x_low = x_src - alpha_kernel_radius; + int x_high = x_src + alpha_kernel_radius + 1; + + // Summed-area table lookups for alpha average + float vasum = VARBUF1(0, y_low, x_low).lane<3>() + - VARBUF1(0, y_low, x_high).lane<3>() + - VARBUF1(0, y_high, x_low).lane<3>() + + VARBUF1(0, y_high, x_high).lane<3>(); + + int out_index = y_dst * ydt + x_dst; + input_alpha_averages[out_index] = (vasum * alpha_rsamples); + } + } + } +} + +/* See header for documentation. */ +unsigned int init_compute_averages( + const astcenc_image& img, + unsigned int alpha_kernel_radius, + const astcenc_swizzle& swz, + avg_args& ag +) { + unsigned int size_x = img.dim_x; + unsigned int size_y = img.dim_y; + unsigned int size_z = img.dim_z; + + // Compute maximum block size and from that the working memory buffer size + unsigned int kernel_radius = alpha_kernel_radius; + unsigned int kerneldim = 2 * kernel_radius + 1; + + bool have_z = (size_z > 1); + unsigned int max_blk_size_xy = have_z ? 16 : 32; + unsigned int max_blk_size_z = astc::min(size_z, have_z ? 16u : 1u); + + unsigned int max_padsize_xy = max_blk_size_xy + kerneldim; + unsigned int max_padsize_z = max_blk_size_z + (have_z ? kerneldim : 0); + + // Perform block-wise averages calculations across the image + // Initialize fields which are not populated until later + ag.arg.size_x = 0; + ag.arg.size_y = 0; + ag.arg.size_z = 0; + ag.arg.offset_x = 0; + ag.arg.offset_y = 0; + ag.arg.offset_z = 0; + ag.arg.work_memory = nullptr; + + ag.arg.img = &img; + ag.arg.swz = swz; + ag.arg.have_z = have_z; + ag.arg.alpha_kernel_radius = alpha_kernel_radius; + + ag.img_size_x = size_x; + ag.img_size_y = size_y; + ag.img_size_z = size_z; + ag.blk_size_xy = max_blk_size_xy; + ag.blk_size_z = max_blk_size_z; + ag.work_memory_size = 2 * max_padsize_xy * max_padsize_xy * max_padsize_z; + + // The parallel task count + unsigned int z_tasks = (size_z + max_blk_size_z - 1) / max_blk_size_z; + unsigned int y_tasks = (size_y + max_blk_size_xy - 1) / max_blk_size_xy; + return z_tasks * y_tasks; +} + +#endif diff --git a/thirdparty/astcenc/astcenc_decompress_symbolic.cpp b/thirdparty/astcenc/astcenc_decompress_symbolic.cpp new file mode 100644 index 0000000000..39e5525c3b --- /dev/null +++ b/thirdparty/astcenc/astcenc_decompress_symbolic.cpp @@ -0,0 +1,623 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2023 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief Functions to decompress a symbolic block. + */ + +#include "astcenc_internal.h" + +#include <stdio.h> +#include <assert.h> + +/** + * @brief Compute the integer linear interpolation of two color endpoints. + * + * @param decode_mode The ASTC profile (linear or sRGB) + * @param color0 The endpoint0 color. + * @param color1 The endpoint1 color. + * @param weights The interpolation weight (between 0 and 64). + * + * @return The interpolated color. + */ +static vint4 lerp_color_int( + astcenc_profile decode_mode, + vint4 color0, + vint4 color1, + vint4 weights +) { + vint4 weight1 = weights; + vint4 weight0 = vint4(64) - weight1; + + if (decode_mode == ASTCENC_PRF_LDR_SRGB) + { + color0 = asr<8>(color0); + color1 = asr<8>(color1); + } + + vint4 color = (color0 * weight0) + (color1 * weight1) + vint4(32); + color = asr<6>(color); + + if (decode_mode == ASTCENC_PRF_LDR_SRGB) + { + color = color * vint4(257); + } + + return color; +} + + +/** + * @brief Convert integer color value into a float value for the decoder. + * + * @param data The integer color value post-interpolation. + * @param lns_mask If set treat lane as HDR (LNS) else LDR (unorm16). + * + * @return The float color value. + */ +static inline vfloat4 decode_texel( + vint4 data, + vmask4 lns_mask +) { + vint4 color_lns = vint4::zero(); + vint4 color_unorm = vint4::zero(); + + if (any(lns_mask)) + { + color_lns = lns_to_sf16(data); + } + + if (!all(lns_mask)) + { + color_unorm = unorm16_to_sf16(data); + } + + // Pick components and then convert to FP16 + vint4 datai = select(color_unorm, color_lns, lns_mask); + return float16_to_float(datai); +} + +/* See header for documentation. */ +void unpack_weights( + const block_size_descriptor& bsd, + const symbolic_compressed_block& scb, + const decimation_info& di, + bool is_dual_plane, + int weights_plane1[BLOCK_MAX_TEXELS], + int weights_plane2[BLOCK_MAX_TEXELS] +) { + // Safe to overshoot as all arrays are allocated to full size + if (!is_dual_plane) + { + // Build full 64-entry weight lookup table + vint4 tab0(reinterpret_cast<const int*>(scb.weights + 0)); + vint4 tab1(reinterpret_cast<const int*>(scb.weights + 16)); + vint4 tab2(reinterpret_cast<const int*>(scb.weights + 32)); + vint4 tab3(reinterpret_cast<const int*>(scb.weights + 48)); + + vint tab0p, tab1p, tab2p, tab3p; + vtable_prepare(tab0, tab1, tab2, tab3, tab0p, tab1p, tab2p, tab3p); + + for (unsigned int i = 0; i < bsd.texel_count; i += ASTCENC_SIMD_WIDTH) + { + vint summed_value(8); + vint weight_count(di.texel_weight_count + i); + int max_weight_count = hmax(weight_count).lane<0>(); + + promise(max_weight_count > 0); + for (int j = 0; j < max_weight_count; j++) + { + vint texel_weights(di.texel_weights_tr[j] + i); + vint texel_weights_int(di.texel_weight_contribs_int_tr[j] + i); + + summed_value += vtable_8bt_32bi(tab0p, tab1p, tab2p, tab3p, texel_weights) * texel_weights_int; + } + + store(lsr<4>(summed_value), weights_plane1 + i); + } + } + else + { + // Build a 32-entry weight lookup table per plane + // Plane 1 + vint4 tab0_plane1(reinterpret_cast<const int*>(scb.weights + 0)); + vint4 tab1_plane1(reinterpret_cast<const int*>(scb.weights + 16)); + vint tab0_plane1p, tab1_plane1p; + vtable_prepare(tab0_plane1, tab1_plane1, tab0_plane1p, tab1_plane1p); + + // Plane 2 + vint4 tab0_plane2(reinterpret_cast<const int*>(scb.weights + 32)); + vint4 tab1_plane2(reinterpret_cast<const int*>(scb.weights + 48)); + vint tab0_plane2p, tab1_plane2p; + vtable_prepare(tab0_plane2, tab1_plane2, tab0_plane2p, tab1_plane2p); + + for (unsigned int i = 0; i < bsd.texel_count; i += ASTCENC_SIMD_WIDTH) + { + vint sum_plane1(8); + vint sum_plane2(8); + + vint weight_count(di.texel_weight_count + i); + int max_weight_count = hmax(weight_count).lane<0>(); + + promise(max_weight_count > 0); + for (int j = 0; j < max_weight_count; j++) + { + vint texel_weights(di.texel_weights_tr[j] + i); + vint texel_weights_int(di.texel_weight_contribs_int_tr[j] + i); + + sum_plane1 += vtable_8bt_32bi(tab0_plane1p, tab1_plane1p, texel_weights) * texel_weights_int; + sum_plane2 += vtable_8bt_32bi(tab0_plane2p, tab1_plane2p, texel_weights) * texel_weights_int; + } + + store(lsr<4>(sum_plane1), weights_plane1 + i); + store(lsr<4>(sum_plane2), weights_plane2 + i); + } + } +} + +/** + * @brief Return an FP32 NaN value for use in error colors. + * + * This NaN encoding will turn into 0xFFFF when converted to an FP16 NaN. + * + * @return The float color value. + */ +static float error_color_nan() +{ + if32 v; + v.u = 0xFFFFE000U; + return v.f; +} + +/* See header for documentation. */ +void decompress_symbolic_block( + astcenc_profile decode_mode, + const block_size_descriptor& bsd, + int xpos, + int ypos, + int zpos, + const symbolic_compressed_block& scb, + image_block& blk +) { + blk.xpos = xpos; + blk.ypos = ypos; + blk.zpos = zpos; + + blk.data_min = vfloat4::zero(); + blk.data_mean = vfloat4::zero(); + blk.data_max = vfloat4::zero(); + blk.grayscale = false; + + // If we detected an error-block, blow up immediately. + if (scb.block_type == SYM_BTYPE_ERROR) + { + for (unsigned int i = 0; i < bsd.texel_count; i++) + { + blk.data_r[i] = error_color_nan(); + blk.data_g[i] = error_color_nan(); + blk.data_b[i] = error_color_nan(); + blk.data_a[i] = error_color_nan(); + blk.rgb_lns[i] = 0; + blk.alpha_lns[i] = 0; + } + + return; + } + + if ((scb.block_type == SYM_BTYPE_CONST_F16) || + (scb.block_type == SYM_BTYPE_CONST_U16)) + { + vfloat4 color; + uint8_t use_lns = 0; + + // UNORM16 constant color block + if (scb.block_type == SYM_BTYPE_CONST_U16) + { + vint4 colori(scb.constant_color); + + // For sRGB decoding a real decoder would just use the top 8 bits for color conversion. + // We don't color convert, so rescale the top 8 bits into the full 16 bit dynamic range. + if (decode_mode == ASTCENC_PRF_LDR_SRGB) + { + colori = asr<8>(colori) * 257; + } + + vint4 colorf16 = unorm16_to_sf16(colori); + color = float16_to_float(colorf16); + } + // FLOAT16 constant color block + else + { + switch (decode_mode) + { + case ASTCENC_PRF_LDR_SRGB: + case ASTCENC_PRF_LDR: + color = vfloat4(error_color_nan()); + break; + case ASTCENC_PRF_HDR_RGB_LDR_A: + case ASTCENC_PRF_HDR: + // Constant-color block; unpack from FP16 to FP32. + color = float16_to_float(vint4(scb.constant_color)); + use_lns = 1; + break; + } + } + + for (unsigned int i = 0; i < bsd.texel_count; i++) + { + blk.data_r[i] = color.lane<0>(); + blk.data_g[i] = color.lane<1>(); + blk.data_b[i] = color.lane<2>(); + blk.data_a[i] = color.lane<3>(); + blk.rgb_lns[i] = use_lns; + blk.alpha_lns[i] = use_lns; + } + + return; + } + + // Get the appropriate partition-table entry + int partition_count = scb.partition_count; + const auto& pi = bsd.get_partition_info(partition_count, scb.partition_index); + + // Get the appropriate block descriptors + const auto& bm = bsd.get_block_mode(scb.block_mode); + const auto& di = bsd.get_decimation_info(bm.decimation_mode); + + bool is_dual_plane = static_cast<bool>(bm.is_dual_plane); + + // Unquantize and undecimate the weights + int plane1_weights[BLOCK_MAX_TEXELS]; + int plane2_weights[BLOCK_MAX_TEXELS]; + unpack_weights(bsd, scb, di, is_dual_plane, plane1_weights, plane2_weights); + + // Now that we have endpoint colors and weights, we can unpack texel colors + int plane2_component = scb.plane2_component; + vmask4 plane2_mask = vint4::lane_id() == vint4(plane2_component); + + for (int i = 0; i < partition_count; i++) + { + // Decode the color endpoints for this partition + vint4 ep0; + vint4 ep1; + bool rgb_lns; + bool a_lns; + + unpack_color_endpoints(decode_mode, + scb.color_formats[i], + scb.color_values[i], + rgb_lns, a_lns, + ep0, ep1); + + vmask4 lns_mask(rgb_lns, rgb_lns, rgb_lns, a_lns); + + int texel_count = pi.partition_texel_count[i]; + for (int j = 0; j < texel_count; j++) + { + int tix = pi.texels_of_partition[i][j]; + vint4 weight = select(vint4(plane1_weights[tix]), vint4(plane2_weights[tix]), plane2_mask); + vint4 color = lerp_color_int(decode_mode, ep0, ep1, weight); + vfloat4 colorf = decode_texel(color, lns_mask); + + blk.data_r[tix] = colorf.lane<0>(); + blk.data_g[tix] = colorf.lane<1>(); + blk.data_b[tix] = colorf.lane<2>(); + blk.data_a[tix] = colorf.lane<3>(); + } + } +} + +#if !defined(ASTCENC_DECOMPRESS_ONLY) + +/* See header for documentation. */ +float compute_symbolic_block_difference_2plane( + const astcenc_config& config, + const block_size_descriptor& bsd, + const symbolic_compressed_block& scb, + const image_block& blk +) { + // If we detected an error-block, blow up immediately. + if (scb.block_type == SYM_BTYPE_ERROR) + { + return ERROR_CALC_DEFAULT; + } + + assert(scb.block_mode >= 0); + assert(scb.partition_count == 1); + assert(bsd.get_block_mode(scb.block_mode).is_dual_plane == 1); + + // Get the appropriate block descriptor + const block_mode& bm = bsd.get_block_mode(scb.block_mode); + const decimation_info& di = bsd.get_decimation_info(bm.decimation_mode); + + // Unquantize and undecimate the weights + int plane1_weights[BLOCK_MAX_TEXELS]; + int plane2_weights[BLOCK_MAX_TEXELS]; + unpack_weights(bsd, scb, di, true, plane1_weights, plane2_weights); + + vmask4 plane2_mask = vint4::lane_id() == vint4(scb.plane2_component); + + vfloat4 summa = vfloat4::zero(); + + // Decode the color endpoints for this partition + vint4 ep0; + vint4 ep1; + bool rgb_lns; + bool a_lns; + + unpack_color_endpoints(config.profile, + scb.color_formats[0], + scb.color_values[0], + rgb_lns, a_lns, + ep0, ep1); + + // Unpack and compute error for each texel in the partition + unsigned int texel_count = bsd.texel_count; + for (unsigned int i = 0; i < texel_count; i++) + { + vint4 weight = select(vint4(plane1_weights[i]), vint4(plane2_weights[i]), plane2_mask); + vint4 colori = lerp_color_int(config.profile, ep0, ep1, weight); + + vfloat4 color = int_to_float(colori); + vfloat4 oldColor = blk.texel(i); + + // Compare error using a perceptual decode metric for RGBM textures + if (config.flags & ASTCENC_FLG_MAP_RGBM) + { + // Fail encodings that result in zero weight M pixels. Note that this can cause + // "interesting" artifacts if we reject all useful encodings - we typically get max + // brightness encodings instead which look just as bad. We recommend users apply a + // bias to their stored M value, limiting the lower value to 16 or 32 to avoid + // getting small M values post-quantization, but we can't prove it would never + // happen, especially at low bit rates ... + if (color.lane<3>() == 0.0f) + { + return -ERROR_CALC_DEFAULT; + } + + // Compute error based on decoded RGBM color + color = vfloat4( + color.lane<0>() * color.lane<3>() * config.rgbm_m_scale, + color.lane<1>() * color.lane<3>() * config.rgbm_m_scale, + color.lane<2>() * color.lane<3>() * config.rgbm_m_scale, + 1.0f + ); + + oldColor = vfloat4( + oldColor.lane<0>() * oldColor.lane<3>() * config.rgbm_m_scale, + oldColor.lane<1>() * oldColor.lane<3>() * config.rgbm_m_scale, + oldColor.lane<2>() * oldColor.lane<3>() * config.rgbm_m_scale, + 1.0f + ); + } + + vfloat4 error = oldColor - color; + error = min(abs(error), 1e15f); + error = error * error; + + summa += min(dot(error, blk.channel_weight), ERROR_CALC_DEFAULT); + } + + return summa.lane<0>(); +} + +/* See header for documentation. */ +float compute_symbolic_block_difference_1plane( + const astcenc_config& config, + const block_size_descriptor& bsd, + const symbolic_compressed_block& scb, + const image_block& blk +) { + assert(bsd.get_block_mode(scb.block_mode).is_dual_plane == 0); + + // If we detected an error-block, blow up immediately. + if (scb.block_type == SYM_BTYPE_ERROR) + { + return ERROR_CALC_DEFAULT; + } + + assert(scb.block_mode >= 0); + + // Get the appropriate partition-table entry + unsigned int partition_count = scb.partition_count; + const auto& pi = bsd.get_partition_info(partition_count, scb.partition_index); + + // Get the appropriate block descriptor + const block_mode& bm = bsd.get_block_mode(scb.block_mode); + const decimation_info& di = bsd.get_decimation_info(bm.decimation_mode); + + // Unquantize and undecimate the weights + int plane1_weights[BLOCK_MAX_TEXELS]; + unpack_weights(bsd, scb, di, false, plane1_weights, nullptr); + + vfloat4 summa = vfloat4::zero(); + for (unsigned int i = 0; i < partition_count; i++) + { + // Decode the color endpoints for this partition + vint4 ep0; + vint4 ep1; + bool rgb_lns; + bool a_lns; + + unpack_color_endpoints(config.profile, + scb.color_formats[i], + scb.color_values[i], + rgb_lns, a_lns, + ep0, ep1); + + // Unpack and compute error for each texel in the partition + unsigned int texel_count = pi.partition_texel_count[i]; + for (unsigned int j = 0; j < texel_count; j++) + { + unsigned int tix = pi.texels_of_partition[i][j]; + vint4 colori = lerp_color_int(config.profile, ep0, ep1, + vint4(plane1_weights[tix])); + + vfloat4 color = int_to_float(colori); + vfloat4 oldColor = blk.texel(tix); + + // Compare error using a perceptual decode metric for RGBM textures + if (config.flags & ASTCENC_FLG_MAP_RGBM) + { + // Fail encodings that result in zero weight M pixels. Note that this can cause + // "interesting" artifacts if we reject all useful encodings - we typically get max + // brightness encodings instead which look just as bad. We recommend users apply a + // bias to their stored M value, limiting the lower value to 16 or 32 to avoid + // getting small M values post-quantization, but we can't prove it would never + // happen, especially at low bit rates ... + if (color.lane<3>() == 0.0f) + { + return -ERROR_CALC_DEFAULT; + } + + // Compute error based on decoded RGBM color + color = vfloat4( + color.lane<0>() * color.lane<3>() * config.rgbm_m_scale, + color.lane<1>() * color.lane<3>() * config.rgbm_m_scale, + color.lane<2>() * color.lane<3>() * config.rgbm_m_scale, + 1.0f + ); + + oldColor = vfloat4( + oldColor.lane<0>() * oldColor.lane<3>() * config.rgbm_m_scale, + oldColor.lane<1>() * oldColor.lane<3>() * config.rgbm_m_scale, + oldColor.lane<2>() * oldColor.lane<3>() * config.rgbm_m_scale, + 1.0f + ); + } + + vfloat4 error = oldColor - color; + error = min(abs(error), 1e15f); + error = error * error; + + summa += min(dot(error, blk.channel_weight), ERROR_CALC_DEFAULT); + } + } + + return summa.lane<0>(); +} + +/* See header for documentation. */ +float compute_symbolic_block_difference_1plane_1partition( + const astcenc_config& config, + const block_size_descriptor& bsd, + const symbolic_compressed_block& scb, + const image_block& blk +) { + // If we detected an error-block, blow up immediately. + if (scb.block_type == SYM_BTYPE_ERROR) + { + return ERROR_CALC_DEFAULT; + } + + assert(scb.block_mode >= 0); + assert(bsd.get_partition_info(scb.partition_count, scb.partition_index).partition_count == 1); + + // Get the appropriate block descriptor + const block_mode& bm = bsd.get_block_mode(scb.block_mode); + const decimation_info& di = bsd.get_decimation_info(bm.decimation_mode); + + // Unquantize and undecimate the weights + alignas(ASTCENC_VECALIGN) int plane1_weights[BLOCK_MAX_TEXELS]; + unpack_weights(bsd, scb, di, false, plane1_weights, nullptr); + + // Decode the color endpoints for this partition + vint4 ep0; + vint4 ep1; + bool rgb_lns; + bool a_lns; + + unpack_color_endpoints(config.profile, + scb.color_formats[0], + scb.color_values[0], + rgb_lns, a_lns, + ep0, ep1); + + + // Pre-shift sRGB so things round correctly + if (config.profile == ASTCENC_PRF_LDR_SRGB) + { + ep0 = asr<8>(ep0); + ep1 = asr<8>(ep1); + } + + // Unpack and compute error for each texel in the partition + vfloatacc summav = vfloatacc::zero(); + + vint lane_id = vint::lane_id(); + vint srgb_scale(config.profile == ASTCENC_PRF_LDR_SRGB ? 257 : 1); + + unsigned int texel_count = bsd.texel_count; + for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) + { + // Compute EP1 contribution + vint weight1 = vint::loada(plane1_weights + i); + vint ep1_r = vint(ep1.lane<0>()) * weight1; + vint ep1_g = vint(ep1.lane<1>()) * weight1; + vint ep1_b = vint(ep1.lane<2>()) * weight1; + vint ep1_a = vint(ep1.lane<3>()) * weight1; + + // Compute EP0 contribution + vint weight0 = vint(64) - weight1; + vint ep0_r = vint(ep0.lane<0>()) * weight0; + vint ep0_g = vint(ep0.lane<1>()) * weight0; + vint ep0_b = vint(ep0.lane<2>()) * weight0; + vint ep0_a = vint(ep0.lane<3>()) * weight0; + + // Shift so things round correctly + vint colori_r = asr<6>(ep0_r + ep1_r + vint(32)) * srgb_scale; + vint colori_g = asr<6>(ep0_g + ep1_g + vint(32)) * srgb_scale; + vint colori_b = asr<6>(ep0_b + ep1_b + vint(32)) * srgb_scale; + vint colori_a = asr<6>(ep0_a + ep1_a + vint(32)) * srgb_scale; + + // Compute color diff + vfloat color_r = int_to_float(colori_r); + vfloat color_g = int_to_float(colori_g); + vfloat color_b = int_to_float(colori_b); + vfloat color_a = int_to_float(colori_a); + + vfloat color_orig_r = loada(blk.data_r + i); + vfloat color_orig_g = loada(blk.data_g + i); + vfloat color_orig_b = loada(blk.data_b + i); + vfloat color_orig_a = loada(blk.data_a + i); + + vfloat color_error_r = min(abs(color_orig_r - color_r), vfloat(1e15f)); + vfloat color_error_g = min(abs(color_orig_g - color_g), vfloat(1e15f)); + vfloat color_error_b = min(abs(color_orig_b - color_b), vfloat(1e15f)); + vfloat color_error_a = min(abs(color_orig_a - color_a), vfloat(1e15f)); + + // Compute squared error metric + color_error_r = color_error_r * color_error_r; + color_error_g = color_error_g * color_error_g; + color_error_b = color_error_b * color_error_b; + color_error_a = color_error_a * color_error_a; + + vfloat metric = color_error_r * blk.channel_weight.lane<0>() + + color_error_g * blk.channel_weight.lane<1>() + + color_error_b * blk.channel_weight.lane<2>() + + color_error_a * blk.channel_weight.lane<3>(); + + // Mask off bad lanes + vmask mask = lane_id < vint(texel_count); + lane_id += vint(ASTCENC_SIMD_WIDTH); + haccumulate(summav, metric, mask); + } + + return hadd_s(summav); +} + +#endif diff --git a/thirdparty/astcenc/astcenc_diagnostic_trace.cpp b/thirdparty/astcenc/astcenc_diagnostic_trace.cpp new file mode 100644 index 0000000000..7fa7ab1a8b --- /dev/null +++ b/thirdparty/astcenc/astcenc_diagnostic_trace.cpp @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2021-2022 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief Functions for the library entrypoint. + */ + +#if defined(ASTCENC_DIAGNOSTICS) + +#include <cassert> +#include <cstdarg> +#include <cstdio> +#include <string> + +#include "astcenc_diagnostic_trace.h" + +/** @brief The global trace logger. */ +static TraceLog* g_TraceLog = nullptr; + +/** @brief The JSON indentation level. */ +static const size_t g_trace_indent = 2; + +TraceLog::TraceLog( + const char* file_name): + m_file(file_name, std::ofstream::out | std::ofstream::binary) +{ + assert(!g_TraceLog); + g_TraceLog = this; + m_root = new TraceNode("root"); +} + +/* See header for documentation. */ +TraceNode* TraceLog::get_current_leaf() +{ + if (m_stack.size()) + { + return m_stack.back(); + } + + return nullptr; +} + +/* See header for documentation. */ +size_t TraceLog::get_depth() +{ + return m_stack.size(); +} + +/* See header for documentation. */ +TraceLog::~TraceLog() +{ + assert(g_TraceLog == this); + delete m_root; + g_TraceLog = nullptr; +} + +/* See header for documentation. */ +TraceNode::TraceNode( + const char* format, + ... +) { + // Format the name string + constexpr size_t bufsz = 256; + char buffer[bufsz]; + + va_list args; + va_start (args, format); + vsnprintf (buffer, bufsz, format, args); + va_end (args); + + // Guarantee there is a nul terminator + buffer[bufsz - 1] = 0; + + // Generate the node + TraceNode* parent = g_TraceLog->get_current_leaf(); + size_t depth = g_TraceLog->get_depth(); + g_TraceLog->m_stack.push_back(this); + + bool comma = parent && parent->m_attrib_count; + auto& out = g_TraceLog->m_file; + + if (parent) + { + parent->m_attrib_count++; + } + + if (comma) + { + out << ','; + } + + if (depth) + { + out << '\n'; + } + + size_t out_indent = (depth * 2) * g_trace_indent; + size_t in_indent = (depth * 2 + 1) * g_trace_indent; + + std::string out_indents(""); + if (out_indent) + { + out_indents = std::string(out_indent, ' '); + } + + std::string in_indents(in_indent, ' '); + + out << out_indents << "[ \"node\", \"" << buffer << "\",\n"; + out << in_indents << "["; +} + +/* See header for documentation. */ +void TraceNode::add_attrib( + std::string type, + std::string key, + std::string value +) { + (void)type; + + size_t depth = g_TraceLog->get_depth(); + size_t indent = (depth * 2) * g_trace_indent; + auto& out = g_TraceLog->m_file; + bool comma = m_attrib_count; + m_attrib_count++; + + if (comma) + { + out << ','; + } + + out << '\n'; + out << std::string(indent, ' ') << "[ " + << "\"" << key << "\", " + << value << " ]"; +} + +/* See header for documentation. */ +TraceNode::~TraceNode() +{ + g_TraceLog->m_stack.pop_back(); + + auto& out = g_TraceLog->m_file; + size_t depth = g_TraceLog->get_depth(); + size_t out_indent = (depth * 2) * g_trace_indent; + size_t in_indent = (depth * 2 + 1) * g_trace_indent; + + std::string out_indents(""); + if (out_indent) + { + out_indents = std::string(out_indent, ' '); + } + + std::string in_indents(in_indent, ' '); + + if (m_attrib_count) + { + out << "\n" << in_indents; + } + out << "]\n"; + + out << out_indents << "]"; +} + +/* See header for documentation. */ +void trace_add_data( + const char* key, + const char* format, + ... +) { + constexpr size_t bufsz = 256; + char buffer[bufsz]; + + va_list args; + va_start (args, format); + vsnprintf (buffer, bufsz, format, args); + va_end (args); + + // Guarantee there is a nul terminator + buffer[bufsz - 1] = 0; + + std::string value = "\"" + std::string(buffer) + "\""; + + TraceNode* node = g_TraceLog->get_current_leaf(); + node->add_attrib("str", key, value); +} + +/* See header for documentation. */ +void trace_add_data( + const char* key, + float value +) { + char buffer[256]; + sprintf(buffer, "%.20g", (double)value); + TraceNode* node = g_TraceLog->get_current_leaf(); + node->add_attrib("float", key, buffer); +} + +/* See header for documentation. */ +void trace_add_data( + const char* key, + int value +) { + TraceNode* node = g_TraceLog->get_current_leaf(); + node->add_attrib("int", key, std::to_string(value)); +} + +/* See header for documentation. */ +void trace_add_data( + const char* key, + unsigned int value +) { + TraceNode* node = g_TraceLog->get_current_leaf(); + node->add_attrib("int", key, std::to_string(value)); +} + +#endif diff --git a/thirdparty/astcenc/astcenc_diagnostic_trace.h b/thirdparty/astcenc/astcenc_diagnostic_trace.h new file mode 100644 index 0000000000..f5586b0ad5 --- /dev/null +++ b/thirdparty/astcenc/astcenc_diagnostic_trace.h @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2021-2022 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief This module provides a set of diagnostic tracing utilities. + * + * Overview + * ======== + * + * The built-in diagnostic trace tool generates a hierarchical JSON tree structure. The tree + * hierarchy contains three levels: + * + * - block + * - pass + * - candidate + * + * One block node exists for each compressed block in the image. One pass node exists for each major + * pass (N partition, M planes, O components) applied to a block. One candidate node exists for each + * encoding candidate trialed for a pass. + * + * Each node contains both the hierarchy but also a number of attributes which explain the behavior. + * For example, the block node contains the block coordinates in the image, the pass explains the + * pass configuration, and the candidate will explain the candidate encoding such as weight + * decimation, refinement error, etc. + * + * Trace Nodes are designed as scope-managed C++ objects with stack-like push/pop behavior. + * Constructing a trace node on the stack will automatically add it to the current node as a child, + * and then make it the current node. Destroying the current node will pop the stack and set the + * parent to the current node. This provides a robust mechanism for ensuring reliable nesting in the + * tree structure. + * + * A set of utility macros are provided to add attribute annotations to the current trace node. + * + * Usage + * ===== + * + * Create Trace Nodes on the stack using the @c TRACE_NODE() macro. This will compile-out completely + * in builds with diagnostics disabled. + * + * Add annotations to the current trace node using the @c trace_add_data() macro. This will + * similarly compile out completely in builds with diagnostics disabled. + * + * If you need to add additional code to support diagnostics-only behavior wrap + * it in preprocessor guards: + * + * #if defined(ASTCENC_DIAGNOSTICS) + * #endif + */ + +#ifndef ASTCENC_DIAGNOSTIC_TRACE_INCLUDED +#define ASTCENC_DIAGNOSTIC_TRACE_INCLUDED + +#if defined(ASTCENC_DIAGNOSTICS) + +#include <iostream> +#include <fstream> +#include <vector> + +/** + * @brief Class representing a single node in the trace hierarchy. + */ +class TraceNode +{ +public: + /** + * @brief Construct a new node. + * + * Constructing a node will push to the the top of the stack, automatically making it a child of + * the current node, and then setting it to become the current node. + * + * @param format The format template for the node name. + * @param ... The format parameters. + */ + TraceNode(const char* format, ...); + + /** + * @brief Add an attribute to this node. + * + * Note that no quoting is applied to the @c value, so if quoting is needed it must be done by + * the caller. + * + * @param type The type of the attribute. + * @param key The key of the attribute. + * @param value The value of the attribute. + */ + void add_attrib(std::string type, std::string key, std::string value); + + /** + * @brief Destroy this node. + * + * Destroying a node will pop it from the top of the stack, making its parent the current node. + * It is invalid behavior to destroy a node that is not the current node; usage must conform to + * stack push-pop semantics. + */ + ~TraceNode(); + + /** + * @brief The number of attributes and child nodes in this node. + */ + unsigned int m_attrib_count { 0 }; +}; + +/** + * @brief Class representing the trace log file being written. + */ +class TraceLog +{ +public: + /** + * @brief Create a new trace log. + * + * The trace log is global; there can be only one at a time. + * + * @param file_name The name of the file to write. + */ + TraceLog(const char* file_name); + + /** + * @brief Detroy the trace log. + * + * Trace logs MUST be cleanly destroyed to ensure the file gets written. + */ + ~TraceLog(); + + /** + * @brief Get the current child node. + * + * @return The current leaf node. + */ + TraceNode* get_current_leaf(); + + /** + * @brief Get the stack depth of the current child node. + * + * @return The current leaf node stack depth. + */ + size_t get_depth(); + + /** + * @brief The file stream to write to. + */ + std::ofstream m_file; + + /** + * @brief The stack of nodes (newest at the back). + */ + std::vector<TraceNode*> m_stack; + +private: + /** + * @brief The root node in the JSON file. + */ + TraceNode* m_root; +}; + +/** + * @brief Utility macro to create a trace node on the stack. + * + * @param name The variable name to use. + * @param ... The name template and format parameters. + */ +#define TRACE_NODE(name, ...) TraceNode name(__VA_ARGS__); + +/** + * @brief Add a string annotation to the current node. + * + * @param key The name of the attribute. + * @param format The format template for the attribute value. + * @param ... The format parameters. + */ +void trace_add_data(const char* key, const char* format, ...); + +/** + * @brief Add a float annotation to the current node. + * + * @param key The name of the attribute. + * @param value The value of the attribute. + */ +void trace_add_data(const char* key, float value); + +/** + * @brief Add an integer annotation to the current node. + * + * @param key The name of the attribute. + * @param value The value of the attribute. + */ +void trace_add_data(const char* key, int value); + +/** + * @brief Add an unsigned integer annotation to the current node. + * + * @param key The name of the attribute. + * @param value The value of the attribute. + */ +void trace_add_data(const char* key, unsigned int value); + +#else + +#define TRACE_NODE(name, ...) + +#define trace_add_data(...) + +#endif + +#endif diff --git a/thirdparty/astcenc/astcenc_entry.cpp b/thirdparty/astcenc/astcenc_entry.cpp new file mode 100644 index 0000000000..e59f1fe61a --- /dev/null +++ b/thirdparty/astcenc/astcenc_entry.cpp @@ -0,0 +1,1427 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2023 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief Functions for the library entrypoint. + */ + +#include <array> +#include <cstring> +#include <new> + +#include "astcenc.h" +#include "astcenc_internal_entry.h" +#include "astcenc_diagnostic_trace.h" + +/** + * @brief Record of the quality tuning parameter values. + * + * See the @c astcenc_config structure for detailed parameter documentation. + * + * Note that the mse_overshoot entries are scaling factors relative to the base MSE to hit db_limit. + * A 20% overshoot is harder to hit for a higher base db_limit, so we may actually use lower ratios + * for the more through search presets because the underlying db_limit is so much higher. + */ +struct astcenc_preset_config +{ + float quality; + unsigned int tune_partition_count_limit; + unsigned int tune_2partition_index_limit; + unsigned int tune_3partition_index_limit; + unsigned int tune_4partition_index_limit; + unsigned int tune_block_mode_limit; + unsigned int tune_refinement_limit; + unsigned int tune_candidate_limit; + unsigned int tune_2partitioning_candidate_limit; + unsigned int tune_3partitioning_candidate_limit; + unsigned int tune_4partitioning_candidate_limit; + float tune_db_limit_a_base; + float tune_db_limit_b_base; + float tune_mse_overshoot; + float tune_2_partition_early_out_limit_factor; + float tune_3_partition_early_out_limit_factor; + float tune_2_plane_early_out_limit_correlation; +}; + +/** + * @brief The static presets for high bandwidth encodings (x < 25 texels per block). + */ +static const std::array<astcenc_preset_config, 6> preset_configs_high {{ + { + ASTCENC_PRE_FASTEST, + 2, 10, 6, 4, 43, 2, 2, 2, 2, 2, 85.2f, 63.2f, 3.5f, 1.0f, 1.0f, 0.85f + }, { + ASTCENC_PRE_FAST, + 3, 18, 10, 8, 55, 3, 3, 2, 2, 2, 85.2f, 63.2f, 3.5f, 1.0f, 1.0f, 0.90f + }, { + ASTCENC_PRE_MEDIUM, + 4, 34, 28, 16, 77, 3, 3, 2, 2, 2, 95.0f, 70.0f, 2.5f, 1.1f, 1.05f, 0.95f + }, { + ASTCENC_PRE_THOROUGH, + 4, 82, 60, 30, 94, 4, 4, 3, 2, 2, 105.0f, 77.0f, 10.0f, 1.35f, 1.15f, 0.97f + }, { + ASTCENC_PRE_VERYTHOROUGH, + 4, 256, 128, 64, 98, 4, 6, 20, 14, 8, 200.0f, 200.0f, 10.0f, 1.6f, 1.4f, 0.98f + }, { + ASTCENC_PRE_EXHAUSTIVE, + 4, 512, 512, 512, 100, 4, 8, 32, 32, 32, 200.0f, 200.0f, 10.0f, 2.0f, 2.0f, 0.99f + } +}}; + +/** + * @brief The static presets for medium bandwidth encodings (25 <= x < 64 texels per block). + */ +static const std::array<astcenc_preset_config, 6> preset_configs_mid {{ + { + ASTCENC_PRE_FASTEST, + 2, 10, 6, 4, 43, 2, 2, 2, 2, 2, 85.2f, 63.2f, 3.5f, 1.0f, 1.0f, 0.80f + }, { + ASTCENC_PRE_FAST, + 3, 18, 12, 10, 55, 3, 3, 2, 2, 2, 85.2f, 63.2f, 3.5f, 1.0f, 1.0f, 0.85f + }, { + ASTCENC_PRE_MEDIUM, + 4, 34, 28, 16, 77, 3, 3, 2, 2, 2, 95.0f, 70.0f, 3.0f, 1.1f, 1.05f, 0.90f + }, { + ASTCENC_PRE_THOROUGH, + 4, 82, 60, 30, 94, 4, 4, 3, 2, 2, 105.0f, 77.0f, 10.0f, 1.4f, 1.2f, 0.95f + }, { + ASTCENC_PRE_VERYTHOROUGH, + 4, 256, 128, 64, 98, 4, 6, 12, 8, 3, 200.0f, 200.0f, 10.0f, 1.6f, 1.4f, 0.98f + }, { + ASTCENC_PRE_EXHAUSTIVE, + 4, 256, 256, 256, 100, 4, 8, 32, 32, 32, 200.0f, 200.0f, 10.0f, 2.0f, 2.0f, 0.99f + } +}}; + +/** + * @brief The static presets for low bandwidth encodings (64 <= x texels per block). + */ +static const std::array<astcenc_preset_config, 6> preset_configs_low {{ + { + ASTCENC_PRE_FASTEST, + 2, 10, 6, 4, 40, 2, 2, 2, 2, 2, 85.0f, 63.0f, 3.5f, 1.0f, 1.0f, 0.80f + }, { + ASTCENC_PRE_FAST, + 2, 18, 12, 10, 55, 3, 3, 2, 2, 2, 85.0f, 63.0f, 3.5f, 1.0f, 1.0f, 0.85f + }, { + ASTCENC_PRE_MEDIUM, + 3, 34, 28, 16, 77, 3, 3, 2, 2, 2, 95.0f, 70.0f, 3.5f, 1.1f, 1.05f, 0.90f + }, { + ASTCENC_PRE_THOROUGH, + 4, 82, 60, 30, 93, 4, 4, 3, 2, 2, 105.0f, 77.0f, 10.0f, 1.3f, 1.2f, 0.97f + }, { + ASTCENC_PRE_VERYTHOROUGH, + 4, 256, 128, 64, 98, 4, 6, 9, 5, 2, 200.0f, 200.0f, 10.0f, 1.6f, 1.4f, 0.98f + }, { + ASTCENC_PRE_EXHAUSTIVE, + 4, 256, 256, 256, 100, 4, 8, 32, 32, 32, 200.0f, 200.0f, 10.0f, 2.0f, 2.0f, 0.99f + } +}}; + +/** + * @brief Validate CPU floating point meets assumptions made in the codec. + * + * The codec is written with the assumption that a float threaded through the @c if32 union will be + * stored and reloaded as a 32-bit IEEE-754 float with round-to-nearest rounding. This is always the + * case in an IEEE-754 compliant system, however not every system or compilation mode is actually + * IEEE-754 compliant. This normally fails if the code is compiled with fast math enabled. + * + * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure. + */ +static astcenc_error validate_cpu_float() +{ + if32 p; + volatile float xprec_testval = 2.51f; + p.f = xprec_testval + 12582912.0f; + float q = p.f - 12582912.0f; + + if (q != 3.0f) + { + return ASTCENC_ERR_BAD_CPU_FLOAT; + } + + return ASTCENC_SUCCESS; +} + +/** + * @brief Validate CPU ISA support meets the requirements of this build of the library. + * + * Each library build is statically compiled for a particular set of CPU ISA features, such as the + * SIMD support or other ISA extensions such as POPCNT. This function checks that the host CPU + * actually supports everything this build needs. + * + * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure. + */ +static astcenc_error validate_cpu_isa() +{ + #if ASTCENC_SSE >= 41 + if (!cpu_supports_sse41()) + { + return ASTCENC_ERR_BAD_CPU_ISA; + } + #endif + + #if ASTCENC_POPCNT >= 1 + if (!cpu_supports_popcnt()) + { + return ASTCENC_ERR_BAD_CPU_ISA; + } + #endif + + #if ASTCENC_F16C >= 1 + if (!cpu_supports_f16c()) + { + return ASTCENC_ERR_BAD_CPU_ISA; + } + #endif + + #if ASTCENC_AVX >= 2 + if (!cpu_supports_avx2()) + { + return ASTCENC_ERR_BAD_CPU_ISA; + } + #endif + + return ASTCENC_SUCCESS; +} + +/** + * @brief Validate config profile. + * + * @param profile The profile to check. + * + * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure. + */ +static astcenc_error validate_profile( + astcenc_profile profile +) { + // Values in this enum are from an external user, so not guaranteed to be + // bounded to the enum values + switch (static_cast<int>(profile)) + { + case ASTCENC_PRF_LDR_SRGB: + case ASTCENC_PRF_LDR: + case ASTCENC_PRF_HDR_RGB_LDR_A: + case ASTCENC_PRF_HDR: + return ASTCENC_SUCCESS; + default: + return ASTCENC_ERR_BAD_PROFILE; + } +} + +/** + * @brief Validate block size. + * + * @param block_x The block x dimensions. + * @param block_y The block y dimensions. + * @param block_z The block z dimensions. + * + * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure. + */ +static astcenc_error validate_block_size( + unsigned int block_x, + unsigned int block_y, + unsigned int block_z +) { + // Test if this is a legal block size at all + bool is_legal = (((block_z <= 1) && is_legal_2d_block_size(block_x, block_y)) || + ((block_z >= 2) && is_legal_3d_block_size(block_x, block_y, block_z))); + if (!is_legal) + { + return ASTCENC_ERR_BAD_BLOCK_SIZE; + } + + // Test if this build has sufficient capacity for this block size + bool have_capacity = (block_x * block_y * block_z) <= BLOCK_MAX_TEXELS; + if (!have_capacity) + { + return ASTCENC_ERR_NOT_IMPLEMENTED; + } + + return ASTCENC_SUCCESS; +} + +/** + * @brief Validate flags. + * + * @param flags The flags to check. + * + * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure. + */ +static astcenc_error validate_flags( + unsigned int flags +) { + // Flags field must not contain any unknown flag bits + unsigned int exMask = ~ASTCENC_ALL_FLAGS; + if (popcount(flags & exMask) != 0) + { + return ASTCENC_ERR_BAD_FLAGS; + } + + // Flags field must only contain at most a single map type + exMask = ASTCENC_FLG_MAP_NORMAL + | ASTCENC_FLG_MAP_RGBM; + if (popcount(flags & exMask) > 1) + { + return ASTCENC_ERR_BAD_FLAGS; + } + + return ASTCENC_SUCCESS; +} + +#if !defined(ASTCENC_DECOMPRESS_ONLY) + +/** + * @brief Validate single channel compression swizzle. + * + * @param swizzle The swizzle to check. + * + * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure. + */ +static astcenc_error validate_compression_swz( + astcenc_swz swizzle +) { + // Not all enum values are handled; SWZ_Z is invalid for compression + switch (static_cast<int>(swizzle)) + { + case ASTCENC_SWZ_R: + case ASTCENC_SWZ_G: + case ASTCENC_SWZ_B: + case ASTCENC_SWZ_A: + case ASTCENC_SWZ_0: + case ASTCENC_SWZ_1: + return ASTCENC_SUCCESS; + default: + return ASTCENC_ERR_BAD_SWIZZLE; + } +} + +/** + * @brief Validate overall compression swizzle. + * + * @param swizzle The swizzle to check. + * + * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure. + */ +static astcenc_error validate_compression_swizzle( + const astcenc_swizzle& swizzle +) { + if (validate_compression_swz(swizzle.r) || + validate_compression_swz(swizzle.g) || + validate_compression_swz(swizzle.b) || + validate_compression_swz(swizzle.a)) + { + return ASTCENC_ERR_BAD_SWIZZLE; + } + + return ASTCENC_SUCCESS; +} +#endif + +/** + * @brief Validate single channel decompression swizzle. + * + * @param swizzle The swizzle to check. + * + * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure. + */ +static astcenc_error validate_decompression_swz( + astcenc_swz swizzle +) { + // Values in this enum are from an external user, so not guaranteed to be + // bounded to the enum values + switch (static_cast<int>(swizzle)) + { + case ASTCENC_SWZ_R: + case ASTCENC_SWZ_G: + case ASTCENC_SWZ_B: + case ASTCENC_SWZ_A: + case ASTCENC_SWZ_0: + case ASTCENC_SWZ_1: + case ASTCENC_SWZ_Z: + return ASTCENC_SUCCESS; + default: + return ASTCENC_ERR_BAD_SWIZZLE; + } +} + +/** + * @brief Validate overall decompression swizzle. + * + * @param swizzle The swizzle to check. + * + * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure. + */ +static astcenc_error validate_decompression_swizzle( + const astcenc_swizzle& swizzle +) { + if (validate_decompression_swz(swizzle.r) || + validate_decompression_swz(swizzle.g) || + validate_decompression_swz(swizzle.b) || + validate_decompression_swz(swizzle.a)) + { + return ASTCENC_ERR_BAD_SWIZZLE; + } + + return ASTCENC_SUCCESS; +} + +/** + * Validate that an incoming configuration is in-spec. + * + * This function can respond in two ways: + * + * * Numerical inputs that have valid ranges are clamped to those valid ranges. No error is thrown + * for out-of-range inputs in this case. + * * Numerical inputs and logic inputs are are logically invalid and which make no sense + * algorithmically will return an error. + * + * @param[in,out] config The input compressor configuration. + * + * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure. + */ +static astcenc_error validate_config( + astcenc_config &config +) { + astcenc_error status; + + status = validate_profile(config.profile); + if (status != ASTCENC_SUCCESS) + { + return status; + } + + status = validate_flags(config.flags); + if (status != ASTCENC_SUCCESS) + { + return status; + } + + status = validate_block_size(config.block_x, config.block_y, config.block_z); + if (status != ASTCENC_SUCCESS) + { + return status; + } + +#if defined(ASTCENC_DECOMPRESS_ONLY) + // Decompress-only builds only support decompress-only contexts + if (!(config.flags & ASTCENC_FLG_DECOMPRESS_ONLY)) + { + return ASTCENC_ERR_BAD_PARAM; + } +#endif + + config.rgbm_m_scale = astc::max(config.rgbm_m_scale, 1.0f); + + config.tune_partition_count_limit = astc::clamp(config.tune_partition_count_limit, 1u, 4u); + config.tune_2partition_index_limit = astc::clamp(config.tune_2partition_index_limit, 1u, BLOCK_MAX_PARTITIONINGS); + config.tune_3partition_index_limit = astc::clamp(config.tune_3partition_index_limit, 1u, BLOCK_MAX_PARTITIONINGS); + config.tune_4partition_index_limit = astc::clamp(config.tune_4partition_index_limit, 1u, BLOCK_MAX_PARTITIONINGS); + config.tune_block_mode_limit = astc::clamp(config.tune_block_mode_limit, 1u, 100u); + config.tune_refinement_limit = astc::max(config.tune_refinement_limit, 1u); + config.tune_candidate_limit = astc::clamp(config.tune_candidate_limit, 1u, TUNE_MAX_TRIAL_CANDIDATES); + config.tune_2partitioning_candidate_limit = astc::clamp(config.tune_2partitioning_candidate_limit, 1u, TUNE_MAX_PARTITIONING_CANDIDATES); + config.tune_3partitioning_candidate_limit = astc::clamp(config.tune_3partitioning_candidate_limit, 1u, TUNE_MAX_PARTITIONING_CANDIDATES); + config.tune_4partitioning_candidate_limit = astc::clamp(config.tune_4partitioning_candidate_limit, 1u, TUNE_MAX_PARTITIONING_CANDIDATES); + config.tune_db_limit = astc::max(config.tune_db_limit, 0.0f); + config.tune_mse_overshoot = astc::max(config.tune_mse_overshoot, 1.0f); + config.tune_2_partition_early_out_limit_factor = astc::max(config.tune_2_partition_early_out_limit_factor, 0.0f); + config.tune_3_partition_early_out_limit_factor = astc::max(config.tune_3_partition_early_out_limit_factor, 0.0f); + config.tune_2_plane_early_out_limit_correlation = astc::max(config.tune_2_plane_early_out_limit_correlation, 0.0f); + + // Specifying a zero weight color component is not allowed; force to small value + float max_weight = astc::max(astc::max(config.cw_r_weight, config.cw_g_weight), + astc::max(config.cw_b_weight, config.cw_a_weight)); + if (max_weight > 0.0f) + { + max_weight /= 1000.0f; + config.cw_r_weight = astc::max(config.cw_r_weight, max_weight); + config.cw_g_weight = astc::max(config.cw_g_weight, max_weight); + config.cw_b_weight = astc::max(config.cw_b_weight, max_weight); + config.cw_a_weight = astc::max(config.cw_a_weight, max_weight); + } + // If all color components error weights are zero then return an error + else + { + return ASTCENC_ERR_BAD_PARAM; + } + + return ASTCENC_SUCCESS; +} + +/* See header for documentation. */ +astcenc_error astcenc_config_init( + astcenc_profile profile, + unsigned int block_x, + unsigned int block_y, + unsigned int block_z, + float quality, + unsigned int flags, + astcenc_config* configp +) { + astcenc_error status; + + // Check basic library compatibility options here so they are checked early. Note, these checks + // are repeated in context_alloc for cases where callers use a manually defined config struct + status = validate_cpu_isa(); + if (status != ASTCENC_SUCCESS) + { + return status; + } + + status = validate_cpu_float(); + if (status != ASTCENC_SUCCESS) + { + return status; + } + + // Zero init all config fields; although most of will be over written + astcenc_config& config = *configp; + std::memset(&config, 0, sizeof(config)); + + // Process the block size + block_z = astc::max(block_z, 1u); // For 2D blocks Z==0 is accepted, but convert to 1 + status = validate_block_size(block_x, block_y, block_z); + if (status != ASTCENC_SUCCESS) + { + return status; + } + + config.block_x = block_x; + config.block_y = block_y; + config.block_z = block_z; + + float texels = static_cast<float>(block_x * block_y * block_z); + float ltexels = logf(texels) / logf(10.0f); + + // Process the performance quality level or preset; note that this must be done before we + // process any additional settings, such as color profile and flags, which may replace some of + // these settings with more use case tuned values + if (quality < ASTCENC_PRE_FASTEST || + quality > ASTCENC_PRE_EXHAUSTIVE) + { + return ASTCENC_ERR_BAD_QUALITY; + } + + static const std::array<astcenc_preset_config, 6>* preset_configs; + int texels_int = block_x * block_y * block_z; + if (texels_int < 25) + { + preset_configs = &preset_configs_high; + } + else if (texels_int < 64) + { + preset_configs = &preset_configs_mid; + } + else + { + preset_configs = &preset_configs_low; + } + + // Determine which preset to use, or which pair to interpolate + size_t start; + size_t end; + for (end = 0; end < preset_configs->size(); end++) + { + if ((*preset_configs)[end].quality >= quality) + { + break; + } + } + + start = end == 0 ? 0 : end - 1; + + // Start and end node are the same - so just transfer the values. + if (start == end) + { + config.tune_partition_count_limit = (*preset_configs)[start].tune_partition_count_limit; + config.tune_2partition_index_limit = (*preset_configs)[start].tune_2partition_index_limit; + config.tune_3partition_index_limit = (*preset_configs)[start].tune_3partition_index_limit; + config.tune_4partition_index_limit = (*preset_configs)[start].tune_4partition_index_limit; + config.tune_block_mode_limit = (*preset_configs)[start].tune_block_mode_limit; + config.tune_refinement_limit = (*preset_configs)[start].tune_refinement_limit; + config.tune_candidate_limit = astc::min((*preset_configs)[start].tune_candidate_limit, TUNE_MAX_TRIAL_CANDIDATES); + config.tune_2partitioning_candidate_limit = astc::min((*preset_configs)[start].tune_2partitioning_candidate_limit, TUNE_MAX_PARTITIONING_CANDIDATES); + config.tune_3partitioning_candidate_limit = astc::min((*preset_configs)[start].tune_3partitioning_candidate_limit, TUNE_MAX_PARTITIONING_CANDIDATES); + config.tune_4partitioning_candidate_limit = astc::min((*preset_configs)[start].tune_4partitioning_candidate_limit, TUNE_MAX_PARTITIONING_CANDIDATES); + config.tune_db_limit = astc::max((*preset_configs)[start].tune_db_limit_a_base - 35 * ltexels, + (*preset_configs)[start].tune_db_limit_b_base - 19 * ltexels); + + config.tune_mse_overshoot = (*preset_configs)[start].tune_mse_overshoot; + + config.tune_2_partition_early_out_limit_factor = (*preset_configs)[start].tune_2_partition_early_out_limit_factor; + config.tune_3_partition_early_out_limit_factor =(*preset_configs)[start].tune_3_partition_early_out_limit_factor; + config.tune_2_plane_early_out_limit_correlation = (*preset_configs)[start].tune_2_plane_early_out_limit_correlation; + } + // Start and end node are not the same - so interpolate between them + else + { + auto& node_a = (*preset_configs)[start]; + auto& node_b = (*preset_configs)[end]; + + float wt_range = node_b.quality - node_a.quality; + assert(wt_range > 0); + + // Compute interpolation factors + float wt_node_a = (node_b.quality - quality) / wt_range; + float wt_node_b = (quality - node_a.quality) / wt_range; + + #define LERP(param) ((node_a.param * wt_node_a) + (node_b.param * wt_node_b)) + #define LERPI(param) astc::flt2int_rtn(\ + (static_cast<float>(node_a.param) * wt_node_a) + \ + (static_cast<float>(node_b.param) * wt_node_b)) + #define LERPUI(param) static_cast<unsigned int>(LERPI(param)) + + config.tune_partition_count_limit = LERPI(tune_partition_count_limit); + config.tune_2partition_index_limit = LERPI(tune_2partition_index_limit); + config.tune_3partition_index_limit = LERPI(tune_3partition_index_limit); + config.tune_4partition_index_limit = LERPI(tune_4partition_index_limit); + config.tune_block_mode_limit = LERPI(tune_block_mode_limit); + config.tune_refinement_limit = LERPI(tune_refinement_limit); + config.tune_candidate_limit = astc::min(LERPUI(tune_candidate_limit), + TUNE_MAX_TRIAL_CANDIDATES); + config.tune_2partitioning_candidate_limit = astc::min(LERPUI(tune_2partitioning_candidate_limit), + BLOCK_MAX_PARTITIONINGS); + config.tune_3partitioning_candidate_limit = astc::min(LERPUI(tune_3partitioning_candidate_limit), + BLOCK_MAX_PARTITIONINGS); + config.tune_4partitioning_candidate_limit = astc::min(LERPUI(tune_4partitioning_candidate_limit), + BLOCK_MAX_PARTITIONINGS); + config.tune_db_limit = astc::max(LERP(tune_db_limit_a_base) - 35 * ltexels, + LERP(tune_db_limit_b_base) - 19 * ltexels); + + config.tune_mse_overshoot = LERP(tune_mse_overshoot); + + config.tune_2_partition_early_out_limit_factor = LERP(tune_2_partition_early_out_limit_factor); + config.tune_3_partition_early_out_limit_factor = LERP(tune_3_partition_early_out_limit_factor); + config.tune_2_plane_early_out_limit_correlation = LERP(tune_2_plane_early_out_limit_correlation); + #undef LERP + #undef LERPI + #undef LERPUI + } + + // Set heuristics to the defaults for each color profile + config.cw_r_weight = 1.0f; + config.cw_g_weight = 1.0f; + config.cw_b_weight = 1.0f; + config.cw_a_weight = 1.0f; + + config.a_scale_radius = 0; + + config.rgbm_m_scale = 0.0f; + + config.profile = profile; + + // Values in this enum are from an external user, so not guaranteed to be + // bounded to the enum values + switch (static_cast<int>(profile)) + { + case ASTCENC_PRF_LDR: + case ASTCENC_PRF_LDR_SRGB: + break; + case ASTCENC_PRF_HDR_RGB_LDR_A: + case ASTCENC_PRF_HDR: + config.tune_db_limit = 999.0f; + break; + default: + return ASTCENC_ERR_BAD_PROFILE; + } + + // Flags field must not contain any unknown flag bits + status = validate_flags(flags); + if (status != ASTCENC_SUCCESS) + { + return status; + } + + if (flags & ASTCENC_FLG_MAP_NORMAL) + { + // Normal map encoding uses L+A blocks, so allow one more partitioning + // than normal. We need need fewer bits for endpoints, so more likely + // to be able to use more partitions than an RGB/RGBA block + config.tune_partition_count_limit = astc::min(config.tune_partition_count_limit + 1u, 4u); + + config.cw_g_weight = 0.0f; + config.cw_b_weight = 0.0f; + config.tune_2_partition_early_out_limit_factor *= 1.5f; + config.tune_3_partition_early_out_limit_factor *= 1.5f; + config.tune_2_plane_early_out_limit_correlation = 0.99f; + + // Normals are prone to blocking artifacts on smooth curves + // so force compressor to try harder here ... + config.tune_db_limit *= 1.03f; + } + else if (flags & ASTCENC_FLG_MAP_RGBM) + { + config.rgbm_m_scale = 5.0f; + config.cw_a_weight = 2.0f * config.rgbm_m_scale; + } + else // (This is color data) + { + // This is a very basic perceptual metric for RGB color data, which weights error + // significance by the perceptual luminance contribution of each color channel. For + // luminance the usual weights to compute luminance from a linear RGB value are as + // follows: + // + // l = r * 0.3 + g * 0.59 + b * 0.11 + // + // ... but we scale these up to keep a better balance between color and alpha. Note + // that if the content is using alpha we'd recommend using the -a option to weight + // the color contribution by the alpha transparency. + if (flags & ASTCENC_FLG_USE_PERCEPTUAL) + { + config.cw_r_weight = 0.30f * 2.25f; + config.cw_g_weight = 0.59f * 2.25f; + config.cw_b_weight = 0.11f * 2.25f; + } + } + config.flags = flags; + + return ASTCENC_SUCCESS; +} + +/* See header for documentation. */ +astcenc_error astcenc_context_alloc( + const astcenc_config* configp, + unsigned int thread_count, + astcenc_context** context +) { + astcenc_error status; + const astcenc_config& config = *configp; + + status = validate_cpu_isa(); + if (status != ASTCENC_SUCCESS) + { + return status; + } + + status = validate_cpu_float(); + if (status != ASTCENC_SUCCESS) + { + return status; + } + + if (thread_count == 0) + { + return ASTCENC_ERR_BAD_PARAM; + } + +#if defined(ASTCENC_DIAGNOSTICS) + // Force single threaded compressor use in diagnostic mode. + if (thread_count != 1) + { + return ASTCENC_ERR_BAD_PARAM; + } +#endif + + astcenc_context* ctxo = new astcenc_context; + astcenc_contexti* ctx = &ctxo->context; + ctx->thread_count = thread_count; + ctx->config = config; + ctx->working_buffers = nullptr; + + // These are allocated per-compress, as they depend on image size + ctx->input_alpha_averages = nullptr; + + // Copy the config first and validate the copy (we may modify it) + status = validate_config(ctx->config); + if (status != ASTCENC_SUCCESS) + { + delete ctxo; + return status; + } + + ctx->bsd = aligned_malloc<block_size_descriptor>(sizeof(block_size_descriptor), ASTCENC_VECALIGN); + bool can_omit_modes = static_cast<bool>(config.flags & ASTCENC_FLG_SELF_DECOMPRESS_ONLY); + init_block_size_descriptor(config.block_x, config.block_y, config.block_z, + can_omit_modes, + config.tune_partition_count_limit, + static_cast<float>(config.tune_block_mode_limit) / 100.0f, + *ctx->bsd); + +#if !defined(ASTCENC_DECOMPRESS_ONLY) + // Do setup only needed by compression + if (!(status & ASTCENC_FLG_DECOMPRESS_ONLY)) + { + // Turn a dB limit into a per-texel error for faster use later + if ((ctx->config.profile == ASTCENC_PRF_LDR) || (ctx->config.profile == ASTCENC_PRF_LDR_SRGB)) + { + ctx->config.tune_db_limit = astc::pow(0.1f, ctx->config.tune_db_limit * 0.1f) * 65535.0f * 65535.0f; + } + else + { + ctx->config.tune_db_limit = 0.0f; + } + + size_t worksize = sizeof(compression_working_buffers) * thread_count; + ctx->working_buffers = aligned_malloc<compression_working_buffers>(worksize, ASTCENC_VECALIGN); + static_assert((sizeof(compression_working_buffers) % ASTCENC_VECALIGN) == 0, + "compression_working_buffers size must be multiple of vector alignment"); + if (!ctx->working_buffers) + { + aligned_free<block_size_descriptor>(ctx->bsd); + delete ctxo; + *context = nullptr; + return ASTCENC_ERR_OUT_OF_MEM; + } + } +#endif + +#if defined(ASTCENC_DIAGNOSTICS) + ctx->trace_log = new TraceLog(ctx->config.trace_file_path); + if (!ctx->trace_log->m_file) + { + return ASTCENC_ERR_DTRACE_FAILURE; + } + + trace_add_data("block_x", config.block_x); + trace_add_data("block_y", config.block_y); + trace_add_data("block_z", config.block_z); +#endif + + *context = ctxo; + +#if !defined(ASTCENC_DECOMPRESS_ONLY) + prepare_angular_tables(); +#endif + + return ASTCENC_SUCCESS; +} + +/* See header dor documentation. */ +void astcenc_context_free( + astcenc_context* ctxo +) { + if (ctxo) + { + astcenc_contexti* ctx = &ctxo->context; + aligned_free<compression_working_buffers>(ctx->working_buffers); + aligned_free<block_size_descriptor>(ctx->bsd); +#if defined(ASTCENC_DIAGNOSTICS) + delete ctx->trace_log; +#endif + delete ctxo; + } +} + +#if !defined(ASTCENC_DECOMPRESS_ONLY) + +/** + * @brief Compress an image, after any preflight has completed. + * + * @param[out] ctxo The compressor context. + * @param thread_index The thread index. + * @param image The intput image. + * @param swizzle The input swizzle. + * @param[out] buffer The output array for the compressed data. + */ +static void compress_image( + astcenc_context& ctxo, + unsigned int thread_index, + const astcenc_image& image, + const astcenc_swizzle& swizzle, + uint8_t* buffer +) { + astcenc_contexti& ctx = ctxo.context; + const block_size_descriptor& bsd = *ctx.bsd; + astcenc_profile decode_mode = ctx.config.profile; + + image_block blk; + + int block_x = bsd.xdim; + int block_y = bsd.ydim; + int block_z = bsd.zdim; + blk.texel_count = static_cast<uint8_t>(block_x * block_y * block_z); + + int dim_x = image.dim_x; + int dim_y = image.dim_y; + int dim_z = image.dim_z; + + int xblocks = (dim_x + block_x - 1) / block_x; + int yblocks = (dim_y + block_y - 1) / block_y; + int zblocks = (dim_z + block_z - 1) / block_z; + int block_count = zblocks * yblocks * xblocks; + + int row_blocks = xblocks; + int plane_blocks = xblocks * yblocks; + + // Populate the block channel weights + blk.channel_weight = vfloat4(ctx.config.cw_r_weight, + ctx.config.cw_g_weight, + ctx.config.cw_b_weight, + ctx.config.cw_a_weight); + + // Use preallocated scratch buffer + auto& temp_buffers = ctx.working_buffers[thread_index]; + + // Only the first thread actually runs the initializer + ctxo.manage_compress.init(block_count); + + // Determine if we can use an optimized load function + bool needs_swz = (swizzle.r != ASTCENC_SWZ_R) || (swizzle.g != ASTCENC_SWZ_G) || + (swizzle.b != ASTCENC_SWZ_B) || (swizzle.a != ASTCENC_SWZ_A); + + bool needs_hdr = (decode_mode == ASTCENC_PRF_HDR) || + (decode_mode == ASTCENC_PRF_HDR_RGB_LDR_A); + + bool use_fast_load = !needs_swz && !needs_hdr && + block_z == 1 && image.data_type == ASTCENC_TYPE_U8; + + auto load_func = load_image_block; + if (use_fast_load) + { + load_func = load_image_block_fast_ldr; + } + + // All threads run this processing loop until there is no work remaining + while (true) + { + unsigned int count; + unsigned int base = ctxo.manage_compress.get_task_assignment(16, count); + if (!count) + { + break; + } + + for (unsigned int i = base; i < base + count; i++) + { + // Decode i into x, y, z block indices + int z = i / plane_blocks; + unsigned int rem = i - (z * plane_blocks); + int y = rem / row_blocks; + int x = rem - (y * row_blocks); + + // Test if we can apply some basic alpha-scale RDO + bool use_full_block = true; + if (ctx.config.a_scale_radius != 0 && block_z == 1) + { + int start_x = x * block_x; + int end_x = astc::min(dim_x, start_x + block_x); + + int start_y = y * block_y; + int end_y = astc::min(dim_y, start_y + block_y); + + // SATs accumulate error, so don't test exactly zero. Test for + // less than 1 alpha in the expanded block footprint that + // includes the alpha radius. + int x_footprint = block_x + 2 * (ctx.config.a_scale_radius - 1); + + int y_footprint = block_y + 2 * (ctx.config.a_scale_radius - 1); + + float footprint = static_cast<float>(x_footprint * y_footprint); + float threshold = 0.9f / (255.0f * footprint); + + // Do we have any alpha values? + use_full_block = false; + for (int ay = start_y; ay < end_y; ay++) + { + for (int ax = start_x; ax < end_x; ax++) + { + float a_avg = ctx.input_alpha_averages[ay * dim_x + ax]; + if (a_avg > threshold) + { + use_full_block = true; + ax = end_x; + ay = end_y; + } + } + } + } + + // Fetch the full block for compression + if (use_full_block) + { + load_func(decode_mode, image, blk, bsd, x * block_x, y * block_y, z * block_z, swizzle); + + // Scale RGB error contribution by the maximum alpha in the block + // This encourages preserving alpha accuracy in regions with high + // transparency, and can buy up to 0.5 dB PSNR. + if (ctx.config.flags & ASTCENC_FLG_USE_ALPHA_WEIGHT) + { + float alpha_scale = blk.data_max.lane<3>() * (1.0f / 65535.0f); + blk.channel_weight = vfloat4(ctx.config.cw_r_weight * alpha_scale, + ctx.config.cw_g_weight * alpha_scale, + ctx.config.cw_b_weight * alpha_scale, + ctx.config.cw_a_weight); + } + } + // Apply alpha scale RDO - substitute constant color block + else + { + blk.origin_texel = vfloat4::zero(); + blk.data_min = vfloat4::zero(); + blk.data_mean = vfloat4::zero(); + blk.data_max = vfloat4::zero(); + blk.grayscale = true; + } + + int offset = ((z * yblocks + y) * xblocks + x) * 16; + uint8_t *bp = buffer + offset; + physical_compressed_block* pcb = reinterpret_cast<physical_compressed_block*>(bp); + compress_block(ctx, blk, *pcb, temp_buffers); + } + + ctxo.manage_compress.complete_task_assignment(count); + } +} + +/** + * @brief Compute regional averages in an image. + * + * This function can be called by multiple threads, but only after a single + * thread calls the setup function @c init_compute_averages(). + * + * Results are written back into @c img->input_alpha_averages. + * + * @param[out] ctx The context. + * @param ag The average and variance arguments created during setup. + */ +static void compute_averages( + astcenc_context& ctx, + const avg_args &ag +) { + pixel_region_args arg = ag.arg; + arg.work_memory = new vfloat4[ag.work_memory_size]; + + int size_x = ag.img_size_x; + int size_y = ag.img_size_y; + int size_z = ag.img_size_z; + + int step_xy = ag.blk_size_xy; + int step_z = ag.blk_size_z; + + int y_tasks = (size_y + step_xy - 1) / step_xy; + + // All threads run this processing loop until there is no work remaining + while (true) + { + unsigned int count; + unsigned int base = ctx.manage_avg.get_task_assignment(16, count); + if (!count) + { + break; + } + + for (unsigned int i = base; i < base + count; i++) + { + int z = (i / (y_tasks)) * step_z; + int y = (i - (z * y_tasks)) * step_xy; + + arg.size_z = astc::min(step_z, size_z - z); + arg.offset_z = z; + + arg.size_y = astc::min(step_xy, size_y - y); + arg.offset_y = y; + + for (int x = 0; x < size_x; x += step_xy) + { + arg.size_x = astc::min(step_xy, size_x - x); + arg.offset_x = x; + compute_pixel_region_variance(ctx.context, arg); + } + } + + ctx.manage_avg.complete_task_assignment(count); + } + + delete[] arg.work_memory; +} + +#endif + +/* See header for documentation. */ +astcenc_error astcenc_compress_image( + astcenc_context* ctxo, + astcenc_image* imagep, + const astcenc_swizzle* swizzle, + uint8_t* data_out, + size_t data_len, + unsigned int thread_index +) { +#if defined(ASTCENC_DECOMPRESS_ONLY) + (void)ctxo; + (void)imagep; + (void)swizzle; + (void)data_out; + (void)data_len; + (void)thread_index; + return ASTCENC_ERR_BAD_CONTEXT; +#else + astcenc_contexti* ctx = &ctxo->context; + astcenc_error status; + astcenc_image& image = *imagep; + + if (ctx->config.flags & ASTCENC_FLG_DECOMPRESS_ONLY) + { + return ASTCENC_ERR_BAD_CONTEXT; + } + + status = validate_compression_swizzle(*swizzle); + if (status != ASTCENC_SUCCESS) + { + return status; + } + + if (thread_index >= ctx->thread_count) + { + return ASTCENC_ERR_BAD_PARAM; + } + + unsigned int block_x = ctx->config.block_x; + unsigned int block_y = ctx->config.block_y; + unsigned int block_z = ctx->config.block_z; + + unsigned int xblocks = (image.dim_x + block_x - 1) / block_x; + unsigned int yblocks = (image.dim_y + block_y - 1) / block_y; + unsigned int zblocks = (image.dim_z + block_z - 1) / block_z; + + // Check we have enough output space (16 bytes per block) + size_t size_needed = xblocks * yblocks * zblocks * 16; + if (data_len < size_needed) + { + return ASTCENC_ERR_OUT_OF_MEM; + } + + // If context thread count is one then implicitly reset + if (ctx->thread_count == 1) + { + astcenc_compress_reset(ctxo); + } + + if (ctx->config.a_scale_radius != 0) + { + // First thread to enter will do setup, other threads will subsequently + // enter the critical section but simply skip over the initialization + auto init_avg = [ctx, &image, swizzle]() { + // Perform memory allocations for the destination buffers + size_t texel_count = image.dim_x * image.dim_y * image.dim_z; + ctx->input_alpha_averages = new float[texel_count]; + + return init_compute_averages( + image, ctx->config.a_scale_radius, *swizzle, + ctx->avg_preprocess_args); + }; + + // Only the first thread actually runs the initializer + ctxo->manage_avg.init(init_avg); + + // All threads will enter this function and dynamically grab work + compute_averages(*ctxo, ctx->avg_preprocess_args); + } + + // Wait for compute_averages to complete before compressing + ctxo->manage_avg.wait(); + + compress_image(*ctxo, thread_index, image, *swizzle, data_out); + + // Wait for compress to complete before freeing memory + ctxo->manage_compress.wait(); + + auto term_compress = [ctx]() { + delete[] ctx->input_alpha_averages; + ctx->input_alpha_averages = nullptr; + }; + + // Only the first thread to arrive actually runs the term + ctxo->manage_compress.term(term_compress); + + return ASTCENC_SUCCESS; +#endif +} + +/* See header for documentation. */ +astcenc_error astcenc_compress_reset( + astcenc_context* ctxo +) { +#if defined(ASTCENC_DECOMPRESS_ONLY) + (void)ctxo; + return ASTCENC_ERR_BAD_CONTEXT; +#else + astcenc_contexti* ctx = &ctxo->context; + if (ctx->config.flags & ASTCENC_FLG_DECOMPRESS_ONLY) + { + return ASTCENC_ERR_BAD_CONTEXT; + } + + ctxo->manage_avg.reset(); + ctxo->manage_compress.reset(); + return ASTCENC_SUCCESS; +#endif +} + +/* See header for documentation. */ +astcenc_error astcenc_decompress_image( + astcenc_context* ctxo, + const uint8_t* data, + size_t data_len, + astcenc_image* image_outp, + const astcenc_swizzle* swizzle, + unsigned int thread_index +) { + astcenc_error status; + astcenc_image& image_out = *image_outp; + astcenc_contexti* ctx = &ctxo->context; + + // Today this doesn't matter (working set on stack) but might in future ... + if (thread_index >= ctx->thread_count) + { + return ASTCENC_ERR_BAD_PARAM; + } + + status = validate_decompression_swizzle(*swizzle); + if (status != ASTCENC_SUCCESS) + { + return status; + } + + unsigned int block_x = ctx->config.block_x; + unsigned int block_y = ctx->config.block_y; + unsigned int block_z = ctx->config.block_z; + + unsigned int xblocks = (image_out.dim_x + block_x - 1) / block_x; + unsigned int yblocks = (image_out.dim_y + block_y - 1) / block_y; + unsigned int zblocks = (image_out.dim_z + block_z - 1) / block_z; + + int row_blocks = xblocks; + int plane_blocks = xblocks * yblocks; + + // Check we have enough output space (16 bytes per block) + size_t size_needed = xblocks * yblocks * zblocks * 16; + if (data_len < size_needed) + { + return ASTCENC_ERR_OUT_OF_MEM; + } + + image_block blk; + blk.texel_count = static_cast<uint8_t>(block_x * block_y * block_z); + + // If context thread count is one then implicitly reset + if (ctx->thread_count == 1) + { + astcenc_decompress_reset(ctxo); + } + + // Only the first thread actually runs the initializer + ctxo->manage_decompress.init(zblocks * yblocks * xblocks); + + // All threads run this processing loop until there is no work remaining + while (true) + { + unsigned int count; + unsigned int base = ctxo->manage_decompress.get_task_assignment(128, count); + if (!count) + { + break; + } + + for (unsigned int i = base; i < base + count; i++) + { + // Decode i into x, y, z block indices + int z = i / plane_blocks; + unsigned int rem = i - (z * plane_blocks); + int y = rem / row_blocks; + int x = rem - (y * row_blocks); + + unsigned int offset = (((z * yblocks + y) * xblocks) + x) * 16; + const uint8_t* bp = data + offset; + + const physical_compressed_block& pcb = *reinterpret_cast<const physical_compressed_block*>(bp); + symbolic_compressed_block scb; + + physical_to_symbolic(*ctx->bsd, pcb, scb); + + decompress_symbolic_block(ctx->config.profile, *ctx->bsd, + x * block_x, y * block_y, z * block_z, + scb, blk); + + store_image_block(image_out, blk, *ctx->bsd, + x * block_x, y * block_y, z * block_z, *swizzle); + } + + ctxo->manage_decompress.complete_task_assignment(count); + } + + return ASTCENC_SUCCESS; +} + +/* See header for documentation. */ +astcenc_error astcenc_decompress_reset( + astcenc_context* ctxo +) { + ctxo->manage_decompress.reset(); + return ASTCENC_SUCCESS; +} + +/* See header for documentation. */ +astcenc_error astcenc_get_block_info( + astcenc_context* ctxo, + const uint8_t data[16], + astcenc_block_info* info +) { +#if defined(ASTCENC_DECOMPRESS_ONLY) + (void)ctxo; + (void)data; + (void)info; + return ASTCENC_ERR_BAD_CONTEXT; +#else + astcenc_contexti* ctx = &ctxo->context; + + // Decode the compressed data into a symbolic form + const physical_compressed_block&pcb = *reinterpret_cast<const physical_compressed_block*>(data); + symbolic_compressed_block scb; + physical_to_symbolic(*ctx->bsd, pcb, scb); + + // Fetch the appropriate partition and decimation tables + block_size_descriptor& bsd = *ctx->bsd; + + // Start from a clean slate + memset(info, 0, sizeof(*info)); + + // Basic info we can always populate + info->profile = ctx->config.profile; + + info->block_x = ctx->config.block_x; + info->block_y = ctx->config.block_y; + info->block_z = ctx->config.block_z; + info->texel_count = bsd.texel_count; + + // Check for error blocks first + info->is_error_block = scb.block_type == SYM_BTYPE_ERROR; + if (info->is_error_block) + { + return ASTCENC_SUCCESS; + } + + // Check for constant color blocks second + info->is_constant_block = scb.block_type == SYM_BTYPE_CONST_F16 || + scb.block_type == SYM_BTYPE_CONST_U16; + if (info->is_constant_block) + { + return ASTCENC_SUCCESS; + } + + // Otherwise handle a full block ; known to be valid after conditions above have been checked + int partition_count = scb.partition_count; + const auto& pi = bsd.get_partition_info(partition_count, scb.partition_index); + + const block_mode& bm = bsd.get_block_mode(scb.block_mode); + const decimation_info& di = bsd.get_decimation_info(bm.decimation_mode); + + info->weight_x = di.weight_x; + info->weight_y = di.weight_y; + info->weight_z = di.weight_z; + + info->is_dual_plane_block = bm.is_dual_plane != 0; + + info->partition_count = scb.partition_count; + info->partition_index = scb.partition_index; + info->dual_plane_component = scb.plane2_component; + + info->color_level_count = get_quant_level(scb.get_color_quant_mode()); + info->weight_level_count = get_quant_level(bm.get_weight_quant_mode()); + + // Unpack color endpoints for each active partition + for (unsigned int i = 0; i < scb.partition_count; i++) + { + bool rgb_hdr; + bool a_hdr; + vint4 endpnt[2]; + + unpack_color_endpoints(ctx->config.profile, + scb.color_formats[i], + scb.color_values[i], + rgb_hdr, a_hdr, + endpnt[0], endpnt[1]); + + // Store the color endpoint mode info + info->color_endpoint_modes[i] = scb.color_formats[i]; + info->is_hdr_block = info->is_hdr_block || rgb_hdr || a_hdr; + + // Store the unpacked and decoded color endpoint + vmask4 hdr_mask(rgb_hdr, rgb_hdr, rgb_hdr, a_hdr); + for (int j = 0; j < 2; j++) + { + vint4 color_lns = lns_to_sf16(endpnt[j]); + vint4 color_unorm = unorm16_to_sf16(endpnt[j]); + vint4 datai = select(color_unorm, color_lns, hdr_mask); + store(float16_to_float(datai), info->color_endpoints[i][j]); + } + } + + // Unpack weights for each texel + int weight_plane1[BLOCK_MAX_TEXELS]; + int weight_plane2[BLOCK_MAX_TEXELS]; + + unpack_weights(bsd, scb, di, bm.is_dual_plane, weight_plane1, weight_plane2); + for (unsigned int i = 0; i < bsd.texel_count; i++) + { + info->weight_values_plane1[i] = static_cast<float>(weight_plane1[i]) * (1.0f / WEIGHTS_TEXEL_SUM); + if (info->is_dual_plane_block) + { + info->weight_values_plane2[i] = static_cast<float>(weight_plane2[i]) * (1.0f / WEIGHTS_TEXEL_SUM); + } + } + + // Unpack partition assignments for each texel + for (unsigned int i = 0; i < bsd.texel_count; i++) + { + info->partition_assignment[i] = pi.partition_of_texel[i]; + } + + return ASTCENC_SUCCESS; +#endif +} + +/* See header for documentation. */ +const char* astcenc_get_error_string( + astcenc_error status +) { + // Values in this enum are from an external user, so not guaranteed to be + // bounded to the enum values + switch (static_cast<int>(status)) + { + case ASTCENC_SUCCESS: + return "ASTCENC_SUCCESS"; + case ASTCENC_ERR_OUT_OF_MEM: + return "ASTCENC_ERR_OUT_OF_MEM"; + case ASTCENC_ERR_BAD_CPU_FLOAT: + return "ASTCENC_ERR_BAD_CPU_FLOAT"; + case ASTCENC_ERR_BAD_CPU_ISA: + return "ASTCENC_ERR_BAD_CPU_ISA"; + case ASTCENC_ERR_BAD_PARAM: + return "ASTCENC_ERR_BAD_PARAM"; + case ASTCENC_ERR_BAD_BLOCK_SIZE: + return "ASTCENC_ERR_BAD_BLOCK_SIZE"; + case ASTCENC_ERR_BAD_PROFILE: + return "ASTCENC_ERR_BAD_PROFILE"; + case ASTCENC_ERR_BAD_QUALITY: + return "ASTCENC_ERR_BAD_QUALITY"; + case ASTCENC_ERR_BAD_FLAGS: + return "ASTCENC_ERR_BAD_FLAGS"; + case ASTCENC_ERR_BAD_SWIZZLE: + return "ASTCENC_ERR_BAD_SWIZZLE"; + case ASTCENC_ERR_BAD_CONTEXT: + return "ASTCENC_ERR_BAD_CONTEXT"; + case ASTCENC_ERR_NOT_IMPLEMENTED: + return "ASTCENC_ERR_NOT_IMPLEMENTED"; +#if defined(ASTCENC_DIAGNOSTICS) + case ASTCENC_ERR_DTRACE_FAILURE: + return "ASTCENC_ERR_DTRACE_FAILURE"; +#endif + default: + return nullptr; + } +} diff --git a/thirdparty/astcenc/astcenc_find_best_partitioning.cpp b/thirdparty/astcenc/astcenc_find_best_partitioning.cpp new file mode 100644 index 0000000000..ffde3c7060 --- /dev/null +++ b/thirdparty/astcenc/astcenc_find_best_partitioning.cpp @@ -0,0 +1,780 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2023 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +#if !defined(ASTCENC_DECOMPRESS_ONLY) + +/** + * @brief Functions for finding best partition for a block. + * + * The partition search operates in two stages. The first pass uses kmeans clustering to group + * texels into an ideal partitioning for the requested partition count, and then compares that + * against the 1024 partitionings generated by the ASTC partition hash function. The generated + * partitions are then ranked by the number of texels in the wrong partition, compared to the ideal + * clustering. All 1024 partitions are tested for similarity and ranked, apart from duplicates and + * partitionings that actually generate fewer than the requested partition count, but only the top + * N candidates are actually put through a more detailed search. N is determined by the compressor + * quality preset. + * + * For the detailed search, each candidate is checked against two possible encoding methods: + * + * - The best partitioning assuming different chroma colors (RGB + RGB or RGB + delta endpoints). + * - The best partitioning assuming same chroma colors (RGB + scale endpoints). + * + * This is implemented by computing the compute mean color and dominant direction for each + * partition. This defines two lines, both of which go through the mean color value. + * + * - One line has a direction defined by the dominant direction; this is used to assess the error + * from using an uncorrelated color representation. + * - The other line goes through (0,0,0,1) and is used to assess the error from using a same chroma + * (RGB + scale) color representation. + * + * The best candidate is selected by computing the squared-errors that result from using these + * lines for endpoint selection. + */ + +#include <limits> +#include "astcenc_internal.h" + +/** + * @brief Pick some initial kmeans cluster centers. + * + * @param blk The image block color data to compress. + * @param texel_count The number of texels in the block. + * @param partition_count The number of partitions in the block. + * @param[out] cluster_centers The initial partition cluster center colors. + */ +static void kmeans_init( + const image_block& blk, + unsigned int texel_count, + unsigned int partition_count, + vfloat4 cluster_centers[BLOCK_MAX_PARTITIONS] +) { + promise(texel_count > 0); + promise(partition_count > 0); + + unsigned int clusters_selected = 0; + float distances[BLOCK_MAX_TEXELS]; + + // Pick a random sample as first cluster center; 145897 from random.org + unsigned int sample = 145897 % texel_count; + vfloat4 center_color = blk.texel(sample); + cluster_centers[clusters_selected] = center_color; + clusters_selected++; + + // Compute the distance to the first cluster center + float distance_sum = 0.0f; + for (unsigned int i = 0; i < texel_count; i++) + { + vfloat4 color = blk.texel(i); + vfloat4 diff = color - center_color; + float distance = dot_s(diff * diff, blk.channel_weight); + distance_sum += distance; + distances[i] = distance; + } + + // More numbers from random.org for weighted-random center selection + const float cluster_cutoffs[9] { + 0.626220f, 0.932770f, 0.275454f, + 0.318558f, 0.240113f, 0.009190f, + 0.347661f, 0.731960f, 0.156391f + }; + + unsigned int cutoff = (clusters_selected - 1) + 3 * (partition_count - 2); + + // Pick the remaining samples as needed + while (true) + { + // Pick the next center in a weighted-random fashion. + float summa = 0.0f; + float distance_cutoff = distance_sum * cluster_cutoffs[cutoff++]; + for (sample = 0; sample < texel_count; sample++) + { + summa += distances[sample]; + if (summa >= distance_cutoff) + { + break; + } + } + + // Clamp to a valid range and store the selected cluster center + sample = astc::min(sample, texel_count - 1); + + center_color = blk.texel(sample); + cluster_centers[clusters_selected++] = center_color; + if (clusters_selected >= partition_count) + { + break; + } + + // Compute the distance to the new cluster center, keep the min dist + distance_sum = 0.0f; + for (unsigned int i = 0; i < texel_count; i++) + { + vfloat4 color = blk.texel(i); + vfloat4 diff = color - center_color; + float distance = dot_s(diff * diff, blk.channel_weight); + distance = astc::min(distance, distances[i]); + distance_sum += distance; + distances[i] = distance; + } + } +} + +/** + * @brief Assign texels to clusters, based on a set of chosen center points. + * + * @param blk The image block color data to compress. + * @param texel_count The number of texels in the block. + * @param partition_count The number of partitions in the block. + * @param cluster_centers The partition cluster center colors. + * @param[out] partition_of_texel The partition assigned for each texel. + */ +static void kmeans_assign( + const image_block& blk, + unsigned int texel_count, + unsigned int partition_count, + const vfloat4 cluster_centers[BLOCK_MAX_PARTITIONS], + uint8_t partition_of_texel[BLOCK_MAX_TEXELS] +) { + promise(texel_count > 0); + promise(partition_count > 0); + + uint8_t partition_texel_count[BLOCK_MAX_PARTITIONS] { 0 }; + + // Find the best partition for every texel + for (unsigned int i = 0; i < texel_count; i++) + { + float best_distance = std::numeric_limits<float>::max(); + unsigned int best_partition = 0; + + vfloat4 color = blk.texel(i); + for (unsigned int j = 0; j < partition_count; j++) + { + vfloat4 diff = color - cluster_centers[j]; + float distance = dot_s(diff * diff, blk.channel_weight); + if (distance < best_distance) + { + best_distance = distance; + best_partition = j; + } + } + + partition_of_texel[i] = static_cast<uint8_t>(best_partition); + partition_texel_count[best_partition]++; + } + + // It is possible to get a situation where a partition ends up without any texels. In this case, + // assign texel N to partition N. This is silly, but ensures that every partition retains at + // least one texel. Reassigning a texel in this manner may cause another partition to go empty, + // so if we actually did a reassignment, run the whole loop over again. + bool problem_case; + do + { + problem_case = false; + for (unsigned int i = 0; i < partition_count; i++) + { + if (partition_texel_count[i] == 0) + { + partition_texel_count[partition_of_texel[i]]--; + partition_texel_count[i]++; + partition_of_texel[i] = static_cast<uint8_t>(i); + problem_case = true; + } + } + } while (problem_case); +} + +/** + * @brief Compute new cluster centers based on their center of gravity. + * + * @param blk The image block color data to compress. + * @param texel_count The number of texels in the block. + * @param partition_count The number of partitions in the block. + * @param[out] cluster_centers The new cluster center colors. + * @param partition_of_texel The partition assigned for each texel. + */ +static void kmeans_update( + const image_block& blk, + unsigned int texel_count, + unsigned int partition_count, + vfloat4 cluster_centers[BLOCK_MAX_PARTITIONS], + const uint8_t partition_of_texel[BLOCK_MAX_TEXELS] +) { + promise(texel_count > 0); + promise(partition_count > 0); + + vfloat4 color_sum[BLOCK_MAX_PARTITIONS] { + vfloat4::zero(), + vfloat4::zero(), + vfloat4::zero(), + vfloat4::zero() + }; + + uint8_t partition_texel_count[BLOCK_MAX_PARTITIONS] { 0 }; + + // Find the center-of-gravity in each cluster + for (unsigned int i = 0; i < texel_count; i++) + { + uint8_t partition = partition_of_texel[i]; + color_sum[partition] += blk.texel(i); + partition_texel_count[partition]++; + } + + // Set the center of gravity to be the new cluster center + for (unsigned int i = 0; i < partition_count; i++) + { + float scale = 1.0f / static_cast<float>(partition_texel_count[i]); + cluster_centers[i] = color_sum[i] * scale; + } +} + +/** + * @brief Compute bit-mismatch for partitioning in 2-partition mode. + * + * @param a The texel assignment bitvector for the block. + * @param b The texel assignment bitvector for the partition table. + * + * @return The number of bit mismatches. + */ +static inline unsigned int partition_mismatch2( + const uint64_t a[2], + const uint64_t b[2] +) { + int v1 = popcount(a[0] ^ b[0]) + popcount(a[1] ^ b[1]); + int v2 = popcount(a[0] ^ b[1]) + popcount(a[1] ^ b[0]); + return astc::min(v1, v2); +} + +/** + * @brief Compute bit-mismatch for partitioning in 3-partition mode. + * + * @param a The texel assignment bitvector for the block. + * @param b The texel assignment bitvector for the partition table. + * + * @return The number of bit mismatches. + */ +static inline unsigned int partition_mismatch3( + const uint64_t a[3], + const uint64_t b[3] +) { + int p00 = popcount(a[0] ^ b[0]); + int p01 = popcount(a[0] ^ b[1]); + int p02 = popcount(a[0] ^ b[2]); + + int p10 = popcount(a[1] ^ b[0]); + int p11 = popcount(a[1] ^ b[1]); + int p12 = popcount(a[1] ^ b[2]); + + int p20 = popcount(a[2] ^ b[0]); + int p21 = popcount(a[2] ^ b[1]); + int p22 = popcount(a[2] ^ b[2]); + + int s0 = p11 + p22; + int s1 = p12 + p21; + int v0 = astc::min(s0, s1) + p00; + + int s2 = p10 + p22; + int s3 = p12 + p20; + int v1 = astc::min(s2, s3) + p01; + + int s4 = p10 + p21; + int s5 = p11 + p20; + int v2 = astc::min(s4, s5) + p02; + + return astc::min(v0, v1, v2); +} + +/** + * @brief Compute bit-mismatch for partitioning in 4-partition mode. + * + * @param a The texel assignment bitvector for the block. + * @param b The texel assignment bitvector for the partition table. + * + * @return The number of bit mismatches. + */ +static inline unsigned int partition_mismatch4( + const uint64_t a[4], + const uint64_t b[4] +) { + int p00 = popcount(a[0] ^ b[0]); + int p01 = popcount(a[0] ^ b[1]); + int p02 = popcount(a[0] ^ b[2]); + int p03 = popcount(a[0] ^ b[3]); + + int p10 = popcount(a[1] ^ b[0]); + int p11 = popcount(a[1] ^ b[1]); + int p12 = popcount(a[1] ^ b[2]); + int p13 = popcount(a[1] ^ b[3]); + + int p20 = popcount(a[2] ^ b[0]); + int p21 = popcount(a[2] ^ b[1]); + int p22 = popcount(a[2] ^ b[2]); + int p23 = popcount(a[2] ^ b[3]); + + int p30 = popcount(a[3] ^ b[0]); + int p31 = popcount(a[3] ^ b[1]); + int p32 = popcount(a[3] ^ b[2]); + int p33 = popcount(a[3] ^ b[3]); + + int mx23 = astc::min(p22 + p33, p23 + p32); + int mx13 = astc::min(p21 + p33, p23 + p31); + int mx12 = astc::min(p21 + p32, p22 + p31); + int mx03 = astc::min(p20 + p33, p23 + p30); + int mx02 = astc::min(p20 + p32, p22 + p30); + int mx01 = astc::min(p21 + p30, p20 + p31); + + int v0 = p00 + astc::min(p11 + mx23, p12 + mx13, p13 + mx12); + int v1 = p01 + astc::min(p10 + mx23, p12 + mx03, p13 + mx02); + int v2 = p02 + astc::min(p11 + mx03, p10 + mx13, p13 + mx01); + int v3 = p03 + astc::min(p11 + mx02, p12 + mx01, p10 + mx12); + + return astc::min(v0, v1, v2, v3); +} + +using mismatch_dispatch = unsigned int (*)(const uint64_t*, const uint64_t*); + +/** + * @brief Count the partition table mismatches vs the data clustering. + * + * @param bsd The block size information. + * @param partition_count The number of partitions in the block. + * @param bitmaps The block texel partition assignment patterns. + * @param[out] mismatch_counts The array storing per partitioning mismatch counts. + */ +static void count_partition_mismatch_bits( + const block_size_descriptor& bsd, + unsigned int partition_count, + const uint64_t bitmaps[BLOCK_MAX_PARTITIONS], + unsigned int mismatch_counts[BLOCK_MAX_PARTITIONINGS] +) { + unsigned int active_count = bsd.partitioning_count_selected[partition_count - 1]; + promise(active_count > 0); + + if (partition_count == 2) + { + for (unsigned int i = 0; i < active_count; i++) + { + mismatch_counts[i] = partition_mismatch2(bitmaps, bsd.coverage_bitmaps_2[i]); + } + } + else if (partition_count == 3) + { + for (unsigned int i = 0; i < active_count; i++) + { + mismatch_counts[i] = partition_mismatch3(bitmaps, bsd.coverage_bitmaps_3[i]); + } + } + else + { + for (unsigned int i = 0; i < active_count; i++) + { + mismatch_counts[i] = partition_mismatch4(bitmaps, bsd.coverage_bitmaps_4[i]); + } + } +} + +/** + * @brief Use counting sort on the mismatch array to sort partition candidates. + * + * @param partitioning_count The number of packed partitionings. + * @param mismatch_count Partitioning mismatch counts, in index order. + * @param[out] partition_ordering Partition index values, in mismatch order. + * + * @return The number of active partitions in this selection. + */ +static unsigned int get_partition_ordering_by_mismatch_bits( + unsigned int partitioning_count, + const unsigned int mismatch_count[BLOCK_MAX_PARTITIONINGS], + unsigned int partition_ordering[BLOCK_MAX_PARTITIONINGS] +) { + promise(partitioning_count > 0); + unsigned int mscount[256] { 0 }; + + // Create the histogram of mismatch counts + for (unsigned int i = 0; i < partitioning_count; i++) + { + mscount[mismatch_count[i]]++; + } + + unsigned int active_count = partitioning_count - mscount[255]; + + // Create a running sum from the histogram array + // Cells store previous values only; i.e. exclude self after sum + unsigned int summa = 0; + for (unsigned int i = 0; i < 256; i++) + { + unsigned int cnt = mscount[i]; + mscount[i] = summa; + summa += cnt; + } + + // Use the running sum as the index, incrementing after read to allow + // sequential entries with the same count + for (unsigned int i = 0; i < partitioning_count; i++) + { + unsigned int idx = mscount[mismatch_count[i]]++; + partition_ordering[idx] = i; + } + + return active_count; +} + +/** + * @brief Use k-means clustering to compute a partition ordering for a block.. + * + * @param bsd The block size information. + * @param blk The image block color data to compress. + * @param partition_count The desired number of partitions in the block. + * @param[out] partition_ordering The list of recommended partition indices, in priority order. + * + * @return The number of active partitionings in this selection. + */ +static unsigned int compute_kmeans_partition_ordering( + const block_size_descriptor& bsd, + const image_block& blk, + unsigned int partition_count, + unsigned int partition_ordering[BLOCK_MAX_PARTITIONINGS] +) { + vfloat4 cluster_centers[BLOCK_MAX_PARTITIONS]; + uint8_t texel_partitions[BLOCK_MAX_TEXELS]; + + // Use three passes of k-means clustering to partition the block data + for (unsigned int i = 0; i < 3; i++) + { + if (i == 0) + { + kmeans_init(blk, bsd.texel_count, partition_count, cluster_centers); + } + else + { + kmeans_update(blk, bsd.texel_count, partition_count, cluster_centers, texel_partitions); + } + + kmeans_assign(blk, bsd.texel_count, partition_count, cluster_centers, texel_partitions); + } + + // Construct the block bitmaps of texel assignments to each partition + uint64_t bitmaps[BLOCK_MAX_PARTITIONS] { 0 }; + unsigned int texels_to_process = astc::min(bsd.texel_count, BLOCK_MAX_KMEANS_TEXELS); + promise(texels_to_process > 0); + for (unsigned int i = 0; i < texels_to_process; i++) + { + unsigned int idx = bsd.kmeans_texels[i]; + bitmaps[texel_partitions[idx]] |= 1ULL << i; + } + + // Count the mismatch between the block and the format's partition tables + unsigned int mismatch_counts[BLOCK_MAX_PARTITIONINGS]; + count_partition_mismatch_bits(bsd, partition_count, bitmaps, mismatch_counts); + + // Sort the partitions based on the number of mismatched bits + return get_partition_ordering_by_mismatch_bits( + bsd.partitioning_count_selected[partition_count - 1], + mismatch_counts, partition_ordering); +} + +/** + * @brief Insert a partitioning into an order list of results, sorted by error. + * + * @param max_values The max number of entries in the best result arrays. + * @param this_error The error of the new entry. + * @param this_partition The partition ID of the new entry. + * @param[out] best_errors The array of best error values. + * @param[out] best_partitions The array of best partition values. + */ +static void insert_result( + unsigned int max_values, + float this_error, + unsigned int this_partition, + float* best_errors, + unsigned int* best_partitions) +{ + promise(max_values > 0); + + // Don't bother searching if the current worst error beats the new error + if (this_error >= best_errors[max_values - 1]) + { + return; + } + + // Else insert into the list in error-order + for (unsigned int i = 0; i < max_values; i++) + { + // Existing result is better - move on ... + if (this_error > best_errors[i]) + { + continue; + } + + // Move existing results down one + for (unsigned int j = max_values - 1; j > i; j--) + { + best_errors[j] = best_errors[j - 1]; + best_partitions[j] = best_partitions[j - 1]; + } + + // Insert new result + best_errors[i] = this_error; + best_partitions[i] = this_partition; + break; + } +} + +/* See header for documentation. */ +unsigned int find_best_partition_candidates( + const block_size_descriptor& bsd, + const image_block& blk, + unsigned int partition_count, + unsigned int partition_search_limit, + unsigned int best_partitions[TUNE_MAX_PARTITIONING_CANDIDATES], + unsigned int requested_candidates +) { + // Constant used to estimate quantization error for a given partitioning; the optimal value for + // this depends on bitrate. These values have been determined empirically. + unsigned int texels_per_block = bsd.texel_count; + float weight_imprecision_estim = 0.055f; + if (texels_per_block <= 20) + { + weight_imprecision_estim = 0.03f; + } + else if (texels_per_block <= 31) + { + weight_imprecision_estim = 0.04f; + } + else if (texels_per_block <= 41) + { + weight_imprecision_estim = 0.05f; + } + + promise(partition_count > 0); + promise(partition_search_limit > 0); + + weight_imprecision_estim = weight_imprecision_estim * weight_imprecision_estim; + + unsigned int partition_sequence[BLOCK_MAX_PARTITIONINGS]; + unsigned int sequence_len = compute_kmeans_partition_ordering(bsd, blk, partition_count, partition_sequence); + partition_search_limit = astc::min(partition_search_limit, sequence_len); + requested_candidates = astc::min(partition_search_limit, requested_candidates); + + bool uses_alpha = !blk.is_constant_channel(3); + + // Partitioning errors assuming uncorrelated-chrominance endpoints + float uncor_best_errors[TUNE_MAX_PARTITIONING_CANDIDATES]; + unsigned int uncor_best_partitions[TUNE_MAX_PARTITIONING_CANDIDATES]; + + // Partitioning errors assuming same-chrominance endpoints + float samec_best_errors[TUNE_MAX_PARTITIONING_CANDIDATES]; + unsigned int samec_best_partitions[TUNE_MAX_PARTITIONING_CANDIDATES]; + + for (unsigned int i = 0; i < requested_candidates; i++) + { + uncor_best_errors[i] = ERROR_CALC_DEFAULT; + samec_best_errors[i] = ERROR_CALC_DEFAULT; + } + + if (uses_alpha) + { + for (unsigned int i = 0; i < partition_search_limit; i++) + { + unsigned int partition = partition_sequence[i]; + const auto& pi = bsd.get_raw_partition_info(partition_count, partition); + + // Compute weighting to give to each component in each partition + partition_metrics pms[BLOCK_MAX_PARTITIONS]; + + compute_avgs_and_dirs_4_comp(pi, blk, pms); + + line4 uncor_lines[BLOCK_MAX_PARTITIONS]; + line4 samec_lines[BLOCK_MAX_PARTITIONS]; + + processed_line4 uncor_plines[BLOCK_MAX_PARTITIONS]; + processed_line4 samec_plines[BLOCK_MAX_PARTITIONS]; + + float uncor_line_lens[BLOCK_MAX_PARTITIONS]; + float samec_line_lens[BLOCK_MAX_PARTITIONS]; + + for (unsigned int j = 0; j < partition_count; j++) + { + partition_metrics& pm = pms[j]; + + uncor_lines[j].a = pm.avg; + uncor_lines[j].b = normalize_safe(pm.dir, unit4()); + + uncor_plines[j].amod = uncor_lines[j].a - uncor_lines[j].b * dot(uncor_lines[j].a, uncor_lines[j].b); + uncor_plines[j].bs = uncor_lines[j].b; + + samec_lines[j].a = vfloat4::zero(); + samec_lines[j].b = normalize_safe(pm.avg, unit4()); + + samec_plines[j].amod = vfloat4::zero(); + samec_plines[j].bs = samec_lines[j].b; + } + + float uncor_error = 0.0f; + float samec_error = 0.0f; + + compute_error_squared_rgba(pi, + blk, + uncor_plines, + samec_plines, + uncor_line_lens, + samec_line_lens, + uncor_error, + samec_error); + + // Compute an estimate of error introduced by weight quantization imprecision. + // This error is computed as follows, for each partition + // 1: compute the principal-axis vector (full length) in error-space + // 2: convert the principal-axis vector to regular RGB-space + // 3: scale the vector by a constant that estimates average quantization error + // 4: for each texel, square the vector, then do a dot-product with the texel's + // error weight; sum up the results across all texels. + // 4(optimized): square the vector once, then do a dot-product with the average + // texel error, then multiply by the number of texels. + + for (unsigned int j = 0; j < partition_count; j++) + { + float tpp = static_cast<float>(pi.partition_texel_count[j]); + vfloat4 error_weights(tpp * weight_imprecision_estim); + + vfloat4 uncor_vector = uncor_lines[j].b * uncor_line_lens[j]; + vfloat4 samec_vector = samec_lines[j].b * samec_line_lens[j]; + + uncor_error += dot_s(uncor_vector * uncor_vector, error_weights); + samec_error += dot_s(samec_vector * samec_vector, error_weights); + } + + insert_result(requested_candidates, uncor_error, partition, uncor_best_errors, uncor_best_partitions); + insert_result(requested_candidates, samec_error, partition, samec_best_errors, samec_best_partitions); + } + } + else + { + for (unsigned int i = 0; i < partition_search_limit; i++) + { + unsigned int partition = partition_sequence[i]; + const auto& pi = bsd.get_raw_partition_info(partition_count, partition); + + // Compute weighting to give to each component in each partition + partition_metrics pms[BLOCK_MAX_PARTITIONS]; + compute_avgs_and_dirs_3_comp_rgb(pi, blk, pms); + + partition_lines3 plines[BLOCK_MAX_PARTITIONS]; + + for (unsigned int j = 0; j < partition_count; j++) + { + partition_metrics& pm = pms[j]; + partition_lines3& pl = plines[j]; + + pl.uncor_line.a = pm.avg; + pl.uncor_line.b = normalize_safe(pm.dir, unit3()); + + pl.samec_line.a = vfloat4::zero(); + pl.samec_line.b = normalize_safe(pm.avg, unit3()); + + pl.uncor_pline.amod = pl.uncor_line.a - pl.uncor_line.b * dot3(pl.uncor_line.a, pl.uncor_line.b); + pl.uncor_pline.bs = pl.uncor_line.b; + + pl.samec_pline.amod = vfloat4::zero(); + pl.samec_pline.bs = pl.samec_line.b; + } + + float uncor_error = 0.0f; + float samec_error = 0.0f; + + compute_error_squared_rgb(pi, + blk, + plines, + uncor_error, + samec_error); + + // Compute an estimate of error introduced by weight quantization imprecision. + // This error is computed as follows, for each partition + // 1: compute the principal-axis vector (full length) in error-space + // 2: convert the principal-axis vector to regular RGB-space + // 3: scale the vector by a constant that estimates average quantization error + // 4: for each texel, square the vector, then do a dot-product with the texel's + // error weight; sum up the results across all texels. + // 4(optimized): square the vector once, then do a dot-product with the average + // texel error, then multiply by the number of texels. + + for (unsigned int j = 0; j < partition_count; j++) + { + partition_lines3& pl = plines[j]; + + float tpp = static_cast<float>(pi.partition_texel_count[j]); + vfloat4 error_weights(tpp * weight_imprecision_estim); + + vfloat4 uncor_vector = pl.uncor_line.b * pl.uncor_line_len; + vfloat4 samec_vector = pl.samec_line.b * pl.samec_line_len; + + uncor_error += dot3_s(uncor_vector * uncor_vector, error_weights); + samec_error += dot3_s(samec_vector * samec_vector, error_weights); + } + + insert_result(requested_candidates, uncor_error, partition, uncor_best_errors, uncor_best_partitions); + insert_result(requested_candidates, samec_error, partition, samec_best_errors, samec_best_partitions); + } + } + + bool best_is_uncor = uncor_best_partitions[0] > samec_best_partitions[0]; + + unsigned int interleave[2 * TUNE_MAX_PARTITIONING_CANDIDATES]; + for (unsigned int i = 0; i < requested_candidates; i++) + { + if (best_is_uncor) + { + interleave[2 * i] = bsd.get_raw_partition_info(partition_count, uncor_best_partitions[i]).partition_index; + interleave[2 * i + 1] = bsd.get_raw_partition_info(partition_count, samec_best_partitions[i]).partition_index; + } + else + { + interleave[2 * i] = bsd.get_raw_partition_info(partition_count, samec_best_partitions[i]).partition_index; + interleave[2 * i + 1] = bsd.get_raw_partition_info(partition_count, uncor_best_partitions[i]).partition_index; + } + } + + uint64_t bitmasks[1024/64] { 0 }; + unsigned int emitted = 0; + + // Deduplicate the first "requested" entries + for (unsigned int i = 0; i < requested_candidates * 2; i++) + { + unsigned int partition = interleave[i]; + + unsigned int word = partition / 64; + unsigned int bit = partition % 64; + + bool written = bitmasks[word] & (1ull << bit); + + if (!written) + { + best_partitions[emitted] = partition; + bitmasks[word] |= 1ull << bit; + emitted++; + + if (emitted == requested_candidates) + { + break; + } + } + } + + return emitted; +} + +#endif diff --git a/thirdparty/astcenc/astcenc_ideal_endpoints_and_weights.cpp b/thirdparty/astcenc/astcenc_ideal_endpoints_and_weights.cpp new file mode 100644 index 0000000000..5145e08693 --- /dev/null +++ b/thirdparty/astcenc/astcenc_ideal_endpoints_and_weights.cpp @@ -0,0 +1,1663 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2023 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +#if !defined(ASTCENC_DECOMPRESS_ONLY) + +/** + * @brief Functions for computing color endpoints and texel weights. + */ + +#include <cassert> + +#include "astcenc_internal.h" +#include "astcenc_vecmathlib.h" + +/** + * @brief Compute the infilled weight for N texel indices in a decimated grid. + * + * @param di The weight grid decimation to use. + * @param weights The decimated weight values to use. + * @param index The first texel index to interpolate. + * + * @return The interpolated weight for the given set of SIMD_WIDTH texels. + */ +static vfloat bilinear_infill_vla( + const decimation_info& di, + const float* weights, + unsigned int index +) { + // Load the bilinear filter texel weight indexes in the decimated grid + vint weight_idx0 = vint(di.texel_weights_tr[0] + index); + vint weight_idx1 = vint(di.texel_weights_tr[1] + index); + vint weight_idx2 = vint(di.texel_weights_tr[2] + index); + vint weight_idx3 = vint(di.texel_weights_tr[3] + index); + + // Load the bilinear filter weights from the decimated grid + vfloat weight_val0 = gatherf(weights, weight_idx0); + vfloat weight_val1 = gatherf(weights, weight_idx1); + vfloat weight_val2 = gatherf(weights, weight_idx2); + vfloat weight_val3 = gatherf(weights, weight_idx3); + + // Load the weight contribution factors for each decimated weight + vfloat tex_weight_float0 = loada(di.texel_weight_contribs_float_tr[0] + index); + vfloat tex_weight_float1 = loada(di.texel_weight_contribs_float_tr[1] + index); + vfloat tex_weight_float2 = loada(di.texel_weight_contribs_float_tr[2] + index); + vfloat tex_weight_float3 = loada(di.texel_weight_contribs_float_tr[3] + index); + + // Compute the bilinear interpolation to generate the per-texel weight + return (weight_val0 * tex_weight_float0 + weight_val1 * tex_weight_float1) + + (weight_val2 * tex_weight_float2 + weight_val3 * tex_weight_float3); +} + +/** + * @brief Compute the infilled weight for N texel indices in a decimated grid. + * + * This is specialized version which computes only two weights per texel for + * encodings that are only decimated in a single axis. + * + * @param di The weight grid decimation to use. + * @param weights The decimated weight values to use. + * @param index The first texel index to interpolate. + * + * @return The interpolated weight for the given set of SIMD_WIDTH texels. + */ +static vfloat bilinear_infill_vla_2( + const decimation_info& di, + const float* weights, + unsigned int index +) { + // Load the bilinear filter texel weight indexes in the decimated grid + vint weight_idx0 = vint(di.texel_weights_tr[0] + index); + vint weight_idx1 = vint(di.texel_weights_tr[1] + index); + + // Load the bilinear filter weights from the decimated grid + vfloat weight_val0 = gatherf(weights, weight_idx0); + vfloat weight_val1 = gatherf(weights, weight_idx1); + + // Load the weight contribution factors for each decimated weight + vfloat tex_weight_float0 = loada(di.texel_weight_contribs_float_tr[0] + index); + vfloat tex_weight_float1 = loada(di.texel_weight_contribs_float_tr[1] + index); + + // Compute the bilinear interpolation to generate the per-texel weight + return (weight_val0 * tex_weight_float0 + weight_val1 * tex_weight_float1); +} + +/** + * @brief Compute the ideal endpoints and weights for 1 color component. + * + * @param blk The image block color data to compress. + * @param pi The partition info for the current trial. + * @param[out] ei The computed ideal endpoints and weights. + * @param component The color component to compute. + */ +static void compute_ideal_colors_and_weights_1_comp( + const image_block& blk, + const partition_info& pi, + endpoints_and_weights& ei, + unsigned int component +) { + unsigned int partition_count = pi.partition_count; + ei.ep.partition_count = partition_count; + promise(partition_count > 0); + + unsigned int texel_count = blk.texel_count; + promise(texel_count > 0); + + float error_weight; + const float* data_vr = nullptr; + + assert(component < BLOCK_MAX_COMPONENTS); + switch (component) + { + case 0: + error_weight = blk.channel_weight.lane<0>(); + data_vr = blk.data_r; + break; + case 1: + error_weight = blk.channel_weight.lane<1>(); + data_vr = blk.data_g; + break; + case 2: + error_weight = blk.channel_weight.lane<2>(); + data_vr = blk.data_b; + break; + default: + assert(component == 3); + error_weight = blk.channel_weight.lane<3>(); + data_vr = blk.data_a; + break; + } + + vmask4 sep_mask = vint4::lane_id() == vint4(component); + bool is_constant_wes { true }; + float partition0_len_sq { 0.0f }; + + for (unsigned int i = 0; i < partition_count; i++) + { + float lowvalue { 1e10f }; + float highvalue { -1e10f }; + + unsigned int partition_texel_count = pi.partition_texel_count[i]; + for (unsigned int j = 0; j < partition_texel_count; j++) + { + unsigned int tix = pi.texels_of_partition[i][j]; + float value = data_vr[tix]; + lowvalue = astc::min(value, lowvalue); + highvalue = astc::max(value, highvalue); + } + + if (highvalue <= lowvalue) + { + lowvalue = 0.0f; + highvalue = 1e-7f; + } + + float length = highvalue - lowvalue; + float length_squared = length * length; + float scale = 1.0f / length; + + if (i == 0) + { + partition0_len_sq = length_squared; + } + else + { + is_constant_wes = is_constant_wes && length_squared == partition0_len_sq; + } + + for (unsigned int j = 0; j < partition_texel_count; j++) + { + unsigned int tix = pi.texels_of_partition[i][j]; + float value = (data_vr[tix] - lowvalue) * scale; + value = astc::clamp1f(value); + + ei.weights[tix] = value; + ei.weight_error_scale[tix] = length_squared * error_weight; + assert(!astc::isnan(ei.weight_error_scale[tix])); + } + + ei.ep.endpt0[i] = select(blk.data_min, vfloat4(lowvalue), sep_mask); + ei.ep.endpt1[i] = select(blk.data_max, vfloat4(highvalue), sep_mask); + } + + // Zero initialize any SIMD over-fetch + unsigned int texel_count_simd = round_up_to_simd_multiple_vla(texel_count); + for (unsigned int i = texel_count; i < texel_count_simd; i++) + { + ei.weights[i] = 0.0f; + ei.weight_error_scale[i] = 0.0f; + } + + ei.is_constant_weight_error_scale = is_constant_wes; +} + +/** + * @brief Compute the ideal endpoints and weights for 2 color components. + * + * @param blk The image block color data to compress. + * @param pi The partition info for the current trial. + * @param[out] ei The computed ideal endpoints and weights. + * @param component1 The first color component to compute. + * @param component2 The second color component to compute. + */ +static void compute_ideal_colors_and_weights_2_comp( + const image_block& blk, + const partition_info& pi, + endpoints_and_weights& ei, + int component1, + int component2 +) { + unsigned int partition_count = pi.partition_count; + ei.ep.partition_count = partition_count; + promise(partition_count > 0); + + unsigned int texel_count = blk.texel_count; + promise(texel_count > 0); + + partition_metrics pms[BLOCK_MAX_PARTITIONS]; + + float error_weight; + const float* data_vr = nullptr; + const float* data_vg = nullptr; + + if (component1 == 0 && component2 == 1) + { + error_weight = hadd_s(blk.channel_weight.swz<0, 1>()) / 2.0f; + + data_vr = blk.data_r; + data_vg = blk.data_g; + } + else if (component1 == 0 && component2 == 2) + { + error_weight = hadd_s(blk.channel_weight.swz<0, 2>()) / 2.0f; + + data_vr = blk.data_r; + data_vg = blk.data_b; + } + else // (component1 == 1 && component2 == 2) + { + assert(component1 == 1 && component2 == 2); + + error_weight = hadd_s(blk.channel_weight.swz<1, 2>()) / 2.0f; + + data_vr = blk.data_g; + data_vg = blk.data_b; + } + + compute_avgs_and_dirs_2_comp(pi, blk, component1, component2, pms); + + bool is_constant_wes { true }; + float partition0_len_sq { 0.0f }; + + vmask4 comp1_mask = vint4::lane_id() == vint4(component1); + vmask4 comp2_mask = vint4::lane_id() == vint4(component2); + + for (unsigned int i = 0; i < partition_count; i++) + { + vfloat4 dir = pms[i].dir; + if (hadd_s(dir) < 0.0f) + { + dir = vfloat4::zero() - dir; + } + + line2 line { pms[i].avg, normalize_safe(dir, unit2()) }; + float lowparam { 1e10f }; + float highparam { -1e10f }; + + unsigned int partition_texel_count = pi.partition_texel_count[i]; + for (unsigned int j = 0; j < partition_texel_count; j++) + { + unsigned int tix = pi.texels_of_partition[i][j]; + vfloat4 point = vfloat2(data_vr[tix], data_vg[tix]); + float param = dot_s(point - line.a, line.b); + ei.weights[tix] = param; + + lowparam = astc::min(param, lowparam); + highparam = astc::max(param, highparam); + } + + // It is possible for a uniform-color partition to produce length=0; + // this causes NaN issues so set to small value to avoid this problem + if (highparam <= lowparam) + { + lowparam = 0.0f; + highparam = 1e-7f; + } + + float length = highparam - lowparam; + float length_squared = length * length; + float scale = 1.0f / length; + + if (i == 0) + { + partition0_len_sq = length_squared; + } + else + { + is_constant_wes = is_constant_wes && length_squared == partition0_len_sq; + } + + for (unsigned int j = 0; j < partition_texel_count; j++) + { + unsigned int tix = pi.texels_of_partition[i][j]; + float idx = (ei.weights[tix] - lowparam) * scale; + idx = astc::clamp1f(idx); + + ei.weights[tix] = idx; + ei.weight_error_scale[tix] = length_squared * error_weight; + assert(!astc::isnan(ei.weight_error_scale[tix])); + } + + vfloat4 lowvalue = line.a + line.b * lowparam; + vfloat4 highvalue = line.a + line.b * highparam; + + vfloat4 ep0 = select(blk.data_min, vfloat4(lowvalue.lane<0>()), comp1_mask); + vfloat4 ep1 = select(blk.data_max, vfloat4(highvalue.lane<0>()), comp1_mask); + + ei.ep.endpt0[i] = select(ep0, vfloat4(lowvalue.lane<1>()), comp2_mask); + ei.ep.endpt1[i] = select(ep1, vfloat4(highvalue.lane<1>()), comp2_mask); + } + + // Zero initialize any SIMD over-fetch + unsigned int texel_count_simd = round_up_to_simd_multiple_vla(texel_count); + for (unsigned int i = texel_count; i < texel_count_simd; i++) + { + ei.weights[i] = 0.0f; + ei.weight_error_scale[i] = 0.0f; + } + + ei.is_constant_weight_error_scale = is_constant_wes; +} + +/** + * @brief Compute the ideal endpoints and weights for 3 color components. + * + * @param blk The image block color data to compress. + * @param pi The partition info for the current trial. + * @param[out] ei The computed ideal endpoints and weights. + * @param omitted_component The color component excluded from the calculation. + */ +static void compute_ideal_colors_and_weights_3_comp( + const image_block& blk, + const partition_info& pi, + endpoints_and_weights& ei, + unsigned int omitted_component +) { + unsigned int partition_count = pi.partition_count; + ei.ep.partition_count = partition_count; + promise(partition_count > 0); + + unsigned int texel_count = blk.texel_count; + promise(texel_count > 0); + + partition_metrics pms[BLOCK_MAX_PARTITIONS]; + + float error_weight; + const float* data_vr = nullptr; + const float* data_vg = nullptr; + const float* data_vb = nullptr; + if (omitted_component == 0) + { + error_weight = hadd_s(blk.channel_weight.swz<0, 1, 2>()); + data_vr = blk.data_g; + data_vg = blk.data_b; + data_vb = blk.data_a; + } + else if (omitted_component == 1) + { + error_weight = hadd_s(blk.channel_weight.swz<0, 2, 3>()); + data_vr = blk.data_r; + data_vg = blk.data_b; + data_vb = blk.data_a; + } + else if (omitted_component == 2) + { + error_weight = hadd_s(blk.channel_weight.swz<0, 1, 3>()); + data_vr = blk.data_r; + data_vg = blk.data_g; + data_vb = blk.data_a; + } + else + { + assert(omitted_component == 3); + + error_weight = hadd_s(blk.channel_weight.swz<0, 1, 2>()); + data_vr = blk.data_r; + data_vg = blk.data_g; + data_vb = blk.data_b; + } + + error_weight = error_weight * (1.0f / 3.0f); + + if (omitted_component == 3) + { + compute_avgs_and_dirs_3_comp_rgb(pi, blk, pms); + } + else + { + compute_avgs_and_dirs_3_comp(pi, blk, omitted_component, pms); + } + + bool is_constant_wes { true }; + float partition0_len_sq { 0.0f }; + + for (unsigned int i = 0; i < partition_count; i++) + { + vfloat4 dir = pms[i].dir; + if (hadd_rgb_s(dir) < 0.0f) + { + dir = vfloat4::zero() - dir; + } + + line3 line { pms[i].avg, normalize_safe(dir, unit3()) }; + float lowparam { 1e10f }; + float highparam { -1e10f }; + + unsigned int partition_texel_count = pi.partition_texel_count[i]; + for (unsigned int j = 0; j < partition_texel_count; j++) + { + unsigned int tix = pi.texels_of_partition[i][j]; + vfloat4 point = vfloat3(data_vr[tix], data_vg[tix], data_vb[tix]); + float param = dot3_s(point - line.a, line.b); + ei.weights[tix] = param; + + lowparam = astc::min(param, lowparam); + highparam = astc::max(param, highparam); + } + + // It is possible for a uniform-color partition to produce length=0; + // this causes NaN issues so set to small value to avoid this problem + if (highparam <= lowparam) + { + lowparam = 0.0f; + highparam = 1e-7f; + } + + float length = highparam - lowparam; + float length_squared = length * length; + float scale = 1.0f / length; + + if (i == 0) + { + partition0_len_sq = length_squared; + } + else + { + is_constant_wes = is_constant_wes && length_squared == partition0_len_sq; + } + + for (unsigned int j = 0; j < partition_texel_count; j++) + { + unsigned int tix = pi.texels_of_partition[i][j]; + float idx = (ei.weights[tix] - lowparam) * scale; + idx = astc::clamp1f(idx); + + ei.weights[tix] = idx; + ei.weight_error_scale[tix] = length_squared * error_weight; + assert(!astc::isnan(ei.weight_error_scale[tix])); + } + + vfloat4 ep0 = line.a + line.b * lowparam; + vfloat4 ep1 = line.a + line.b * highparam; + + vfloat4 bmin = blk.data_min; + vfloat4 bmax = blk.data_max; + + assert(omitted_component < BLOCK_MAX_COMPONENTS); + switch (omitted_component) + { + case 0: + ei.ep.endpt0[i] = vfloat4(bmin.lane<0>(), ep0.lane<0>(), ep0.lane<1>(), ep0.lane<2>()); + ei.ep.endpt1[i] = vfloat4(bmax.lane<0>(), ep1.lane<0>(), ep1.lane<1>(), ep1.lane<2>()); + break; + case 1: + ei.ep.endpt0[i] = vfloat4(ep0.lane<0>(), bmin.lane<1>(), ep0.lane<1>(), ep0.lane<2>()); + ei.ep.endpt1[i] = vfloat4(ep1.lane<0>(), bmax.lane<1>(), ep1.lane<1>(), ep1.lane<2>()); + break; + case 2: + ei.ep.endpt0[i] = vfloat4(ep0.lane<0>(), ep0.lane<1>(), bmin.lane<2>(), ep0.lane<2>()); + ei.ep.endpt1[i] = vfloat4(ep1.lane<0>(), ep1.lane<1>(), bmax.lane<2>(), ep1.lane<2>()); + break; + default: + ei.ep.endpt0[i] = vfloat4(ep0.lane<0>(), ep0.lane<1>(), ep0.lane<2>(), bmin.lane<3>()); + ei.ep.endpt1[i] = vfloat4(ep1.lane<0>(), ep1.lane<1>(), ep1.lane<2>(), bmax.lane<3>()); + break; + } + } + + // Zero initialize any SIMD over-fetch + unsigned int texel_count_simd = round_up_to_simd_multiple_vla(texel_count); + for (unsigned int i = texel_count; i < texel_count_simd; i++) + { + ei.weights[i] = 0.0f; + ei.weight_error_scale[i] = 0.0f; + } + + ei.is_constant_weight_error_scale = is_constant_wes; +} + +/** + * @brief Compute the ideal endpoints and weights for 4 color components. + * + * @param blk The image block color data to compress. + * @param pi The partition info for the current trial. + * @param[out] ei The computed ideal endpoints and weights. + */ +static void compute_ideal_colors_and_weights_4_comp( + const image_block& blk, + const partition_info& pi, + endpoints_and_weights& ei +) { + const float error_weight = hadd_s(blk.channel_weight) / 4.0f; + + unsigned int partition_count = pi.partition_count; + + unsigned int texel_count = blk.texel_count; + promise(texel_count > 0); + promise(partition_count > 0); + + partition_metrics pms[BLOCK_MAX_PARTITIONS]; + + compute_avgs_and_dirs_4_comp(pi, blk, pms); + + bool is_constant_wes { true }; + float partition0_len_sq { 0.0f }; + + for (unsigned int i = 0; i < partition_count; i++) + { + vfloat4 dir = pms[i].dir; + if (hadd_rgb_s(dir) < 0.0f) + { + dir = vfloat4::zero() - dir; + } + + line4 line { pms[i].avg, normalize_safe(dir, unit4()) }; + float lowparam { 1e10f }; + float highparam { -1e10f }; + + unsigned int partition_texel_count = pi.partition_texel_count[i]; + for (unsigned int j = 0; j < partition_texel_count; j++) + { + unsigned int tix = pi.texels_of_partition[i][j]; + vfloat4 point = blk.texel(tix); + float param = dot_s(point - line.a, line.b); + ei.weights[tix] = param; + + lowparam = astc::min(param, lowparam); + highparam = astc::max(param, highparam); + } + + // It is possible for a uniform-color partition to produce length=0; + // this causes NaN issues so set to small value to avoid this problem + if (highparam <= lowparam) + { + lowparam = 0.0f; + highparam = 1e-7f; + } + + float length = highparam - lowparam; + float length_squared = length * length; + float scale = 1.0f / length; + + if (i == 0) + { + partition0_len_sq = length_squared; + } + else + { + is_constant_wes = is_constant_wes && length_squared == partition0_len_sq; + } + + ei.ep.endpt0[i] = line.a + line.b * lowparam; + ei.ep.endpt1[i] = line.a + line.b * highparam; + + for (unsigned int j = 0; j < partition_texel_count; j++) + { + unsigned int tix = pi.texels_of_partition[i][j]; + float idx = (ei.weights[tix] - lowparam) * scale; + idx = astc::clamp1f(idx); + + ei.weights[tix] = idx; + ei.weight_error_scale[tix] = length_squared * error_weight; + assert(!astc::isnan(ei.weight_error_scale[tix])); + } + } + + // Zero initialize any SIMD over-fetch + unsigned int texel_count_simd = round_up_to_simd_multiple_vla(texel_count); + for (unsigned int i = texel_count; i < texel_count_simd; i++) + { + ei.weights[i] = 0.0f; + ei.weight_error_scale[i] = 0.0f; + } + + ei.is_constant_weight_error_scale = is_constant_wes; +} + +/* See header for documentation. */ +void compute_ideal_colors_and_weights_1plane( + const image_block& blk, + const partition_info& pi, + endpoints_and_weights& ei +) { + bool uses_alpha = !blk.is_constant_channel(3); + + if (uses_alpha) + { + compute_ideal_colors_and_weights_4_comp(blk, pi, ei); + } + else + { + compute_ideal_colors_and_weights_3_comp(blk, pi, ei, 3); + } +} + +/* See header for documentation. */ +void compute_ideal_colors_and_weights_2planes( + const block_size_descriptor& bsd, + const image_block& blk, + unsigned int plane2_component, + endpoints_and_weights& ei1, + endpoints_and_weights& ei2 +) { + const auto& pi = bsd.get_partition_info(1, 0); + bool uses_alpha = !blk.is_constant_channel(3); + + assert(plane2_component < BLOCK_MAX_COMPONENTS); + switch (plane2_component) + { + case 0: // Separate weights for red + if (uses_alpha) + { + compute_ideal_colors_and_weights_3_comp(blk, pi, ei1, 0); + } + else + { + compute_ideal_colors_and_weights_2_comp(blk, pi, ei1, 1, 2); + } + compute_ideal_colors_and_weights_1_comp(blk, pi, ei2, 0); + break; + + case 1: // Separate weights for green + if (uses_alpha) + { + compute_ideal_colors_and_weights_3_comp(blk, pi, ei1, 1); + } + else + { + compute_ideal_colors_and_weights_2_comp(blk, pi, ei1, 0, 2); + } + compute_ideal_colors_and_weights_1_comp(blk, pi, ei2, 1); + break; + + case 2: // Separate weights for blue + if (uses_alpha) + { + compute_ideal_colors_and_weights_3_comp(blk, pi, ei1, 2); + } + else + { + compute_ideal_colors_and_weights_2_comp(blk, pi, ei1, 0, 1); + } + compute_ideal_colors_and_weights_1_comp(blk, pi, ei2, 2); + break; + + default: // Separate weights for alpha + assert(uses_alpha); + compute_ideal_colors_and_weights_3_comp(blk, pi, ei1, 3); + compute_ideal_colors_and_weights_1_comp(blk, pi, ei2, 3); + break; + } +} + +/* See header for documentation. */ +float compute_error_of_weight_set_1plane( + const endpoints_and_weights& eai, + const decimation_info& di, + const float* dec_weight_quant_uvalue +) { + vfloatacc error_summav = vfloatacc::zero(); + unsigned int texel_count = di.texel_count; + promise(texel_count > 0); + + // Process SIMD-width chunks, safe to over-fetch - the extra space is zero initialized + if (di.max_texel_weight_count > 2) + { + for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) + { + // Compute the bilinear interpolation of the decimated weight grid + vfloat current_values = bilinear_infill_vla(di, dec_weight_quant_uvalue, i); + + // Compute the error between the computed value and the ideal weight + vfloat actual_values = loada(eai.weights + i); + vfloat diff = current_values - actual_values; + vfloat significance = loada(eai.weight_error_scale + i); + vfloat error = diff * diff * significance; + + haccumulate(error_summav, error); + } + } + else if (di.max_texel_weight_count > 1) + { + for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) + { + // Compute the bilinear interpolation of the decimated weight grid + vfloat current_values = bilinear_infill_vla_2(di, dec_weight_quant_uvalue, i); + + // Compute the error between the computed value and the ideal weight + vfloat actual_values = loada(eai.weights + i); + vfloat diff = current_values - actual_values; + vfloat significance = loada(eai.weight_error_scale + i); + vfloat error = diff * diff * significance; + + haccumulate(error_summav, error); + } + } + else + { + for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) + { + // Load the weight set directly, without interpolation + vfloat current_values = loada(dec_weight_quant_uvalue + i); + + // Compute the error between the computed value and the ideal weight + vfloat actual_values = loada(eai.weights + i); + vfloat diff = current_values - actual_values; + vfloat significance = loada(eai.weight_error_scale + i); + vfloat error = diff * diff * significance; + + haccumulate(error_summav, error); + } + } + + // Resolve the final scalar accumulator sum + return hadd_s(error_summav); +} + +/* See header for documentation. */ +float compute_error_of_weight_set_2planes( + const endpoints_and_weights& eai1, + const endpoints_and_weights& eai2, + const decimation_info& di, + const float* dec_weight_quant_uvalue_plane1, + const float* dec_weight_quant_uvalue_plane2 +) { + vfloatacc error_summav = vfloatacc::zero(); + unsigned int texel_count = di.texel_count; + promise(texel_count > 0); + + // Process SIMD-width chunks, safe to over-fetch - the extra space is zero initialized + if (di.max_texel_weight_count > 2) + { + for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) + { + // Plane 1 + // Compute the bilinear interpolation of the decimated weight grid + vfloat current_values1 = bilinear_infill_vla(di, dec_weight_quant_uvalue_plane1, i); + + // Compute the error between the computed value and the ideal weight + vfloat actual_values1 = loada(eai1.weights + i); + vfloat diff = current_values1 - actual_values1; + vfloat error1 = diff * diff * loada(eai1.weight_error_scale + i); + + // Plane 2 + // Compute the bilinear interpolation of the decimated weight grid + vfloat current_values2 = bilinear_infill_vla(di, dec_weight_quant_uvalue_plane2, i); + + // Compute the error between the computed value and the ideal weight + vfloat actual_values2 = loada(eai2.weights + i); + diff = current_values2 - actual_values2; + vfloat error2 = diff * diff * loada(eai2.weight_error_scale + i); + + haccumulate(error_summav, error1 + error2); + } + } + else if (di.max_texel_weight_count > 1) + { + for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) + { + // Plane 1 + // Compute the bilinear interpolation of the decimated weight grid + vfloat current_values1 = bilinear_infill_vla_2(di, dec_weight_quant_uvalue_plane1, i); + + // Compute the error between the computed value and the ideal weight + vfloat actual_values1 = loada(eai1.weights + i); + vfloat diff = current_values1 - actual_values1; + vfloat error1 = diff * diff * loada(eai1.weight_error_scale + i); + + // Plane 2 + // Compute the bilinear interpolation of the decimated weight grid + vfloat current_values2 = bilinear_infill_vla_2(di, dec_weight_quant_uvalue_plane2, i); + + // Compute the error between the computed value and the ideal weight + vfloat actual_values2 = loada(eai2.weights + i); + diff = current_values2 - actual_values2; + vfloat error2 = diff * diff * loada(eai2.weight_error_scale + i); + + haccumulate(error_summav, error1 + error2); + } + } + else + { + for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) + { + // Plane 1 + // Load the weight set directly, without interpolation + vfloat current_values1 = loada(dec_weight_quant_uvalue_plane1 + i); + + // Compute the error between the computed value and the ideal weight + vfloat actual_values1 = loada(eai1.weights + i); + vfloat diff = current_values1 - actual_values1; + vfloat error1 = diff * diff * loada(eai1.weight_error_scale + i); + + // Plane 2 + // Load the weight set directly, without interpolation + vfloat current_values2 = loada(dec_weight_quant_uvalue_plane2 + i); + + // Compute the error between the computed value and the ideal weight + vfloat actual_values2 = loada(eai2.weights + i); + diff = current_values2 - actual_values2; + vfloat error2 = diff * diff * loada(eai2.weight_error_scale + i); + + haccumulate(error_summav, error1 + error2); + } + } + + // Resolve the final scalar accumulator sum + return hadd_s(error_summav); +} + +/* See header for documentation. */ +void compute_ideal_weights_for_decimation( + const endpoints_and_weights& ei, + const decimation_info& di, + float* dec_weight_ideal_value +) { + unsigned int texel_count = di.texel_count; + unsigned int weight_count = di.weight_count; + bool is_direct = texel_count == weight_count; + promise(texel_count > 0); + promise(weight_count > 0); + + // Ensure that the end of the output arrays that are used for SIMD paths later are filled so we + // can safely run SIMD elsewhere without a loop tail. Note that this is always safe as weight + // arrays always contain space for 64 elements + unsigned int prev_weight_count_simd = round_down_to_simd_multiple_vla(weight_count - 1); + storea(vfloat::zero(), dec_weight_ideal_value + prev_weight_count_simd); + + // If we have a 1:1 mapping just shortcut the computation. Transfer enough to also copy the + // zero-initialized SIMD over-fetch region + if (is_direct) + { + for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) + { + vfloat weight(ei.weights + i); + storea(weight, dec_weight_ideal_value + i); + } + + return; + } + + // Otherwise compute an estimate and perform single refinement iteration + alignas(ASTCENC_VECALIGN) float infilled_weights[BLOCK_MAX_TEXELS]; + + // Compute an initial average for each decimated weight + bool constant_wes = ei.is_constant_weight_error_scale; + vfloat weight_error_scale(ei.weight_error_scale[0]); + + // This overshoots - this is OK as we initialize the array tails in the + // decimation table structures to safe values ... + for (unsigned int i = 0; i < weight_count; i += ASTCENC_SIMD_WIDTH) + { + // Start with a small value to avoid div-by-zero later + vfloat weight_weight(1e-10f); + vfloat initial_weight = vfloat::zero(); + + // Accumulate error weighting of all the texels using this weight + vint weight_texel_count(di.weight_texel_count + i); + unsigned int max_texel_count = hmax(weight_texel_count).lane<0>(); + promise(max_texel_count > 0); + + for (unsigned int j = 0; j < max_texel_count; j++) + { + vint texel(di.weight_texels_tr[j] + i); + vfloat weight = loada(di.weights_texel_contribs_tr[j] + i); + + if (!constant_wes) + { + weight_error_scale = gatherf(ei.weight_error_scale, texel); + } + + vfloat contrib_weight = weight * weight_error_scale; + + weight_weight += contrib_weight; + initial_weight += gatherf(ei.weights, texel) * contrib_weight; + } + + storea(initial_weight / weight_weight, dec_weight_ideal_value + i); + } + + // Populate the interpolated weight grid based on the initial average + // Process SIMD-width texel coordinates at at time while we can. Safe to + // over-process full SIMD vectors - the tail is zeroed. + if (di.max_texel_weight_count <= 2) + { + for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) + { + vfloat weight = bilinear_infill_vla_2(di, dec_weight_ideal_value, i); + storea(weight, infilled_weights + i); + } + } + else + { + for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) + { + vfloat weight = bilinear_infill_vla(di, dec_weight_ideal_value, i); + storea(weight, infilled_weights + i); + } + } + + // Perform a single iteration of refinement + // Empirically determined step size; larger values don't help but smaller drops image quality + constexpr float stepsize = 0.25f; + constexpr float chd_scale = -WEIGHTS_TEXEL_SUM; + + for (unsigned int i = 0; i < weight_count; i += ASTCENC_SIMD_WIDTH) + { + vfloat weight_val = loada(dec_weight_ideal_value + i); + + // Accumulate error weighting of all the texels using this weight + // Start with a small value to avoid div-by-zero later + vfloat error_change0(1e-10f); + vfloat error_change1(0.0f); + + // Accumulate error weighting of all the texels using this weight + vint weight_texel_count(di.weight_texel_count + i); + unsigned int max_texel_count = hmax(weight_texel_count).lane<0>(); + promise(max_texel_count > 0); + + for (unsigned int j = 0; j < max_texel_count; j++) + { + vint texel(di.weight_texels_tr[j] + i); + vfloat contrib_weight = loada(di.weights_texel_contribs_tr[j] + i); + + if (!constant_wes) + { + weight_error_scale = gatherf(ei.weight_error_scale, texel); + } + + vfloat scale = weight_error_scale * contrib_weight; + vfloat old_weight = gatherf(infilled_weights, texel); + vfloat ideal_weight = gatherf(ei.weights, texel); + + error_change0 += contrib_weight * scale; + error_change1 += (old_weight - ideal_weight) * scale; + } + + vfloat step = (error_change1 * chd_scale) / error_change0; + step = clamp(-stepsize, stepsize, step); + + // Update the weight; note this can store negative values + storea(weight_val + step, dec_weight_ideal_value + i); + } +} + +/* See header for documentation. */ +void compute_quantized_weights_for_decimation( + const decimation_info& di, + float low_bound, + float high_bound, + const float* dec_weight_ideal_value, + float* weight_set_out, + uint8_t* quantized_weight_set, + quant_method quant_level +) { + int weight_count = di.weight_count; + promise(weight_count > 0); + const quant_and_transfer_table& qat = quant_and_xfer_tables[quant_level]; + + // The available quant levels, stored with a minus 1 bias + static const float quant_levels_m1[12] { + 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 7.0f, 9.0f, 11.0f, 15.0f, 19.0f, 23.0f, 31.0f + }; + + vint steps_m1(get_quant_level(quant_level) - 1); + float quant_level_m1 = quant_levels_m1[quant_level]; + + // Quantize the weight set using both the specified low/high bounds and standard 0..1 bounds + + // TODO: Oddity to investigate; triggered by test in issue #265. + if (high_bound <= low_bound) + { + low_bound = 0.0f; + high_bound = 1.0f; + } + + float rscale = high_bound - low_bound; + float scale = 1.0f / rscale; + + float scaled_low_bound = low_bound * scale; + rscale *= 1.0f / 64.0f; + + vfloat scalev(scale); + vfloat scaled_low_boundv(scaled_low_bound); + vfloat quant_level_m1v(quant_level_m1); + vfloat rscalev(rscale); + vfloat low_boundv(low_bound); + + // This runs to the rounded-up SIMD size, which is safe as the loop tail is filled with known + // safe data in compute_ideal_weights_for_decimation and arrays are always 64 elements + if (get_quant_level(quant_level) <= 16) + { + vint4 tab0(reinterpret_cast<const int*>(qat.quant_to_unquant)); + vint tab0p; + vtable_prepare(tab0, tab0p); + + for (int i = 0; i < weight_count; i += ASTCENC_SIMD_WIDTH) + { + vfloat ix = loada(dec_weight_ideal_value + i) * scalev - scaled_low_boundv; + ix = clampzo(ix); + + // Look up the two closest indexes and return the one that was closest + vfloat ix1 = ix * quant_level_m1v; + + vint weightl = float_to_int(ix1); + vint weighth = min(weightl + vint(1), steps_m1); + + vint ixli = vtable_8bt_32bi(tab0p, weightl); + vint ixhi = vtable_8bt_32bi(tab0p, weighth); + + vfloat ixl = int_to_float(ixli); + vfloat ixh = int_to_float(ixhi); + + vmask mask = (ixl + ixh) < (vfloat(128.0f) * ix); + vint weight = select(ixli, ixhi, mask); + ixl = select(ixl, ixh, mask); + + // Invert the weight-scaling that was done initially + storea(ixl * rscalev + low_boundv, weight_set_out + i); + vint scn = pack_low_bytes(weight); + store_nbytes(scn, quantized_weight_set + i); + } + } + else + { + vint4 tab0(reinterpret_cast<const int*>(qat.quant_to_unquant)); + vint4 tab1(reinterpret_cast<const int*>(qat.quant_to_unquant + 16)); + vint tab0p, tab1p; + vtable_prepare(tab0, tab1, tab0p, tab1p); + + for (int i = 0; i < weight_count; i += ASTCENC_SIMD_WIDTH) + { + vfloat ix = loada(dec_weight_ideal_value + i) * scalev - scaled_low_boundv; + ix = clampzo(ix); + + // Look up the two closest indexes and return the one that was closest + vfloat ix1 = ix * quant_level_m1v; + + vint weightl = float_to_int(ix1); + vint weighth = min(weightl + vint(1), steps_m1); + + vint ixli = vtable_8bt_32bi(tab0p, tab1p, weightl); + vint ixhi = vtable_8bt_32bi(tab0p, tab1p, weighth); + + vfloat ixl = int_to_float(ixli); + vfloat ixh = int_to_float(ixhi); + + vmask mask = (ixl + ixh) < (vfloat(128.0f) * ix); + vint weight = select(ixli, ixhi, mask); + ixl = select(ixl, ixh, mask); + + // Invert the weight-scaling that was done initially + storea(ixl * rscalev + low_boundv, weight_set_out + i); + vint scn = pack_low_bytes(weight); + store_nbytes(scn, quantized_weight_set + i); + } + } +} + +/** + * @brief Compute the RGB + offset for a HDR endpoint mode #7. + * + * Since the matrix needed has a regular structure we can simplify the inverse calculation. This + * gives us ~24 multiplications vs. 96 for a generic inverse. + * + * mat[0] = vfloat4(rgba_ws.x, 0.0f, 0.0f, wght_ws.x); + * mat[1] = vfloat4( 0.0f, rgba_ws.y, 0.0f, wght_ws.y); + * mat[2] = vfloat4( 0.0f, 0.0f, rgba_ws.z, wght_ws.z); + * mat[3] = vfloat4(wght_ws.x, wght_ws.y, wght_ws.z, psum); + * mat = invert(mat); + * + * @param rgba_weight_sum Sum of partition component error weights. + * @param weight_weight_sum Sum of partition component error weights * texel weight. + * @param rgbq_sum Sum of partition component error weights * texel weight * color data. + * @param psum Sum of RGB color weights * texel weight^2. + */ +static inline vfloat4 compute_rgbo_vector( + vfloat4 rgba_weight_sum, + vfloat4 weight_weight_sum, + vfloat4 rgbq_sum, + float psum +) { + float X = rgba_weight_sum.lane<0>(); + float Y = rgba_weight_sum.lane<1>(); + float Z = rgba_weight_sum.lane<2>(); + float P = weight_weight_sum.lane<0>(); + float Q = weight_weight_sum.lane<1>(); + float R = weight_weight_sum.lane<2>(); + float S = psum; + + float PP = P * P; + float QQ = Q * Q; + float RR = R * R; + + float SZmRR = S * Z - RR; + float DT = SZmRR * Y - Z * QQ; + float YP = Y * P; + float QX = Q * X; + float YX = Y * X; + float mZYP = -Z * YP; + float mZQX = -Z * QX; + float mRYX = -R * YX; + float ZQP = Z * Q * P; + float RYP = R * YP; + float RQX = R * QX; + + // Compute the reciprocal of matrix determinant + float rdet = 1.0f / (DT * X + mZYP * P); + + // Actually compute the adjugate, and then apply 1/det separately + vfloat4 mat0(DT, ZQP, RYP, mZYP); + vfloat4 mat1(ZQP, SZmRR * X - Z * PP, RQX, mZQX); + vfloat4 mat2(RYP, RQX, (S * Y - QQ) * X - Y * PP, mRYX); + vfloat4 mat3(mZYP, mZQX, mRYX, Z * YX); + vfloat4 vect = rgbq_sum * rdet; + + return vfloat4(dot_s(mat0, vect), + dot_s(mat1, vect), + dot_s(mat2, vect), + dot_s(mat3, vect)); +} + +/* See header for documentation. */ +void recompute_ideal_colors_1plane( + const image_block& blk, + const partition_info& pi, + const decimation_info& di, + const uint8_t* dec_weights_uquant, + endpoints& ep, + vfloat4 rgbs_vectors[BLOCK_MAX_PARTITIONS], + vfloat4 rgbo_vectors[BLOCK_MAX_PARTITIONS] +) { + unsigned int weight_count = di.weight_count; + unsigned int total_texel_count = blk.texel_count; + unsigned int partition_count = pi.partition_count; + + promise(weight_count > 0); + promise(total_texel_count > 0); + promise(partition_count > 0); + + alignas(ASTCENC_VECALIGN) float dec_weight[BLOCK_MAX_WEIGHTS]; + for (unsigned int i = 0; i < weight_count; i += ASTCENC_SIMD_WIDTH) + { + vint unquant_value(dec_weights_uquant + i); + vfloat unquant_valuef = int_to_float(unquant_value) * vfloat(1.0f / 64.0f); + storea(unquant_valuef, dec_weight + i); + } + + alignas(ASTCENC_VECALIGN) float undec_weight[BLOCK_MAX_TEXELS]; + float* undec_weight_ref; + if (di.max_texel_weight_count == 1) + { + undec_weight_ref = dec_weight; + } + else if (di.max_texel_weight_count <= 2) + { + for (unsigned int i = 0; i < total_texel_count; i += ASTCENC_SIMD_WIDTH) + { + vfloat weight = bilinear_infill_vla_2(di, dec_weight, i); + storea(weight, undec_weight + i); + } + + undec_weight_ref = undec_weight; + } + else + { + for (unsigned int i = 0; i < total_texel_count; i += ASTCENC_SIMD_WIDTH) + { + vfloat weight = bilinear_infill_vla(di, dec_weight, i); + storea(weight, undec_weight + i); + } + + undec_weight_ref = undec_weight; + } + + vfloat4 rgba_sum(blk.data_mean * static_cast<float>(blk.texel_count)); + + for (unsigned int i = 0; i < partition_count; i++) + { + unsigned int texel_count = pi.partition_texel_count[i]; + const uint8_t *texel_indexes = pi.texels_of_partition[i]; + + // Only compute a partition mean if more than one partition + if (partition_count > 1) + { + rgba_sum = vfloat4::zero(); + promise(texel_count > 0); + for (unsigned int j = 0; j < texel_count; j++) + { + unsigned int tix = texel_indexes[j]; + rgba_sum += blk.texel(tix); + } + } + + rgba_sum = rgba_sum * blk.channel_weight; + vfloat4 rgba_weight_sum = max(blk.channel_weight * static_cast<float>(texel_count), 1e-17f); + vfloat4 scale_dir = normalize((rgba_sum / rgba_weight_sum).swz<0, 1, 2>()); + + float scale_max = 0.0f; + float scale_min = 1e10f; + + float wmin1 = 1.0f; + float wmax1 = 0.0f; + + float left_sum_s = 0.0f; + float middle_sum_s = 0.0f; + float right_sum_s = 0.0f; + + vfloat4 color_vec_x = vfloat4::zero(); + vfloat4 color_vec_y = vfloat4::zero(); + + vfloat4 scale_vec = vfloat4::zero(); + + float weight_weight_sum_s = 1e-17f; + + vfloat4 color_weight = blk.channel_weight; + float ls_weight = hadd_rgb_s(color_weight); + + for (unsigned int j = 0; j < texel_count; j++) + { + unsigned int tix = texel_indexes[j]; + vfloat4 rgba = blk.texel(tix); + + float idx0 = undec_weight_ref[tix]; + + float om_idx0 = 1.0f - idx0; + wmin1 = astc::min(idx0, wmin1); + wmax1 = astc::max(idx0, wmax1); + + float scale = dot3_s(scale_dir, rgba); + scale_min = astc::min(scale, scale_min); + scale_max = astc::max(scale, scale_max); + + left_sum_s += om_idx0 * om_idx0; + middle_sum_s += om_idx0 * idx0; + right_sum_s += idx0 * idx0; + weight_weight_sum_s += idx0; + + vfloat4 color_idx(idx0); + vfloat4 cwprod = rgba; + vfloat4 cwiprod = cwprod * color_idx; + + color_vec_y += cwiprod; + color_vec_x += cwprod - cwiprod; + + scale_vec += vfloat2(om_idx0, idx0) * (scale * ls_weight); + } + + vfloat4 left_sum = vfloat4(left_sum_s) * color_weight; + vfloat4 middle_sum = vfloat4(middle_sum_s) * color_weight; + vfloat4 right_sum = vfloat4(right_sum_s) * color_weight; + vfloat4 lmrs_sum = vfloat3(left_sum_s, middle_sum_s, right_sum_s) * ls_weight; + + color_vec_x = color_vec_x * color_weight; + color_vec_y = color_vec_y * color_weight; + + // Initialize the luminance and scale vectors with a reasonable default + float scalediv = scale_min / astc::max(scale_max, 1e-10f); + scalediv = astc::clamp1f(scalediv); + + vfloat4 sds = scale_dir * scale_max; + + rgbs_vectors[i] = vfloat4(sds.lane<0>(), sds.lane<1>(), sds.lane<2>(), scalediv); + + if (wmin1 >= wmax1 * 0.999f) + { + // If all weights in the partition were equal, then just take average of all colors in + // the partition and use that as both endpoint colors + vfloat4 avg = (color_vec_x + color_vec_y) / rgba_weight_sum; + + vmask4 notnan_mask = avg == avg; + ep.endpt0[i] = select(ep.endpt0[i], avg, notnan_mask); + ep.endpt1[i] = select(ep.endpt1[i], avg, notnan_mask); + + rgbs_vectors[i] = vfloat4(sds.lane<0>(), sds.lane<1>(), sds.lane<2>(), 1.0f); + } + else + { + // Otherwise, complete the analytic calculation of ideal-endpoint-values for the given + // set of texel weights and pixel colors + vfloat4 color_det1 = (left_sum * right_sum) - (middle_sum * middle_sum); + vfloat4 color_rdet1 = 1.0f / color_det1; + + float ls_det1 = (lmrs_sum.lane<0>() * lmrs_sum.lane<2>()) - (lmrs_sum.lane<1>() * lmrs_sum.lane<1>()); + float ls_rdet1 = 1.0f / ls_det1; + + vfloat4 color_mss1 = (left_sum * left_sum) + + (2.0f * middle_sum * middle_sum) + + (right_sum * right_sum); + + float ls_mss1 = (lmrs_sum.lane<0>() * lmrs_sum.lane<0>()) + + (2.0f * lmrs_sum.lane<1>() * lmrs_sum.lane<1>()) + + (lmrs_sum.lane<2>() * lmrs_sum.lane<2>()); + + vfloat4 ep0 = (right_sum * color_vec_x - middle_sum * color_vec_y) * color_rdet1; + vfloat4 ep1 = (left_sum * color_vec_y - middle_sum * color_vec_x) * color_rdet1; + + vmask4 det_mask = abs(color_det1) > (color_mss1 * 1e-4f); + vmask4 notnan_mask = (ep0 == ep0) & (ep1 == ep1); + vmask4 full_mask = det_mask & notnan_mask; + + ep.endpt0[i] = select(ep.endpt0[i], ep0, full_mask); + ep.endpt1[i] = select(ep.endpt1[i], ep1, full_mask); + + float scale_ep0 = (lmrs_sum.lane<2>() * scale_vec.lane<0>() - lmrs_sum.lane<1>() * scale_vec.lane<1>()) * ls_rdet1; + float scale_ep1 = (lmrs_sum.lane<0>() * scale_vec.lane<1>() - lmrs_sum.lane<1>() * scale_vec.lane<0>()) * ls_rdet1; + + if (fabsf(ls_det1) > (ls_mss1 * 1e-4f) && scale_ep0 == scale_ep0 && scale_ep1 == scale_ep1 && scale_ep0 < scale_ep1) + { + float scalediv2 = scale_ep0 / scale_ep1; + vfloat4 sdsm = scale_dir * scale_ep1; + rgbs_vectors[i] = vfloat4(sdsm.lane<0>(), sdsm.lane<1>(), sdsm.lane<2>(), scalediv2); + } + } + + // Calculations specific to mode #7, the HDR RGB-scale mode - skip if known LDR + if (blk.rgb_lns[0] || blk.alpha_lns[0]) + { + vfloat4 weight_weight_sum = vfloat4(weight_weight_sum_s) * color_weight; + float psum = right_sum_s * hadd_rgb_s(color_weight); + + vfloat4 rgbq_sum = color_vec_x + color_vec_y; + rgbq_sum.set_lane<3>(hadd_rgb_s(color_vec_y)); + + vfloat4 rgbovec = compute_rgbo_vector(rgba_weight_sum, weight_weight_sum, rgbq_sum, psum); + rgbo_vectors[i] = rgbovec; + + // We can get a failure due to the use of a singular (non-invertible) matrix + // If it failed, compute rgbo_vectors[] with a different method ... + if (astc::isnan(dot_s(rgbovec, rgbovec))) + { + vfloat4 v0 = ep.endpt0[i]; + vfloat4 v1 = ep.endpt1[i]; + + float avgdif = hadd_rgb_s(v1 - v0) * (1.0f / 3.0f); + avgdif = astc::max(avgdif, 0.0f); + + vfloat4 avg = (v0 + v1) * 0.5f; + vfloat4 ep0 = avg - vfloat4(avgdif) * 0.5f; + rgbo_vectors[i] = vfloat4(ep0.lane<0>(), ep0.lane<1>(), ep0.lane<2>(), avgdif); + } + } + } +} + +/* See header for documentation. */ +void recompute_ideal_colors_2planes( + const image_block& blk, + const block_size_descriptor& bsd, + const decimation_info& di, + const uint8_t* dec_weights_uquant_plane1, + const uint8_t* dec_weights_uquant_plane2, + endpoints& ep, + vfloat4& rgbs_vector, + vfloat4& rgbo_vector, + int plane2_component +) { + unsigned int weight_count = di.weight_count; + unsigned int total_texel_count = blk.texel_count; + + promise(total_texel_count > 0); + promise(weight_count > 0); + + alignas(ASTCENC_VECALIGN) float dec_weight_plane1[BLOCK_MAX_WEIGHTS_2PLANE]; + alignas(ASTCENC_VECALIGN) float dec_weight_plane2[BLOCK_MAX_WEIGHTS_2PLANE]; + + assert(weight_count <= BLOCK_MAX_WEIGHTS_2PLANE); + + for (unsigned int i = 0; i < weight_count; i += ASTCENC_SIMD_WIDTH) + { + vint unquant_value1(dec_weights_uquant_plane1 + i); + vfloat unquant_value1f = int_to_float(unquant_value1) * vfloat(1.0f / 64.0f); + storea(unquant_value1f, dec_weight_plane1 + i); + + vint unquant_value2(dec_weights_uquant_plane2 + i); + vfloat unquant_value2f = int_to_float(unquant_value2) * vfloat(1.0f / 64.0f); + storea(unquant_value2f, dec_weight_plane2 + i); + } + + alignas(ASTCENC_VECALIGN) float undec_weight_plane1[BLOCK_MAX_TEXELS]; + alignas(ASTCENC_VECALIGN) float undec_weight_plane2[BLOCK_MAX_TEXELS]; + + float* undec_weight_plane1_ref; + float* undec_weight_plane2_ref; + + if (di.max_texel_weight_count == 1) + { + undec_weight_plane1_ref = dec_weight_plane1; + undec_weight_plane2_ref = dec_weight_plane2; + } + else if (di.max_texel_weight_count <= 2) + { + for (unsigned int i = 0; i < total_texel_count; i += ASTCENC_SIMD_WIDTH) + { + vfloat weight = bilinear_infill_vla_2(di, dec_weight_plane1, i); + storea(weight, undec_weight_plane1 + i); + + weight = bilinear_infill_vla_2(di, dec_weight_plane2, i); + storea(weight, undec_weight_plane2 + i); + } + + undec_weight_plane1_ref = undec_weight_plane1; + undec_weight_plane2_ref = undec_weight_plane2; + } + else + { + for (unsigned int i = 0; i < total_texel_count; i += ASTCENC_SIMD_WIDTH) + { + vfloat weight = bilinear_infill_vla(di, dec_weight_plane1, i); + storea(weight, undec_weight_plane1 + i); + + weight = bilinear_infill_vla(di, dec_weight_plane2, i); + storea(weight, undec_weight_plane2 + i); + } + + undec_weight_plane1_ref = undec_weight_plane1; + undec_weight_plane2_ref = undec_weight_plane2; + } + + unsigned int texel_count = bsd.texel_count; + vfloat4 rgba_weight_sum = max(blk.channel_weight * static_cast<float>(texel_count), 1e-17f); + vfloat4 scale_dir = normalize(blk.data_mean.swz<0, 1, 2>()); + + float scale_max = 0.0f; + float scale_min = 1e10f; + + float wmin1 = 1.0f; + float wmax1 = 0.0f; + + float wmin2 = 1.0f; + float wmax2 = 0.0f; + + float left1_sum_s = 0.0f; + float middle1_sum_s = 0.0f; + float right1_sum_s = 0.0f; + + float left2_sum_s = 0.0f; + float middle2_sum_s = 0.0f; + float right2_sum_s = 0.0f; + + vfloat4 color_vec_x = vfloat4::zero(); + vfloat4 color_vec_y = vfloat4::zero(); + + vfloat4 scale_vec = vfloat4::zero(); + + vfloat4 weight_weight_sum = vfloat4(1e-17f); + + vmask4 p2_mask = vint4::lane_id() == vint4(plane2_component); + vfloat4 color_weight = blk.channel_weight; + float ls_weight = hadd_rgb_s(color_weight); + + for (unsigned int j = 0; j < texel_count; j++) + { + vfloat4 rgba = blk.texel(j); + + float idx0 = undec_weight_plane1_ref[j]; + + float om_idx0 = 1.0f - idx0; + wmin1 = astc::min(idx0, wmin1); + wmax1 = astc::max(idx0, wmax1); + + float scale = dot3_s(scale_dir, rgba); + scale_min = astc::min(scale, scale_min); + scale_max = astc::max(scale, scale_max); + + left1_sum_s += om_idx0 * om_idx0; + middle1_sum_s += om_idx0 * idx0; + right1_sum_s += idx0 * idx0; + + float idx1 = undec_weight_plane2_ref[j]; + + float om_idx1 = 1.0f - idx1; + wmin2 = astc::min(idx1, wmin2); + wmax2 = astc::max(idx1, wmax2); + + left2_sum_s += om_idx1 * om_idx1; + middle2_sum_s += om_idx1 * idx1; + right2_sum_s += idx1 * idx1; + + vfloat4 color_idx = select(vfloat4(idx0), vfloat4(idx1), p2_mask); + + vfloat4 cwprod = rgba; + vfloat4 cwiprod = cwprod * color_idx; + + color_vec_y += cwiprod; + color_vec_x += cwprod - cwiprod; + + scale_vec += vfloat2(om_idx0, idx0) * (ls_weight * scale); + weight_weight_sum += color_idx; + } + + vfloat4 left1_sum = vfloat4(left1_sum_s) * color_weight; + vfloat4 middle1_sum = vfloat4(middle1_sum_s) * color_weight; + vfloat4 right1_sum = vfloat4(right1_sum_s) * color_weight; + vfloat4 lmrs_sum = vfloat3(left1_sum_s, middle1_sum_s, right1_sum_s) * ls_weight; + + vfloat4 left2_sum = vfloat4(left2_sum_s) * color_weight; + vfloat4 middle2_sum = vfloat4(middle2_sum_s) * color_weight; + vfloat4 right2_sum = vfloat4(right2_sum_s) * color_weight; + + color_vec_x = color_vec_x * color_weight; + color_vec_y = color_vec_y * color_weight; + + // Initialize the luminance and scale vectors with a reasonable default + float scalediv = scale_min / astc::max(scale_max, 1e-10f); + scalediv = astc::clamp1f(scalediv); + + vfloat4 sds = scale_dir * scale_max; + + rgbs_vector = vfloat4(sds.lane<0>(), sds.lane<1>(), sds.lane<2>(), scalediv); + + if (wmin1 >= wmax1 * 0.999f) + { + // If all weights in the partition were equal, then just take average of all colors in + // the partition and use that as both endpoint colors + vfloat4 avg = (color_vec_x + color_vec_y) / rgba_weight_sum; + + vmask4 p1_mask = vint4::lane_id() != vint4(plane2_component); + vmask4 notnan_mask = avg == avg; + vmask4 full_mask = p1_mask & notnan_mask; + + ep.endpt0[0] = select(ep.endpt0[0], avg, full_mask); + ep.endpt1[0] = select(ep.endpt1[0], avg, full_mask); + + rgbs_vector = vfloat4(sds.lane<0>(), sds.lane<1>(), sds.lane<2>(), 1.0f); + } + else + { + // Otherwise, complete the analytic calculation of ideal-endpoint-values for the given + // set of texel weights and pixel colors + vfloat4 color_det1 = (left1_sum * right1_sum) - (middle1_sum * middle1_sum); + vfloat4 color_rdet1 = 1.0f / color_det1; + + float ls_det1 = (lmrs_sum.lane<0>() * lmrs_sum.lane<2>()) - (lmrs_sum.lane<1>() * lmrs_sum.lane<1>()); + float ls_rdet1 = 1.0f / ls_det1; + + vfloat4 color_mss1 = (left1_sum * left1_sum) + + (2.0f * middle1_sum * middle1_sum) + + (right1_sum * right1_sum); + + float ls_mss1 = (lmrs_sum.lane<0>() * lmrs_sum.lane<0>()) + + (2.0f * lmrs_sum.lane<1>() * lmrs_sum.lane<1>()) + + (lmrs_sum.lane<2>() * lmrs_sum.lane<2>()); + + vfloat4 ep0 = (right1_sum * color_vec_x - middle1_sum * color_vec_y) * color_rdet1; + vfloat4 ep1 = (left1_sum * color_vec_y - middle1_sum * color_vec_x) * color_rdet1; + + float scale_ep0 = (lmrs_sum.lane<2>() * scale_vec.lane<0>() - lmrs_sum.lane<1>() * scale_vec.lane<1>()) * ls_rdet1; + float scale_ep1 = (lmrs_sum.lane<0>() * scale_vec.lane<1>() - lmrs_sum.lane<1>() * scale_vec.lane<0>()) * ls_rdet1; + + vmask4 p1_mask = vint4::lane_id() != vint4(plane2_component); + vmask4 det_mask = abs(color_det1) > (color_mss1 * 1e-4f); + vmask4 notnan_mask = (ep0 == ep0) & (ep1 == ep1); + vmask4 full_mask = p1_mask & det_mask & notnan_mask; + + ep.endpt0[0] = select(ep.endpt0[0], ep0, full_mask); + ep.endpt1[0] = select(ep.endpt1[0], ep1, full_mask); + + if (fabsf(ls_det1) > (ls_mss1 * 1e-4f) && scale_ep0 == scale_ep0 && scale_ep1 == scale_ep1 && scale_ep0 < scale_ep1) + { + float scalediv2 = scale_ep0 / scale_ep1; + vfloat4 sdsm = scale_dir * scale_ep1; + rgbs_vector = vfloat4(sdsm.lane<0>(), sdsm.lane<1>(), sdsm.lane<2>(), scalediv2); + } + } + + if (wmin2 >= wmax2 * 0.999f) + { + // If all weights in the partition were equal, then just take average of all colors in + // the partition and use that as both endpoint colors + vfloat4 avg = (color_vec_x + color_vec_y) / rgba_weight_sum; + + vmask4 notnan_mask = avg == avg; + vmask4 full_mask = p2_mask & notnan_mask; + + ep.endpt0[0] = select(ep.endpt0[0], avg, full_mask); + ep.endpt1[0] = select(ep.endpt1[0], avg, full_mask); + } + else + { + // Otherwise, complete the analytic calculation of ideal-endpoint-values for the given + // set of texel weights and pixel colors + vfloat4 color_det2 = (left2_sum * right2_sum) - (middle2_sum * middle2_sum); + vfloat4 color_rdet2 = 1.0f / color_det2; + + vfloat4 color_mss2 = (left2_sum * left2_sum) + + (2.0f * middle2_sum * middle2_sum) + + (right2_sum * right2_sum); + + vfloat4 ep0 = (right2_sum * color_vec_x - middle2_sum * color_vec_y) * color_rdet2; + vfloat4 ep1 = (left2_sum * color_vec_y - middle2_sum * color_vec_x) * color_rdet2; + + vmask4 det_mask = abs(color_det2) > (color_mss2 * 1e-4f); + vmask4 notnan_mask = (ep0 == ep0) & (ep1 == ep1); + vmask4 full_mask = p2_mask & det_mask & notnan_mask; + + ep.endpt0[0] = select(ep.endpt0[0], ep0, full_mask); + ep.endpt1[0] = select(ep.endpt1[0], ep1, full_mask); + } + + // Calculations specific to mode #7, the HDR RGB-scale mode - skip if known LDR + if (blk.rgb_lns[0] || blk.alpha_lns[0]) + { + weight_weight_sum = weight_weight_sum * color_weight; + float psum = dot3_s(select(right1_sum, right2_sum, p2_mask), color_weight); + + vfloat4 rgbq_sum = color_vec_x + color_vec_y; + rgbq_sum.set_lane<3>(hadd_rgb_s(color_vec_y)); + + rgbo_vector = compute_rgbo_vector(rgba_weight_sum, weight_weight_sum, rgbq_sum, psum); + + // We can get a failure due to the use of a singular (non-invertible) matrix + // If it failed, compute rgbo_vectors[] with a different method ... + if (astc::isnan(dot_s(rgbo_vector, rgbo_vector))) + { + vfloat4 v0 = ep.endpt0[0]; + vfloat4 v1 = ep.endpt1[0]; + + float avgdif = hadd_rgb_s(v1 - v0) * (1.0f / 3.0f); + avgdif = astc::max(avgdif, 0.0f); + + vfloat4 avg = (v0 + v1) * 0.5f; + vfloat4 ep0 = avg - vfloat4(avgdif) * 0.5f; + + rgbo_vector = vfloat4(ep0.lane<0>(), ep0.lane<1>(), ep0.lane<2>(), avgdif); + } + } +} + +#endif diff --git a/thirdparty/astcenc/astcenc_image.cpp b/thirdparty/astcenc/astcenc_image.cpp new file mode 100644 index 0000000000..9c0d6727d0 --- /dev/null +++ b/thirdparty/astcenc/astcenc_image.cpp @@ -0,0 +1,558 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2022 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief Functions for creating in-memory ASTC image structures. + */ + +#include <cassert> +#include <cstring> + +#include "astcenc_internal.h" + +/** + * @brief Loader pipeline function type for data fetch from memory. + */ +using pixel_loader = vfloat4(*)(const void*, int); + +/** + * @brief Loader pipeline function type for swizzling data in a vector. + */ +using pixel_swizzler = vfloat4(*)(vfloat4, const astcenc_swizzle&); + +/** + * @brief Loader pipeline function type for converting data in a vector to LNS. + */ +using pixel_converter = vfloat4(*)(vfloat4, vmask4); + +/** + * @brief Load a 8-bit UNORM texel from a data array. + * + * @param data The data pointer. + * @param base_offset The index offset to the start of the pixel. + */ +static vfloat4 load_texel_u8( + const void* data, + int base_offset +) { + const uint8_t* data8 = static_cast<const uint8_t*>(data); + return int_to_float(vint4(data8 + base_offset)) / 255.0f; +} + +/** + * @brief Load a 16-bit fp16 texel from a data array. + * + * @param data The data pointer. + * @param base_offset The index offset to the start of the pixel. + */ +static vfloat4 load_texel_f16( + const void* data, + int base_offset +) { + const uint16_t* data16 = static_cast<const uint16_t*>(data); + int r = data16[base_offset ]; + int g = data16[base_offset + 1]; + int b = data16[base_offset + 2]; + int a = data16[base_offset + 3]; + return float16_to_float(vint4(r, g, b, a)); +} + +/** + * @brief Load a 32-bit float texel from a data array. + * + * @param data The data pointer. + * @param base_offset The index offset to the start of the pixel. + */ +static vfloat4 load_texel_f32( + const void* data, + int base_offset +) { + const float* data32 = static_cast<const float*>(data); + return vfloat4(data32 + base_offset); +} + +/** + * @brief Dummy no-op swizzle function. + * + * @param data The source RGBA vector to swizzle. + * @param swz The swizzle to use. + */ +static vfloat4 swz_texel_skip( + vfloat4 data, + const astcenc_swizzle& swz +) { + (void)swz; + return data; +} + +/** + * @brief Swizzle a texel into a new arrangement. + * + * @param data The source RGBA vector to swizzle. + * @param swz The swizzle to use. + */ +static vfloat4 swz_texel( + vfloat4 data, + const astcenc_swizzle& swz +) { + alignas(16) float datas[6]; + + storea(data, datas); + datas[ASTCENC_SWZ_0] = 0.0f; + datas[ASTCENC_SWZ_1] = 1.0f; + + return vfloat4(datas[swz.r], datas[swz.g], datas[swz.b], datas[swz.a]); +} + +/** + * @brief Encode a texel that is entirely LDR linear. + * + * @param data The RGBA data to encode. + * @param lns_mask The mask for the HDR channels than need LNS encoding. + */ +static vfloat4 encode_texel_unorm( + vfloat4 data, + vmask4 lns_mask +) { + (void)lns_mask; + return data * 65535.0f; +} + +/** + * @brief Encode a texel that includes at least some HDR LNS texels. + * + * @param data The RGBA data to encode. + * @param lns_mask The mask for the HDR channels than need LNS encoding. + */ +static vfloat4 encode_texel_lns( + vfloat4 data, + vmask4 lns_mask +) { + vfloat4 datav_unorm = data * 65535.0f; + vfloat4 datav_lns = float_to_lns(data); + return select(datav_unorm, datav_lns, lns_mask); +} + +/* See header for documentation. */ +void load_image_block( + astcenc_profile decode_mode, + const astcenc_image& img, + image_block& blk, + const block_size_descriptor& bsd, + unsigned int xpos, + unsigned int ypos, + unsigned int zpos, + const astcenc_swizzle& swz +) { + unsigned int xsize = img.dim_x; + unsigned int ysize = img.dim_y; + unsigned int zsize = img.dim_z; + + blk.xpos = xpos; + blk.ypos = ypos; + blk.zpos = zpos; + + // True if any non-identity swizzle + bool needs_swz = (swz.r != ASTCENC_SWZ_R) || (swz.g != ASTCENC_SWZ_G) || + (swz.b != ASTCENC_SWZ_B) || (swz.a != ASTCENC_SWZ_A); + + int idx = 0; + + vfloat4 data_min(1e38f); + vfloat4 data_mean(0.0f); + vfloat4 data_mean_scale(1.0f / static_cast<float>(bsd.texel_count)); + vfloat4 data_max(-1e38f); + vmask4 grayscalev(true); + + // This works because we impose the same choice everywhere during encode + uint8_t rgb_lns = (decode_mode == ASTCENC_PRF_HDR) || + (decode_mode == ASTCENC_PRF_HDR_RGB_LDR_A) ? 1 : 0; + uint8_t a_lns = decode_mode == ASTCENC_PRF_HDR ? 1 : 0; + vint4 use_lns(rgb_lns, rgb_lns, rgb_lns, a_lns); + vmask4 lns_mask = use_lns != vint4::zero(); + + // Set up the function pointers for loading pipeline as needed + pixel_loader loader = load_texel_u8; + if (img.data_type == ASTCENC_TYPE_F16) + { + loader = load_texel_f16; + } + else if (img.data_type == ASTCENC_TYPE_F32) + { + loader = load_texel_f32; + } + + pixel_swizzler swizzler = swz_texel_skip; + if (needs_swz) + { + swizzler = swz_texel; + } + + pixel_converter converter = encode_texel_unorm; + if (any(lns_mask)) + { + converter = encode_texel_lns; + } + + for (unsigned int z = 0; z < bsd.zdim; z++) + { + unsigned int zi = astc::min(zpos + z, zsize - 1); + void* plane = img.data[zi]; + + for (unsigned int y = 0; y < bsd.ydim; y++) + { + unsigned int yi = astc::min(ypos + y, ysize - 1); + + for (unsigned int x = 0; x < bsd.xdim; x++) + { + unsigned int xi = astc::min(xpos + x, xsize - 1); + + vfloat4 datav = loader(plane, (4 * xsize * yi) + (4 * xi)); + datav = swizzler(datav, swz); + datav = converter(datav, lns_mask); + + // Compute block metadata + data_min = min(data_min, datav); + data_mean += datav * data_mean_scale; + data_max = max(data_max, datav); + + grayscalev = grayscalev & (datav.swz<0,0,0,0>() == datav.swz<1,1,2,2>()); + + blk.data_r[idx] = datav.lane<0>(); + blk.data_g[idx] = datav.lane<1>(); + blk.data_b[idx] = datav.lane<2>(); + blk.data_a[idx] = datav.lane<3>(); + + blk.rgb_lns[idx] = rgb_lns; + blk.alpha_lns[idx] = a_lns; + + idx++; + } + } + } + + // Reverse the encoding so we store origin block in the original format + vfloat4 data_enc = blk.texel(0); + vfloat4 data_enc_unorm = data_enc / 65535.0f; + vfloat4 data_enc_lns = vfloat4::zero(); + + if (rgb_lns || a_lns) + { + data_enc_lns = float16_to_float(lns_to_sf16(float_to_int(data_enc))); + } + + blk.origin_texel = select(data_enc_unorm, data_enc_lns, lns_mask); + + // Store block metadata + blk.data_min = data_min; + blk.data_mean = data_mean; + blk.data_max = data_max; + blk.grayscale = all(grayscalev); +} + +/* See header for documentation. */ +void load_image_block_fast_ldr( + astcenc_profile decode_mode, + const astcenc_image& img, + image_block& blk, + const block_size_descriptor& bsd, + unsigned int xpos, + unsigned int ypos, + unsigned int zpos, + const astcenc_swizzle& swz +) { + (void)swz; + (void)decode_mode; + + unsigned int xsize = img.dim_x; + unsigned int ysize = img.dim_y; + + blk.xpos = xpos; + blk.ypos = ypos; + blk.zpos = zpos; + + vfloat4 data_min(1e38f); + vfloat4 data_mean = vfloat4::zero(); + vfloat4 data_max(-1e38f); + vmask4 grayscalev(true); + int idx = 0; + + const uint8_t* plane = static_cast<const uint8_t*>(img.data[0]); + for (unsigned int y = ypos; y < ypos + bsd.ydim; y++) + { + unsigned int yi = astc::min(y, ysize - 1); + + for (unsigned int x = xpos; x < xpos + bsd.xdim; x++) + { + unsigned int xi = astc::min(x, xsize - 1); + + vint4 datavi = vint4(plane + (4 * xsize * yi) + (4 * xi)); + vfloat4 datav = int_to_float(datavi) * (65535.0f / 255.0f); + + // Compute block metadata + data_min = min(data_min, datav); + data_mean += datav; + data_max = max(data_max, datav); + + grayscalev = grayscalev & (datav.swz<0,0,0,0>() == datav.swz<1,1,2,2>()); + + blk.data_r[idx] = datav.lane<0>(); + blk.data_g[idx] = datav.lane<1>(); + blk.data_b[idx] = datav.lane<2>(); + blk.data_a[idx] = datav.lane<3>(); + + idx++; + } + } + + // Reverse the encoding so we store origin block in the original format + blk.origin_texel = blk.texel(0) / 65535.0f; + + // Store block metadata + blk.rgb_lns[0] = 0; + blk.alpha_lns[0] = 0; + blk.data_min = data_min; + blk.data_mean = data_mean / static_cast<float>(bsd.texel_count); + blk.data_max = data_max; + blk.grayscale = all(grayscalev); +} + +/* See header for documentation. */ +void store_image_block( + astcenc_image& img, + const image_block& blk, + const block_size_descriptor& bsd, + unsigned int xpos, + unsigned int ypos, + unsigned int zpos, + const astcenc_swizzle& swz +) { + unsigned int x_size = img.dim_x; + unsigned int x_start = xpos; + unsigned int x_end = astc::min(x_size, xpos + bsd.xdim); + unsigned int x_count = x_end - x_start; + unsigned int x_nudge = bsd.xdim - x_count; + + unsigned int y_size = img.dim_y; + unsigned int y_start = ypos; + unsigned int y_end = astc::min(y_size, ypos + bsd.ydim); + unsigned int y_count = y_end - y_start; + unsigned int y_nudge = (bsd.ydim - y_count) * bsd.xdim; + + unsigned int z_size = img.dim_z; + unsigned int z_start = zpos; + unsigned int z_end = astc::min(z_size, zpos + bsd.zdim); + + // True if any non-identity swizzle + bool needs_swz = (swz.r != ASTCENC_SWZ_R) || (swz.g != ASTCENC_SWZ_G) || + (swz.b != ASTCENC_SWZ_B) || (swz.a != ASTCENC_SWZ_A); + + // True if any swizzle uses Z reconstruct + bool needs_z = (swz.r == ASTCENC_SWZ_Z) || (swz.g == ASTCENC_SWZ_Z) || + (swz.b == ASTCENC_SWZ_Z) || (swz.a == ASTCENC_SWZ_Z); + + int idx = 0; + if (img.data_type == ASTCENC_TYPE_U8) + { + for (unsigned int z = z_start; z < z_end; z++) + { + // Fetch the image plane + uint8_t* data8 = static_cast<uint8_t*>(img.data[z]); + + for (unsigned int y = y_start; y < y_end; y++) + { + uint8_t* data8_row = data8 + (4 * x_size * y) + (4 * x_start); + + for (unsigned int x = 0; x < x_count; x += ASTCENC_SIMD_WIDTH) + { + unsigned int max_texels = ASTCENC_SIMD_WIDTH; + unsigned int used_texels = astc::min(x_count - x, max_texels); + + // Unaligned load as rows are not always SIMD_WIDTH long + vfloat data_r(blk.data_r + idx); + vfloat data_g(blk.data_g + idx); + vfloat data_b(blk.data_b + idx); + vfloat data_a(blk.data_a + idx); + + vint data_ri = float_to_int_rtn(min(data_r, 1.0f) * 255.0f); + vint data_gi = float_to_int_rtn(min(data_g, 1.0f) * 255.0f); + vint data_bi = float_to_int_rtn(min(data_b, 1.0f) * 255.0f); + vint data_ai = float_to_int_rtn(min(data_a, 1.0f) * 255.0f); + + if (needs_swz) + { + vint swizzle_table[7]; + swizzle_table[ASTCENC_SWZ_0] = vint(0); + swizzle_table[ASTCENC_SWZ_1] = vint(255); + swizzle_table[ASTCENC_SWZ_R] = data_ri; + swizzle_table[ASTCENC_SWZ_G] = data_gi; + swizzle_table[ASTCENC_SWZ_B] = data_bi; + swizzle_table[ASTCENC_SWZ_A] = data_ai; + + if (needs_z) + { + vfloat data_x = (data_r * vfloat(2.0f)) - vfloat(1.0f); + vfloat data_y = (data_a * vfloat(2.0f)) - vfloat(1.0f); + vfloat data_z = vfloat(1.0f) - (data_x * data_x) - (data_y * data_y); + data_z = max(data_z, 0.0f); + data_z = (sqrt(data_z) * vfloat(0.5f)) + vfloat(0.5f); + + swizzle_table[ASTCENC_SWZ_Z] = float_to_int_rtn(min(data_z, 1.0f) * 255.0f); + } + + data_ri = swizzle_table[swz.r]; + data_gi = swizzle_table[swz.g]; + data_bi = swizzle_table[swz.b]; + data_ai = swizzle_table[swz.a]; + } + + // Errors are NaN encoded - convert to magenta error color + // Branch is OK here - it is almost never true so predicts well + vmask nan_mask = data_r != data_r; + if (any(nan_mask)) + { + data_ri = select(data_ri, vint(0xFF), nan_mask); + data_gi = select(data_gi, vint(0x00), nan_mask); + data_bi = select(data_bi, vint(0xFF), nan_mask); + data_ai = select(data_ai, vint(0xFF), nan_mask); + } + + vint data_rgbai = interleave_rgba8(data_ri, data_gi, data_bi, data_ai); + vmask store_mask = vint::lane_id() < vint(used_texels); + store_lanes_masked(reinterpret_cast<int*>(data8_row), data_rgbai, store_mask); + + data8_row += ASTCENC_SIMD_WIDTH * 4; + idx += used_texels; + } + idx += x_nudge; + } + idx += y_nudge; + } + } + else if (img.data_type == ASTCENC_TYPE_F16) + { + for (unsigned int z = z_start; z < z_end; z++) + { + // Fetch the image plane + uint16_t* data16 = static_cast<uint16_t*>(img.data[z]); + + for (unsigned int y = y_start; y < y_end; y++) + { + uint16_t* data16_row = data16 + (4 * x_size * y) + (4 * x_start); + + for (unsigned int x = 0; x < x_count; x++) + { + vint4 color; + + // NaNs are handled inline - no need to special case + if (needs_swz) + { + float data[7]; + data[ASTCENC_SWZ_0] = 0.0f; + data[ASTCENC_SWZ_1] = 1.0f; + data[ASTCENC_SWZ_R] = blk.data_r[idx]; + data[ASTCENC_SWZ_G] = blk.data_g[idx]; + data[ASTCENC_SWZ_B] = blk.data_b[idx]; + data[ASTCENC_SWZ_A] = blk.data_a[idx]; + + if (needs_z) + { + float xN = (data[0] * 2.0f) - 1.0f; + float yN = (data[3] * 2.0f) - 1.0f; + float zN = 1.0f - xN * xN - yN * yN; + if (zN < 0.0f) + { + zN = 0.0f; + } + data[ASTCENC_SWZ_Z] = (astc::sqrt(zN) * 0.5f) + 0.5f; + } + + vfloat4 colorf(data[swz.r], data[swz.g], data[swz.b], data[swz.a]); + color = float_to_float16(colorf); + } + else + { + vfloat4 colorf = blk.texel(idx); + color = float_to_float16(colorf); + } + + // TODO: Vectorize with store N shorts? + data16_row[0] = static_cast<uint16_t>(color.lane<0>()); + data16_row[1] = static_cast<uint16_t>(color.lane<1>()); + data16_row[2] = static_cast<uint16_t>(color.lane<2>()); + data16_row[3] = static_cast<uint16_t>(color.lane<3>()); + data16_row += 4; + idx++; + } + idx += x_nudge; + } + idx += y_nudge; + } + } + else // if (img.data_type == ASTCENC_TYPE_F32) + { + assert(img.data_type == ASTCENC_TYPE_F32); + + for (unsigned int z = z_start; z < z_end; z++) + { + // Fetch the image plane + float* data32 = static_cast<float*>(img.data[z]); + + for (unsigned int y = y_start; y < y_end; y++) + { + float* data32_row = data32 + (4 * x_size * y) + (4 * x_start); + + for (unsigned int x = 0; x < x_count; x++) + { + vfloat4 color = blk.texel(idx); + + // NaNs are handled inline - no need to special case + if (needs_swz) + { + float data[7]; + data[ASTCENC_SWZ_0] = 0.0f; + data[ASTCENC_SWZ_1] = 1.0f; + data[ASTCENC_SWZ_R] = color.lane<0>(); + data[ASTCENC_SWZ_G] = color.lane<1>(); + data[ASTCENC_SWZ_B] = color.lane<2>(); + data[ASTCENC_SWZ_A] = color.lane<3>(); + + if (needs_z) + { + float xN = (data[0] * 2.0f) - 1.0f; + float yN = (data[3] * 2.0f) - 1.0f; + float zN = 1.0f - xN * xN - yN * yN; + if (zN < 0.0f) + { + zN = 0.0f; + } + data[ASTCENC_SWZ_Z] = (astc::sqrt(zN) * 0.5f) + 0.5f; + } + + color = vfloat4(data[swz.r], data[swz.g], data[swz.b], data[swz.a]); + } + + store(color, data32_row); + data32_row += 4; + idx++; + } + idx += x_nudge; + } + idx += y_nudge; + } + } +} diff --git a/thirdparty/astcenc/astcenc_integer_sequence.cpp b/thirdparty/astcenc/astcenc_integer_sequence.cpp new file mode 100644 index 0000000000..416750374d --- /dev/null +++ b/thirdparty/astcenc/astcenc_integer_sequence.cpp @@ -0,0 +1,739 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2021 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief Functions for encoding/decoding Bounded Integer Sequence Encoding. + */ + +#include "astcenc_internal.h" + +#include <array> + +/** @brief Unpacked quint triplets <low,middle,high> for each packed value */ +// TODO: Bitpack these into a uint16_t? +static const uint8_t quints_of_integer[128][3] { + {0, 0, 0}, {1, 0, 0}, {2, 0, 0}, {3, 0, 0}, + {4, 0, 0}, {0, 4, 0}, {4, 4, 0}, {4, 4, 4}, + {0, 1, 0}, {1, 1, 0}, {2, 1, 0}, {3, 1, 0}, + {4, 1, 0}, {1, 4, 0}, {4, 4, 1}, {4, 4, 4}, + {0, 2, 0}, {1, 2, 0}, {2, 2, 0}, {3, 2, 0}, + {4, 2, 0}, {2, 4, 0}, {4, 4, 2}, {4, 4, 4}, + {0, 3, 0}, {1, 3, 0}, {2, 3, 0}, {3, 3, 0}, + {4, 3, 0}, {3, 4, 0}, {4, 4, 3}, {4, 4, 4}, + {0, 0, 1}, {1, 0, 1}, {2, 0, 1}, {3, 0, 1}, + {4, 0, 1}, {0, 4, 1}, {4, 0, 4}, {0, 4, 4}, + {0, 1, 1}, {1, 1, 1}, {2, 1, 1}, {3, 1, 1}, + {4, 1, 1}, {1, 4, 1}, {4, 1, 4}, {1, 4, 4}, + {0, 2, 1}, {1, 2, 1}, {2, 2, 1}, {3, 2, 1}, + {4, 2, 1}, {2, 4, 1}, {4, 2, 4}, {2, 4, 4}, + {0, 3, 1}, {1, 3, 1}, {2, 3, 1}, {3, 3, 1}, + {4, 3, 1}, {3, 4, 1}, {4, 3, 4}, {3, 4, 4}, + {0, 0, 2}, {1, 0, 2}, {2, 0, 2}, {3, 0, 2}, + {4, 0, 2}, {0, 4, 2}, {2, 0, 4}, {3, 0, 4}, + {0, 1, 2}, {1, 1, 2}, {2, 1, 2}, {3, 1, 2}, + {4, 1, 2}, {1, 4, 2}, {2, 1, 4}, {3, 1, 4}, + {0, 2, 2}, {1, 2, 2}, {2, 2, 2}, {3, 2, 2}, + {4, 2, 2}, {2, 4, 2}, {2, 2, 4}, {3, 2, 4}, + {0, 3, 2}, {1, 3, 2}, {2, 3, 2}, {3, 3, 2}, + {4, 3, 2}, {3, 4, 2}, {2, 3, 4}, {3, 3, 4}, + {0, 0, 3}, {1, 0, 3}, {2, 0, 3}, {3, 0, 3}, + {4, 0, 3}, {0, 4, 3}, {0, 0, 4}, {1, 0, 4}, + {0, 1, 3}, {1, 1, 3}, {2, 1, 3}, {3, 1, 3}, + {4, 1, 3}, {1, 4, 3}, {0, 1, 4}, {1, 1, 4}, + {0, 2, 3}, {1, 2, 3}, {2, 2, 3}, {3, 2, 3}, + {4, 2, 3}, {2, 4, 3}, {0, 2, 4}, {1, 2, 4}, + {0, 3, 3}, {1, 3, 3}, {2, 3, 3}, {3, 3, 3}, + {4, 3, 3}, {3, 4, 3}, {0, 3, 4}, {1, 3, 4} +}; + +/** @brief Packed quint values for each unpacked value, indexed [hi][mid][lo]. */ +static const uint8_t integer_of_quints[5][5][5] { + { + {0, 1, 2, 3, 4}, + {8, 9, 10, 11, 12}, + {16, 17, 18, 19, 20}, + {24, 25, 26, 27, 28}, + {5, 13, 21, 29, 6} + }, + { + {32, 33, 34, 35, 36}, + {40, 41, 42, 43, 44}, + {48, 49, 50, 51, 52}, + {56, 57, 58, 59, 60}, + {37, 45, 53, 61, 14} + }, + { + {64, 65, 66, 67, 68}, + {72, 73, 74, 75, 76}, + {80, 81, 82, 83, 84}, + {88, 89, 90, 91, 92}, + {69, 77, 85, 93, 22} + }, + { + {96, 97, 98, 99, 100}, + {104, 105, 106, 107, 108}, + {112, 113, 114, 115, 116}, + {120, 121, 122, 123, 124}, + {101, 109, 117, 125, 30} + }, + { + {102, 103, 70, 71, 38}, + {110, 111, 78, 79, 46}, + {118, 119, 86, 87, 54}, + {126, 127, 94, 95, 62}, + {39, 47, 55, 63, 31} + } +}; + +/** @brief Unpacked trit quintuplets <low,...,high> for each packed value */ +// TODO: Bitpack these into a uint16_t? +static const uint8_t trits_of_integer[256][5] { + {0, 0, 0, 0, 0}, {1, 0, 0, 0, 0}, {2, 0, 0, 0, 0}, {0, 0, 2, 0, 0}, + {0, 1, 0, 0, 0}, {1, 1, 0, 0, 0}, {2, 1, 0, 0, 0}, {1, 0, 2, 0, 0}, + {0, 2, 0, 0, 0}, {1, 2, 0, 0, 0}, {2, 2, 0, 0, 0}, {2, 0, 2, 0, 0}, + {0, 2, 2, 0, 0}, {1, 2, 2, 0, 0}, {2, 2, 2, 0, 0}, {2, 0, 2, 0, 0}, + {0, 0, 1, 0, 0}, {1, 0, 1, 0, 0}, {2, 0, 1, 0, 0}, {0, 1, 2, 0, 0}, + {0, 1, 1, 0, 0}, {1, 1, 1, 0, 0}, {2, 1, 1, 0, 0}, {1, 1, 2, 0, 0}, + {0, 2, 1, 0, 0}, {1, 2, 1, 0, 0}, {2, 2, 1, 0, 0}, {2, 1, 2, 0, 0}, + {0, 0, 0, 2, 2}, {1, 0, 0, 2, 2}, {2, 0, 0, 2, 2}, {0, 0, 2, 2, 2}, + {0, 0, 0, 1, 0}, {1, 0, 0, 1, 0}, {2, 0, 0, 1, 0}, {0, 0, 2, 1, 0}, + {0, 1, 0, 1, 0}, {1, 1, 0, 1, 0}, {2, 1, 0, 1, 0}, {1, 0, 2, 1, 0}, + {0, 2, 0, 1, 0}, {1, 2, 0, 1, 0}, {2, 2, 0, 1, 0}, {2, 0, 2, 1, 0}, + {0, 2, 2, 1, 0}, {1, 2, 2, 1, 0}, {2, 2, 2, 1, 0}, {2, 0, 2, 1, 0}, + {0, 0, 1, 1, 0}, {1, 0, 1, 1, 0}, {2, 0, 1, 1, 0}, {0, 1, 2, 1, 0}, + {0, 1, 1, 1, 0}, {1, 1, 1, 1, 0}, {2, 1, 1, 1, 0}, {1, 1, 2, 1, 0}, + {0, 2, 1, 1, 0}, {1, 2, 1, 1, 0}, {2, 2, 1, 1, 0}, {2, 1, 2, 1, 0}, + {0, 1, 0, 2, 2}, {1, 1, 0, 2, 2}, {2, 1, 0, 2, 2}, {1, 0, 2, 2, 2}, + {0, 0, 0, 2, 0}, {1, 0, 0, 2, 0}, {2, 0, 0, 2, 0}, {0, 0, 2, 2, 0}, + {0, 1, 0, 2, 0}, {1, 1, 0, 2, 0}, {2, 1, 0, 2, 0}, {1, 0, 2, 2, 0}, + {0, 2, 0, 2, 0}, {1, 2, 0, 2, 0}, {2, 2, 0, 2, 0}, {2, 0, 2, 2, 0}, + {0, 2, 2, 2, 0}, {1, 2, 2, 2, 0}, {2, 2, 2, 2, 0}, {2, 0, 2, 2, 0}, + {0, 0, 1, 2, 0}, {1, 0, 1, 2, 0}, {2, 0, 1, 2, 0}, {0, 1, 2, 2, 0}, + {0, 1, 1, 2, 0}, {1, 1, 1, 2, 0}, {2, 1, 1, 2, 0}, {1, 1, 2, 2, 0}, + {0, 2, 1, 2, 0}, {1, 2, 1, 2, 0}, {2, 2, 1, 2, 0}, {2, 1, 2, 2, 0}, + {0, 2, 0, 2, 2}, {1, 2, 0, 2, 2}, {2, 2, 0, 2, 2}, {2, 0, 2, 2, 2}, + {0, 0, 0, 0, 2}, {1, 0, 0, 0, 2}, {2, 0, 0, 0, 2}, {0, 0, 2, 0, 2}, + {0, 1, 0, 0, 2}, {1, 1, 0, 0, 2}, {2, 1, 0, 0, 2}, {1, 0, 2, 0, 2}, + {0, 2, 0, 0, 2}, {1, 2, 0, 0, 2}, {2, 2, 0, 0, 2}, {2, 0, 2, 0, 2}, + {0, 2, 2, 0, 2}, {1, 2, 2, 0, 2}, {2, 2, 2, 0, 2}, {2, 0, 2, 0, 2}, + {0, 0, 1, 0, 2}, {1, 0, 1, 0, 2}, {2, 0, 1, 0, 2}, {0, 1, 2, 0, 2}, + {0, 1, 1, 0, 2}, {1, 1, 1, 0, 2}, {2, 1, 1, 0, 2}, {1, 1, 2, 0, 2}, + {0, 2, 1, 0, 2}, {1, 2, 1, 0, 2}, {2, 2, 1, 0, 2}, {2, 1, 2, 0, 2}, + {0, 2, 2, 2, 2}, {1, 2, 2, 2, 2}, {2, 2, 2, 2, 2}, {2, 0, 2, 2, 2}, + {0, 0, 0, 0, 1}, {1, 0, 0, 0, 1}, {2, 0, 0, 0, 1}, {0, 0, 2, 0, 1}, + {0, 1, 0, 0, 1}, {1, 1, 0, 0, 1}, {2, 1, 0, 0, 1}, {1, 0, 2, 0, 1}, + {0, 2, 0, 0, 1}, {1, 2, 0, 0, 1}, {2, 2, 0, 0, 1}, {2, 0, 2, 0, 1}, + {0, 2, 2, 0, 1}, {1, 2, 2, 0, 1}, {2, 2, 2, 0, 1}, {2, 0, 2, 0, 1}, + {0, 0, 1, 0, 1}, {1, 0, 1, 0, 1}, {2, 0, 1, 0, 1}, {0, 1, 2, 0, 1}, + {0, 1, 1, 0, 1}, {1, 1, 1, 0, 1}, {2, 1, 1, 0, 1}, {1, 1, 2, 0, 1}, + {0, 2, 1, 0, 1}, {1, 2, 1, 0, 1}, {2, 2, 1, 0, 1}, {2, 1, 2, 0, 1}, + {0, 0, 1, 2, 2}, {1, 0, 1, 2, 2}, {2, 0, 1, 2, 2}, {0, 1, 2, 2, 2}, + {0, 0, 0, 1, 1}, {1, 0, 0, 1, 1}, {2, 0, 0, 1, 1}, {0, 0, 2, 1, 1}, + {0, 1, 0, 1, 1}, {1, 1, 0, 1, 1}, {2, 1, 0, 1, 1}, {1, 0, 2, 1, 1}, + {0, 2, 0, 1, 1}, {1, 2, 0, 1, 1}, {2, 2, 0, 1, 1}, {2, 0, 2, 1, 1}, + {0, 2, 2, 1, 1}, {1, 2, 2, 1, 1}, {2, 2, 2, 1, 1}, {2, 0, 2, 1, 1}, + {0, 0, 1, 1, 1}, {1, 0, 1, 1, 1}, {2, 0, 1, 1, 1}, {0, 1, 2, 1, 1}, + {0, 1, 1, 1, 1}, {1, 1, 1, 1, 1}, {2, 1, 1, 1, 1}, {1, 1, 2, 1, 1}, + {0, 2, 1, 1, 1}, {1, 2, 1, 1, 1}, {2, 2, 1, 1, 1}, {2, 1, 2, 1, 1}, + {0, 1, 1, 2, 2}, {1, 1, 1, 2, 2}, {2, 1, 1, 2, 2}, {1, 1, 2, 2, 2}, + {0, 0, 0, 2, 1}, {1, 0, 0, 2, 1}, {2, 0, 0, 2, 1}, {0, 0, 2, 2, 1}, + {0, 1, 0, 2, 1}, {1, 1, 0, 2, 1}, {2, 1, 0, 2, 1}, {1, 0, 2, 2, 1}, + {0, 2, 0, 2, 1}, {1, 2, 0, 2, 1}, {2, 2, 0, 2, 1}, {2, 0, 2, 2, 1}, + {0, 2, 2, 2, 1}, {1, 2, 2, 2, 1}, {2, 2, 2, 2, 1}, {2, 0, 2, 2, 1}, + {0, 0, 1, 2, 1}, {1, 0, 1, 2, 1}, {2, 0, 1, 2, 1}, {0, 1, 2, 2, 1}, + {0, 1, 1, 2, 1}, {1, 1, 1, 2, 1}, {2, 1, 1, 2, 1}, {1, 1, 2, 2, 1}, + {0, 2, 1, 2, 1}, {1, 2, 1, 2, 1}, {2, 2, 1, 2, 1}, {2, 1, 2, 2, 1}, + {0, 2, 1, 2, 2}, {1, 2, 1, 2, 2}, {2, 2, 1, 2, 2}, {2, 1, 2, 2, 2}, + {0, 0, 0, 1, 2}, {1, 0, 0, 1, 2}, {2, 0, 0, 1, 2}, {0, 0, 2, 1, 2}, + {0, 1, 0, 1, 2}, {1, 1, 0, 1, 2}, {2, 1, 0, 1, 2}, {1, 0, 2, 1, 2}, + {0, 2, 0, 1, 2}, {1, 2, 0, 1, 2}, {2, 2, 0, 1, 2}, {2, 0, 2, 1, 2}, + {0, 2, 2, 1, 2}, {1, 2, 2, 1, 2}, {2, 2, 2, 1, 2}, {2, 0, 2, 1, 2}, + {0, 0, 1, 1, 2}, {1, 0, 1, 1, 2}, {2, 0, 1, 1, 2}, {0, 1, 2, 1, 2}, + {0, 1, 1, 1, 2}, {1, 1, 1, 1, 2}, {2, 1, 1, 1, 2}, {1, 1, 2, 1, 2}, + {0, 2, 1, 1, 2}, {1, 2, 1, 1, 2}, {2, 2, 1, 1, 2}, {2, 1, 2, 1, 2}, + {0, 2, 2, 2, 2}, {1, 2, 2, 2, 2}, {2, 2, 2, 2, 2}, {2, 1, 2, 2, 2} +}; + +/** @brief Packed trit values for each unpacked value, indexed [hi][][][][lo]. */ +static const uint8_t integer_of_trits[3][3][3][3][3] { + { + { + { + {0, 1, 2}, + {4, 5, 6}, + {8, 9, 10} + }, + { + {16, 17, 18}, + {20, 21, 22}, + {24, 25, 26} + }, + { + {3, 7, 15}, + {19, 23, 27}, + {12, 13, 14} + } + }, + { + { + {32, 33, 34}, + {36, 37, 38}, + {40, 41, 42} + }, + { + {48, 49, 50}, + {52, 53, 54}, + {56, 57, 58} + }, + { + {35, 39, 47}, + {51, 55, 59}, + {44, 45, 46} + } + }, + { + { + {64, 65, 66}, + {68, 69, 70}, + {72, 73, 74} + }, + { + {80, 81, 82}, + {84, 85, 86}, + {88, 89, 90} + }, + { + {67, 71, 79}, + {83, 87, 91}, + {76, 77, 78} + } + } + }, + { + { + { + {128, 129, 130}, + {132, 133, 134}, + {136, 137, 138} + }, + { + {144, 145, 146}, + {148, 149, 150}, + {152, 153, 154} + }, + { + {131, 135, 143}, + {147, 151, 155}, + {140, 141, 142} + } + }, + { + { + {160, 161, 162}, + {164, 165, 166}, + {168, 169, 170} + }, + { + {176, 177, 178}, + {180, 181, 182}, + {184, 185, 186} + }, + { + {163, 167, 175}, + {179, 183, 187}, + {172, 173, 174} + } + }, + { + { + {192, 193, 194}, + {196, 197, 198}, + {200, 201, 202} + }, + { + {208, 209, 210}, + {212, 213, 214}, + {216, 217, 218} + }, + { + {195, 199, 207}, + {211, 215, 219}, + {204, 205, 206} + } + } + }, + { + { + { + {96, 97, 98}, + {100, 101, 102}, + {104, 105, 106} + }, + { + {112, 113, 114}, + {116, 117, 118}, + {120, 121, 122} + }, + { + {99, 103, 111}, + {115, 119, 123}, + {108, 109, 110} + } + }, + { + { + {224, 225, 226}, + {228, 229, 230}, + {232, 233, 234} + }, + { + {240, 241, 242}, + {244, 245, 246}, + {248, 249, 250} + }, + { + {227, 231, 239}, + {243, 247, 251}, + {236, 237, 238} + } + }, + { + { + {28, 29, 30}, + {60, 61, 62}, + {92, 93, 94} + }, + { + {156, 157, 158}, + {188, 189, 190}, + {220, 221, 222} + }, + { + {31, 63, 127}, + {159, 191, 255}, + {252, 253, 254} + } + } + } +}; + +/** + * @brief The number of bits, trits, and quints needed for a quant level. + */ +struct btq_count +{ + /** @brief The number of bits. */ + uint8_t bits:6; + + /** @brief The number of trits. */ + uint8_t trits:1; + + /** @brief The number of quints. */ + uint8_t quints:1; +}; + +/** + * @brief The table of bits, trits, and quints needed for a quant encode. + */ +static const std::array<btq_count, 21> btq_counts {{ + { 1, 0, 0 }, // QUANT_2 + { 0, 1, 0 }, // QUANT_3 + { 2, 0, 0 }, // QUANT_4 + { 0, 0, 1 }, // QUANT_5 + { 1, 1, 0 }, // QUANT_6 + { 3, 0, 0 }, // QUANT_8 + { 1, 0, 1 }, // QUANT_10 + { 2, 1, 0 }, // QUANT_12 + { 4, 0, 0 }, // QUANT_16 + { 2, 0, 1 }, // QUANT_20 + { 3, 1, 0 }, // QUANT_24 + { 5, 0, 0 }, // QUANT_32 + { 3, 0, 1 }, // QUANT_40 + { 4, 1, 0 }, // QUANT_48 + { 6, 0, 0 }, // QUANT_64 + { 4, 0, 1 }, // QUANT_80 + { 5, 1, 0 }, // QUANT_96 + { 7, 0, 0 }, // QUANT_128 + { 5, 0, 1 }, // QUANT_160 + { 6, 1, 0 }, // QUANT_192 + { 8, 0, 0 } // QUANT_256 +}}; + +/** + * @brief The sequence scale, round, and divisors needed to compute sizing. + * + * The length of a quantized sequence in bits is: + * (scale * <sequence_len> + round) / divisor + */ +struct ise_size +{ + /** @brief The scaling parameter. */ + uint8_t scale:6; + + /** @brief The divisor parameter. */ + uint8_t divisor:2; +}; + +/** + * @brief The table of scale, round, and divisors needed for quant sizing. + */ +static const std::array<ise_size, 21> ise_sizes {{ + { 1, 0 }, // QUANT_2 + { 8, 2 }, // QUANT_3 + { 2, 0 }, // QUANT_4 + { 7, 1 }, // QUANT_5 + { 13, 2 }, // QUANT_6 + { 3, 0 }, // QUANT_8 + { 10, 1 }, // QUANT_10 + { 18, 2 }, // QUANT_12 + { 4, 0 }, // QUANT_16 + { 13, 1 }, // QUANT_20 + { 23, 2 }, // QUANT_24 + { 5, 0 }, // QUANT_32 + { 16, 1 }, // QUANT_40 + { 28, 2 }, // QUANT_48 + { 6, 0 }, // QUANT_64 + { 19, 1 }, // QUANT_80 + { 33, 2 }, // QUANT_96 + { 7, 0 }, // QUANT_128 + { 22, 1 }, // QUANT_160 + { 38, 2 }, // QUANT_192 + { 8, 0 } // QUANT_256 +}}; + +/* See header for documentation. */ +unsigned int get_ise_sequence_bitcount( + unsigned int character_count, + quant_method quant_level +) { + // Cope with out-of bounds values - input might be invalid + if (static_cast<size_t>(quant_level) >= ise_sizes.size()) + { + // Arbitrary large number that's more than an ASTC block can hold + return 1024; + } + + auto& entry = ise_sizes[quant_level]; + unsigned int divisor = (entry.divisor << 1) + 1; + return (entry.scale * character_count + divisor - 1) / divisor; +} + +/** + * @brief Write up to 8 bits at an arbitrary bit offset. + * + * The stored value is at most 8 bits, but can be stored at an offset of between 0 and 7 bits so may + * span two separate bytes in memory. + * + * @param value The value to write. + * @param bitcount The number of bits to write, starting from LSB. + * @param bitoffset The bit offset to store at, between 0 and 7. + * @param[in,out] ptr The data pointer to write to. + */ +static inline void write_bits( + unsigned int value, + unsigned int bitcount, + unsigned int bitoffset, + uint8_t ptr[2] +) { + unsigned int mask = (1 << bitcount) - 1; + value &= mask; + ptr += bitoffset >> 3; + bitoffset &= 7; + value <<= bitoffset; + mask <<= bitoffset; + mask = ~mask; + + ptr[0] &= mask; + ptr[0] |= value; + ptr[1] &= mask >> 8; + ptr[1] |= value >> 8; +} + +/** + * @brief Read up to 8 bits at an arbitrary bit offset. + * + * The stored value is at most 8 bits, but can be stored at an offset of between 0 and 7 bits so may + * span two separate bytes in memory. + * + * @param bitcount The number of bits to read. + * @param bitoffset The bit offset to read from, between 0 and 7. + * @param[in,out] ptr The data pointer to read from. + * + * @return The read value. + */ +static inline unsigned int read_bits( + unsigned int bitcount, + unsigned int bitoffset, + const uint8_t* ptr +) { + unsigned int mask = (1 << bitcount) - 1; + ptr += bitoffset >> 3; + bitoffset &= 7; + unsigned int value = ptr[0] | (ptr[1] << 8); + value >>= bitoffset; + value &= mask; + return value; +} + +/* See header for documentation. */ +void encode_ise( + quant_method quant_level, + unsigned int character_count, + const uint8_t* input_data, + uint8_t* output_data, + unsigned int bit_offset +) { + promise(character_count > 0); + + unsigned int bits = btq_counts[quant_level].bits; + unsigned int trits = btq_counts[quant_level].trits; + unsigned int quints = btq_counts[quant_level].quints; + unsigned int mask = (1 << bits) - 1; + + // Write out trits and bits + if (trits) + { + unsigned int i = 0; + unsigned int full_trit_blocks = character_count / 5; + + for (unsigned int j = 0; j < full_trit_blocks; j++) + { + unsigned int i4 = input_data[i + 4] >> bits; + unsigned int i3 = input_data[i + 3] >> bits; + unsigned int i2 = input_data[i + 2] >> bits; + unsigned int i1 = input_data[i + 1] >> bits; + unsigned int i0 = input_data[i + 0] >> bits; + + uint8_t T = integer_of_trits[i4][i3][i2][i1][i0]; + + // The max size of a trit bit count is 6, so we can always safely + // pack a single MX value with the following 1 or 2 T bits. + uint8_t pack; + + // Element 0 + T0 + T1 + pack = (input_data[i++] & mask) | (((T >> 0) & 0x3) << bits); + write_bits(pack, bits + 2, bit_offset, output_data); + bit_offset += bits + 2; + + // Element 1 + T2 + T3 + pack = (input_data[i++] & mask) | (((T >> 2) & 0x3) << bits); + write_bits(pack, bits + 2, bit_offset, output_data); + bit_offset += bits + 2; + + // Element 2 + T4 + pack = (input_data[i++] & mask) | (((T >> 4) & 0x1) << bits); + write_bits(pack, bits + 1, bit_offset, output_data); + bit_offset += bits + 1; + + // Element 3 + T5 + T6 + pack = (input_data[i++] & mask) | (((T >> 5) & 0x3) << bits); + write_bits(pack, bits + 2, bit_offset, output_data); + bit_offset += bits + 2; + + // Element 4 + T7 + pack = (input_data[i++] & mask) | (((T >> 7) & 0x1) << bits); + write_bits(pack, bits + 1, bit_offset, output_data); + bit_offset += bits + 1; + } + + // Loop tail for a partial block + if (i != character_count) + { + // i4 cannot be present - we know the block is partial + // i0 must be present - we know the block isn't empty + unsigned int i4 = 0; + unsigned int i3 = i + 3 >= character_count ? 0 : input_data[i + 3] >> bits; + unsigned int i2 = i + 2 >= character_count ? 0 : input_data[i + 2] >> bits; + unsigned int i1 = i + 1 >= character_count ? 0 : input_data[i + 1] >> bits; + unsigned int i0 = input_data[i + 0] >> bits; + + uint8_t T = integer_of_trits[i4][i3][i2][i1][i0]; + + for (unsigned int j = 0; i < character_count; i++, j++) + { + // Truncated table as this iteration is always partital + static const uint8_t tbits[4] { 2, 2, 1, 2 }; + static const uint8_t tshift[4] { 0, 2, 4, 5 }; + + uint8_t pack = (input_data[i] & mask) | + (((T >> tshift[j]) & ((1 << tbits[j]) - 1)) << bits); + + write_bits(pack, bits + tbits[j], bit_offset, output_data); + bit_offset += bits + tbits[j]; + } + } + } + // Write out quints and bits + else if (quints) + { + unsigned int i = 0; + unsigned int full_quint_blocks = character_count / 3; + + for (unsigned int j = 0; j < full_quint_blocks; j++) + { + unsigned int i2 = input_data[i + 2] >> bits; + unsigned int i1 = input_data[i + 1] >> bits; + unsigned int i0 = input_data[i + 0] >> bits; + + uint8_t T = integer_of_quints[i2][i1][i0]; + + // The max size of a quint bit count is 5, so we can always safely + // pack a single M value with the following 2 or 3 T bits. + uint8_t pack; + + // Element 0 + pack = (input_data[i++] & mask) | (((T >> 0) & 0x7) << bits); + write_bits(pack, bits + 3, bit_offset, output_data); + bit_offset += bits + 3; + + // Element 1 + pack = (input_data[i++] & mask) | (((T >> 3) & 0x3) << bits); + write_bits(pack, bits + 2, bit_offset, output_data); + bit_offset += bits + 2; + + // Element 2 + pack = (input_data[i++] & mask) | (((T >> 5) & 0x3) << bits); + write_bits(pack, bits + 2, bit_offset, output_data); + bit_offset += bits + 2; + } + + // Loop tail for a partial block + if (i != character_count) + { + // i2 cannot be present - we know the block is partial + // i0 must be present - we know the block isn't empty + unsigned int i2 = 0; + unsigned int i1 = i + 1 >= character_count ? 0 : input_data[i + 1] >> bits; + unsigned int i0 = input_data[i + 0] >> bits; + + uint8_t T = integer_of_quints[i2][i1][i0]; + + for (unsigned int j = 0; i < character_count; i++, j++) + { + // Truncated table as this iteration is always partital + static const uint8_t tbits[2] { 3, 2 }; + static const uint8_t tshift[2] { 0, 3 }; + + uint8_t pack = (input_data[i] & mask) | + (((T >> tshift[j]) & ((1 << tbits[j]) - 1)) << bits); + + write_bits(pack, bits + tbits[j], bit_offset, output_data); + bit_offset += bits + tbits[j]; + } + } + } + // Write out just bits + else + { + for (unsigned int i = 0; i < character_count; i++) + { + write_bits(input_data[i], bits, bit_offset, output_data); + bit_offset += bits; + } + } +} + +/* See header for documentation. */ +void decode_ise( + quant_method quant_level, + unsigned int character_count, + const uint8_t* input_data, + uint8_t* output_data, + unsigned int bit_offset +) { + promise(character_count > 0); + + // Note: due to how the trit/quint-block unpacking is done in this function, we may write more + // temporary results than the number of outputs. The maximum actual number of results is 64 bit, + // but we keep 4 additional character_count of padding. + uint8_t results[68]; + uint8_t tq_blocks[22] { 0 }; // Trit-blocks or quint-blocks, must be zeroed + + unsigned int bits = btq_counts[quant_level].bits; + unsigned int trits = btq_counts[quant_level].trits; + unsigned int quints = btq_counts[quant_level].quints; + + unsigned int lcounter = 0; + unsigned int hcounter = 0; + + // Collect bits for each element, as well as bits for any trit-blocks and quint-blocks. + for (unsigned int i = 0; i < character_count; i++) + { + results[i] = static_cast<uint8_t>(read_bits(bits, bit_offset, input_data)); + bit_offset += bits; + + if (trits) + { + static const uint8_t bits_to_read[5] { 2, 2, 1, 2, 1 }; + static const uint8_t block_shift[5] { 0, 2, 4, 5, 7 }; + static const uint8_t next_lcounter[5] { 1, 2, 3, 4, 0 }; + static const uint8_t hcounter_incr[5] { 0, 0, 0, 0, 1 }; + unsigned int tdata = read_bits(bits_to_read[lcounter], bit_offset, input_data); + bit_offset += bits_to_read[lcounter]; + tq_blocks[hcounter] |= tdata << block_shift[lcounter]; + hcounter += hcounter_incr[lcounter]; + lcounter = next_lcounter[lcounter]; + } + + if (quints) + { + static const uint8_t bits_to_read[3] { 3, 2, 2 }; + static const uint8_t block_shift[3] { 0, 3, 5 }; + static const uint8_t next_lcounter[3] { 1, 2, 0 }; + static const uint8_t hcounter_incr[3] { 0, 0, 1 }; + unsigned int tdata = read_bits(bits_to_read[lcounter], bit_offset, input_data); + bit_offset += bits_to_read[lcounter]; + tq_blocks[hcounter] |= tdata << block_shift[lcounter]; + hcounter += hcounter_incr[lcounter]; + lcounter = next_lcounter[lcounter]; + } + } + + // Unpack trit-blocks or quint-blocks as needed + if (trits) + { + unsigned int trit_blocks = (character_count + 4) / 5; + promise(trit_blocks > 0); + for (unsigned int i = 0; i < trit_blocks; i++) + { + const uint8_t *tritptr = trits_of_integer[tq_blocks[i]]; + results[5 * i ] |= tritptr[0] << bits; + results[5 * i + 1] |= tritptr[1] << bits; + results[5 * i + 2] |= tritptr[2] << bits; + results[5 * i + 3] |= tritptr[3] << bits; + results[5 * i + 4] |= tritptr[4] << bits; + } + } + + if (quints) + { + unsigned int quint_blocks = (character_count + 2) / 3; + promise(quint_blocks > 0); + for (unsigned int i = 0; i < quint_blocks; i++) + { + const uint8_t *quintptr = quints_of_integer[tq_blocks[i]]; + results[3 * i ] |= quintptr[0] << bits; + results[3 * i + 1] |= quintptr[1] << bits; + results[3 * i + 2] |= quintptr[2] << bits; + } + } + + for (unsigned int i = 0; i < character_count; i++) + { + output_data[i] = results[i]; + } +} diff --git a/thirdparty/astcenc/astcenc_internal.h b/thirdparty/astcenc/astcenc_internal.h new file mode 100644 index 0000000000..0aa8fa0f81 --- /dev/null +++ b/thirdparty/astcenc/astcenc_internal.h @@ -0,0 +1,2196 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2023 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief Functions and data declarations. + */ + +#ifndef ASTCENC_INTERNAL_INCLUDED +#define ASTCENC_INTERNAL_INCLUDED + +#include <algorithm> +#include <cstddef> +#include <cstdint> +#if defined(ASTCENC_DIAGNOSTICS) + #include <cstdio> +#endif +#include <cstdlib> + +#include "astcenc.h" +#include "astcenc_mathlib.h" +#include "astcenc_vecmathlib.h" + +/** + * @brief Make a promise to the compiler's optimizer. + * + * A promise is an expression that the optimizer is can assume is true for to help it generate + * faster code. Common use cases for this are to promise that a for loop will iterate more than + * once, or that the loop iteration count is a multiple of a vector length, which avoids pre-loop + * checks and can avoid loop tails if loops are unrolled by the auto-vectorizer. + */ +#if defined(NDEBUG) + #if !defined(__clang__) && defined(_MSC_VER) + #define promise(cond) __assume(cond) + #elif defined(__clang__) + #if __has_builtin(__builtin_assume) + #define promise(cond) __builtin_assume(cond) + #elif __has_builtin(__builtin_unreachable) + #define promise(cond) if (!(cond)) { __builtin_unreachable(); } + #else + #define promise(cond) + #endif + #else // Assume GCC + #define promise(cond) if (!(cond)) { __builtin_unreachable(); } + #endif +#else + #define promise(cond) assert(cond) +#endif + +/* ============================================================================ + Constants +============================================================================ */ +#if !defined(ASTCENC_BLOCK_MAX_TEXELS) + #define ASTCENC_BLOCK_MAX_TEXELS 216 // A 3D 6x6x6 block +#endif + +/** @brief The maximum number of texels a block can support (6x6x6 block). */ +static constexpr unsigned int BLOCK_MAX_TEXELS { ASTCENC_BLOCK_MAX_TEXELS }; + +/** @brief The maximum number of components a block can support. */ +static constexpr unsigned int BLOCK_MAX_COMPONENTS { 4 }; + +/** @brief The maximum number of partitions a block can support. */ +static constexpr unsigned int BLOCK_MAX_PARTITIONS { 4 }; + +/** @brief The number of partitionings, per partition count, suported by the ASTC format. */ +static constexpr unsigned int BLOCK_MAX_PARTITIONINGS { 1024 }; + +/** @brief The maximum number of weights used during partition selection for texel clustering. */ +static constexpr uint8_t BLOCK_MAX_KMEANS_TEXELS { 64 }; + +/** @brief The maximum number of weights a block can support. */ +static constexpr unsigned int BLOCK_MAX_WEIGHTS { 64 }; + +/** @brief The maximum number of weights a block can support per plane in 2 plane mode. */ +static constexpr unsigned int BLOCK_MAX_WEIGHTS_2PLANE { BLOCK_MAX_WEIGHTS / 2 }; + +/** @brief The minimum number of weight bits a candidate encoding must encode. */ +static constexpr unsigned int BLOCK_MIN_WEIGHT_BITS { 24 }; + +/** @brief The maximum number of weight bits a candidate encoding can encode. */ +static constexpr unsigned int BLOCK_MAX_WEIGHT_BITS { 96 }; + +/** @brief The index indicating a bad (unused) block mode in the remap array. */ +static constexpr uint16_t BLOCK_BAD_BLOCK_MODE { 0xFFFFu }; + +/** @brief The index indicating a bad (unused) partitioning in the remap array. */ +static constexpr uint16_t BLOCK_BAD_PARTITIONING { 0xFFFFu }; + +/** @brief The number of partition index bits supported by the ASTC format . */ +static constexpr unsigned int PARTITION_INDEX_BITS { 10 }; + +/** @brief The offset of the plane 2 weights in shared weight arrays. */ +static constexpr unsigned int WEIGHTS_PLANE2_OFFSET { BLOCK_MAX_WEIGHTS_2PLANE }; + +/** @brief The sum of quantized weights for one texel. */ +static constexpr float WEIGHTS_TEXEL_SUM { 16.0f }; + +/** @brief The number of block modes supported by the ASTC format. */ +static constexpr unsigned int WEIGHTS_MAX_BLOCK_MODES { 2048 }; + +/** @brief The number of weight grid decimation modes supported by the ASTC format. */ +static constexpr unsigned int WEIGHTS_MAX_DECIMATION_MODES { 87 }; + +/** @brief The high default error used to initialize error trackers. */ +static constexpr float ERROR_CALC_DEFAULT { 1e30f }; + +/** + * @brief The minimum texel count for a block to use the one partition fast path. + * + * This setting skips 4x4 and 5x4 block sizes. + */ +static constexpr unsigned int TUNE_MIN_TEXELS_MODE0_FASTPATH { 24 }; + +/** + * @brief The maximum number of candidate encodings tested for each encoding mode. + * + * This can be dynamically reduced by the compression quality preset. + */ +static constexpr unsigned int TUNE_MAX_TRIAL_CANDIDATES { 8 }; + +/** + * @brief The maximum number of candidate partitionings tested for each encoding mode. + * + * This can be dynamically reduced by the compression quality preset. + */ +static constexpr unsigned int TUNE_MAX_PARTITIONING_CANDIDATES { 32 }; + +/** + * @brief The maximum quant level using full angular endpoint search method. + * + * The angular endpoint search is used to find the min/max weight that should + * be used for a given quantization level. It is effective but expensive, so + * we only use it where it has the most value - low quant levels with wide + * spacing. It is used below TUNE_MAX_ANGULAR_QUANT (inclusive). Above this we + * assume the min weight is 0.0f, and the max weight is 1.0f. + * + * Note the angular algorithm is vectorized, and using QUANT_12 exactly fills + * one 8-wide vector. Decreasing by one doesn't buy much performance, and + * increasing by one is disproportionately expensive. + */ +static constexpr unsigned int TUNE_MAX_ANGULAR_QUANT { 7 }; /* QUANT_12 */ + +static_assert((BLOCK_MAX_TEXELS % ASTCENC_SIMD_WIDTH) == 0, + "BLOCK_MAX_TEXELS must be multiple of ASTCENC_SIMD_WIDTH"); + +static_assert(BLOCK_MAX_TEXELS <= 216, + "BLOCK_MAX_TEXELS must not be greater than 216"); + +static_assert((BLOCK_MAX_WEIGHTS % ASTCENC_SIMD_WIDTH) == 0, + "BLOCK_MAX_WEIGHTS must be multiple of ASTCENC_SIMD_WIDTH"); + +static_assert((WEIGHTS_MAX_BLOCK_MODES % ASTCENC_SIMD_WIDTH) == 0, + "WEIGHTS_MAX_BLOCK_MODES must be multiple of ASTCENC_SIMD_WIDTH"); + + +/* ============================================================================ + Commonly used data structures +============================================================================ */ + +/** + * @brief The ASTC endpoint formats. + * + * Note, the values here are used directly in the encoding in the format so do not rearrange. + */ +enum endpoint_formats +{ + FMT_LUMINANCE = 0, + FMT_LUMINANCE_DELTA = 1, + FMT_HDR_LUMINANCE_LARGE_RANGE = 2, + FMT_HDR_LUMINANCE_SMALL_RANGE = 3, + FMT_LUMINANCE_ALPHA = 4, + FMT_LUMINANCE_ALPHA_DELTA = 5, + FMT_RGB_SCALE = 6, + FMT_HDR_RGB_SCALE = 7, + FMT_RGB = 8, + FMT_RGB_DELTA = 9, + FMT_RGB_SCALE_ALPHA = 10, + FMT_HDR_RGB = 11, + FMT_RGBA = 12, + FMT_RGBA_DELTA = 13, + FMT_HDR_RGB_LDR_ALPHA = 14, + FMT_HDR_RGBA = 15 +}; + +/** + * @brief The ASTC quantization methods. + * + * Note, the values here are used directly in the encoding in the format so do not rearrange. + */ +enum quant_method +{ + QUANT_2 = 0, + QUANT_3 = 1, + QUANT_4 = 2, + QUANT_5 = 3, + QUANT_6 = 4, + QUANT_8 = 5, + QUANT_10 = 6, + QUANT_12 = 7, + QUANT_16 = 8, + QUANT_20 = 9, + QUANT_24 = 10, + QUANT_32 = 11, + QUANT_40 = 12, + QUANT_48 = 13, + QUANT_64 = 14, + QUANT_80 = 15, + QUANT_96 = 16, + QUANT_128 = 17, + QUANT_160 = 18, + QUANT_192 = 19, + QUANT_256 = 20 +}; + +/** + * @brief The number of levels use by an ASTC quantization method. + * + * @param method The quantization method + * + * @return The number of levels used by @c method. + */ +static inline unsigned int get_quant_level(quant_method method) +{ + switch (method) + { + case QUANT_2: return 2; + case QUANT_3: return 3; + case QUANT_4: return 4; + case QUANT_5: return 5; + case QUANT_6: return 6; + case QUANT_8: return 8; + case QUANT_10: return 10; + case QUANT_12: return 12; + case QUANT_16: return 16; + case QUANT_20: return 20; + case QUANT_24: return 24; + case QUANT_32: return 32; + case QUANT_40: return 40; + case QUANT_48: return 48; + case QUANT_64: return 64; + case QUANT_80: return 80; + case QUANT_96: return 96; + case QUANT_128: return 128; + case QUANT_160: return 160; + case QUANT_192: return 192; + case QUANT_256: return 256; + } + + // Unreachable - the enum is fully described + return 0; +} + +/** + * @brief Computed metrics about a partition in a block. + */ +struct partition_metrics +{ + /** @brief The error-weighted average color in the partition. */ + vfloat4 avg; + + /** @brief The dominant error-weighted direction in the partition. */ + vfloat4 dir; +}; + +/** + * @brief Computed lines for a a three component analysis. + */ +struct partition_lines3 +{ + /** @brief Line for uncorrelated chroma. */ + line3 uncor_line; + + /** @brief Line for correlated chroma, passing though the origin. */ + line3 samec_line; + + /** @brief Post-processed line for uncorrelated chroma. */ + processed_line3 uncor_pline; + + /** @brief Post-processed line for correlated chroma, passing though the origin. */ + processed_line3 samec_pline; + + /** @brief The length of the line for uncorrelated chroma. */ + float uncor_line_len; + + /** @brief The length of the line for correlated chroma. */ + float samec_line_len; +}; + +/** + * @brief The partition information for a single partition. + * + * ASTC has a total of 1024 candidate partitions for each of 2/3/4 partition counts, although this + * 1024 includes seeds that generate duplicates of other seeds and seeds that generate completely + * empty partitions. These are both valid encodings, but astcenc will skip both during compression + * as they are not useful. + */ +struct partition_info +{ + /** @brief The number of partitions in this partitioning. */ + uint16_t partition_count; + + /** @brief The index (seed) of this partitioning. */ + uint16_t partition_index; + + /** + * @brief The number of texels in each partition. + * + * Note that some seeds result in zero texels assigned to a partition are valid, but are skipped + * by this compressor as there is no point spending bits encoding an unused color endpoint. + */ + uint8_t partition_texel_count[BLOCK_MAX_PARTITIONS]; + + /** @brief The partition of each texel in the block. */ + uint8_t partition_of_texel[BLOCK_MAX_TEXELS]; + + /** @brief The list of texels in each partition. */ + uint8_t texels_of_partition[BLOCK_MAX_PARTITIONS][BLOCK_MAX_TEXELS]; +}; + +/** + * @brief The weight grid information for a single decimation pattern. + * + * ASTC can store one weight per texel, but is also capable of storing lower resolution weight grids + * that are interpolated during decompression to assign a with to a texel. Storing fewer weights + * can free up a substantial amount of bits that we can then spend on more useful things, such as + * more accurate endpoints and weights, or additional partitions. + * + * This data structure is used to store information about a single weight grid decimation pattern, + * for a single block size. + */ +struct decimation_info +{ + /** @brief The total number of texels in the block. */ + uint8_t texel_count; + + /** @brief The maximum number of stored weights that contribute to each texel, between 1 and 4. */ + uint8_t max_texel_weight_count; + + /** @brief The total number of weights stored. */ + uint8_t weight_count; + + /** @brief The number of stored weights in the X dimension. */ + uint8_t weight_x; + + /** @brief The number of stored weights in the Y dimension. */ + uint8_t weight_y; + + /** @brief The number of stored weights in the Z dimension. */ + uint8_t weight_z; + + /** + * @brief The number of weights that contribute to each texel. + * Value is between 1 and 4. + */ + uint8_t texel_weight_count[BLOCK_MAX_TEXELS]; + + /** + * @brief The weight index of the N weights that are interpolated for each texel. + * Stored transposed to improve vectorization. + */ + uint8_t texel_weights_tr[4][BLOCK_MAX_TEXELS]; + + /** + * @brief The bilinear contribution of the N weights that are interpolated for each texel. + * Value is between 0 and 16, stored transposed to improve vectorization. + */ + uint8_t texel_weight_contribs_int_tr[4][BLOCK_MAX_TEXELS]; + + /** + * @brief The bilinear contribution of the N weights that are interpolated for each texel. + * Value is between 0 and 1, stored transposed to improve vectorization. + */ + alignas(ASTCENC_VECALIGN) float texel_weight_contribs_float_tr[4][BLOCK_MAX_TEXELS]; + + /** @brief The number of texels that each stored weight contributes to. */ + uint8_t weight_texel_count[BLOCK_MAX_WEIGHTS]; + + /** + * @brief The list of texels that use a specific weight index. + * Stored transposed to improve vectorization. + */ + uint8_t weight_texels_tr[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS]; + + /** + * @brief The bilinear contribution to the N texels that use each weight. + * Value is between 0 and 1, stored transposed to improve vectorization. + */ + alignas(ASTCENC_VECALIGN) float weights_texel_contribs_tr[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS]; + + /** + * @brief The bilinear contribution to the Nth texel that uses each weight. + * Value is between 0 and 1, stored transposed to improve vectorization. + */ + float texel_contrib_for_weight[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS]; +}; + +/** + * @brief Metadata for single block mode for a specific block size. + */ +struct block_mode +{ + /** @brief The block mode index in the ASTC encoded form. */ + uint16_t mode_index; + + /** @brief The decimation mode index in the compressor reindexed list. */ + uint8_t decimation_mode; + + /** @brief The weight quantization used by this block mode. */ + uint8_t quant_mode; + + /** @brief The weight quantization used by this block mode. */ + uint8_t weight_bits; + + /** @brief Is a dual weight plane used by this block mode? */ + uint8_t is_dual_plane : 1; + + /** + * @brief Get the weight quantization used by this block mode. + * + * @return The quantization level. + */ + inline quant_method get_weight_quant_mode() const + { + return static_cast<quant_method>(this->quant_mode); + } +}; + +/** + * @brief Metadata for single decimation mode for a specific block size. + */ +struct decimation_mode +{ + /** @brief The max weight precision for 1 plane, or -1 if not supported. */ + int8_t maxprec_1plane; + + /** @brief The max weight precision for 2 planes, or -1 if not supported. */ + int8_t maxprec_2planes; + + /** + * @brief Bitvector indicating weight quant modes used by active 1 plane block modes. + * + * Bit 0 = QUANT_2, Bit 1 = QUANT_3, etc. + */ + uint16_t refprec_1_plane; + + /** + * @brief Bitvector indicating weight quant methods used by active 2 plane block modes. + * + * Bit 0 = QUANT_2, Bit 1 = QUANT_3, etc. + */ + uint16_t refprec_2_planes; + + /** + * @brief Set a 1 plane weight quant as active. + * + * @param weight_quant The quant method to set. + */ + void set_ref_1_plane(quant_method weight_quant) + { + refprec_1_plane |= (1 << weight_quant); + } + + /** + * @brief Test if this mode is active below a given 1 plane weight quant (inclusive). + * + * @param max_weight_quant The max quant method to test. + */ + bool is_ref_1_plane(quant_method max_weight_quant) const + { + uint16_t mask = static_cast<uint16_t>((1 << (max_weight_quant + 1)) - 1); + return (refprec_1_plane & mask) != 0; + } + + /** + * @brief Set a 2 plane weight quant as active. + * + * @param weight_quant The quant method to set. + */ + void set_ref_2_plane(quant_method weight_quant) + { + refprec_2_planes |= static_cast<uint16_t>(1 << weight_quant); + } + + /** + * @brief Test if this mode is active below a given 2 plane weight quant (inclusive). + * + * @param max_weight_quant The max quant method to test. + */ + bool is_ref_2_plane(quant_method max_weight_quant) const + { + uint16_t mask = static_cast<uint16_t>((1 << (max_weight_quant + 1)) - 1); + return (refprec_2_planes & mask) != 0; + } +}; + +/** + * @brief Data tables for a single block size. + * + * The decimation tables store the information to apply weight grid dimension reductions. We only + * store the decimation modes that are actually needed by the current context; many of the possible + * modes will be unused (too many weights for the current block size or disabled by heuristics). The + * actual number of weights stored is @c decimation_mode_count, and the @c decimation_modes and + * @c decimation_tables arrays store the active modes contiguously at the start of the array. These + * entries are not stored in any particular order. + * + * The block mode tables store the unpacked block mode settings. Block modes are stored in the + * compressed block as an 11 bit field, but for any given block size and set of compressor + * heuristics, only a subset of the block modes will be used. The actual number of block modes + * stored is indicated in @c block_mode_count, and the @c block_modes array store the active modes + * contiguously at the start of the array. These entries are stored in incrementing "packed" value + * order, which doesn't mean much once unpacked. To allow decompressors to reference the packed data + * efficiently the @c block_mode_packed_index array stores the mapping between physical ID and the + * actual remapped array index. + */ +struct block_size_descriptor +{ + /** @brief The block X dimension, in texels. */ + uint8_t xdim; + + /** @brief The block Y dimension, in texels. */ + uint8_t ydim; + + /** @brief The block Z dimension, in texels. */ + uint8_t zdim; + + /** @brief The block total texel count. */ + uint8_t texel_count; + + /** + * @brief The number of stored decimation modes which are "always" modes. + * + * Always modes are stored at the start of the decimation_modes list. + */ + unsigned int decimation_mode_count_always; + + /** @brief The number of stored decimation modes for selected encodings. */ + unsigned int decimation_mode_count_selected; + + /** @brief The number of stored decimation modes for any encoding. */ + unsigned int decimation_mode_count_all; + + /** + * @brief The number of stored block modes which are "always" modes. + * + * Always modes are stored at the start of the block_modes list. + */ + unsigned int block_mode_count_1plane_always; + + /** @brief The number of stored block modes for active 1 plane encodings. */ + unsigned int block_mode_count_1plane_selected; + + /** @brief The number of stored block modes for active 1 and 2 plane encodings. */ + unsigned int block_mode_count_1plane_2plane_selected; + + /** @brief The number of stored block modes for any encoding. */ + unsigned int block_mode_count_all; + + /** @brief The number of selected partitionings for 1/2/3/4 partitionings. */ + unsigned int partitioning_count_selected[BLOCK_MAX_PARTITIONS]; + + /** @brief The number of partitionings for 1/2/3/4 partitionings. */ + unsigned int partitioning_count_all[BLOCK_MAX_PARTITIONS]; + + /** @brief The active decimation modes, stored in low indices. */ + decimation_mode decimation_modes[WEIGHTS_MAX_DECIMATION_MODES]; + + /** @brief The active decimation tables, stored in low indices. */ + alignas(ASTCENC_VECALIGN) decimation_info decimation_tables[WEIGHTS_MAX_DECIMATION_MODES]; + + /** @brief The packed block mode array index, or @c BLOCK_BAD_BLOCK_MODE if not active. */ + uint16_t block_mode_packed_index[WEIGHTS_MAX_BLOCK_MODES]; + + /** @brief The active block modes, stored in low indices. */ + block_mode block_modes[WEIGHTS_MAX_BLOCK_MODES]; + + /** @brief The active partition tables, stored in low indices per-count. */ + partition_info partitionings[(3 * BLOCK_MAX_PARTITIONINGS) + 1]; + + /** + * @brief The packed partition table array index, or @c BLOCK_BAD_PARTITIONING if not active. + * + * Indexed by partition_count - 2, containing 2, 3 and 4 partitions. + */ + uint16_t partitioning_packed_index[3][BLOCK_MAX_PARTITIONINGS]; + + /** @brief The active texels for k-means partition selection. */ + uint8_t kmeans_texels[BLOCK_MAX_KMEANS_TEXELS]; + + /** + * @brief The canonical 2-partition coverage pattern used during block partition search. + * + * Indexed by remapped index, not physical index. + */ + uint64_t coverage_bitmaps_2[BLOCK_MAX_PARTITIONINGS][2]; + + /** + * @brief The canonical 3-partition coverage pattern used during block partition search. + * + * Indexed by remapped index, not physical index. + */ + uint64_t coverage_bitmaps_3[BLOCK_MAX_PARTITIONINGS][3]; + + /** + * @brief The canonical 4-partition coverage pattern used during block partition search. + * + * Indexed by remapped index, not physical index. + */ + uint64_t coverage_bitmaps_4[BLOCK_MAX_PARTITIONINGS][4]; + + /** + * @brief Get the block mode structure for index @c block_mode. + * + * This function can only return block modes that are enabled by the current compressor config. + * Decompression from an arbitrary source should not use this without first checking that the + * packed block mode index is not @c BLOCK_BAD_BLOCK_MODE. + * + * @param block_mode The packed block mode index. + * + * @return The block mode structure. + */ + const block_mode& get_block_mode(unsigned int block_mode) const + { + unsigned int packed_index = this->block_mode_packed_index[block_mode]; + assert(packed_index != BLOCK_BAD_BLOCK_MODE && packed_index < this->block_mode_count_all); + return this->block_modes[packed_index]; + } + + /** + * @brief Get the decimation mode structure for index @c decimation_mode. + * + * This function can only return decimation modes that are enabled by the current compressor + * config. The mode array is stored packed, but this is only ever indexed by the packed index + * stored in the @c block_mode and never exists in an unpacked form. + * + * @param decimation_mode The packed decimation mode index. + * + * @return The decimation mode structure. + */ + const decimation_mode& get_decimation_mode(unsigned int decimation_mode) const + { + return this->decimation_modes[decimation_mode]; + } + + /** + * @brief Get the decimation info structure for index @c decimation_mode. + * + * This function can only return decimation modes that are enabled by the current compressor + * config. The mode array is stored packed, but this is only ever indexed by the packed index + * stored in the @c block_mode and never exists in an unpacked form. + * + * @param decimation_mode The packed decimation mode index. + * + * @return The decimation info structure. + */ + const decimation_info& get_decimation_info(unsigned int decimation_mode) const + { + return this->decimation_tables[decimation_mode]; + } + + /** + * @brief Get the partition info table for a given partition count. + * + * @param partition_count The number of partitions we want the table for. + * + * @return The pointer to the table of 1024 entries (for 2/3/4 parts) or 1 entry (for 1 part). + */ + const partition_info* get_partition_table(unsigned int partition_count) const + { + if (partition_count == 1) + { + partition_count = 5; + } + unsigned int index = (partition_count - 2) * BLOCK_MAX_PARTITIONINGS; + return this->partitionings + index; + } + + /** + * @brief Get the partition info structure for a given partition count and seed. + * + * @param partition_count The number of partitions we want the info for. + * @param index The partition seed (between 0 and 1023). + * + * @return The partition info structure. + */ + const partition_info& get_partition_info(unsigned int partition_count, unsigned int index) const + { + unsigned int packed_index = 0; + if (partition_count >= 2) + { + packed_index = this->partitioning_packed_index[partition_count - 2][index]; + } + + assert(packed_index != BLOCK_BAD_PARTITIONING && packed_index < this->partitioning_count_all[partition_count - 1]); + auto& result = get_partition_table(partition_count)[packed_index]; + assert(index == result.partition_index); + return result; + } + + /** + * @brief Get the partition info structure for a given partition count and seed. + * + * @param partition_count The number of partitions we want the info for. + * @param packed_index The raw array offset. + * + * @return The partition info structure. + */ + const partition_info& get_raw_partition_info(unsigned int partition_count, unsigned int packed_index) const + { + assert(packed_index != BLOCK_BAD_PARTITIONING && packed_index < this->partitioning_count_all[partition_count - 1]); + auto& result = get_partition_table(partition_count)[packed_index]; + return result; + } +}; + +/** + * @brief The image data for a single block. + * + * The @c data_[rgba] fields store the image data in an encoded SoA float form designed for easy + * vectorization. Input data is converted to float and stored as values between 0 and 65535. LDR + * data is stored as direct UNORM data, HDR data is stored as LNS data. + * + * The @c rgb_lns and @c alpha_lns fields that assigned a per-texel use of HDR are only used during + * decompression. The current compressor will always use HDR endpoint formats when in HDR mode. + */ +struct image_block +{ + /** @brief The input (compress) or output (decompress) data for the red color component. */ + alignas(ASTCENC_VECALIGN) float data_r[BLOCK_MAX_TEXELS]; + + /** @brief The input (compress) or output (decompress) data for the green color component. */ + alignas(ASTCENC_VECALIGN) float data_g[BLOCK_MAX_TEXELS]; + + /** @brief The input (compress) or output (decompress) data for the blue color component. */ + alignas(ASTCENC_VECALIGN) float data_b[BLOCK_MAX_TEXELS]; + + /** @brief The input (compress) or output (decompress) data for the alpha color component. */ + alignas(ASTCENC_VECALIGN) float data_a[BLOCK_MAX_TEXELS]; + + /** @brief The number of texels in the block. */ + uint8_t texel_count; + + /** @brief The original data for texel 0 for constant color block encoding. */ + vfloat4 origin_texel; + + /** @brief The min component value of all texels in the block. */ + vfloat4 data_min; + + /** @brief The mean component value of all texels in the block. */ + vfloat4 data_mean; + + /** @brief The max component value of all texels in the block. */ + vfloat4 data_max; + + /** @brief The relative error significance of the color channels. */ + vfloat4 channel_weight; + + /** @brief Is this grayscale block where R == G == B for all texels? */ + bool grayscale; + + /** @brief Set to 1 if a texel is using HDR RGB endpoints (decompression only). */ + uint8_t rgb_lns[BLOCK_MAX_TEXELS]; + + /** @brief Set to 1 if a texel is using HDR alpha endpoints (decompression only). */ + uint8_t alpha_lns[BLOCK_MAX_TEXELS]; + + /** @brief The X position of this block in the input or output image. */ + unsigned int xpos; + + /** @brief The Y position of this block in the input or output image. */ + unsigned int ypos; + + /** @brief The Z position of this block in the input or output image. */ + unsigned int zpos; + + /** + * @brief Get an RGBA texel value from the data. + * + * @param index The texel index. + * + * @return The texel in RGBA component ordering. + */ + inline vfloat4 texel(unsigned int index) const + { + return vfloat4(data_r[index], + data_g[index], + data_b[index], + data_a[index]); + } + + /** + * @brief Get an RGB texel value from the data. + * + * @param index The texel index. + * + * @return The texel in RGB0 component ordering. + */ + inline vfloat4 texel3(unsigned int index) const + { + return vfloat3(data_r[index], + data_g[index], + data_b[index]); + } + + /** + * @brief Get the default alpha value for endpoints that don't store it. + * + * The default depends on whether the alpha endpoint is LDR or HDR. + * + * @return The alpha value in the scaled range used by the compressor. + */ + inline float get_default_alpha() const + { + return this->alpha_lns[0] ? static_cast<float>(0x7800) : static_cast<float>(0xFFFF); + } + + /** + * @brief Test if a single color channel is constant across the block. + * + * Constant color channels are easier to compress as interpolating between two identical colors + * always returns the same value, irrespective of the weight used. They therefore can be ignored + * for the purposes of weight selection and use of a second weight plane. + * + * @return @c true if the channel is constant across the block, @c false otherwise. + */ + inline bool is_constant_channel(int channel) const + { + vmask4 lane_mask = vint4::lane_id() == vint4(channel); + vmask4 color_mask = this->data_min == this->data_max; + return any(lane_mask & color_mask); + } + + /** + * @brief Test if this block is a luminance block with constant 1.0 alpha. + * + * @return @c true if the block is a luminance block , @c false otherwise. + */ + inline bool is_luminance() const + { + float default_alpha = this->get_default_alpha(); + bool alpha1 = (this->data_min.lane<3>() == default_alpha) && + (this->data_max.lane<3>() == default_alpha); + return this->grayscale && alpha1; + } + + /** + * @brief Test if this block is a luminance block with variable alpha. + * + * @return @c true if the block is a luminance + alpha block , @c false otherwise. + */ + inline bool is_luminancealpha() const + { + float default_alpha = this->get_default_alpha(); + bool alpha1 = (this->data_min.lane<3>() == default_alpha) && + (this->data_max.lane<3>() == default_alpha); + return this->grayscale && !alpha1; + } +}; + +/** + * @brief Data structure storing the color endpoints for a block. + */ +struct endpoints +{ + /** @brief The number of partition endpoints stored. */ + unsigned int partition_count; + + /** @brief The colors for endpoint 0. */ + vfloat4 endpt0[BLOCK_MAX_PARTITIONS]; + + /** @brief The colors for endpoint 1. */ + vfloat4 endpt1[BLOCK_MAX_PARTITIONS]; +}; + +/** + * @brief Data structure storing the color endpoints and weights. + */ +struct endpoints_and_weights +{ + /** @brief True if all active values in weight_error_scale are the same. */ + bool is_constant_weight_error_scale; + + /** @brief The color endpoints. */ + endpoints ep; + + /** @brief The ideal weight for each texel; may be undecimated or decimated. */ + alignas(ASTCENC_VECALIGN) float weights[BLOCK_MAX_TEXELS]; + + /** @brief The ideal weight error scaling for each texel; may be undecimated or decimated. */ + alignas(ASTCENC_VECALIGN) float weight_error_scale[BLOCK_MAX_TEXELS]; +}; + +/** + * @brief Utility storing estimated errors from choosing particular endpoint encodings. + */ +struct encoding_choice_errors +{ + /** @brief Error of using LDR RGB-scale instead of complete endpoints. */ + float rgb_scale_error; + + /** @brief Error of using HDR RGB-scale instead of complete endpoints. */ + float rgb_luma_error; + + /** @brief Error of using luminance instead of RGB. */ + float luminance_error; + + /** @brief Error of discarding alpha and using a constant 1.0 alpha. */ + float alpha_drop_error; + + /** @brief Can we use delta offset encoding? */ + bool can_offset_encode; + + /** @brief Can we use blue contraction encoding? */ + bool can_blue_contract; +}; + +/** + * @brief Preallocated working buffers, allocated per thread during context creation. + */ +struct alignas(ASTCENC_VECALIGN) compression_working_buffers +{ + /** @brief Ideal endpoints and weights for plane 1. */ + endpoints_and_weights ei1; + + /** @brief Ideal endpoints and weights for plane 2. */ + endpoints_and_weights ei2; + + /** + * @brief Decimated ideal weight values in the ~0-1 range. + * + * Note that values can be slightly below zero or higher than one due to + * endpoint extents being inside the ideal color representation. + * + * For two planes, second plane starts at @c WEIGHTS_PLANE2_OFFSET offsets. + */ + alignas(ASTCENC_VECALIGN) float dec_weights_ideal[WEIGHTS_MAX_DECIMATION_MODES * BLOCK_MAX_WEIGHTS]; + + /** + * @brief Decimated quantized weight values in the unquantized 0-64 range. + * + * For two planes, second plane starts at @c WEIGHTS_PLANE2_OFFSET offsets. + */ + uint8_t dec_weights_uquant[WEIGHTS_MAX_BLOCK_MODES * BLOCK_MAX_WEIGHTS]; + + /** @brief Error of the best encoding combination for each block mode. */ + alignas(ASTCENC_VECALIGN) float errors_of_best_combination[WEIGHTS_MAX_BLOCK_MODES]; + + /** @brief The best color quant for each block mode. */ + uint8_t best_quant_levels[WEIGHTS_MAX_BLOCK_MODES]; + + /** @brief The best color quant for each block mode if modes are the same and we have spare bits. */ + uint8_t best_quant_levels_mod[WEIGHTS_MAX_BLOCK_MODES]; + + /** @brief The best endpoint format for each partition. */ + uint8_t best_ep_formats[WEIGHTS_MAX_BLOCK_MODES][BLOCK_MAX_PARTITIONS]; + + /** @brief The total bit storage needed for quantized weights for each block mode. */ + int8_t qwt_bitcounts[WEIGHTS_MAX_BLOCK_MODES]; + + /** @brief The cumulative error for quantized weights for each block mode. */ + float qwt_errors[WEIGHTS_MAX_BLOCK_MODES]; + + /** @brief The low weight value in plane 1 for each block mode. */ + float weight_low_value1[WEIGHTS_MAX_BLOCK_MODES]; + + /** @brief The high weight value in plane 1 for each block mode. */ + float weight_high_value1[WEIGHTS_MAX_BLOCK_MODES]; + + /** @brief The low weight value in plane 1 for each quant level and decimation mode. */ + float weight_low_values1[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1]; + + /** @brief The high weight value in plane 1 for each quant level and decimation mode. */ + float weight_high_values1[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1]; + + /** @brief The low weight value in plane 2 for each block mode. */ + float weight_low_value2[WEIGHTS_MAX_BLOCK_MODES]; + + /** @brief The high weight value in plane 2 for each block mode. */ + float weight_high_value2[WEIGHTS_MAX_BLOCK_MODES]; + + /** @brief The low weight value in plane 2 for each quant level and decimation mode. */ + float weight_low_values2[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1]; + + /** @brief The high weight value in plane 2 for each quant level and decimation mode. */ + float weight_high_values2[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1]; +}; + +struct dt_init_working_buffers +{ + uint8_t weight_count_of_texel[BLOCK_MAX_TEXELS]; + uint8_t grid_weights_of_texel[BLOCK_MAX_TEXELS][4]; + uint8_t weights_of_texel[BLOCK_MAX_TEXELS][4]; + + uint8_t texel_count_of_weight[BLOCK_MAX_WEIGHTS]; + uint8_t texels_of_weight[BLOCK_MAX_WEIGHTS][BLOCK_MAX_TEXELS]; + uint8_t texel_weights_of_weight[BLOCK_MAX_WEIGHTS][BLOCK_MAX_TEXELS]; +}; + +/** + * @brief Weight quantization transfer table. + * + * ASTC can store texel weights at many quantization levels, so for performance we store essential + * information about each level as a precomputed data structure. Unquantized weights are integers + * or floats in the range [0, 64]. + * + * This structure provides a table, used to estimate the closest quantized weight for a given + * floating-point weight. For each quantized weight, the corresponding unquantized values. For each + * quantized weight, a previous-value and a next-value. +*/ +struct quant_and_transfer_table +{ + /** @brief The unscrambled unquantized value. */ + int8_t quant_to_unquant[32]; + + /** @brief The scrambling order: scrambled_quant = map[unscrambled_quant]. */ + int8_t scramble_map[32]; + + /** @brief The unscrambling order: unscrambled_unquant = map[scrambled_quant]. */ + int8_t unscramble_and_unquant_map[32]; + + /** + * @brief A table of previous-and-next weights, indexed by the current unquantized value. + * * bits 7:0 = previous-index, unquantized + * * bits 15:8 = next-index, unquantized + */ + uint16_t prev_next_values[65]; +}; + +/** @brief The precomputed quant and transfer table. */ +extern const quant_and_transfer_table quant_and_xfer_tables[12]; + +/** @brief The block is an error block, and will return error color or NaN. */ +static constexpr uint8_t SYM_BTYPE_ERROR { 0 }; + +/** @brief The block is a constant color block using FP16 colors. */ +static constexpr uint8_t SYM_BTYPE_CONST_F16 { 1 }; + +/** @brief The block is a constant color block using UNORM16 colors. */ +static constexpr uint8_t SYM_BTYPE_CONST_U16 { 2 }; + +/** @brief The block is a normal non-constant color block. */ +static constexpr uint8_t SYM_BTYPE_NONCONST { 3 }; + +/** + * @brief A symbolic representation of a compressed block. + * + * The symbolic representation stores the unpacked content of a single + * @c physical_compressed_block, in a form which is much easier to access for + * the rest of the compressor code. + */ +struct symbolic_compressed_block +{ + /** @brief The block type, one of the @c SYM_BTYPE_* constants. */ + uint8_t block_type; + + /** @brief The number of partitions; valid for @c NONCONST blocks. */ + uint8_t partition_count; + + /** @brief Non-zero if the color formats matched; valid for @c NONCONST blocks. */ + uint8_t color_formats_matched; + + /** @brief The plane 2 color component, or -1 if single plane; valid for @c NONCONST blocks. */ + int8_t plane2_component; + + /** @brief The block mode; valid for @c NONCONST blocks. */ + uint16_t block_mode; + + /** @brief The partition index; valid for @c NONCONST blocks if 2 or more partitions. */ + uint16_t partition_index; + + /** @brief The endpoint color formats for each partition; valid for @c NONCONST blocks. */ + uint8_t color_formats[BLOCK_MAX_PARTITIONS]; + + /** @brief The endpoint color quant mode; valid for @c NONCONST blocks. */ + quant_method quant_mode; + + /** @brief The error of the current encoding; valid for @c NONCONST blocks. */ + float errorval; + + // We can't have both of these at the same time + union { + /** @brief The constant color; valid for @c CONST blocks. */ + int constant_color[BLOCK_MAX_COMPONENTS]; + + /** @brief The quantized endpoint color pairs; valid for @c NONCONST blocks. */ + uint8_t color_values[BLOCK_MAX_PARTITIONS][8]; + }; + + /** @brief The quantized and decimated weights. + * + * Weights are stored in the 0-64 unpacked range allowing them to be used + * directly in encoding passes without per-use unpacking. Packing happens + * when converting to/from the physical bitstream encoding. + * + * If dual plane, the second plane starts at @c weights[WEIGHTS_PLANE2_OFFSET]. + */ + uint8_t weights[BLOCK_MAX_WEIGHTS]; + + /** + * @brief Get the weight quantization used by this block mode. + * + * @return The quantization level. + */ + inline quant_method get_color_quant_mode() const + { + return this->quant_mode; + } +}; + +/** + * @brief A physical representation of a compressed block. + * + * The physical representation stores the raw bytes of the format in memory. + */ +struct physical_compressed_block +{ + /** @brief The ASTC encoded data for a single block. */ + uint8_t data[16]; +}; + + +/** + * @brief Parameter structure for @c compute_pixel_region_variance(). + * + * This function takes a structure to avoid spilling arguments to the stack on every function + * invocation, as there are a lot of parameters. + */ +struct pixel_region_args +{ + /** @brief The image to analyze. */ + const astcenc_image* img; + + /** @brief The component swizzle pattern. */ + astcenc_swizzle swz; + + /** @brief Should the algorithm bother with Z axis processing? */ + bool have_z; + + /** @brief The kernel radius for alpha processing. */ + unsigned int alpha_kernel_radius; + + /** @brief The X dimension of the working data to process. */ + unsigned int size_x; + + /** @brief The Y dimension of the working data to process. */ + unsigned int size_y; + + /** @brief The Z dimension of the working data to process. */ + unsigned int size_z; + + /** @brief The X position of first src and dst data in the data set. */ + unsigned int offset_x; + + /** @brief The Y position of first src and dst data in the data set. */ + unsigned int offset_y; + + /** @brief The Z position of first src and dst data in the data set. */ + unsigned int offset_z; + + /** @brief The working memory buffer. */ + vfloat4 *work_memory; +}; + +/** + * @brief Parameter structure for @c compute_averages_proc(). + */ +struct avg_args +{ + /** @brief The arguments for the nested variance computation. */ + pixel_region_args arg; + + /** @brief The image X dimensions. */ + unsigned int img_size_x; + + /** @brief The image Y dimensions. */ + unsigned int img_size_y; + + /** @brief The image Z dimensions. */ + unsigned int img_size_z; + + /** @brief The maximum working block dimensions in X and Y dimensions. */ + unsigned int blk_size_xy; + + /** @brief The maximum working block dimensions in Z dimensions. */ + unsigned int blk_size_z; + + /** @brief The working block memory size. */ + unsigned int work_memory_size; +}; + +#if defined(ASTCENC_DIAGNOSTICS) +/* See astcenc_diagnostic_trace header for details. */ +class TraceLog; +#endif + +/** + * @brief The astcenc compression context. + */ +struct astcenc_contexti +{ + /** @brief The configuration this context was created with. */ + astcenc_config config; + + /** @brief The thread count supported by this context. */ + unsigned int thread_count; + + /** @brief The block size descriptor this context was created with. */ + block_size_descriptor* bsd; + + /* + * Fields below here are not needed in a decompress-only build, but some remain as they are + * small and it avoids littering the code with #ifdefs. The most significant contributors to + * large structure size are omitted. + */ + + /** @brief The input image alpha channel averages table, may be @c nullptr if not needed. */ + float* input_alpha_averages; + + /** @brief The scratch working buffers, one per thread (see @c thread_count). */ + compression_working_buffers* working_buffers; + +#if !defined(ASTCENC_DECOMPRESS_ONLY) + /** @brief The pixel region and variance worker arguments. */ + avg_args avg_preprocess_args; +#endif + +#if defined(ASTCENC_DIAGNOSTICS) + /** + * @brief The diagnostic trace logger. + * + * Note that this is a singleton, so can only be used in single threaded mode. It only exists + * here so we have a reference to close the file at the end of the capture. + */ + TraceLog* trace_log; +#endif +}; + +/* ============================================================================ + Functionality for managing block sizes and partition tables. +============================================================================ */ + +/** + * @brief Populate the block size descriptor for the target block size. + * + * This will also initialize the partition table metadata, which is stored as part of the BSD + * structure. + * + * @param x_texels The number of texels in the block X dimension. + * @param y_texels The number of texels in the block Y dimension. + * @param z_texels The number of texels in the block Z dimension. + * @param can_omit_modes Can we discard modes and partitionings that astcenc won't use? + * @param partition_count_cutoff The partition count cutoff to use, if we can omit partitionings. + * @param mode_cutoff The block mode percentile cutoff [0-1]. + * @param[out] bsd The descriptor to initialize. + */ +void init_block_size_descriptor( + unsigned int x_texels, + unsigned int y_texels, + unsigned int z_texels, + bool can_omit_modes, + unsigned int partition_count_cutoff, + float mode_cutoff, + block_size_descriptor& bsd); + +/** + * @brief Populate the partition tables for the target block size. + * + * Note the @c bsd descriptor must be initialized by calling @c init_block_size_descriptor() before + * calling this function. + * + * @param[out] bsd The block size information structure to populate. + * @param can_omit_partitionings True if we can we drop partitionings that astcenc won't use. + * @param partition_count_cutoff The partition count cutoff to use, if we can omit partitionings. + */ +void init_partition_tables( + block_size_descriptor& bsd, + bool can_omit_partitionings, + unsigned int partition_count_cutoff); + +/** + * @brief Get the percentile table for 2D block modes. + * + * This is an empirically determined prioritization of which block modes to use in the search in + * terms of their centile (lower centiles = more useful). + * + * Returns a dynamically allocated array; caller must free with delete[]. + * + * @param xdim The block x size. + * @param ydim The block y size. + * + * @return The unpacked table. + */ +const float* get_2d_percentile_table( + unsigned int xdim, + unsigned int ydim); + +/** + * @brief Query if a 2D block size is legal. + * + * @return True if legal, false otherwise. + */ +bool is_legal_2d_block_size( + unsigned int xdim, + unsigned int ydim); + +/** + * @brief Query if a 3D block size is legal. + * + * @return True if legal, false otherwise. + */ +bool is_legal_3d_block_size( + unsigned int xdim, + unsigned int ydim, + unsigned int zdim); + +/* ============================================================================ + Functionality for managing BISE quantization and unquantization. +============================================================================ */ + +/** + * @brief The precomputed table for quantizing color values. + * + * Converts unquant value in 0-255 range into quant value in 0-255 range. + * No BISE scrambling is applied at this stage. + * + * Indexed by [quant_mode - 4][data_value]. + */ +extern const uint8_t color_unquant_to_uquant_tables[17][256]; + +/** + * @brief The precomputed table for packing quantized color values. + * + * Converts quant value in 0-255 range into packed quant value in 0-N range, + * with BISE scrambling applied. + * + * Indexed by [quant_mode - 4][data_value]. + */ +extern const uint8_t color_uquant_to_scrambled_pquant_tables[17][256]; + +/** + * @brief The precomputed table for unpacking color values. + * + * Converts quant value in 0-N range into unpacked value in 0-255 range, + * with BISE unscrambling applied. + * + * Indexed by [quant_mode - 4][data_value]. + */ +extern const uint8_t* color_scrambled_pquant_to_uquant_tables[17]; + +/** + * @brief The precomputed quant mode storage table. + * + * Indexing by [integer_count/2][bits] gives us the quantization level for a given integer count and + * number of compressed storage bits. Returns -1 for cases where the requested integer count cannot + * ever fit in the supplied storage size. + */ +extern const int8_t quant_mode_table[10][128]; + +/** + * @brief Encode a packed string using BISE. + * + * Note that BISE can return strings that are not a whole number of bytes in length, and ASTC can + * start storing strings in a block at arbitrary bit offsets in the encoded data. + * + * @param quant_level The BISE alphabet size. + * @param character_count The number of characters in the string. + * @param input_data The unpacked string, one byte per character. + * @param[in,out] output_data The output packed string. + * @param bit_offset The starting offset in the output storage. + */ +void encode_ise( + quant_method quant_level, + unsigned int character_count, + const uint8_t* input_data, + uint8_t* output_data, + unsigned int bit_offset); + +/** + * @brief Decode a packed string using BISE. + * + * Note that BISE input strings are not a whole number of bytes in length, and ASTC can start + * strings at arbitrary bit offsets in the encoded data. + * + * @param quant_level The BISE alphabet size. + * @param character_count The number of characters in the string. + * @param input_data The packed string. + * @param[in,out] output_data The output storage, one byte per character. + * @param bit_offset The starting offset in the output storage. + */ +void decode_ise( + quant_method quant_level, + unsigned int character_count, + const uint8_t* input_data, + uint8_t* output_data, + unsigned int bit_offset); + +/** + * @brief Return the number of bits needed to encode an ISE sequence. + * + * This implementation assumes that the @c quant level is untrusted, given it may come from random + * data being decompressed, so we return an arbitrary unencodable size if that is the case. + * + * @param character_count The number of items in the sequence. + * @param quant_level The desired quantization level. + * + * @return The number of bits needed to encode the BISE string. + */ +unsigned int get_ise_sequence_bitcount( + unsigned int character_count, + quant_method quant_level); + +/* ============================================================================ + Functionality for managing color partitioning. +============================================================================ */ + +/** + * @brief Compute averages and dominant directions for each partition in a 2 component texture. + * + * @param pi The partition info for the current trial. + * @param blk The image block color data to be compressed. + * @param component1 The first component included in the analysis. + * @param component2 The second component included in the analysis. + * @param[out] pm The output partition metrics. + * - Only pi.partition_count array entries actually get initialized. + * - Direction vectors @c pm.dir are not normalized. + */ +void compute_avgs_and_dirs_2_comp( + const partition_info& pi, + const image_block& blk, + unsigned int component1, + unsigned int component2, + partition_metrics pm[BLOCK_MAX_PARTITIONS]); + +/** + * @brief Compute averages and dominant directions for each partition in a 3 component texture. + * + * @param pi The partition info for the current trial. + * @param blk The image block color data to be compressed. + * @param omitted_component The component excluded from the analysis. + * @param[out] pm The output partition metrics. + * - Only pi.partition_count array entries actually get initialized. + * - Direction vectors @c pm.dir are not normalized. + */ +void compute_avgs_and_dirs_3_comp( + const partition_info& pi, + const image_block& blk, + unsigned int omitted_component, + partition_metrics pm[BLOCK_MAX_PARTITIONS]); + +/** + * @brief Compute averages and dominant directions for each partition in a 3 component texture. + * + * This is a specialization of @c compute_avgs_and_dirs_3_comp where the omitted component is + * always alpha, a common case during partition search. + * + * @param pi The partition info for the current trial. + * @param blk The image block color data to be compressed. + * @param[out] pm The output partition metrics. + * - Only pi.partition_count array entries actually get initialized. + * - Direction vectors @c pm.dir are not normalized. + */ +void compute_avgs_and_dirs_3_comp_rgb( + const partition_info& pi, + const image_block& blk, + partition_metrics pm[BLOCK_MAX_PARTITIONS]); + +/** + * @brief Compute averages and dominant directions for each partition in a 4 component texture. + * + * @param pi The partition info for the current trial. + * @param blk The image block color data to be compressed. + * @param[out] pm The output partition metrics. + * - Only pi.partition_count array entries actually get initialized. + * - Direction vectors @c pm.dir are not normalized. + */ +void compute_avgs_and_dirs_4_comp( + const partition_info& pi, + const image_block& blk, + partition_metrics pm[BLOCK_MAX_PARTITIONS]); + +/** + * @brief Compute the RGB error for uncorrelated and same chroma projections. + * + * The output of compute averages and dirs is post processed to define two lines, both of which go + * through the mean-color-value. One line has a direction defined by the dominant direction; this + * is used to assess the error from using an uncorrelated color representation. The other line goes + * through (0,0,0) and is used to assess the error from using an RGBS color representation. + * + * This function computes the squared error when using these two representations. + * + * @param pi The partition info for the current trial. + * @param blk The image block color data to be compressed. + * @param[in,out] plines Processed line inputs, and line length outputs. + * @param[out] uncor_error The cumulative error for using the uncorrelated line. + * @param[out] samec_error The cumulative error for using the same chroma line. + */ +void compute_error_squared_rgb( + const partition_info& pi, + const image_block& blk, + partition_lines3 plines[BLOCK_MAX_PARTITIONS], + float& uncor_error, + float& samec_error); + +/** + * @brief Compute the RGBA error for uncorrelated and same chroma projections. + * + * The output of compute averages and dirs is post processed to define two lines, both of which go + * through the mean-color-value. One line has a direction defined by the dominant direction; this + * is used to assess the error from using an uncorrelated color representation. The other line goes + * through (0,0,0,1) and is used to assess the error from using an RGBS color representation. + * + * This function computes the squared error when using these two representations. + * + * @param pi The partition info for the current trial. + * @param blk The image block color data to be compressed. + * @param uncor_plines Processed uncorrelated partition lines for each partition. + * @param samec_plines Processed same chroma partition lines for each partition. + * @param[out] uncor_lengths The length of each components deviation from the line. + * @param[out] samec_lengths The length of each components deviation from the line. + * @param[out] uncor_error The cumulative error for using the uncorrelated line. + * @param[out] samec_error The cumulative error for using the same chroma line. + */ +void compute_error_squared_rgba( + const partition_info& pi, + const image_block& blk, + const processed_line4 uncor_plines[BLOCK_MAX_PARTITIONS], + const processed_line4 samec_plines[BLOCK_MAX_PARTITIONS], + float uncor_lengths[BLOCK_MAX_PARTITIONS], + float samec_lengths[BLOCK_MAX_PARTITIONS], + float& uncor_error, + float& samec_error); + +/** + * @brief Find the best set of partitions to trial for a given block. + * + * On return the @c best_partitions list will contain the two best partition + * candidates; one assuming data has uncorrelated chroma and one assuming the + * data has correlated chroma. The best candidate is returned first in the list. + * + * @param bsd The block size information. + * @param blk The image block color data to compress. + * @param partition_count The number of partitions in the block. + * @param partition_search_limit The number of candidate partition encodings to trial. + * @param[out] best_partitions The best partition candidates. + * @param requested_candidates The number of requested partitionings. May return fewer if + * candidates are not available. + * + * @return The actual number of candidates returned. + */ +unsigned int find_best_partition_candidates( + const block_size_descriptor& bsd, + const image_block& blk, + unsigned int partition_count, + unsigned int partition_search_limit, + unsigned int best_partitions[TUNE_MAX_PARTITIONING_CANDIDATES], + unsigned int requested_candidates); + +/* ============================================================================ + Functionality for managing images and image related data. +============================================================================ */ + +/** + * @brief Setup computation of regional averages in an image. + * + * This must be done by only a single thread per image, before any thread calls + * @c compute_averages(). + * + * Results are written back into @c img->input_alpha_averages. + * + * @param img The input image data, also holds output data. + * @param alpha_kernel_radius The kernel radius (in pixels) for alpha mods. + * @param swz Input data component swizzle. + * @param[out] ag The average variance arguments to init. + * + * @return The number of tasks in the processing stage. + */ +unsigned int init_compute_averages( + const astcenc_image& img, + unsigned int alpha_kernel_radius, + const astcenc_swizzle& swz, + avg_args& ag); + +/** + * @brief Compute averages for a pixel region. + * + * The routine computes both in a single pass, using a summed-area table to decouple the running + * time from the averaging/variance kernel size. + * + * @param[out] ctx The compressor context storing the output data. + * @param arg The input parameter structure. + */ +void compute_pixel_region_variance( + astcenc_contexti& ctx, + const pixel_region_args& arg); +/** + * @brief Load a single image block from the input image. + * + * @param decode_mode The compression color profile. + * @param img The input image data. + * @param[out] blk The image block to populate. + * @param bsd The block size information. + * @param xpos The block X coordinate in the input image. + * @param ypos The block Y coordinate in the input image. + * @param zpos The block Z coordinate in the input image. + * @param swz The swizzle to apply on load. + */ +void load_image_block( + astcenc_profile decode_mode, + const astcenc_image& img, + image_block& blk, + const block_size_descriptor& bsd, + unsigned int xpos, + unsigned int ypos, + unsigned int zpos, + const astcenc_swizzle& swz); + +/** + * @brief Load a single image block from the input image. + * + * This specialized variant can be used only if the block is 2D LDR U8 data, + * with no swizzle. + * + * @param decode_mode The compression color profile. + * @param img The input image data. + * @param[out] blk The image block to populate. + * @param bsd The block size information. + * @param xpos The block X coordinate in the input image. + * @param ypos The block Y coordinate in the input image. + * @param zpos The block Z coordinate in the input image. + * @param swz The swizzle to apply on load. + */ +void load_image_block_fast_ldr( + astcenc_profile decode_mode, + const astcenc_image& img, + image_block& blk, + const block_size_descriptor& bsd, + unsigned int xpos, + unsigned int ypos, + unsigned int zpos, + const astcenc_swizzle& swz); + +/** + * @brief Store a single image block to the output image. + * + * @param[out] img The output image data. + * @param blk The image block to export. + * @param bsd The block size information. + * @param xpos The block X coordinate in the input image. + * @param ypos The block Y coordinate in the input image. + * @param zpos The block Z coordinate in the input image. + * @param swz The swizzle to apply on store. + */ +void store_image_block( + astcenc_image& img, + const image_block& blk, + const block_size_descriptor& bsd, + unsigned int xpos, + unsigned int ypos, + unsigned int zpos, + const astcenc_swizzle& swz); + +/* ============================================================================ + Functionality for computing endpoint colors and weights for a block. +============================================================================ */ + +/** + * @brief Compute ideal endpoint colors and weights for 1 plane of weights. + * + * The ideal endpoints define a color line for the partition. For each texel the ideal weight + * defines an exact position on the partition color line. We can then use these to assess the error + * introduced by removing and quantizing the weight grid. + * + * @param blk The image block color data to compress. + * @param pi The partition info for the current trial. + * @param[out] ei The endpoint and weight values. + */ +void compute_ideal_colors_and_weights_1plane( + const image_block& blk, + const partition_info& pi, + endpoints_and_weights& ei); + +/** + * @brief Compute ideal endpoint colors and weights for 2 planes of weights. + * + * The ideal endpoints define a color line for the partition. For each texel the ideal weight + * defines an exact position on the partition color line. We can then use these to assess the error + * introduced by removing and quantizing the weight grid. + * + * @param bsd The block size information. + * @param blk The image block color data to compress. + * @param plane2_component The component assigned to plane 2. + * @param[out] ei1 The endpoint and weight values for plane 1. + * @param[out] ei2 The endpoint and weight values for plane 2. + */ +void compute_ideal_colors_and_weights_2planes( + const block_size_descriptor& bsd, + const image_block& blk, + unsigned int plane2_component, + endpoints_and_weights& ei1, + endpoints_and_weights& ei2); + +/** + * @brief Compute the optimal unquantized weights for a decimation table. + * + * After computing ideal weights for the case for a complete weight grid, we we want to compute the + * ideal weights for the case where weights exist only for some texels. We do this with a + * steepest-descent grid solver which works as follows: + * + * First, for each actual weight, perform a weighted averaging of the texels affected by the weight. + * Then, set step size to <some initial value> and attempt one step towards the original ideal + * weight if it helps to reduce error. + * + * @param ei The non-decimated endpoints and weights. + * @param di The selected weight decimation. + * @param[out] dec_weight_ideal_value The ideal values for the decimated weight set. + */ +void compute_ideal_weights_for_decimation( + const endpoints_and_weights& ei, + const decimation_info& di, + float* dec_weight_ideal_value); + +/** + * @brief Compute the optimal quantized weights for a decimation table. + * + * We test the two closest weight indices in the allowed quantization range and keep the weight that + * is the closest match. + * + * @param di The selected weight decimation. + * @param low_bound The lowest weight allowed. + * @param high_bound The highest weight allowed. + * @param dec_weight_ideal_value The ideal weight set. + * @param[out] dec_weight_quant_uvalue The output quantized weight as a float. + * @param[out] dec_weight_uquant The output quantized weight as encoded int. + * @param quant_level The desired weight quant level. + */ +void compute_quantized_weights_for_decimation( + const decimation_info& di, + float low_bound, + float high_bound, + const float* dec_weight_ideal_value, + float* dec_weight_quant_uvalue, + uint8_t* dec_weight_uquant, + quant_method quant_level); + +/** + * @brief Compute the error of a decimated weight set for 1 plane. + * + * After computing ideal weights for the case with one weight per texel, we want to compute the + * error for decimated weight grids where weights are stored at a lower resolution. This function + * computes the error of the reduced grid, compared to the full grid. + * + * @param eai The ideal weights for the full grid. + * @param di The selected weight decimation. + * @param dec_weight_quant_uvalue The quantized weights for the decimated grid. + * + * @return The accumulated error. + */ +float compute_error_of_weight_set_1plane( + const endpoints_and_weights& eai, + const decimation_info& di, + const float* dec_weight_quant_uvalue); + +/** + * @brief Compute the error of a decimated weight set for 2 planes. + * + * After computing ideal weights for the case with one weight per texel, we want to compute the + * error for decimated weight grids where weights are stored at a lower resolution. This function + * computes the error of the reduced grid, compared to the full grid. + * + * @param eai1 The ideal weights for the full grid and plane 1. + * @param eai2 The ideal weights for the full grid and plane 2. + * @param di The selected weight decimation. + * @param dec_weight_quant_uvalue_plane1 The quantized weights for the decimated grid plane 1. + * @param dec_weight_quant_uvalue_plane2 The quantized weights for the decimated grid plane 2. + * + * @return The accumulated error. + */ +float compute_error_of_weight_set_2planes( + const endpoints_and_weights& eai1, + const endpoints_and_weights& eai2, + const decimation_info& di, + const float* dec_weight_quant_uvalue_plane1, + const float* dec_weight_quant_uvalue_plane2); + +/** + * @brief Pack a single pair of color endpoints as effectively as possible. + * + * The user requests a base color endpoint mode in @c format, but the quantizer may choose a + * delta-based representation. It will report back the format variant it actually used. + * + * @param color0 The input unquantized color0 endpoint for absolute endpoint pairs. + * @param color1 The input unquantized color1 endpoint for absolute endpoint pairs. + * @param rgbs_color The input unquantized RGBS variant endpoint for same chroma endpoints. + * @param rgbo_color The input unquantized RGBS variant endpoint for HDR endpoints. + * @param format The desired base format. + * @param[out] output The output storage for the quantized colors/ + * @param quant_level The quantization level requested. + * + * @return The actual endpoint mode used. + */ +uint8_t pack_color_endpoints( + vfloat4 color0, + vfloat4 color1, + vfloat4 rgbs_color, + vfloat4 rgbo_color, + int format, + uint8_t* output, + quant_method quant_level); + +/** + * @brief Unpack a single pair of encoded endpoints. + * + * Endpoints must be unscrambled and converted into the 0-255 range before calling this functions. + * + * @param decode_mode The decode mode (LDR, HDR). + * @param format The color endpoint mode used. + * @param input The raw array of encoded input integers. The length of this array + * depends on @c format; it can be safely assumed to be large enough. + * @param[out] rgb_hdr Is the endpoint using HDR for the RGB channels? + * @param[out] alpha_hdr Is the endpoint using HDR for the A channel? + * @param[out] output0 The output color for endpoint 0. + * @param[out] output1 The output color for endpoint 1. + */ +void unpack_color_endpoints( + astcenc_profile decode_mode, + int format, + const uint8_t* input, + bool& rgb_hdr, + bool& alpha_hdr, + vint4& output0, + vint4& output1); + +/** + * @brief Unpack a set of quantized and decimated weights. + * + * TODO: Can we skip this for non-decimated weights now that the @c scb is + * already storing unquantized weights? + * + * @param bsd The block size information. + * @param scb The symbolic compressed encoding. + * @param di The weight grid decimation table. + * @param is_dual_plane @c true if this is a dual plane block, @c false otherwise. + * @param[out] weights_plane1 The output array for storing the plane 1 weights. + * @param[out] weights_plane2 The output array for storing the plane 2 weights. + */ +void unpack_weights( + const block_size_descriptor& bsd, + const symbolic_compressed_block& scb, + const decimation_info& di, + bool is_dual_plane, + int weights_plane1[BLOCK_MAX_TEXELS], + int weights_plane2[BLOCK_MAX_TEXELS]); + +/** + * @brief Identify, for each mode, which set of color endpoint produces the best result. + * + * Returns the best @c tune_candidate_limit best looking modes, along with the ideal color encoding + * combination for each. The modified quantization level can be used when all formats are the same, + * as this frees up two additional bits of storage. + * + * @param pi The partition info for the current trial. + * @param blk The image block color data to compress. + * @param ep The ideal endpoints. + * @param qwt_bitcounts Bit counts for different quantization methods. + * @param qwt_errors Errors for different quantization methods. + * @param tune_candidate_limit The max number of candidates to return, may be less. + * @param start_block_mode The first block mode to inspect. + * @param end_block_mode The last block mode to inspect. + * @param[out] partition_format_specifiers The best formats per partition. + * @param[out] block_mode The best packed block mode indexes. + * @param[out] quant_level The best color quant level. + * @param[out] quant_level_mod The best color quant level if endpoints are the same. + * @param[out] tmpbuf Preallocated scratch buffers for the compressor. + * + * @return The actual number of candidate matches returned. + */ +unsigned int compute_ideal_endpoint_formats( + const partition_info& pi, + const image_block& blk, + const endpoints& ep, + const int8_t* qwt_bitcounts, + const float* qwt_errors, + unsigned int tune_candidate_limit, + unsigned int start_block_mode, + unsigned int end_block_mode, + uint8_t partition_format_specifiers[TUNE_MAX_TRIAL_CANDIDATES][BLOCK_MAX_PARTITIONS], + int block_mode[TUNE_MAX_TRIAL_CANDIDATES], + quant_method quant_level[TUNE_MAX_TRIAL_CANDIDATES], + quant_method quant_level_mod[TUNE_MAX_TRIAL_CANDIDATES], + compression_working_buffers& tmpbuf); + +/** + * @brief For a given 1 plane weight set recompute the endpoint colors. + * + * As we quantize and decimate weights the optimal endpoint colors may change slightly, so we must + * recompute the ideal colors for a specific weight set. + * + * @param blk The image block color data to compress. + * @param pi The partition info for the current trial. + * @param di The weight grid decimation table. + * @param dec_weights_uquant The quantized weight set. + * @param[in,out] ep The color endpoints (modifed in place). + * @param[out] rgbs_vectors The RGB+scale vectors for LDR blocks. + * @param[out] rgbo_vectors The RGB+offset vectors for HDR blocks. + */ +void recompute_ideal_colors_1plane( + const image_block& blk, + const partition_info& pi, + const decimation_info& di, + const uint8_t* dec_weights_uquant, + endpoints& ep, + vfloat4 rgbs_vectors[BLOCK_MAX_PARTITIONS], + vfloat4 rgbo_vectors[BLOCK_MAX_PARTITIONS]); + +/** + * @brief For a given 2 plane weight set recompute the endpoint colors. + * + * As we quantize and decimate weights the optimal endpoint colors may change slightly, so we must + * recompute the ideal colors for a specific weight set. + * + * @param blk The image block color data to compress. + * @param bsd The block_size descriptor. + * @param di The weight grid decimation table. + * @param dec_weights_uquant_plane1 The quantized weight set for plane 1. + * @param dec_weights_uquant_plane2 The quantized weight set for plane 2. + * @param[in,out] ep The color endpoints (modifed in place). + * @param[out] rgbs_vector The RGB+scale color for LDR blocks. + * @param[out] rgbo_vector The RGB+offset color for HDR blocks. + * @param plane2_component The component assigned to plane 2. + */ +void recompute_ideal_colors_2planes( + const image_block& blk, + const block_size_descriptor& bsd, + const decimation_info& di, + const uint8_t* dec_weights_uquant_plane1, + const uint8_t* dec_weights_uquant_plane2, + endpoints& ep, + vfloat4& rgbs_vector, + vfloat4& rgbo_vector, + int plane2_component); + +/** + * @brief Expand the angular tables needed for the alternative to PCA that we use. + */ +void prepare_angular_tables(); + +/** + * @brief Compute the angular endpoints for one plane for each block mode. + * + * @param only_always Only consider block modes that are always enabled. + * @param bsd The block size descriptor for the current trial. + * @param dec_weight_ideal_value The ideal decimated unquantized weight values. + * @param max_weight_quant The maximum block mode weight quantization allowed. + * @param[out] tmpbuf Preallocated scratch buffers for the compressor. + */ +void compute_angular_endpoints_1plane( + bool only_always, + const block_size_descriptor& bsd, + const float* dec_weight_ideal_value, + unsigned int max_weight_quant, + compression_working_buffers& tmpbuf); + +/** + * @brief Compute the angular endpoints for two planes for each block mode. + * + * @param bsd The block size descriptor for the current trial. + * @param dec_weight_ideal_value The ideal decimated unquantized weight values. + * @param max_weight_quant The maximum block mode weight quantization allowed. + * @param[out] tmpbuf Preallocated scratch buffers for the compressor. + */ +void compute_angular_endpoints_2planes( + const block_size_descriptor& bsd, + const float* dec_weight_ideal_value, + unsigned int max_weight_quant, + compression_working_buffers& tmpbuf); + +/* ============================================================================ + Functionality for high level compression and decompression access. +============================================================================ */ + +/** + * @brief Compress an image block into a physical block. + * + * @param ctx The compressor context and configuration. + * @param blk The image block color data to compress. + * @param[out] pcb The physical compressed block output. + * @param[out] tmpbuf Preallocated scratch buffers for the compressor. + */ +void compress_block( + const astcenc_contexti& ctx, + const image_block& blk, + physical_compressed_block& pcb, + compression_working_buffers& tmpbuf); + +/** + * @brief Decompress a symbolic block in to an image block. + * + * @param decode_mode The decode mode (LDR, HDR, etc). + * @param bsd The block size information. + * @param xpos The X coordinate of the block in the overall image. + * @param ypos The Y coordinate of the block in the overall image. + * @param zpos The Z coordinate of the block in the overall image. + * @param[out] blk The decompressed image block color data. + */ +void decompress_symbolic_block( + astcenc_profile decode_mode, + const block_size_descriptor& bsd, + int xpos, + int ypos, + int zpos, + const symbolic_compressed_block& scb, + image_block& blk); + +/** + * @brief Compute the error between a symbolic block and the original input data. + * + * This function is specialized for 2 plane and 1 partition search. + * + * In RGBM mode this will reject blocks that attempt to encode a zero M value. + * + * @param config The compressor config. + * @param bsd The block size information. + * @param scb The symbolic compressed encoding. + * @param blk The original image block color data. + * + * @return Returns the computed error, or a negative value if the encoding + * should be rejected for any reason. + */ +float compute_symbolic_block_difference_2plane( + const astcenc_config& config, + const block_size_descriptor& bsd, + const symbolic_compressed_block& scb, + const image_block& blk); + +/** + * @brief Compute the error between a symbolic block and the original input data. + * + * This function is specialized for 1 plane and N partition search. + * + * In RGBM mode this will reject blocks that attempt to encode a zero M value. + * + * @param config The compressor config. + * @param bsd The block size information. + * @param scb The symbolic compressed encoding. + * @param blk The original image block color data. + * + * @return Returns the computed error, or a negative value if the encoding + * should be rejected for any reason. + */ +float compute_symbolic_block_difference_1plane( + const astcenc_config& config, + const block_size_descriptor& bsd, + const symbolic_compressed_block& scb, + const image_block& blk); + +/** + * @brief Compute the error between a symbolic block and the original input data. + * + * This function is specialized for 1 plane and 1 partition search. + * + * In RGBM mode this will reject blocks that attempt to encode a zero M value. + * + * @param config The compressor config. + * @param bsd The block size information. + * @param scb The symbolic compressed encoding. + * @param blk The original image block color data. + * + * @return Returns the computed error, or a negative value if the encoding + * should be rejected for any reason. + */ +float compute_symbolic_block_difference_1plane_1partition( + const astcenc_config& config, + const block_size_descriptor& bsd, + const symbolic_compressed_block& scb, + const image_block& blk); + +/** + * @brief Convert a symbolic representation into a binary physical encoding. + * + * It is assumed that the symbolic encoding is valid and encodable, or + * previously flagged as an error block if an error color it to be encoded. + * + * @param bsd The block size information. + * @param scb The symbolic representation. + * @param[out] pcb The binary encoded data. + */ +void symbolic_to_physical( + const block_size_descriptor& bsd, + const symbolic_compressed_block& scb, + physical_compressed_block& pcb); + +/** + * @brief Convert a binary physical encoding into a symbolic representation. + * + * This function can cope with arbitrary input data; output blocks will be + * flagged as an error block if the encoding is invalid. + * + * @param bsd The block size information. + * @param pcb The binary encoded data. + * @param[out] scb The output symbolic representation. + */ +void physical_to_symbolic( + const block_size_descriptor& bsd, + const physical_compressed_block& pcb, + symbolic_compressed_block& scb); + +/* ============================================================================ +Platform-specific functions. +============================================================================ */ +/** + * @brief Run-time detection if the host CPU supports the POPCNT extension. + * + * @return @c true if supported, @c false if not. + */ +bool cpu_supports_popcnt(); + +/** + * @brief Run-time detection if the host CPU supports F16C extension. + * + * @return @c true if supported, @c false if not. + */ +bool cpu_supports_f16c(); + +/** + * @brief Run-time detection if the host CPU supports SSE 4.1 extension. + * + * @return @c true if supported, @c false if not. + */ +bool cpu_supports_sse41(); + +/** + * @brief Run-time detection if the host CPU supports AVX 2 extension. + * + * @return @c true if supported, @c false if not. + */ +bool cpu_supports_avx2(); + +/** + * @brief Allocate an aligned memory buffer. + * + * Allocated memory must be freed by aligned_free; + * + * @param size The desired buffer size. + * @param align The desired buffer alignment; must be 2^N. + * + * @return The memory buffer pointer or nullptr on allocation failure. + */ +template<typename T> +T* aligned_malloc(size_t size, size_t align) +{ + void* ptr; + int error = 0; + +#if defined(_WIN32) + ptr = _aligned_malloc(size, align); +#else + error = posix_memalign(&ptr, align, size); +#endif + + if (error || (!ptr)) + { + return nullptr; + } + + return static_cast<T*>(ptr); +} + +/** + * @brief Free an aligned memory buffer. + * + * @param ptr The buffer to free. + */ +template<typename T> +void aligned_free(T* ptr) +{ +#if defined(_WIN32) + _aligned_free(reinterpret_cast<void*>(ptr)); +#else + free(reinterpret_cast<void*>(ptr)); +#endif +} + +#endif diff --git a/thirdparty/astcenc/astcenc_internal_entry.h b/thirdparty/astcenc/astcenc_internal_entry.h new file mode 100644 index 0000000000..4e8794547a --- /dev/null +++ b/thirdparty/astcenc/astcenc_internal_entry.h @@ -0,0 +1,273 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2022 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief Functions and data declarations for the outer context. + * + * The outer context includes thread-pool management, which is slower to + * compile due to increased use of C++ stdlib. The inner context used in the + * majority of the codec library does not include this. + */ + +#ifndef ASTCENC_INTERNAL_ENTRY_INCLUDED +#define ASTCENC_INTERNAL_ENTRY_INCLUDED + +#include <atomic> +#include <condition_variable> +#include <functional> +#include <mutex> + +#include "astcenc_internal.h" + +/* ============================================================================ + Parallel execution control +============================================================================ */ + +/** + * @brief A simple counter-based manager for parallel task execution. + * + * The task processing execution consists of: + * + * * A single-threaded init stage. + * * A multi-threaded processing stage. + * * A condition variable so threads can wait for processing completion. + * + * The init stage will be executed by the first thread to arrive in the critical section, there is + * no main thread in the thread pool. + * + * The processing stage uses dynamic dispatch to assign task tickets to threads on an on-demand + * basis. Threads may each therefore executed different numbers of tasks, depending on their + * processing complexity. The task queue and the task tickets are just counters; the caller must map + * these integers to an actual processing partition in a specific problem domain. + * + * The exit wait condition is needed to ensure processing has finished before a worker thread can + * progress to the next stage of the pipeline. Specifically a worker may exit the processing stage + * because there are no new tasks to assign to it while other worker threads are still processing. + * Calling @c wait() will ensure that all other worker have finished before the thread can proceed. + * + * The basic usage model: + * + * // --------- From single-threaded code --------- + * + * // Reset the tracker state + * manager->reset() + * + * // --------- From multi-threaded code --------- + * + * // Run the stage init; only first thread actually runs the lambda + * manager->init(<lambda>) + * + * do + * { + * // Request a task assignment + * uint task_count; + * uint base_index = manager->get_tasks(<granule>, task_count); + * + * // Process any tasks we were given (task_count <= granule size) + * if (task_count) + * { + * // Run the user task processing code for N tasks here + * ... + * + * // Flag these tasks as complete + * manager->complete_tasks(task_count); + * } + * } while (task_count); + * + * // Wait for all threads to complete tasks before progressing + * manager->wait() + * + * // Run the stage term; only first thread actually runs the lambda + * manager->term(<lambda>) + */ +class ParallelManager +{ +private: + /** @brief Lock used for critical section and condition synchronization. */ + std::mutex m_lock; + + /** @brief True if the stage init() step has been executed. */ + bool m_init_done; + + /** @brief True if the stage term() step has been executed. */ + bool m_term_done; + + /** @brief Condition variable for tracking stage processing completion. */ + std::condition_variable m_complete; + + /** @brief Number of tasks started, but not necessarily finished. */ + std::atomic<unsigned int> m_start_count; + + /** @brief Number of tasks finished. */ + unsigned int m_done_count; + + /** @brief Number of tasks that need to be processed. */ + unsigned int m_task_count; + +public: + /** @brief Create a new ParallelManager. */ + ParallelManager() + { + reset(); + } + + /** + * @brief Reset the tracker for a new processing batch. + * + * This must be called from single-threaded code before starting the multi-threaded processing + * operations. + */ + void reset() + { + m_init_done = false; + m_term_done = false; + m_start_count = 0; + m_done_count = 0; + m_task_count = 0; + } + + /** + * @brief Trigger the pipeline stage init step. + * + * This can be called from multi-threaded code. The first thread to hit this will process the + * initialization. Other threads will block and wait for it to complete. + * + * @param init_func Callable which executes the stage initialization. It must return the + * total number of tasks in the stage. + */ + void init(std::function<unsigned int(void)> init_func) + { + std::lock_guard<std::mutex> lck(m_lock); + if (!m_init_done) + { + m_task_count = init_func(); + m_init_done = true; + } + } + + /** + * @brief Trigger the pipeline stage init step. + * + * This can be called from multi-threaded code. The first thread to hit this will process the + * initialization. Other threads will block and wait for it to complete. + * + * @param task_count Total number of tasks needing processing. + */ + void init(unsigned int task_count) + { + std::lock_guard<std::mutex> lck(m_lock); + if (!m_init_done) + { + m_task_count = task_count; + m_init_done = true; + } + } + + /** + * @brief Request a task assignment. + * + * Assign up to @c granule tasks to the caller for processing. + * + * @param granule Maximum number of tasks that can be assigned. + * @param[out] count Actual number of tasks assigned, or zero if no tasks were assigned. + * + * @return Task index of the first assigned task; assigned tasks increment from this. + */ + unsigned int get_task_assignment(unsigned int granule, unsigned int& count) + { + unsigned int base = m_start_count.fetch_add(granule, std::memory_order_relaxed); + if (base >= m_task_count) + { + count = 0; + return 0; + } + + count = astc::min(m_task_count - base, granule); + return base; + } + + /** + * @brief Complete a task assignment. + * + * Mark @c count tasks as complete. This will notify all threads blocked on @c wait() if this + * completes the processing of the stage. + * + * @param count The number of completed tasks. + */ + void complete_task_assignment(unsigned int count) + { + // Note: m_done_count cannot use an atomic without the mutex; this has a race between the + // update here and the wait() for other threads + std::unique_lock<std::mutex> lck(m_lock); + this->m_done_count += count; + if (m_done_count == m_task_count) + { + lck.unlock(); + m_complete.notify_all(); + } + } + + /** + * @brief Wait for stage processing to complete. + */ + void wait() + { + std::unique_lock<std::mutex> lck(m_lock); + m_complete.wait(lck, [this]{ return m_done_count == m_task_count; }); + } + + /** + * @brief Trigger the pipeline stage term step. + * + * This can be called from multi-threaded code. The first thread to hit this will process the + * work pool termination. Caller must have called @c wait() prior to calling this function to + * ensure that processing is complete. + * + * @param term_func Callable which executes the stage termination. + */ + void term(std::function<void(void)> term_func) + { + std::lock_guard<std::mutex> lck(m_lock); + if (!m_term_done) + { + term_func(); + m_term_done = true; + } + } +}; + +/** + * @brief The astcenc compression context. + */ +struct astcenc_context +{ + /** @brief The context internal state. */ + astcenc_contexti context; + +#if !defined(ASTCENC_DECOMPRESS_ONLY) + /** @brief The parallel manager for averages computation. */ + ParallelManager manage_avg; + + /** @brief The parallel manager for compression. */ + ParallelManager manage_compress; +#endif + + /** @brief The parallel manager for decompression. */ + ParallelManager manage_decompress; +}; + +#endif diff --git a/thirdparty/astcenc/astcenc_mathlib.cpp b/thirdparty/astcenc/astcenc_mathlib.cpp new file mode 100644 index 0000000000..f276ac7e3d --- /dev/null +++ b/thirdparty/astcenc/astcenc_mathlib.cpp @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2021 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +#include "astcenc_mathlib.h" + +/** + * @brief 64-bit rotate left. + * + * @param val The value to rotate. + * @param count The rotation, in bits. + */ +static inline uint64_t rotl(uint64_t val, int count) +{ + return (val << count) | (val >> (64 - count)); +} + +/* See header for documentation. */ +void astc::rand_init(uint64_t state[2]) +{ + state[0] = 0xfaf9e171cea1ec6bULL; + state[1] = 0xf1b318cc06af5d71ULL; +} + +/* See header for documentation. */ +uint64_t astc::rand(uint64_t state[2]) +{ + uint64_t s0 = state[0]; + uint64_t s1 = state[1]; + uint64_t res = s0 + s1; + s1 ^= s0; + state[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); + state[1] = rotl(s1, 37); + return res; +} diff --git a/thirdparty/astcenc/astcenc_mathlib.h b/thirdparty/astcenc/astcenc_mathlib.h new file mode 100644 index 0000000000..0540c4fedd --- /dev/null +++ b/thirdparty/astcenc/astcenc_mathlib.h @@ -0,0 +1,476 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2021 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/* + * This module implements a variety of mathematical data types and library + * functions used by the codec. + */ + +#ifndef ASTC_MATHLIB_H_INCLUDED +#define ASTC_MATHLIB_H_INCLUDED + +#include <cassert> +#include <cstdint> +#include <cmath> + +#ifndef ASTCENC_POPCNT + #if defined(__POPCNT__) + #define ASTCENC_POPCNT 1 + #else + #define ASTCENC_POPCNT 0 + #endif +#endif + +#ifndef ASTCENC_F16C + #if defined(__F16C__) + #define ASTCENC_F16C 1 + #else + #define ASTCENC_F16C 0 + #endif +#endif + +#ifndef ASTCENC_SSE + #if defined(__SSE4_2__) + #define ASTCENC_SSE 42 + #elif defined(__SSE4_1__) + #define ASTCENC_SSE 41 + #elif defined(__SSE2__) + #define ASTCENC_SSE 20 + #else + #define ASTCENC_SSE 0 + #endif +#endif + +#ifndef ASTCENC_AVX + #if defined(__AVX2__) + #define ASTCENC_AVX 2 + #elif defined(__AVX__) + #define ASTCENC_AVX 1 + #else + #define ASTCENC_AVX 0 + #endif +#endif + +#ifndef ASTCENC_NEON + #if defined(__aarch64__) + #define ASTCENC_NEON 1 + #else + #define ASTCENC_NEON 0 + #endif +#endif + +#if ASTCENC_AVX + #define ASTCENC_VECALIGN 32 +#else + #define ASTCENC_VECALIGN 16 +#endif + +#if ASTCENC_SSE != 0 || ASTCENC_AVX != 0 || ASTCENC_POPCNT != 0 + #include <immintrin.h> +#endif + +/* ============================================================================ + Fast math library; note that many of the higher-order functions in this set + use approximations which are less accurate, but faster, than <cmath> standard + library equivalents. + + Note: Many of these are not necessarily faster than simple C versions when + used on a single scalar value, but are included for testing purposes as most + have an option based on SSE intrinsics and therefore provide an obvious route + to future vectorization. +============================================================================ */ + +// Union for manipulation of float bit patterns +typedef union +{ + uint32_t u; + int32_t s; + float f; +} if32; + +// These are namespaced to avoid colliding with C standard library functions. +namespace astc +{ + +static const float PI = 3.14159265358979323846f; +static const float PI_OVER_TWO = 1.57079632679489661923f; + +/** + * @brief SP float absolute value. + * + * @param v The value to make absolute. + * + * @return The absolute value. + */ +static inline float fabs(float v) +{ + return std::fabs(v); +} + +/** + * @brief Test if a float value is a nan. + * + * @param v The value test. + * + * @return Zero is not a NaN, non-zero otherwise. + */ +static inline bool isnan(float v) +{ + return v != v; +} + +/** + * @brief Return the minimum of two values. + * + * For floats, NaNs are turned into @c q. + * + * @param p The first value to compare. + * @param q The second value to compare. + * + * @return The smallest value. + */ +template<typename T> +static inline T min(T p, T q) +{ + return p < q ? p : q; +} + +/** + * @brief Return the minimum of three values. + * + * For floats, NaNs are turned into @c r. + * + * @param p The first value to compare. + * @param q The second value to compare. + * @param r The third value to compare. + * + * @return The smallest value. + */ +template<typename T> +static inline T min(T p, T q, T r) +{ + return min(min(p, q), r); +} + +/** + * @brief Return the minimum of four values. + * + * For floats, NaNs are turned into @c s. + * + * @param p The first value to compare. + * @param q The second value to compare. + * @param r The third value to compare. + * @param s The fourth value to compare. + * + * @return The smallest value. + */ +template<typename T> +static inline T min(T p, T q, T r, T s) +{ + return min(min(p, q), min(r, s)); +} + +/** + * @brief Return the maximum of two values. + * + * For floats, NaNs are turned into @c q. + * + * @param p The first value to compare. + * @param q The second value to compare. + * + * @return The largest value. + */ +template<typename T> +static inline T max(T p, T q) +{ + return p > q ? p : q; +} + +/** + * @brief Return the maximum of three values. + * + * For floats, NaNs are turned into @c r. + * + * @param p The first value to compare. + * @param q The second value to compare. + * @param r The third value to compare. + * + * @return The largest value. + */ +template<typename T> +static inline T max(T p, T q, T r) +{ + return max(max(p, q), r); +} + +/** + * @brief Return the maximum of four values. + * + * For floats, NaNs are turned into @c s. + * + * @param p The first value to compare. + * @param q The second value to compare. + * @param r The third value to compare. + * @param s The fourth value to compare. + * + * @return The largest value. + */ +template<typename T> +static inline T max(T p, T q, T r, T s) +{ + return max(max(p, q), max(r, s)); +} + +/** + * @brief Clamp a value value between @c mn and @c mx. + * + * For floats, NaNs are turned into @c mn. + * + * @param v The value to clamp. + * @param mn The min value (inclusive). + * @param mx The max value (inclusive). + * + * @return The clamped value. + */ +template<typename T> +inline T clamp(T v, T mn, T mx) +{ + // Do not reorder; correct NaN handling relies on the fact that comparison + // with NaN returns false and will fall-though to the "min" value. + if (v > mx) return mx; + if (v > mn) return v; + return mn; +} + +/** + * @brief Clamp a float value between 0.0f and 1.0f. + * + * NaNs are turned into 0.0f. + * + * @param v The value to clamp. + * + * @return The clamped value. + */ +static inline float clamp1f(float v) +{ + return astc::clamp(v, 0.0f, 1.0f); +} + +/** + * @brief Clamp a float value between 0.0f and 255.0f. + * + * NaNs are turned into 0.0f. + * + * @param v The value to clamp. + * + * @return The clamped value. + */ +static inline float clamp255f(float v) +{ + return astc::clamp(v, 0.0f, 255.0f); +} + +/** + * @brief SP float round-down. + * + * @param v The value to round. + * + * @return The rounded value. + */ +static inline float flt_rd(float v) +{ + return std::floor(v); +} + +/** + * @brief SP float round-to-nearest and convert to integer. + * + * @param v The value to round. + * + * @return The rounded value. + */ +static inline int flt2int_rtn(float v) +{ + + return static_cast<int>(v + 0.5f); +} + +/** + * @brief SP float round down and convert to integer. + * + * @param v The value to round. + * + * @return The rounded value. + */ +static inline int flt2int_rd(float v) +{ + return static_cast<int>(v); +} + +/** + * @brief SP float bit-interpreted as an integer. + * + * @param v The value to bitcast. + * + * @return The converted value. + */ +static inline int float_as_int(float v) +{ + union { int a; float b; } u; + u.b = v; + return u.a; +} + +/** + * @brief Integer bit-interpreted as an SP float. + * + * @param v The value to bitcast. + * + * @return The converted value. + */ +static inline float int_as_float(int v) +{ + union { int a; float b; } u; + u.a = v; + return u.b; +} + +/** + * @brief Fast approximation of 1.0 / sqrt(val). + * + * @param v The input value. + * + * @return The approximated result. + */ +static inline float rsqrt(float v) +{ + return 1.0f / std::sqrt(v); +} + +/** + * @brief Fast approximation of sqrt(val). + * + * @param v The input value. + * + * @return The approximated result. + */ +static inline float sqrt(float v) +{ + return std::sqrt(v); +} + +/** + * @brief Extract mantissa and exponent of a float value. + * + * @param v The input value. + * @param[out] expo The output exponent. + * + * @return The mantissa. + */ +static inline float frexp(float v, int* expo) +{ + if32 p; + p.f = v; + *expo = ((p.u >> 23) & 0xFF) - 126; + p.u = (p.u & 0x807fffff) | 0x3f000000; + return p.f; +} + +/** + * @brief Initialize the seed structure for a random number generator. + * + * Important note: For the purposes of ASTC we want sets of random numbers to + * use the codec, but we want the same seed value across instances and threads + * to ensure that image output is stable across compressor runs and across + * platforms. Every PRNG created by this call will therefore return the same + * sequence of values ... + * + * @param state The state structure to initialize. + */ +void rand_init(uint64_t state[2]); + +/** + * @brief Return the next random number from the generator. + * + * This RNG is an implementation of the "xoroshoro-128+ 1.0" PRNG, based on the + * public-domain implementation given by David Blackman & Sebastiano Vigna at + * http://vigna.di.unimi.it/xorshift/xoroshiro128plus.c + * + * @param state The state structure to use/update. + */ +uint64_t rand(uint64_t state[2]); + +} + +/* ============================================================================ + Softfloat library with fp32 and fp16 conversion functionality. +============================================================================ */ +#if (ASTCENC_F16C == 0) && (ASTCENC_NEON == 0) + /* narrowing float->float conversions */ + uint16_t float_to_sf16(float val); + float sf16_to_float(uint16_t val); +#endif + +/********************************* + Vector library +*********************************/ +#include "astcenc_vecmathlib.h" + +/********************************* + Declaration of line types +*********************************/ +// parametric line, 2D: The line is given by line = a + b * t. + +struct line2 +{ + vfloat4 a; + vfloat4 b; +}; + +// parametric line, 3D +struct line3 +{ + vfloat4 a; + vfloat4 b; +}; + +struct line4 +{ + vfloat4 a; + vfloat4 b; +}; + + +struct processed_line2 +{ + vfloat4 amod; + vfloat4 bs; +}; + +struct processed_line3 +{ + vfloat4 amod; + vfloat4 bs; +}; + +struct processed_line4 +{ + vfloat4 amod; + vfloat4 bs; +}; + +#endif diff --git a/thirdparty/astcenc/astcenc_mathlib_softfloat.cpp b/thirdparty/astcenc/astcenc_mathlib_softfloat.cpp new file mode 100644 index 0000000000..42db764549 --- /dev/null +++ b/thirdparty/astcenc/astcenc_mathlib_softfloat.cpp @@ -0,0 +1,411 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2021 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief Soft-float library for IEEE-754. + */ +#if (ASTCENC_F16C == 0) && (ASTCENC_NEON == 0) + +#include "astcenc_mathlib.h" + +/* sized soft-float types. These are mapped to the sized integer + types of C99, instead of C's floating-point types; this is because + the library needs to maintain exact, bit-level control on all + operations on these data types. */ +typedef uint16_t sf16; +typedef uint32_t sf32; + +/****************************************** + helper functions and their lookup tables + ******************************************/ +/* count leading zeros functions. Only used when the input is nonzero. */ + +#if defined(__GNUC__) && (defined(__i386) || defined(__amd64)) +#elif defined(__arm__) && defined(__ARMCC_VERSION) +#elif defined(__arm__) && defined(__GNUC__) +#else + /* table used for the slow default versions. */ + static const uint8_t clz_table[256] = + { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 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, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; +#endif + +/* + 32-bit count-leading-zeros function: use the Assembly instruction whenever possible. */ +static uint32_t clz32(uint32_t inp) +{ + #if defined(__GNUC__) && (defined(__i386) || defined(__amd64)) + uint32_t bsr; + __asm__("bsrl %1, %0": "=r"(bsr):"r"(inp | 1)); + return 31 - bsr; + #else + #if defined(__arm__) && defined(__ARMCC_VERSION) + return __clz(inp); /* armcc builtin */ + #else + #if defined(__arm__) && defined(__GNUC__) + uint32_t lz; + __asm__("clz %0, %1": "=r"(lz):"r"(inp)); + return lz; + #else + /* slow default version */ + uint32_t summa = 24; + if (inp >= UINT32_C(0x10000)) + { + inp >>= 16; + summa -= 16; + } + if (inp >= UINT32_C(0x100)) + { + inp >>= 8; + summa -= 8; + } + return summa + clz_table[inp]; + #endif + #endif + #endif +} + +/* the five rounding modes that IEEE-754r defines */ +typedef enum +{ + SF_UP = 0, /* round towards positive infinity */ + SF_DOWN = 1, /* round towards negative infinity */ + SF_TOZERO = 2, /* round towards zero */ + SF_NEARESTEVEN = 3, /* round toward nearest value; if mid-between, round to even value */ + SF_NEARESTAWAY = 4 /* round toward nearest value; if mid-between, round away from zero */ +} roundmode; + + +static uint32_t rtne_shift32(uint32_t inp, uint32_t shamt) +{ + uint32_t vl1 = UINT32_C(1) << shamt; + uint32_t inp2 = inp + (vl1 >> 1); /* added 0.5 ULP */ + uint32_t msk = (inp | UINT32_C(1)) & vl1; /* nonzero if odd. '| 1' forces it to 1 if the shamt is 0. */ + msk--; /* negative if even, nonnegative if odd. */ + inp2 -= (msk >> 31); /* subtract epsilon before shift if even. */ + inp2 >>= shamt; + return inp2; +} + +static uint32_t rtna_shift32(uint32_t inp, uint32_t shamt) +{ + uint32_t vl1 = (UINT32_C(1) << shamt) >> 1; + inp += vl1; + inp >>= shamt; + return inp; +} + +static uint32_t rtup_shift32(uint32_t inp, uint32_t shamt) +{ + uint32_t vl1 = UINT32_C(1) << shamt; + inp += vl1; + inp--; + inp >>= shamt; + return inp; +} + +/* convert from FP16 to FP32. */ +static sf32 sf16_to_sf32(sf16 inp) +{ + uint32_t inpx = inp; + + /* + This table contains, for every FP16 sign/exponent value combination, + the difference between the input FP16 value and the value obtained + by shifting the correct FP32 result right by 13 bits. + This table allows us to handle every case except denormals and NaN + with just 1 table lookup, 2 shifts and 1 add. + */ + + #define WITH_MSB(a) (UINT32_C(a) | (1u << 31)) + static const uint32_t tbl[64] = + { + WITH_MSB(0x00000), 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, + 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, + 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, + 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, WITH_MSB(0x38000), + WITH_MSB(0x38000), 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, + 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, + 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, + 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, WITH_MSB(0x70000) + }; + + uint32_t res = tbl[inpx >> 10]; + res += inpx; + + /* Normal cases: MSB of 'res' not set. */ + if ((res & WITH_MSB(0)) == 0) + { + return res << 13; + } + + /* Infinity and Zero: 10 LSB of 'res' not set. */ + if ((res & 0x3FF) == 0) + { + return res << 13; + } + + /* NaN: the exponent field of 'inp' is non-zero. */ + if ((inpx & 0x7C00) != 0) + { + /* All NaNs are quietened. */ + return (res << 13) | 0x400000; + } + + /* Denormal cases */ + uint32_t sign = (inpx & 0x8000) << 16; + uint32_t mskval = inpx & 0x7FFF; + uint32_t leadingzeroes = clz32(mskval); + mskval <<= leadingzeroes; + return (mskval >> 8) + ((0x85 - leadingzeroes) << 23) + sign; +} + +/* Conversion routine that converts from FP32 to FP16. It supports denormals and all rounding modes. If a NaN is given as input, it is quietened. */ +static sf16 sf32_to_sf16(sf32 inp, roundmode rmode) +{ + /* for each possible sign/exponent combination, store a case index. This gives a 512-byte table */ + static const uint8_t tab[512] { + 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 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, 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, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 50, + + 5, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 55, + }; + + /* many of the cases below use a case-dependent magic constant. So we look up a magic constant before actually performing the switch. This table allows us to group cases, thereby minimizing code + size. */ + static const uint32_t tabx[60] { + UINT32_C(0), UINT32_C(0), UINT32_C(0), UINT32_C(0), UINT32_C(0), UINT32_C(0x8000), UINT32_C(0x80000000), UINT32_C(0x8000), UINT32_C(0x8000), UINT32_C(0x8000), + UINT32_C(1), UINT32_C(0), UINT32_C(0), UINT32_C(0), UINT32_C(0), UINT32_C(0x8000), UINT32_C(0x8001), UINT32_C(0x8000), UINT32_C(0x8000), UINT32_C(0x8000), + UINT32_C(0), UINT32_C(0), UINT32_C(0), UINT32_C(0), UINT32_C(0), UINT32_C(0x8000), UINT32_C(0x8000), UINT32_C(0x8000), UINT32_C(0x8000), UINT32_C(0x8000), + UINT32_C(0xC8001FFF), UINT32_C(0xC8000000), UINT32_C(0xC8000000), UINT32_C(0xC8000FFF), UINT32_C(0xC8001000), + UINT32_C(0x58000000), UINT32_C(0x38001FFF), UINT32_C(0x58000000), UINT32_C(0x58000FFF), UINT32_C(0x58001000), + UINT32_C(0x7C00), UINT32_C(0x7BFF), UINT32_C(0x7BFF), UINT32_C(0x7C00), UINT32_C(0x7C00), + UINT32_C(0xFBFF), UINT32_C(0xFC00), UINT32_C(0xFBFF), UINT32_C(0xFC00), UINT32_C(0xFC00), + UINT32_C(0x90000000), UINT32_C(0x90000000), UINT32_C(0x90000000), UINT32_C(0x90000000), UINT32_C(0x90000000), + UINT32_C(0x20000000), UINT32_C(0x20000000), UINT32_C(0x20000000), UINT32_C(0x20000000), UINT32_C(0x20000000) + }; + + uint32_t p; + uint32_t idx = rmode + tab[inp >> 23]; + uint32_t vlx = tabx[idx]; + switch (idx) + { + /* + Positive number which may be Infinity or NaN. + We need to check whether it is NaN; if it is, quieten it by setting the top bit of the mantissa. + (If we don't do this quieting, then a NaN that is distinguished only by having + its low-order bits set, would be turned into an INF. */ + case 50: + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + case 58: + case 59: + /* + the input value is 0x7F800000 or 0xFF800000 if it is INF. + By subtracting 1, we get 7F7FFFFF or FF7FFFFF, that is, bit 23 becomes zero. + For NaNs, however, this operation will keep bit 23 with the value 1. + We can then extract bit 23, and logical-OR bit 9 of the result with this + bit in order to quieten the NaN (a Quiet NaN is a NaN where the top bit + of the mantissa is set.) + */ + p = (inp - 1) & UINT32_C(0x800000); /* zero if INF, nonzero if NaN. */ + return static_cast<sf16>(((inp + vlx) >> 13) | (p >> 14)); + /* + positive, exponent = 0, round-mode == UP; need to check whether number actually is 0. + If it is, then return 0, else return 1 (the smallest representable nonzero number) + */ + case 0: + /* + -inp will set the MSB if the input number is nonzero. + Thus (-inp) >> 31 will turn into 0 if the input number is 0 and 1 otherwise. + */ + return static_cast<sf16>(static_cast<uint32_t>((-static_cast<int32_t>(inp))) >> 31); + + /* + negative, exponent = , round-mode == DOWN, need to check whether number is + actually 0. If it is, return 0x8000 ( float -0.0 ) + Else return the smallest negative number ( 0x8001 ) */ + case 6: + /* + in this case 'vlx' is 0x80000000. By subtracting the input value from it, + we obtain a value that is 0 if the input value is in fact zero and has + the MSB set if it isn't. We then right-shift the value by 31 places to + get a value that is 0 if the input is -0.0 and 1 otherwise. + */ + return static_cast<sf16>(((vlx - inp) >> 31) + UINT32_C(0x8000)); + + /* + for all other cases involving underflow/overflow, we don't need to + do actual tests; we just return 'vlx'. + */ + case 1: + case 2: + case 3: + case 4: + case 5: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 40: + case 41: + case 42: + case 43: + case 44: + case 45: + case 46: + case 47: + case 48: + case 49: + return static_cast<sf16>(vlx); + + /* + for normal numbers, 'vlx' is the difference between the FP32 value of a number and the + FP16 representation of the same number left-shifted by 13 places. In addition, a rounding constant is + baked into 'vlx': for rounding-away-from zero, the constant is 2^13 - 1, causing roundoff away + from zero. for round-to-nearest away, the constant is 2^12, causing roundoff away from zero. + for round-to-nearest-even, the constant is 2^12 - 1. This causes correct round-to-nearest-even + except for odd input numbers. For odd input numbers, we need to add 1 to the constant. */ + + /* normal number, all rounding modes except round-to-nearest-even: */ + case 30: + case 31: + case 32: + case 34: + case 35: + case 36: + case 37: + case 39: + return static_cast<sf16>((inp + vlx) >> 13); + + /* normal number, round-to-nearest-even. */ + case 33: + case 38: + p = inp + vlx; + p += (inp >> 13) & 1; + return static_cast<sf16>(p >> 13); + + /* + the various denormal cases. These are not expected to be common, so their performance is a bit + less important. For each of these cases, we need to extract an exponent and a mantissa + (including the implicit '1'!), and then right-shift the mantissa by a shift-amount that + depends on the exponent. The shift must apply the correct rounding mode. 'vlx' is used to supply the + sign of the resulting denormal number. + */ + case 21: + case 22: + case 25: + case 27: + /* denormal, round towards zero. */ + p = 126 - ((inp >> 23) & 0xFF); + return static_cast<sf16>((((inp & UINT32_C(0x7FFFFF)) + UINT32_C(0x800000)) >> p) | vlx); + case 20: + case 26: + /* denormal, round away from zero. */ + p = 126 - ((inp >> 23) & 0xFF); + return static_cast<sf16>(rtup_shift32((inp & UINT32_C(0x7FFFFF)) + UINT32_C(0x800000), p) | vlx); + case 24: + case 29: + /* denormal, round to nearest-away */ + p = 126 - ((inp >> 23) & 0xFF); + return static_cast<sf16>(rtna_shift32((inp & UINT32_C(0x7FFFFF)) + UINT32_C(0x800000), p) | vlx); + case 23: + case 28: + /* denormal, round to nearest-even. */ + p = 126 - ((inp >> 23) & 0xFF); + return static_cast<sf16>(rtne_shift32((inp & UINT32_C(0x7FFFFF)) + UINT32_C(0x800000), p) | vlx); + } + + return 0; +} + +/* convert from soft-float to native-float */ +float sf16_to_float(uint16_t p) +{ + if32 i; + i.u = sf16_to_sf32(p); + return i.f; +} + +/* convert from native-float to soft-float */ +uint16_t float_to_sf16(float p) +{ + if32 i; + i.f = p; + return sf32_to_sf16(i.u, SF_NEARESTEVEN); +} + +#endif diff --git a/thirdparty/astcenc/astcenc_partition_tables.cpp b/thirdparty/astcenc/astcenc_partition_tables.cpp new file mode 100644 index 0000000000..cad42384d7 --- /dev/null +++ b/thirdparty/astcenc/astcenc_partition_tables.cpp @@ -0,0 +1,481 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2023 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief Functions for generating partition tables on demand. + */ + +#include "astcenc_internal.h" + +/** @brief The number of 64-bit words needed to represent a canonical partition bit pattern. */ +#define BIT_PATTERN_WORDS (((ASTCENC_BLOCK_MAX_TEXELS * 2) + 63) / 64) + +/** + * @brief Generate a canonical representation of a partition pattern. + * + * The returned value stores two bits per texel, for up to 6x6x6 texels, where the two bits store + * the remapped texel index. Remapping ensures that we only match on the partition pattern, + * independent of the partition order generated by the hash. + * + * @param texel_count The number of texels in the block. + * @param partition_of_texel The partition assignments, in hash order. + * @param[out] bit_pattern The output bit pattern representation. + */ +static void generate_canonical_partitioning( + unsigned int texel_count, + const uint8_t* partition_of_texel, + uint64_t bit_pattern[BIT_PATTERN_WORDS] +) { + // Clear the pattern + for (unsigned int i = 0; i < BIT_PATTERN_WORDS; i++) + { + bit_pattern[i] = 0; + } + + // Store a mapping to reorder the raw partitions so that the partitions are ordered such + // that the lowest texel index in partition N is smaller than the lowest texel index in + // partition N + 1. + int mapped_index[BLOCK_MAX_PARTITIONS]; + int map_weight_count = 0; + + for (unsigned int i = 0; i < BLOCK_MAX_PARTITIONS; i++) + { + mapped_index[i] = -1; + } + + for (unsigned int i = 0; i < texel_count; i++) + { + int index = partition_of_texel[i]; + if (mapped_index[index] < 0) + { + mapped_index[index] = map_weight_count++; + } + + uint64_t xlat_index = mapped_index[index]; + bit_pattern[i >> 5] |= xlat_index << (2 * (i & 0x1F)); + } +} + +/** + * @brief Compare two canonical patterns to see if they are the same. + * + * @param part1 The first canonical bit pattern to check. + * @param part2 The second canonical bit pattern to check. + * + * @return @c true if the patterns are the same, @c false otherwise. + */ +static bool compare_canonical_partitionings( + const uint64_t part1[BIT_PATTERN_WORDS], + const uint64_t part2[BIT_PATTERN_WORDS] +) { + return (part1[0] == part2[0]) +#if BIT_PATTERN_WORDS > 1 + && (part1[1] == part2[1]) +#endif +#if BIT_PATTERN_WORDS > 2 + && (part1[2] == part2[2]) +#endif +#if BIT_PATTERN_WORDS > 3 + && (part1[3] == part2[3]) +#endif +#if BIT_PATTERN_WORDS > 4 + && (part1[4] == part2[4]) +#endif +#if BIT_PATTERN_WORDS > 5 + && (part1[5] == part2[5]) +#endif +#if BIT_PATTERN_WORDS > 6 + && (part1[6] == part2[6]) +#endif + ; +} + +/** + * @brief Hash function used for procedural partition assignment. + * + * @param inp The hash seed. + * + * @return The hashed value. + */ +static uint32_t hash52( + uint32_t inp +) { + inp ^= inp >> 15; + + // (2^4 + 1) * (2^7 + 1) * (2^17 - 1) + inp *= 0xEEDE0891; + inp ^= inp >> 5; + inp += inp << 16; + inp ^= inp >> 7; + inp ^= inp >> 3; + inp ^= inp << 6; + inp ^= inp >> 17; + return inp; +} + +/** + * @brief Select texel assignment for a single coordinate. + * + * @param seed The seed - the partition index from the block. + * @param x The texel X coordinate in the block. + * @param y The texel Y coordinate in the block. + * @param z The texel Z coordinate in the block. + * @param partition_count The total partition count of this encoding. + * @param small_block @c true if the block has fewer than 32 texels. + * + * @return The assigned partition index for this texel. + */ +static uint8_t select_partition( + int seed, + int x, + int y, + int z, + int partition_count, + bool small_block +) { + // For small blocks bias the coordinates to get better distribution + if (small_block) + { + x <<= 1; + y <<= 1; + z <<= 1; + } + + seed += (partition_count - 1) * 1024; + + uint32_t rnum = hash52(seed); + + uint8_t seed1 = rnum & 0xF; + uint8_t seed2 = (rnum >> 4) & 0xF; + uint8_t seed3 = (rnum >> 8) & 0xF; + uint8_t seed4 = (rnum >> 12) & 0xF; + uint8_t seed5 = (rnum >> 16) & 0xF; + uint8_t seed6 = (rnum >> 20) & 0xF; + uint8_t seed7 = (rnum >> 24) & 0xF; + uint8_t seed8 = (rnum >> 28) & 0xF; + uint8_t seed9 = (rnum >> 18) & 0xF; + uint8_t seed10 = (rnum >> 22) & 0xF; + uint8_t seed11 = (rnum >> 26) & 0xF; + uint8_t seed12 = ((rnum >> 30) | (rnum << 2)) & 0xF; + + // Squaring all the seeds in order to bias their distribution towards lower values. + seed1 *= seed1; + seed2 *= seed2; + seed3 *= seed3; + seed4 *= seed4; + seed5 *= seed5; + seed6 *= seed6; + seed7 *= seed7; + seed8 *= seed8; + seed9 *= seed9; + seed10 *= seed10; + seed11 *= seed11; + seed12 *= seed12; + + int sh1, sh2; + if (seed & 1) + { + sh1 = (seed & 2 ? 4 : 5); + sh2 = (partition_count == 3 ? 6 : 5); + } + else + { + sh1 = (partition_count == 3 ? 6 : 5); + sh2 = (seed & 2 ? 4 : 5); + } + + int sh3 = (seed & 0x10) ? sh1 : sh2; + + seed1 >>= sh1; + seed2 >>= sh2; + seed3 >>= sh1; + seed4 >>= sh2; + seed5 >>= sh1; + seed6 >>= sh2; + seed7 >>= sh1; + seed8 >>= sh2; + + seed9 >>= sh3; + seed10 >>= sh3; + seed11 >>= sh3; + seed12 >>= sh3; + + int a = seed1 * x + seed2 * y + seed11 * z + (rnum >> 14); + int b = seed3 * x + seed4 * y + seed12 * z + (rnum >> 10); + int c = seed5 * x + seed6 * y + seed9 * z + (rnum >> 6); + int d = seed7 * x + seed8 * y + seed10 * z + (rnum >> 2); + + // Apply the saw + a &= 0x3F; + b &= 0x3F; + c &= 0x3F; + d &= 0x3F; + + // Remove some of the components if we are to output < 4 partitions. + if (partition_count <= 3) + { + d = 0; + } + + if (partition_count <= 2) + { + c = 0; + } + + if (partition_count <= 1) + { + b = 0; + } + + uint8_t partition; + if (a >= b && a >= c && a >= d) + { + partition = 0; + } + else if (b >= c && b >= d) + { + partition = 1; + } + else if (c >= d) + { + partition = 2; + } + else + { + partition = 3; + } + + return partition; +} + +/** + * @brief Generate a single partition info structure. + * + * @param[out] bsd The block size information. + * @param partition_count The partition count of this partitioning. + * @param partition_index The partition index / seed of this partitioning. + * @param partition_remap_index The remapped partition index of this partitioning. + * @param[out] pi The partition info structure to populate. + * + * @return True if this is a useful partition index, False if we can skip it. + */ +static bool generate_one_partition_info_entry( + block_size_descriptor& bsd, + unsigned int partition_count, + unsigned int partition_index, + unsigned int partition_remap_index, + partition_info& pi +) { + int texels_per_block = bsd.texel_count; + bool small_block = texels_per_block < 32; + + uint8_t *partition_of_texel = pi.partition_of_texel; + + // Assign texels to partitions + int texel_idx = 0; + int counts[BLOCK_MAX_PARTITIONS] { 0 }; + for (unsigned int z = 0; z < bsd.zdim; z++) + { + for (unsigned int y = 0; y < bsd.ydim; y++) + { + for (unsigned int x = 0; x < bsd.xdim; x++) + { + uint8_t part = select_partition(partition_index, x, y, z, partition_count, small_block); + pi.texels_of_partition[part][counts[part]++] = static_cast<uint8_t>(texel_idx++); + *partition_of_texel++ = part; + } + } + } + + // Fill loop tail so we can overfetch later + for (unsigned int i = 0; i < partition_count; i++) + { + int ptex_count = counts[i]; + int ptex_count_simd = round_up_to_simd_multiple_vla(ptex_count); + for (int j = ptex_count; j < ptex_count_simd; j++) + { + pi.texels_of_partition[i][j] = pi.texels_of_partition[i][ptex_count - 1]; + } + } + + // Populate the actual procedural partition count + if (counts[0] == 0) + { + pi.partition_count = 0; + } + else if (counts[1] == 0) + { + pi.partition_count = 1; + } + else if (counts[2] == 0) + { + pi.partition_count = 2; + } + else if (counts[3] == 0) + { + pi.partition_count = 3; + } + else + { + pi.partition_count = 4; + } + + // Populate the partition index + pi.partition_index = static_cast<uint16_t>(partition_index); + + // Populate the coverage bitmaps for 2/3/4 partitions + uint64_t* bitmaps { nullptr }; + if (partition_count == 2) + { + bitmaps = bsd.coverage_bitmaps_2[partition_remap_index]; + } + else if (partition_count == 3) + { + bitmaps = bsd.coverage_bitmaps_3[partition_remap_index]; + } + else if (partition_count == 4) + { + bitmaps = bsd.coverage_bitmaps_4[partition_remap_index]; + } + + for (unsigned int i = 0; i < BLOCK_MAX_PARTITIONS; i++) + { + pi.partition_texel_count[i] = static_cast<uint8_t>(counts[i]); + } + + // Valid partitionings have texels in all of the requested partitions + bool valid = pi.partition_count == partition_count; + + if (bitmaps) + { + // Populate the partition coverage bitmap + for (unsigned int i = 0; i < partition_count; i++) + { + bitmaps[i] = 0ULL; + } + + unsigned int texels_to_process = astc::min(bsd.texel_count, BLOCK_MAX_KMEANS_TEXELS); + for (unsigned int i = 0; i < texels_to_process; i++) + { + unsigned int idx = bsd.kmeans_texels[i]; + bitmaps[pi.partition_of_texel[idx]] |= 1ULL << i; + } + } + + return valid; +} + +static void build_partition_table_for_one_partition_count( + block_size_descriptor& bsd, + bool can_omit_partitionings, + unsigned int partition_count_cutoff, + unsigned int partition_count, + partition_info* ptab, + uint64_t* canonical_patterns +) { + unsigned int next_index = 0; + bsd.partitioning_count_selected[partition_count - 1] = 0; + bsd.partitioning_count_all[partition_count - 1] = 0; + + // Skip tables larger than config max partition count if we can omit modes + if (can_omit_partitionings && (partition_count > partition_count_cutoff)) + { + return; + } + + // Iterate through twice + // - Pass 0: Keep selected partitionings + // - Pass 1: Keep non-selected partitionings (skip if in omit mode) + unsigned int max_iter = can_omit_partitionings ? 1 : 2; + + // Tracker for things we built in the first iteration + uint8_t build[BLOCK_MAX_PARTITIONINGS] { 0 }; + for (unsigned int x = 0; x < max_iter; x++) + { + for (unsigned int i = 0; i < BLOCK_MAX_PARTITIONINGS; i++) + { + // Don't include things we built in the first pass + if ((x == 1) && build[i]) + { + continue; + } + + bool keep_useful = generate_one_partition_info_entry(bsd, partition_count, i, next_index, ptab[next_index]); + if ((x == 0) && !keep_useful) + { + continue; + } + + generate_canonical_partitioning(bsd.texel_count, ptab[next_index].partition_of_texel, canonical_patterns + next_index * BIT_PATTERN_WORDS); + bool keep_canonical = true; + for (unsigned int j = 0; j < next_index; j++) + { + bool match = compare_canonical_partitionings(canonical_patterns + next_index * BIT_PATTERN_WORDS, canonical_patterns + j * BIT_PATTERN_WORDS); + if (match) + { + keep_canonical = false; + break; + } + } + + if (keep_useful && keep_canonical) + { + if (x == 0) + { + bsd.partitioning_packed_index[partition_count - 2][i] = static_cast<uint16_t>(next_index); + bsd.partitioning_count_selected[partition_count - 1]++; + bsd.partitioning_count_all[partition_count - 1]++; + build[i] = 1; + next_index++; + } + } + else + { + if (x == 1) + { + bsd.partitioning_packed_index[partition_count - 2][i] = static_cast<uint16_t>(next_index); + bsd.partitioning_count_all[partition_count - 1]++; + next_index++; + } + } + } + } +} + +/* See header for documentation. */ +void init_partition_tables( + block_size_descriptor& bsd, + bool can_omit_partitionings, + unsigned int partition_count_cutoff +) { + partition_info* par_tab2 = bsd.partitionings; + partition_info* par_tab3 = par_tab2 + BLOCK_MAX_PARTITIONINGS; + partition_info* par_tab4 = par_tab3 + BLOCK_MAX_PARTITIONINGS; + partition_info* par_tab1 = par_tab4 + BLOCK_MAX_PARTITIONINGS; + + generate_one_partition_info_entry(bsd, 1, 0, 0, *par_tab1); + bsd.partitioning_count_selected[0] = 1; + bsd.partitioning_count_all[0] = 1; + + uint64_t* canonical_patterns = new uint64_t[BLOCK_MAX_PARTITIONINGS * BIT_PATTERN_WORDS]; + + build_partition_table_for_one_partition_count(bsd, can_omit_partitionings, partition_count_cutoff, 2, par_tab2, canonical_patterns); + build_partition_table_for_one_partition_count(bsd, can_omit_partitionings, partition_count_cutoff, 3, par_tab3, canonical_patterns); + build_partition_table_for_one_partition_count(bsd, can_omit_partitionings, partition_count_cutoff, 4, par_tab4, canonical_patterns); + + delete[] canonical_patterns; +} diff --git a/thirdparty/astcenc/astcenc_percentile_tables.cpp b/thirdparty/astcenc/astcenc_percentile_tables.cpp new file mode 100644 index 0000000000..448ddcc968 --- /dev/null +++ b/thirdparty/astcenc/astcenc_percentile_tables.cpp @@ -0,0 +1,1251 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2022 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief Percentile data tables for different block encodings. + * + * To reduce binary size the tables are stored using a packed differential encoding. + */ + +#include "astcenc_internal.h" + +#if !defined(ASTCENC_DECOMPRESS_ONLY) +/** + * @brief Structure containing packed percentile metadata. + * + * Note that percentile tables do not exist for 3D textures, so no zdim is stored. + */ +struct packed_percentile_table +{ + /** The block X dimension. */ + uint8_t xdim; + + /** The block Y dimension. */ + uint8_t ydim; + + /** The number of packed items in the 1 and 2 plane data. */ + uint16_t item_count[2]; + + /** The accumulator divisor for 1 and 2 plane data. */ + uint16_t difscales[2]; + + /** The initial accumulator values for 1 and 2 plane data. */ + uint16_t initial_percs[2]; + + /** The packed data for the 1 and 2 plane data. */ + const uint16_t *items[2]; +}; + +#if ASTCENC_BLOCK_MAX_TEXELS >= (4 * 4) +static const uint16_t percentile_arr_4x4_0[61] { + 0x0242, 0x7243, 0x6A51, 0x6A52, 0x5A41, 0x4A53, 0x8851, 0x3842, + 0x3852, 0x3853, 0x3043, 0xFA33, 0x1BDF, 0x2022, 0x1032, 0x29CE, + 0x21DE, 0x2823, 0x0813, 0x0A13, 0x0A31, 0x0A23, 0x09CF, 0x0833, + 0x0A32, 0x01DF, 0x0BDD, 0x0BCF, 0x0221, 0x095F, 0x0A01, 0x0BDE, + 0x0BCD, 0x0A22, 0x09AF, 0x0B5F, 0x0B4D, 0x0BCE, 0x0BBF, 0x0A11, + 0x01BF, 0x0202, 0x0B5D, 0x1203, 0x034E, 0x0B8E, 0x035E, 0x0212, + 0x032E, 0x0B4F, 0x03AF, 0x03AD, 0x03BD, 0x0BBE, 0x03AE, 0x039F, + 0x039E, 0x033E, 0x033F, 0x038F, 0x032F +}; + +static const uint16_t percentile_arr_4x4_1[84] { + 0x0452, 0xFFAE, 0x2433, 0x1DDF, 0x17CD, 0x1E21, 0x1C43, 0x1442, + 0x3FBE, 0x1FDD, 0x0E31, 0x0F4F, 0x1423, 0x0FBD, 0x1451, 0x0E03, + 0x05CF, 0x0C32, 0x0DDE, 0x27AD, 0x274E, 0x0E02, 0x0F5E, 0x07AF, + 0x0F5F, 0x0DCE, 0x0C41, 0x0422, 0x0613, 0x0E12, 0x0611, 0x0F3F, + 0x0601, 0x0DBF, 0x05DD, 0x075D, 0x0C02, 0x054E, 0x0431, 0x0413, + 0x079F, 0x05BE, 0x0F4D, 0x0403, 0x05AF, 0x055F, 0x05AE, 0x054F, + 0x0421, 0x05BD, 0x0DCD, 0x0411, 0x0412, 0x055E, 0x055D, 0x073D, + 0x058E, 0x072F, 0x072D, 0x079D, 0x0D2E, 0x0453, 0x078D, 0x053E, + 0x053F, 0x059E, 0x052F, 0x058F, 0x072E, 0x078F, 0x059F, 0x078E, + 0x071F, 0x073E, 0x051F, 0x070D, 0x079E, 0x070E, 0x071D, 0x0622, + 0x070F, 0x071E, 0x07BF, 0x07CE +}; + +static const packed_percentile_table block_pcd_4x4 { + 4, 4, + { 61, 84 }, + { 184, 141 }, + { 0, 53 }, + { percentile_arr_4x4_0, percentile_arr_4x4_1 } +}; +#endif + +#if ASTCENC_BLOCK_MAX_TEXELS >= (5 * 4) +static const uint16_t percentile_arr_5x4_0[91] { + 0x02C1, 0xFAD1, 0xE8D3, 0xDAC2, 0xA8D2, 0x70D1, 0x50C2, 0x80C3, + 0xD2C3, 0x4AA2, 0x2AD2, 0x2242, 0x2251, 0x42A3, 0x1A43, 0x4A52, + 0x32B3, 0x2A41, 0x1042, 0x1851, 0x5892, 0x10A2, 0x2253, 0x10B2, + 0x10B3, 0x13DF, 0x3083, 0x08B1, 0x1043, 0x12B1, 0x0AB2, 0x1A93, + 0x1852, 0x1A33, 0x09CE, 0x08A3, 0x1022, 0x1283, 0x0853, 0x1AA1, + 0x1093, 0x11DE, 0x135F, 0x1832, 0x195F, 0x0A81, 0x11CF, 0x0A31, + 0x09DF, 0x0B4D, 0x09AF, 0x03CF, 0x0813, 0x03DD, 0x0A92, 0x0A82, + 0x03CD, 0x0023, 0x0BDE, 0x0BBF, 0x1232, 0x0221, 0x0291, 0x0A23, + 0x0833, 0x035D, 0x0BCE, 0x01BF, 0x0222, 0x134E, 0x0213, 0x0A01, + 0x0B4F, 0x0B5E, 0x038E, 0x032E, 0x03AF, 0x0A11, 0x03AD, 0x0203, + 0x0202, 0x0BBD, 0x033E, 0x03AE, 0x03BE, 0x0212, 0x033F, 0x039E, + 0x039F, 0x032F, 0x038F +}; + +static const uint16_t percentile_arr_5x4_1[104] { + 0x0433, 0xB621, 0x5452, 0x4443, 0x7FAE, 0xFCA3, 0x7CC2, 0x24B2, + 0x45DF, 0x44B3, 0x7631, 0x27CD, 0x1CD1, 0x1E03, 0x4FBE, 0x774F, + 0x1C42, 0x7691, 0x24A2, 0x2681, 0x3C23, 0x3C93, 0x0FBD, 0x1C32, + 0x1E82, 0x1E12, 0x0F4E, 0x1602, 0x0FAD, 0x0C51, 0x1FDD, 0x0E13, + 0x0DCF, 0x175E, 0x0C22, 0x175F, 0x15DE, 0x0CB1, 0x17AF, 0x1CC1, + 0x1F3F, 0x1483, 0x0441, 0x0C91, 0x04D2, 0x0DCE, 0x154E, 0x079F, + 0x0CA1, 0x0F5D, 0x0431, 0x15DD, 0x05BF, 0x0C92, 0x0611, 0x0C82, + 0x0402, 0x074D, 0x0DBD, 0x055E, 0x05BE, 0x0DCD, 0x0421, 0x05AF, + 0x0403, 0x0D4F, 0x055F, 0x05AE, 0x0413, 0x0E01, 0x055D, 0x073D, + 0x0C12, 0x0692, 0x0411, 0x072D, 0x078D, 0x079D, 0x058E, 0x0D2E, + 0x0453, 0x072F, 0x059E, 0x052F, 0x071F, 0x053F, 0x053E, 0x078F, + 0x058F, 0x051F, 0x0F2E, 0x059F, 0x078E, 0x073E, 0x071D, 0x070D, + 0x070E, 0x079E, 0x0622, 0x0683, 0x070F, 0x071E, 0x07BF, 0x07CE +}; + +static const packed_percentile_table block_pcd_5x4 { + 5, 4, + { 91, 104 }, + { 322, 464 }, + { 0, 202 }, + { percentile_arr_5x4_0, percentile_arr_5x4_1 } +}; +#endif + +#if ASTCENC_BLOCK_MAX_TEXELS >= (5 * 5) +static const uint16_t percentile_arr_5x5_0[129] { + 0x00F3, 0xF8F2, 0x70E3, 0x62E1, 0x60E1, 0x4AC1, 0x3261, 0x38D3, + 0x3271, 0x5AF1, 0x5873, 0x2AD1, 0x28E2, 0x28F1, 0x2262, 0x9AC2, + 0x18D2, 0x1072, 0x1071, 0x22A2, 0x2062, 0x1A51, 0x10C2, 0x0892, + 0x08D1, 0x1AA3, 0x23EE, 0x08C3, 0x0BEF, 0x2242, 0x0863, 0x0AB3, + 0x0BFF, 0x0A93, 0x08A2, 0x0A41, 0x1083, 0x0842, 0x10B3, 0x21EE, + 0x10B2, 0x00B1, 0x1263, 0x12C3, 0x0A83, 0x0851, 0x11FE, 0x0253, + 0x09FD, 0x0A72, 0x09FF, 0x1AB2, 0x0BDF, 0x0A33, 0x0243, 0x0B7F, + 0x0AB1, 0x12D2, 0x0252, 0x096F, 0x00A3, 0x0893, 0x0822, 0x0843, + 0x097E, 0x097F, 0x01EF, 0x09CE, 0x03FE, 0x0A81, 0x036F, 0x0052, + 0x13FD, 0x0AA1, 0x1853, 0x036D, 0x0A92, 0x0832, 0x01DE, 0x0A82, + 0x0BED, 0x0231, 0x0BBF, 0x03DD, 0x0B6E, 0x01AF, 0x0813, 0x0023, + 0x0A91, 0x015F, 0x037E, 0x01CF, 0x0232, 0x0BCD, 0x0221, 0x0BDE, + 0x0213, 0x035F, 0x0B7D, 0x0223, 0x01BF, 0x0BCF, 0x01DF, 0x0033, + 0x0222, 0x03CE, 0x0A01, 0x03AF, 0x034D, 0x0B8E, 0x032E, 0x0203, + 0x0211, 0x0202, 0x0B5D, 0x03AD, 0x034E, 0x03AE, 0x034F, 0x033F, + 0x039F, 0x03BD, 0x03BE, 0x035E, 0x0212, 0x033E, 0x039E, 0x032F, + 0x038F +}; + +static const uint16_t percentile_arr_5x5_1[126] { + 0x0443, 0x6452, 0xFE21, 0x27AE, 0x2433, 0x1FCD, 0x25DF, 0x6CC2, + 0x2C62, 0x1F4F, 0x4C42, 0x1FBE, 0x0DEF, 0x34A3, 0x0E03, 0x54B2, + 0x1F7D, 0x17DD, 0x0DFF, 0x0CD1, 0x0E31, 0x0C71, 0x1CF1, 0x15FE, + 0x1691, 0x1681, 0x24B3, 0x174E, 0x0F6E, 0x0493, 0x175E, 0x1C51, + 0x17BD, 0x076D, 0x2CA2, 0x05EE, 0x1472, 0x2423, 0x0DCF, 0x0432, + 0x15DE, 0x0612, 0x0CD2, 0x0682, 0x0F5F, 0x07AD, 0x0602, 0x0CE1, + 0x0C91, 0x0FAF, 0x073F, 0x0E13, 0x0D7F, 0x0DCE, 0x0422, 0x0D7D, + 0x0441, 0x05FD, 0x0CB1, 0x0C83, 0x04C1, 0x0461, 0x0F9F, 0x0DDD, + 0x056E, 0x0C92, 0x0482, 0x0431, 0x05ED, 0x0D6F, 0x075D, 0x0402, + 0x057E, 0x0DBF, 0x04A1, 0x054E, 0x0F4D, 0x0403, 0x05CD, 0x0453, + 0x05AE, 0x0421, 0x0F1F, 0x05BE, 0x0601, 0x0611, 0x05BD, 0x05AF, + 0x078D, 0x072D, 0x073D, 0x055E, 0x0F9D, 0x0411, 0x0413, 0x0412, + 0x055F, 0x077E, 0x055D, 0x052E, 0x054F, 0x053E, 0x058E, 0x078F, + 0x059E, 0x071D, 0x0E92, 0x053F, 0x059F, 0x051F, 0x072F, 0x052F, + 0x070D, 0x079E, 0x058F, 0x072E, 0x070E, 0x078E, 0x070F, 0x073E, + 0x0622, 0x0683, 0x071E, 0x076F, 0x07BF, 0x07CE +}; + +static const packed_percentile_table block_pcd_5x5 { + 5, 5, + { 129, 126 }, + { 258, 291 }, + { 0, 116 }, + { percentile_arr_5x5_0, percentile_arr_5x5_1 } +}; +#endif + +#if ASTCENC_BLOCK_MAX_TEXELS >= (6 * 5) +static const uint16_t percentile_arr_6x5_0[165] { + 0x0163, 0xF8F3, 0x9962, 0x8972, 0x7961, 0x7173, 0x6953, 0x5943, + 0x4B41, 0x3AE1, 0x38E3, 0x6971, 0x32C1, 0x28D3, 0x2A61, 0xC8F2, + 0x2271, 0x4873, 0x5B21, 0x3AD1, 0x1B13, 0x1952, 0x1B51, 0x12F1, + 0x1A62, 0x1322, 0x1951, 0x10E2, 0x1B31, 0x20F1, 0x2102, 0x2072, + 0x10D2, 0x1142, 0x2912, 0x3871, 0x2BEE, 0x0862, 0x1123, 0x0AC2, + 0x12A2, 0x0A51, 0x1922, 0x0941, 0x1BEF, 0x0B42, 0x08D1, 0x13FF, + 0x1933, 0x08C3, 0x08C2, 0x1131, 0x08E1, 0x2903, 0x0863, 0x0B32, + 0x1132, 0x1AC3, 0x0A42, 0x1A41, 0x0042, 0x21EE, 0x09FF, 0x03DF, + 0x0AA3, 0x11FE, 0x02B3, 0x0B11, 0x10B3, 0x0B03, 0x11FD, 0x0913, + 0x0A53, 0x037F, 0x1263, 0x0051, 0x0A33, 0x0B01, 0x016F, 0x0A72, + 0x1312, 0x08A2, 0x10B1, 0x0BFE, 0x11EF, 0x0B02, 0x0A52, 0x0043, + 0x0822, 0x01CE, 0x0A43, 0x097F, 0x036F, 0x08B2, 0x03FD, 0x0A83, + 0x0B33, 0x0AB1, 0x017E, 0x0B23, 0x0852, 0x02D2, 0x0BBF, 0x0BDD, + 0x03ED, 0x0AB2, 0x02A1, 0x0853, 0x036D, 0x0892, 0x0032, 0x0A31, + 0x0083, 0x09DE, 0x0A93, 0x08A3, 0x1213, 0x0BDE, 0x03CD, 0x036E, + 0x037E, 0x0A21, 0x0023, 0x0BCF, 0x01CF, 0x0013, 0x01AF, 0x0A92, + 0x0232, 0x035F, 0x0093, 0x0B7D, 0x015F, 0x0282, 0x01BF, 0x09DF, + 0x03CE, 0x0223, 0x0833, 0x0222, 0x03AF, 0x0A01, 0x0291, 0x0B4D, + 0x032E, 0x038E, 0x0203, 0x0281, 0x035D, 0x03AD, 0x0B9F, 0x0202, + 0x034F, 0x03BE, 0x0211, 0x03AE, 0x03BD, 0x0212, 0x034E, 0x033F, + 0x033E, 0x035E, 0x039E, 0x032F, 0x038F +}; + +static const uint16_t percentile_arr_6x5_1[145] { + 0x0443, 0xEFAE, 0x2CC2, 0x2E21, 0x2C52, 0x7C33, 0x47CD, 0x25DF, + 0x3CA3, 0xFFBE, 0x2551, 0x24B3, 0x474F, 0x1513, 0x2691, 0x1603, + 0x1462, 0x1D32, 0x14B2, 0x5442, 0x2CD2, 0x35EF, 0x0CD1, 0x3D22, + 0x17BD, 0x0FDD, 0x0DFF, 0x2631, 0x177D, 0x0CF1, 0x1E81, 0x0E82, + 0x1DFE, 0x0F5E, 0x0701, 0x2CA2, 0x1D03, 0x0F4E, 0x1471, 0x0C51, + 0x1F6E, 0x2FAF, 0x0561, 0x0C72, 0x176D, 0x0FAD, 0x0DEE, 0x05CF, + 0x0E13, 0x0F5F, 0x0E12, 0x0C23, 0x1E02, 0x1D12, 0x0CB1, 0x0C32, + 0x0C93, 0x15DE, 0x0F9F, 0x0F3F, 0x0D41, 0x0C41, 0x0CC1, 0x0D31, + 0x0C22, 0x05FD, 0x057F, 0x0D01, 0x0461, 0x04E1, 0x0D7D, 0x05CE, + 0x0502, 0x0C31, 0x05ED, 0x05DD, 0x0511, 0x0F11, 0x0491, 0x0D6F, + 0x0521, 0x056E, 0x0C83, 0x0D23, 0x04A1, 0x0C02, 0x075D, 0x05BF, + 0x0C21, 0x079D, 0x0482, 0x05BD, 0x0DBE, 0x05CD, 0x054E, 0x057E, + 0x0DAE, 0x074D, 0x078D, 0x0542, 0x0492, 0x05AF, 0x0611, 0x0F3D, + 0x0601, 0x071F, 0x055E, 0x059E, 0x0571, 0x054F, 0x0412, 0x0453, + 0x058E, 0x0413, 0x0D3E, 0x077E, 0x072D, 0x052E, 0x059F, 0x055D, + 0x072F, 0x0403, 0x0411, 0x058F, 0x055F, 0x0692, 0x078E, 0x053F, + 0x0D2F, 0x078F, 0x070D, 0x071D, 0x051F, 0x072E, 0x079E, 0x070E, + 0x070F, 0x073E, 0x0622, 0x0683, 0x0702, 0x071E, 0x076F, 0x07BF, + 0x07CE +}; + +static const packed_percentile_table block_pcd_6x5 { + 6, 5, + { 165, 145 }, + { 388, 405 }, + { 0, 156 }, + { percentile_arr_6x5_0, percentile_arr_6x5_1 } +}; +#endif + +#if ASTCENC_BLOCK_MAX_TEXELS >= (6 * 6) +static const uint16_t percentile_arr_6x6_0[206] { + 0x006F, 0xF908, 0xF104, 0xE918, 0xE963, 0xD114, 0xB0F3, 0xA07E, + 0x7972, 0x705F, 0x687F, 0x6162, 0x5953, 0x586E, 0x610C, 0x524D, + 0x5973, 0x9943, 0x98E3, 0x904F, 0x8341, 0x7AC1, 0x3A61, 0x70D3, + 0xA073, 0x6AE1, 0x30F2, 0x3313, 0x2B21, 0x9A2E, 0x4322, 0x225D, + 0x2331, 0x2271, 0x22D1, 0x1A2D, 0x221F, 0x22F1, 0x1971, 0x6952, + 0x1951, 0x187D, 0x18F1, 0x1902, 0x185E, 0x1B51, 0x105D, 0x1A3D, + 0x30E2, 0x10D2, 0x1961, 0x12A2, 0x6072, 0x3942, 0x386D, 0x33EE, + 0x104E, 0x4923, 0x101E, 0x2122, 0x1251, 0x1141, 0x182F, 0x3133, + 0x080E, 0x1262, 0x123E, 0x1B32, 0x102E, 0x1931, 0x10D1, 0x1912, + 0x0871, 0x12C2, 0x08C2, 0x1103, 0x0B03, 0x1062, 0x083D, 0x08E1, + 0x1132, 0x184D, 0x0863, 0x08C3, 0x303F, 0x083E, 0x10B3, 0x12A3, + 0x0BEF, 0x0B11, 0x1A42, 0x2233, 0x13FF, 0x080F, 0x0A41, 0x0AC3, + 0x0842, 0x1A63, 0x0BDF, 0x09FF, 0x12B3, 0x124E, 0x0B12, 0x0B42, + 0x0A2F, 0x1253, 0x0913, 0x1051, 0x0B01, 0x120F, 0x0B02, 0x08A2, + 0x0BBF, 0x00B1, 0x22B1, 0x01EE, 0x1B33, 0x0B23, 0x0283, 0x13FD, + 0x0AB2, 0x11FD, 0x09FE, 0x0A43, 0x08B2, 0x0A1D, 0x0A52, 0x023F, + 0x101F, 0x01CE, 0x0A31, 0x0BDD, 0x0293, 0x1822, 0x12A1, 0x03FE, + 0x121E, 0x0843, 0x0272, 0x0B6F, 0x0052, 0x0A0D, 0x0BED, 0x12D2, + 0x1B7F, 0x1053, 0x0032, 0x01DE, 0x08A3, 0x020E, 0x0883, 0x09EF, + 0x0892, 0x0A21, 0x03CD, 0x0B5F, 0x0213, 0x0A32, 0x016F, 0x1292, + 0x03DE, 0x017E, 0x0BAF, 0x0223, 0x1093, 0x0BCF, 0x037E, 0x01DF, + 0x09CF, 0x015F, 0x09AF, 0x0023, 0x01BF, 0x0222, 0x0282, 0x03CE, + 0x1013, 0x036E, 0x097F, 0x0033, 0x0A01, 0x0B6D, 0x03BE, 0x037D, + 0x0281, 0x0BAE, 0x0203, 0x032E, 0x034D, 0x034F, 0x0291, 0x0211, + 0x038E, 0x03BD, 0x039E, 0x0BAD, 0x033E, 0x034E, 0x039F, 0x0202, + 0x035D, 0x0212, 0x033F, 0x035E, 0x038F, 0x032F +}; + +static const uint16_t percentile_arr_6x6_1[164] { + 0x07AE, 0x8443, 0x7E21, 0x77CD, 0x6C62, 0x9433, 0x6452, 0x34C2, + 0x5DDF, 0xC7BE, 0x25EF, 0x24A3, 0x3CF1, 0xFDFF, 0x177D, 0x1F4F, + 0xC551, 0x5CB3, 0x1532, 0x1513, 0x143E, 0x245D, 0x14B2, 0x2472, + 0x14D2, 0x1FBD, 0x1631, 0x2DFE, 0x1691, 0x17DD, 0x2E03, 0x376E, + 0x2442, 0x0F6D, 0x3C71, 0x2CD1, 0x2522, 0x6C51, 0x260D, 0x17AF, + 0x0DEE, 0x1C1F, 0x2F01, 0x142E, 0x0CA2, 0x0FAD, 0x3D03, 0x275E, + 0x1681, 0x274E, 0x1682, 0x1C23, 0x273F, 0x0F5F, 0x05DE, 0x15FD, + 0x0DCF, 0x1E02, 0x04B1, 0x144D, 0x0E12, 0x0D12, 0x1CC1, 0x0E13, + 0x1C6D, 0x0C32, 0x043D, 0x0C61, 0x0F9F, 0x04E1, 0x0DCE, 0x0D41, + 0x1C93, 0x0C22, 0x061D, 0x0D7F, 0x0C41, 0x0561, 0x0531, 0x0D21, + 0x0711, 0x0C91, 0x0501, 0x0C1E, 0x040F, 0x15DD, 0x0431, 0x0C2F, + 0x057D, 0x0C2D, 0x0DBE, 0x040E, 0x0D02, 0x0D11, 0x054E, 0x040D, + 0x0D23, 0x0DBF, 0x04A1, 0x05ED, 0x0C1D, 0x05BD, 0x072D, 0x056E, + 0x0483, 0x0F3D, 0x0482, 0x078D, 0x0F5D, 0x0453, 0x0D9E, 0x0C4E, + 0x05CD, 0x079D, 0x0402, 0x05AE, 0x0F1F, 0x0542, 0x074D, 0x056F, + 0x0421, 0x0D4F, 0x0601, 0x0571, 0x0492, 0x059F, 0x053F, 0x05AF, + 0x0611, 0x055E, 0x0D8E, 0x053E, 0x055D, 0x047D, 0x0411, 0x052E, + 0x058F, 0x051F, 0x055F, 0x0D7E, 0x072F, 0x052F, 0x0412, 0x078F, + 0x0403, 0x077E, 0x070D, 0x070E, 0x078E, 0x0F1D, 0x072E, 0x0413, + 0x070F, 0x0692, 0x079E, 0x060E, 0x0622, 0x0683, 0x0702, 0x071E, + 0x073E, 0x076F, 0x07BF, 0x07CE +}; + +static const packed_percentile_table block_pcd_6x6 { + 6, 6, + { 206, 164 }, + { 769, 644 }, + { 0, 256 }, + { percentile_arr_6x6_0, percentile_arr_6x6_1 } +}; +#endif + +#if ASTCENC_BLOCK_MAX_TEXELS >= (8 * 5) +static const uint16_t percentile_arr_8x5_0[226] { + 0x0066, 0xF865, 0xE963, 0xA856, 0xA1F2, 0x9875, 0x91C3, 0x91E2, + 0x80F3, 0x8076, 0x61E3, 0x6153, 0x5172, 0x59D2, 0x51D3, 0x5047, + 0xA943, 0x49B3, 0x4846, 0x4962, 0xC037, 0x4173, 0x39F1, 0x7027, + 0xA2C1, 0x3AE1, 0x9341, 0x30D3, 0x5225, 0x2A61, 0x33C1, 0x28E3, + 0x53A1, 0x49C2, 0x2A06, 0x4055, 0x2006, 0x21D1, 0x2271, 0x4321, + 0x3873, 0x18F2, 0x2015, 0x1A15, 0x1857, 0x52D1, 0x3045, 0x4835, + 0x1952, 0x29E1, 0x3207, 0x1036, 0x1816, 0x2A16, 0x2971, 0x13B1, + 0x2A17, 0x2351, 0x1025, 0x1826, 0x30E2, 0x1262, 0x20F1, 0x1007, + 0x1072, 0x1151, 0x10D2, 0x1235, 0x1205, 0x1062, 0x4AF1, 0x1251, + 0x0B31, 0x1381, 0x13EE, 0x1B92, 0x13EF, 0x0942, 0x1AA2, 0x13FF, + 0x1161, 0x0B93, 0x19A2, 0x11B1, 0x08D1, 0x12C2, 0x0B13, 0x1B22, + 0x2123, 0x09A3, 0x2071, 0x1B7F, 0x1817, 0x0A42, 0x10C2, 0x1233, + 0x08C3, 0x0A41, 0x0B42, 0x09C1, 0x0933, 0x1AB3, 0x1382, 0x1BDF, + 0x2122, 0x0A53, 0x0AC3, 0x20E1, 0x0941, 0x0931, 0x0042, 0x0BA2, + 0x0AA3, 0x0992, 0x0863, 0x08B3, 0x11B2, 0x0902, 0x1283, 0x09FF, + 0x0B83, 0x0982, 0x0932, 0x0BFE, 0x0B32, 0x0BBF, 0x11FE, 0x036F, + 0x0851, 0x08B1, 0x18A2, 0x11EE, 0x0A52, 0x0BB2, 0x01FD, 0x0A43, + 0x1A63, 0x1193, 0x0B91, 0x0043, 0x1231, 0x0A26, 0x0AB1, 0x03FD, + 0x096F, 0x00B2, 0x0983, 0x0A72, 0x01CE, 0x0BDD, 0x0022, 0x0B11, + 0x1213, 0x0B6D, 0x017E, 0x1333, 0x0112, 0x0852, 0x02D2, 0x097F, + 0x01EF, 0x0AB2, 0x0293, 0x0853, 0x0BED, 0x0B12, 0x1303, 0x02A1, + 0x0892, 0x0032, 0x0883, 0x0B6E, 0x0292, 0x0A32, 0x037E, 0x0B23, + 0x0103, 0x0A21, 0x0B01, 0x0302, 0x0BCD, 0x00A3, 0x0BCF, 0x0BDE, + 0x0113, 0x01DE, 0x0B5F, 0x0013, 0x0BAF, 0x0223, 0x0222, 0x0A82, + 0x0833, 0x0023, 0x09CF, 0x037D, 0x01AF, 0x095F, 0x03CE, 0x09DF, + 0x01BF, 0x0893, 0x0203, 0x0201, 0x0B4D, 0x03BE, 0x032E, 0x03AE, + 0x0291, 0x0A02, 0x0211, 0x039F, 0x0281, 0x038E, 0x03AD, 0x033F, + 0x035D, 0x033E, 0x034E, 0x034F, 0x0212, 0x03BD, 0x032F, 0x035E, + 0x038F, 0x039E +}; + +static const uint16_t percentile_arr_8x5_1[167] { + 0x0621, 0xFCC2, 0x3443, 0xA433, 0x5532, 0x2551, 0x6CA3, 0x27AE, + 0x6452, 0x8E03, 0x3CB3, 0x4DA2, 0x6DDF, 0x37CD, 0x6F01, 0x1691, + 0x2E82, 0x27BE, 0x1513, 0x34D2, 0x1D22, 0x3E31, 0x2593, 0x2CB2, + 0x1C16, 0x374F, 0x0DD1, 0x2583, 0x6613, 0x0CD1, 0x0C35, 0x1462, + 0x3E81, 0x2612, 0x2C42, 0x3407, 0x14A2, 0x0E02, 0x1CF1, 0x0C06, + 0x17BD, 0x0F7D, 0x1D23, 0x35B1, 0x179F, 0x0D92, 0x0F5E, 0x1451, + 0x04B1, 0x1F6E, 0x0DEF, 0x0D31, 0x374E, 0x15C1, 0x0541, 0x2405, + 0x17AD, 0x0471, 0x1472, 0x0DFE, 0x0711, 0x0FDD, 0x0DFF, 0x0432, + 0x1D82, 0x0423, 0x0F6D, 0x07AF, 0x0F5F, 0x04C1, 0x1542, 0x0561, + 0x0DCF, 0x1D03, 0x1493, 0x0422, 0x0445, 0x0D12, 0x0C25, 0x0415, + 0x0DA1, 0x1591, 0x0DEE, 0x05DE, 0x0C31, 0x0491, 0x0441, 0x0D21, + 0x078D, 0x057D, 0x0C61, 0x0F3F, 0x0581, 0x0D6E, 0x0501, 0x0CA1, + 0x04E1, 0x0DFD, 0x057F, 0x0502, 0x0511, 0x0C82, 0x0483, 0x0C03, + 0x079D, 0x0402, 0x0DDD, 0x0611, 0x05AE, 0x0DCE, 0x056F, 0x0421, + 0x057E, 0x071F, 0x0DBF, 0x05BE, 0x0412, 0x059F, 0x054E, 0x077E, + 0x0C26, 0x05ED, 0x073D, 0x0601, 0x0492, 0x0453, 0x075D, 0x058E, + 0x0F2D, 0x05CD, 0x0571, 0x053E, 0x0692, 0x05BD, 0x054F, 0x055E, + 0x0411, 0x0F1D, 0x074D, 0x059E, 0x05AF, 0x070D, 0x053F, 0x058F, + 0x0413, 0x070F, 0x055D, 0x070E, 0x078F, 0x052E, 0x072F, 0x055F, + 0x078E, 0x0F2E, 0x052F, 0x051F, 0x0417, 0x071E, 0x0781, 0x0622, + 0x0683, 0x0702, 0x073E, 0x076F, 0x079E, 0x07BF, 0x07CE +}; + +static const packed_percentile_table block_pcd_8x5 { + 8, 5, + { 226, 167 }, + { 763, 517 }, + { 0, 178 }, + { percentile_arr_8x5_0, percentile_arr_8x5_1 } +}; +#endif + +#if ASTCENC_BLOCK_MAX_TEXELS >= (8 * 6) +static const uint16_t percentile_arr_8x6_0[273] { + 0x0154, 0xF944, 0xE066, 0xA128, 0x9963, 0x8118, 0x806F, 0x79F2, + 0x79E2, 0x7108, 0xD934, 0x6056, 0x69C3, 0x60F3, 0x5972, 0x59E3, + 0x5075, 0x91B3, 0xC9D2, 0x807E, 0x385F, 0x4153, 0x3943, 0x4162, + 0x3837, 0x3847, 0x7173, 0x31D3, 0x6948, 0x3046, 0x307F, 0x5827, + 0x3114, 0x32C1, 0x3076, 0x2A4D, 0x58E3, 0x306E, 0x2924, 0x2A61, + 0x29F1, 0x50D3, 0x704F, 0x210C, 0x2BA1, 0x2225, 0x2873, 0x4865, + 0x2206, 0x8341, 0x2006, 0x3B21, 0x18F2, 0x21C2, 0x1A1F, 0x23C1, + 0x3AE1, 0x1855, 0x19D1, 0x1A15, 0x3815, 0x1207, 0x1835, 0x2A2E, + 0x1A16, 0x1836, 0x2271, 0x2845, 0x1A2D, 0x11E1, 0x1816, 0x1171, + 0x2217, 0x1952, 0x12D1, 0x3904, 0x125D, 0x4BB1, 0x207D, 0x10E2, + 0x1026, 0x2025, 0x12F1, 0x28F1, 0x105D, 0x1235, 0x12A2, 0x1007, + 0x123D, 0x1A05, 0x1072, 0x1331, 0x101E, 0x0951, 0x10D2, 0x1057, + 0x1B92, 0x185E, 0x1251, 0x19A2, 0x186D, 0x0B81, 0x2BEE, 0x080E, + 0x1A33, 0x1942, 0x0B13, 0x0B51, 0x11A3, 0x0923, 0x2322, 0x09B1, + 0x184E, 0x1161, 0x18D1, 0x0933, 0x0B93, 0x4A62, 0x1017, 0x082F, + 0x0A42, 0x0B82, 0x0AA3, 0x0A41, 0x08C2, 0x08B3, 0x0A3E, 0x22B3, + 0x0871, 0x1BBF, 0x09C1, 0x0AC2, 0x09B2, 0x0BEF, 0x082E, 0x1062, + 0x0922, 0x08C3, 0x1063, 0x0A53, 0x0BDF, 0x080F, 0x0B42, 0x0A83, + 0x084D, 0x103F, 0x0931, 0x08E1, 0x0A0F, 0x1BA2, 0x09FF, 0x1332, + 0x03FF, 0x0941, 0x12C3, 0x0A63, 0x003D, 0x0842, 0x083E, 0x0B83, + 0x0BB2, 0x0A31, 0x0932, 0x1102, 0x0992, 0x0982, 0x1051, 0x08B1, + 0x0A2F, 0x121E, 0x02B1, 0x0A4E, 0x11EE, 0x00A2, 0x1022, 0x0043, + 0x0A52, 0x0A1D, 0x0226, 0x1193, 0x03DD, 0x08B2, 0x0BFD, 0x0A43, + 0x0A13, 0x0AB2, 0x01FD, 0x09FE, 0x020D, 0x081F, 0x0B33, 0x0053, + 0x0B91, 0x0293, 0x0B11, 0x0B7F, 0x0AA1, 0x0B03, 0x0A0E, 0x03FE, + 0x01CE, 0x0B6F, 0x0183, 0x0912, 0x023F, 0x0852, 0x0A21, 0x0323, + 0x03ED, 0x0A32, 0x13AF, 0x0272, 0x08A3, 0x0B12, 0x0083, 0x0832, + 0x13CD, 0x0223, 0x0A92, 0x0092, 0x0AD2, 0x0301, 0x0302, 0x0BDE, + 0x0A22, 0x01EF, 0x0B5F, 0x0103, 0x0BCF, 0x096F, 0x017E, 0x0113, + 0x01DE, 0x0823, 0x0282, 0x0B6E, 0x015F, 0x0813, 0x01AF, 0x01CF, + 0x0B7E, 0x0033, 0x01DF, 0x0BCE, 0x01BF, 0x036D, 0x0A03, 0x017F, + 0x03BE, 0x0201, 0x0893, 0x038E, 0x034D, 0x03AE, 0x0202, 0x039F, + 0x0291, 0x0A11, 0x032E, 0x033F, 0x034F, 0x0281, 0x037D, 0x03BD, + 0x0212, 0x033E, 0x035E, 0x034E, 0x035D, 0x03AD, 0x032F, 0x038F, + 0x039E +}; + +static const uint16_t percentile_arr_8x6_1[186] { + 0x0621, 0xFC33, 0x37AE, 0x1CC2, 0x2C43, 0xAD32, 0x34A3, 0x4551, + 0x6452, 0x5C62, 0x1FCD, 0x14F1, 0x4CB3, 0x24D2, 0x15DF, 0x0FBE, + 0x2603, 0x3DA2, 0x2E31, 0x25D1, 0x25EF, 0x0D22, 0x2E91, 0x1E82, + 0x0FBD, 0x1513, 0x0CB2, 0x0CD1, 0x0F4F, 0x1F7D, 0x1701, 0x0C16, + 0x2593, 0x2C42, 0x0C72, 0x14A2, 0x0F6E, 0x0C35, 0x0C71, 0x0D83, + 0x0C07, 0x1DFF, 0x043E, 0x1613, 0x07DD, 0x0FAD, 0x1451, 0x076D, + 0x0E81, 0x05FE, 0x0406, 0x0E0D, 0x045D, 0x2612, 0x0E02, 0x07AF, + 0x0DB1, 0x0F5E, 0x15C1, 0x0C23, 0x1523, 0x0C1F, 0x0D92, 0x04B1, + 0x0D31, 0x0432, 0x0D61, 0x0F4E, 0x0D41, 0x0DEE, 0x0D42, 0x04C1, + 0x0CE1, 0x079F, 0x0C2E, 0x0405, 0x0C22, 0x0461, 0x0E1D, 0x0582, + 0x073F, 0x0571, 0x0C4D, 0x0DFD, 0x05CE, 0x0C6D, 0x05DE, 0x0415, + 0x0C45, 0x075F, 0x0C41, 0x0D03, 0x05A1, 0x0711, 0x05CF, 0x0425, + 0x0C93, 0x0D21, 0x0591, 0x043D, 0x0D12, 0x0501, 0x040F, 0x0511, + 0x0431, 0x0C03, 0x04A1, 0x078D, 0x0581, 0x041E, 0x040D, 0x0C02, + 0x040E, 0x05DD, 0x057F, 0x079D, 0x042D, 0x0D9F, 0x0502, 0x056E, + 0x0412, 0x071F, 0x044E, 0x05BF, 0x0C1D, 0x0482, 0x05AE, 0x042F, + 0x057D, 0x0491, 0x054E, 0x047D, 0x0DBE, 0x0611, 0x0492, 0x0601, + 0x05BD, 0x05CD, 0x0426, 0x05ED, 0x072D, 0x073D, 0x0483, 0x0F5D, + 0x0421, 0x056F, 0x053F, 0x058E, 0x054F, 0x078F, 0x053E, 0x059E, + 0x057E, 0x051F, 0x055D, 0x0413, 0x070D, 0x05AF, 0x0411, 0x0453, + 0x0D5E, 0x077E, 0x052F, 0x070F, 0x074D, 0x0692, 0x070E, 0x072F, + 0x072E, 0x058F, 0x071D, 0x052E, 0x0417, 0x073E, 0x0781, 0x078E, + 0x055F, 0x060E, 0x0622, 0x0683, 0x0702, 0x071E, 0x076F, 0x079E, + 0x07BF, 0x07CE +}; + +static const packed_percentile_table block_pcd_8x6 { + 8, 6, + { 273, 186 }, + { 880, 300 }, + { 0, 64 }, + { percentile_arr_8x6_0, percentile_arr_8x6_1 } +}; +#endif + +#if ASTCENC_BLOCK_MAX_TEXELS >= (8 * 8) +static const uint16_t percentile_arr_8x8_0[347] { + 0x0334, 0xFD44, 0xDD14, 0x9154, 0x9B08, 0x906A, 0x8928, 0x8108, + 0xE866, 0xC918, 0x606F, 0xC0FE, 0x5963, 0x58EE, 0x6534, 0x505A, + 0x51E2, 0xA8CF, 0x5354, 0x5314, 0x5134, 0x5524, 0x48F3, 0x504B, + 0x487E, 0x5344, 0x49C3, 0x4972, 0x49F2, 0x4856, 0xD0EF, 0x81D2, + 0x78DE, 0x4261, 0x3AC1, 0x71E3, 0x6879, 0x390C, 0x3143, 0x31B3, + 0x385F, 0x3153, 0x306E, 0x3037, 0x30DF, 0x3162, 0x304F, 0x3075, + 0xB03B, 0x2847, 0x28E3, 0x2914, 0x507F, 0x28BF, 0x5173, 0x5073, + 0x20D3, 0x2A06, 0x2827, 0x2508, 0x2229, 0x29D3, 0x204A, 0x207A, + 0x2046, 0x4148, 0x20FD, 0x4225, 0x23A1, 0x3944, 0x2065, 0x1924, + 0x2324, 0x1806, 0x19F1, 0x2215, 0x1876, 0x22AD, 0x502B, 0x1B04, + 0x18F2, 0x3A4D, 0x3216, 0x3504, 0x18DD, 0x1B21, 0x10CE, 0x1869, + 0x1B41, 0x1855, 0x1207, 0x1AE1, 0x2845, 0x19D1, 0x2A0A, 0x1A2D, + 0x2A1A, 0x11C2, 0x1A0B, 0x1217, 0x2816, 0x121B, 0x1271, 0x2AD1, + 0x1035, 0x1015, 0x287D, 0x12F1, 0x43C1, 0x1171, 0x1A05, 0x08E2, + 0x11E1, 0x3251, 0x2049, 0x20F1, 0x12CD, 0x0A39, 0x1219, 0x1059, + 0x1104, 0x1036, 0x1872, 0x3007, 0x08ED, 0x205E, 0x1026, 0x0952, + 0x1392, 0x1019, 0x0951, 0x100A, 0x13EE, 0x08D2, 0x1242, 0x0ABD, + 0x22A2, 0x0BDF, 0x2B81, 0x0A35, 0x13B1, 0x0839, 0x13BF, 0x0A33, + 0x1B31, 0x205D, 0x1241, 0x183A, 0x2025, 0x0B93, 0x0A3D, 0x1017, + 0x1313, 0x1253, 0x082A, 0x204E, 0x09A2, 0x080B, 0x0A1F, 0x125D, + 0x0A2E, 0x081A, 0x08D1, 0x082F, 0x086D, 0x1B82, 0x0A09, 0x0B22, + 0x1062, 0x11A3, 0x2161, 0x0923, 0x129F, 0x1A62, 0x0871, 0x0942, + 0x081B, 0x1133, 0x18AE, 0x0A9E, 0x0863, 0x09FF, 0x18C2, 0x0B51, + 0x08BD, 0x0AA3, 0x09B1, 0x1AC2, 0x08B3, 0x0829, 0x0BEF, 0x0B83, + 0x0AAE, 0x0A8D, 0x1857, 0x185B, 0x08AF, 0x103F, 0x08C3, 0x09B2, + 0x0A4E, 0x11C1, 0x0A31, 0x0B42, 0x0A83, 0x0BFF, 0x13DD, 0x00CD, + 0x0AB3, 0x0842, 0x08BE, 0x0922, 0x1A8E, 0x08E1, 0x002E, 0x0BA2, + 0x0A8F, 0x2263, 0x0252, 0x0B32, 0x0AC3, 0x0941, 0x0A43, 0x083D, + 0x083E, 0x0A3E, 0x084D, 0x1131, 0x136F, 0x0AB1, 0x0193, 0x0BFD, + 0x0391, 0x0851, 0x13AF, 0x0843, 0x0213, 0x1226, 0x0932, 0x03B2, + 0x0902, 0x0BCD, 0x0221, 0x089E, 0x00B1, 0x0BDE, 0x03FE, 0x02A1, + 0x0982, 0x009F, 0x080E, 0x0B5F, 0x02BE, 0x0A32, 0x0A2A, 0x01EE, + 0x0053, 0x0AB2, 0x0192, 0x09FD, 0x0052, 0x0B03, 0x0293, 0x00A2, + 0x0B7F, 0x0BED, 0x0311, 0x08B2, 0x0A72, 0x088E, 0x0333, 0x0B12, + 0x0A23, 0x0822, 0x0083, 0x11CE, 0x021D, 0x08A3, 0x088F, 0x029D, + 0x0A22, 0x0A3F, 0x01FE, 0x020F, 0x0983, 0x02D2, 0x0292, 0x0B23, + 0x001E, 0x0BCF, 0x03CE, 0x09AF, 0x0B02, 0x0301, 0x022F, 0x137E, + 0x021E, 0x09EF, 0x016F, 0x0112, 0x097E, 0x080F, 0x020D, 0x0092, + 0x01DE, 0x09DF, 0x0032, 0x0033, 0x0A82, 0x03BE, 0x0B6E, 0x001F, + 0x020E, 0x0023, 0x09CF, 0x0113, 0x0103, 0x0013, 0x0BAE, 0x0203, + 0x0BAD, 0x01BF, 0x034F, 0x095F, 0x036D, 0x0202, 0x017F, 0x0093, + 0x0201, 0x034D, 0x0212, 0x035D, 0x03BD, 0x0B3F, 0x035E, 0x0211, + 0x0281, 0x0291, 0x032E, 0x037D, 0x034E, 0x038E, 0x039F, 0x032F, + 0x033E, 0x038F, 0x039E +}; + +static const uint16_t percentile_arr_8x8_1[208] { + 0x0621, 0x3443, 0x47CD, 0x97AE, 0xFC62, 0x14F1, 0x24C2, 0x25DF, + 0x3C33, 0x1C52, 0x9C72, 0x0FBE, 0x0C5D, 0x343E, 0x24A3, 0x1551, + 0x5D32, 0x1CD2, 0x15EF, 0x4E31, 0x04DD, 0x1FDD, 0x174F, 0x0DD1, + 0x3E0D, 0x15FF, 0x0DA2, 0x1E03, 0x17BD, 0x177D, 0x14B3, 0x0471, + 0x0CAE, 0x1C1F, 0x04D1, 0x0F6E, 0x0DFE, 0x1C42, 0x0C16, 0x0D22, + 0x0C9F, 0x2C2E, 0x0FAD, 0x0571, 0x147D, 0x0C07, 0x04B2, 0x0F6D, + 0x0F5E, 0x07AF, 0x146D, 0x0C51, 0x0593, 0x2583, 0x0C4E, 0x040B, + 0x0C35, 0x0513, 0x0E91, 0x0406, 0x073F, 0x144D, 0x0561, 0x048F, + 0x0F01, 0x0F4E, 0x0CA2, 0x075F, 0x1682, 0x04E1, 0x0C1A, 0x04BD, + 0x0542, 0x0D41, 0x0DEE, 0x04CD, 0x0DCF, 0x04B1, 0x0C15, 0x0C3D, + 0x0423, 0x0592, 0x0DDE, 0x0422, 0x0432, 0x05FD, 0x0DC1, 0x05B1, + 0x0DCE, 0x0612, 0x0C2F, 0x0445, 0x0602, 0x0531, 0x0439, 0x0E81, + 0x0582, 0x0C61, 0x061D, 0x049E, 0x0405, 0x0409, 0x0DBE, 0x079F, + 0x0D21, 0x04C1, 0x0C0A, 0x0E13, 0x04AD, 0x040E, 0x0581, 0x0419, + 0x05DD, 0x0D03, 0x049D, 0x0449, 0x0429, 0x048E, 0x0DA1, 0x0425, + 0x0512, 0x0501, 0x0431, 0x0523, 0x0441, 0x042D, 0x040F, 0x0D7D, + 0x0511, 0x0502, 0x05BF, 0x04A1, 0x0C03, 0x0402, 0x079D, 0x05AE, + 0x075D, 0x057F, 0x041D, 0x048D, 0x042A, 0x0453, 0x05AF, 0x078D, + 0x0C0D, 0x073D, 0x0491, 0x0591, 0x05BD, 0x072D, 0x057E, 0x051F, + 0x0482, 0x0492, 0x041E, 0x0412, 0x0D9F, 0x0421, 0x0493, 0x0711, + 0x056E, 0x059E, 0x054E, 0x0611, 0x05ED, 0x074D, 0x070F, 0x056F, + 0x052F, 0x053F, 0x071F, 0x054F, 0x05CD, 0x0483, 0x055E, 0x072F, + 0x0E01, 0x0426, 0x058F, 0x0413, 0x078F, 0x071D, 0x055F, 0x058E, + 0x0411, 0x053E, 0x071E, 0x055D, 0x077E, 0x052E, 0x0692, 0x0417, + 0x070D, 0x078E, 0x070E, 0x072E, 0x041B, 0x060E, 0x0622, 0x0683, + 0x068D, 0x0702, 0x073E, 0x076F, 0x0781, 0x079E, 0x07BF, 0x07CE +}; + +static const packed_percentile_table block_pcd_8x8 { + 8, 8, + { 347, 208 }, + { 1144, 267 }, + { 0, 38 }, + { percentile_arr_8x8_0, percentile_arr_8x8_1 } +}; +#endif + +#if ASTCENC_BLOCK_MAX_TEXELS >= (10 * 5) +static const uint16_t percentile_arr_10x5_0[274] { + 0x0165, 0xF975, 0xD866, 0xC056, 0xA946, 0x90C6, 0x90F5, 0x8963, + 0x80D6, 0x80E6, 0x60F3, 0x61C3, 0x59F2, 0xA927, 0x5075, 0x4847, + 0x5153, 0x4955, 0x49E2, 0x48B6, 0x41D2, 0x4943, 0x8305, 0x8172, + 0x4046, 0x4037, 0x40A7, 0x70B7, 0x7AC1, 0x31E3, 0x7027, 0x30E5, + 0x69D3, 0x99B3, 0x3315, 0x6115, 0x3136, 0x3076, 0x3173, 0x30D5, + 0x3106, 0x8962, 0x2916, 0x30C7, 0x5126, 0x30D3, 0x2956, 0x5117, + 0x2B41, 0x2AE1, 0x2A61, 0x29F1, 0x2306, 0x2145, 0x4A85, 0x2057, + 0x40E3, 0x4137, 0x3B21, 0x23C1, 0x2065, 0x1925, 0x51C2, 0x5225, + 0x4935, 0x1AD1, 0x23A1, 0x19D1, 0x1A71, 0x4055, 0x1873, 0x1A86, + 0x1295, 0x18F2, 0x28A6, 0x1952, 0x4AA5, 0x20B5, 0x10C5, 0x2AA2, + 0x11E1, 0x1107, 0x10D2, 0x2171, 0x1351, 0x3036, 0x1331, 0x1BEE, + 0x2035, 0x1045, 0x1313, 0x0A15, 0x1087, 0x1296, 0x13EF, 0x18E2, + 0x1151, 0x1086, 0x10F1, 0x08A5, 0x12C2, 0x1BFF, 0x1095, 0x1A62, + 0x1322, 0x0942, 0x1026, 0x1872, 0x1062, 0x0897, 0x1123, 0x08D1, + 0x1A06, 0x0806, 0x137F, 0x13B1, 0x13DF, 0x1A51, 0x09B1, 0x0A83, + 0x1015, 0x22F1, 0x0961, 0x0B81, 0x12B3, 0x0A35, 0x0AA3, 0x20B3, + 0x08C3, 0x2342, 0x0933, 0x0A33, 0x09A2, 0x10C2, 0x0896, 0x2205, + 0x0825, 0x20E1, 0x0922, 0x1242, 0x0B16, 0x0B32, 0x09A3, 0x0AC3, + 0x0BBF, 0x0B93, 0x0071, 0x0931, 0x0A41, 0x2392, 0x13FE, 0x09C1, + 0x0B07, 0x0016, 0x1182, 0x09B2, 0x0A26, 0x0132, 0x0941, 0x0A93, + 0x0992, 0x1063, 0x1217, 0x01FF, 0x11EE, 0x1216, 0x0B23, 0x0B82, + 0x0042, 0x1102, 0x0213, 0x0B6F, 0x09FE, 0x1207, 0x0807, 0x18B1, + 0x0253, 0x0AB1, 0x08A2, 0x13FD, 0x01FD, 0x1983, 0x0AB2, 0x0A31, + 0x016F, 0x0B11, 0x00B2, 0x0851, 0x0AD2, 0x0993, 0x0BDD, 0x12A1, + 0x017F, 0x0A97, 0x1022, 0x0383, 0x0843, 0x0A52, 0x03A2, 0x097E, + 0x0817, 0x03B2, 0x0A43, 0x09EF, 0x0A63, 0x0B33, 0x0B03, 0x0292, + 0x0272, 0x09CE, 0x0287, 0x136D, 0x0053, 0x0B12, 0x0083, 0x0892, + 0x0112, 0x1282, 0x03ED, 0x0852, 0x0301, 0x1391, 0x0232, 0x0B7E, + 0x0221, 0x08A3, 0x0BCD, 0x0BCF, 0x036E, 0x09DE, 0x0103, 0x03DE, + 0x0832, 0x0BAF, 0x0302, 0x13CE, 0x035F, 0x0093, 0x0A23, 0x01DF, + 0x0013, 0x0A22, 0x0023, 0x0113, 0x09AF, 0x01BF, 0x0033, 0x095F, + 0x0203, 0x0281, 0x09CF, 0x037D, 0x0201, 0x0B4D, 0x03AE, 0x03BE, + 0x0291, 0x035E, 0x038E, 0x0B9F, 0x03AD, 0x0202, 0x034F, 0x0211, + 0x035D, 0x0212, 0x032E, 0x039E, 0x033F, 0x034E, 0x03BD, 0x032F, + 0x033E, 0x038F +}; + +static const uint16_t percentile_arr_10x5_1[180] { + 0x0532, 0xFCA3, 0x3621, 0x6E82, 0x2CC2, 0x3D51, 0x3F01, 0x2691, + 0x17AE, 0x35A2, 0x74B3, 0x1603, 0x4433, 0x3C43, 0x6C35, 0x25D1, + 0x1D13, 0x15DF, 0x37CD, 0x0D93, 0x1D22, 0x0E81, 0x1452, 0x0CD2, + 0x37BE, 0x0CB2, 0x3407, 0x1523, 0x0C16, 0x0CB5, 0x0C96, 0x1486, + 0x2631, 0x1506, 0x0F4F, 0x1583, 0x0CD1, 0x2CA2, 0x2612, 0x1613, + 0x1602, 0x1F11, 0x179F, 0x17BD, 0x15B1, 0x0406, 0x1D41, 0x0CF1, + 0x0D31, 0x0442, 0x1C62, 0x0F6E, 0x077D, 0x0C51, 0x0445, 0x0D15, + 0x2592, 0x0CB1, 0x05EF, 0x0542, 0x17AF, 0x1425, 0x075E, 0x0FAD, + 0x0CC1, 0x0503, 0x0512, 0x15C1, 0x0C95, 0x0415, 0x0505, 0x0F4E, + 0x04A5, 0x0493, 0x0C32, 0x0F5F, 0x04E1, 0x0521, 0x0C85, 0x07DD, + 0x0582, 0x15FF, 0x05CF, 0x0405, 0x0D91, 0x05A1, 0x05FE, 0x0C23, + 0x0561, 0x0472, 0x0471, 0x0C22, 0x0DEE, 0x076D, 0x0502, 0x0426, + 0x0C61, 0x0D7D, 0x0525, 0x05DE, 0x0DCE, 0x079D, 0x0692, 0x0441, + 0x0C91, 0x05DD, 0x0511, 0x057F, 0x0611, 0x0DFD, 0x078D, 0x056E, + 0x0492, 0x04A1, 0x073F, 0x0C31, 0x05BE, 0x0483, 0x0571, 0x056F, + 0x0D9F, 0x0581, 0x0501, 0x057E, 0x05BF, 0x078F, 0x0516, 0x05ED, + 0x0402, 0x0F7E, 0x0482, 0x054E, 0x075D, 0x071F, 0x05CD, 0x0535, + 0x05AE, 0x0C11, 0x058F, 0x05AF, 0x0421, 0x0413, 0x0601, 0x054F, + 0x073D, 0x059E, 0x0487, 0x070F, 0x078E, 0x0781, 0x053E, 0x0403, + 0x072D, 0x055D, 0x05BD, 0x079E, 0x0D8E, 0x0412, 0x052E, 0x074D, + 0x053F, 0x051F, 0x070E, 0x055F, 0x072F, 0x052F, 0x070D, 0x055E, + 0x0417, 0x0453, 0x072E, 0x0622, 0x0683, 0x0702, 0x071D, 0x071E, + 0x073E, 0x076F, 0x07BF, 0x07CE +}; + +static const packed_percentile_table block_pcd_10x5 { + 10, 5, + { 274, 180 }, + { 954, 324 }, + { 0, 79 }, + { percentile_arr_10x5_0, percentile_arr_10x5_1 } +}; +#endif + +#if ASTCENC_BLOCK_MAX_TEXELS >= (10 * 6) +static const uint16_t percentile_arr_10x6_0[325] { + 0x01A4, 0xF954, 0xA066, 0x9975, 0x80F5, 0x7056, 0x6918, 0x6963, + 0x58C6, 0x5946, 0x5928, 0x5174, 0x586F, 0xA0E6, 0x5108, 0x48D6, + 0x49E2, 0x40F3, 0x9172, 0x41F2, 0xB875, 0x3927, 0x39C3, 0xA953, + 0x3934, 0x3305, 0x30B6, 0x6943, 0x31D2, 0x3876, 0x3037, 0x2955, + 0x30A7, 0x32C1, 0x29B3, 0x3027, 0x287E, 0x30B7, 0x29E3, 0x5846, + 0x2B15, 0x2847, 0x3162, 0x5173, 0x4936, 0x285F, 0x48D3, 0x2164, + 0x4906, 0x20E5, 0x2915, 0x2116, 0x407F, 0x20D5, 0x2A61, 0x4117, + 0x20E3, 0x2126, 0x4148, 0x206E, 0x39D3, 0x2145, 0x41B4, 0x1B06, + 0x2114, 0x2165, 0x5321, 0x5A85, 0x1A4D, 0x1A1F, 0x19F1, 0x3341, + 0x184F, 0x1956, 0x3125, 0x30C7, 0x28F2, 0x1937, 0x1AE1, 0x1073, + 0x1BA1, 0x1935, 0x110C, 0x1BC1, 0x3A25, 0x19C2, 0x1295, 0x122E, + 0x1944, 0x11D1, 0x1124, 0x1857, 0x22D1, 0x2286, 0x1A2D, 0x12A2, + 0x2107, 0x1055, 0x2065, 0x0A71, 0x2152, 0x10C5, 0x10D2, 0x1331, + 0x08B5, 0x1171, 0x2836, 0x10A6, 0x0904, 0x123D, 0x20F1, 0x12A5, + 0x10E2, 0x107D, 0x1AF1, 0x1313, 0x0951, 0x11E1, 0x1B22, 0x1B51, + 0x0835, 0x101E, 0x0A5D, 0x0A15, 0x3045, 0x0A96, 0x08A5, 0x1142, + 0x12A3, 0x1872, 0x085D, 0x09B1, 0x100E, 0x0887, 0x0886, 0x086D, + 0x0933, 0x12B3, 0x0897, 0x08B3, 0x0A33, 0x0923, 0x1095, 0x0BEE, + 0x2BB1, 0x085E, 0x1283, 0x0A51, 0x1026, 0x0A06, 0x12C2, 0x08D1, + 0x11A2, 0x13BF, 0x08C3, 0x10C2, 0x0A3E, 0x0BDF, 0x0B81, 0x13EF, + 0x0A35, 0x0B16, 0x082F, 0x2161, 0x1B32, 0x0806, 0x084E, 0x11A3, + 0x1015, 0x1122, 0x2931, 0x0342, 0x0825, 0x0A0F, 0x0896, 0x0A05, + 0x0241, 0x09C1, 0x083F, 0x0A42, 0x0071, 0x0B07, 0x082E, 0x0393, + 0x12B1, 0x0A62, 0x0226, 0x0A2F, 0x0B92, 0x0063, 0x0932, 0x0862, + 0x09FF, 0x0A31, 0x00E1, 0x12B2, 0x09B2, 0x0AC3, 0x0941, 0x0293, + 0x1323, 0x104D, 0x003E, 0x083D, 0x0992, 0x1382, 0x03FF, 0x0A13, + 0x1016, 0x0A53, 0x0182, 0x1007, 0x0AA1, 0x080F, 0x0A16, 0x0A1E, + 0x0042, 0x0902, 0x13DD, 0x0BB2, 0x0A63, 0x00A2, 0x08B1, 0x03FE, + 0x1207, 0x08B2, 0x0B83, 0x09EE, 0x0311, 0x0A87, 0x0BAF, 0x03A2, + 0x09FD, 0x0051, 0x0B33, 0x020D, 0x09CE, 0x0217, 0x021D, 0x0817, + 0x020E, 0x0A4E, 0x001F, 0x0BFD, 0x0297, 0x0983, 0x0A92, 0x0252, + 0x0243, 0x0B03, 0x0193, 0x036F, 0x0B12, 0x0043, 0x0822, 0x0A21, + 0x01FE, 0x0853, 0x037F, 0x023F, 0x0BED, 0x02D2, 0x0B91, 0x0232, + 0x0282, 0x0912, 0x08A3, 0x0852, 0x0223, 0x0BCD, 0x0083, 0x0301, + 0x0832, 0x01EF, 0x0892, 0x0302, 0x0A72, 0x03DE, 0x0893, 0x0BCF, + 0x09DE, 0x03CE, 0x035F, 0x0833, 0x0023, 0x0103, 0x017E, 0x0813, + 0x01CF, 0x01BF, 0x016F, 0x0A22, 0x037E, 0x0113, 0x01AF, 0x0B6E, + 0x03BE, 0x0201, 0x0A03, 0x01DF, 0x036D, 0x03AE, 0x015F, 0x0281, + 0x033E, 0x0A02, 0x038E, 0x017F, 0x0291, 0x034D, 0x03BD, 0x0B7D, + 0x03AD, 0x0211, 0x0212, 0x034F, 0x032E, 0x039F, 0x034E, 0x035D, + 0x035E, 0x033F, 0x039E, 0x032F, 0x038F +}; + +static const uint16_t percentile_arr_10x6_1[199] { + 0x0621, 0xBD32, 0x5CA3, 0x1FAE, 0x64C2, 0x1D51, 0x6C33, 0xFC43, + 0x5CB3, 0x25A2, 0x2E82, 0x35D1, 0x4F01, 0x3FBE, 0x3691, 0x2DDF, + 0x2E03, 0x3FCD, 0x14D2, 0x1CF1, 0x0C52, 0x3C35, 0x2D22, 0x1513, + 0x1462, 0x54B2, 0x0E31, 0x4E81, 0x1593, 0x1D23, 0x1CD1, 0x14B5, + 0x2FBD, 0x0C07, 0x1D06, 0x0DEF, 0x14A2, 0x1612, 0x1F4F, 0x0C16, + 0x1F7D, 0x0C96, 0x0486, 0x1F9F, 0x0D42, 0x4583, 0x0E02, 0x0472, + 0x0DB1, 0x1613, 0x0FAD, 0x0D41, 0x0F11, 0x0E0D, 0x1C42, 0x143E, + 0x076E, 0x04B1, 0x0FAF, 0x0D61, 0x0531, 0x0C71, 0x0DFF, 0x0DFE, + 0x0406, 0x0C45, 0x0451, 0x0D15, 0x05C1, 0x2CC1, 0x141F, 0x0CE1, + 0x0FDD, 0x0C22, 0x0582, 0x0D92, 0x0571, 0x0F6D, 0x0C93, 0x045D, + 0x0F5E, 0x044D, 0x0423, 0x0D05, 0x0425, 0x0C95, 0x04A5, 0x0DCE, + 0x075F, 0x0E1D, 0x0503, 0x042E, 0x0D91, 0x0512, 0x0DDE, 0x05A1, + 0x074E, 0x0C32, 0x0431, 0x0415, 0x0D21, 0x05EE, 0x040E, 0x0DDD, + 0x0485, 0x1525, 0x0491, 0x0C26, 0x046D, 0x0C05, 0x05CF, 0x05FD, + 0x0E92, 0x073F, 0x0C0D, 0x043D, 0x0502, 0x0C1E, 0x041D, 0x0461, + 0x04A1, 0x0511, 0x0581, 0x05BD, 0x0C41, 0x059F, 0x05BF, 0x040F, + 0x0C7D, 0x0402, 0x054E, 0x057D, 0x0403, 0x078D, 0x05AE, 0x042D, + 0x0483, 0x079D, 0x0D7F, 0x0482, 0x0611, 0x056E, 0x0516, 0x05BE, + 0x0535, 0x044E, 0x05AF, 0x0DED, 0x042F, 0x0492, 0x058E, 0x078F, + 0x0412, 0x057E, 0x053E, 0x0F1F, 0x073D, 0x0601, 0x0501, 0x075D, + 0x059E, 0x05CD, 0x053F, 0x054F, 0x055E, 0x055D, 0x0421, 0x074D, + 0x051F, 0x072F, 0x0781, 0x0411, 0x0D6F, 0x077E, 0x0487, 0x070E, + 0x070F, 0x072D, 0x058F, 0x078E, 0x079E, 0x052E, 0x0413, 0x072E, + 0x071D, 0x052F, 0x055F, 0x073E, 0x0417, 0x0453, 0x060E, 0x0622, + 0x0683, 0x0702, 0x070D, 0x071E, 0x076F, 0x07BF, 0x07CE +}; + +static const packed_percentile_table block_pcd_10x6 { + 10, 6, + { 325, 199 }, + { 922, 381 }, + { 0, 78 }, + { percentile_arr_10x6_0, percentile_arr_10x6_1 } +}; +#endif + +#if ASTCENC_BLOCK_MAX_TEXELS >= (10 * 8) +static const uint16_t percentile_arr_10x8_0[400] { + 0x0154, 0xAB34, 0xAD44, 0x8308, 0x7866, 0x7B64, 0x79A4, 0x7975, + 0x686A, 0x6908, 0xC514, 0x6174, 0x6128, 0x6118, 0x5B54, 0x5163, + 0xF856, 0x50F5, 0x986F, 0xDD34, 0x48FE, 0x4972, 0x48E6, 0x4146, + 0x48EE, 0x40F3, 0x4AC1, 0x38C6, 0x41E2, 0xBB05, 0x707E, 0x38D6, + 0x3927, 0x6B14, 0x384B, 0x3948, 0x3153, 0x385A, 0x3134, 0x6B15, + 0x39F2, 0x30CF, 0x3143, 0x91D2, 0x31C3, 0x60EF, 0x5973, 0x3076, + 0x28D3, 0x3261, 0x2875, 0x28DE, 0x290C, 0x51E3, 0x28A7, 0x20E3, + 0x2962, 0x2B06, 0x2917, 0x483B, 0x20B6, 0x2D24, 0x206E, 0x285F, + 0x20B7, 0x2936, 0x4047, 0x2037, 0x20DF, 0x28BF, 0x21B4, 0x21B3, + 0x1D08, 0x2027, 0x404F, 0x3846, 0x2116, 0x187F, 0x1879, 0x2285, + 0x1A29, 0x3915, 0x4873, 0x1955, 0x3114, 0x1B44, 0x2165, 0x107A, + 0x1956, 0x6137, 0x1106, 0x3145, 0x1B21, 0x19D3, 0x12AD, 0x1B41, + 0x1AD1, 0x1126, 0x18F2, 0x282B, 0x40E5, 0x20D5, 0x2A0A, 0x284A, + 0x1286, 0x1295, 0x121A, 0x2A0B, 0x321B, 0x122D, 0x10FD, 0x13A1, + 0x32A2, 0x12E1, 0x1164, 0x13C1, 0x124D, 0x1239, 0x4504, 0x10C7, + 0x22F1, 0x11F1, 0x0AC2, 0x2125, 0x1225, 0x0B04, 0x1107, 0x1069, + 0x1A19, 0x13BF, 0x2A96, 0x08D2, 0x1271, 0x0952, 0x2BDF, 0x0B31, + 0x1251, 0x2124, 0x0B13, 0x12BD, 0x1233, 0x13EE, 0x2144, 0x0B16, + 0x0A15, 0x18E2, 0x08DD, 0x1097, 0x0857, 0x0B24, 0x0AA5, 0x12A3, + 0x11C2, 0x11D1, 0x10CE, 0x0865, 0x123D, 0x08B3, 0x0B51, 0x1971, + 0x0A41, 0x0A06, 0x1039, 0x080A, 0x0B22, 0x0923, 0x0836, 0x08C3, + 0x0A1F, 0x1072, 0x080B, 0x0935, 0x0855, 0x18A6, 0x0A42, 0x1133, + 0x0A83, 0x0A09, 0x0ACD, 0x0A2E, 0x0887, 0x083A, 0x10C5, 0x085E, + 0x13B1, 0x087D, 0x0819, 0x0A9F, 0x0049, 0x08F1, 0x0BEF, 0x1161, + 0x0B42, 0x09E1, 0x0A05, 0x0904, 0x12AE, 0x029E, 0x0A31, 0x09FF, + 0x0951, 0x0859, 0x001A, 0x082F, 0x0B81, 0x08B5, 0x0A35, 0x082A, + 0x08ED, 0x1142, 0x1262, 0x0B32, 0x08A5, 0x12D2, 0x03DD, 0x0B07, + 0x18AE, 0x083F, 0x00AF, 0x0AB3, 0x086D, 0x0287, 0x0A93, 0x025D, + 0x0816, 0x13FF, 0x0A8D, 0x005D, 0x08D1, 0x0392, 0x0845, 0x0AC3, + 0x08C2, 0x01A3, 0x0AB1, 0x09A2, 0x005B, 0x0B93, 0x02B2, 0x1086, + 0x001B, 0x0863, 0x0216, 0x0AA1, 0x0896, 0x0A8F, 0x084E, 0x0A8E, + 0x0A53, 0x0026, 0x0A26, 0x0382, 0x0807, 0x0862, 0x0029, 0x0871, + 0x00BD, 0x0835, 0x024E, 0x0806, 0x0941, 0x0895, 0x03AF, 0x0A13, + 0x0932, 0x03ED, 0x0BFD, 0x0207, 0x0B83, 0x0993, 0x09B1, 0x03CD, + 0x0A3E, 0x03FE, 0x0A21, 0x0015, 0x0B11, 0x0A43, 0x00E1, 0x136F, + 0x00BE, 0x00A2, 0x0842, 0x0043, 0x0825, 0x082E, 0x0A2A, 0x03DE, + 0x0BA2, 0x0122, 0x0BCF, 0x004D, 0x0323, 0x09C1, 0x0292, 0x083E, + 0x0252, 0x0017, 0x0A72, 0x00CD, 0x0182, 0x0A63, 0x0131, 0x09B2, + 0x0303, 0x0902, 0x0053, 0x035F, 0x0A32, 0x003D, 0x0992, 0x0A2F, + 0x03B2, 0x0ABE, 0x009F, 0x0183, 0x0312, 0x08B1, 0x0B02, 0x0A17, + 0x0B7F, 0x0333, 0x0297, 0x0A23, 0x020F, 0x0282, 0x0851, 0x0822, + 0x03CE, 0x01EE, 0x000E, 0x08B2, 0x0083, 0x0A1D, 0x00A3, 0x0222, + 0x088F, 0x0112, 0x029D, 0x0092, 0x0A3F, 0x0391, 0x089E, 0x0301, + 0x01FD, 0x09BF, 0x01CE, 0x0852, 0x01FE, 0x0013, 0x0903, 0x088E, + 0x037E, 0x021E, 0x01EF, 0x095F, 0x016F, 0x09DE, 0x03BE, 0x020E, + 0x0113, 0x01DF, 0x080F, 0x020D, 0x0833, 0x03AE, 0x0032, 0x03BD, + 0x0823, 0x001E, 0x01AF, 0x0203, 0x034F, 0x0093, 0x0A81, 0x036E, + 0x0291, 0x038E, 0x0A01, 0x001F, 0x017F, 0x01CF, 0x017E, 0x0202, + 0x0BAD, 0x0211, 0x035D, 0x035E, 0x039F, 0x0212, 0x032E, 0x033F, + 0x034D, 0x034E, 0x036D, 0x032F, 0x033E, 0x037D, 0x038F, 0x039E +}; + +static const uint16_t percentile_arr_10x8_1[221] { + 0x0621, 0xDFAE, 0x2443, 0x54C2, 0x37CD, 0x1CF1, 0xFCA3, 0x14D2, + 0x2D32, 0x5551, 0x7DDF, 0x5C33, 0x15D1, 0x3462, 0x24B3, 0x7452, + 0x5FBE, 0x6472, 0x65A2, 0x1D06, 0x445D, 0x15EF, 0x0E31, 0x1D71, + 0x343E, 0x0D42, 0x0CDD, 0x1F01, 0x4691, 0x1435, 0x0E82, 0x0DFF, + 0x17DD, 0x0D22, 0x24B2, 0x1603, 0x04B5, 0x24AE, 0x060D, 0x2D13, + 0x0C7D, 0x0496, 0x17BD, 0x1F4F, 0x1F7D, 0x1486, 0x0593, 0x1C16, + 0x0C07, 0x15FE, 0x041F, 0x14D1, 0x0C9F, 0x0E81, 0x0D15, 0x27AF, + 0x0C2E, 0x0D23, 0x176E, 0x0FAD, 0x1C06, 0x1561, 0x0DB1, 0x040B, + 0x1C4E, 0x0D83, 0x1711, 0x0C42, 0x0C71, 0x1C1A, 0x0D25, 0x04A2, + 0x0C45, 0x076D, 0x0F9F, 0x075F, 0x0E12, 0x046D, 0x048F, 0x1D92, + 0x0602, 0x0C39, 0x174E, 0x0C51, 0x0CA1, 0x075E, 0x05C1, 0x14BD, + 0x0D31, 0x0423, 0x0F3F, 0x0495, 0x0C93, 0x049E, 0x0D05, 0x04E1, + 0x0DEE, 0x0415, 0x04B1, 0x0503, 0x0CCD, 0x042F, 0x0DCF, 0x044D, + 0x0541, 0x1582, 0x05DE, 0x0D01, 0x0487, 0x040A, 0x0516, 0x0CA5, + 0x05FD, 0x05BF, 0x057D, 0x0DA1, 0x0426, 0x040F, 0x071F, 0x0613, + 0x0432, 0x0D12, 0x043D, 0x0425, 0x0461, 0x061D, 0x0D21, 0x0591, + 0x079D, 0x048D, 0x0429, 0x0C49, 0x04C1, 0x042A, 0x040E, 0x0485, + 0x0511, 0x0405, 0x0502, 0x0441, 0x0C19, 0x0692, 0x0535, 0x058F, + 0x041D, 0x059F, 0x072D, 0x04AD, 0x049D, 0x05CE, 0x048E, 0x0C31, + 0x057F, 0x078D, 0x0409, 0x041E, 0x05AE, 0x0611, 0x058E, 0x05DD, + 0x05CD, 0x056E, 0x0483, 0x073D, 0x054E, 0x0D9E, 0x0402, 0x0491, + 0x040D, 0x056F, 0x042D, 0x0581, 0x0421, 0x057E, 0x0781, 0x053E, + 0x0482, 0x078F, 0x0413, 0x052E, 0x0601, 0x0422, 0x0492, 0x055E, + 0x05BE, 0x0F9E, 0x072F, 0x074D, 0x0412, 0x070F, 0x075D, 0x05BD, + 0x051F, 0x071D, 0x073E, 0x077E, 0x0403, 0x0411, 0x078E, 0x055D, + 0x05AF, 0x05ED, 0x052F, 0x053F, 0x070D, 0x070E, 0x072E, 0x054F, + 0x0417, 0x041B, 0x0453, 0x055F, 0x060E, 0x0622, 0x0683, 0x068D, + 0x0702, 0x071E, 0x076F, 0x07BF, 0x07CE +}; + +static const packed_percentile_table block_pcd_10x8 = +{ + 10, 8, + { 400, 221 }, + { 1119, 376 }, + { 0, 52 }, + { percentile_arr_10x8_0, percentile_arr_10x8_1 } +}; +#endif + +#if ASTCENC_BLOCK_MAX_TEXELS >= (10 * 10) +static const uint16_t percentile_arr_10x10_0[453] { + 0x0334, 0x9514, 0x8954, 0x806A, 0x6F14, 0x6724, 0x6108, 0x6364, + 0x5175, 0x5D44, 0x5866, 0x5118, 0x5308, 0xA179, 0x5128, 0xF534, + 0x49A4, 0x5354, 0x9174, 0x486F, 0x48EA, 0x40F3, 0x4963, 0x414A, + 0xF8F9, 0x3984, 0x4172, 0x387E, 0x405A, 0x38DA, 0x38F5, 0x9B05, + 0x30EE, 0x32C1, 0x3261, 0x3D08, 0x31E2, 0x3056, 0x292B, 0x3146, + 0x3127, 0x3315, 0x58CA, 0x58E6, 0x290C, 0x3314, 0x8134, 0x28E3, + 0x28FE, 0x2948, 0x28C6, 0x78DE, 0x28BB, 0x68D6, 0x286E, 0x2173, + 0x2962, 0x21D2, 0x205F, 0x49F2, 0x2917, 0x2306, 0x207F, 0x404F, + 0x2153, 0x2943, 0x20CF, 0x21C3, 0x2073, 0x20D3, 0x2136, 0x183B, + 0x430A, 0x40A7, 0x18B6, 0x2079, 0x2309, 0x2075, 0x184B, 0x20EF, + 0x187A, 0x7837, 0x1B19, 0x20AB, 0x18BA, 0x20B7, 0x1994, 0x19E3, + 0x21B4, 0x49B3, 0x38BF, 0x193B, 0x1876, 0x182B, 0x30F2, 0x193A, + 0x1827, 0x1965, 0x1914, 0x184A, 0x4047, 0x1916, 0x1285, 0x1937, + 0x122D, 0x1915, 0x1321, 0x1955, 0x1046, 0x191B, 0x2106, 0x2919, + 0x1344, 0x1524, 0x12E1, 0x3926, 0x10E5, 0x2295, 0x1159, 0x1145, + 0x10DF, 0x124D, 0x1271, 0x092A, 0x2169, 0x1704, 0x22A2, 0x1164, + 0x13EE, 0x12F1, 0x0AD1, 0x128A, 0x110A, 0x11D3, 0x1286, 0x115A, + 0x2BA1, 0x0BBF, 0x3956, 0x2A89, 0x12AD, 0x10E9, 0x0B41, 0x1A29, + 0x2225, 0x08FD, 0x1107, 0x08D5, 0x191A, 0x1125, 0x1A96, 0x0B04, + 0x18D9, 0x2B16, 0x11F1, 0x0A33, 0x0924, 0x131A, 0x1149, 0x1324, + 0x0BEF, 0x0A99, 0x08CB, 0x123D, 0x1331, 0x0BDF, 0x0872, 0x22A3, + 0x0AC2, 0x1144, 0x0D04, 0x08D2, 0x08CE, 0x0AA9, 0x0A9A, 0x0B13, + 0x1251, 0x0865, 0x1069, 0x0897, 0x1215, 0x18B3, 0x1A62, 0x08C7, + 0x185E, 0x10E2, 0x0AA5, 0x21FF, 0x090B, 0x0952, 0x09E1, 0x0A42, + 0x08F1, 0x0A06, 0x0B22, 0x087D, 0x1139, 0x021F, 0x122E, 0x082F, + 0x09C2, 0x0887, 0x0A0A, 0x03C1, 0x0929, 0x0A5D, 0x0A83, 0x0BFF, + 0x0935, 0x085B, 0x0104, 0x08DD, 0x0923, 0x083F, 0x0241, 0x09D1, + 0x0A39, 0x0863, 0x0A8B, 0x08A6, 0x008B, 0x1133, 0x13B1, 0x089B, + 0x0AB3, 0x0036, 0x0BDD, 0x08ED, 0x0857, 0x0971, 0x0219, 0x1235, + 0x0AB1, 0x0ACD, 0x036F, 0x0A31, 0x08AA, 0x003A, 0x08C3, 0x0A05, + 0x02BD, 0x0B92, 0x0B07, 0x12B2, 0x08C5, 0x0B51, 0x0381, 0x0A8D, + 0x01A3, 0x0896, 0x0855, 0x0BFD, 0x005D, 0x0BFE, 0x023E, 0x08AF, + 0x00B9, 0x0A93, 0x00B5, 0x0862, 0x0A0B, 0x0A09, 0x0A72, 0x0332, + 0x0AA1, 0x08C9, 0x024E, 0x1382, 0x0951, 0x00A5, 0x0A2A, 0x0059, + 0x0A9E, 0x0B42, 0x004E, 0x0942, 0x03ED, 0x09B2, 0x02D2, 0x0849, + 0x0035, 0x0216, 0x0961, 0x0BAF, 0x00AE, 0x0826, 0x0287, 0x0A1A, + 0x0393, 0x0221, 0x09A2, 0x086D, 0x0226, 0x0871, 0x0039, 0x082A, + 0x08C2, 0x08E1, 0x0845, 0x0207, 0x0B23, 0x0015, 0x00D1, 0x0B83, + 0x037F, 0x0252, 0x08A9, 0x0099, 0x0A13, 0x0053, 0x0807, 0x03CD, + 0x0BDE, 0x0016, 0x089A, 0x0232, 0x035F, 0x0A8E, 0x0AC3, 0x022F, + 0x0263, 0x0829, 0x004D, 0x0132, 0x0806, 0x0311, 0x01B1, 0x0941, + 0x0086, 0x000B, 0x1122, 0x0025, 0x0842, 0x00BD, 0x0BCF, 0x03A2, + 0x0043, 0x0B03, 0x0895, 0x0A8F, 0x008A, 0x09EF, 0x0253, 0x0A1B, + 0x0182, 0x0243, 0x0A92, 0x00CD, 0x083E, 0x030B, 0x0223, 0x081A, + 0x0A9F, 0x0193, 0x00BE, 0x0017, 0x0931, 0x0391, 0x037E, 0x09C1, + 0x0312, 0x0333, 0x03B2, 0x083D, 0x08B1, 0x00B2, 0x002E, 0x021D, + 0x0A9D, 0x0192, 0x02AE, 0x0102, 0x0022, 0x081B, 0x0222, 0x009E, + 0x021E, 0x000A, 0x089F, 0x0217, 0x0BCE, 0x0052, 0x020F, 0x0A97, + 0x0282, 0x008E, 0x0A3F, 0x01FD, 0x00A3, 0x0019, 0x08A2, 0x0301, + 0x036E, 0x01FE, 0x03BE, 0x0ABE, 0x01CE, 0x0302, 0x029B, 0x0051, + 0x0883, 0x008F, 0x0BAE, 0x01DF, 0x0183, 0x0912, 0x000E, 0x020D, + 0x01EE, 0x0B4F, 0x0033, 0x0103, 0x020E, 0x0832, 0x01AF, 0x0913, + 0x01DE, 0x0203, 0x001E, 0x0092, 0x0093, 0x000F, 0x015F, 0x0291, + 0x0281, 0x0813, 0x001F, 0x01CF, 0x033F, 0x0023, 0x01BF, 0x0202, + 0x016F, 0x017E, 0x03AD, 0x0201, 0x034E, 0x0BBD, 0x036D, 0x017F, + 0x0211, 0x038E, 0x0212, 0x032E, 0x034D, 0x035E, 0x037D, 0x039E, + 0x032F, 0x033E, 0x035D, 0x038F, 0x039F +}; + +static const uint16_t percentile_arr_10x10_1[234] { + 0x07CD, 0x6E21, 0x24F1, 0x8443, 0xD7AE, 0x24C2, 0x1C62, 0xCCA3, + 0x1C33, 0xFDEF, 0x2532, 0x55DF, 0x1472, 0x6C3E, 0x14D2, 0x34DD, + 0x1452, 0x745D, 0x4D51, 0x8DD1, 0x247D, 0x75FF, 0x0CB3, 0x17BE, + 0x6CAE, 0x17DD, 0x1571, 0x3D06, 0x4E31, 0x0DA2, 0x67BD, 0x160D, + 0x2C4E, 0x0D22, 0x176E, 0x3CB2, 0x142E, 0x4DFE, 0x0F4F, 0x1435, + 0x0F01, 0x0D42, 0x0F7D, 0x0CB5, 0x1E03, 0x149F, 0x1C96, 0x141F, + 0x14B9, 0x0FAF, 0x0439, 0x0E91, 0x2682, 0x1D13, 0x1FAD, 0x0407, + 0x3471, 0x0C86, 0x0F6D, 0x0D15, 0x0D61, 0x040B, 0x0C6D, 0x0C16, + 0x0C9A, 0x0D0A, 0x0593, 0x0CD1, 0x248F, 0x0C2F, 0x3C42, 0x1523, + 0x0445, 0x0E81, 0x0CA2, 0x1525, 0x0406, 0x1C8A, 0x0C1A, 0x04BD, + 0x0F5E, 0x0F3F, 0x1F4E, 0x0E1D, 0x0423, 0x0DCF, 0x044D, 0x0D92, + 0x0583, 0x0DB1, 0x1449, 0x15EE, 0x0F5F, 0x079F, 0x0D19, 0x0409, + 0x04CD, 0x05FD, 0x143D, 0x0612, 0x0D03, 0x0D82, 0x04B1, 0x0C95, + 0x0C2A, 0x049E, 0x05AF, 0x0D31, 0x05BE, 0x04E1, 0x0D05, 0x0516, + 0x0711, 0x05C1, 0x0509, 0x0D41, 0x0493, 0x048E, 0x0602, 0x05BF, + 0x0CA5, 0x0529, 0x0535, 0x0D12, 0x0539, 0x0451, 0x0C29, 0x071F, + 0x040A, 0x0F3D, 0x0432, 0x059F, 0x0425, 0x0C99, 0x05DE, 0x05CE, + 0x0C0F, 0x0489, 0x051A, 0x0501, 0x0415, 0x057F, 0x0431, 0x0E13, + 0x040D, 0x041D, 0x075D, 0x0C53, 0x0502, 0x04C1, 0x049D, 0x0426, + 0x040E, 0x05A1, 0x055F, 0x0781, 0x0591, 0x04A9, 0x048B, 0x0D8E, + 0x052E, 0x0412, 0x0521, 0x0405, 0x04AD, 0x074D, 0x0611, 0x077E, + 0x078F, 0x078D, 0x048D, 0x041E, 0x0487, 0x0461, 0x0C85, 0x05ED, + 0x0402, 0x0483, 0x0419, 0x0511, 0x0491, 0x0482, 0x059E, 0x068D, + 0x055D, 0x072E, 0x05DD, 0x054E, 0x0441, 0x0422, 0x052F, 0x057D, + 0x072D, 0x079D, 0x0CA1, 0x072F, 0x079E, 0x0581, 0x042D, 0x055E, + 0x0601, 0x0413, 0x0692, 0x0403, 0x051F, 0x053F, 0x054F, 0x05CD, + 0x070F, 0x071D, 0x05AE, 0x05BD, 0x0492, 0x056E, 0x0411, 0x0417, + 0x041B, 0x0421, 0x053E, 0x056F, 0x057E, 0x058F, 0x060E, 0x0622, + 0x0683, 0x0702, 0x070D, 0x070E, 0x071E, 0x073E, 0x076F, 0x078E, + 0x07BF, 0x07CE +}; + +static const packed_percentile_table block_pcd_10x10 { + 10, 10, + { 453, 234 }, + { 1095, 472 }, + { 0, 70 }, + { percentile_arr_10x10_0, percentile_arr_10x10_1 } +}; +#endif + +#if ASTCENC_BLOCK_MAX_TEXELS >= (12 * 10) +static const uint16_t percentile_arr_12x10_0[491] { + 0x0334, 0x9954, 0x8514, 0x7128, 0x6364, 0xC174, 0x5D34, 0x5866, + 0x5975, 0x5354, 0xAF14, 0x506A, 0x5108, 0x5724, 0x5308, 0x4544, + 0x4918, 0x4064, 0x49E2, 0x4179, 0x8163, 0x4054, 0xF81C, 0x394A, + 0x38F3, 0x4172, 0x38F5, 0xA06F, 0x68EA, 0x69F2, 0x3134, 0x31A4, + 0x305A, 0x68DA, 0x3056, 0x3146, 0x31F5, 0x3148, 0x5A61, 0x32C1, + 0x31D2, 0x307E, 0x29E3, 0x30E6, 0x59C3, 0x2984, 0x29B6, 0x28F9, + 0x5204, 0x28EE, 0x50CA, 0x2997, 0x48C6, 0x4838, 0x2953, 0x200C, + 0x2943, 0x2173, 0x2D08, 0x4162, 0x29B4, 0x2314, 0x21B3, 0x212B, + 0x210C, 0x48E3, 0x60DE, 0x205F, 0x20FE, 0x2028, 0x21A6, 0x404F, + 0x20D6, 0x2214, 0x2127, 0x1873, 0x40CF, 0x206E, 0x1B09, 0x21C6, + 0x2075, 0x19D5, 0x2305, 0x18D3, 0x2076, 0x1804, 0x230A, 0x304B, + 0x20BB, 0x18B6, 0x1936, 0x1B19, 0x3037, 0x187F, 0x18A7, 0x1B85, + 0x30BA, 0x183B, 0x1027, 0x18EF, 0x1B21, 0x1879, 0x10AB, 0x1917, + 0x1114, 0x18BF, 0x1074, 0x1994, 0x2847, 0x111B, 0x28F2, 0x11E5, + 0x19A7, 0x113A, 0x1046, 0x28B7, 0x207A, 0x182B, 0x1155, 0x104A, + 0x1344, 0x293B, 0x11D3, 0x2014, 0x1044, 0x1018, 0x13A1, 0x1315, + 0x2524, 0x20DF, 0x10E5, 0x1126, 0x12A2, 0x1824, 0x2271, 0x11F1, + 0x2964, 0x12D1, 0x115A, 0x092A, 0x2341, 0x1A2D, 0x12E1, 0x090A, + 0x13BF, 0x0A4D, 0x2119, 0x0BC1, 0x1233, 0x1A8A, 0x2008, 0x1159, + 0x1A89, 0x08D5, 0x1156, 0x0834, 0x13EE, 0x1169, 0x1187, 0x1AA3, + 0x1229, 0x1331, 0x0A85, 0x0937, 0x1704, 0x08FD, 0x2124, 0x0B13, + 0x1251, 0x0AAD, 0x082C, 0x091A, 0x18D9, 0x0A99, 0x1848, 0x18E9, + 0x0B95, 0x1144, 0x0AF1, 0x1A25, 0x131A, 0x09C5, 0x0986, 0x1BDF, + 0x0B24, 0x0965, 0x1262, 0x0949, 0x0872, 0x09C2, 0x12C2, 0x0916, + 0x085E, 0x0B06, 0x08CB, 0x08C7, 0x1242, 0x1BEF, 0x0A9A, 0x1152, + 0x08B3, 0x0AA9, 0x090B, 0x08D2, 0x1B22, 0x0B04, 0x0865, 0x0A15, + 0x1286, 0x0A83, 0x0A95, 0x09D1, 0x0A06, 0x0196, 0x1139, 0x0A3D, + 0x0933, 0x13B1, 0x0123, 0x0D04, 0x08E2, 0x122E, 0x08A6, 0x00CE, + 0x0A31, 0x1241, 0x0B51, 0x1057, 0x1171, 0x007D, 0x1145, 0x0A0A, + 0x0129, 0x09FF, 0x089B, 0x085B, 0x0063, 0x0AB1, 0x0A1F, 0x0A5D, + 0x0AA5, 0x0036, 0x0904, 0x0B86, 0x0A8B, 0x0897, 0x11E1, 0x0332, + 0x083F, 0x0A19, 0x02B3, 0x0859, 0x08C3, 0x0855, 0x11B5, 0x01A5, + 0x0AB2, 0x0392, 0x10DD, 0x09A3, 0x00ED, 0x0907, 0x1161, 0x002F, + 0x0887, 0x0216, 0x0ABD, 0x0B81, 0x0A93, 0x0A21, 0x003A, 0x0ACD, + 0x0AA1, 0x0A35, 0x0272, 0x0BDD, 0x03FE, 0x0BAF, 0x0869, 0x0213, + 0x088B, 0x020B, 0x00B5, 0x1035, 0x08F1, 0x0151, 0x0A4E, 0x0239, + 0x0BA2, 0x00AA, 0x0896, 0x0382, 0x0A08, 0x0A05, 0x0A09, 0x0142, + 0x086D, 0x004E, 0x0B23, 0x0106, 0x0807, 0x036F, 0x0995, 0x03FD, + 0x08AF, 0x08C5, 0x0062, 0x0053, 0x0B42, 0x0826, 0x021A, 0x01A2, + 0x09B1, 0x00C9, 0x09B2, 0x0045, 0x0207, 0x08B9, 0x00A5, 0x0AD2, + 0x0095, 0x003E, 0x0A32, 0x0383, 0x0849, 0x0135, 0x029E, 0x0A26, + 0x023E, 0x0BFF, 0x0A52, 0x0311, 0x001B, 0x0915, 0x0A8D, 0x0223, + 0x022A, 0x0BED, 0x0086, 0x0A96, 0x0222, 0x035F, 0x0A43, 0x085D, + 0x0303, 0x0393, 0x0A63, 0x082A, 0x037F, 0x0932, 0x0043, 0x0292, + 0x03CD, 0x0BDE, 0x009F, 0x0125, 0x08A9, 0x0253, 0x0015, 0x0192, + 0x0A17, 0x08C2, 0x0316, 0x00D1, 0x0282, 0x0871, 0x0312, 0x0122, + 0x0A9F, 0x02AE, 0x0006, 0x0A8E, 0x08E1, 0x0016, 0x0B0B, 0x00AE, + 0x0025, 0x0193, 0x0AC3, 0x0017, 0x0307, 0x00BD, 0x08BE, 0x0039, + 0x0BB2, 0x021B, 0x01FD, 0x084D, 0x03CE, 0x00A3, 0x0302, 0x0BCF, + 0x0033, 0x0391, 0x028F, 0x0852, 0x0287, 0x008A, 0x0333, 0x080B, + 0x0131, 0x01C1, 0x037E, 0x0A0F, 0x00B1, 0x002E, 0x0099, 0x0902, + 0x009A, 0x003D, 0x0982, 0x0301, 0x00CD, 0x0941, 0x0042, 0x0183, + 0x029D, 0x08A2, 0x021D, 0x001A, 0x0A97, 0x01EF, 0x01CE, 0x0051, + 0x0BAE, 0x022F, 0x03BE, 0x021E, 0x000A, 0x09DF, 0x0029, 0x020D, + 0x02BE, 0x029B, 0x09EE, 0x00B2, 0x0912, 0x036E, 0x009E, 0x0022, + 0x0019, 0x0892, 0x0032, 0x01FE, 0x0083, 0x023F, 0x0B96, 0x000E, + 0x008F, 0x0113, 0x0103, 0x001E, 0x0A0E, 0x0013, 0x008E, 0x0281, + 0x09AF, 0x017E, 0x0203, 0x016F, 0x0291, 0x0023, 0x0093, 0x03BD, + 0x001F, 0x01CF, 0x01DE, 0x0201, 0x01BF, 0x0B4F, 0x000F, 0x0202, + 0x037D, 0x038E, 0x0211, 0x0212, 0x034E, 0x039F, 0x03AD, 0x015F, + 0x017F, 0x032E, 0x033F, 0x034D, 0x035E, 0x036D, 0x032F, 0x033E, + 0x035D, 0x038F, 0x039E +}; + +static const uint16_t percentile_arr_12x10_1[240] { + 0x0621, 0xA443, 0xFCC2, 0x3CA3, 0x1D32, 0x14F1, 0x7462, 0x1433, + 0x27CD, 0x2571, 0x57AE, 0x5DD1, 0x64B3, 0x44D2, 0x2C72, 0x25A2, + 0x1E31, 0x55DF, 0x4C52, 0x1DEF, 0x0D51, 0x3C5D, 0x3C3E, 0x74DD, + 0x347D, 0x27BE, 0x5CB5, 0x17DD, 0x2C14, 0x0CAE, 0x24B2, 0x15FF, + 0x2701, 0x0D42, 0x1FBD, 0x0C35, 0x1603, 0x060D, 0x1D93, 0x0C96, + 0x1C07, 0x1522, 0x0D06, 0x0F4F, 0x0C9F, 0x1F6E, 0x0D86, 0x0C2E, + 0x1DFE, 0x0682, 0x1E91, 0x0F7D, 0x0C86, 0x040B, 0x1513, 0x044E, + 0x14D1, 0x0C39, 0x14B9, 0x1C71, 0x05B1, 0x0C1F, 0x0681, 0x1445, + 0x0C16, 0x0D95, 0x1583, 0x0D61, 0x0FAD, 0x1442, 0x048F, 0x0D0A, + 0x049A, 0x0F6D, 0x146D, 0x0C2F, 0x0D25, 0x0406, 0x0C1A, 0x0D23, + 0x0612, 0x0FAF, 0x0F11, 0x0592, 0x0515, 0x14E1, 0x0602, 0x048A, + 0x0E1D, 0x0CBD, 0x0F9F, 0x0423, 0x075E, 0x174E, 0x0426, 0x0404, + 0x0C22, 0x0CA2, 0x0DEE, 0x0CA5, 0x0F3F, 0x05C1, 0x0CCD, 0x0503, + 0x044D, 0x0D16, 0x0449, 0x0D82, 0x0613, 0x0585, 0x0519, 0x0C95, + 0x075F, 0x0D35, 0x04B1, 0x0509, 0x0531, 0x0DA1, 0x049E, 0x040A, + 0x05CF, 0x0D41, 0x0415, 0x0692, 0x05FD, 0x0C25, 0x04A1, 0x0529, + 0x0591, 0x0C93, 0x057F, 0x04C1, 0x0512, 0x051A, 0x078D, 0x0451, + 0x0C0F, 0x0487, 0x0611, 0x0432, 0x042A, 0x05AF, 0x0461, 0x072D, + 0x0409, 0x0405, 0x0D39, 0x05DE, 0x048E, 0x0499, 0x0483, 0x04A9, + 0x0491, 0x042D, 0x049D, 0x0429, 0x040E, 0x05AE, 0x0521, 0x043D, + 0x0581, 0x05DD, 0x0492, 0x0CAD, 0x041E, 0x058F, 0x071F, 0x072F, + 0x0419, 0x073D, 0x057D, 0x0511, 0x05CE, 0x041D, 0x0485, 0x056E, + 0x0412, 0x0431, 0x05BF, 0x0441, 0x054E, 0x0489, 0x0421, 0x0502, + 0x0408, 0x040D, 0x051F, 0x059F, 0x073E, 0x078F, 0x0482, 0x079D, + 0x0C02, 0x05BE, 0x048B, 0x0411, 0x0505, 0x057E, 0x052E, 0x074D, + 0x077E, 0x054F, 0x0601, 0x055F, 0x068D, 0x070D, 0x070F, 0x071E, + 0x072E, 0x05CD, 0x0403, 0x0501, 0x055D, 0x059E, 0x0781, 0x0413, + 0x0417, 0x041B, 0x0453, 0x048D, 0x052F, 0x053E, 0x053F, 0x055E, + 0x056F, 0x058E, 0x05BD, 0x05ED, 0x060E, 0x0622, 0x0683, 0x0702, + 0x070E, 0x071D, 0x075D, 0x076F, 0x078E, 0x079E, 0x07BF, 0x07CE +}; + +static const packed_percentile_table block_pcd_12x10 = +{ + 12, 10, + { 491, 240 }, + { 1099, 341 }, + { 0, 23 }, + { percentile_arr_12x10_0, percentile_arr_12x10_1 } +}; +#endif + +#if ASTCENC_BLOCK_MAX_TEXELS >= (12 * 12) +static const uint16_t percentile_arr_12x12_0[529] { + 0x0334, 0xF534, 0x8514, 0x8954, 0x7F14, 0xFB54, 0x7B08, 0x7128, + 0x7974, 0x6179, 0x6B64, 0x6908, 0x606A, 0x6724, 0xB544, 0xB066, + 0xA14A, 0x5118, 0x9975, 0x51F9, 0x981C, 0x49CA, 0x4854, 0x886F, + 0x88D4, 0x48EE, 0x41E2, 0x4163, 0x40F3, 0x4261, 0x4064, 0x407E, + 0x385A, 0x42C1, 0x4172, 0x38EA, 0x3946, 0x78CF, 0xA056, 0x38DE, + 0x3D08, 0x38F9, 0x3B14, 0x38FE, 0xA134, 0x38B8, 0x31A4, 0x71D2, + 0x60DA, 0x39C3, 0x99BA, 0x60CA, 0x39F2, 0x30F5, 0x304F, 0x31B6, + 0x31F5, 0x3204, 0x3148, 0x305F, 0x2953, 0x3194, 0x3184, 0x310C, + 0x889C, 0x300C, 0x2943, 0x30EF, 0x28C6, 0x2997, 0x2838, 0x58E6, + 0x20E4, 0x28E3, 0x2873, 0x29E3, 0x2A84, 0x28D3, 0x492B, 0x2962, + 0x286E, 0x20BF, 0x21AA, 0x29A6, 0x6A14, 0x2828, 0x89C6, 0x21B3, + 0x2305, 0x29B4, 0x2173, 0x2127, 0x20D6, 0x407F, 0x2294, 0x21D9, + 0x21D5, 0x2004, 0x404B, 0x18DF, 0x2079, 0x219B, 0x18A8, 0x2385, + 0x1936, 0x21AB, 0x188C, 0x1B09, 0x18BA, 0x203B, 0x187A, 0x1875, + 0x2344, 0x18BB, 0x18B6, 0x193A, 0x1837, 0x1914, 0x1846, 0x1876, + 0x1884, 0x1D24, 0x182B, 0x284A, 0x18A7, 0x18AB, 0x1917, 0x322D, + 0x1047, 0x1874, 0x1818, 0x18F2, 0x1164, 0x1B89, 0x2959, 0x1B21, + 0x39E5, 0x1827, 0x10F4, 0x18B7, 0x11D3, 0x1A4D, 0x1315, 0x12AD, + 0x1AD1, 0x3A71, 0x1319, 0x11A7, 0x2044, 0x2F04, 0x2341, 0x10E5, + 0x1155, 0x195A, 0x1024, 0x111B, 0x1251, 0x1233, 0x12E1, 0x13A1, + 0x13BF, 0x212A, 0x22A2, 0x113B, 0x23DF, 0x10D5, 0x2399, 0x0814, + 0x1126, 0x13EE, 0x1285, 0x10C4, 0x18FD, 0x20D9, 0x0987, 0x1242, + 0x29C5, 0x2313, 0x0898, 0x13C1, 0x08C8, 0x11F1, 0x1034, 0x1B24, + 0x0B0A, 0x11E9, 0x0808, 0x125D, 0x18E9, 0x0848, 0x1395, 0x0965, + 0x123D, 0x2186, 0x1295, 0x18CE, 0x098B, 0x0BEF, 0x1504, 0x082C, + 0x0A41, 0x1144, 0x0A89, 0x0956, 0x1331, 0x085E, 0x0B04, 0x128A, + 0x12A3, 0x1937, 0x19C2, 0x0952, 0x0872, 0x08B4, 0x1262, 0x1124, + 0x1969, 0x1063, 0x0AF1, 0x1225, 0x0894, 0x11C9, 0x18D2, 0x0ACD, + 0x0A29, 0x0B06, 0x09B5, 0x18C7, 0x0916, 0x1088, 0x09FF, 0x2206, + 0x0A15, 0x08B3, 0x0B51, 0x0A1F, 0x18CB, 0x0AC2, 0x0A2E, 0x1865, + 0x08AC, 0x0A31, 0x08A4, 0x138A, 0x0A99, 0x09D1, 0x0A86, 0x189B, + 0x0283, 0x0BDD, 0x0ABD, 0x1933, 0x083F, 0x1386, 0x0923, 0x0322, + 0x0869, 0x10DD, 0x13B1, 0x082F, 0x087D, 0x11B9, 0x085B, 0x08ED, + 0x00C3, 0x08E2, 0x084E, 0x0887, 0x0855, 0x0A0A, 0x0857, 0x0B92, + 0x1036, 0x12A5, 0x0293, 0x0945, 0x08A6, 0x0196, 0x19A3, 0x036F, + 0x0904, 0x1205, 0x09E1, 0x0381, 0x0971, 0x1219, 0x0BAF, 0x0949, + 0x00AF, 0x0AA9, 0x018A, 0x0907, 0x0BFD, 0x003A, 0x0BCD, 0x0AB2, + 0x088B, 0x0252, 0x0A4E, 0x03FF, 0x0845, 0x0897, 0x0059, 0x090B, + 0x0B42, 0x0807, 0x0A16, 0x0853, 0x0A8D, 0x01B2, 0x0AB1, 0x091A, + 0x0195, 0x0A35, 0x00B5, 0x10AA, 0x0115, 0x0A21, 0x0096, 0x0A08, + 0x03FE, 0x0B7F, 0x08B9, 0x12B3, 0x023E, 0x0A23, 0x029E, 0x08F1, + 0x01A9, 0x0BDE, 0x0843, 0x02D2, 0x0A1A, 0x08C5, 0x0151, 0x0A43, + 0x0332, 0x0383, 0x0826, 0x0BED, 0x10C2, 0x00AE, 0x0B82, 0x0213, + 0x0232, 0x085D, 0x02A1, 0x101B, 0x035F, 0x0303, 0x0A39, 0x0207, + 0x0A53, 0x0142, 0x01A5, 0x082A, 0x0099, 0x0A17, 0x03CF, 0x0906, + 0x0125, 0x0A96, 0x0A9A, 0x0209, 0x0393, 0x0961, 0x0131, 0x0A88, + 0x0139, 0x099A, 0x0292, 0x0272, 0x0862, 0x08BE, 0x0141, 0x02C3, + 0x0886, 0x0039, 0x08A9, 0x01A2, 0x01B1, 0x0851, 0x020B, 0x086D, + 0x0312, 0x08CD, 0x020F, 0x0311, 0x0BCE, 0x0135, 0x0006, 0x0849, + 0x0132, 0x0A8F, 0x022F, 0x022A, 0x0AAE, 0x0A8E, 0x0263, 0x03A2, + 0x083E, 0x009A, 0x021B, 0x0835, 0x0323, 0x0871, 0x0993, 0x0226, + 0x0302, 0x0922, 0x0119, 0x0222, 0x021D, 0x0B07, 0x08C9, 0x037E, + 0x08BD, 0x0042, 0x00D1, 0x0B33, 0x01C1, 0x0B9A, 0x0282, 0x088A, + 0x0182, 0x083D, 0x004D, 0x010A, 0x0A1E, 0x0019, 0x00B2, 0x0999, + 0x00A5, 0x0095, 0x0817, 0x0022, 0x031A, 0x0902, 0x00A3, 0x01BF, + 0x029F, 0x0816, 0x03B2, 0x0015, 0x0391, 0x0BBE, 0x01FE, 0x1129, + 0x002E, 0x01DF, 0x0301, 0x0033, 0x0B6E, 0x00E1, 0x0297, 0x00B1, + 0x009F, 0x0B16, 0x000A, 0x001A, 0x0052, 0x080B, 0x030B, 0x029D, + 0x0BAE, 0x01FD, 0x020E, 0x00A2, 0x0A3F, 0x0192, 0x0ABE, 0x020D, + 0x008F, 0x028B, 0x0083, 0x0025, 0x09EE, 0x01EF, 0x0029, 0x0291, + 0x0B4F, 0x0396, 0x0287, 0x008E, 0x0092, 0x0B4E, 0x017E, 0x001E, + 0x009E, 0x0103, 0x080F, 0x000E, 0x0113, 0x0203, 0x01CF, 0x0183, + 0x01CE, 0x001F, 0x0112, 0x01DE, 0x038E, 0x0832, 0x033E, 0x0212, + 0x029B, 0x0023, 0x016F, 0x0201, 0x09AF, 0x0202, 0x0281, 0x035E, + 0x034D, 0x037D, 0x03AD, 0x0013, 0x0093, 0x015F, 0x0211, 0x033F, + 0x036D, 0x039F, 0x03BD, 0x017F, 0x032E, 0x032F, 0x035D, 0x038F, + 0x039E +}; + +static const uint16_t percentile_arr_12x12_1[246] { + 0x0443, 0xFFCD, 0x2C62, 0x2E21, 0x3CF1, 0x34C2, 0x4CDD, 0x2452, + 0xD5DF, 0x1DD1, 0x0FAE, 0x64A3, 0x0C7D, 0x3433, 0x1CD2, 0x2DEF, + 0x0C3E, 0x1D71, 0xA472, 0x0D32, 0x54B3, 0x4D51, 0x445D, 0x0E31, + 0x1FDD, 0x0DFF, 0x0CAE, 0x45A2, 0x2FBE, 0xA4B9, 0x1C4E, 0x2C9F, + 0x160D, 0x0D42, 0x342E, 0x074F, 0x1414, 0x0F6E, 0x0CB2, 0x34B5, + 0x0DFE, 0x0D86, 0x1496, 0x1D22, 0x0691, 0x140B, 0x041F, 0x0C35, + 0x1D93, 0x1506, 0x1439, 0x0C9A, 0x0F01, 0x2442, 0x0C8F, 0x04D1, + 0x1486, 0x0C6D, 0x0513, 0x0C71, 0x0E82, 0x177D, 0x0E03, 0x07BD, + 0x0C2F, 0x0D83, 0x07AF, 0x0D61, 0x1407, 0x0DB1, 0x050A, 0x0C94, + 0x07AD, 0x0D8A, 0x0C04, 0x0416, 0x0C49, 0x0445, 0x15C1, 0x0C1A, + 0x0525, 0x0595, 0x0C8A, 0x075E, 0x0CBD, 0x0681, 0x0F4E, 0x075F, + 0x061D, 0x1541, 0x0CB1, 0x0F3F, 0x0406, 0x076D, 0x0DCF, 0x05EE, + 0x0D23, 0x0599, 0x0CCD, 0x0711, 0x0C23, 0x079F, 0x0D15, 0x0585, + 0x04A2, 0x042A, 0x0D31, 0x05BF, 0x0D92, 0x0C26, 0x043D, 0x0C93, + 0x0502, 0x0C15, 0x048B, 0x0D03, 0x0613, 0x0516, 0x0495, 0x0C29, + 0x04A5, 0x040F, 0x0425, 0x0539, 0x0D19, 0x04E1, 0x05BE, 0x0422, + 0x0432, 0x0C0A, 0x0431, 0x041E, 0x0492, 0x04A9, 0x0582, 0x0529, + 0x0487, 0x0C4D, 0x0512, 0x049E, 0x0505, 0x0451, 0x0D7F, 0x0489, + 0x0602, 0x05DE, 0x0591, 0x0535, 0x074D, 0x055E, 0x04C1, 0x0612, + 0x05DD, 0x05FD, 0x0C61, 0x0521, 0x0484, 0x05CE, 0x0581, 0x0491, + 0x051A, 0x04A1, 0x048E, 0x040D, 0x0499, 0x071F, 0x072E, 0x075D, + 0x0441, 0x0589, 0x057E, 0x0CAD, 0x0501, 0x054F, 0x0692, 0x0511, + 0x049D, 0x0509, 0x056E, 0x040E, 0x0409, 0x0601, 0x048D, 0x0413, + 0x053E, 0x0419, 0x072D, 0x0408, 0x0485, 0x042D, 0x041D, 0x05A1, + 0x0781, 0x0402, 0x05ED, 0x0C82, 0x0403, 0x057D, 0x05CD, 0x0611, + 0x0488, 0x0411, 0x054E, 0x051F, 0x053F, 0x056F, 0x059F, 0x070F, + 0x071D, 0x073D, 0x073E, 0x077E, 0x078F, 0x0405, 0x079D, 0x079E, + 0x058E, 0x0412, 0x055D, 0x05AE, 0x041B, 0x0421, 0x0453, 0x0417, + 0x0483, 0x052E, 0x052F, 0x055F, 0x058F, 0x059E, 0x05AF, 0x05BD, + 0x060E, 0x0622, 0x0683, 0x068D, 0x0702, 0x070D, 0x070E, 0x071E, + 0x072F, 0x076F, 0x078D, 0x078E, 0x07BF, 0x07CE +}; + +static const packed_percentile_table block_pcd_12x12 { + 12, 12, + { 529, 246 }, + { 1435, 335 }, + { 0, 22 }, + { percentile_arr_12x12_0, percentile_arr_12x12_1 } +}; +#endif + +/** + * @brief Fetch the packed percentile table for the given 2D block size. + * + * @param xdim The block x size. + * @param ydim The block y size. + * + * @return The packed table. + */ +static const packed_percentile_table *get_packed_table( + int xdim, + int ydim +) { + int idx = (ydim << 8) | xdim; + switch (idx) + { +#if ASTCENC_BLOCK_MAX_TEXELS >= (4 * 4) + case 0x0404: return &block_pcd_4x4; +#endif +#if ASTCENC_BLOCK_MAX_TEXELS >= (5 * 4) + case 0x0405: return &block_pcd_5x4; +#endif +#if ASTCENC_BLOCK_MAX_TEXELS >= (5 * 5) + case 0x0505: return &block_pcd_5x5; +#endif +#if ASTCENC_BLOCK_MAX_TEXELS >= (6 * 5) + case 0x0506: return &block_pcd_6x5; +#endif +#if ASTCENC_BLOCK_MAX_TEXELS >= (6 * 6) + case 0x0606: return &block_pcd_6x6; +#endif +#if ASTCENC_BLOCK_MAX_TEXELS >= (8 * 5) + case 0x0508: return &block_pcd_8x5; +#endif +#if ASTCENC_BLOCK_MAX_TEXELS >= (8 * 6) + case 0x0608: return &block_pcd_8x6; +#endif +#if ASTCENC_BLOCK_MAX_TEXELS >= (8 * 8) + case 0x0808: return &block_pcd_8x8; +#endif +#if ASTCENC_BLOCK_MAX_TEXELS >= (10 * 5) + case 0x050A: return &block_pcd_10x5; +#endif +#if ASTCENC_BLOCK_MAX_TEXELS >= (10 * 6) + case 0x060A: return &block_pcd_10x6; +#endif +#if ASTCENC_BLOCK_MAX_TEXELS >= (10 * 8) + case 0x080A: return &block_pcd_10x8; +#endif +#if ASTCENC_BLOCK_MAX_TEXELS >= (10 * 10) + case 0x0A0A: return &block_pcd_10x10; +#endif +#if ASTCENC_BLOCK_MAX_TEXELS >= (12 * 10) + case 0x0A0C: return &block_pcd_12x10; +#endif +#if ASTCENC_BLOCK_MAX_TEXELS >= (12 * 12) + case 0x0C0C: return &block_pcd_12x12; +#endif + } + + // Should never hit this with a valid 2D block size + return nullptr; +} + +/* See header for documentation. */ +const float *get_2d_percentile_table( + unsigned int xdim, + unsigned int ydim +) { + float* unpacked_table = new float[WEIGHTS_MAX_BLOCK_MODES]; + const packed_percentile_table *apt = get_packed_table(xdim, ydim); + + // Set the default percentile + for (unsigned int i = 0; i < WEIGHTS_MAX_BLOCK_MODES; i++) + { + unpacked_table[i] = 1.0f; + } + + // Populate the unpacked percentile values + for (int i = 0; i < 2; i++) + { + unsigned int itemcount = apt->item_count[i]; + unsigned int difscale = apt->difscales[i]; + unsigned int accum = apt->initial_percs[i]; + const uint16_t *item_ptr = apt->items[i]; + + for (unsigned int j = 0; j < itemcount; j++) + { + uint16_t item = item_ptr[j]; + unsigned int idx = item & 0x7FF; + unsigned int weight = (item >> 11) & 0x1F; + accum += weight; + unpacked_table[idx] = static_cast<float>(accum) / static_cast<float>(difscale); + } + } + + return unpacked_table; +} +#endif + +/* See header for documentation. */ +bool is_legal_2d_block_size( + unsigned int xdim, + unsigned int ydim +) { + unsigned int idx = (xdim << 8) | ydim; + switch (idx) + { + case 0x0404: + case 0x0504: + case 0x0505: + case 0x0605: + case 0x0606: + case 0x0805: + case 0x0806: + case 0x0808: + case 0x0A05: + case 0x0A06: + case 0x0A08: + case 0x0A0A: + case 0x0C0A: + case 0x0C0C: + return true; + } + + return false; +} + +/* See header for documentation. */ +bool is_legal_3d_block_size( + unsigned int xdim, + unsigned int ydim, + unsigned int zdim +) { + unsigned int idx = (xdim << 16) | (ydim << 8) | zdim; + switch (idx) + { + case 0x030303: + case 0x040303: + case 0x040403: + case 0x040404: + case 0x050404: + case 0x050504: + case 0x050505: + case 0x060505: + case 0x060605: + case 0x060606: + return true; + } + + return false; +} diff --git a/thirdparty/astcenc/astcenc_pick_best_endpoint_format.cpp b/thirdparty/astcenc/astcenc_pick_best_endpoint_format.cpp new file mode 100644 index 0000000000..f25140d4c7 --- /dev/null +++ b/thirdparty/astcenc/astcenc_pick_best_endpoint_format.cpp @@ -0,0 +1,1350 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2022 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +#if !defined(ASTCENC_DECOMPRESS_ONLY) + +/** + * @brief Functions for finding best endpoint format. + * + * We assume there are two independent sources of error in any given partition: + * + * - Encoding choice errors + * - Quantization errors + * + * Encoding choice errors are caused by encoder decisions. For example: + * + * - Using luminance instead of separate RGB components. + * - Using a constant 1.0 alpha instead of storing an alpha component. + * - Using RGB+scale instead of storing two full RGB endpoints. + * + * Quantization errors occur due to the limited precision we use for storage. These errors generally + * scale with quantization level, but are not actually independent of color encoding. In particular: + * + * - If we can use offset encoding then quantization error is halved. + * - If we can use blue-contraction then quantization error for RG is halved. + * - If we use HDR endpoints the quantization error is higher. + * + * Apart from these effects, we assume the error is proportional to the quantization step size. + */ + + +#include "astcenc_internal.h" +#include "astcenc_vecmathlib.h" + +#include <assert.h> + +/** + * @brief Compute the errors of the endpoint line options for one partition. + * + * Uncorrelated data assumes storing completely independent RGBA channels for each endpoint. Same + * chroma data assumes storing RGBA endpoints which pass though the origin (LDR only). RGBL data + * assumes storing RGB + lumashift (HDR only). Luminance error assumes storing RGB channels as a + * single value. + * + * + * @param pi The partition info data. + * @param partition_index The partition index to compule the error for. + * @param blk The image block. + * @param uncor_pline The endpoint line assuming uncorrelated endpoints. + * @param[out] uncor_err The computed error for the uncorrelated endpoint line. + * @param samec_pline The endpoint line assuming the same chroma for both endpoints. + * @param[out] samec_err The computed error for the uncorrelated endpoint line. + * @param rgbl_pline The endpoint line assuming RGB + lumashift data. + * @param[out] rgbl_err The computed error for the RGB + lumashift endpoint line. + * @param l_pline The endpoint line assuming luminance data. + * @param[out] l_err The computed error for the luminance endpoint line. + * @param[out] a_drop_err The computed error for dropping the alpha component. + */ +static void compute_error_squared_rgb_single_partition( + const partition_info& pi, + int partition_index, + const image_block& blk, + const processed_line3& uncor_pline, + float& uncor_err, + const processed_line3& samec_pline, + float& samec_err, + const processed_line3& rgbl_pline, + float& rgbl_err, + const processed_line3& l_pline, + float& l_err, + float& a_drop_err +) { + vfloat4 ews = blk.channel_weight; + + unsigned int texel_count = pi.partition_texel_count[partition_index]; + const uint8_t* texel_indexes = pi.texels_of_partition[partition_index]; + promise(texel_count > 0); + + vfloatacc a_drop_errv = vfloatacc::zero(); + vfloat default_a(blk.get_default_alpha()); + + vfloatacc uncor_errv = vfloatacc::zero(); + vfloat uncor_bs0(uncor_pline.bs.lane<0>()); + vfloat uncor_bs1(uncor_pline.bs.lane<1>()); + vfloat uncor_bs2(uncor_pline.bs.lane<2>()); + + vfloat uncor_amod0(uncor_pline.amod.lane<0>()); + vfloat uncor_amod1(uncor_pline.amod.lane<1>()); + vfloat uncor_amod2(uncor_pline.amod.lane<2>()); + + vfloatacc samec_errv = vfloatacc::zero(); + vfloat samec_bs0(samec_pline.bs.lane<0>()); + vfloat samec_bs1(samec_pline.bs.lane<1>()); + vfloat samec_bs2(samec_pline.bs.lane<2>()); + + vfloatacc rgbl_errv = vfloatacc::zero(); + vfloat rgbl_bs0(rgbl_pline.bs.lane<0>()); + vfloat rgbl_bs1(rgbl_pline.bs.lane<1>()); + vfloat rgbl_bs2(rgbl_pline.bs.lane<2>()); + + vfloat rgbl_amod0(rgbl_pline.amod.lane<0>()); + vfloat rgbl_amod1(rgbl_pline.amod.lane<1>()); + vfloat rgbl_amod2(rgbl_pline.amod.lane<2>()); + + vfloatacc l_errv = vfloatacc::zero(); + vfloat l_bs0(l_pline.bs.lane<0>()); + vfloat l_bs1(l_pline.bs.lane<1>()); + vfloat l_bs2(l_pline.bs.lane<2>()); + + vint lane_ids = vint::lane_id(); + for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) + { + vint tix(texel_indexes + i); + + vmask mask = lane_ids < vint(texel_count); + lane_ids += vint(ASTCENC_SIMD_WIDTH); + + // Compute the error that arises from just ditching alpha + vfloat data_a = gatherf(blk.data_a, tix); + vfloat alpha_diff = data_a - default_a; + alpha_diff = alpha_diff * alpha_diff; + + haccumulate(a_drop_errv, alpha_diff, mask); + + vfloat data_r = gatherf(blk.data_r, tix); + vfloat data_g = gatherf(blk.data_g, tix); + vfloat data_b = gatherf(blk.data_b, tix); + + // Compute uncorrelated error + vfloat param = data_r * uncor_bs0 + + data_g * uncor_bs1 + + data_b * uncor_bs2; + + vfloat dist0 = (uncor_amod0 + param * uncor_bs0) - data_r; + vfloat dist1 = (uncor_amod1 + param * uncor_bs1) - data_g; + vfloat dist2 = (uncor_amod2 + param * uncor_bs2) - data_b; + + vfloat error = dist0 * dist0 * ews.lane<0>() + + dist1 * dist1 * ews.lane<1>() + + dist2 * dist2 * ews.lane<2>(); + + haccumulate(uncor_errv, error, mask); + + // Compute same chroma error - no "amod", its always zero + param = data_r * samec_bs0 + + data_g * samec_bs1 + + data_b * samec_bs2; + + dist0 = (param * samec_bs0) - data_r; + dist1 = (param * samec_bs1) - data_g; + dist2 = (param * samec_bs2) - data_b; + + error = dist0 * dist0 * ews.lane<0>() + + dist1 * dist1 * ews.lane<1>() + + dist2 * dist2 * ews.lane<2>(); + + haccumulate(samec_errv, error, mask); + + // Compute rgbl error + param = data_r * rgbl_bs0 + + data_g * rgbl_bs1 + + data_b * rgbl_bs2; + + dist0 = (rgbl_amod0 + param * rgbl_bs0) - data_r; + dist1 = (rgbl_amod1 + param * rgbl_bs1) - data_g; + dist2 = (rgbl_amod2 + param * rgbl_bs2) - data_b; + + error = dist0 * dist0 * ews.lane<0>() + + dist1 * dist1 * ews.lane<1>() + + dist2 * dist2 * ews.lane<2>(); + + haccumulate(rgbl_errv, error, mask); + + // Compute luma error - no "amod", its always zero + param = data_r * l_bs0 + + data_g * l_bs1 + + data_b * l_bs2; + + dist0 = (param * l_bs0) - data_r; + dist1 = (param * l_bs1) - data_g; + dist2 = (param * l_bs2) - data_b; + + error = dist0 * dist0 * ews.lane<0>() + + dist1 * dist1 * ews.lane<1>() + + dist2 * dist2 * ews.lane<2>(); + + haccumulate(l_errv, error, mask); + } + + a_drop_err = hadd_s(a_drop_errv) * ews.lane<3>(); + uncor_err = hadd_s(uncor_errv); + samec_err = hadd_s(samec_errv); + rgbl_err = hadd_s(rgbl_errv); + l_err = hadd_s(l_errv); +} + +/** + * @brief For a given set of input colors and partitioning determine endpoint encode errors. + * + * This function determines the color error that results from RGB-scale encoding (LDR only), + * RGB-lumashift encoding (HDR only), luminance-encoding, and alpha drop. Also determines whether + * the endpoints are eligible for offset encoding or blue-contraction + * + * @param blk The image block. + * @param pi The partition info data. + * @param ep The idealized endpoints. + * @param[out] eci The resulting encoding choice error metrics. + */ +static void compute_encoding_choice_errors( + const image_block& blk, + const partition_info& pi, + const endpoints& ep, + encoding_choice_errors eci[BLOCK_MAX_PARTITIONS]) +{ + int partition_count = pi.partition_count; + promise(partition_count > 0); + + partition_metrics pms[BLOCK_MAX_PARTITIONS]; + + compute_avgs_and_dirs_3_comp_rgb(pi, blk, pms); + + for (int i = 0; i < partition_count; i++) + { + partition_metrics& pm = pms[i]; + + line3 uncor_rgb_lines; + line3 samec_rgb_lines; // for LDR-RGB-scale + line3 rgb_luma_lines; // for HDR-RGB-scale + + processed_line3 uncor_rgb_plines; + processed_line3 samec_rgb_plines; + processed_line3 rgb_luma_plines; + processed_line3 luminance_plines; + + float uncorr_rgb_error; + float samechroma_rgb_error; + float rgb_luma_error; + float luminance_rgb_error; + float alpha_drop_error; + + uncor_rgb_lines.a = pm.avg; + uncor_rgb_lines.b = normalize_safe(pm.dir, unit3()); + + samec_rgb_lines.a = vfloat4::zero(); + samec_rgb_lines.b = normalize_safe(pm.avg, unit3()); + + rgb_luma_lines.a = pm.avg; + rgb_luma_lines.b = unit3(); + + uncor_rgb_plines.amod = uncor_rgb_lines.a - uncor_rgb_lines.b * dot3(uncor_rgb_lines.a, uncor_rgb_lines.b); + uncor_rgb_plines.bs = uncor_rgb_lines.b; + + // Same chroma always goes though zero, so this is simpler than the others + samec_rgb_plines.amod = vfloat4::zero(); + samec_rgb_plines.bs = samec_rgb_lines.b; + + rgb_luma_plines.amod = rgb_luma_lines.a - rgb_luma_lines.b * dot3(rgb_luma_lines.a, rgb_luma_lines.b); + rgb_luma_plines.bs = rgb_luma_lines.b; + + // Luminance always goes though zero, so this is simpler than the others + luminance_plines.amod = vfloat4::zero(); + luminance_plines.bs = unit3(); + + compute_error_squared_rgb_single_partition( + pi, i, blk, + uncor_rgb_plines, uncorr_rgb_error, + samec_rgb_plines, samechroma_rgb_error, + rgb_luma_plines, rgb_luma_error, + luminance_plines, luminance_rgb_error, + alpha_drop_error); + + // Determine if we can offset encode RGB lanes + vfloat4 endpt0 = ep.endpt0[i]; + vfloat4 endpt1 = ep.endpt1[i]; + vfloat4 endpt_diff = abs(endpt1 - endpt0); + vmask4 endpt_can_offset = endpt_diff < vfloat4(0.12f * 65535.0f); + bool can_offset_encode = (mask(endpt_can_offset) & 0x7) == 0x7; + + // Store out the settings + eci[i].rgb_scale_error = (samechroma_rgb_error - uncorr_rgb_error) * 0.7f; // empirical + eci[i].rgb_luma_error = (rgb_luma_error - uncorr_rgb_error) * 1.5f; // wild guess + eci[i].luminance_error = (luminance_rgb_error - uncorr_rgb_error) * 3.0f; // empirical + eci[i].alpha_drop_error = alpha_drop_error * 3.0f; + eci[i].can_offset_encode = can_offset_encode; + eci[i].can_blue_contract = !blk.is_luminance(); + } +} + +/** + * @brief For a given partition compute the error for every endpoint integer count and quant level. + * + * @param encode_hdr_rgb @c true if using HDR for RGB, @c false for LDR. + * @param encode_hdr_alpha @c true if using HDR for alpha, @c false for LDR. + * @param partition_index The partition index. + * @param pi The partition info. + * @param eci The encoding choice error metrics. + * @param ep The idealized endpoints. + * @param error_weight The resulting encoding choice error metrics. + * @param[out] best_error The best error for each integer count and quant level. + * @param[out] format_of_choice The preferred endpoint format for each integer count and quant level. + */ +static void compute_color_error_for_every_integer_count_and_quant_level( + bool encode_hdr_rgb, + bool encode_hdr_alpha, + int partition_index, + const partition_info& pi, + const encoding_choice_errors& eci, + const endpoints& ep, + vfloat4 error_weight, + float best_error[21][4], + uint8_t format_of_choice[21][4] +) { + int partition_size = pi.partition_texel_count[partition_index]; + + static const float baseline_quant_error[21 - QUANT_6] { + (65536.0f * 65536.0f / 18.0f) / (5 * 5), + (65536.0f * 65536.0f / 18.0f) / (7 * 7), + (65536.0f * 65536.0f / 18.0f) / (9 * 9), + (65536.0f * 65536.0f / 18.0f) / (11 * 11), + (65536.0f * 65536.0f / 18.0f) / (15 * 15), + (65536.0f * 65536.0f / 18.0f) / (19 * 19), + (65536.0f * 65536.0f / 18.0f) / (23 * 23), + (65536.0f * 65536.0f / 18.0f) / (31 * 31), + (65536.0f * 65536.0f / 18.0f) / (39 * 39), + (65536.0f * 65536.0f / 18.0f) / (47 * 47), + (65536.0f * 65536.0f / 18.0f) / (63 * 63), + (65536.0f * 65536.0f / 18.0f) / (79 * 79), + (65536.0f * 65536.0f / 18.0f) / (95 * 95), + (65536.0f * 65536.0f / 18.0f) / (127 * 127), + (65536.0f * 65536.0f / 18.0f) / (159 * 159), + (65536.0f * 65536.0f / 18.0f) / (191 * 191), + (65536.0f * 65536.0f / 18.0f) / (255 * 255) + }; + + vfloat4 ep0 = ep.endpt0[partition_index]; + vfloat4 ep1 = ep.endpt1[partition_index]; + + float ep1_min = hmin_rgb_s(ep1); + ep1_min = astc::max(ep1_min, 0.0f); + + float error_weight_rgbsum = hadd_rgb_s(error_weight); + + float range_upper_limit_rgb = encode_hdr_rgb ? 61440.0f : 65535.0f; + float range_upper_limit_alpha = encode_hdr_alpha ? 61440.0f : 65535.0f; + + // It is possible to get endpoint colors significantly outside [0,upper-limit] even if the + // input data are safely contained in [0,upper-limit]; we need to add an error term for this + vfloat4 offset(range_upper_limit_rgb, range_upper_limit_rgb, range_upper_limit_rgb, range_upper_limit_alpha); + vfloat4 ep0_range_error_high = max(ep0 - offset, 0.0f); + vfloat4 ep1_range_error_high = max(ep1 - offset, 0.0f); + + vfloat4 ep0_range_error_low = min(ep0, 0.0f); + vfloat4 ep1_range_error_low = min(ep1, 0.0f); + + vfloat4 sum_range_error = + (ep0_range_error_low * ep0_range_error_low) + + (ep1_range_error_low * ep1_range_error_low) + + (ep0_range_error_high * ep0_range_error_high) + + (ep1_range_error_high * ep1_range_error_high); + + float rgb_range_error = dot3_s(sum_range_error, error_weight) + * 0.5f * static_cast<float>(partition_size); + float alpha_range_error = sum_range_error.lane<3>() * error_weight.lane<3>() + * 0.5f * static_cast<float>(partition_size); + + if (encode_hdr_rgb) + { + + // Collect some statistics + float af, cf; + if (ep1.lane<0>() > ep1.lane<1>() && ep1.lane<0>() > ep1.lane<2>()) + { + af = ep1.lane<0>(); + cf = ep1.lane<0>() - ep0.lane<0>(); + } + else if (ep1.lane<1>() > ep1.lane<2>()) + { + af = ep1.lane<1>(); + cf = ep1.lane<1>() - ep0.lane<1>(); + } + else + { + af = ep1.lane<2>(); + cf = ep1.lane<2>() - ep0.lane<2>(); + } + + // Estimate of color-component spread in high endpoint color + float bf = af - ep1_min; + vfloat4 prd = (ep1 - vfloat4(cf)).swz<0, 1, 2>(); + vfloat4 pdif = prd - ep0.swz<0, 1, 2>(); + // Estimate of color-component spread in low endpoint color + float df = hmax_s(abs(pdif)); + + int b = static_cast<int>(bf); + int c = static_cast<int>(cf); + int d = static_cast<int>(df); + + // Determine which one of the 6 submodes is likely to be used in case of an RGBO-mode + int rgbo_mode = 5; // 7 bits per component + // mode 4: 8 7 6 + if (b < 32768 && c < 16384) + { + rgbo_mode = 4; + } + + // mode 3: 9 6 7 + if (b < 8192 && c < 16384) + { + rgbo_mode = 3; + } + + // mode 2: 10 5 8 + if (b < 2048 && c < 16384) + { + rgbo_mode = 2; + } + + // mode 1: 11 6 5 + if (b < 2048 && c < 1024) + { + rgbo_mode = 1; + } + + // mode 0: 11 5 7 + if (b < 1024 && c < 4096) + { + rgbo_mode = 0; + } + + // Determine which one of the 9 submodes is likely to be used in case of an RGB-mode. + int rgb_mode = 8; // 8 bits per component, except 7 bits for blue + + // mode 0: 9 7 6 7 + if (b < 16384 && c < 8192 && d < 8192) + { + rgb_mode = 0; + } + + // mode 1: 9 8 6 6 + if (b < 32768 && c < 8192 && d < 4096) + { + rgb_mode = 1; + } + + // mode 2: 10 6 7 7 + if (b < 4096 && c < 8192 && d < 4096) + { + rgb_mode = 2; + } + + // mode 3: 10 7 7 6 + if (b < 8192 && c < 8192 && d < 2048) + { + rgb_mode = 3; + } + + // mode 4: 11 8 6 5 + if (b < 8192 && c < 2048 && d < 512) + { + rgb_mode = 4; + } + + // mode 5: 11 6 8 6 + if (b < 2048 && c < 8192 && d < 1024) + { + rgb_mode = 5; + } + + // mode 6: 12 7 7 5 + if (b < 2048 && c < 2048 && d < 256) + { + rgb_mode = 6; + } + + // mode 7: 12 6 7 6 + if (b < 1024 && c < 2048 && d < 512) + { + rgb_mode = 7; + } + + static const float rgbo_error_scales[6] { 4.0f, 4.0f, 16.0f, 64.0f, 256.0f, 1024.0f }; + static const float rgb_error_scales[9] { 64.0f, 64.0f, 16.0f, 16.0f, 4.0f, 4.0f, 1.0f, 1.0f, 384.0f }; + + float mode7mult = rgbo_error_scales[rgbo_mode] * 0.0015f; // Empirically determined .... + float mode11mult = rgb_error_scales[rgb_mode] * 0.010f; // Empirically determined .... + + + float lum_high = hadd_rgb_s(ep1) * (1.0f / 3.0f); + float lum_low = hadd_rgb_s(ep0) * (1.0f / 3.0f); + float lumdif = lum_high - lum_low; + float mode23mult = lumdif < 960 ? 4.0f : lumdif < 3968 ? 16.0f : 128.0f; + + mode23mult *= 0.0005f; // Empirically determined .... + + // Pick among the available HDR endpoint modes + for (int i = QUANT_2; i < QUANT_16; i++) + { + best_error[i][3] = ERROR_CALC_DEFAULT; + best_error[i][2] = ERROR_CALC_DEFAULT; + best_error[i][1] = ERROR_CALC_DEFAULT; + best_error[i][0] = ERROR_CALC_DEFAULT; + + format_of_choice[i][3] = static_cast<uint8_t>(encode_hdr_alpha ? FMT_HDR_RGBA : FMT_HDR_RGB_LDR_ALPHA); + format_of_choice[i][2] = FMT_HDR_RGB; + format_of_choice[i][1] = FMT_HDR_RGB_SCALE; + format_of_choice[i][0] = FMT_HDR_LUMINANCE_LARGE_RANGE; + } + + for (int i = QUANT_16; i <= QUANT_256; i++) + { + // The base_quant_error should depend on the scale-factor that would be used during + // actual encode of the color value + + float base_quant_error = baseline_quant_error[i - QUANT_6] * static_cast<float>(partition_size); + float rgb_quantization_error = error_weight_rgbsum * base_quant_error * 2.0f; + float alpha_quantization_error = error_weight.lane<3>() * base_quant_error * 2.0f; + float rgba_quantization_error = rgb_quantization_error + alpha_quantization_error; + + // For 8 integers, we have two encodings: one with HDR A and another one with LDR A + + float full_hdr_rgba_error = rgba_quantization_error + rgb_range_error + alpha_range_error; + best_error[i][3] = full_hdr_rgba_error; + format_of_choice[i][3] = static_cast<uint8_t>(encode_hdr_alpha ? FMT_HDR_RGBA : FMT_HDR_RGB_LDR_ALPHA); + + // For 6 integers, we have one HDR-RGB encoding + float full_hdr_rgb_error = (rgb_quantization_error * mode11mult) + rgb_range_error + eci.alpha_drop_error; + best_error[i][2] = full_hdr_rgb_error; + format_of_choice[i][2] = FMT_HDR_RGB; + + // For 4 integers, we have one HDR-RGB-Scale encoding + float hdr_rgb_scale_error = (rgb_quantization_error * mode7mult) + rgb_range_error + eci.alpha_drop_error + eci.rgb_luma_error; + + best_error[i][1] = hdr_rgb_scale_error; + format_of_choice[i][1] = FMT_HDR_RGB_SCALE; + + // For 2 integers, we assume luminance-with-large-range + float hdr_luminance_error = (rgb_quantization_error * mode23mult) + rgb_range_error + eci.alpha_drop_error + eci.luminance_error; + best_error[i][0] = hdr_luminance_error; + format_of_choice[i][0] = FMT_HDR_LUMINANCE_LARGE_RANGE; + } + } + else + { + for (int i = QUANT_2; i < QUANT_6; i++) + { + best_error[i][3] = ERROR_CALC_DEFAULT; + best_error[i][2] = ERROR_CALC_DEFAULT; + best_error[i][1] = ERROR_CALC_DEFAULT; + best_error[i][0] = ERROR_CALC_DEFAULT; + + format_of_choice[i][3] = FMT_RGBA; + format_of_choice[i][2] = FMT_RGB; + format_of_choice[i][1] = FMT_RGB_SCALE; + format_of_choice[i][0] = FMT_LUMINANCE; + } + + float base_quant_error_rgb = error_weight_rgbsum * static_cast<float>(partition_size); + float base_quant_error_a = error_weight.lane<3>() * static_cast<float>(partition_size); + float base_quant_error_rgba = base_quant_error_rgb + base_quant_error_a; + + float error_scale_bc_rgba = eci.can_blue_contract ? 0.625f : 1.0f; + float error_scale_oe_rgba = eci.can_offset_encode ? 0.5f : 1.0f; + + float error_scale_bc_rgb = eci.can_blue_contract ? 0.5f : 1.0f; + float error_scale_oe_rgb = eci.can_offset_encode ? 0.25f : 1.0f; + + // Pick among the available LDR endpoint modes + for (int i = QUANT_6; i <= QUANT_256; i++) + { + // Offset encoding not possible at higher quant levels + if (i >= QUANT_192) + { + error_scale_oe_rgba = 1.0f; + error_scale_oe_rgb = 1.0f; + } + + float base_quant_error = baseline_quant_error[i - QUANT_6]; + float quant_error_rgb = base_quant_error_rgb * base_quant_error; + float quant_error_rgba = base_quant_error_rgba * base_quant_error; + + // 8 integers can encode as RGBA+RGBA + float full_ldr_rgba_error = quant_error_rgba + * error_scale_bc_rgba + * error_scale_oe_rgba + + rgb_range_error + + alpha_range_error; + + best_error[i][3] = full_ldr_rgba_error; + format_of_choice[i][3] = FMT_RGBA; + + // 6 integers can encode as RGB+RGB or RGBS+AA + float full_ldr_rgb_error = quant_error_rgb + * error_scale_bc_rgb + * error_scale_oe_rgb + + rgb_range_error + + eci.alpha_drop_error; + + float rgbs_alpha_error = quant_error_rgba + + eci.rgb_scale_error + + rgb_range_error + + alpha_range_error; + + if (rgbs_alpha_error < full_ldr_rgb_error) + { + best_error[i][2] = rgbs_alpha_error; + format_of_choice[i][2] = FMT_RGB_SCALE_ALPHA; + } + else + { + best_error[i][2] = full_ldr_rgb_error; + format_of_choice[i][2] = FMT_RGB; + } + + // 4 integers can encode as RGBS or LA+LA + float ldr_rgbs_error = quant_error_rgb + + rgb_range_error + + eci.alpha_drop_error + + eci.rgb_scale_error; + + float lum_alpha_error = quant_error_rgba + + rgb_range_error + + alpha_range_error + + eci.luminance_error; + + if (ldr_rgbs_error < lum_alpha_error) + { + best_error[i][1] = ldr_rgbs_error; + format_of_choice[i][1] = FMT_RGB_SCALE; + } + else + { + best_error[i][1] = lum_alpha_error; + format_of_choice[i][1] = FMT_LUMINANCE_ALPHA; + } + + // 2 integers can encode as L+L + float luminance_error = quant_error_rgb + + rgb_range_error + + eci.alpha_drop_error + + eci.luminance_error; + + best_error[i][0] = luminance_error; + format_of_choice[i][0] = FMT_LUMINANCE; + } + } +} + +/** + * @brief For one partition compute the best format and quantization for a given bit count. + * + * @param best_combined_error The best error for each quant level and integer count. + * @param best_combined_format The best format for each quant level and integer count. + * @param bits_available The number of bits available for encoding. + * @param[out] best_quant_level The output best color quant level. + * @param[out] best_format The output best color format. + * + * @return The output error for the best pairing. + */ +static float one_partition_find_best_combination_for_bitcount( + const float best_combined_error[21][4], + const uint8_t best_combined_format[21][4], + int bits_available, + uint8_t& best_quant_level, + uint8_t& best_format +) { + int best_integer_count = 0; + float best_integer_count_error = ERROR_CALC_DEFAULT; + + for (int integer_count = 1; integer_count <= 4; integer_count++) + { + // Compute the quantization level for a given number of integers and a given number of bits + int quant_level = quant_mode_table[integer_count][bits_available]; + + // Don't have enough bits to represent a given endpoint format at all! + if (quant_level < QUANT_6) + { + continue; + } + + float integer_count_error = best_combined_error[quant_level][integer_count - 1]; + if (integer_count_error < best_integer_count_error) + { + best_integer_count_error = integer_count_error; + best_integer_count = integer_count - 1; + } + } + + int ql = quant_mode_table[best_integer_count + 1][bits_available]; + + best_quant_level = static_cast<uint8_t>(ql); + best_format = FMT_LUMINANCE; + + if (ql >= QUANT_6) + { + best_format = best_combined_format[ql][best_integer_count]; + } + + return best_integer_count_error; +} + +/** + * @brief For 2 partitions compute the best format combinations for every pair of quant mode and integer count. + * + * @param best_error The best error for a single endpoint quant level and integer count. + * @param best_format The best format for a single endpoint quant level and integer count. + * @param[out] best_combined_error The best combined error pairings for the 2 partitions. + * @param[out] best_combined_format The best combined format pairings for the 2 partitions. + */ +static void two_partitions_find_best_combination_for_every_quantization_and_integer_count( + const float best_error[2][21][4], // indexed by (partition, quant-level, integer-pair-count-minus-1) + const uint8_t best_format[2][21][4], + float best_combined_error[21][7], // indexed by (quant-level, integer-pair-count-minus-2) + uint8_t best_combined_format[21][7][2] +) { + for (int i = QUANT_2; i <= QUANT_256; i++) + { + for (int j = 0; j < 7; j++) + { + best_combined_error[i][j] = ERROR_CALC_DEFAULT; + } + } + + for (int quant = QUANT_6; quant <= QUANT_256; quant++) + { + for (int i = 0; i < 4; i++) // integer-count for first endpoint-pair + { + for (int j = 0; j < 4; j++) // integer-count for second endpoint-pair + { + int low2 = astc::min(i, j); + int high2 = astc::max(i, j); + if ((high2 - low2) > 1) + { + continue; + } + + int intcnt = i + j; + float errorterm = astc::min(best_error[0][quant][i] + best_error[1][quant][j], 1e10f); + if (errorterm <= best_combined_error[quant][intcnt]) + { + best_combined_error[quant][intcnt] = errorterm; + best_combined_format[quant][intcnt][0] = best_format[0][quant][i]; + best_combined_format[quant][intcnt][1] = best_format[1][quant][j]; + } + } + } + } +} + +/** + * @brief For 2 partitions compute the best format and quantization for a given bit count. + * + * @param best_combined_error The best error for each quant level and integer count. + * @param best_combined_format The best format for each quant level and integer count. + * @param bits_available The number of bits available for encoding. + * @param[out] best_quant_level The output best color quant level. + * @param[out] best_quant_level_mod The output best color quant level assuming two more bits are available. + * @param[out] best_formats The output best color formats. + * + * @return The output error for the best pairing. + */ +static float two_partitions_find_best_combination_for_bitcount( + float best_combined_error[21][7], + uint8_t best_combined_format[21][7][2], + int bits_available, + uint8_t& best_quant_level, + uint8_t& best_quant_level_mod, + uint8_t* best_formats +) { + int best_integer_count = 0; + float best_integer_count_error = ERROR_CALC_DEFAULT; + + for (int integer_count = 2; integer_count <= 8; integer_count++) + { + // Compute the quantization level for a given number of integers and a given number of bits + int quant_level = quant_mode_table[integer_count][bits_available]; + + // Don't have enough bits to represent a given endpoint format at all! + if (quant_level < QUANT_6) + { + break; + } + + float integer_count_error = best_combined_error[quant_level][integer_count - 2]; + if (integer_count_error < best_integer_count_error) + { + best_integer_count_error = integer_count_error; + best_integer_count = integer_count; + } + } + + int ql = quant_mode_table[best_integer_count][bits_available]; + int ql_mod = quant_mode_table[best_integer_count][bits_available + 2]; + + best_quant_level = static_cast<uint8_t>(ql); + best_quant_level_mod = static_cast<uint8_t>(ql_mod); + + if (ql >= QUANT_6) + { + for (int i = 0; i < 2; i++) + { + best_formats[i] = best_combined_format[ql][best_integer_count - 2][i]; + } + } + else + { + for (int i = 0; i < 2; i++) + { + best_formats[i] = FMT_LUMINANCE; + } + } + + return best_integer_count_error; +} + +/** + * @brief For 3 partitions compute the best format combinations for every pair of quant mode and integer count. + * + * @param best_error The best error for a single endpoint quant level and integer count. + * @param best_format The best format for a single endpoint quant level and integer count. + * @param[out] best_combined_error The best combined error pairings for the 3 partitions. + * @param[out] best_combined_format The best combined format pairings for the 3 partitions. + */ +static void three_partitions_find_best_combination_for_every_quantization_and_integer_count( + const float best_error[3][21][4], // indexed by (partition, quant-level, integer-count) + const uint8_t best_format[3][21][4], + float best_combined_error[21][10], + uint8_t best_combined_format[21][10][3] +) { + for (int i = QUANT_2; i <= QUANT_256; i++) + { + for (int j = 0; j < 10; j++) + { + best_combined_error[i][j] = ERROR_CALC_DEFAULT; + } + } + + for (int quant = QUANT_6; quant <= QUANT_256; quant++) + { + for (int i = 0; i < 4; i++) // integer-count for first endpoint-pair + { + for (int j = 0; j < 4; j++) // integer-count for second endpoint-pair + { + int low2 = astc::min(i, j); + int high2 = astc::max(i, j); + if ((high2 - low2) > 1) + { + continue; + } + + for (int k = 0; k < 4; k++) // integer-count for third endpoint-pair + { + int low3 = astc::min(k, low2); + int high3 = astc::max(k, high2); + if ((high3 - low3) > 1) + { + continue; + } + + int intcnt = i + j + k; + float errorterm = astc::min(best_error[0][quant][i] + best_error[1][quant][j] + best_error[2][quant][k], 1e10f); + if (errorterm <= best_combined_error[quant][intcnt]) + { + best_combined_error[quant][intcnt] = errorterm; + best_combined_format[quant][intcnt][0] = best_format[0][quant][i]; + best_combined_format[quant][intcnt][1] = best_format[1][quant][j]; + best_combined_format[quant][intcnt][2] = best_format[2][quant][k]; + } + } + } + } + } +} + +/** + * @brief For 3 partitions compute the best format and quantization for a given bit count. + * + * @param best_combined_error The best error for each quant level and integer count. + * @param best_combined_format The best format for each quant level and integer count. + * @param bits_available The number of bits available for encoding. + * @param[out] best_quant_level The output best color quant level. + * @param[out] best_quant_level_mod The output best color quant level assuming two more bits are available. + * @param[out] best_formats The output best color formats. + * + * @return The output error for the best pairing. + */ +static float three_partitions_find_best_combination_for_bitcount( + const float best_combined_error[21][10], + const uint8_t best_combined_format[21][10][3], + int bits_available, + uint8_t& best_quant_level, + uint8_t& best_quant_level_mod, + uint8_t* best_formats +) { + int best_integer_count = 0; + float best_integer_count_error = ERROR_CALC_DEFAULT; + + for (int integer_count = 3; integer_count <= 9; integer_count++) + { + // Compute the quantization level for a given number of integers and a given number of bits + int quant_level = quant_mode_table[integer_count][bits_available]; + + // Don't have enough bits to represent a given endpoint format at all! + if (quant_level < QUANT_6) + { + break; + } + + float integer_count_error = best_combined_error[quant_level][integer_count - 3]; + if (integer_count_error < best_integer_count_error) + { + best_integer_count_error = integer_count_error; + best_integer_count = integer_count; + } + } + + int ql = quant_mode_table[best_integer_count][bits_available]; + int ql_mod = quant_mode_table[best_integer_count][bits_available + 5]; + + best_quant_level = static_cast<uint8_t>(ql); + best_quant_level_mod = static_cast<uint8_t>(ql_mod); + + if (ql >= QUANT_6) + { + for (int i = 0; i < 3; i++) + { + best_formats[i] = best_combined_format[ql][best_integer_count - 3][i]; + } + } + else + { + for (int i = 0; i < 3; i++) + { + best_formats[i] = FMT_LUMINANCE; + } + } + + return best_integer_count_error; +} + +/** + * @brief For 4 partitions compute the best format combinations for every pair of quant mode and integer count. + * + * @param best_error The best error for a single endpoint quant level and integer count. + * @param best_format The best format for a single endpoint quant level and integer count. + * @param[out] best_combined_error The best combined error pairings for the 4 partitions. + * @param[out] best_combined_format The best combined format pairings for the 4 partitions. + */ +static void four_partitions_find_best_combination_for_every_quantization_and_integer_count( + const float best_error[4][21][4], // indexed by (partition, quant-level, integer-count) + const uint8_t best_format[4][21][4], + float best_combined_error[21][13], + uint8_t best_combined_format[21][13][4] +) { + for (int i = QUANT_2; i <= QUANT_256; i++) + { + for (int j = 0; j < 13; j++) + { + best_combined_error[i][j] = ERROR_CALC_DEFAULT; + } + } + + for (int quant = QUANT_6; quant <= QUANT_256; quant++) + { + for (int i = 0; i < 4; i++) // integer-count for first endpoint-pair + { + for (int j = 0; j < 4; j++) // integer-count for second endpoint-pair + { + int low2 = astc::min(i, j); + int high2 = astc::max(i, j); + if ((high2 - low2) > 1) + { + continue; + } + + for (int k = 0; k < 4; k++) // integer-count for third endpoint-pair + { + int low3 = astc::min(k, low2); + int high3 = astc::max(k, high2); + if ((high3 - low3) > 1) + { + continue; + } + + for (int l = 0; l < 4; l++) // integer-count for fourth endpoint-pair + { + int low4 = astc::min(l, low3); + int high4 = astc::max(l, high3); + if ((high4 - low4) > 1) + { + continue; + } + + int intcnt = i + j + k + l; + float errorterm = astc::min(best_error[0][quant][i] + best_error[1][quant][j] + best_error[2][quant][k] + best_error[3][quant][l], 1e10f); + if (errorterm <= best_combined_error[quant][intcnt]) + { + best_combined_error[quant][intcnt] = errorterm; + best_combined_format[quant][intcnt][0] = best_format[0][quant][i]; + best_combined_format[quant][intcnt][1] = best_format[1][quant][j]; + best_combined_format[quant][intcnt][2] = best_format[2][quant][k]; + best_combined_format[quant][intcnt][3] = best_format[3][quant][l]; + } + } + } + } + } + } +} + +/** + * @brief For 4 partitions compute the best format and quantization for a given bit count. + * + * @param best_combined_error The best error for each quant level and integer count. + * @param best_combined_format The best format for each quant level and integer count. + * @param bits_available The number of bits available for encoding. + * @param[out] best_quant_level The output best color quant level. + * @param[out] best_quant_level_mod The output best color quant level assuming two more bits are available. + * @param[out] best_formats The output best color formats. + * + * @return best_error The output error for the best pairing. + */ +static float four_partitions_find_best_combination_for_bitcount( + const float best_combined_error[21][13], + const uint8_t best_combined_format[21][13][4], + int bits_available, + uint8_t& best_quant_level, + uint8_t& best_quant_level_mod, + uint8_t* best_formats +) { + int best_integer_count = 0; + float best_integer_count_error = ERROR_CALC_DEFAULT; + + for (int integer_count = 4; integer_count <= 9; integer_count++) + { + // Compute the quantization level for a given number of integers and a given number of bits + int quant_level = quant_mode_table[integer_count][bits_available]; + + // Don't have enough bits to represent a given endpoint format at all! + if (quant_level < QUANT_6) + { + break; + } + + float integer_count_error = best_combined_error[quant_level][integer_count - 4]; + if (integer_count_error < best_integer_count_error) + { + best_integer_count_error = integer_count_error; + best_integer_count = integer_count; + } + } + + int ql = quant_mode_table[best_integer_count][bits_available]; + int ql_mod = quant_mode_table[best_integer_count][bits_available + 8]; + + best_quant_level = static_cast<uint8_t>(ql); + best_quant_level_mod = static_cast<uint8_t>(ql_mod); + + if (ql >= QUANT_6) + { + for (int i = 0; i < 4; i++) + { + best_formats[i] = best_combined_format[ql][best_integer_count - 4][i]; + } + } + else + { + for (int i = 0; i < 4; i++) + { + best_formats[i] = FMT_LUMINANCE; + } + } + + return best_integer_count_error; +} + +/* See header for documentation. */ +unsigned int compute_ideal_endpoint_formats( + const partition_info& pi, + const image_block& blk, + const endpoints& ep, + // bitcounts and errors computed for the various quantization methods + const int8_t* qwt_bitcounts, + const float* qwt_errors, + unsigned int tune_candidate_limit, + unsigned int start_block_mode, + unsigned int end_block_mode, + // output data + uint8_t partition_format_specifiers[TUNE_MAX_TRIAL_CANDIDATES][BLOCK_MAX_PARTITIONS], + int block_mode[TUNE_MAX_TRIAL_CANDIDATES], + quant_method quant_level[TUNE_MAX_TRIAL_CANDIDATES], + quant_method quant_level_mod[TUNE_MAX_TRIAL_CANDIDATES], + compression_working_buffers& tmpbuf +) { + int partition_count = pi.partition_count; + + promise(partition_count > 0); + + bool encode_hdr_rgb = static_cast<bool>(blk.rgb_lns[0]); + bool encode_hdr_alpha = static_cast<bool>(blk.alpha_lns[0]); + + // Compute the errors that result from various encoding choices (such as using luminance instead + // of RGB, discarding Alpha, using RGB-scale in place of two separate RGB endpoints and so on) + encoding_choice_errors eci[BLOCK_MAX_PARTITIONS]; + compute_encoding_choice_errors(blk, pi, ep, eci); + + float best_error[BLOCK_MAX_PARTITIONS][21][4]; + uint8_t format_of_choice[BLOCK_MAX_PARTITIONS][21][4]; + for (int i = 0; i < partition_count; i++) + { + compute_color_error_for_every_integer_count_and_quant_level( + encode_hdr_rgb, encode_hdr_alpha, i, + pi, eci[i], ep, blk.channel_weight, best_error[i], + format_of_choice[i]); + } + + float* errors_of_best_combination = tmpbuf.errors_of_best_combination; + uint8_t* best_quant_levels = tmpbuf.best_quant_levels; + uint8_t* best_quant_levels_mod = tmpbuf.best_quant_levels_mod; + uint8_t (&best_ep_formats)[WEIGHTS_MAX_BLOCK_MODES][BLOCK_MAX_PARTITIONS] = tmpbuf.best_ep_formats; + + // Ensure that the first iteration understep contains data that will never be picked + vfloat clear_error(ERROR_CALC_DEFAULT); + vint clear_quant(0); + + unsigned int packed_start_block_mode = round_down_to_simd_multiple_vla(start_block_mode); + storea(clear_error, errors_of_best_combination + packed_start_block_mode); + store_nbytes(clear_quant, best_quant_levels + packed_start_block_mode); + store_nbytes(clear_quant, best_quant_levels_mod + packed_start_block_mode); + + // Ensure that last iteration overstep contains data that will never be picked + unsigned int packed_end_block_mode = round_down_to_simd_multiple_vla(end_block_mode - 1); + storea(clear_error, errors_of_best_combination + packed_end_block_mode); + store_nbytes(clear_quant, best_quant_levels + packed_end_block_mode); + store_nbytes(clear_quant, best_quant_levels_mod + packed_end_block_mode); + + // Track a scalar best to avoid expensive search at least once ... + float error_of_best_combination = ERROR_CALC_DEFAULT; + int index_of_best_combination = -1; + + // The block contains 1 partition + if (partition_count == 1) + { + for (unsigned int i = start_block_mode; i < end_block_mode; i++) + { + if (qwt_errors[i] >= ERROR_CALC_DEFAULT) + { + errors_of_best_combination[i] = ERROR_CALC_DEFAULT; + continue; + } + + float error_of_best = one_partition_find_best_combination_for_bitcount( + best_error[0], format_of_choice[0], qwt_bitcounts[i], + best_quant_levels[i], best_ep_formats[i][0]); + + float total_error = error_of_best + qwt_errors[i]; + errors_of_best_combination[i] = total_error; + best_quant_levels_mod[i] = best_quant_levels[i]; + + if (total_error < error_of_best_combination) + { + error_of_best_combination = total_error; + index_of_best_combination = i; + } + } + } + // The block contains 2 partitions + else if (partition_count == 2) + { + float combined_best_error[21][7]; + uint8_t formats_of_choice[21][7][2]; + + two_partitions_find_best_combination_for_every_quantization_and_integer_count( + best_error, format_of_choice, combined_best_error, formats_of_choice); + + assert(start_block_mode == 0); + for (unsigned int i = 0; i < end_block_mode; i++) + { + if (qwt_errors[i] >= ERROR_CALC_DEFAULT) + { + errors_of_best_combination[i] = ERROR_CALC_DEFAULT; + continue; + } + + float error_of_best = two_partitions_find_best_combination_for_bitcount( + combined_best_error, formats_of_choice, qwt_bitcounts[i], + best_quant_levels[i], best_quant_levels_mod[i], + best_ep_formats[i]); + + float total_error = error_of_best + qwt_errors[i]; + errors_of_best_combination[i] = total_error; + + if (total_error < error_of_best_combination) + { + error_of_best_combination = total_error; + index_of_best_combination = i; + } + } + } + // The block contains 3 partitions + else if (partition_count == 3) + { + float combined_best_error[21][10]; + uint8_t formats_of_choice[21][10][3]; + + three_partitions_find_best_combination_for_every_quantization_and_integer_count( + best_error, format_of_choice, combined_best_error, formats_of_choice); + + assert(start_block_mode == 0); + for (unsigned int i = 0; i < end_block_mode; i++) + { + if (qwt_errors[i] >= ERROR_CALC_DEFAULT) + { + errors_of_best_combination[i] = ERROR_CALC_DEFAULT; + continue; + } + + float error_of_best = three_partitions_find_best_combination_for_bitcount( + combined_best_error, formats_of_choice, qwt_bitcounts[i], + best_quant_levels[i], best_quant_levels_mod[i], + best_ep_formats[i]); + + float total_error = error_of_best + qwt_errors[i]; + errors_of_best_combination[i] = total_error; + + if (total_error < error_of_best_combination) + { + error_of_best_combination = total_error; + index_of_best_combination = i; + } + } + } + // The block contains 4 partitions + else // if (partition_count == 4) + { + assert(partition_count == 4); + float combined_best_error[21][13]; + uint8_t formats_of_choice[21][13][4]; + + four_partitions_find_best_combination_for_every_quantization_and_integer_count( + best_error, format_of_choice, combined_best_error, formats_of_choice); + + assert(start_block_mode == 0); + for (unsigned int i = 0; i < end_block_mode; i++) + { + if (qwt_errors[i] >= ERROR_CALC_DEFAULT) + { + errors_of_best_combination[i] = ERROR_CALC_DEFAULT; + continue; + } + + float error_of_best = four_partitions_find_best_combination_for_bitcount( + combined_best_error, formats_of_choice, qwt_bitcounts[i], + best_quant_levels[i], best_quant_levels_mod[i], + best_ep_formats[i]); + + float total_error = error_of_best + qwt_errors[i]; + errors_of_best_combination[i] = total_error; + + if (total_error < error_of_best_combination) + { + error_of_best_combination = total_error; + index_of_best_combination = i; + } + } + } + + int best_error_weights[TUNE_MAX_TRIAL_CANDIDATES]; + + // Fast path the first result and avoid the list search for trial 0 + best_error_weights[0] = index_of_best_combination; + if (index_of_best_combination >= 0) + { + errors_of_best_combination[index_of_best_combination] = ERROR_CALC_DEFAULT; + } + + // Search the remaining results and pick the best candidate modes for trial 1+ + for (unsigned int i = 1; i < tune_candidate_limit; i++) + { + vint vbest_error_index(-1); + vfloat vbest_ep_error(ERROR_CALC_DEFAULT); + + start_block_mode = round_down_to_simd_multiple_vla(start_block_mode); + vint lane_ids = vint::lane_id() + vint(start_block_mode); + for (unsigned int j = start_block_mode; j < end_block_mode; j += ASTCENC_SIMD_WIDTH) + { + vfloat err = vfloat(errors_of_best_combination + j); + vmask mask = err < vbest_ep_error; + vbest_ep_error = select(vbest_ep_error, err, mask); + vbest_error_index = select(vbest_error_index, lane_ids, mask); + lane_ids += vint(ASTCENC_SIMD_WIDTH); + } + + // Pick best mode from the SIMD result, using lowest matching index to ensure invariance + vmask lanes_min_error = vbest_ep_error == hmin(vbest_ep_error); + vbest_error_index = select(vint(0x7FFFFFFF), vbest_error_index, lanes_min_error); + vbest_error_index = hmin(vbest_error_index); + int best_error_index = vbest_error_index.lane<0>(); + + best_error_weights[i] = best_error_index; + + // Max the error for this candidate so we don't pick it again + if (best_error_index >= 0) + { + errors_of_best_combination[best_error_index] = ERROR_CALC_DEFAULT; + } + // Early-out if no more candidates are valid + else + { + break; + } + } + + for (unsigned int i = 0; i < tune_candidate_limit; i++) + { + if (best_error_weights[i] < 0) + { + return i; + } + + block_mode[i] = best_error_weights[i]; + + quant_level[i] = static_cast<quant_method>(best_quant_levels[best_error_weights[i]]); + quant_level_mod[i] = static_cast<quant_method>(best_quant_levels_mod[best_error_weights[i]]); + + assert(quant_level[i] >= QUANT_6 && quant_level[i] <= QUANT_256); + assert(quant_level_mod[i] >= QUANT_6 && quant_level_mod[i] <= QUANT_256); + + for (int j = 0; j < partition_count; j++) + { + partition_format_specifiers[i][j] = best_ep_formats[best_error_weights[i]][j]; + } + } + + return tune_candidate_limit; +} + +#endif diff --git a/thirdparty/astcenc/astcenc_platform_isa_detection.cpp b/thirdparty/astcenc/astcenc_platform_isa_detection.cpp new file mode 100644 index 0000000000..8ed98437ea --- /dev/null +++ b/thirdparty/astcenc/astcenc_platform_isa_detection.cpp @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2020-2022 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief Platform-specific function implementations. + * + * This module contains functions for querying the host extended ISA support. + */ + +// Include before the defines below to pick up any auto-setup based on compiler +// built-in config, if not being set explicitly by the build system +#include "astcenc_internal.h" + +#if (ASTCENC_SSE > 0) || (ASTCENC_AVX > 0) || \ + (ASTCENC_POPCNT > 0) || (ASTCENC_F16C > 0) + +static bool g_init { false }; + +/** Does this CPU support SSE 4.1? Set to -1 if not yet initialized. */ +static bool g_cpu_has_sse41 { false }; + +/** Does this CPU support AVX2? Set to -1 if not yet initialized. */ +static bool g_cpu_has_avx2 { false }; + +/** Does this CPU support POPCNT? Set to -1 if not yet initialized. */ +static bool g_cpu_has_popcnt { false }; + +/** Does this CPU support F16C? Set to -1 if not yet initialized. */ +static bool g_cpu_has_f16c { false }; + +/* ============================================================================ + Platform code for Visual Studio +============================================================================ */ +#if !defined(__clang__) && defined(_MSC_VER) +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <intrin.h> + +/** + * @brief Detect platform CPU ISA support and update global trackers. + */ +static void detect_cpu_isa() +{ + int data[4]; + + __cpuid(data, 0); + int num_id = data[0]; + + if (num_id >= 1) + { + __cpuidex(data, 1, 0); + // SSE41 = Bank 1, ECX, bit 19 + g_cpu_has_sse41 = data[2] & (1 << 19) ? true : false; + // POPCNT = Bank 1, ECX, bit 23 + g_cpu_has_popcnt = data[2] & (1 << 23) ? true : false; + // F16C = Bank 1, ECX, bit 29 + g_cpu_has_f16c = data[2] & (1 << 29) ? true : false; + } + + if (num_id >= 7) + { + __cpuidex(data, 7, 0); + // AVX2 = Bank 7, EBX, bit 5 + g_cpu_has_avx2 = data[1] & (1 << 5) ? true : false; + } + + // Ensure state bits are updated before init flag is updated + MemoryBarrier(); + g_init = true; +} + +/* ============================================================================ + Platform code for GCC and Clang +============================================================================ */ +#else +#include <cpuid.h> + +/** + * @brief Detect platform CPU ISA support and update global trackers. + */ +static void detect_cpu_isa() +{ + unsigned int data[4]; + + if (__get_cpuid_count(1, 0, &data[0], &data[1], &data[2], &data[3])) + { + // SSE41 = Bank 1, ECX, bit 19 + g_cpu_has_sse41 = data[2] & (1 << 19) ? true : false; + // POPCNT = Bank 1, ECX, bit 23 + g_cpu_has_popcnt = data[2] & (1 << 23) ? true : false; + // F16C = Bank 1, ECX, bit 29 + g_cpu_has_f16c = data[2] & (1 << 29) ? true : false; + } + + g_cpu_has_avx2 = 0; + if (__get_cpuid_count(7, 0, &data[0], &data[1], &data[2], &data[3])) + { + // AVX2 = Bank 7, EBX, bit 5 + g_cpu_has_avx2 = data[1] & (1 << 5) ? true : false; + } + + // Ensure state bits are updated before init flag is updated + __sync_synchronize(); + g_init = true; +} +#endif + +/* See header for documentation. */ +bool cpu_supports_popcnt() +{ + if (!g_init) + { + detect_cpu_isa(); + } + + return g_cpu_has_popcnt; +} + +/* See header for documentation. */ +bool cpu_supports_f16c() +{ + if (!g_init) + { + detect_cpu_isa(); + } + + return g_cpu_has_f16c; +} + +/* See header for documentation. */ +bool cpu_supports_sse41() +{ + if (!g_init) + { + detect_cpu_isa(); + } + + return g_cpu_has_sse41; +} + +/* See header for documentation. */ +bool cpu_supports_avx2() +{ + if (!g_init) + { + detect_cpu_isa(); + } + + return g_cpu_has_avx2; +} + +#endif diff --git a/thirdparty/astcenc/astcenc_quantization.cpp b/thirdparty/astcenc/astcenc_quantization.cpp new file mode 100644 index 0000000000..478a21ead7 --- /dev/null +++ b/thirdparty/astcenc/astcenc_quantization.cpp @@ -0,0 +1,904 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2021 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief Functions and data tables for numeric quantization.. + */ + +#include "astcenc_internal.h" + +#if !defined(ASTCENC_DECOMPRESS_ONLY) + +// Starts from QUANT_6 +// Not scrambled +const uint8_t color_unquant_to_uquant_tables[17][256] { + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 + }, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, + 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, + 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, + 182, 182, 182, 182, 182, 182, 182, 182, 182, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 + }, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, + 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, + 227, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 + }, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 163, 163, 163, 163, 163, 163, 163, 163, 163, + 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 186, + 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 232, 232, 232, + 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, + 232, 232, 232, 232, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 + }, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, + 204, 204, 204, 204, 204, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, + 238, 238, 238, 238, 238, 238, 238, 255, 255, 255, 255, 255, 255, 255, 255, 255 + }, + { + 0, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, + 188, 188, 188, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, + 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 255, 255, 255, 255, 255, 255, 255 + }, + { + 0, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 156, 156, 156, 156, 156, 156, 156, 156, 156, + 156, 156, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 211, 211, + 211, 211, 211, 211, 211, 211, 211, 211, 211, 222, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 244, + 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 255, 255, 255, 255, 255, 255 + }, + { + 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 16, 16, 16, + 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 24, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 41, 41, 41, 41, 41, 41, 41, 41, 49, 49, + 49, 49, 49, 49, 49, 49, 57, 57, 57, 57, 57, 57, 57, 57, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 74, 74, 74, 74, 74, 74, 74, 74, 82, + 82, 82, 82, 82, 82, 82, 82, 90, 90, 90, 90, 90, 90, 90, 90, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 107, 107, 107, 107, 107, 107, 107, 107, + 115, 115, 115, 115, 115, 115, 115, 115, 123, 123, 123, 123, 123, 123, 123, 123, + 132, 132, 132, 132, 132, 132, 132, 132, 140, 140, 140, 140, 140, 140, 140, 140, + 148, 148, 148, 148, 148, 148, 148, 148, 156, 156, 156, 156, 156, 156, 156, 156, + 156, 165, 165, 165, 165, 165, 165, 165, 165, 173, 173, 173, 173, 173, 173, 173, + 173, 181, 181, 181, 181, 181, 181, 181, 181, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 198, 198, 198, 198, 198, 198, 198, 198, 206, 206, 206, 206, 206, 206, + 206, 206, 214, 214, 214, 214, 214, 214, 214, 214, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 231, 231, 231, 231, 231, 231, 231, 231, 239, 239, 239, 239, 239, + 239, 239, 239, 247, 247, 247, 247, 247, 247, 247, 247, 255, 255, 255, 255, 255 + }, + { + 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 13, 13, 13, 13, 13, 13, + 13, 19, 19, 19, 19, 19, 19, 26, 26, 26, 26, 26, 26, 26, 32, 32, + 32, 32, 32, 32, 39, 39, 39, 39, 39, 39, 39, 45, 45, 45, 45, 45, + 45, 52, 52, 52, 52, 52, 52, 52, 58, 58, 58, 58, 58, 58, 65, 65, + 65, 65, 65, 65, 65, 71, 71, 71, 71, 71, 71, 78, 78, 78, 78, 78, + 78, 78, 84, 84, 84, 84, 84, 84, 91, 91, 91, 91, 91, 91, 91, 97, + 97, 97, 97, 97, 97, 104, 104, 104, 104, 104, 104, 104, 110, 110, 110, 110, + 110, 110, 117, 117, 117, 117, 117, 117, 117, 123, 123, 123, 123, 123, 123, 123, + 132, 132, 132, 132, 132, 132, 132, 138, 138, 138, 138, 138, 138, 138, 145, 145, + 145, 145, 145, 145, 151, 151, 151, 151, 151, 151, 151, 158, 158, 158, 158, 158, + 158, 164, 164, 164, 164, 164, 164, 164, 171, 171, 171, 171, 171, 171, 177, 177, + 177, 177, 177, 177, 177, 184, 184, 184, 184, 184, 184, 190, 190, 190, 190, 190, + 190, 190, 197, 197, 197, 197, 197, 197, 203, 203, 203, 203, 203, 203, 203, 210, + 210, 210, 210, 210, 210, 216, 216, 216, 216, 216, 216, 216, 223, 223, 223, 223, + 223, 223, 229, 229, 229, 229, 229, 229, 229, 236, 236, 236, 236, 236, 236, 242, + 242, 242, 242, 242, 242, 242, 249, 249, 249, 249, 249, 249, 255, 255, 255, 255 + }, + { + 0, 0, 0, 5, 5, 5, 5, 5, 5, 11, 11, 11, 11, 11, 16, 16, + 16, 16, 16, 21, 21, 21, 21, 21, 21, 27, 27, 27, 27, 27, 32, 32, + 32, 32, 32, 32, 38, 38, 38, 38, 38, 43, 43, 43, 43, 43, 48, 48, + 48, 48, 48, 48, 54, 54, 54, 54, 54, 59, 59, 59, 59, 59, 59, 65, + 65, 65, 65, 65, 70, 70, 70, 70, 70, 70, 76, 76, 76, 76, 76, 81, + 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 92, 92, 92, 92, 92, 97, + 97, 97, 97, 97, 97, 103, 103, 103, 103, 103, 108, 108, 108, 108, 108, 113, + 113, 113, 113, 113, 113, 119, 119, 119, 119, 119, 124, 124, 124, 124, 124, 124, + 131, 131, 131, 131, 131, 131, 136, 136, 136, 136, 136, 142, 142, 142, 142, 142, + 142, 147, 147, 147, 147, 147, 152, 152, 152, 152, 152, 158, 158, 158, 158, 158, + 158, 163, 163, 163, 163, 163, 169, 169, 169, 169, 169, 169, 174, 174, 174, 174, + 174, 179, 179, 179, 179, 179, 185, 185, 185, 185, 185, 185, 190, 190, 190, 190, + 190, 196, 196, 196, 196, 196, 196, 201, 201, 201, 201, 201, 207, 207, 207, 207, + 207, 207, 212, 212, 212, 212, 212, 217, 217, 217, 217, 217, 223, 223, 223, 223, + 223, 223, 228, 228, 228, 228, 228, 234, 234, 234, 234, 234, 234, 239, 239, 239, + 239, 239, 244, 244, 244, 244, 244, 250, 250, 250, 250, 250, 250, 255, 255, 255 + }, + { + 0, 0, 0, 4, 4, 4, 4, 8, 8, 8, 8, 12, 12, 12, 12, 16, + 16, 16, 16, 20, 20, 20, 20, 24, 24, 24, 24, 28, 28, 28, 28, 32, + 32, 32, 32, 36, 36, 36, 36, 40, 40, 40, 40, 44, 44, 44, 44, 48, + 48, 48, 48, 52, 52, 52, 52, 56, 56, 56, 56, 60, 60, 60, 60, 65, + 65, 65, 65, 65, 69, 69, 69, 69, 73, 73, 73, 73, 77, 77, 77, 77, + 81, 81, 81, 81, 85, 85, 85, 85, 89, 89, 89, 89, 93, 93, 93, 93, + 97, 97, 97, 97, 101, 101, 101, 101, 105, 105, 105, 105, 109, 109, 109, 109, + 113, 113, 113, 113, 117, 117, 117, 117, 121, 121, 121, 121, 125, 125, 125, 125, + 130, 130, 130, 130, 134, 134, 134, 134, 138, 138, 138, 138, 142, 142, 142, 142, + 146, 146, 146, 146, 150, 150, 150, 150, 154, 154, 154, 154, 158, 158, 158, 158, + 162, 162, 162, 162, 166, 166, 166, 166, 170, 170, 170, 170, 174, 174, 174, 174, + 178, 178, 178, 178, 182, 182, 182, 182, 186, 186, 186, 186, 190, 190, 190, 190, + 190, 195, 195, 195, 195, 199, 199, 199, 199, 203, 203, 203, 203, 207, 207, 207, + 207, 211, 211, 211, 211, 215, 215, 215, 215, 219, 219, 219, 219, 223, 223, 223, + 223, 227, 227, 227, 227, 231, 231, 231, 231, 235, 235, 235, 235, 239, 239, 239, + 239, 243, 243, 243, 243, 247, 247, 247, 247, 251, 251, 251, 251, 255, 255, 255 + }, + { + 0, 0, 3, 3, 3, 6, 6, 6, 9, 9, 9, 9, 13, 13, 13, 16, + 16, 16, 19, 19, 19, 22, 22, 22, 25, 25, 25, 25, 29, 29, 29, 32, + 32, 32, 35, 35, 35, 38, 38, 38, 38, 42, 42, 42, 45, 45, 45, 48, + 48, 48, 51, 51, 51, 54, 54, 54, 54, 58, 58, 58, 61, 61, 61, 64, + 64, 64, 67, 67, 67, 67, 71, 71, 71, 74, 74, 74, 77, 77, 77, 80, + 80, 80, 83, 83, 83, 83, 87, 87, 87, 90, 90, 90, 93, 93, 93, 96, + 96, 96, 96, 100, 100, 100, 103, 103, 103, 106, 106, 106, 109, 109, 109, 112, + 112, 112, 112, 116, 116, 116, 119, 119, 119, 122, 122, 122, 125, 125, 125, 125, + 130, 130, 130, 130, 133, 133, 133, 136, 136, 136, 139, 139, 139, 143, 143, 143, + 143, 146, 146, 146, 149, 149, 149, 152, 152, 152, 155, 155, 155, 159, 159, 159, + 159, 162, 162, 162, 165, 165, 165, 168, 168, 168, 172, 172, 172, 172, 175, 175, + 175, 178, 178, 178, 181, 181, 181, 184, 184, 184, 188, 188, 188, 188, 191, 191, + 191, 194, 194, 194, 197, 197, 197, 201, 201, 201, 201, 204, 204, 204, 207, 207, + 207, 210, 210, 210, 213, 213, 213, 217, 217, 217, 217, 220, 220, 220, 223, 223, + 223, 226, 226, 226, 230, 230, 230, 230, 233, 233, 233, 236, 236, 236, 239, 239, + 239, 242, 242, 242, 246, 246, 246, 246, 249, 249, 249, 252, 252, 252, 255, 255 + }, + { + 0, 0, 2, 2, 5, 5, 5, 8, 8, 8, 10, 10, 13, 13, 13, 16, + 16, 16, 18, 18, 21, 21, 21, 24, 24, 24, 26, 26, 29, 29, 29, 32, + 32, 32, 35, 35, 35, 37, 37, 40, 40, 40, 43, 43, 43, 45, 45, 48, + 48, 48, 51, 51, 51, 53, 53, 56, 56, 56, 59, 59, 59, 61, 61, 64, + 64, 64, 67, 67, 67, 70, 70, 70, 72, 72, 75, 75, 75, 78, 78, 78, + 80, 80, 83, 83, 83, 86, 86, 86, 88, 88, 91, 91, 91, 94, 94, 94, + 96, 96, 99, 99, 99, 102, 102, 102, 104, 104, 107, 107, 107, 110, 110, 110, + 112, 112, 115, 115, 115, 118, 118, 118, 120, 120, 123, 123, 123, 126, 126, 126, + 129, 129, 129, 132, 132, 132, 135, 135, 137, 137, 137, 140, 140, 140, 143, 143, + 145, 145, 145, 148, 148, 148, 151, 151, 153, 153, 153, 156, 156, 156, 159, 159, + 161, 161, 161, 164, 164, 164, 167, 167, 169, 169, 169, 172, 172, 172, 175, 175, + 177, 177, 177, 180, 180, 180, 183, 183, 185, 185, 185, 188, 188, 188, 191, 191, + 191, 194, 194, 196, 196, 196, 199, 199, 199, 202, 202, 204, 204, 204, 207, 207, + 207, 210, 210, 212, 212, 212, 215, 215, 215, 218, 218, 220, 220, 220, 223, 223, + 223, 226, 226, 226, 229, 229, 231, 231, 231, 234, 234, 234, 237, 237, 239, 239, + 239, 242, 242, 242, 245, 245, 247, 247, 247, 250, 250, 250, 253, 253, 255, 255 + }, + { + 0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, + 16, 16, 18, 18, 20, 20, 22, 22, 24, 24, 26, 26, 28, 28, 30, 30, + 32, 32, 34, 34, 36, 36, 38, 38, 40, 40, 42, 42, 44, 44, 46, 46, + 48, 48, 50, 50, 52, 52, 54, 54, 56, 56, 58, 58, 60, 60, 62, 62, + 64, 64, 66, 66, 68, 68, 70, 70, 72, 72, 74, 74, 76, 76, 78, 78, + 80, 80, 82, 82, 84, 84, 86, 86, 88, 88, 90, 90, 92, 92, 94, 94, + 96, 96, 98, 98, 100, 100, 102, 102, 104, 104, 106, 106, 108, 108, 110, 110, + 112, 112, 114, 114, 116, 116, 118, 118, 120, 120, 122, 122, 124, 124, 126, 126, + 129, 129, 131, 131, 133, 133, 135, 135, 137, 137, 139, 139, 141, 141, 143, 143, + 145, 145, 147, 147, 149, 149, 151, 151, 153, 153, 155, 155, 157, 157, 159, 159, + 161, 161, 163, 163, 165, 165, 167, 167, 169, 169, 171, 171, 173, 173, 175, 175, + 177, 177, 179, 179, 181, 181, 183, 183, 185, 185, 187, 187, 189, 189, 191, 191, + 193, 193, 195, 195, 197, 197, 199, 199, 201, 201, 203, 203, 205, 205, 207, 207, + 209, 209, 211, 211, 213, 213, 215, 215, 217, 217, 219, 219, 221, 221, 223, 223, + 225, 225, 227, 227, 229, 229, 231, 231, 233, 233, 235, 235, 237, 237, 239, 239, + 241, 241, 243, 243, 245, 245, 247, 247, 249, 249, 251, 251, 253, 253, 255, 255 + }, + { + 0, 1, 1, 3, 4, 4, 6, 6, 8, 9, 9, 11, 12, 12, 14, 14, + 16, 17, 17, 19, 20, 20, 22, 22, 24, 25, 25, 27, 28, 28, 30, 30, + 32, 33, 33, 35, 36, 36, 38, 38, 40, 41, 41, 43, 44, 44, 46, 46, + 48, 49, 49, 51, 52, 52, 54, 54, 56, 57, 57, 59, 60, 60, 62, 62, + 64, 65, 65, 67, 68, 68, 70, 70, 72, 73, 73, 75, 76, 76, 78, 78, + 80, 81, 81, 83, 84, 84, 86, 86, 88, 89, 89, 91, 92, 92, 94, 94, + 96, 97, 97, 99, 100, 100, 102, 102, 104, 105, 105, 107, 108, 108, 110, 110, + 112, 113, 113, 115, 116, 116, 118, 118, 120, 121, 121, 123, 124, 124, 126, 126, + 129, 129, 131, 131, 132, 134, 134, 135, 137, 137, 139, 139, 140, 142, 142, 143, + 145, 145, 147, 147, 148, 150, 150, 151, 153, 153, 155, 155, 156, 158, 158, 159, + 161, 161, 163, 163, 164, 166, 166, 167, 169, 169, 171, 171, 172, 174, 174, 175, + 177, 177, 179, 179, 180, 182, 182, 183, 185, 185, 187, 187, 188, 190, 190, 191, + 193, 193, 195, 195, 196, 198, 198, 199, 201, 201, 203, 203, 204, 206, 206, 207, + 209, 209, 211, 211, 212, 214, 214, 215, 217, 217, 219, 219, 220, 222, 222, 223, + 225, 225, 227, 227, 228, 230, 230, 231, 233, 233, 235, 235, 236, 238, 238, 239, + 241, 241, 243, 243, 244, 246, 246, 247, 249, 249, 251, 251, 252, 254, 254, 255 + }, + { + 0, 1, 2, 2, 4, 5, 6, 6, 8, 9, 10, 10, 12, 13, 14, 14, + 16, 17, 18, 18, 20, 21, 22, 22, 24, 25, 26, 26, 28, 29, 30, 30, + 32, 33, 34, 34, 36, 37, 38, 38, 40, 41, 42, 42, 44, 45, 46, 46, + 48, 49, 50, 50, 52, 53, 54, 54, 56, 57, 58, 58, 60, 61, 62, 62, + 64, 65, 66, 66, 68, 69, 70, 70, 72, 73, 74, 74, 76, 77, 78, 78, + 80, 81, 82, 82, 84, 85, 86, 86, 88, 89, 90, 90, 92, 93, 94, 94, + 96, 97, 98, 98, 100, 101, 102, 102, 104, 105, 106, 106, 108, 109, 110, 110, + 112, 113, 114, 114, 116, 117, 118, 118, 120, 121, 122, 122, 124, 125, 126, 126, + 129, 129, 130, 131, 133, 133, 134, 135, 137, 137, 138, 139, 141, 141, 142, 143, + 145, 145, 146, 147, 149, 149, 150, 151, 153, 153, 154, 155, 157, 157, 158, 159, + 161, 161, 162, 163, 165, 165, 166, 167, 169, 169, 170, 171, 173, 173, 174, 175, + 177, 177, 178, 179, 181, 181, 182, 183, 185, 185, 186, 187, 189, 189, 190, 191, + 193, 193, 194, 195, 197, 197, 198, 199, 201, 201, 202, 203, 205, 205, 206, 207, + 209, 209, 210, 211, 213, 213, 214, 215, 217, 217, 218, 219, 221, 221, 222, 223, + 225, 225, 226, 227, 229, 229, 230, 231, 233, 233, 234, 235, 237, 237, 238, 239, + 241, 241, 242, 243, 245, 245, 246, 247, 249, 249, 250, 251, 253, 253, 254, 255 + }, + { + 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, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + } +}; + +// Starts from QUANT_6 +// Scrambled +const uint8_t color_uquant_to_scrambled_pquant_tables[17][256] { + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, + 5, 5, 5, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }, + { + 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, 1, 1, 1, 1, 1, 1, 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, 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, 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, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 + }, + { + 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, 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, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 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, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 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, 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, 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, 6, 6, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15 + }, + { + 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1 + }, + { + 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1, 1, 1 + }, + { + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, + 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, + 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, + 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, + 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, + 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, + 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, + 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31 + }, + { + 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, + 16, 24, 24, 24, 24, 24, 24, 32, 32, 32, 32, 32, 32, 32, 2, 2, + 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 18, 18, 18, 18, 18, + 18, 26, 26, 26, 26, 26, 26, 26, 34, 34, 34, 34, 34, 34, 4, 4, + 4, 4, 4, 4, 4, 12, 12, 12, 12, 12, 12, 20, 20, 20, 20, 20, + 20, 20, 28, 28, 28, 28, 28, 28, 36, 36, 36, 36, 36, 36, 36, 6, + 6, 6, 6, 6, 6, 14, 14, 14, 14, 14, 14, 14, 22, 22, 22, 22, + 22, 22, 30, 30, 30, 30, 30, 30, 30, 38, 38, 38, 38, 38, 38, 38, + 39, 39, 39, 39, 39, 39, 39, 31, 31, 31, 31, 31, 31, 31, 23, 23, + 23, 23, 23, 23, 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, + 7, 37, 37, 37, 37, 37, 37, 37, 29, 29, 29, 29, 29, 29, 21, 21, + 21, 21, 21, 21, 21, 13, 13, 13, 13, 13, 13, 5, 5, 5, 5, 5, + 5, 5, 35, 35, 35, 35, 35, 35, 27, 27, 27, 27, 27, 27, 27, 19, + 19, 19, 19, 19, 19, 11, 11, 11, 11, 11, 11, 11, 3, 3, 3, 3, + 3, 3, 33, 33, 33, 33, 33, 33, 33, 25, 25, 25, 25, 25, 25, 17, + 17, 17, 17, 17, 17, 17, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1 + }, + { + 0, 0, 0, 16, 16, 16, 16, 16, 16, 32, 32, 32, 32, 32, 2, 2, + 2, 2, 2, 18, 18, 18, 18, 18, 18, 34, 34, 34, 34, 34, 4, 4, + 4, 4, 4, 4, 20, 20, 20, 20, 20, 36, 36, 36, 36, 36, 6, 6, + 6, 6, 6, 6, 22, 22, 22, 22, 22, 38, 38, 38, 38, 38, 38, 8, + 8, 8, 8, 8, 24, 24, 24, 24, 24, 24, 40, 40, 40, 40, 40, 10, + 10, 10, 10, 10, 26, 26, 26, 26, 26, 26, 42, 42, 42, 42, 42, 12, + 12, 12, 12, 12, 12, 28, 28, 28, 28, 28, 44, 44, 44, 44, 44, 14, + 14, 14, 14, 14, 14, 30, 30, 30, 30, 30, 46, 46, 46, 46, 46, 46, + 47, 47, 47, 47, 47, 47, 31, 31, 31, 31, 31, 15, 15, 15, 15, 15, + 15, 45, 45, 45, 45, 45, 29, 29, 29, 29, 29, 13, 13, 13, 13, 13, + 13, 43, 43, 43, 43, 43, 27, 27, 27, 27, 27, 27, 11, 11, 11, 11, + 11, 41, 41, 41, 41, 41, 25, 25, 25, 25, 25, 25, 9, 9, 9, 9, + 9, 39, 39, 39, 39, 39, 39, 23, 23, 23, 23, 23, 7, 7, 7, 7, + 7, 7, 37, 37, 37, 37, 37, 21, 21, 21, 21, 21, 5, 5, 5, 5, + 5, 5, 35, 35, 35, 35, 35, 19, 19, 19, 19, 19, 19, 3, 3, 3, + 3, 3, 33, 33, 33, 33, 33, 17, 17, 17, 17, 17, 17, 1, 1, 1 + }, + { + 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, 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, + 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 + }, + { + 0, 0, 16, 16, 16, 32, 32, 32, 48, 48, 48, 48, 64, 64, 64, 2, + 2, 2, 18, 18, 18, 34, 34, 34, 50, 50, 50, 50, 66, 66, 66, 4, + 4, 4, 20, 20, 20, 36, 36, 36, 36, 52, 52, 52, 68, 68, 68, 6, + 6, 6, 22, 22, 22, 38, 38, 38, 38, 54, 54, 54, 70, 70, 70, 8, + 8, 8, 24, 24, 24, 24, 40, 40, 40, 56, 56, 56, 72, 72, 72, 10, + 10, 10, 26, 26, 26, 26, 42, 42, 42, 58, 58, 58, 74, 74, 74, 12, + 12, 12, 12, 28, 28, 28, 44, 44, 44, 60, 60, 60, 76, 76, 76, 14, + 14, 14, 14, 30, 30, 30, 46, 46, 46, 62, 62, 62, 78, 78, 78, 78, + 79, 79, 79, 79, 63, 63, 63, 47, 47, 47, 31, 31, 31, 15, 15, 15, + 15, 77, 77, 77, 61, 61, 61, 45, 45, 45, 29, 29, 29, 13, 13, 13, + 13, 75, 75, 75, 59, 59, 59, 43, 43, 43, 27, 27, 27, 27, 11, 11, + 11, 73, 73, 73, 57, 57, 57, 41, 41, 41, 25, 25, 25, 25, 9, 9, + 9, 71, 71, 71, 55, 55, 55, 39, 39, 39, 39, 23, 23, 23, 7, 7, + 7, 69, 69, 69, 53, 53, 53, 37, 37, 37, 37, 21, 21, 21, 5, 5, + 5, 67, 67, 67, 51, 51, 51, 51, 35, 35, 35, 19, 19, 19, 3, 3, + 3, 65, 65, 65, 49, 49, 49, 49, 33, 33, 33, 17, 17, 17, 1, 1 + }, + { + 0, 0, 32, 32, 64, 64, 64, 2, 2, 2, 34, 34, 66, 66, 66, 4, + 4, 4, 36, 36, 68, 68, 68, 6, 6, 6, 38, 38, 70, 70, 70, 8, + 8, 8, 40, 40, 40, 72, 72, 10, 10, 10, 42, 42, 42, 74, 74, 12, + 12, 12, 44, 44, 44, 76, 76, 14, 14, 14, 46, 46, 46, 78, 78, 16, + 16, 16, 48, 48, 48, 80, 80, 80, 18, 18, 50, 50, 50, 82, 82, 82, + 20, 20, 52, 52, 52, 84, 84, 84, 22, 22, 54, 54, 54, 86, 86, 86, + 24, 24, 56, 56, 56, 88, 88, 88, 26, 26, 58, 58, 58, 90, 90, 90, + 28, 28, 60, 60, 60, 92, 92, 92, 30, 30, 62, 62, 62, 94, 94, 94, + 95, 95, 95, 63, 63, 63, 31, 31, 93, 93, 93, 61, 61, 61, 29, 29, + 91, 91, 91, 59, 59, 59, 27, 27, 89, 89, 89, 57, 57, 57, 25, 25, + 87, 87, 87, 55, 55, 55, 23, 23, 85, 85, 85, 53, 53, 53, 21, 21, + 83, 83, 83, 51, 51, 51, 19, 19, 81, 81, 81, 49, 49, 49, 17, 17, + 17, 79, 79, 47, 47, 47, 15, 15, 15, 77, 77, 45, 45, 45, 13, 13, + 13, 75, 75, 43, 43, 43, 11, 11, 11, 73, 73, 41, 41, 41, 9, 9, + 9, 71, 71, 71, 39, 39, 7, 7, 7, 69, 69, 69, 37, 37, 5, 5, + 5, 67, 67, 67, 35, 35, 3, 3, 3, 65, 65, 65, 33, 33, 1, 1 + }, + { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, + 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, + 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, + 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, + 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, + 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, + 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63, + 64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, + 72, 72, 73, 73, 74, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, + 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87, + 88, 88, 89, 89, 90, 90, 91, 91, 92, 92, 93, 93, 94, 94, 95, 95, + 96, 96, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102, 103, 103, + 104, 104, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, + 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, + 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 127, 127 + }, + { + 0, 32, 32, 64, 96, 96, 128, 128, 2, 34, 34, 66, 98, 98, 130, 130, + 4, 36, 36, 68, 100, 100, 132, 132, 6, 38, 38, 70, 102, 102, 134, 134, + 8, 40, 40, 72, 104, 104, 136, 136, 10, 42, 42, 74, 106, 106, 138, 138, + 12, 44, 44, 76, 108, 108, 140, 140, 14, 46, 46, 78, 110, 110, 142, 142, + 16, 48, 48, 80, 112, 112, 144, 144, 18, 50, 50, 82, 114, 114, 146, 146, + 20, 52, 52, 84, 116, 116, 148, 148, 22, 54, 54, 86, 118, 118, 150, 150, + 24, 56, 56, 88, 120, 120, 152, 152, 26, 58, 58, 90, 122, 122, 154, 154, + 28, 60, 60, 92, 124, 124, 156, 156, 30, 62, 62, 94, 126, 126, 158, 158, + 159, 159, 127, 127, 95, 63, 63, 31, 157, 157, 125, 125, 93, 61, 61, 29, + 155, 155, 123, 123, 91, 59, 59, 27, 153, 153, 121, 121, 89, 57, 57, 25, + 151, 151, 119, 119, 87, 55, 55, 23, 149, 149, 117, 117, 85, 53, 53, 21, + 147, 147, 115, 115, 83, 51, 51, 19, 145, 145, 113, 113, 81, 49, 49, 17, + 143, 143, 111, 111, 79, 47, 47, 15, 141, 141, 109, 109, 77, 45, 45, 13, + 139, 139, 107, 107, 75, 43, 43, 11, 137, 137, 105, 105, 73, 41, 41, 9, + 135, 135, 103, 103, 71, 39, 39, 7, 133, 133, 101, 101, 69, 37, 37, 5, + 131, 131, 99, 99, 67, 35, 35, 3, 129, 129, 97, 97, 65, 33, 33, 1 + }, + { + 0, 64, 128, 128, 2, 66, 130, 130, 4, 68, 132, 132, 6, 70, 134, 134, + 8, 72, 136, 136, 10, 74, 138, 138, 12, 76, 140, 140, 14, 78, 142, 142, + 16, 80, 144, 144, 18, 82, 146, 146, 20, 84, 148, 148, 22, 86, 150, 150, + 24, 88, 152, 152, 26, 90, 154, 154, 28, 92, 156, 156, 30, 94, 158, 158, + 32, 96, 160, 160, 34, 98, 162, 162, 36, 100, 164, 164, 38, 102, 166, 166, + 40, 104, 168, 168, 42, 106, 170, 170, 44, 108, 172, 172, 46, 110, 174, 174, + 48, 112, 176, 176, 50, 114, 178, 178, 52, 116, 180, 180, 54, 118, 182, 182, + 56, 120, 184, 184, 58, 122, 186, 186, 60, 124, 188, 188, 62, 126, 190, 190, + 191, 191, 127, 63, 189, 189, 125, 61, 187, 187, 123, 59, 185, 185, 121, 57, + 183, 183, 119, 55, 181, 181, 117, 53, 179, 179, 115, 51, 177, 177, 113, 49, + 175, 175, 111, 47, 173, 173, 109, 45, 171, 171, 107, 43, 169, 169, 105, 41, + 167, 167, 103, 39, 165, 165, 101, 37, 163, 163, 99, 35, 161, 161, 97, 33, + 159, 159, 95, 31, 157, 157, 93, 29, 155, 155, 91, 27, 153, 153, 89, 25, + 151, 151, 87, 23, 149, 149, 85, 21, 147, 147, 83, 19, 145, 145, 81, 17, + 143, 143, 79, 15, 141, 141, 77, 13, 139, 139, 75, 11, 137, 137, 73, 9, + 135, 135, 71, 7, 133, 133, 69, 5, 131, 131, 67, 3, 129, 129, 65, 1 + }, + { + 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, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + } +}; + +#endif + +// Starts from QUANT_6 +// Scrambled +static const uint8_t color_scrambled_pquant_to_uquant_q6[6] { + 0, 255, 51, 204, 102, 153 +}; + +static const uint8_t color_scrambled_pquant_to_uquant_q8[8] { + 0, 36, 73, 109, 146, 182, 219, 255 +}; + +static const uint8_t color_scrambled_pquant_to_uquant_q10[10] { + 0, 255, 28, 227, 56, 199, 84, 171, 113, 142 +}; + +static const uint8_t color_scrambled_pquant_to_uquant_q12[12] { + 0, 255, 69, 186, 23, 232, 92, 163, 46, 209, 116, 139 +}; + +static const uint8_t color_scrambled_pquant_to_uquant_q16[16] { + 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255 +}; + +static const uint8_t color_scrambled_pquant_to_uquant_q20[20] { + 0, 255, 67, 188, 13, 242, 80, 175, 27, 228, 94, 161, 40, 215, 107, 148, + 54, 201, 121, 134 +}; + +static const uint8_t color_scrambled_pquant_to_uquant_q24[24] { + 0, 255, 33, 222, 66, 189, 99, 156, 11, 244, 44, 211, 77, 178, 110, 145, + 22, 233, 55, 200, 88, 167, 121, 134 +}; + +static const uint8_t color_scrambled_pquant_to_uquant_q32[32] { + 0, 8, 16, 24, 33, 41, 49, 57, 66, 74, 82, 90, 99, 107, 115, 123, + 132, 140, 148, 156, 165, 173, 181, 189, 198, 206, 214, 222, 231, 239, 247, 255 +}; + +static const uint8_t color_scrambled_pquant_to_uquant_q40[40] { + 0, 255, 32, 223, 65, 190, 97, 158, 6, 249, 39, 216, 71, 184, 104, 151, + 13, 242, 45, 210, 78, 177, 110, 145, 19, 236, 52, 203, 84, 171, 117, 138, + 26, 229, 58, 197, 91, 164, 123, 132 +}; + +static const uint8_t color_scrambled_pquant_to_uquant_q48[48] { + 0, 255, 16, 239, 32, 223, 48, 207, 65, 190, 81, 174, 97, 158, 113, 142, + 5, 250, 21, 234, 38, 217, 54, 201, 70, 185, 86, 169, 103, 152, 119, 136, + 11, 244, 27, 228, 43, 212, 59, 196, 76, 179, 92, 163, 108, 147, 124, 131 +}; + +static const uint8_t color_scrambled_pquant_to_uquant_q64[64] { + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, + 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, + 130, 134, 138, 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190, + 195, 199, 203, 207, 211, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255, +}; + +static const uint8_t color_scrambled_pquant_to_uquant_q80[80] { + 0, 255, 16, 239, 32, 223, 48, 207, 64, 191, 80, 175, 96, 159, 112, 143, + 3, 252, 19, 236, 35, 220, 51, 204, 67, 188, 83, 172, 100, 155, 116, 139, + 6, 249, 22, 233, 38, 217, 54, 201, 71, 184, 87, 168, 103, 152, 119, 136, + 9, 246, 25, 230, 42, 213, 58, 197, 74, 181, 90, 165, 106, 149, 122, 133, + 13, 242, 29, 226, 45, 210, 61, 194, 77, 178, 93, 162, 109, 146, 125, 130 +}; + +static const uint8_t color_scrambled_pquant_to_uquant_q96[96] { + 0, 255, 8, 247, 16, 239, 24, 231, 32, 223, 40, 215, 48, 207, 56, 199, + 64, 191, 72, 183, 80, 175, 88, 167, 96, 159, 104, 151, 112, 143, 120, 135, + 2, 253, 10, 245, 18, 237, 26, 229, 35, 220, 43, 212, 51, 204, 59, 196, + 67, 188, 75, 180, 83, 172, 91, 164, 99, 156, 107, 148, 115, 140, 123, 132, + 5, 250, 13, 242, 21, 234, 29, 226, 37, 218, 45, 210, 53, 202, 61, 194, + 70, 185, 78, 177, 86, 169, 94, 161, 102, 153, 110, 145, 118, 137, 126, 129 +}; + +static const uint8_t color_scrambled_pquant_to_uquant_q128[128] { + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, + 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, + 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, + 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157, 159, + 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, + 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, + 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255 +}; + +static const uint8_t color_scrambled_pquant_to_uquant_q160[160] { + 0, 255, 8, 247, 16, 239, 24, 231, 32, 223, 40, 215, 48, 207, 56, 199, + 64, 191, 72, 183, 80, 175, 88, 167, 96, 159, 104, 151, 112, 143, 120, 135, + 1, 254, 9, 246, 17, 238, 25, 230, 33, 222, 41, 214, 49, 206, 57, 198, + 65, 190, 73, 182, 81, 174, 89, 166, 97, 158, 105, 150, 113, 142, 121, 134, + 3, 252, 11, 244, 19, 236, 27, 228, 35, 220, 43, 212, 51, 204, 59, 196, + 67, 188, 75, 180, 83, 172, 91, 164, 99, 156, 107, 148, 115, 140, 123, 132, + 4, 251, 12, 243, 20, 235, 28, 227, 36, 219, 44, 211, 52, 203, 60, 195, + 68, 187, 76, 179, 84, 171, 92, 163, 100, 155, 108, 147, 116, 139, 124, 131, + 6, 249, 14, 241, 22, 233, 30, 225, 38, 217, 46, 209, 54, 201, 62, 193, + 70, 185, 78, 177, 86, 169, 94, 161, 102, 153, 110, 145, 118, 137, 126, 129 +}; + +static const uint8_t color_scrambled_pquant_to_uquant_q192[192] { + 0, 255, 4, 251, 8, 247, 12, 243, 16, 239, 20, 235, 24, 231, 28, 227, + 32, 223, 36, 219, 40, 215, 44, 211, 48, 207, 52, 203, 56, 199, 60, 195, + 64, 191, 68, 187, 72, 183, 76, 179, 80, 175, 84, 171, 88, 167, 92, 163, + 96, 159, 100, 155, 104, 151, 108, 147, 112, 143, 116, 139, 120, 135, 124, 131, + 1, 254, 5, 250, 9, 246, 13, 242, 17, 238, 21, 234, 25, 230, 29, 226, + 33, 222, 37, 218, 41, 214, 45, 210, 49, 206, 53, 202, 57, 198, 61, 194, + 65, 190, 69, 186, 73, 182, 77, 178, 81, 174, 85, 170, 89, 166, 93, 162, + 97, 158, 101, 154, 105, 150, 109, 146, 113, 142, 117, 138, 121, 134, 125, 130, + 2, 253, 6, 249, 10, 245, 14, 241, 18, 237, 22, 233, 26, 229, 30, 225, + 34, 221, 38, 217, 42, 213, 46, 209, 50, 205, 54, 201, 58, 197, 62, 193, + 66, 189, 70, 185, 74, 181, 78, 177, 82, 173, 86, 169, 90, 165, 94, 161, + 98, 157, 102, 153, 106, 149, 110, 145, 114, 141, 118, 137, 122, 133, 126, 129 +}; + +static const uint8_t color_scrambled_pquant_to_uquant_q256[256] { + 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, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 +}; + +const uint8_t* color_scrambled_pquant_to_uquant_tables[17] { + color_scrambled_pquant_to_uquant_q6, + color_scrambled_pquant_to_uquant_q8, + color_scrambled_pquant_to_uquant_q10, + color_scrambled_pquant_to_uquant_q12, + color_scrambled_pquant_to_uquant_q16, + color_scrambled_pquant_to_uquant_q20, + color_scrambled_pquant_to_uquant_q24, + color_scrambled_pquant_to_uquant_q32, + color_scrambled_pquant_to_uquant_q40, + color_scrambled_pquant_to_uquant_q48, + color_scrambled_pquant_to_uquant_q64, + color_scrambled_pquant_to_uquant_q80, + color_scrambled_pquant_to_uquant_q96, + color_scrambled_pquant_to_uquant_q128, + color_scrambled_pquant_to_uquant_q160, + color_scrambled_pquant_to_uquant_q192, + color_scrambled_pquant_to_uquant_q256 +}; + +// The quant_mode_table[integer_count/2][bits] gives us the quantization level for a given integer +// count and number of bits that the integer may fit into. +const int8_t quant_mode_table[10][128] { + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }, + { + -1, -1, 0, 0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 15, 17, 18, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 + }, + { + -1, -1, -1, -1, 0, 0, 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 + }, + { + -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, + 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 + }, + { + -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, + 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, + 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, + 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 19, 19, 19, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 + }, + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, + 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 10, 10, + 10, 10, 11, 11, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, + 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 19, 19, 19, 19, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 + }, + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, + 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, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 + }, + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, + 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, + 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, + 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, + 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, + 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 19, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 + }, + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, + 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, + 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19 + }, + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, + 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, + 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, + 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, + 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, + 14, 14, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 17, 17 + } +}; diff --git a/thirdparty/astcenc/astcenc_symbolic_physical.cpp b/thirdparty/astcenc/astcenc_symbolic_physical.cpp new file mode 100644 index 0000000000..80221a6013 --- /dev/null +++ b/thirdparty/astcenc/astcenc_symbolic_physical.cpp @@ -0,0 +1,534 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2021 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief Functions for converting between symbolic and physical encodings. + */ + +#include "astcenc_internal.h" + +#include <cassert> + +/** + * @brief Write up to 8 bits at an arbitrary bit offset. + * + * The stored value is at most 8 bits, but can be stored at an offset of between 0 and 7 bits so + * may span two separate bytes in memory. + * + * @param value The value to write. + * @param bitcount The number of bits to write, starting from LSB. + * @param bitoffset The bit offset to store at, between 0 and 7. + * @param[in,out] ptr The data pointer to write to. + */ +static inline void write_bits( + int value, + int bitcount, + int bitoffset, + uint8_t* ptr +) { + int mask = (1 << bitcount) - 1; + value &= mask; + ptr += bitoffset >> 3; + bitoffset &= 7; + value <<= bitoffset; + mask <<= bitoffset; + mask = ~mask; + + ptr[0] &= mask; + ptr[0] |= value; + ptr[1] &= mask >> 8; + ptr[1] |= value >> 8; +} + +/** + * @brief Read up to 8 bits at an arbitrary bit offset. + * + * The stored value is at most 8 bits, but can be stored at an offset of between 0 and 7 bits so may + * span two separate bytes in memory. + * + * @param bitcount The number of bits to read. + * @param bitoffset The bit offset to read from, between 0 and 7. + * @param[in,out] ptr The data pointer to read from. + * + * @return The read value. + */ +static inline int read_bits( + int bitcount, + int bitoffset, + const uint8_t* ptr +) { + int mask = (1 << bitcount) - 1; + ptr += bitoffset >> 3; + bitoffset &= 7; + int value = ptr[0] | (ptr[1] << 8); + value >>= bitoffset; + value &= mask; + return value; +} + +/** + * @brief Reverse bits in a byte. + * + * @param p The value to reverse. + * + * @return The reversed result. + */ +static inline int bitrev8(int p) +{ + p = ((p & 0x0F) << 4) | ((p >> 4) & 0x0F); + p = ((p & 0x33) << 2) | ((p >> 2) & 0x33); + p = ((p & 0x55) << 1) | ((p >> 1) & 0x55); + return p; +} + +/* See header for documentation. */ +void symbolic_to_physical( + const block_size_descriptor& bsd, + const symbolic_compressed_block& scb, + physical_compressed_block& pcb +) { + assert(scb.block_type != SYM_BTYPE_ERROR); + + // Constant color block using UNORM16 colors + if (scb.block_type == SYM_BTYPE_CONST_U16) + { + // There is currently no attempt to coalesce larger void-extents + static const uint8_t cbytes[8] { 0xFC, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + for (unsigned int i = 0; i < 8; i++) + { + pcb.data[i] = cbytes[i]; + } + + for (unsigned int i = 0; i < BLOCK_MAX_COMPONENTS; i++) + { + pcb.data[2 * i + 8] = scb.constant_color[i] & 0xFF; + pcb.data[2 * i + 9] = (scb.constant_color[i] >> 8) & 0xFF; + } + + return; + } + + // Constant color block using FP16 colors + if (scb.block_type == SYM_BTYPE_CONST_F16) + { + // There is currently no attempt to coalesce larger void-extents + static const uint8_t cbytes[8] { 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + for (unsigned int i = 0; i < 8; i++) + { + pcb.data[i] = cbytes[i]; + } + + for (unsigned int i = 0; i < BLOCK_MAX_COMPONENTS; i++) + { + pcb.data[2 * i + 8] = scb.constant_color[i] & 0xFF; + pcb.data[2 * i + 9] = (scb.constant_color[i] >> 8) & 0xFF; + } + + return; + } + + unsigned int partition_count = scb.partition_count; + + // Compress the weights. + // They are encoded as an ordinary integer-sequence, then bit-reversed + uint8_t weightbuf[16] { 0 }; + + const auto& bm = bsd.get_block_mode(scb.block_mode); + const auto& di = bsd.get_decimation_info(bm.decimation_mode); + int weight_count = di.weight_count; + quant_method weight_quant_method = bm.get_weight_quant_mode(); + float weight_quant_levels = static_cast<float>(get_quant_level(weight_quant_method)); + int is_dual_plane = bm.is_dual_plane; + + const auto& qat = quant_and_xfer_tables[weight_quant_method]; + + int real_weight_count = is_dual_plane ? 2 * weight_count : weight_count; + + int bits_for_weights = get_ise_sequence_bitcount(real_weight_count, weight_quant_method); + + uint8_t weights[64]; + if (is_dual_plane) + { + for (int i = 0; i < weight_count; i++) + { + float uqw = static_cast<float>(scb.weights[i]); + float qw = (uqw / 64.0f) * (weight_quant_levels - 1.0f); + int qwi = static_cast<int>(qw + 0.5f); + weights[2 * i] = qat.scramble_map[qwi]; + + uqw = static_cast<float>(scb.weights[i + WEIGHTS_PLANE2_OFFSET]); + qw = (uqw / 64.0f) * (weight_quant_levels - 1.0f); + qwi = static_cast<int>(qw + 0.5f); + weights[2 * i + 1] = qat.scramble_map[qwi]; + } + } + else + { + for (int i = 0; i < weight_count; i++) + { + float uqw = static_cast<float>(scb.weights[i]); + float qw = (uqw / 64.0f) * (weight_quant_levels - 1.0f); + int qwi = static_cast<int>(qw + 0.5f); + weights[i] = qat.scramble_map[qwi]; + } + } + + encode_ise(weight_quant_method, real_weight_count, weights, weightbuf, 0); + + for (int i = 0; i < 16; i++) + { + pcb.data[i] = static_cast<uint8_t>(bitrev8(weightbuf[15 - i])); + } + + write_bits(scb.block_mode, 11, 0, pcb.data); + write_bits(partition_count - 1, 2, 11, pcb.data); + + int below_weights_pos = 128 - bits_for_weights; + + // Encode partition index and color endpoint types for blocks with 2+ partitions + if (partition_count > 1) + { + write_bits(scb.partition_index, 6, 13, pcb.data); + write_bits(scb.partition_index >> 6, PARTITION_INDEX_BITS - 6, 19, pcb.data); + + if (scb.color_formats_matched) + { + write_bits(scb.color_formats[0] << 2, 6, 13 + PARTITION_INDEX_BITS, pcb.data); + } + else + { + // Check endpoint types for each partition to determine the lowest class present + int low_class = 4; + + for (unsigned int i = 0; i < partition_count; i++) + { + int class_of_format = scb.color_formats[i] >> 2; + low_class = astc::min(class_of_format, low_class); + } + + if (low_class == 3) + { + low_class = 2; + } + + int encoded_type = low_class + 1; + int bitpos = 2; + + for (unsigned int i = 0; i < partition_count; i++) + { + int classbit_of_format = (scb.color_formats[i] >> 2) - low_class; + encoded_type |= classbit_of_format << bitpos; + bitpos++; + } + + for (unsigned int i = 0; i < partition_count; i++) + { + int lowbits_of_format = scb.color_formats[i] & 3; + encoded_type |= lowbits_of_format << bitpos; + bitpos += 2; + } + + int encoded_type_lowpart = encoded_type & 0x3F; + int encoded_type_highpart = encoded_type >> 6; + int encoded_type_highpart_size = (3 * partition_count) - 4; + int encoded_type_highpart_pos = 128 - bits_for_weights - encoded_type_highpart_size; + write_bits(encoded_type_lowpart, 6, 13 + PARTITION_INDEX_BITS, pcb.data); + write_bits(encoded_type_highpart, encoded_type_highpart_size, encoded_type_highpart_pos, pcb.data); + below_weights_pos -= encoded_type_highpart_size; + } + } + else + { + write_bits(scb.color_formats[0], 4, 13, pcb.data); + } + + // In dual-plane mode, encode the color component of the second plane of weights + if (is_dual_plane) + { + write_bits(scb.plane2_component, 2, below_weights_pos - 2, pcb.data); + } + + // Encode the color components + uint8_t values_to_encode[32]; + int valuecount_to_encode = 0; + + const uint8_t* pack_table = color_uquant_to_scrambled_pquant_tables[scb.quant_mode - QUANT_6]; + for (unsigned int i = 0; i < scb.partition_count; i++) + { + int vals = 2 * (scb.color_formats[i] >> 2) + 2; + assert(vals <= 8); + for (int j = 0; j < vals; j++) + { + values_to_encode[j + valuecount_to_encode] = pack_table[scb.color_values[i][j]]; + } + valuecount_to_encode += vals; + } + + encode_ise(scb.get_color_quant_mode(), valuecount_to_encode, values_to_encode, pcb.data, + scb.partition_count == 1 ? 17 : 19 + PARTITION_INDEX_BITS); +} + +/* See header for documentation. */ +void physical_to_symbolic( + const block_size_descriptor& bsd, + const physical_compressed_block& pcb, + symbolic_compressed_block& scb +) { + uint8_t bswapped[16]; + + scb.block_type = SYM_BTYPE_NONCONST; + + // Extract header fields + int block_mode = read_bits(11, 0, pcb.data); + if ((block_mode & 0x1FF) == 0x1FC) + { + // Constant color block + + // Check what format the data has + if (block_mode & 0x200) + { + scb.block_type = SYM_BTYPE_CONST_F16; + } + else + { + scb.block_type = SYM_BTYPE_CONST_U16; + } + + scb.partition_count = 0; + for (int i = 0; i < 4; i++) + { + scb.constant_color[i] = pcb.data[2 * i + 8] | (pcb.data[2 * i + 9] << 8); + } + + // Additionally, check that the void-extent + if (bsd.zdim == 1) + { + // 2D void-extent + int rsvbits = read_bits(2, 10, pcb.data); + if (rsvbits != 3) + { + scb.block_type = SYM_BTYPE_ERROR; + return; + } + + int vx_low_s = read_bits(8, 12, pcb.data) | (read_bits(5, 12 + 8, pcb.data) << 8); + int vx_high_s = read_bits(8, 25, pcb.data) | (read_bits(5, 25 + 8, pcb.data) << 8); + int vx_low_t = read_bits(8, 38, pcb.data) | (read_bits(5, 38 + 8, pcb.data) << 8); + int vx_high_t = read_bits(8, 51, pcb.data) | (read_bits(5, 51 + 8, pcb.data) << 8); + + int all_ones = vx_low_s == 0x1FFF && vx_high_s == 0x1FFF && vx_low_t == 0x1FFF && vx_high_t == 0x1FFF; + + if ((vx_low_s >= vx_high_s || vx_low_t >= vx_high_t) && !all_ones) + { + scb.block_type = SYM_BTYPE_ERROR; + return; + } + } + else + { + // 3D void-extent + int vx_low_s = read_bits(9, 10, pcb.data); + int vx_high_s = read_bits(9, 19, pcb.data); + int vx_low_t = read_bits(9, 28, pcb.data); + int vx_high_t = read_bits(9, 37, pcb.data); + int vx_low_p = read_bits(9, 46, pcb.data); + int vx_high_p = read_bits(9, 55, pcb.data); + + int all_ones = vx_low_s == 0x1FF && vx_high_s == 0x1FF && vx_low_t == 0x1FF && vx_high_t == 0x1FF && vx_low_p == 0x1FF && vx_high_p == 0x1FF; + + if ((vx_low_s >= vx_high_s || vx_low_t >= vx_high_t || vx_low_p >= vx_high_p) && !all_ones) + { + scb.block_type = SYM_BTYPE_ERROR; + return; + } + } + + return; + } + + unsigned int packed_index = bsd.block_mode_packed_index[block_mode]; + if (packed_index == BLOCK_BAD_BLOCK_MODE) + { + scb.block_type = SYM_BTYPE_ERROR; + return; + } + + const auto& bm = bsd.get_block_mode(block_mode); + const auto& di = bsd.get_decimation_info(bm.decimation_mode); + + int weight_count = di.weight_count; + promise(weight_count > 0); + + quant_method weight_quant_method = static_cast<quant_method>(bm.quant_mode); + int is_dual_plane = bm.is_dual_plane; + + int real_weight_count = is_dual_plane ? 2 * weight_count : weight_count; + + int partition_count = read_bits(2, 11, pcb.data) + 1; + promise(partition_count > 0); + + scb.block_mode = static_cast<uint16_t>(block_mode); + scb.partition_count = static_cast<uint8_t>(partition_count); + + for (int i = 0; i < 16; i++) + { + bswapped[i] = static_cast<uint8_t>(bitrev8(pcb.data[15 - i])); + } + + int bits_for_weights = get_ise_sequence_bitcount(real_weight_count, weight_quant_method); + + int below_weights_pos = 128 - bits_for_weights; + + uint8_t indices[64]; + const auto& qat = quant_and_xfer_tables[weight_quant_method]; + + decode_ise(weight_quant_method, real_weight_count, bswapped, indices, 0); + + if (is_dual_plane) + { + for (int i = 0; i < weight_count; i++) + { + scb.weights[i] = qat.unscramble_and_unquant_map[indices[2 * i]]; + scb.weights[i + WEIGHTS_PLANE2_OFFSET] = qat.unscramble_and_unquant_map[indices[2 * i + 1]]; + } + } + else + { + for (int i = 0; i < weight_count; i++) + { + scb.weights[i] = qat.unscramble_and_unquant_map[indices[i]]; + } + } + + if (is_dual_plane && partition_count == 4) + { + scb.block_type = SYM_BTYPE_ERROR; + return; + } + + scb.color_formats_matched = 0; + + // Determine the format of each endpoint pair + int color_formats[BLOCK_MAX_PARTITIONS]; + int encoded_type_highpart_size = 0; + if (partition_count == 1) + { + color_formats[0] = read_bits(4, 13, pcb.data); + scb.partition_index = 0; + } + else + { + encoded_type_highpart_size = (3 * partition_count) - 4; + below_weights_pos -= encoded_type_highpart_size; + int encoded_type = read_bits(6, 13 + PARTITION_INDEX_BITS, pcb.data) | (read_bits(encoded_type_highpart_size, below_weights_pos, pcb.data) << 6); + int baseclass = encoded_type & 0x3; + if (baseclass == 0) + { + for (int i = 0; i < partition_count; i++) + { + color_formats[i] = (encoded_type >> 2) & 0xF; + } + + below_weights_pos += encoded_type_highpart_size; + scb.color_formats_matched = 1; + encoded_type_highpart_size = 0; + } + else + { + int bitpos = 2; + baseclass--; + + for (int i = 0; i < partition_count; i++) + { + color_formats[i] = (((encoded_type >> bitpos) & 1) + baseclass) << 2; + bitpos++; + } + + for (int i = 0; i < partition_count; i++) + { + color_formats[i] |= (encoded_type >> bitpos) & 3; + bitpos += 2; + } + } + scb.partition_index = static_cast<uint16_t>(read_bits(6, 13, pcb.data) | (read_bits(PARTITION_INDEX_BITS - 6, 19, pcb.data) << 6)); + } + + for (int i = 0; i < partition_count; i++) + { + scb.color_formats[i] = static_cast<uint8_t>(color_formats[i]); + } + + // Determine number of color endpoint integers + int color_integer_count = 0; + for (int i = 0; i < partition_count; i++) + { + int endpoint_class = color_formats[i] >> 2; + color_integer_count += (endpoint_class + 1) * 2; + } + + if (color_integer_count > 18) + { + scb.block_type = SYM_BTYPE_ERROR; + return; + } + + // Determine the color endpoint format to use + static const int color_bits_arr[5] { -1, 115 - 4, 113 - 4 - PARTITION_INDEX_BITS, 113 - 4 - PARTITION_INDEX_BITS, 113 - 4 - PARTITION_INDEX_BITS }; + int color_bits = color_bits_arr[partition_count] - bits_for_weights - encoded_type_highpart_size; + if (is_dual_plane) + { + color_bits -= 2; + } + + if (color_bits < 0) + { + color_bits = 0; + } + + int color_quant_level = quant_mode_table[color_integer_count >> 1][color_bits]; + if (color_quant_level < QUANT_6) + { + scb.block_type = SYM_BTYPE_ERROR; + return; + } + + // Unpack the integer color values and assign to endpoints + scb.quant_mode = static_cast<quant_method>(color_quant_level); + + uint8_t values_to_decode[32]; + decode_ise(static_cast<quant_method>(color_quant_level), color_integer_count, pcb.data, + values_to_decode, (partition_count == 1 ? 17 : 19 + PARTITION_INDEX_BITS)); + + int valuecount_to_decode = 0; + const uint8_t* unpack_table = color_scrambled_pquant_to_uquant_tables[scb.quant_mode - QUANT_6]; + for (int i = 0; i < partition_count; i++) + { + int vals = 2 * (color_formats[i] >> 2) + 2; + for (int j = 0; j < vals; j++) + { + scb.color_values[i][j] = unpack_table[values_to_decode[j + valuecount_to_decode]]; + } + valuecount_to_decode += vals; + } + + // Fetch component for second-plane in the case of dual plane of weights. + scb.plane2_component = -1; + if (is_dual_plane) + { + scb.plane2_component = static_cast<int8_t>(read_bits(2, below_weights_pos - 2, pcb.data)); + } +} diff --git a/thirdparty/astcenc/astcenc_vecmathlib.h b/thirdparty/astcenc/astcenc_vecmathlib.h new file mode 100644 index 0000000000..d48f1d73ea --- /dev/null +++ b/thirdparty/astcenc/astcenc_vecmathlib.h @@ -0,0 +1,570 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2019-2022 Arm Limited +// Copyright 2008 Jose Fonseca +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/* + * This module implements vector support for floats, ints, and vector lane + * control masks. It provides access to both explicit vector width types, and + * flexible N-wide types where N can be determined at compile time. + * + * The design of this module encourages use of vector length agnostic code, via + * the vint, vfloat, and vmask types. These will take on the widest SIMD vector + * with that is available at compile time. The current vector width is + * accessible for e.g. loop strides via the ASTCENC_SIMD_WIDTH constant. + * + * Explicit scalar types are accessible via the vint1, vfloat1, vmask1 types. + * These are provided primarily for prototyping and algorithm debug of VLA + * implementations. + * + * Explicit 4-wide types are accessible via the vint4, vfloat4, and vmask4 + * types. These are provided for use by VLA code, but are also expected to be + * used as a fixed-width type and will supported a reference C++ fallback for + * use on platforms without SIMD intrinsics. + * + * Explicit 8-wide types are accessible via the vint8, vfloat8, and vmask8 + * types. These are provide for use by VLA code, and are not expected to be + * used as a fixed-width type in normal code. No reference C implementation is + * provided on platforms without underlying SIMD intrinsics. + * + * With the current implementation ISA support is provided for: + * + * * 1-wide for scalar reference. + * * 4-wide for Armv8-A NEON. + * * 4-wide for x86-64 SSE2. + * * 4-wide for x86-64 SSE4.1. + * * 8-wide for x86-64 AVX2. + */ + +#ifndef ASTC_VECMATHLIB_H_INCLUDED +#define ASTC_VECMATHLIB_H_INCLUDED + +#if ASTCENC_SSE != 0 || ASTCENC_AVX != 0 + #include <immintrin.h> +#elif ASTCENC_NEON != 0 + #include <arm_neon.h> +#endif + +#if !defined(__clang__) && defined(_MSC_VER) + #define ASTCENC_SIMD_INLINE __forceinline + #define ASTCENC_NO_INLINE +#elif defined(__GNUC__) && !defined(__clang__) + #define ASTCENC_SIMD_INLINE __attribute__((always_inline)) inline + #define ASTCENC_NO_INLINE __attribute__ ((noinline)) +#else + #define ASTCENC_SIMD_INLINE __attribute__((always_inline, nodebug)) inline + #define ASTCENC_NO_INLINE __attribute__ ((noinline)) +#endif + +#if ASTCENC_AVX >= 2 + /* If we have AVX2 expose 8-wide VLA. */ + #include "astcenc_vecmathlib_sse_4.h" + #include "astcenc_vecmathlib_common_4.h" + #include "astcenc_vecmathlib_avx2_8.h" + + #define ASTCENC_SIMD_WIDTH 8 + + using vfloat = vfloat8; + + #if defined(ASTCENC_NO_INVARIANCE) + using vfloatacc = vfloat8; + #else + using vfloatacc = vfloat4; + #endif + + using vint = vint8; + using vmask = vmask8; + + constexpr auto loada = vfloat8::loada; + constexpr auto load1 = vfloat8::load1; + +#elif ASTCENC_SSE >= 20 + /* If we have SSE expose 4-wide VLA, and 4-wide fixed width. */ + #include "astcenc_vecmathlib_sse_4.h" + #include "astcenc_vecmathlib_common_4.h" + + #define ASTCENC_SIMD_WIDTH 4 + + using vfloat = vfloat4; + using vfloatacc = vfloat4; + using vint = vint4; + using vmask = vmask4; + + constexpr auto loada = vfloat4::loada; + constexpr auto load1 = vfloat4::load1; + +#elif ASTCENC_NEON > 0 + /* If we have NEON expose 4-wide VLA. */ + #include "astcenc_vecmathlib_neon_4.h" + #include "astcenc_vecmathlib_common_4.h" + + #define ASTCENC_SIMD_WIDTH 4 + + using vfloat = vfloat4; + using vfloatacc = vfloat4; + using vint = vint4; + using vmask = vmask4; + + constexpr auto loada = vfloat4::loada; + constexpr auto load1 = vfloat4::load1; + +#else + // If we have nothing expose 4-wide VLA, and 4-wide fixed width. + + // Note: We no longer expose the 1-wide scalar fallback because it is not + // invariant with the 4-wide path due to algorithms that use horizontal + // operations that accumulate a local vector sum before accumulating into + // a running sum. + // + // For 4 items adding into an accumulator using 1-wide vectors the sum is: + // + // result = ((((sum + l0) + l1) + l2) + l3) + // + // ... whereas the accumulator for a 4-wide vector sum is: + // + // result = sum + ((l0 + l2) + (l1 + l3)) + // + // In "normal maths" this is the same, but the floating point reassociation + // differences mean that these will not produce the same result. + + #include "astcenc_vecmathlib_none_4.h" + #include "astcenc_vecmathlib_common_4.h" + + #define ASTCENC_SIMD_WIDTH 4 + + using vfloat = vfloat4; + using vfloatacc = vfloat4; + using vint = vint4; + using vmask = vmask4; + + constexpr auto loada = vfloat4::loada; + constexpr auto load1 = vfloat4::load1; +#endif + +/** + * @brief Round a count down to the largest multiple of 8. + * + * @param count The unrounded value. + * + * @return The rounded value. + */ +ASTCENC_SIMD_INLINE unsigned int round_down_to_simd_multiple_8(unsigned int count) +{ + return count & static_cast<unsigned int>(~(8 - 1)); +} + +/** + * @brief Round a count down to the largest multiple of 4. + * + * @param count The unrounded value. + * + * @return The rounded value. + */ +ASTCENC_SIMD_INLINE unsigned int round_down_to_simd_multiple_4(unsigned int count) +{ + return count & static_cast<unsigned int>(~(4 - 1)); +} + +/** + * @brief Round a count down to the largest multiple of the SIMD width. + * + * Assumption that the vector width is a power of two ... + * + * @param count The unrounded value. + * + * @return The rounded value. + */ +ASTCENC_SIMD_INLINE unsigned int round_down_to_simd_multiple_vla(unsigned int count) +{ + return count & static_cast<unsigned int>(~(ASTCENC_SIMD_WIDTH - 1)); +} + +/** + * @brief Round a count up to the largest multiple of the SIMD width. + * + * Assumption that the vector width is a power of two ... + * + * @param count The unrounded value. + * + * @return The rounded value. + */ +ASTCENC_SIMD_INLINE unsigned int round_up_to_simd_multiple_vla(unsigned int count) +{ + unsigned int multiples = (count + ASTCENC_SIMD_WIDTH - 1) / ASTCENC_SIMD_WIDTH; + return multiples * ASTCENC_SIMD_WIDTH; +} + +/** + * @brief Return @c a with lanes negated if the @c b lane is negative. + */ +ASTCENC_SIMD_INLINE vfloat change_sign(vfloat a, vfloat b) +{ + vint ia = float_as_int(a); + vint ib = float_as_int(b); + vint sign_mask(static_cast<int>(0x80000000)); + vint r = ia ^ (ib & sign_mask); + return int_as_float(r); +} + +/** + * @brief Return fast, but approximate, vector atan(x). + * + * Max error of this implementation is 0.004883. + */ +ASTCENC_SIMD_INLINE vfloat atan(vfloat x) +{ + vmask c = abs(x) > vfloat(1.0f); + vfloat z = change_sign(vfloat(astc::PI_OVER_TWO), x); + vfloat y = select(x, vfloat(1.0f) / x, c); + y = y / (y * y * vfloat(0.28f) + vfloat(1.0f)); + return select(y, z - y, c); +} + +/** + * @brief Return fast, but approximate, vector atan2(x, y). + */ +ASTCENC_SIMD_INLINE vfloat atan2(vfloat y, vfloat x) +{ + vfloat z = atan(abs(y / x)); + vmask xmask = vmask(float_as_int(x).m); + return change_sign(select_msb(z, vfloat(astc::PI) - z, xmask), y); +} + +/* + * @brief Factory that returns a unit length 4 component vfloat4. + */ +static ASTCENC_SIMD_INLINE vfloat4 unit4() +{ + return vfloat4(0.5f); +} + +/** + * @brief Factory that returns a unit length 3 component vfloat4. + */ +static ASTCENC_SIMD_INLINE vfloat4 unit3() +{ + float val = 0.577350258827209473f; + return vfloat4(val, val, val, 0.0f); +} + +/** + * @brief Factory that returns a unit length 2 component vfloat4. + */ +static ASTCENC_SIMD_INLINE vfloat4 unit2() +{ + float val = 0.707106769084930420f; + return vfloat4(val, val, 0.0f, 0.0f); +} + +/** + * @brief Factory that returns a 3 component vfloat4. + */ +static ASTCENC_SIMD_INLINE vfloat4 vfloat3(float a, float b, float c) +{ + return vfloat4(a, b, c, 0.0f); +} + +/** + * @brief Factory that returns a 2 component vfloat4. + */ +static ASTCENC_SIMD_INLINE vfloat4 vfloat2(float a, float b) +{ + return vfloat4(a, b, 0.0f, 0.0f); +} + +/** + * @brief Normalize a non-zero length vector to unit length. + */ +static ASTCENC_SIMD_INLINE vfloat4 normalize(vfloat4 a) +{ + vfloat4 length = dot(a, a); + return a / sqrt(length); +} + +/** + * @brief Normalize a vector, returning @c safe if len is zero. + */ +static ASTCENC_SIMD_INLINE vfloat4 normalize_safe(vfloat4 a, vfloat4 safe) +{ + vfloat4 length = dot(a, a); + if (length.lane<0>() != 0.0f) + { + return a / sqrt(length); + } + + return safe; +} + + + +#define POLY0(x, c0) ( c0) +#define POLY1(x, c0, c1) ((POLY0(x, c1) * x) + c0) +#define POLY2(x, c0, c1, c2) ((POLY1(x, c1, c2) * x) + c0) +#define POLY3(x, c0, c1, c2, c3) ((POLY2(x, c1, c2, c3) * x) + c0) +#define POLY4(x, c0, c1, c2, c3, c4) ((POLY3(x, c1, c2, c3, c4) * x) + c0) +#define POLY5(x, c0, c1, c2, c3, c4, c5) ((POLY4(x, c1, c2, c3, c4, c5) * x) + c0) + +/** + * @brief Compute an approximate exp2(x) for each lane in the vector. + * + * Based on 5th degree minimax polynomials, ported from this blog + * https://jrfonseca.blogspot.com/2008/09/fast-sse2-pow-tables-or-polynomials.html + */ +static ASTCENC_SIMD_INLINE vfloat4 exp2(vfloat4 x) +{ + x = clamp(-126.99999f, 129.0f, x); + + vint4 ipart = float_to_int(x - 0.5f); + vfloat4 fpart = x - int_to_float(ipart); + + // Integer contrib, using 1 << ipart + vfloat4 iexp = int_as_float(lsl<23>(ipart + 127)); + + // Fractional contrib, using polynomial fit of 2^x in range [-0.5, 0.5) + vfloat4 fexp = POLY5(fpart, + 9.9999994e-1f, + 6.9315308e-1f, + 2.4015361e-1f, + 5.5826318e-2f, + 8.9893397e-3f, + 1.8775767e-3f); + + return iexp * fexp; +} + +/** + * @brief Compute an approximate log2(x) for each lane in the vector. + * + * Based on 5th degree minimax polynomials, ported from this blog + * https://jrfonseca.blogspot.com/2008/09/fast-sse2-pow-tables-or-polynomials.html + */ +static ASTCENC_SIMD_INLINE vfloat4 log2(vfloat4 x) +{ + vint4 exp(0x7F800000); + vint4 mant(0x007FFFFF); + vint4 one(0x3F800000); + + vint4 i = float_as_int(x); + + vfloat4 e = int_to_float(lsr<23>(i & exp) - 127); + + vfloat4 m = int_as_float((i & mant) | one); + + // Polynomial fit of log2(x)/(x - 1), for x in range [1, 2) + vfloat4 p = POLY4(m, + 2.8882704548164776201f, + -2.52074962577807006663f, + 1.48116647521213171641f, + -0.465725644288844778798f, + 0.0596515482674574969533f); + + // Increases the polynomial degree, but ensures that log2(1) == 0 + p = p * (m - 1.0f); + + return p + e; +} + +/** + * @brief Compute an approximate pow(x, y) for each lane in the vector. + * + * Power function based on the exp2(log2(x) * y) transform. + */ +static ASTCENC_SIMD_INLINE vfloat4 pow(vfloat4 x, vfloat4 y) +{ + vmask4 zero_mask = y == vfloat4(0.0f); + vfloat4 estimate = exp2(log2(x) * y); + + // Guarantee that y == 0 returns exactly 1.0f + return select(estimate, vfloat4(1.0f), zero_mask); +} + +/** + * @brief Count the leading zeros for each lane in @c a. + * + * Valid for all data values of @c a; will return a per-lane value [0, 32]. + */ +static ASTCENC_SIMD_INLINE vint4 clz(vint4 a) +{ + // This function is a horrible abuse of floating point exponents to convert + // the original integer value into a 2^N encoding we can recover easily. + + // Convert to float without risk of rounding up by keeping only top 8 bits. + // This trick is is guaranteed to keep top 8 bits and clear the 9th. + a = (~lsr<8>(a)) & a; + a = float_as_int(int_to_float(a)); + + // Extract and unbias exponent + a = vint4(127 + 31) - lsr<23>(a); + + // Clamp result to a valid 32-bit range + return clamp(0, 32, a); +} + +/** + * @brief Return lanewise 2^a for each lane in @c a. + * + * Use of signed int means that this is only valid for values in range [0, 31]. + */ +static ASTCENC_SIMD_INLINE vint4 two_to_the_n(vint4 a) +{ + // 2^30 is the largest signed number than can be represented + assert(all(a < vint4(31))); + + // This function is a horrible abuse of floating point to use the exponent + // and float conversion to generate a 2^N multiple. + + // Bias the exponent + vint4 exp = a + 127; + exp = lsl<23>(exp); + + // Reinterpret the bits as a float, and then convert to an int + vfloat4 f = int_as_float(exp); + return float_to_int(f); +} + +/** + * @brief Convert unorm16 [0, 65535] to float16 in range [0, 1]. + */ +static ASTCENC_SIMD_INLINE vint4 unorm16_to_sf16(vint4 p) +{ + vint4 fp16_one = vint4(0x3C00); + vint4 fp16_small = lsl<8>(p); + + vmask4 is_one = p == vint4(0xFFFF); + vmask4 is_small = p < vint4(4); + + // Manually inline clz() on Visual Studio to avoid release build codegen bug + // see https://github.com/ARM-software/astc-encoder/issues/259 +#if !defined(__clang__) && defined(_MSC_VER) + vint4 a = (~lsr<8>(p)) & p; + a = float_as_int(int_to_float(a)); + a = vint4(127 + 31) - lsr<23>(a); + vint4 lz = clamp(0, 32, a) - 16; +#else + vint4 lz = clz(p) - 16; +#endif + + p = p * two_to_the_n(lz + 1); + p = p & vint4(0xFFFF); + + p = lsr<6>(p); + + p = p | lsl<10>(vint4(14) - lz); + + vint4 r = select(p, fp16_one, is_one); + r = select(r, fp16_small, is_small); + return r; +} + +/** + * @brief Convert 16-bit LNS to float16. + */ +static ASTCENC_SIMD_INLINE vint4 lns_to_sf16(vint4 p) +{ + vint4 mc = p & 0x7FF; + vint4 ec = lsr<11>(p); + + vint4 mc_512 = mc * 3; + vmask4 mask_512 = mc < vint4(512); + + vint4 mc_1536 = mc * 4 - 512; + vmask4 mask_1536 = mc < vint4(1536); + + vint4 mc_else = mc * 5 - 2048; + + vint4 mt = mc_else; + mt = select(mt, mc_1536, mask_1536); + mt = select(mt, mc_512, mask_512); + + vint4 res = lsl<10>(ec) | lsr<3>(mt); + return min(res, vint4(0x7BFF)); +} + +/** + * @brief Extract mantissa and exponent of a float value. + * + * @param a The input value. + * @param[out] exp The output exponent. + * + * @return The mantissa. + */ +static ASTCENC_SIMD_INLINE vfloat4 frexp(vfloat4 a, vint4& exp) +{ + // Interpret the bits as an integer + vint4 ai = float_as_int(a); + + // Extract and unbias the exponent + exp = (lsr<23>(ai) & 0xFF) - 126; + + // Extract and unbias the mantissa + vint4 manti = (ai & static_cast<int>(0x807FFFFF)) | 0x3F000000; + return int_as_float(manti); +} + +/** + * @brief Convert float to 16-bit LNS. + */ +static ASTCENC_SIMD_INLINE vfloat4 float_to_lns(vfloat4 a) +{ + vint4 exp; + vfloat4 mant = frexp(a, exp); + + // Do these early before we start messing about ... + vmask4 mask_underflow_nan = ~(a > vfloat4(1.0f / 67108864.0f)); + vmask4 mask_infinity = a >= vfloat4(65536.0f); + + // If input is smaller than 2^-14, multiply by 2^25 and don't bias. + vmask4 exp_lt_m13 = exp < vint4(-13); + + vfloat4 a1a = a * 33554432.0f; + vint4 expa = vint4::zero(); + + vfloat4 a1b = (mant - 0.5f) * 4096; + vint4 expb = exp + 14; + + a = select(a1b, a1a, exp_lt_m13); + exp = select(expb, expa, exp_lt_m13); + + vmask4 a_lt_384 = a < vfloat4(384.0f); + vmask4 a_lt_1408 = a <= vfloat4(1408.0f); + + vfloat4 a2a = a * (4.0f / 3.0f); + vfloat4 a2b = a + 128.0f; + vfloat4 a2c = (a + 512.0f) * (4.0f / 5.0f); + + a = a2c; + a = select(a, a2b, a_lt_1408); + a = select(a, a2a, a_lt_384); + + a = a + (int_to_float(exp) * 2048.0f) + 1.0f; + + a = select(a, vfloat4(65535.0f), mask_infinity); + a = select(a, vfloat4::zero(), mask_underflow_nan); + + return a; +} + +namespace astc +{ + +static ASTCENC_SIMD_INLINE float pow(float x, float y) +{ + return pow(vfloat4(x), vfloat4(y)).lane<0>(); +} + +} + +#endif // #ifndef ASTC_VECMATHLIB_H_INCLUDED diff --git a/thirdparty/astcenc/astcenc_vecmathlib_avx2_8.h b/thirdparty/astcenc/astcenc_vecmathlib_avx2_8.h new file mode 100644 index 0000000000..a785aca75b --- /dev/null +++ b/thirdparty/astcenc/astcenc_vecmathlib_avx2_8.h @@ -0,0 +1,1204 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2019-2022 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief 8x32-bit vectors, implemented using AVX2. + * + * This module implements 8-wide 32-bit float, int, and mask vectors for x86 + * AVX2. + * + * There is a baseline level of functionality provided by all vector widths and + * implementations. This is implemented using identical function signatures, + * modulo data type, so we can use them as substitutable implementations in VLA + * code. + */ + +#ifndef ASTC_VECMATHLIB_AVX2_8_H_INCLUDED +#define ASTC_VECMATHLIB_AVX2_8_H_INCLUDED + +#ifndef ASTCENC_SIMD_INLINE + #error "Include astcenc_vecmathlib.h, do not include directly" +#endif + +#include <cstdio> + +// Define convenience intrinsics that are missing on older compilers +#define astcenc_mm256_set_m128i(m, n) _mm256_insertf128_si256(_mm256_castsi128_si256((n)), (m), 1) + +// ============================================================================ +// vfloat8 data type +// ============================================================================ + +/** + * @brief Data type for 8-wide floats. + */ +struct vfloat8 +{ + /** + * @brief Construct from zero-initialized value. + */ + ASTCENC_SIMD_INLINE vfloat8() = default; + + /** + * @brief Construct from 4 values loaded from an unaligned address. + * + * Consider using loada() which is better with vectors if data is aligned + * to vector length. + */ + ASTCENC_SIMD_INLINE explicit vfloat8(const float *p) + { + m = _mm256_loadu_ps(p); + } + + /** + * @brief Construct from 1 scalar value replicated across all lanes. + * + * Consider using zero() for constexpr zeros. + */ + ASTCENC_SIMD_INLINE explicit vfloat8(float a) + { + m = _mm256_set1_ps(a); + } + + /** + * @brief Construct from 8 scalar values. + * + * The value of @c a is stored to lane 0 (LSB) in the SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vfloat8( + float a, float b, float c, float d, + float e, float f, float g, float h) + { + m = _mm256_set_ps(h, g, f, e, d, c, b, a); + } + + /** + * @brief Construct from an existing SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vfloat8(__m256 a) + { + m = a; + } + + /** + * @brief Get the scalar value of a single lane. + */ + template <int l> ASTCENC_SIMD_INLINE float lane() const + { + #if !defined(__clang__) && defined(_MSC_VER) + return m.m256_f32[l]; + #else + union { __m256 m; float f[8]; } cvt; + cvt.m = m; + return cvt.f[l]; + #endif + } + + /** + * @brief Factory that returns a vector of zeros. + */ + static ASTCENC_SIMD_INLINE vfloat8 zero() + { + return vfloat8(_mm256_setzero_ps()); + } + + /** + * @brief Factory that returns a replicated scalar loaded from memory. + */ + static ASTCENC_SIMD_INLINE vfloat8 load1(const float* p) + { + return vfloat8(_mm256_broadcast_ss(p)); + } + + /** + * @brief Factory that returns a vector loaded from 32B aligned memory. + */ + static ASTCENC_SIMD_INLINE vfloat8 loada(const float* p) + { + return vfloat8(_mm256_load_ps(p)); + } + + /** + * @brief Factory that returns a vector containing the lane IDs. + */ + static ASTCENC_SIMD_INLINE vfloat8 lane_id() + { + return vfloat8(_mm256_set_ps(7, 6, 5, 4, 3, 2, 1, 0)); + } + + /** + * @brief The vector ... + */ + __m256 m; +}; + +// ============================================================================ +// vint8 data type +// ============================================================================ + +/** + * @brief Data type for 8-wide ints. + */ +struct vint8 +{ + /** + * @brief Construct from zero-initialized value. + */ + ASTCENC_SIMD_INLINE vint8() = default; + + /** + * @brief Construct from 8 values loaded from an unaligned address. + * + * Consider using loada() which is better with vectors if data is aligned + * to vector length. + */ + ASTCENC_SIMD_INLINE explicit vint8(const int *p) + { + m = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(p)); + } + + /** + * @brief Construct from 8 uint8_t loaded from an unaligned address. + */ + ASTCENC_SIMD_INLINE explicit vint8(const uint8_t *p) + { + // _mm_loadu_si64 would be nicer syntax, but missing on older GCC + m = _mm256_cvtepu8_epi32(_mm_cvtsi64_si128(*reinterpret_cast<const long long*>(p))); + } + + /** + * @brief Construct from 1 scalar value replicated across all lanes. + * + * Consider using vfloat4::zero() for constexpr zeros. + */ + ASTCENC_SIMD_INLINE explicit vint8(int a) + { + m = _mm256_set1_epi32(a); + } + + /** + * @brief Construct from 8 scalar values. + * + * The value of @c a is stored to lane 0 (LSB) in the SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vint8( + int a, int b, int c, int d, + int e, int f, int g, int h) + { + m = _mm256_set_epi32(h, g, f, e, d, c, b, a); + } + + /** + * @brief Construct from an existing SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vint8(__m256i a) + { + m = a; + } + + /** + * @brief Get the scalar from a single lane. + */ + template <int l> ASTCENC_SIMD_INLINE int lane() const + { + #if !defined(__clang__) && defined(_MSC_VER) + return m.m256i_i32[l]; + #else + union { __m256i m; int f[8]; } cvt; + cvt.m = m; + return cvt.f[l]; + #endif + } + + /** + * @brief Factory that returns a vector of zeros. + */ + static ASTCENC_SIMD_INLINE vint8 zero() + { + return vint8(_mm256_setzero_si256()); + } + + /** + * @brief Factory that returns a replicated scalar loaded from memory. + */ + static ASTCENC_SIMD_INLINE vint8 load1(const int* p) + { + __m128i a = _mm_set1_epi32(*p); + return vint8(_mm256_broadcastd_epi32(a)); + } + + /** + * @brief Factory that returns a vector loaded from 32B aligned memory. + */ + static ASTCENC_SIMD_INLINE vint8 loada(const int* p) + { + return vint8(_mm256_load_si256(reinterpret_cast<const __m256i*>(p))); + } + + /** + * @brief Factory that returns a vector containing the lane IDs. + */ + static ASTCENC_SIMD_INLINE vint8 lane_id() + { + return vint8(_mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0)); + } + + /** + * @brief The vector ... + */ + __m256i m; +}; + +// ============================================================================ +// vmask8 data type +// ============================================================================ + +/** + * @brief Data type for 8-wide control plane masks. + */ +struct vmask8 +{ + /** + * @brief Construct from an existing SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vmask8(__m256 a) + { + m = a; + } + + /** + * @brief Construct from an existing SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vmask8(__m256i a) + { + m = _mm256_castsi256_ps(a); + } + + /** + * @brief Construct from 1 scalar value. + */ + ASTCENC_SIMD_INLINE explicit vmask8(bool a) + { + vint8 mask(a == false ? 0 : -1); + m = _mm256_castsi256_ps(mask.m); + } + + /** + * @brief The vector ... + */ + __m256 m; +}; + +// ============================================================================ +// vmask8 operators and functions +// ============================================================================ + +/** + * @brief Overload: mask union (or). + */ +ASTCENC_SIMD_INLINE vmask8 operator|(vmask8 a, vmask8 b) +{ + return vmask8(_mm256_or_ps(a.m, b.m)); +} + +/** + * @brief Overload: mask intersect (and). + */ +ASTCENC_SIMD_INLINE vmask8 operator&(vmask8 a, vmask8 b) +{ + return vmask8(_mm256_and_ps(a.m, b.m)); +} + +/** + * @brief Overload: mask difference (xor). + */ +ASTCENC_SIMD_INLINE vmask8 operator^(vmask8 a, vmask8 b) +{ + return vmask8(_mm256_xor_ps(a.m, b.m)); +} + +/** + * @brief Overload: mask invert (not). + */ +ASTCENC_SIMD_INLINE vmask8 operator~(vmask8 a) +{ + return vmask8(_mm256_xor_si256(_mm256_castps_si256(a.m), _mm256_set1_epi32(-1))); +} + +/** + * @brief Return a 8-bit mask code indicating mask status. + * + * bit0 = lane 0 + */ +ASTCENC_SIMD_INLINE unsigned int mask(vmask8 a) +{ + return static_cast<unsigned int>(_mm256_movemask_ps(a.m)); +} + +/** + * @brief True if any lanes are enabled, false otherwise. + */ +ASTCENC_SIMD_INLINE bool any(vmask8 a) +{ + return mask(a) != 0; +} + +/** + * @brief True if all lanes are enabled, false otherwise. + */ +ASTCENC_SIMD_INLINE bool all(vmask8 a) +{ + return mask(a) == 0xFF; +} + +// ============================================================================ +// vint8 operators and functions +// ============================================================================ +/** + * @brief Overload: vector by vector addition. + */ +ASTCENC_SIMD_INLINE vint8 operator+(vint8 a, vint8 b) +{ + return vint8(_mm256_add_epi32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector incremental addition. + */ +ASTCENC_SIMD_INLINE vint8& operator+=(vint8& a, const vint8& b) +{ + a = a + b; + return a; +} + +/** + * @brief Overload: vector by vector subtraction. + */ +ASTCENC_SIMD_INLINE vint8 operator-(vint8 a, vint8 b) +{ + return vint8(_mm256_sub_epi32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector multiplication. + */ +ASTCENC_SIMD_INLINE vint8 operator*(vint8 a, vint8 b) +{ + return vint8(_mm256_mullo_epi32(a.m, b.m)); +} + +/** + * @brief Overload: vector bit invert. + */ +ASTCENC_SIMD_INLINE vint8 operator~(vint8 a) +{ + return vint8(_mm256_xor_si256(a.m, _mm256_set1_epi32(-1))); +} + +/** + * @brief Overload: vector by vector bitwise or. + */ +ASTCENC_SIMD_INLINE vint8 operator|(vint8 a, vint8 b) +{ + return vint8(_mm256_or_si256(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector bitwise and. + */ +ASTCENC_SIMD_INLINE vint8 operator&(vint8 a, vint8 b) +{ + return vint8(_mm256_and_si256(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector bitwise xor. + */ +ASTCENC_SIMD_INLINE vint8 operator^(vint8 a, vint8 b) +{ + return vint8(_mm256_xor_si256(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector equality. + */ +ASTCENC_SIMD_INLINE vmask8 operator==(vint8 a, vint8 b) +{ + return vmask8(_mm256_cmpeq_epi32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector inequality. + */ +ASTCENC_SIMD_INLINE vmask8 operator!=(vint8 a, vint8 b) +{ + return ~vmask8(_mm256_cmpeq_epi32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector less than. + */ +ASTCENC_SIMD_INLINE vmask8 operator<(vint8 a, vint8 b) +{ + return vmask8(_mm256_cmpgt_epi32(b.m, a.m)); +} + +/** + * @brief Overload: vector by vector greater than. + */ +ASTCENC_SIMD_INLINE vmask8 operator>(vint8 a, vint8 b) +{ + return vmask8(_mm256_cmpgt_epi32(a.m, b.m)); +} + +/** + * @brief Logical shift left. + */ +template <int s> ASTCENC_SIMD_INLINE vint8 lsl(vint8 a) +{ + return vint8(_mm256_slli_epi32(a.m, s)); +} + +/** + * @brief Arithmetic shift right. + */ +template <int s> ASTCENC_SIMD_INLINE vint8 asr(vint8 a) +{ + return vint8(_mm256_srai_epi32(a.m, s)); +} + +/** + * @brief Logical shift right. + */ +template <int s> ASTCENC_SIMD_INLINE vint8 lsr(vint8 a) +{ + return vint8(_mm256_srli_epi32(a.m, s)); +} + +/** + * @brief Return the min vector of two vectors. + */ +ASTCENC_SIMD_INLINE vint8 min(vint8 a, vint8 b) +{ + return vint8(_mm256_min_epi32(a.m, b.m)); +} + +/** + * @brief Return the max vector of two vectors. + */ +ASTCENC_SIMD_INLINE vint8 max(vint8 a, vint8 b) +{ + return vint8(_mm256_max_epi32(a.m, b.m)); +} + +/** + * @brief Return the horizontal minimum of a vector. + */ +ASTCENC_SIMD_INLINE vint8 hmin(vint8 a) +{ + __m128i m = _mm_min_epi32(_mm256_extracti128_si256(a.m, 0), _mm256_extracti128_si256(a.m, 1)); + m = _mm_min_epi32(m, _mm_shuffle_epi32(m, _MM_SHUFFLE(0,0,3,2))); + m = _mm_min_epi32(m, _mm_shuffle_epi32(m, _MM_SHUFFLE(0,0,0,1))); + m = _mm_shuffle_epi32(m, _MM_SHUFFLE(0,0,0,0)); + + __m256i r = astcenc_mm256_set_m128i(m, m); + vint8 vmin(r); + return vmin; +} + +/** + * @brief Return the horizontal maximum of a vector. + */ +ASTCENC_SIMD_INLINE vint8 hmax(vint8 a) +{ + __m128i m = _mm_max_epi32(_mm256_extracti128_si256(a.m, 0), _mm256_extracti128_si256(a.m, 1)); + m = _mm_max_epi32(m, _mm_shuffle_epi32(m, _MM_SHUFFLE(0,0,3,2))); + m = _mm_max_epi32(m, _mm_shuffle_epi32(m, _MM_SHUFFLE(0,0,0,1))); + m = _mm_shuffle_epi32(m, _MM_SHUFFLE(0,0,0,0)); + + __m256i r = astcenc_mm256_set_m128i(m, m); + vint8 vmax(r); + return vmax; +} + +/** + * @brief Store a vector to a 16B aligned memory address. + */ +ASTCENC_SIMD_INLINE void storea(vint8 a, int* p) +{ + _mm256_store_si256(reinterpret_cast<__m256i*>(p), a.m); +} + +/** + * @brief Store a vector to an unaligned memory address. + */ +ASTCENC_SIMD_INLINE void store(vint8 a, int* p) +{ + _mm256_storeu_si256(reinterpret_cast<__m256i*>(p), a.m); +} + +/** + * @brief Store lowest N (vector width) bytes into an unaligned address. + */ +ASTCENC_SIMD_INLINE void store_nbytes(vint8 a, uint8_t* p) +{ + // This is the most logical implementation, but the convenience intrinsic + // is missing on older compilers (supported in g++ 9 and clang++ 9). + // _mm_storeu_si64(ptr, _mm256_extracti128_si256(v.m, 0)) + _mm_storel_epi64(reinterpret_cast<__m128i*>(p), _mm256_extracti128_si256(a.m, 0)); +} + +/** + * @brief Gather N (vector width) indices from the array. + */ +ASTCENC_SIMD_INLINE vint8 gatheri(const int* base, vint8 indices) +{ + return vint8(_mm256_i32gather_epi32(base, indices.m, 4)); +} + +/** + * @brief Pack low 8 bits of N (vector width) lanes into bottom of vector. + */ +ASTCENC_SIMD_INLINE vint8 pack_low_bytes(vint8 v) +{ + __m256i shuf = _mm256_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 28, 24, 20, 16, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 12, 8, 4, 0); + __m256i a = _mm256_shuffle_epi8(v.m, shuf); + __m128i a0 = _mm256_extracti128_si256(a, 0); + __m128i a1 = _mm256_extracti128_si256(a, 1); + __m128i b = _mm_unpacklo_epi32(a0, a1); + + __m256i r = astcenc_mm256_set_m128i(b, b); + return vint8(r); +} + +/** + * @brief Return lanes from @c b if @c cond is set, else @c a. + */ +ASTCENC_SIMD_INLINE vint8 select(vint8 a, vint8 b, vmask8 cond) +{ + __m256i condi = _mm256_castps_si256(cond.m); + return vint8(_mm256_blendv_epi8(a.m, b.m, condi)); +} + +// ============================================================================ +// vfloat4 operators and functions +// ============================================================================ + +/** + * @brief Overload: vector by vector addition. + */ +ASTCENC_SIMD_INLINE vfloat8 operator+(vfloat8 a, vfloat8 b) +{ + return vfloat8(_mm256_add_ps(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector incremental addition. + */ +ASTCENC_SIMD_INLINE vfloat8& operator+=(vfloat8& a, const vfloat8& b) +{ + a = a + b; + return a; +} + +/** + * @brief Overload: vector by vector subtraction. + */ +ASTCENC_SIMD_INLINE vfloat8 operator-(vfloat8 a, vfloat8 b) +{ + return vfloat8(_mm256_sub_ps(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector multiplication. + */ +ASTCENC_SIMD_INLINE vfloat8 operator*(vfloat8 a, vfloat8 b) +{ + return vfloat8(_mm256_mul_ps(a.m, b.m)); +} + +/** + * @brief Overload: vector by scalar multiplication. + */ +ASTCENC_SIMD_INLINE vfloat8 operator*(vfloat8 a, float b) +{ + return vfloat8(_mm256_mul_ps(a.m, _mm256_set1_ps(b))); +} + +/** + * @brief Overload: scalar by vector multiplication. + */ +ASTCENC_SIMD_INLINE vfloat8 operator*(float a, vfloat8 b) +{ + return vfloat8(_mm256_mul_ps(_mm256_set1_ps(a), b.m)); +} + +/** + * @brief Overload: vector by vector division. + */ +ASTCENC_SIMD_INLINE vfloat8 operator/(vfloat8 a, vfloat8 b) +{ + return vfloat8(_mm256_div_ps(a.m, b.m)); +} + +/** + * @brief Overload: vector by scalar division. + */ +ASTCENC_SIMD_INLINE vfloat8 operator/(vfloat8 a, float b) +{ + return vfloat8(_mm256_div_ps(a.m, _mm256_set1_ps(b))); +} + + +/** + * @brief Overload: scalar by vector division. + */ +ASTCENC_SIMD_INLINE vfloat8 operator/(float a, vfloat8 b) +{ + return vfloat8(_mm256_div_ps(_mm256_set1_ps(a), b.m)); +} + + +/** + * @brief Overload: vector by vector equality. + */ +ASTCENC_SIMD_INLINE vmask8 operator==(vfloat8 a, vfloat8 b) +{ + return vmask8(_mm256_cmp_ps(a.m, b.m, _CMP_EQ_OQ)); +} + +/** + * @brief Overload: vector by vector inequality. + */ +ASTCENC_SIMD_INLINE vmask8 operator!=(vfloat8 a, vfloat8 b) +{ + return vmask8(_mm256_cmp_ps(a.m, b.m, _CMP_NEQ_OQ)); +} + +/** + * @brief Overload: vector by vector less than. + */ +ASTCENC_SIMD_INLINE vmask8 operator<(vfloat8 a, vfloat8 b) +{ + return vmask8(_mm256_cmp_ps(a.m, b.m, _CMP_LT_OQ)); +} + +/** + * @brief Overload: vector by vector greater than. + */ +ASTCENC_SIMD_INLINE vmask8 operator>(vfloat8 a, vfloat8 b) +{ + return vmask8(_mm256_cmp_ps(a.m, b.m, _CMP_GT_OQ)); +} + +/** + * @brief Overload: vector by vector less than or equal. + */ +ASTCENC_SIMD_INLINE vmask8 operator<=(vfloat8 a, vfloat8 b) +{ + return vmask8(_mm256_cmp_ps(a.m, b.m, _CMP_LE_OQ)); +} + +/** + * @brief Overload: vector by vector greater than or equal. + */ +ASTCENC_SIMD_INLINE vmask8 operator>=(vfloat8 a, vfloat8 b) +{ + return vmask8(_mm256_cmp_ps(a.m, b.m, _CMP_GE_OQ)); +} + +/** + * @brief Return the min vector of two vectors. + * + * If either lane value is NaN, @c b will be returned for that lane. + */ +ASTCENC_SIMD_INLINE vfloat8 min(vfloat8 a, vfloat8 b) +{ + return vfloat8(_mm256_min_ps(a.m, b.m)); +} + +/** + * @brief Return the min vector of a vector and a scalar. + * + * If either lane value is NaN, @c b will be returned for that lane. + */ +ASTCENC_SIMD_INLINE vfloat8 min(vfloat8 a, float b) +{ + return min(a, vfloat8(b)); +} + +/** + * @brief Return the max vector of two vectors. + * + * If either lane value is NaN, @c b will be returned for that lane. + */ +ASTCENC_SIMD_INLINE vfloat8 max(vfloat8 a, vfloat8 b) +{ + return vfloat8(_mm256_max_ps(a.m, b.m)); +} + +/** + * @brief Return the max vector of a vector and a scalar. + * + * If either lane value is NaN, @c b will be returned for that lane. + */ +ASTCENC_SIMD_INLINE vfloat8 max(vfloat8 a, float b) +{ + return max(a, vfloat8(b)); +} + +/** + * @brief Return the clamped value between min and max. + * + * It is assumed that neither @c min nor @c max are NaN values. If @c a is NaN + * then @c min will be returned for that lane. + */ +ASTCENC_SIMD_INLINE vfloat8 clamp(float min, float max, vfloat8 a) +{ + // Do not reorder - second operand will return if either is NaN + a.m = _mm256_max_ps(a.m, _mm256_set1_ps(min)); + a.m = _mm256_min_ps(a.m, _mm256_set1_ps(max)); + return a; +} + +/** + * @brief Return a clamped value between 0.0f and max. + * + * It is assumed that @c max is not a NaN value. If @c a is NaN then zero will + * be returned for that lane. + */ +ASTCENC_SIMD_INLINE vfloat8 clampz(float max, vfloat8 a) +{ + a.m = _mm256_max_ps(a.m, _mm256_setzero_ps()); + a.m = _mm256_min_ps(a.m, _mm256_set1_ps(max)); + return a; +} + +/** + * @brief Return a clamped value between 0.0f and 1.0f. + * + * If @c a is NaN then zero will be returned for that lane. + */ +ASTCENC_SIMD_INLINE vfloat8 clampzo(vfloat8 a) +{ + a.m = _mm256_max_ps(a.m, _mm256_setzero_ps()); + a.m = _mm256_min_ps(a.m, _mm256_set1_ps(1.0f)); + return a; +} + +/** + * @brief Return the absolute value of the float vector. + */ +ASTCENC_SIMD_INLINE vfloat8 abs(vfloat8 a) +{ + __m256 msk = _mm256_castsi256_ps(_mm256_set1_epi32(0x7fffffff)); + return vfloat8(_mm256_and_ps(a.m, msk)); +} + +/** + * @brief Return a float rounded to the nearest integer value. + */ +ASTCENC_SIMD_INLINE vfloat8 round(vfloat8 a) +{ + constexpr int flags = _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC; + return vfloat8(_mm256_round_ps(a.m, flags)); +} + +/** + * @brief Return the horizontal minimum of a vector. + */ +ASTCENC_SIMD_INLINE vfloat8 hmin(vfloat8 a) +{ + __m128 vlow = _mm256_castps256_ps128(a.m); + __m128 vhigh = _mm256_extractf128_ps(a.m, 1); + vlow = _mm_min_ps(vlow, vhigh); + + // First do an horizontal reduction. + __m128 shuf = _mm_shuffle_ps(vlow, vlow, _MM_SHUFFLE(2, 3, 0, 1)); + __m128 mins = _mm_min_ps(vlow, shuf); + shuf = _mm_movehl_ps(shuf, mins); + mins = _mm_min_ss(mins, shuf); + + // This is the most logical implementation, but the convenience intrinsic + // is missing on older compilers (supported in g++ 9 and clang++ 9). + //__m256i r = _mm256_set_m128(m, m) + __m256 r = _mm256_insertf128_ps(_mm256_castps128_ps256(mins), mins, 1); + + return vfloat8(_mm256_permute_ps(r, 0)); +} + +/** + * @brief Return the horizontal minimum of a vector. + */ +ASTCENC_SIMD_INLINE float hmin_s(vfloat8 a) +{ + return hmin(a).lane<0>(); +} + +/** + * @brief Return the horizontal maximum of a vector. + */ +ASTCENC_SIMD_INLINE vfloat8 hmax(vfloat8 a) +{ + __m128 vlow = _mm256_castps256_ps128(a.m); + __m128 vhigh = _mm256_extractf128_ps(a.m, 1); + vhigh = _mm_max_ps(vlow, vhigh); + + // First do an horizontal reduction. + __m128 shuf = _mm_shuffle_ps(vhigh, vhigh, _MM_SHUFFLE(2, 3, 0, 1)); + __m128 maxs = _mm_max_ps(vhigh, shuf); + shuf = _mm_movehl_ps(shuf,maxs); + maxs = _mm_max_ss(maxs, shuf); + + // This is the most logical implementation, but the convenience intrinsic + // is missing on older compilers (supported in g++ 9 and clang++ 9). + //__m256i r = _mm256_set_m128(m, m) + __m256 r = _mm256_insertf128_ps(_mm256_castps128_ps256(maxs), maxs, 1); + return vfloat8(_mm256_permute_ps(r, 0)); +} + +/** + * @brief Return the horizontal maximum of a vector. + */ +ASTCENC_SIMD_INLINE float hmax_s(vfloat8 a) +{ + return hmax(a).lane<0>(); +} + +/** + * @brief Return the horizontal sum of a vector. + */ +ASTCENC_SIMD_INLINE float hadd_s(vfloat8 a) +{ + // Two sequential 4-wide adds gives invariance with 4-wide code + vfloat4 lo(_mm256_extractf128_ps(a.m, 0)); + vfloat4 hi(_mm256_extractf128_ps(a.m, 1)); + return hadd_s(lo) + hadd_s(hi); +} + +/** + * @brief Return lanes from @c b if @c cond is set, else @c a. + */ +ASTCENC_SIMD_INLINE vfloat8 select(vfloat8 a, vfloat8 b, vmask8 cond) +{ + return vfloat8(_mm256_blendv_ps(a.m, b.m, cond.m)); +} + +/** + * @brief Return lanes from @c b if MSB of @c cond is set, else @c a. + */ +ASTCENC_SIMD_INLINE vfloat8 select_msb(vfloat8 a, vfloat8 b, vmask8 cond) +{ + return vfloat8(_mm256_blendv_ps(a.m, b.m, cond.m)); +} + +/** + * @brief Accumulate lane-wise sums for a vector, folded 4-wide. + * + * This is invariant with 4-wide implementations. + */ +ASTCENC_SIMD_INLINE void haccumulate(vfloat4& accum, vfloat8 a) +{ + vfloat4 lo(_mm256_extractf128_ps(a.m, 0)); + haccumulate(accum, lo); + + vfloat4 hi(_mm256_extractf128_ps(a.m, 1)); + haccumulate(accum, hi); +} + +/** + * @brief Accumulate lane-wise sums for a vector. + * + * This is NOT invariant with 4-wide implementations. + */ +ASTCENC_SIMD_INLINE void haccumulate(vfloat8& accum, vfloat8 a) +{ + accum += a; +} + +/** + * @brief Accumulate masked lane-wise sums for a vector, folded 4-wide. + * + * This is invariant with 4-wide implementations. + */ +ASTCENC_SIMD_INLINE void haccumulate(vfloat4& accum, vfloat8 a, vmask8 m) +{ + a = select(vfloat8::zero(), a, m); + haccumulate(accum, a); +} + +/** + * @brief Accumulate masked lane-wise sums for a vector. + * + * This is NOT invariant with 4-wide implementations. + */ +ASTCENC_SIMD_INLINE void haccumulate(vfloat8& accum, vfloat8 a, vmask8 m) +{ + a = select(vfloat8::zero(), a, m); + haccumulate(accum, a); +} + +/** + * @brief Return the sqrt of the lanes in the vector. + */ +ASTCENC_SIMD_INLINE vfloat8 sqrt(vfloat8 a) +{ + return vfloat8(_mm256_sqrt_ps(a.m)); +} + +/** + * @brief Load a vector of gathered results from an array; + */ +ASTCENC_SIMD_INLINE vfloat8 gatherf(const float* base, vint8 indices) +{ + return vfloat8(_mm256_i32gather_ps(base, indices.m, 4)); +} + +/** + * @brief Store a vector to an unaligned memory address. + */ +ASTCENC_SIMD_INLINE void store(vfloat8 a, float* p) +{ + _mm256_storeu_ps(p, a.m); +} + +/** + * @brief Store a vector to a 32B aligned memory address. + */ +ASTCENC_SIMD_INLINE void storea(vfloat8 a, float* p) +{ + _mm256_store_ps(p, a.m); +} + +/** + * @brief Return a integer value for a float vector, using truncation. + */ +ASTCENC_SIMD_INLINE vint8 float_to_int(vfloat8 a) +{ + return vint8(_mm256_cvttps_epi32(a.m)); +} + +/** + * @brief Return a integer value for a float vector, using round-to-nearest. + */ +ASTCENC_SIMD_INLINE vint8 float_to_int_rtn(vfloat8 a) +{ + a = round(a); + return vint8(_mm256_cvttps_epi32(a.m)); +} + + +/** + * @brief Return a float value for an integer vector. + */ +ASTCENC_SIMD_INLINE vfloat8 int_to_float(vint8 a) +{ + return vfloat8(_mm256_cvtepi32_ps(a.m)); +} + +/** + * @brief Return a float value as an integer bit pattern (i.e. no conversion). + * + * It is a common trick to convert floats into integer bit patterns, perform + * some bit hackery based on knowledge they are IEEE 754 layout, and then + * convert them back again. This is the first half of that flip. + */ +ASTCENC_SIMD_INLINE vint8 float_as_int(vfloat8 a) +{ + return vint8(_mm256_castps_si256(a.m)); +} + +/** + * @brief Return a integer value as a float bit pattern (i.e. no conversion). + * + * It is a common trick to convert floats into integer bit patterns, perform + * some bit hackery based on knowledge they are IEEE 754 layout, and then + * convert them back again. This is the second half of that flip. + */ +ASTCENC_SIMD_INLINE vfloat8 int_as_float(vint8 a) +{ + return vfloat8(_mm256_castsi256_ps(a.m)); +} + +/** + * @brief Prepare a vtable lookup table for use with the native SIMD size. + */ +ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint8& t0p) +{ + // AVX2 duplicates the table within each 128-bit lane + __m128i t0n = t0.m; + t0p = vint8(astcenc_mm256_set_m128i(t0n, t0n)); +} + +/** + * @brief Prepare a vtable lookup table for use with the native SIMD size. + */ +ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4 t1, vint8& t0p, vint8& t1p) +{ + // AVX2 duplicates the table within each 128-bit lane + __m128i t0n = t0.m; + t0p = vint8(astcenc_mm256_set_m128i(t0n, t0n)); + + __m128i t1n = _mm_xor_si128(t0.m, t1.m); + t1p = vint8(astcenc_mm256_set_m128i(t1n, t1n)); +} + +/** + * @brief Prepare a vtable lookup table for use with the native SIMD size. + */ +ASTCENC_SIMD_INLINE void vtable_prepare( + vint4 t0, vint4 t1, vint4 t2, vint4 t3, + vint8& t0p, vint8& t1p, vint8& t2p, vint8& t3p) +{ + // AVX2 duplicates the table within each 128-bit lane + __m128i t0n = t0.m; + t0p = vint8(astcenc_mm256_set_m128i(t0n, t0n)); + + __m128i t1n = _mm_xor_si128(t0.m, t1.m); + t1p = vint8(astcenc_mm256_set_m128i(t1n, t1n)); + + __m128i t2n = _mm_xor_si128(t1.m, t2.m); + t2p = vint8(astcenc_mm256_set_m128i(t2n, t2n)); + + __m128i t3n = _mm_xor_si128(t2.m, t3.m); + t3p = vint8(astcenc_mm256_set_m128i(t3n, t3n)); +} + +/** + * @brief Perform an 8-bit 16-entry table lookup, with 32-bit indexes. + */ +ASTCENC_SIMD_INLINE vint8 vtable_8bt_32bi(vint8 t0, vint8 idx) +{ + // Set index byte MSB to 1 for unused bytes so shuffle returns zero + __m256i idxx = _mm256_or_si256(idx.m, _mm256_set1_epi32(static_cast<int>(0xFFFFFF00))); + + __m256i result = _mm256_shuffle_epi8(t0.m, idxx); + return vint8(result); +} + +/** + * @brief Perform an 8-bit 32-entry table lookup, with 32-bit indexes. + */ +ASTCENC_SIMD_INLINE vint8 vtable_8bt_32bi(vint8 t0, vint8 t1, vint8 idx) +{ + // Set index byte MSB to 1 for unused bytes so shuffle returns zero + __m256i idxx = _mm256_or_si256(idx.m, _mm256_set1_epi32(static_cast<int>(0xFFFFFF00))); + + __m256i result = _mm256_shuffle_epi8(t0.m, idxx); + idxx = _mm256_sub_epi8(idxx, _mm256_set1_epi8(16)); + + __m256i result2 = _mm256_shuffle_epi8(t1.m, idxx); + result = _mm256_xor_si256(result, result2); + return vint8(result); +} + +/** + * @brief Perform an 8-bit 64-entry table lookup, with 32-bit indexes. + */ +ASTCENC_SIMD_INLINE vint8 vtable_8bt_32bi(vint8 t0, vint8 t1, vint8 t2, vint8 t3, vint8 idx) +{ + // Set index byte MSB to 1 for unused bytes so shuffle returns zero + __m256i idxx = _mm256_or_si256(idx.m, _mm256_set1_epi32(static_cast<int>(0xFFFFFF00))); + + __m256i result = _mm256_shuffle_epi8(t0.m, idxx); + idxx = _mm256_sub_epi8(idxx, _mm256_set1_epi8(16)); + + __m256i result2 = _mm256_shuffle_epi8(t1.m, idxx); + result = _mm256_xor_si256(result, result2); + idxx = _mm256_sub_epi8(idxx, _mm256_set1_epi8(16)); + + result2 = _mm256_shuffle_epi8(t2.m, idxx); + result = _mm256_xor_si256(result, result2); + idxx = _mm256_sub_epi8(idxx, _mm256_set1_epi8(16)); + + result2 = _mm256_shuffle_epi8(t3.m, idxx); + result = _mm256_xor_si256(result, result2); + + return vint8(result); +} + +/** + * @brief Return a vector of interleaved RGBA data. + * + * Input vectors have the value stored in the bottom 8 bits of each lane, + * with high bits set to zero. + * + * Output vector stores a single RGBA texel packed in each lane. + */ +ASTCENC_SIMD_INLINE vint8 interleave_rgba8(vint8 r, vint8 g, vint8 b, vint8 a) +{ + return r + lsl<8>(g) + lsl<16>(b) + lsl<24>(a); +} + +/** + * @brief Store a vector, skipping masked lanes. + * + * All masked lanes must be at the end of vector, after all non-masked lanes. + */ +ASTCENC_SIMD_INLINE void store_lanes_masked(int* base, vint8 data, vmask8 mask) +{ + _mm256_maskstore_epi32(base, _mm256_castps_si256(mask.m), data.m); +} + +/** + * @brief Debug function to print a vector of ints. + */ +ASTCENC_SIMD_INLINE void print(vint8 a) +{ + alignas(ASTCENC_VECALIGN) int v[8]; + storea(a, v); + printf("v8_i32:\n %8d %8d %8d %8d %8d %8d %8d %8d\n", + v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); +} + +/** + * @brief Debug function to print a vector of ints. + */ +ASTCENC_SIMD_INLINE void printx(vint8 a) +{ + alignas(ASTCENC_VECALIGN) int v[8]; + storea(a, v); + printf("v8_i32:\n %08x %08x %08x %08x %08x %08x %08x %08x\n", + v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); +} + +/** + * @brief Debug function to print a vector of floats. + */ +ASTCENC_SIMD_INLINE void print(vfloat8 a) +{ + alignas(ASTCENC_VECALIGN) float v[8]; + storea(a, v); + printf("v8_f32:\n %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f\n", + static_cast<double>(v[0]), static_cast<double>(v[1]), + static_cast<double>(v[2]), static_cast<double>(v[3]), + static_cast<double>(v[4]), static_cast<double>(v[5]), + static_cast<double>(v[6]), static_cast<double>(v[7])); +} + +/** + * @brief Debug function to print a vector of masks. + */ +ASTCENC_SIMD_INLINE void print(vmask8 a) +{ + print(select(vint8(0), vint8(1), a)); +} + +#endif // #ifndef ASTC_VECMATHLIB_AVX2_8_H_INCLUDED diff --git a/thirdparty/astcenc/astcenc_vecmathlib_common_4.h b/thirdparty/astcenc/astcenc_vecmathlib_common_4.h new file mode 100644 index 0000000000..86ee4fd3e1 --- /dev/null +++ b/thirdparty/astcenc/astcenc_vecmathlib_common_4.h @@ -0,0 +1,423 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2020-2021 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief Generic 4x32-bit vector functions. + * + * This module implements generic 4-wide vector functions that are valid for + * all instruction sets, typically implemented using lower level 4-wide + * operations that are ISA-specific. + */ + +#ifndef ASTC_VECMATHLIB_COMMON_4_H_INCLUDED +#define ASTC_VECMATHLIB_COMMON_4_H_INCLUDED + +#ifndef ASTCENC_SIMD_INLINE + #error "Include astcenc_vecmathlib.h, do not include directly" +#endif + +#include <cstdio> + +// ============================================================================ +// vmask4 operators and functions +// ============================================================================ + +/** + * @brief True if any lanes are enabled, false otherwise. + */ +ASTCENC_SIMD_INLINE bool any(vmask4 a) +{ + return mask(a) != 0; +} + +/** + * @brief True if all lanes are enabled, false otherwise. + */ +ASTCENC_SIMD_INLINE bool all(vmask4 a) +{ + return mask(a) == 0xF; +} + +// ============================================================================ +// vint4 operators and functions +// ============================================================================ + +/** + * @brief Overload: vector by scalar addition. + */ +ASTCENC_SIMD_INLINE vint4 operator+(vint4 a, int b) +{ + return a + vint4(b); +} + +/** + * @brief Overload: vector by vector incremental addition. + */ +ASTCENC_SIMD_INLINE vint4& operator+=(vint4& a, const vint4& b) +{ + a = a + b; + return a; +} + +/** + * @brief Overload: vector by scalar subtraction. + */ +ASTCENC_SIMD_INLINE vint4 operator-(vint4 a, int b) +{ + return a - vint4(b); +} + +/** + * @brief Overload: vector by scalar multiplication. + */ +ASTCENC_SIMD_INLINE vint4 operator*(vint4 a, int b) +{ + return a * vint4(b); +} + +/** + * @brief Overload: vector by scalar bitwise or. + */ +ASTCENC_SIMD_INLINE vint4 operator|(vint4 a, int b) +{ + return a | vint4(b); +} + +/** + * @brief Overload: vector by scalar bitwise and. + */ +ASTCENC_SIMD_INLINE vint4 operator&(vint4 a, int b) +{ + return a & vint4(b); +} + +/** + * @brief Overload: vector by scalar bitwise xor. + */ +ASTCENC_SIMD_INLINE vint4 operator^(vint4 a, int b) +{ + return a ^ vint4(b); +} + +/** + * @brief Return the clamped value between min and max. + */ +ASTCENC_SIMD_INLINE vint4 clamp(int minv, int maxv, vint4 a) +{ + return min(max(a, vint4(minv)), vint4(maxv)); +} + +/** + * @brief Return the horizontal sum of RGB vector lanes as a scalar. + */ +ASTCENC_SIMD_INLINE int hadd_rgb_s(vint4 a) +{ + return a.lane<0>() + a.lane<1>() + a.lane<2>(); +} + +// ============================================================================ +// vfloat4 operators and functions +// ============================================================================ + +/** + * @brief Overload: vector by vector incremental addition. + */ +ASTCENC_SIMD_INLINE vfloat4& operator+=(vfloat4& a, const vfloat4& b) +{ + a = a + b; + return a; +} + +/** + * @brief Overload: vector by scalar addition. + */ +ASTCENC_SIMD_INLINE vfloat4 operator+(vfloat4 a, float b) +{ + return a + vfloat4(b); +} + +/** + * @brief Overload: vector by scalar subtraction. + */ +ASTCENC_SIMD_INLINE vfloat4 operator-(vfloat4 a, float b) +{ + return a - vfloat4(b); +} + +/** + * @brief Overload: vector by scalar multiplication. + */ +ASTCENC_SIMD_INLINE vfloat4 operator*(vfloat4 a, float b) +{ + return a * vfloat4(b); +} + +/** + * @brief Overload: scalar by vector multiplication. + */ +ASTCENC_SIMD_INLINE vfloat4 operator*(float a, vfloat4 b) +{ + return vfloat4(a) * b; +} + +/** + * @brief Overload: vector by scalar division. + */ +ASTCENC_SIMD_INLINE vfloat4 operator/(vfloat4 a, float b) +{ + return a / vfloat4(b); +} + +/** + * @brief Overload: scalar by vector division. + */ +ASTCENC_SIMD_INLINE vfloat4 operator/(float a, vfloat4 b) +{ + return vfloat4(a) / b; +} + +/** + * @brief Return the min vector of a vector and a scalar. + * + * If either lane value is NaN, @c b will be returned for that lane. + */ +ASTCENC_SIMD_INLINE vfloat4 min(vfloat4 a, float b) +{ + return min(a, vfloat4(b)); +} + +/** + * @brief Return the max vector of a vector and a scalar. + * + * If either lane value is NaN, @c b will be returned for that lane. + */ +ASTCENC_SIMD_INLINE vfloat4 max(vfloat4 a, float b) +{ + return max(a, vfloat4(b)); +} + +/** + * @brief Return the clamped value between min and max. + * + * It is assumed that neither @c min nor @c max are NaN values. If @c a is NaN + * then @c min will be returned for that lane. + */ +ASTCENC_SIMD_INLINE vfloat4 clamp(float minv, float maxv, vfloat4 a) +{ + // Do not reorder - second operand will return if either is NaN + return min(max(a, minv), maxv); +} + +/** + * @brief Return the clamped value between 0.0f and max. + * + * It is assumed that @c max is not a NaN value. If @c a is NaN then zero will + * be returned for that lane. + */ +ASTCENC_SIMD_INLINE vfloat4 clampz(float maxv, vfloat4 a) +{ + // Do not reorder - second operand will return if either is NaN + return min(max(a, vfloat4::zero()), maxv); +} + +/** + * @brief Return the clamped value between 0.0f and 1.0f. + * + * If @c a is NaN then zero will be returned for that lane. + */ +ASTCENC_SIMD_INLINE vfloat4 clampzo(vfloat4 a) +{ + // Do not reorder - second operand will return if either is NaN + return min(max(a, vfloat4::zero()), 1.0f); +} + +/** + * @brief Return the horizontal minimum of a vector. + */ +ASTCENC_SIMD_INLINE float hmin_s(vfloat4 a) +{ + return hmin(a).lane<0>(); +} + +/** + * @brief Return the horizontal min of RGB vector lanes as a scalar. + */ +ASTCENC_SIMD_INLINE float hmin_rgb_s(vfloat4 a) +{ + a.set_lane<3>(a.lane<0>()); + return hmin_s(a); +} + +/** + * @brief Return the horizontal maximum of a vector. + */ +ASTCENC_SIMD_INLINE float hmax_s(vfloat4 a) +{ + return hmax(a).lane<0>(); +} + +/** + * @brief Accumulate lane-wise sums for a vector. + */ +ASTCENC_SIMD_INLINE void haccumulate(vfloat4& accum, vfloat4 a) +{ + accum = accum + a; +} + +/** + * @brief Accumulate lane-wise sums for a masked vector. + */ +ASTCENC_SIMD_INLINE void haccumulate(vfloat4& accum, vfloat4 a, vmask4 m) +{ + a = select(vfloat4::zero(), a, m); + haccumulate(accum, a); +} + +/** + * @brief Return the horizontal sum of RGB vector lanes as a scalar. + */ +ASTCENC_SIMD_INLINE float hadd_rgb_s(vfloat4 a) +{ + return a.lane<0>() + a.lane<1>() + a.lane<2>(); +} + +#if !defined(ASTCENC_USE_NATIVE_DOT_PRODUCT) + +/** + * @brief Return the dot product for the full 4 lanes, returning scalar. + */ +ASTCENC_SIMD_INLINE float dot_s(vfloat4 a, vfloat4 b) +{ + vfloat4 m = a * b; + return hadd_s(m); +} + +/** + * @brief Return the dot product for the full 4 lanes, returning vector. + */ +ASTCENC_SIMD_INLINE vfloat4 dot(vfloat4 a, vfloat4 b) +{ + vfloat4 m = a * b; + return vfloat4(hadd_s(m)); +} + +/** + * @brief Return the dot product for the bottom 3 lanes, returning scalar. + */ +ASTCENC_SIMD_INLINE float dot3_s(vfloat4 a, vfloat4 b) +{ + vfloat4 m = a * b; + return hadd_rgb_s(m); +} + +/** + * @brief Return the dot product for the bottom 3 lanes, returning vector. + */ +ASTCENC_SIMD_INLINE vfloat4 dot3(vfloat4 a, vfloat4 b) +{ + vfloat4 m = a * b; + float d3 = hadd_rgb_s(m); + return vfloat4(d3, d3, d3, 0.0f); +} + +#endif + +#if !defined(ASTCENC_USE_NATIVE_POPCOUNT) + +/** + * @brief Population bit count. + * + * @param v The value to population count. + * + * @return The number of 1 bits. + */ +static inline int popcount(uint64_t v) +{ + uint64_t mask1 = 0x5555555555555555ULL; + uint64_t mask2 = 0x3333333333333333ULL; + uint64_t mask3 = 0x0F0F0F0F0F0F0F0FULL; + v -= (v >> 1) & mask1; + v = (v & mask2) + ((v >> 2) & mask2); + v += v >> 4; + v &= mask3; + v *= 0x0101010101010101ULL; + v >>= 56; + return static_cast<int>(v); +} + +#endif + +/** + * @brief Apply signed bit transfer. + * + * @param input0 The first encoded endpoint. + * @param input1 The second encoded endpoint. + */ +static ASTCENC_SIMD_INLINE void bit_transfer_signed( + vint4& input0, + vint4& input1 +) { + input1 = lsr<1>(input1) | (input0 & 0x80); + input0 = lsr<1>(input0) & 0x3F; + + vmask4 mask = (input0 & 0x20) != vint4::zero(); + input0 = select(input0, input0 - 0x40, mask); +} + +/** + * @brief Debug function to print a vector of ints. + */ +ASTCENC_SIMD_INLINE void print(vint4 a) +{ + alignas(16) int v[4]; + storea(a, v); + printf("v4_i32:\n %8d %8d %8d %8d\n", + v[0], v[1], v[2], v[3]); +} + +/** + * @brief Debug function to print a vector of ints. + */ +ASTCENC_SIMD_INLINE void printx(vint4 a) +{ + alignas(16) int v[4]; + storea(a, v); + printf("v4_i32:\n %08x %08x %08x %08x\n", + v[0], v[1], v[2], v[3]); +} + +/** + * @brief Debug function to print a vector of floats. + */ +ASTCENC_SIMD_INLINE void print(vfloat4 a) +{ + alignas(16) float v[4]; + storea(a, v); + printf("v4_f32:\n %0.4f %0.4f %0.4f %0.4f\n", + static_cast<double>(v[0]), static_cast<double>(v[1]), + static_cast<double>(v[2]), static_cast<double>(v[3])); +} + +/** + * @brief Debug function to print a vector of masks. + */ +ASTCENC_SIMD_INLINE void print(vmask4 a) +{ + print(select(vint4(0), vint4(1), a)); +} + +#endif // #ifndef ASTC_VECMATHLIB_COMMON_4_H_INCLUDED diff --git a/thirdparty/astcenc/astcenc_vecmathlib_neon_4.h b/thirdparty/astcenc/astcenc_vecmathlib_neon_4.h new file mode 100644 index 0000000000..e742eae6cb --- /dev/null +++ b/thirdparty/astcenc/astcenc_vecmathlib_neon_4.h @@ -0,0 +1,1072 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2019-2022 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief 4x32-bit vectors, implemented using Armv8-A NEON. + * + * This module implements 4-wide 32-bit float, int, and mask vectors for + * Armv8-A NEON. + * + * There is a baseline level of functionality provided by all vector widths and + * implementations. This is implemented using identical function signatures, + * modulo data type, so we can use them as substitutable implementations in VLA + * code. + * + * The 4-wide vectors are also used as a fixed-width type, and significantly + * extend the functionality above that available to VLA code. + */ + +#ifndef ASTC_VECMATHLIB_NEON_4_H_INCLUDED +#define ASTC_VECMATHLIB_NEON_4_H_INCLUDED + +#ifndef ASTCENC_SIMD_INLINE + #error "Include astcenc_vecmathlib.h, do not include directly" +#endif + +#include <cstdio> + +// ============================================================================ +// vfloat4 data type +// ============================================================================ + +/** + * @brief Data type for 4-wide floats. + */ +struct vfloat4 +{ + /** + * @brief Construct from zero-initialized value. + */ + ASTCENC_SIMD_INLINE vfloat4() = default; + + /** + * @brief Construct from 4 values loaded from an unaligned address. + * + * Consider using loada() which is better with vectors if data is aligned + * to vector length. + */ + ASTCENC_SIMD_INLINE explicit vfloat4(const float *p) + { + m = vld1q_f32(p); + } + + /** + * @brief Construct from 1 scalar value replicated across all lanes. + * + * Consider using zero() for constexpr zeros. + */ + ASTCENC_SIMD_INLINE explicit vfloat4(float a) + { + m = vdupq_n_f32(a); + } + + /** + * @brief Construct from 4 scalar values. + * + * The value of @c a is stored to lane 0 (LSB) in the SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vfloat4(float a, float b, float c, float d) + { + float v[4] { a, b, c, d }; + m = vld1q_f32(v); + } + + /** + * @brief Construct from an existing SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vfloat4(float32x4_t a) + { + m = a; + } + + /** + * @brief Get the scalar value of a single lane. + */ + template <int l> ASTCENC_SIMD_INLINE float lane() const + { + return vgetq_lane_f32(m, l); + } + + /** + * @brief Set the scalar value of a single lane. + */ + template <int l> ASTCENC_SIMD_INLINE void set_lane(float a) + { + m = vsetq_lane_f32(a, m, l); + } + + /** + * @brief Factory that returns a vector of zeros. + */ + static ASTCENC_SIMD_INLINE vfloat4 zero() + { + return vfloat4(vdupq_n_f32(0.0f)); + } + + /** + * @brief Factory that returns a replicated scalar loaded from memory. + */ + static ASTCENC_SIMD_INLINE vfloat4 load1(const float* p) + { + return vfloat4(vld1q_dup_f32(p)); + } + + /** + * @brief Factory that returns a vector loaded from 16B aligned memory. + */ + static ASTCENC_SIMD_INLINE vfloat4 loada(const float* p) + { + return vfloat4(vld1q_f32(p)); + } + + /** + * @brief Factory that returns a vector containing the lane IDs. + */ + static ASTCENC_SIMD_INLINE vfloat4 lane_id() + { + alignas(16) float data[4] { 0.0f, 1.0f, 2.0f, 3.0f }; + return vfloat4(vld1q_f32(data)); + } + + /** + * @brief Return a swizzled float 2. + */ + template <int l0, int l1> ASTCENC_SIMD_INLINE vfloat4 swz() const + { + return vfloat4(lane<l0>(), lane<l1>(), 0.0f, 0.0f); + } + + /** + * @brief Return a swizzled float 3. + */ + template <int l0, int l1, int l2> ASTCENC_SIMD_INLINE vfloat4 swz() const + { + return vfloat4(lane<l0>(), lane<l1>(), lane<l2>(), 0.0f); + } + + /** + * @brief Return a swizzled float 4. + */ + template <int l0, int l1, int l2, int l3> ASTCENC_SIMD_INLINE vfloat4 swz() const + { + return vfloat4(lane<l0>(), lane<l1>(), lane<l2>(), lane<l3>()); + } + + /** + * @brief The vector ... + */ + float32x4_t m; +}; + +// ============================================================================ +// vint4 data type +// ============================================================================ + +/** + * @brief Data type for 4-wide ints. + */ +struct vint4 +{ + /** + * @brief Construct from zero-initialized value. + */ + ASTCENC_SIMD_INLINE vint4() = default; + + /** + * @brief Construct from 4 values loaded from an unaligned address. + * + * Consider using loada() which is better with vectors if data is aligned + * to vector length. + */ + ASTCENC_SIMD_INLINE explicit vint4(const int *p) + { + m = vld1q_s32(p); + } + + /** + * @brief Construct from 4 uint8_t loaded from an unaligned address. + */ + ASTCENC_SIMD_INLINE explicit vint4(const uint8_t *p) + { + // Cast is safe - NEON loads are allowed to be unaligned + uint32x2_t t8 = vld1_dup_u32(reinterpret_cast<const uint32_t*>(p)); + uint16x4_t t16 = vget_low_u16(vmovl_u8(vreinterpret_u8_u32(t8))); + m = vreinterpretq_s32_u32(vmovl_u16(t16)); + } + + /** + * @brief Construct from 1 scalar value replicated across all lanes. + * + * Consider using vfloat4::zero() for constexpr zeros. + */ + ASTCENC_SIMD_INLINE explicit vint4(int a) + { + m = vdupq_n_s32(a); + } + + /** + * @brief Construct from 4 scalar values. + * + * The value of @c a is stored to lane 0 (LSB) in the SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vint4(int a, int b, int c, int d) + { + int v[4] { a, b, c, d }; + m = vld1q_s32(v); + } + + /** + * @brief Construct from an existing SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vint4(int32x4_t a) + { + m = a; + } + + /** + * @brief Get the scalar from a single lane. + */ + template <int l> ASTCENC_SIMD_INLINE int lane() const + { + return vgetq_lane_s32(m, l); + } + + /** + * @brief Set the scalar value of a single lane. + */ + template <int l> ASTCENC_SIMD_INLINE void set_lane(int a) + { + m = vsetq_lane_s32(a, m, l); + } + + /** + * @brief Factory that returns a vector of zeros. + */ + static ASTCENC_SIMD_INLINE vint4 zero() + { + return vint4(0); + } + + /** + * @brief Factory that returns a replicated scalar loaded from memory. + */ + static ASTCENC_SIMD_INLINE vint4 load1(const int* p) + { + return vint4(*p); + } + + /** + * @brief Factory that returns a vector loaded from 16B aligned memory. + */ + static ASTCENC_SIMD_INLINE vint4 loada(const int* p) + { + return vint4(p); + } + + /** + * @brief Factory that returns a vector containing the lane IDs. + */ + static ASTCENC_SIMD_INLINE vint4 lane_id() + { + alignas(16) static const int data[4] { 0, 1, 2, 3 }; + return vint4(vld1q_s32(data)); + } + + /** + * @brief The vector ... + */ + int32x4_t m; +}; + +// ============================================================================ +// vmask4 data type +// ============================================================================ + +/** + * @brief Data type for 4-wide control plane masks. + */ +struct vmask4 +{ + /** + * @brief Construct from an existing SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vmask4(uint32x4_t a) + { + m = a; + } + +#if !defined(_MSC_VER) + /** + * @brief Construct from an existing SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vmask4(int32x4_t a) + { + m = vreinterpretq_u32_s32(a); + } +#endif + + /** + * @brief Construct from 1 scalar value. + */ + ASTCENC_SIMD_INLINE explicit vmask4(bool a) + { + m = vreinterpretq_u32_s32(vdupq_n_s32(a == true ? -1 : 0)); + } + + /** + * @brief Construct from 4 scalar values. + * + * The value of @c a is stored to lane 0 (LSB) in the SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vmask4(bool a, bool b, bool c, bool d) + { + int v[4] { + a == true ? -1 : 0, + b == true ? -1 : 0, + c == true ? -1 : 0, + d == true ? -1 : 0 + }; + + int32x4_t ms = vld1q_s32(v); + m = vreinterpretq_u32_s32(ms); + } + + /** + * @brief Get the scalar from a single lane. + */ + template <int32_t l> ASTCENC_SIMD_INLINE uint32_t lane() const + { + return vgetq_lane_u32(m, l); + } + + /** + * @brief The vector ... + */ + uint32x4_t m; +}; + +// ============================================================================ +// vmask4 operators and functions +// ============================================================================ + +/** + * @brief Overload: mask union (or). + */ +ASTCENC_SIMD_INLINE vmask4 operator|(vmask4 a, vmask4 b) +{ + return vmask4(vorrq_u32(a.m, b.m)); +} + +/** + * @brief Overload: mask intersect (and). + */ +ASTCENC_SIMD_INLINE vmask4 operator&(vmask4 a, vmask4 b) +{ + return vmask4(vandq_u32(a.m, b.m)); +} + +/** + * @brief Overload: mask difference (xor). + */ +ASTCENC_SIMD_INLINE vmask4 operator^(vmask4 a, vmask4 b) +{ + return vmask4(veorq_u32(a.m, b.m)); +} + +/** + * @brief Overload: mask invert (not). + */ +ASTCENC_SIMD_INLINE vmask4 operator~(vmask4 a) +{ + return vmask4(vmvnq_u32(a.m)); +} + +/** + * @brief Return a 4-bit mask code indicating mask status. + * + * bit0 = lane 0 + */ +ASTCENC_SIMD_INLINE unsigned int mask(vmask4 a) +{ + static const int shifta[4] { 0, 1, 2, 3 }; + static const int32x4_t shift = vld1q_s32(shifta); + + uint32x4_t tmp = vshrq_n_u32(a.m, 31); + return vaddvq_u32(vshlq_u32(tmp, shift)); +} + +// ============================================================================ +// vint4 operators and functions +// ============================================================================ + +/** + * @brief Overload: vector by vector addition. + */ +ASTCENC_SIMD_INLINE vint4 operator+(vint4 a, vint4 b) +{ + return vint4(vaddq_s32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector subtraction. + */ +ASTCENC_SIMD_INLINE vint4 operator-(vint4 a, vint4 b) +{ + return vint4(vsubq_s32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector multiplication. + */ +ASTCENC_SIMD_INLINE vint4 operator*(vint4 a, vint4 b) +{ + return vint4(vmulq_s32(a.m, b.m)); +} + +/** + * @brief Overload: vector bit invert. + */ +ASTCENC_SIMD_INLINE vint4 operator~(vint4 a) +{ + return vint4(vmvnq_s32(a.m)); +} + +/** + * @brief Overload: vector by vector bitwise or. + */ +ASTCENC_SIMD_INLINE vint4 operator|(vint4 a, vint4 b) +{ + return vint4(vorrq_s32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector bitwise and. + */ +ASTCENC_SIMD_INLINE vint4 operator&(vint4 a, vint4 b) +{ + return vint4(vandq_s32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector bitwise xor. + */ +ASTCENC_SIMD_INLINE vint4 operator^(vint4 a, vint4 b) +{ + return vint4(veorq_s32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector equality. + */ +ASTCENC_SIMD_INLINE vmask4 operator==(vint4 a, vint4 b) +{ + return vmask4(vceqq_s32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector inequality. + */ +ASTCENC_SIMD_INLINE vmask4 operator!=(vint4 a, vint4 b) +{ + return ~vmask4(vceqq_s32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector less than. + */ +ASTCENC_SIMD_INLINE vmask4 operator<(vint4 a, vint4 b) +{ + return vmask4(vcltq_s32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector greater than. + */ +ASTCENC_SIMD_INLINE vmask4 operator>(vint4 a, vint4 b) +{ + return vmask4(vcgtq_s32(a.m, b.m)); +} + +/** + * @brief Logical shift left. + */ +template <int s> ASTCENC_SIMD_INLINE vint4 lsl(vint4 a) +{ + return vint4(vshlq_s32(a.m, vdupq_n_s32(s))); +} + +/** + * @brief Logical shift right. + */ +template <int s> ASTCENC_SIMD_INLINE vint4 lsr(vint4 a) +{ + uint32x4_t ua = vreinterpretq_u32_s32(a.m); + ua = vshlq_u32(ua, vdupq_n_s32(-s)); + return vint4(vreinterpretq_s32_u32(ua)); +} + +/** + * @brief Arithmetic shift right. + */ +template <int s> ASTCENC_SIMD_INLINE vint4 asr(vint4 a) +{ + return vint4(vshlq_s32(a.m, vdupq_n_s32(-s))); +} + +/** + * @brief Return the min vector of two vectors. + */ +ASTCENC_SIMD_INLINE vint4 min(vint4 a, vint4 b) +{ + return vint4(vminq_s32(a.m, b.m)); +} + +/** + * @brief Return the max vector of two vectors. + */ +ASTCENC_SIMD_INLINE vint4 max(vint4 a, vint4 b) +{ + return vint4(vmaxq_s32(a.m, b.m)); +} + +/** + * @brief Return the horizontal minimum of a vector. + */ +ASTCENC_SIMD_INLINE vint4 hmin(vint4 a) +{ + return vint4(vminvq_s32(a.m)); +} + +/** + * @brief Return the horizontal maximum of a vector. + */ +ASTCENC_SIMD_INLINE vint4 hmax(vint4 a) +{ + return vint4(vmaxvq_s32(a.m)); +} + +/** + * @brief Return the horizontal sum of a vector. + */ +ASTCENC_SIMD_INLINE int hadd_s(vint4 a) +{ + int32x2_t t = vadd_s32(vget_high_s32(a.m), vget_low_s32(a.m)); + return vget_lane_s32(vpadd_s32(t, t), 0); +} + +/** + * @brief Store a vector to a 16B aligned memory address. + */ +ASTCENC_SIMD_INLINE void storea(vint4 a, int* p) +{ + vst1q_s32(p, a.m); +} + +/** + * @brief Store a vector to an unaligned memory address. + */ +ASTCENC_SIMD_INLINE void store(vint4 a, int* p) +{ + vst1q_s32(p, a.m); +} + +/** + * @brief Store lowest N (vector width) bytes into an unaligned address. + */ +ASTCENC_SIMD_INLINE void store_nbytes(vint4 a, uint8_t* p) +{ + vst1q_lane_s32(reinterpret_cast<int32_t*>(p), a.m, 0); +} + +/** + * @brief Gather N (vector width) indices from the array. + */ +ASTCENC_SIMD_INLINE vint4 gatheri(const int* base, vint4 indices) +{ + alignas(16) int idx[4]; + storea(indices, idx); + alignas(16) int vals[4]; + vals[0] = base[idx[0]]; + vals[1] = base[idx[1]]; + vals[2] = base[idx[2]]; + vals[3] = base[idx[3]]; + return vint4(vals); +} + +/** + * @brief Pack low 8 bits of N (vector width) lanes into bottom of vector. + */ +ASTCENC_SIMD_INLINE vint4 pack_low_bytes(vint4 a) +{ + alignas(16) uint8_t shuf[16] { + 0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + uint8x16_t idx = vld1q_u8(shuf); + int8x16_t av = vreinterpretq_s8_s32(a.m); + return vint4(vreinterpretq_s32_s8(vqtbl1q_s8(av, idx))); +} + +/** + * @brief Return lanes from @c b if @c cond is set, else @c a. + */ +ASTCENC_SIMD_INLINE vint4 select(vint4 a, vint4 b, vmask4 cond) +{ + return vint4(vbslq_s32(cond.m, b.m, a.m)); +} + +// ============================================================================ +// vfloat4 operators and functions +// ============================================================================ + +/** + * @brief Overload: vector by vector addition. + */ +ASTCENC_SIMD_INLINE vfloat4 operator+(vfloat4 a, vfloat4 b) +{ + return vfloat4(vaddq_f32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector subtraction. + */ +ASTCENC_SIMD_INLINE vfloat4 operator-(vfloat4 a, vfloat4 b) +{ + return vfloat4(vsubq_f32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector multiplication. + */ +ASTCENC_SIMD_INLINE vfloat4 operator*(vfloat4 a, vfloat4 b) +{ + return vfloat4(vmulq_f32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector division. + */ +ASTCENC_SIMD_INLINE vfloat4 operator/(vfloat4 a, vfloat4 b) +{ + return vfloat4(vdivq_f32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector equality. + */ +ASTCENC_SIMD_INLINE vmask4 operator==(vfloat4 a, vfloat4 b) +{ + return vmask4(vceqq_f32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector inequality. + */ +ASTCENC_SIMD_INLINE vmask4 operator!=(vfloat4 a, vfloat4 b) +{ + return vmask4(vmvnq_u32(vceqq_f32(a.m, b.m))); +} + +/** + * @brief Overload: vector by vector less than. + */ +ASTCENC_SIMD_INLINE vmask4 operator<(vfloat4 a, vfloat4 b) +{ + return vmask4(vcltq_f32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector greater than. + */ +ASTCENC_SIMD_INLINE vmask4 operator>(vfloat4 a, vfloat4 b) +{ + return vmask4(vcgtq_f32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector less than or equal. + */ +ASTCENC_SIMD_INLINE vmask4 operator<=(vfloat4 a, vfloat4 b) +{ + return vmask4(vcleq_f32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector greater than or equal. + */ +ASTCENC_SIMD_INLINE vmask4 operator>=(vfloat4 a, vfloat4 b) +{ + return vmask4(vcgeq_f32(a.m, b.m)); +} + +/** + * @brief Return the min vector of two vectors. + * + * If either lane value is NaN, @c b will be returned for that lane. + */ +ASTCENC_SIMD_INLINE vfloat4 min(vfloat4 a, vfloat4 b) +{ + // Do not reorder - second operand will return if either is NaN + return vfloat4(vminnmq_f32(a.m, b.m)); +} + +/** + * @brief Return the max vector of two vectors. + * + * If either lane value is NaN, @c b will be returned for that lane. + */ +ASTCENC_SIMD_INLINE vfloat4 max(vfloat4 a, vfloat4 b) +{ + // Do not reorder - second operand will return if either is NaN + return vfloat4(vmaxnmq_f32(a.m, b.m)); +} + +/** + * @brief Return the absolute value of the float vector. + */ +ASTCENC_SIMD_INLINE vfloat4 abs(vfloat4 a) +{ + float32x4_t zero = vdupq_n_f32(0.0f); + float32x4_t inv = vsubq_f32(zero, a.m); + return vfloat4(vmaxq_f32(a.m, inv)); +} + +/** + * @brief Return a float rounded to the nearest integer value. + */ +ASTCENC_SIMD_INLINE vfloat4 round(vfloat4 a) +{ + return vfloat4(vrndnq_f32(a.m)); +} + +/** + * @brief Return the horizontal minimum of a vector. + */ +ASTCENC_SIMD_INLINE vfloat4 hmin(vfloat4 a) +{ + return vfloat4(vminvq_f32(a.m)); +} + +/** + * @brief Return the horizontal maximum of a vector. + */ +ASTCENC_SIMD_INLINE vfloat4 hmax(vfloat4 a) +{ + return vfloat4(vmaxvq_f32(a.m)); +} + +/** + * @brief Return the horizontal sum of a vector. + */ +ASTCENC_SIMD_INLINE float hadd_s(vfloat4 a) +{ + // Perform halving add to ensure invariance; we cannot use vaddqv as this + // does (0 + 1 + 2 + 3) which is not invariant with x86 (0 + 2) + (1 + 3). + float32x2_t t = vadd_f32(vget_high_f32(a.m), vget_low_f32(a.m)); + return vget_lane_f32(vpadd_f32(t, t), 0); +} + +/** + * @brief Return the sqrt of the lanes in the vector. + */ +ASTCENC_SIMD_INLINE vfloat4 sqrt(vfloat4 a) +{ + return vfloat4(vsqrtq_f32(a.m)); +} + +/** + * @brief Return lanes from @c b if @c cond is set, else @c a. + */ +ASTCENC_SIMD_INLINE vfloat4 select(vfloat4 a, vfloat4 b, vmask4 cond) +{ + return vfloat4(vbslq_f32(cond.m, b.m, a.m)); +} + +/** + * @brief Return lanes from @c b if MSB of @c cond is set, else @c a. + */ +ASTCENC_SIMD_INLINE vfloat4 select_msb(vfloat4 a, vfloat4 b, vmask4 cond) +{ + static const uint32x4_t msb = vdupq_n_u32(0x80000000u); + uint32x4_t mask = vcgeq_u32(cond.m, msb); + return vfloat4(vbslq_f32(mask, b.m, a.m)); +} + +/** + * @brief Load a vector of gathered results from an array; + */ +ASTCENC_SIMD_INLINE vfloat4 gatherf(const float* base, vint4 indices) +{ + alignas(16) int idx[4]; + storea(indices, idx); + alignas(16) float vals[4]; + vals[0] = base[idx[0]]; + vals[1] = base[idx[1]]; + vals[2] = base[idx[2]]; + vals[3] = base[idx[3]]; + return vfloat4(vals); +} + +/** + * @brief Store a vector to an unaligned memory address. + */ +ASTCENC_SIMD_INLINE void store(vfloat4 a, float* p) +{ + vst1q_f32(p, a.m); +} + +/** + * @brief Store a vector to a 16B aligned memory address. + */ +ASTCENC_SIMD_INLINE void storea(vfloat4 a, float* p) +{ + vst1q_f32(p, a.m); +} + +/** + * @brief Return a integer value for a float vector, using truncation. + */ +ASTCENC_SIMD_INLINE vint4 float_to_int(vfloat4 a) +{ + return vint4(vcvtq_s32_f32(a.m)); +} + +/** + * @brief Return a integer value for a float vector, using round-to-nearest. + */ +ASTCENC_SIMD_INLINE vint4 float_to_int_rtn(vfloat4 a) +{ + a = round(a); + return vint4(vcvtq_s32_f32(a.m)); +} + +/** + * @brief Return a float value for an integer vector. + */ +ASTCENC_SIMD_INLINE vfloat4 int_to_float(vint4 a) +{ + return vfloat4(vcvtq_f32_s32(a.m)); +} + +/** + * @brief Return a float16 value for a float vector, using round-to-nearest. + */ +ASTCENC_SIMD_INLINE vint4 float_to_float16(vfloat4 a) +{ + // Generate float16 value + float16x4_t f16 = vcvt_f16_f32(a.m); + + // Convert each 16-bit float pattern to a 32-bit pattern + uint16x4_t u16 = vreinterpret_u16_f16(f16); + uint32x4_t u32 = vmovl_u16(u16); + return vint4(vreinterpretq_s32_u32(u32)); +} + +/** + * @brief Return a float16 value for a float scalar, using round-to-nearest. + */ +static inline uint16_t float_to_float16(float a) +{ + vfloat4 av(a); + return static_cast<uint16_t>(float_to_float16(av).lane<0>()); +} + +/** + * @brief Return a float value for a float16 vector. + */ +ASTCENC_SIMD_INLINE vfloat4 float16_to_float(vint4 a) +{ + // Convert each 32-bit float pattern to a 16-bit pattern + uint32x4_t u32 = vreinterpretq_u32_s32(a.m); + uint16x4_t u16 = vmovn_u32(u32); + float16x4_t f16 = vreinterpret_f16_u16(u16); + + // Generate float16 value + return vfloat4(vcvt_f32_f16(f16)); +} + +/** + * @brief Return a float value for a float16 scalar. + */ +ASTCENC_SIMD_INLINE float float16_to_float(uint16_t a) +{ + vint4 av(a); + return float16_to_float(av).lane<0>(); +} + +/** + * @brief Return a float value as an integer bit pattern (i.e. no conversion). + * + * It is a common trick to convert floats into integer bit patterns, perform + * some bit hackery based on knowledge they are IEEE 754 layout, and then + * convert them back again. This is the first half of that flip. + */ +ASTCENC_SIMD_INLINE vint4 float_as_int(vfloat4 a) +{ + return vint4(vreinterpretq_s32_f32(a.m)); +} + +/** + * @brief Return a integer value as a float bit pattern (i.e. no conversion). + * + * It is a common trick to convert floats into integer bit patterns, perform + * some bit hackery based on knowledge they are IEEE 754 layout, and then + * convert them back again. This is the second half of that flip. + */ +ASTCENC_SIMD_INLINE vfloat4 int_as_float(vint4 v) +{ + return vfloat4(vreinterpretq_f32_s32(v.m)); +} + +/** + * @brief Prepare a vtable lookup table for use with the native SIMD size. + */ +ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4& t0p) +{ + t0p = t0; +} + + +/** + * @brief Prepare a vtable lookup table for use with the native SIMD size. + */ +ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4 t1, vint4& t0p, vint4& t1p) +{ + t0p = t0; + t1p = t1; +} + +/** + * @brief Prepare a vtable lookup table for use with the native SIMD size. + */ +ASTCENC_SIMD_INLINE void vtable_prepare( + vint4 t0, vint4 t1, vint4 t2, vint4 t3, + vint4& t0p, vint4& t1p, vint4& t2p, vint4& t3p) +{ + t0p = t0; + t1p = t1; + t2p = t2; + t3p = t3; +} + +/** + * @brief Perform an 8-bit 16-entry table lookup, with 32-bit indexes. + */ +ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 idx) +{ + int8x16_t table { + vreinterpretq_s8_s32(t0.m) + }; + + // Set index byte above max index for unused bytes so table lookup returns zero + int32x4_t idx_masked = vorrq_s32(idx.m, vdupq_n_s32(0xFFFFFF00)); + uint8x16_t idx_bytes = vreinterpretq_u8_s32(idx_masked); + + return vint4(vreinterpretq_s32_s8(vqtbl1q_s8(table, idx_bytes))); +} + +/** + * @brief Perform an 8-bit 32-entry table lookup, with 32-bit indexes. + */ +ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 idx) +{ + int8x16x2_t table { + vreinterpretq_s8_s32(t0.m), + vreinterpretq_s8_s32(t1.m) + }; + + // Set index byte above max index for unused bytes so table lookup returns zero + int32x4_t idx_masked = vorrq_s32(idx.m, vdupq_n_s32(0xFFFFFF00)); + uint8x16_t idx_bytes = vreinterpretq_u8_s32(idx_masked); + + return vint4(vreinterpretq_s32_s8(vqtbl2q_s8(table, idx_bytes))); +} + +/** + * @brief Perform an 8-bit 64-entry table lookup, with 32-bit indexes. + */ +ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 t2, vint4 t3, vint4 idx) +{ + int8x16x4_t table { + vreinterpretq_s8_s32(t0.m), + vreinterpretq_s8_s32(t1.m), + vreinterpretq_s8_s32(t2.m), + vreinterpretq_s8_s32(t3.m) + }; + + // Set index byte above max index for unused bytes so table lookup returns zero + int32x4_t idx_masked = vorrq_s32(idx.m, vdupq_n_s32(0xFFFFFF00)); + uint8x16_t idx_bytes = vreinterpretq_u8_s32(idx_masked); + + return vint4(vreinterpretq_s32_s8(vqtbl4q_s8(table, idx_bytes))); +} + +/** + * @brief Return a vector of interleaved RGBA data. + * + * Input vectors have the value stored in the bottom 8 bits of each lane, + * with high bits set to zero. + * + * Output vector stores a single RGBA texel packed in each lane. + */ +ASTCENC_SIMD_INLINE vint4 interleave_rgba8(vint4 r, vint4 g, vint4 b, vint4 a) +{ + return r + lsl<8>(g) + lsl<16>(b) + lsl<24>(a); +} + +/** + * @brief Store a vector, skipping masked lanes. + * + * All masked lanes must be at the end of vector, after all non-masked lanes. + */ +ASTCENC_SIMD_INLINE void store_lanes_masked(int* base, vint4 data, vmask4 mask) +{ + if (mask.lane<3>()) + { + store(data, base); + } + else if (mask.lane<2>()) + { + base[0] = data.lane<0>(); + base[1] = data.lane<1>(); + base[2] = data.lane<2>(); + } + else if (mask.lane<1>()) + { + base[0] = data.lane<0>(); + base[1] = data.lane<1>(); + } + else if (mask.lane<0>()) + { + base[0] = data.lane<0>(); + } +} + +#define ASTCENC_USE_NATIVE_POPCOUNT 1 + +/** + * @brief Population bit count. + * + * @param v The value to population count. + * + * @return The number of 1 bits. + */ +ASTCENC_SIMD_INLINE int popcount(uint64_t v) +{ + return static_cast<int>(vaddlv_u8(vcnt_u8(vcreate_u8(v)))); +} + +#endif // #ifndef ASTC_VECMATHLIB_NEON_4_H_INCLUDED diff --git a/thirdparty/astcenc/astcenc_vecmathlib_none_4.h b/thirdparty/astcenc/astcenc_vecmathlib_none_4.h new file mode 100644 index 0000000000..d9b52be3e4 --- /dev/null +++ b/thirdparty/astcenc/astcenc_vecmathlib_none_4.h @@ -0,0 +1,1169 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2019-2022 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief 4x32-bit vectors, implemented using plain C++. + * + * This module implements 4-wide 32-bit float, int, and mask vectors. This + * module provides a scalar fallback for VLA code, primarily useful for + * debugging VLA algorithms without the complexity of handling SIMD. Only the + * baseline level of functionality needed to support VLA is provided. + * + * Note that the vector conditional operators implemented by this module are + * designed to behave like SIMD conditional operators that generate lane masks. + * Rather than returning 0/1 booleans like normal C++ code they will return + * 0/-1 to give a full lane-width bitmask. + * + * Note that the documentation for this module still talks about "vectors" to + * help developers think about the implied VLA behavior when writing optimized + * paths. + */ + +#ifndef ASTC_VECMATHLIB_NONE_4_H_INCLUDED +#define ASTC_VECMATHLIB_NONE_4_H_INCLUDED + +#ifndef ASTCENC_SIMD_INLINE + #error "Include astcenc_vecmathlib.h, do not include directly" +#endif + +#include <algorithm> +#include <cstdio> +#include <cstring> +#include <cfenv> + +// ============================================================================ +// vfloat4 data type +// ============================================================================ + +/** + * @brief Data type for 4-wide floats. + */ +struct vfloat4 +{ + /** + * @brief Construct from zero-initialized value. + */ + ASTCENC_SIMD_INLINE vfloat4() = default; + + /** + * @brief Construct from 4 values loaded from an unaligned address. + * + * Consider using loada() which is better with wider VLA vectors if data is + * aligned to vector length. + */ + ASTCENC_SIMD_INLINE explicit vfloat4(const float* p) + { + m[0] = p[0]; + m[1] = p[1]; + m[2] = p[2]; + m[3] = p[3]; + } + + /** + * @brief Construct from 4 scalar values replicated across all lanes. + * + * Consider using zero() for constexpr zeros. + */ + ASTCENC_SIMD_INLINE explicit vfloat4(float a) + { + m[0] = a; + m[1] = a; + m[2] = a; + m[3] = a; + } + + /** + * @brief Construct from 4 scalar values. + * + * The value of @c a is stored to lane 0 (LSB) in the SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vfloat4(float a, float b, float c, float d) + { + m[0] = a; + m[1] = b; + m[2] = c; + m[3] = d; + } + + /** + * @brief Get the scalar value of a single lane. + */ + template <int l> ASTCENC_SIMD_INLINE float lane() const + { + return m[l]; + } + + /** + * @brief Set the scalar value of a single lane. + */ + template <int l> ASTCENC_SIMD_INLINE void set_lane(float a) + { + m[l] = a; + } + + /** + * @brief Factory that returns a vector of zeros. + */ + static ASTCENC_SIMD_INLINE vfloat4 zero() + { + return vfloat4(0.0f); + } + + /** + * @brief Factory that returns a replicated scalar loaded from memory. + */ + static ASTCENC_SIMD_INLINE vfloat4 load1(const float* p) + { + return vfloat4(*p); + } + + /** + * @brief Factory that returns a vector loaded from aligned memory. + */ + static ASTCENC_SIMD_INLINE vfloat4 loada(const float* p) + { + return vfloat4(p); + } + + /** + * @brief Factory that returns a vector containing the lane IDs. + */ + static ASTCENC_SIMD_INLINE vfloat4 lane_id() + { + return vfloat4(0.0f, 1.0f, 2.0f, 3.0f); + } + + /** + * @brief Return a swizzled float 2. + */ + template <int l0, int l1> ASTCENC_SIMD_INLINE vfloat4 swz() const + { + return vfloat4(lane<l0>(), lane<l1>(), 0.0f, 0.0f); + } + + /** + * @brief Return a swizzled float 3. + */ + template <int l0, int l1, int l2> ASTCENC_SIMD_INLINE vfloat4 swz() const + { + return vfloat4(lane<l0>(), lane<l1>(), lane<l2>(), 0.0f); + } + + /** + * @brief Return a swizzled float 4. + */ + template <int l0, int l1, int l2, int l3> ASTCENC_SIMD_INLINE vfloat4 swz() const + { + return vfloat4(lane<l0>(), lane<l1>(), lane<l2>(), lane<l3>()); + } + + /** + * @brief The vector ... + */ + float m[4]; +}; + +// ============================================================================ +// vint4 data type +// ============================================================================ + +/** + * @brief Data type for 4-wide ints. + */ +struct vint4 +{ + /** + * @brief Construct from zero-initialized value. + */ + ASTCENC_SIMD_INLINE vint4() = default; + + /** + * @brief Construct from 4 values loaded from an unaligned address. + * + * Consider using vint4::loada() which is better with wider VLA vectors + * if data is aligned. + */ + ASTCENC_SIMD_INLINE explicit vint4(const int* p) + { + m[0] = p[0]; + m[1] = p[1]; + m[2] = p[2]; + m[3] = p[3]; + } + + /** + * @brief Construct from 4 uint8_t loaded from an unaligned address. + */ + ASTCENC_SIMD_INLINE explicit vint4(const uint8_t *p) + { + m[0] = p[0]; + m[1] = p[1]; + m[2] = p[2]; + m[3] = p[3]; + } + + /** + * @brief Construct from 4 scalar values. + * + * The value of @c a is stored to lane 0 (LSB) in the SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vint4(int a, int b, int c, int d) + { + m[0] = a; + m[1] = b; + m[2] = c; + m[3] = d; + } + + + /** + * @brief Construct from 4 scalar values replicated across all lanes. + * + * Consider using vint4::zero() for constexpr zeros. + */ + ASTCENC_SIMD_INLINE explicit vint4(int a) + { + m[0] = a; + m[1] = a; + m[2] = a; + m[3] = a; + } + + /** + * @brief Get the scalar value of a single lane. + */ + template <int l> ASTCENC_SIMD_INLINE int lane() const + { + return m[l]; + } + + /** + * @brief Set the scalar value of a single lane. + */ + template <int l> ASTCENC_SIMD_INLINE void set_lane(int a) + { + m[l] = a; + } + + /** + * @brief Factory that returns a vector of zeros. + */ + static ASTCENC_SIMD_INLINE vint4 zero() + { + return vint4(0); + } + + /** + * @brief Factory that returns a replicated scalar loaded from memory. + */ + static ASTCENC_SIMD_INLINE vint4 load1(const int* p) + { + return vint4(*p); + } + + /** + * @brief Factory that returns a vector loaded from 16B aligned memory. + */ + static ASTCENC_SIMD_INLINE vint4 loada(const int* p) + { + return vint4(p); + } + + /** + * @brief Factory that returns a vector containing the lane IDs. + */ + static ASTCENC_SIMD_INLINE vint4 lane_id() + { + return vint4(0, 1, 2, 3); + } + + /** + * @brief The vector ... + */ + int m[4]; +}; + +// ============================================================================ +// vmask4 data type +// ============================================================================ + +/** + * @brief Data type for 4-wide control plane masks. + */ +struct vmask4 +{ + /** + * @brief Construct from an existing mask value. + */ + ASTCENC_SIMD_INLINE explicit vmask4(int* p) + { + m[0] = p[0]; + m[1] = p[1]; + m[2] = p[2]; + m[3] = p[3]; + } + + /** + * @brief Construct from 1 scalar value. + */ + ASTCENC_SIMD_INLINE explicit vmask4(bool a) + { + m[0] = a == false ? 0 : -1; + m[1] = a == false ? 0 : -1; + m[2] = a == false ? 0 : -1; + m[3] = a == false ? 0 : -1; + } + + /** + * @brief Construct from 4 scalar values. + * + * The value of @c a is stored to lane 0 (LSB) in the SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vmask4(bool a, bool b, bool c, bool d) + { + m[0] = a == false ? 0 : -1; + m[1] = b == false ? 0 : -1; + m[2] = c == false ? 0 : -1; + m[3] = d == false ? 0 : -1; + } + + + /** + * @brief The vector ... + */ + int m[4]; +}; + +// ============================================================================ +// vmask4 operators and functions +// ============================================================================ + +/** + * @brief Overload: mask union (or). + */ +ASTCENC_SIMD_INLINE vmask4 operator|(vmask4 a, vmask4 b) +{ + return vmask4(a.m[0] | b.m[0], + a.m[1] | b.m[1], + a.m[2] | b.m[2], + a.m[3] | b.m[3]); +} + +/** + * @brief Overload: mask intersect (and). + */ +ASTCENC_SIMD_INLINE vmask4 operator&(vmask4 a, vmask4 b) +{ + return vmask4(a.m[0] & b.m[0], + a.m[1] & b.m[1], + a.m[2] & b.m[2], + a.m[3] & b.m[3]); +} + +/** + * @brief Overload: mask difference (xor). + */ +ASTCENC_SIMD_INLINE vmask4 operator^(vmask4 a, vmask4 b) +{ + return vmask4(a.m[0] ^ b.m[0], + a.m[1] ^ b.m[1], + a.m[2] ^ b.m[2], + a.m[3] ^ b.m[3]); +} + +/** + * @brief Overload: mask invert (not). + */ +ASTCENC_SIMD_INLINE vmask4 operator~(vmask4 a) +{ + return vmask4(~a.m[0], + ~a.m[1], + ~a.m[2], + ~a.m[3]); +} + +/** + * @brief Return a 1-bit mask code indicating mask status. + * + * bit0 = lane 0 + */ +ASTCENC_SIMD_INLINE unsigned int mask(vmask4 a) +{ + return ((a.m[0] >> 31) & 0x1) | + ((a.m[1] >> 30) & 0x2) | + ((a.m[2] >> 29) & 0x4) | + ((a.m[3] >> 28) & 0x8); +} + +// ============================================================================ +// vint4 operators and functions +// ============================================================================ + +/** + * @brief Overload: vector by vector addition. + */ +ASTCENC_SIMD_INLINE vint4 operator+(vint4 a, vint4 b) +{ + return vint4(a.m[0] + b.m[0], + a.m[1] + b.m[1], + a.m[2] + b.m[2], + a.m[3] + b.m[3]); +} + +/** + * @brief Overload: vector by vector subtraction. + */ +ASTCENC_SIMD_INLINE vint4 operator-(vint4 a, vint4 b) +{ + return vint4(a.m[0] - b.m[0], + a.m[1] - b.m[1], + a.m[2] - b.m[2], + a.m[3] - b.m[3]); +} + +/** + * @brief Overload: vector by vector multiplication. + */ +ASTCENC_SIMD_INLINE vint4 operator*(vint4 a, vint4 b) +{ + return vint4(a.m[0] * b.m[0], + a.m[1] * b.m[1], + a.m[2] * b.m[2], + a.m[3] * b.m[3]); +} + +/** + * @brief Overload: vector bit invert. + */ +ASTCENC_SIMD_INLINE vint4 operator~(vint4 a) +{ + return vint4(~a.m[0], + ~a.m[1], + ~a.m[2], + ~a.m[3]); +} + +/** + * @brief Overload: vector by vector bitwise or. + */ +ASTCENC_SIMD_INLINE vint4 operator|(vint4 a, vint4 b) +{ + return vint4(a.m[0] | b.m[0], + a.m[1] | b.m[1], + a.m[2] | b.m[2], + a.m[3] | b.m[3]); +} + +/** + * @brief Overload: vector by vector bitwise and. + */ +ASTCENC_SIMD_INLINE vint4 operator&(vint4 a, vint4 b) +{ + return vint4(a.m[0] & b.m[0], + a.m[1] & b.m[1], + a.m[2] & b.m[2], + a.m[3] & b.m[3]); +} + +/** + * @brief Overload: vector by vector bitwise xor. + */ +ASTCENC_SIMD_INLINE vint4 operator^(vint4 a, vint4 b) +{ + return vint4(a.m[0] ^ b.m[0], + a.m[1] ^ b.m[1], + a.m[2] ^ b.m[2], + a.m[3] ^ b.m[3]); +} + +/** + * @brief Overload: vector by vector equality. + */ +ASTCENC_SIMD_INLINE vmask4 operator==(vint4 a, vint4 b) +{ + return vmask4(a.m[0] == b.m[0], + a.m[1] == b.m[1], + a.m[2] == b.m[2], + a.m[3] == b.m[3]); +} + +/** + * @brief Overload: vector by vector inequality. + */ +ASTCENC_SIMD_INLINE vmask4 operator!=(vint4 a, vint4 b) +{ + return vmask4(a.m[0] != b.m[0], + a.m[1] != b.m[1], + a.m[2] != b.m[2], + a.m[3] != b.m[3]); +} + +/** + * @brief Overload: vector by vector less than. + */ +ASTCENC_SIMD_INLINE vmask4 operator<(vint4 a, vint4 b) +{ + return vmask4(a.m[0] < b.m[0], + a.m[1] < b.m[1], + a.m[2] < b.m[2], + a.m[3] < b.m[3]); +} + +/** + * @brief Overload: vector by vector greater than. + */ +ASTCENC_SIMD_INLINE vmask4 operator>(vint4 a, vint4 b) +{ + return vmask4(a.m[0] > b.m[0], + a.m[1] > b.m[1], + a.m[2] > b.m[2], + a.m[3] > b.m[3]); +} + +/** + * @brief Logical shift left. + */ +template <int s> ASTCENC_SIMD_INLINE vint4 lsl(vint4 a) +{ + return vint4(a.m[0] << s, + a.m[1] << s, + a.m[2] << s, + a.m[3] << s); +} + +/** + * @brief Logical shift right. + */ +template <int s> ASTCENC_SIMD_INLINE vint4 lsr(vint4 a) +{ + unsigned int as0 = static_cast<unsigned int>(a.m[0]) >> s; + unsigned int as1 = static_cast<unsigned int>(a.m[1]) >> s; + unsigned int as2 = static_cast<unsigned int>(a.m[2]) >> s; + unsigned int as3 = static_cast<unsigned int>(a.m[3]) >> s; + + return vint4(static_cast<int>(as0), + static_cast<int>(as1), + static_cast<int>(as2), + static_cast<int>(as3)); +} + +/** + * @brief Arithmetic shift right. + */ +template <int s> ASTCENC_SIMD_INLINE vint4 asr(vint4 a) +{ + return vint4(a.m[0] >> s, + a.m[1] >> s, + a.m[2] >> s, + a.m[3] >> s); +} + +/** + * @brief Return the min vector of two vectors. + */ +ASTCENC_SIMD_INLINE vint4 min(vint4 a, vint4 b) +{ + return vint4(a.m[0] < b.m[0] ? a.m[0] : b.m[0], + a.m[1] < b.m[1] ? a.m[1] : b.m[1], + a.m[2] < b.m[2] ? a.m[2] : b.m[2], + a.m[3] < b.m[3] ? a.m[3] : b.m[3]); +} + +/** + * @brief Return the min vector of two vectors. + */ +ASTCENC_SIMD_INLINE vint4 max(vint4 a, vint4 b) +{ + return vint4(a.m[0] > b.m[0] ? a.m[0] : b.m[0], + a.m[1] > b.m[1] ? a.m[1] : b.m[1], + a.m[2] > b.m[2] ? a.m[2] : b.m[2], + a.m[3] > b.m[3] ? a.m[3] : b.m[3]); +} + +/** + * @brief Return the horizontal minimum of a single vector. + */ +ASTCENC_SIMD_INLINE vint4 hmin(vint4 a) +{ + int b = std::min(a.m[0], a.m[1]); + int c = std::min(a.m[2], a.m[3]); + return vint4(std::min(b, c)); +} + +/** + * @brief Return the horizontal maximum of a single vector. + */ +ASTCENC_SIMD_INLINE vint4 hmax(vint4 a) +{ + int b = std::max(a.m[0], a.m[1]); + int c = std::max(a.m[2], a.m[3]); + return vint4(std::max(b, c)); +} + +/** + * @brief Return the horizontal sum of vector lanes as a scalar. + */ +ASTCENC_SIMD_INLINE int hadd_s(vint4 a) +{ + return a.m[0] + a.m[1] + a.m[2] + a.m[3]; +} + +/** + * @brief Store a vector to an aligned memory address. + */ +ASTCENC_SIMD_INLINE void storea(vint4 a, int* p) +{ + p[0] = a.m[0]; + p[1] = a.m[1]; + p[2] = a.m[2]; + p[3] = a.m[3]; +} + +/** + * @brief Store a vector to an unaligned memory address. + */ +ASTCENC_SIMD_INLINE void store(vint4 a, int* p) +{ + p[0] = a.m[0]; + p[1] = a.m[1]; + p[2] = a.m[2]; + p[3] = a.m[3]; +} + +/** + * @brief Store lowest N (vector width) bytes into an unaligned address. + */ +ASTCENC_SIMD_INLINE void store_nbytes(vint4 a, uint8_t* p) +{ + int* pi = reinterpret_cast<int*>(p); + *pi = a.m[0]; +} + +/** + * @brief Gather N (vector width) indices from the array. + */ +ASTCENC_SIMD_INLINE vint4 gatheri(const int* base, vint4 indices) +{ + return vint4(base[indices.m[0]], + base[indices.m[1]], + base[indices.m[2]], + base[indices.m[3]]); +} + +/** + * @brief Pack low 8 bits of N (vector width) lanes into bottom of vector. + */ +ASTCENC_SIMD_INLINE vint4 pack_low_bytes(vint4 a) +{ + int b0 = a.m[0] & 0xFF; + int b1 = a.m[1] & 0xFF; + int b2 = a.m[2] & 0xFF; + int b3 = a.m[3] & 0xFF; + + int b = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24); + return vint4(b, 0, 0, 0); +} + +/** + * @brief Return lanes from @c b if MSB of @c cond is set, else @c a. + */ +ASTCENC_SIMD_INLINE vint4 select(vint4 a, vint4 b, vmask4 cond) +{ + return vint4((cond.m[0] & static_cast<int>(0x80000000)) ? b.m[0] : a.m[0], + (cond.m[1] & static_cast<int>(0x80000000)) ? b.m[1] : a.m[1], + (cond.m[2] & static_cast<int>(0x80000000)) ? b.m[2] : a.m[2], + (cond.m[3] & static_cast<int>(0x80000000)) ? b.m[3] : a.m[3]); +} + +// ============================================================================ +// vfloat4 operators and functions +// ============================================================================ + +/** + * @brief Overload: vector by vector addition. + */ +ASTCENC_SIMD_INLINE vfloat4 operator+(vfloat4 a, vfloat4 b) +{ + return vfloat4(a.m[0] + b.m[0], + a.m[1] + b.m[1], + a.m[2] + b.m[2], + a.m[3] + b.m[3]); +} + +/** + * @brief Overload: vector by vector subtraction. + */ +ASTCENC_SIMD_INLINE vfloat4 operator-(vfloat4 a, vfloat4 b) +{ + return vfloat4(a.m[0] - b.m[0], + a.m[1] - b.m[1], + a.m[2] - b.m[2], + a.m[3] - b.m[3]); +} + +/** + * @brief Overload: vector by vector multiplication. + */ +ASTCENC_SIMD_INLINE vfloat4 operator*(vfloat4 a, vfloat4 b) +{ + return vfloat4(a.m[0] * b.m[0], + a.m[1] * b.m[1], + a.m[2] * b.m[2], + a.m[3] * b.m[3]); +} + +/** + * @brief Overload: vector by vector division. + */ +ASTCENC_SIMD_INLINE vfloat4 operator/(vfloat4 a, vfloat4 b) +{ + return vfloat4(a.m[0] / b.m[0], + a.m[1] / b.m[1], + a.m[2] / b.m[2], + a.m[3] / b.m[3]); +} + +/** + * @brief Overload: vector by vector equality. + */ +ASTCENC_SIMD_INLINE vmask4 operator==(vfloat4 a, vfloat4 b) +{ + return vmask4(a.m[0] == b.m[0], + a.m[1] == b.m[1], + a.m[2] == b.m[2], + a.m[3] == b.m[3]); +} + +/** + * @brief Overload: vector by vector inequality. + */ +ASTCENC_SIMD_INLINE vmask4 operator!=(vfloat4 a, vfloat4 b) +{ + return vmask4(a.m[0] != b.m[0], + a.m[1] != b.m[1], + a.m[2] != b.m[2], + a.m[3] != b.m[3]); +} + +/** + * @brief Overload: vector by vector less than. + */ +ASTCENC_SIMD_INLINE vmask4 operator<(vfloat4 a, vfloat4 b) +{ + return vmask4(a.m[0] < b.m[0], + a.m[1] < b.m[1], + a.m[2] < b.m[2], + a.m[3] < b.m[3]); +} + +/** + * @brief Overload: vector by vector greater than. + */ +ASTCENC_SIMD_INLINE vmask4 operator>(vfloat4 a, vfloat4 b) +{ + return vmask4(a.m[0] > b.m[0], + a.m[1] > b.m[1], + a.m[2] > b.m[2], + a.m[3] > b.m[3]); +} + +/** + * @brief Overload: vector by vector less than or equal. + */ +ASTCENC_SIMD_INLINE vmask4 operator<=(vfloat4 a, vfloat4 b) +{ + return vmask4(a.m[0] <= b.m[0], + a.m[1] <= b.m[1], + a.m[2] <= b.m[2], + a.m[3] <= b.m[3]); +} + +/** + * @brief Overload: vector by vector greater than or equal. + */ +ASTCENC_SIMD_INLINE vmask4 operator>=(vfloat4 a, vfloat4 b) +{ + return vmask4(a.m[0] >= b.m[0], + a.m[1] >= b.m[1], + a.m[2] >= b.m[2], + a.m[3] >= b.m[3]); +} + +/** + * @brief Return the min vector of two vectors. + * + * If either lane value is NaN, @c b will be returned for that lane. + */ +ASTCENC_SIMD_INLINE vfloat4 min(vfloat4 a, vfloat4 b) +{ + return vfloat4(a.m[0] < b.m[0] ? a.m[0] : b.m[0], + a.m[1] < b.m[1] ? a.m[1] : b.m[1], + a.m[2] < b.m[2] ? a.m[2] : b.m[2], + a.m[3] < b.m[3] ? a.m[3] : b.m[3]); +} + +/** + * @brief Return the max vector of two vectors. + * + * If either lane value is NaN, @c b will be returned for that lane. + */ +ASTCENC_SIMD_INLINE vfloat4 max(vfloat4 a, vfloat4 b) +{ + return vfloat4(a.m[0] > b.m[0] ? a.m[0] : b.m[0], + a.m[1] > b.m[1] ? a.m[1] : b.m[1], + a.m[2] > b.m[2] ? a.m[2] : b.m[2], + a.m[3] > b.m[3] ? a.m[3] : b.m[3]); +} + +/** + * @brief Return the absolute value of the float vector. + */ +ASTCENC_SIMD_INLINE vfloat4 abs(vfloat4 a) +{ + return vfloat4(std::abs(a.m[0]), + std::abs(a.m[1]), + std::abs(a.m[2]), + std::abs(a.m[3])); +} + +/** + * @brief Return a float rounded to the nearest integer value. + */ +ASTCENC_SIMD_INLINE vfloat4 round(vfloat4 a) +{ + assert(std::fegetround() == FE_TONEAREST); + return vfloat4(std::nearbyint(a.m[0]), + std::nearbyint(a.m[1]), + std::nearbyint(a.m[2]), + std::nearbyint(a.m[3])); +} + +/** + * @brief Return the horizontal minimum of a vector. + */ +ASTCENC_SIMD_INLINE vfloat4 hmin(vfloat4 a) +{ + float tmp1 = std::min(a.m[0], a.m[1]); + float tmp2 = std::min(a.m[2], a.m[3]); + return vfloat4(std::min(tmp1, tmp2)); +} + +/** + * @brief Return the horizontal maximum of a vector. + */ +ASTCENC_SIMD_INLINE vfloat4 hmax(vfloat4 a) +{ + float tmp1 = std::max(a.m[0], a.m[1]); + float tmp2 = std::max(a.m[2], a.m[3]); + return vfloat4(std::max(tmp1, tmp2)); +} + +/** + * @brief Return the horizontal sum of a vector. + */ +ASTCENC_SIMD_INLINE float hadd_s(vfloat4 a) +{ + // Use halving add, gives invariance with SIMD versions + return (a.m[0] + a.m[2]) + (a.m[1] + a.m[3]); +} + +/** + * @brief Return the sqrt of the lanes in the vector. + */ +ASTCENC_SIMD_INLINE vfloat4 sqrt(vfloat4 a) +{ + return vfloat4(std::sqrt(a.m[0]), + std::sqrt(a.m[1]), + std::sqrt(a.m[2]), + std::sqrt(a.m[3])); +} + +/** + * @brief Return lanes from @c b if @c cond is set, else @c a. + */ +ASTCENC_SIMD_INLINE vfloat4 select(vfloat4 a, vfloat4 b, vmask4 cond) +{ + return vfloat4((cond.m[0] & static_cast<int>(0x80000000)) ? b.m[0] : a.m[0], + (cond.m[1] & static_cast<int>(0x80000000)) ? b.m[1] : a.m[1], + (cond.m[2] & static_cast<int>(0x80000000)) ? b.m[2] : a.m[2], + (cond.m[3] & static_cast<int>(0x80000000)) ? b.m[3] : a.m[3]); +} + +/** + * @brief Return lanes from @c b if MSB of @c cond is set, else @c a. + */ +ASTCENC_SIMD_INLINE vfloat4 select_msb(vfloat4 a, vfloat4 b, vmask4 cond) +{ + return vfloat4((cond.m[0] & static_cast<int>(0x80000000)) ? b.m[0] : a.m[0], + (cond.m[1] & static_cast<int>(0x80000000)) ? b.m[1] : a.m[1], + (cond.m[2] & static_cast<int>(0x80000000)) ? b.m[2] : a.m[2], + (cond.m[3] & static_cast<int>(0x80000000)) ? b.m[3] : a.m[3]); +} + +/** + * @brief Load a vector of gathered results from an array; + */ +ASTCENC_SIMD_INLINE vfloat4 gatherf(const float* base, vint4 indices) +{ + return vfloat4(base[indices.m[0]], + base[indices.m[1]], + base[indices.m[2]], + base[indices.m[3]]); +} + +/** + * @brief Store a vector to an unaligned memory address. + */ +ASTCENC_SIMD_INLINE void store(vfloat4 a, float* ptr) +{ + ptr[0] = a.m[0]; + ptr[1] = a.m[1]; + ptr[2] = a.m[2]; + ptr[3] = a.m[3]; +} + +/** + * @brief Store a vector to an aligned memory address. + */ +ASTCENC_SIMD_INLINE void storea(vfloat4 a, float* ptr) +{ + ptr[0] = a.m[0]; + ptr[1] = a.m[1]; + ptr[2] = a.m[2]; + ptr[3] = a.m[3]; +} + +/** + * @brief Return a integer value for a float vector, using truncation. + */ +ASTCENC_SIMD_INLINE vint4 float_to_int(vfloat4 a) +{ + return vint4(static_cast<int>(a.m[0]), + static_cast<int>(a.m[1]), + static_cast<int>(a.m[2]), + static_cast<int>(a.m[3])); +} + +/**f + * @brief Return a integer value for a float vector, using round-to-nearest. + */ +ASTCENC_SIMD_INLINE vint4 float_to_int_rtn(vfloat4 a) +{ + return vint4(static_cast<int>(a.m[0] + 0.5f), + static_cast<int>(a.m[1] + 0.5f), + static_cast<int>(a.m[2] + 0.5f), + static_cast<int>(a.m[3] + 0.5f)); +} + +/** + * @brief Return a float value for a integer vector. + */ +ASTCENC_SIMD_INLINE vfloat4 int_to_float(vint4 a) +{ + return vfloat4(static_cast<float>(a.m[0]), + static_cast<float>(a.m[1]), + static_cast<float>(a.m[2]), + static_cast<float>(a.m[3])); +} + +/** + * @brief Return a float16 value for a float vector, using round-to-nearest. + */ +ASTCENC_SIMD_INLINE vint4 float_to_float16(vfloat4 a) +{ + return vint4( + float_to_sf16(a.lane<0>()), + float_to_sf16(a.lane<1>()), + float_to_sf16(a.lane<2>()), + float_to_sf16(a.lane<3>())); +} + +/** + * @brief Return a float16 value for a float scalar, using round-to-nearest. + */ +static inline uint16_t float_to_float16(float a) +{ + return float_to_sf16(a); +} + +/** + * @brief Return a float value for a float16 vector. + */ +ASTCENC_SIMD_INLINE vfloat4 float16_to_float(vint4 a) +{ + return vfloat4( + sf16_to_float(static_cast<uint16_t>(a.lane<0>())), + sf16_to_float(static_cast<uint16_t>(a.lane<1>())), + sf16_to_float(static_cast<uint16_t>(a.lane<2>())), + sf16_to_float(static_cast<uint16_t>(a.lane<3>()))); +} + +/** + * @brief Return a float value for a float16 scalar. + */ +ASTCENC_SIMD_INLINE float float16_to_float(uint16_t a) +{ + return sf16_to_float(a); +} + +/** + * @brief Return a float value as an integer bit pattern (i.e. no conversion). + * + * It is a common trick to convert floats into integer bit patterns, perform + * some bit hackery based on knowledge they are IEEE 754 layout, and then + * convert them back again. This is the first half of that flip. + */ +ASTCENC_SIMD_INLINE vint4 float_as_int(vfloat4 a) +{ + vint4 r; + memcpy(r.m, a.m, 4 * 4); + return r; +} + +/** + * @brief Return a integer value as a float bit pattern (i.e. no conversion). + * + * It is a common trick to convert floats into integer bit patterns, perform + * some bit hackery based on knowledge they are IEEE 754 layout, and then + * convert them back again. This is the second half of that flip. + */ +ASTCENC_SIMD_INLINE vfloat4 int_as_float(vint4 a) +{ + vfloat4 r; + memcpy(r.m, a.m, 4 * 4); + return r; +} + +/** + * @brief Prepare a vtable lookup table for use with the native SIMD size. + */ +ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4& t0p) +{ + t0p = t0; +} + +/** + * @brief Prepare a vtable lookup table for use with the native SIMD size. + */ +ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4 t1, vint4& t0p, vint4& t1p) +{ + t0p = t0; + t1p = t1; +} + +/** + * @brief Prepare a vtable lookup table for use with the native SIMD size. + */ +ASTCENC_SIMD_INLINE void vtable_prepare( + vint4 t0, vint4 t1, vint4 t2, vint4 t3, + vint4& t0p, vint4& t1p, vint4& t2p, vint4& t3p) +{ + t0p = t0; + t1p = t1; + t2p = t2; + t3p = t3; +} + +/** + * @brief Perform an 8-bit 32-entry table lookup, with 32-bit indexes. + */ +ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 idx) +{ + uint8_t table[16]; + storea(t0, reinterpret_cast<int*>(table + 0)); + + return vint4(table[idx.lane<0>()], + table[idx.lane<1>()], + table[idx.lane<2>()], + table[idx.lane<3>()]); +} + + +/** + * @brief Perform an 8-bit 32-entry table lookup, with 32-bit indexes. + */ +ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 idx) +{ + uint8_t table[32]; + storea(t0, reinterpret_cast<int*>(table + 0)); + storea(t1, reinterpret_cast<int*>(table + 16)); + + return vint4(table[idx.lane<0>()], + table[idx.lane<1>()], + table[idx.lane<2>()], + table[idx.lane<3>()]); +} + +/** + * @brief Perform an 8-bit 64-entry table lookup, with 32-bit indexes. + */ +ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 t2, vint4 t3, vint4 idx) +{ + uint8_t table[64]; + storea(t0, reinterpret_cast<int*>(table + 0)); + storea(t1, reinterpret_cast<int*>(table + 16)); + storea(t2, reinterpret_cast<int*>(table + 32)); + storea(t3, reinterpret_cast<int*>(table + 48)); + + return vint4(table[idx.lane<0>()], + table[idx.lane<1>()], + table[idx.lane<2>()], + table[idx.lane<3>()]); +} + +/** + * @brief Return a vector of interleaved RGBA data. + * + * Input vectors have the value stored in the bottom 8 bits of each lane, + * with high bits set to zero. + * + * Output vector stores a single RGBA texel packed in each lane. + */ +ASTCENC_SIMD_INLINE vint4 interleave_rgba8(vint4 r, vint4 g, vint4 b, vint4 a) +{ + return r + lsl<8>(g) + lsl<16>(b) + lsl<24>(a); +} + +/** + * @brief Store a vector, skipping masked lanes. + * + * All masked lanes must be at the end of vector, after all non-masked lanes. + */ +ASTCENC_SIMD_INLINE void store_lanes_masked(int* base, vint4 data, vmask4 mask) +{ + if (mask.m[3]) + { + store(data, base); + } + else if (mask.m[2]) + { + base[0] = data.lane<0>(); + base[1] = data.lane<1>(); + base[2] = data.lane<2>(); + } + else if (mask.m[1]) + { + base[0] = data.lane<0>(); + base[1] = data.lane<1>(); + } + else if (mask.m[0]) + { + base[0] = data.lane<0>(); + } +} + +#endif // #ifndef ASTC_VECMATHLIB_NONE_4_H_INCLUDED diff --git a/thirdparty/astcenc/astcenc_vecmathlib_sse_4.h b/thirdparty/astcenc/astcenc_vecmathlib_sse_4.h new file mode 100644 index 0000000000..26dcc4a891 --- /dev/null +++ b/thirdparty/astcenc/astcenc_vecmathlib_sse_4.h @@ -0,0 +1,1283 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2019-2022 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief 4x32-bit vectors, implemented using SSE. + * + * This module implements 4-wide 32-bit float, int, and mask vectors for x86 + * SSE. The implementation requires at least SSE2, but higher levels of SSE can + * be selected at compile time to improve performance. + * + * There is a baseline level of functionality provided by all vector widths and + * implementations. This is implemented using identical function signatures, + * modulo data type, so we can use them as substitutable implementations in VLA + * code. + * + * The 4-wide vectors are also used as a fixed-width type, and significantly + * extend the functionality above that available to VLA code. + */ + +#ifndef ASTC_VECMATHLIB_SSE_4_H_INCLUDED +#define ASTC_VECMATHLIB_SSE_4_H_INCLUDED + +#ifndef ASTCENC_SIMD_INLINE + #error "Include astcenc_vecmathlib.h, do not include directly" +#endif + +#include <cstdio> + +// ============================================================================ +// vfloat4 data type +// ============================================================================ + +/** + * @brief Data type for 4-wide floats. + */ +struct vfloat4 +{ + /** + * @brief Construct from zero-initialized value. + */ + ASTCENC_SIMD_INLINE vfloat4() = default; + + /** + * @brief Construct from 4 values loaded from an unaligned address. + * + * Consider using loada() which is better with vectors if data is aligned + * to vector length. + */ + ASTCENC_SIMD_INLINE explicit vfloat4(const float *p) + { + m = _mm_loadu_ps(p); + } + + /** + * @brief Construct from 1 scalar value replicated across all lanes. + * + * Consider using zero() for constexpr zeros. + */ + ASTCENC_SIMD_INLINE explicit vfloat4(float a) + { + m = _mm_set1_ps(a); + } + + /** + * @brief Construct from 4 scalar values. + * + * The value of @c a is stored to lane 0 (LSB) in the SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vfloat4(float a, float b, float c, float d) + { + m = _mm_set_ps(d, c, b, a); + } + + /** + * @brief Construct from an existing SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vfloat4(__m128 a) + { + m = a; + } + + /** + * @brief Get the scalar value of a single lane. + */ + template <int l> ASTCENC_SIMD_INLINE float lane() const + { + return _mm_cvtss_f32(_mm_shuffle_ps(m, m, l)); + } + + /** + * @brief Set the scalar value of a single lane. + */ + template <int l> ASTCENC_SIMD_INLINE void set_lane(float a) + { +#if ASTCENC_SSE >= 41 + __m128 v = _mm_set1_ps(a); + m = _mm_insert_ps(m, v, l << 6 | l << 4); +#else + alignas(16) float idx[4]; + _mm_store_ps(idx, m); + idx[l] = a; + m = _mm_load_ps(idx); +#endif + } + + /** + * @brief Factory that returns a vector of zeros. + */ + static ASTCENC_SIMD_INLINE vfloat4 zero() + { + return vfloat4(_mm_setzero_ps()); + } + + /** + * @brief Factory that returns a replicated scalar loaded from memory. + */ + static ASTCENC_SIMD_INLINE vfloat4 load1(const float* p) + { + return vfloat4(_mm_load_ps1(p)); + } + + /** + * @brief Factory that returns a vector loaded from 16B aligned memory. + */ + static ASTCENC_SIMD_INLINE vfloat4 loada(const float* p) + { + return vfloat4(_mm_load_ps(p)); + } + + /** + * @brief Factory that returns a vector containing the lane IDs. + */ + static ASTCENC_SIMD_INLINE vfloat4 lane_id() + { + return vfloat4(_mm_set_ps(3, 2, 1, 0)); + } + + /** + * @brief Return a swizzled float 2. + */ + template <int l0, int l1> ASTCENC_SIMD_INLINE vfloat4 swz() const + { + vfloat4 result(_mm_shuffle_ps(m, m, l0 | l1 << 2)); + result.set_lane<2>(0.0f); + result.set_lane<3>(0.0f); + return result; + } + + /** + * @brief Return a swizzled float 3. + */ + template <int l0, int l1, int l2> ASTCENC_SIMD_INLINE vfloat4 swz() const + { + vfloat4 result(_mm_shuffle_ps(m, m, l0 | l1 << 2 | l2 << 4)); + result.set_lane<3>(0.0f); + return result; + } + + /** + * @brief Return a swizzled float 4. + */ + template <int l0, int l1, int l2, int l3> ASTCENC_SIMD_INLINE vfloat4 swz() const + { + return vfloat4(_mm_shuffle_ps(m, m, l0 | l1 << 2 | l2 << 4 | l3 << 6)); + } + + /** + * @brief The vector ... + */ + __m128 m; +}; + +// ============================================================================ +// vint4 data type +// ============================================================================ + +/** + * @brief Data type for 4-wide ints. + */ +struct vint4 +{ + /** + * @brief Construct from zero-initialized value. + */ + ASTCENC_SIMD_INLINE vint4() = default; + + /** + * @brief Construct from 4 values loaded from an unaligned address. + * + * Consider using loada() which is better with vectors if data is aligned + * to vector length. + */ + ASTCENC_SIMD_INLINE explicit vint4(const int *p) + { + m = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p)); + } + + /** + * @brief Construct from 4 uint8_t loaded from an unaligned address. + */ + ASTCENC_SIMD_INLINE explicit vint4(const uint8_t *p) + { + // _mm_loadu_si32 would be nicer syntax, but missing on older GCC + __m128i t = _mm_cvtsi32_si128(*reinterpret_cast<const int*>(p)); + +#if ASTCENC_SSE >= 41 + m = _mm_cvtepu8_epi32(t); +#else + t = _mm_unpacklo_epi8(t, _mm_setzero_si128()); + m = _mm_unpacklo_epi16(t, _mm_setzero_si128()); +#endif + } + + /** + * @brief Construct from 1 scalar value replicated across all lanes. + * + * Consider using vfloat4::zero() for constexpr zeros. + */ + ASTCENC_SIMD_INLINE explicit vint4(int a) + { + m = _mm_set1_epi32(a); + } + + /** + * @brief Construct from 4 scalar values. + * + * The value of @c a is stored to lane 0 (LSB) in the SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vint4(int a, int b, int c, int d) + { + m = _mm_set_epi32(d, c, b, a); + } + + /** + * @brief Construct from an existing SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vint4(__m128i a) + { + m = a; + } + + /** + * @brief Get the scalar from a single lane. + */ + template <int l> ASTCENC_SIMD_INLINE int lane() const + { + return _mm_cvtsi128_si32(_mm_shuffle_epi32(m, l)); + } + + /** + * @brief Set the scalar value of a single lane. + */ + template <int l> ASTCENC_SIMD_INLINE void set_lane(int a) + { +#if ASTCENC_SSE >= 41 + m = _mm_insert_epi32(m, a, l); +#else + alignas(16) int idx[4]; + _mm_store_si128(reinterpret_cast<__m128i*>(idx), m); + idx[l] = a; + m = _mm_load_si128(reinterpret_cast<const __m128i*>(idx)); +#endif + } + + /** + * @brief Factory that returns a vector of zeros. + */ + static ASTCENC_SIMD_INLINE vint4 zero() + { + return vint4(_mm_setzero_si128()); + } + + /** + * @brief Factory that returns a replicated scalar loaded from memory. + */ + static ASTCENC_SIMD_INLINE vint4 load1(const int* p) + { + return vint4(*p); + } + + /** + * @brief Factory that returns a vector loaded from 16B aligned memory. + */ + static ASTCENC_SIMD_INLINE vint4 loada(const int* p) + { + return vint4(_mm_load_si128(reinterpret_cast<const __m128i*>(p))); + } + + /** + * @brief Factory that returns a vector containing the lane IDs. + */ + static ASTCENC_SIMD_INLINE vint4 lane_id() + { + return vint4(_mm_set_epi32(3, 2, 1, 0)); + } + + /** + * @brief The vector ... + */ + __m128i m; +}; + +// ============================================================================ +// vmask4 data type +// ============================================================================ + +/** + * @brief Data type for 4-wide control plane masks. + */ +struct vmask4 +{ + /** + * @brief Construct from an existing SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vmask4(__m128 a) + { + m = a; + } + + /** + * @brief Construct from an existing SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vmask4(__m128i a) + { + m = _mm_castsi128_ps(a); + } + + /** + * @brief Construct from 1 scalar value. + */ + ASTCENC_SIMD_INLINE explicit vmask4(bool a) + { + vint4 mask(a == false ? 0 : -1); + m = _mm_castsi128_ps(mask.m); + } + + /** + * @brief Construct from 4 scalar values. + * + * The value of @c a is stored to lane 0 (LSB) in the SIMD register. + */ + ASTCENC_SIMD_INLINE explicit vmask4(bool a, bool b, bool c, bool d) + { + vint4 mask(a == false ? 0 : -1, + b == false ? 0 : -1, + c == false ? 0 : -1, + d == false ? 0 : -1); + + m = _mm_castsi128_ps(mask.m); + } + + /** + * @brief Get the scalar value of a single lane. + */ + template <int l> ASTCENC_SIMD_INLINE float lane() const + { + return _mm_cvtss_f32(_mm_shuffle_ps(m, m, l)); + } + + /** + * @brief The vector ... + */ + __m128 m; +}; + +// ============================================================================ +// vmask4 operators and functions +// ============================================================================ + +/** + * @brief Overload: mask union (or). + */ +ASTCENC_SIMD_INLINE vmask4 operator|(vmask4 a, vmask4 b) +{ + return vmask4(_mm_or_ps(a.m, b.m)); +} + +/** + * @brief Overload: mask intersect (and). + */ +ASTCENC_SIMD_INLINE vmask4 operator&(vmask4 a, vmask4 b) +{ + return vmask4(_mm_and_ps(a.m, b.m)); +} + +/** + * @brief Overload: mask difference (xor). + */ +ASTCENC_SIMD_INLINE vmask4 operator^(vmask4 a, vmask4 b) +{ + return vmask4(_mm_xor_ps(a.m, b.m)); +} + +/** + * @brief Overload: mask invert (not). + */ +ASTCENC_SIMD_INLINE vmask4 operator~(vmask4 a) +{ + return vmask4(_mm_xor_si128(_mm_castps_si128(a.m), _mm_set1_epi32(-1))); +} + +/** + * @brief Return a 4-bit mask code indicating mask status. + * + * bit0 = lane 0 + */ +ASTCENC_SIMD_INLINE unsigned int mask(vmask4 a) +{ + return static_cast<unsigned int>(_mm_movemask_ps(a.m)); +} + +// ============================================================================ +// vint4 operators and functions +// ============================================================================ + +/** + * @brief Overload: vector by vector addition. + */ +ASTCENC_SIMD_INLINE vint4 operator+(vint4 a, vint4 b) +{ + return vint4(_mm_add_epi32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector subtraction. + */ +ASTCENC_SIMD_INLINE vint4 operator-(vint4 a, vint4 b) +{ + return vint4(_mm_sub_epi32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector multiplication. + */ +ASTCENC_SIMD_INLINE vint4 operator*(vint4 a, vint4 b) +{ +#if ASTCENC_SSE >= 41 + return vint4(_mm_mullo_epi32 (a.m, b.m)); +#else + __m128i t1 = _mm_mul_epu32(a.m, b.m); + __m128i t2 = _mm_mul_epu32( + _mm_srli_si128(a.m, 4), + _mm_srli_si128(b.m, 4)); + __m128i r = _mm_unpacklo_epi32( + _mm_shuffle_epi32(t1, _MM_SHUFFLE (0, 0, 2, 0)), + _mm_shuffle_epi32(t2, _MM_SHUFFLE (0, 0, 2, 0))); + return vint4(r); +#endif +} + +/** + * @brief Overload: vector bit invert. + */ +ASTCENC_SIMD_INLINE vint4 operator~(vint4 a) +{ + return vint4(_mm_xor_si128(a.m, _mm_set1_epi32(-1))); +} + +/** + * @brief Overload: vector by vector bitwise or. + */ +ASTCENC_SIMD_INLINE vint4 operator|(vint4 a, vint4 b) +{ + return vint4(_mm_or_si128(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector bitwise and. + */ +ASTCENC_SIMD_INLINE vint4 operator&(vint4 a, vint4 b) +{ + return vint4(_mm_and_si128(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector bitwise xor. + */ +ASTCENC_SIMD_INLINE vint4 operator^(vint4 a, vint4 b) +{ + return vint4(_mm_xor_si128(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector equality. + */ +ASTCENC_SIMD_INLINE vmask4 operator==(vint4 a, vint4 b) +{ + return vmask4(_mm_cmpeq_epi32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector inequality. + */ +ASTCENC_SIMD_INLINE vmask4 operator!=(vint4 a, vint4 b) +{ + return ~vmask4(_mm_cmpeq_epi32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector less than. + */ +ASTCENC_SIMD_INLINE vmask4 operator<(vint4 a, vint4 b) +{ + return vmask4(_mm_cmplt_epi32(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector greater than. + */ +ASTCENC_SIMD_INLINE vmask4 operator>(vint4 a, vint4 b) +{ + return vmask4(_mm_cmpgt_epi32(a.m, b.m)); +} + +/** + * @brief Logical shift left. + */ +template <int s> ASTCENC_SIMD_INLINE vint4 lsl(vint4 a) +{ + return vint4(_mm_slli_epi32(a.m, s)); +} + +/** + * @brief Logical shift right. + */ +template <int s> ASTCENC_SIMD_INLINE vint4 lsr(vint4 a) +{ + return vint4(_mm_srli_epi32(a.m, s)); +} + +/** + * @brief Arithmetic shift right. + */ +template <int s> ASTCENC_SIMD_INLINE vint4 asr(vint4 a) +{ + return vint4(_mm_srai_epi32(a.m, s)); +} + +/** + * @brief Return the min vector of two vectors. + */ +ASTCENC_SIMD_INLINE vint4 min(vint4 a, vint4 b) +{ +#if ASTCENC_SSE >= 41 + return vint4(_mm_min_epi32(a.m, b.m)); +#else + vmask4 d = a < b; + __m128i ap = _mm_and_si128(_mm_castps_si128(d.m), a.m); + __m128i bp = _mm_andnot_si128(_mm_castps_si128(d.m), b.m); + return vint4(_mm_or_si128(ap,bp)); +#endif +} + +/** + * @brief Return the max vector of two vectors. + */ +ASTCENC_SIMD_INLINE vint4 max(vint4 a, vint4 b) +{ +#if ASTCENC_SSE >= 41 + return vint4(_mm_max_epi32(a.m, b.m)); +#else + vmask4 d = a > b; + __m128i ap = _mm_and_si128(_mm_castps_si128(d.m), a.m); + __m128i bp = _mm_andnot_si128(_mm_castps_si128(d.m), b.m); + return vint4(_mm_or_si128(ap,bp)); +#endif +} + +/** + * @brief Return the horizontal minimum of a vector. + */ +ASTCENC_SIMD_INLINE vint4 hmin(vint4 a) +{ + a = min(a, vint4(_mm_shuffle_epi32(a.m, _MM_SHUFFLE(0, 0, 3, 2)))); + a = min(a, vint4(_mm_shuffle_epi32(a.m, _MM_SHUFFLE(0, 0, 0, 1)))); + return vint4(_mm_shuffle_epi32(a.m, _MM_SHUFFLE(0, 0, 0, 0))); +} + +/* + * @brief Return the horizontal maximum of a vector. + */ +ASTCENC_SIMD_INLINE vint4 hmax(vint4 a) +{ + a = max(a, vint4(_mm_shuffle_epi32(a.m, _MM_SHUFFLE(0, 0, 3, 2)))); + a = max(a, vint4(_mm_shuffle_epi32(a.m, _MM_SHUFFLE(0, 0, 0, 1)))); + return vint4(_mm_shuffle_epi32(a.m, _MM_SHUFFLE(0, 0, 0, 0))); +} + +/** + * @brief Return the horizontal sum of a vector as a scalar. + */ +ASTCENC_SIMD_INLINE int hadd_s(vint4 a) +{ + // Add top and bottom halves, lane 1/0 + __m128i fold = _mm_castps_si128(_mm_movehl_ps(_mm_castsi128_ps(a.m), + _mm_castsi128_ps(a.m))); + __m128i t = _mm_add_epi32(a.m, fold); + + // Add top and bottom halves, lane 0 (_mm_hadd_ps exists but slow) + t = _mm_add_epi32(t, _mm_shuffle_epi32(t, 0x55)); + + return _mm_cvtsi128_si32(t); +} + +/** + * @brief Store a vector to a 16B aligned memory address. + */ +ASTCENC_SIMD_INLINE void storea(vint4 a, int* p) +{ + _mm_store_si128(reinterpret_cast<__m128i*>(p), a.m); +} + +/** + * @brief Store a vector to an unaligned memory address. + */ +ASTCENC_SIMD_INLINE void store(vint4 a, int* p) +{ + // Cast due to missing intrinsics + _mm_storeu_ps(reinterpret_cast<float*>(p), _mm_castsi128_ps(a.m)); +} + +/** + * @brief Store lowest N (vector width) bytes into an unaligned address. + */ +ASTCENC_SIMD_INLINE void store_nbytes(vint4 a, uint8_t* p) +{ + // Cast due to missing intrinsics + _mm_store_ss(reinterpret_cast<float*>(p), _mm_castsi128_ps(a.m)); +} + +/** + * @brief Gather N (vector width) indices from the array. + */ +ASTCENC_SIMD_INLINE vint4 gatheri(const int* base, vint4 indices) +{ +#if ASTCENC_AVX >= 2 + return vint4(_mm_i32gather_epi32(base, indices.m, 4)); +#else + alignas(16) int idx[4]; + storea(indices, idx); + return vint4(base[idx[0]], base[idx[1]], base[idx[2]], base[idx[3]]); +#endif +} + +/** + * @brief Pack low 8 bits of N (vector width) lanes into bottom of vector. + */ +ASTCENC_SIMD_INLINE vint4 pack_low_bytes(vint4 a) +{ +#if ASTCENC_SSE >= 41 + __m128i shuf = _mm_set_epi8(0,0,0,0, 0,0,0,0, 0,0,0,0, 12,8,4,0); + return vint4(_mm_shuffle_epi8(a.m, shuf)); +#else + __m128i va = _mm_unpacklo_epi8(a.m, _mm_shuffle_epi32(a.m, _MM_SHUFFLE(1,1,1,1))); + __m128i vb = _mm_unpackhi_epi8(a.m, _mm_shuffle_epi32(a.m, _MM_SHUFFLE(3,3,3,3))); + return vint4(_mm_unpacklo_epi16(va, vb)); +#endif +} + +/** + * @brief Return lanes from @c b if @c cond is set, else @c a. + */ +ASTCENC_SIMD_INLINE vint4 select(vint4 a, vint4 b, vmask4 cond) +{ + __m128i condi = _mm_castps_si128(cond.m); + +#if ASTCENC_SSE >= 41 + return vint4(_mm_blendv_epi8(a.m, b.m, condi)); +#else + return vint4(_mm_or_si128(_mm_and_si128(condi, b.m), _mm_andnot_si128(condi, a.m))); +#endif +} + +// ============================================================================ +// vfloat4 operators and functions +// ============================================================================ + +/** + * @brief Overload: vector by vector addition. + */ +ASTCENC_SIMD_INLINE vfloat4 operator+(vfloat4 a, vfloat4 b) +{ + return vfloat4(_mm_add_ps(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector subtraction. + */ +ASTCENC_SIMD_INLINE vfloat4 operator-(vfloat4 a, vfloat4 b) +{ + return vfloat4(_mm_sub_ps(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector multiplication. + */ +ASTCENC_SIMD_INLINE vfloat4 operator*(vfloat4 a, vfloat4 b) +{ + return vfloat4(_mm_mul_ps(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector division. + */ +ASTCENC_SIMD_INLINE vfloat4 operator/(vfloat4 a, vfloat4 b) +{ + return vfloat4(_mm_div_ps(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector equality. + */ +ASTCENC_SIMD_INLINE vmask4 operator==(vfloat4 a, vfloat4 b) +{ + return vmask4(_mm_cmpeq_ps(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector inequality. + */ +ASTCENC_SIMD_INLINE vmask4 operator!=(vfloat4 a, vfloat4 b) +{ + return vmask4(_mm_cmpneq_ps(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector less than. + */ +ASTCENC_SIMD_INLINE vmask4 operator<(vfloat4 a, vfloat4 b) +{ + return vmask4(_mm_cmplt_ps(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector greater than. + */ +ASTCENC_SIMD_INLINE vmask4 operator>(vfloat4 a, vfloat4 b) +{ + return vmask4(_mm_cmpgt_ps(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector less than or equal. + */ +ASTCENC_SIMD_INLINE vmask4 operator<=(vfloat4 a, vfloat4 b) +{ + return vmask4(_mm_cmple_ps(a.m, b.m)); +} + +/** + * @brief Overload: vector by vector greater than or equal. + */ +ASTCENC_SIMD_INLINE vmask4 operator>=(vfloat4 a, vfloat4 b) +{ + return vmask4(_mm_cmpge_ps(a.m, b.m)); +} + +/** + * @brief Return the min vector of two vectors. + * + * If either lane value is NaN, @c b will be returned for that lane. + */ +ASTCENC_SIMD_INLINE vfloat4 min(vfloat4 a, vfloat4 b) +{ + // Do not reorder - second operand will return if either is NaN + return vfloat4(_mm_min_ps(a.m, b.m)); +} + +/** + * @brief Return the max vector of two vectors. + * + * If either lane value is NaN, @c b will be returned for that lane. + */ +ASTCENC_SIMD_INLINE vfloat4 max(vfloat4 a, vfloat4 b) +{ + // Do not reorder - second operand will return if either is NaN + return vfloat4(_mm_max_ps(a.m, b.m)); +} + +/** + * @brief Return the absolute value of the float vector. + */ +ASTCENC_SIMD_INLINE vfloat4 abs(vfloat4 a) +{ + return vfloat4(_mm_max_ps(_mm_sub_ps(_mm_setzero_ps(), a.m), a.m)); +} + +/** + * @brief Return a float rounded to the nearest integer value. + */ +ASTCENC_SIMD_INLINE vfloat4 round(vfloat4 a) +{ +#if ASTCENC_SSE >= 41 + constexpr int flags = _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC; + return vfloat4(_mm_round_ps(a.m, flags)); +#else + __m128 v = a.m; + __m128 neg_zero = _mm_castsi128_ps(_mm_set1_epi32(static_cast<int>(0x80000000))); + __m128 no_fraction = _mm_set1_ps(8388608.0f); + __m128 abs_mask = _mm_castsi128_ps(_mm_set1_epi32(0x7FFFFFFF)); + __m128 sign = _mm_and_ps(v, neg_zero); + __m128 s_magic = _mm_or_ps(no_fraction, sign); + __m128 r1 = _mm_add_ps(v, s_magic); + r1 = _mm_sub_ps(r1, s_magic); + __m128 r2 = _mm_and_ps(v, abs_mask); + __m128 mask = _mm_cmple_ps(r2, no_fraction); + r2 = _mm_andnot_ps(mask, v); + r1 = _mm_and_ps(r1, mask); + return vfloat4(_mm_xor_ps(r1, r2)); +#endif +} + +/** + * @brief Return the horizontal minimum of a vector. + */ +ASTCENC_SIMD_INLINE vfloat4 hmin(vfloat4 a) +{ + a = min(a, vfloat4(_mm_shuffle_ps(a.m, a.m, _MM_SHUFFLE(0, 0, 3, 2)))); + a = min(a, vfloat4(_mm_shuffle_ps(a.m, a.m, _MM_SHUFFLE(0, 0, 0, 1)))); + return vfloat4(_mm_shuffle_ps(a.m, a.m, _MM_SHUFFLE(0, 0, 0, 0))); +} + +/** + * @brief Return the horizontal maximum of a vector. + */ +ASTCENC_SIMD_INLINE vfloat4 hmax(vfloat4 a) +{ + a = max(a, vfloat4(_mm_shuffle_ps(a.m, a.m, _MM_SHUFFLE(0, 0, 3, 2)))); + a = max(a, vfloat4(_mm_shuffle_ps(a.m, a.m, _MM_SHUFFLE(0, 0, 0, 1)))); + return vfloat4(_mm_shuffle_ps(a.m, a.m, _MM_SHUFFLE(0, 0, 0, 0))); +} + +/** + * @brief Return the horizontal sum of a vector as a scalar. + */ +ASTCENC_SIMD_INLINE float hadd_s(vfloat4 a) +{ + // Add top and bottom halves, lane 1/0 + __m128 t = _mm_add_ps(a.m, _mm_movehl_ps(a.m, a.m)); + + // Add top and bottom halves, lane 0 (_mm_hadd_ps exists but slow) + t = _mm_add_ss(t, _mm_shuffle_ps(t, t, 0x55)); + + return _mm_cvtss_f32(t); +} + +/** + * @brief Return the sqrt of the lanes in the vector. + */ +ASTCENC_SIMD_INLINE vfloat4 sqrt(vfloat4 a) +{ + return vfloat4(_mm_sqrt_ps(a.m)); +} + +/** + * @brief Return lanes from @c b if @c cond is set, else @c a. + */ +ASTCENC_SIMD_INLINE vfloat4 select(vfloat4 a, vfloat4 b, vmask4 cond) +{ +#if ASTCENC_SSE >= 41 + return vfloat4(_mm_blendv_ps(a.m, b.m, cond.m)); +#else + return vfloat4(_mm_or_ps(_mm_and_ps(cond.m, b.m), _mm_andnot_ps(cond.m, a.m))); +#endif +} + +/** + * @brief Return lanes from @c b if MSB of @c cond is set, else @c a. + */ +ASTCENC_SIMD_INLINE vfloat4 select_msb(vfloat4 a, vfloat4 b, vmask4 cond) +{ +#if ASTCENC_SSE >= 41 + return vfloat4(_mm_blendv_ps(a.m, b.m, cond.m)); +#else + __m128 d = _mm_castsi128_ps(_mm_srai_epi32(_mm_castps_si128(cond.m), 31)); + return vfloat4(_mm_or_ps(_mm_and_ps(d, b.m), _mm_andnot_ps(d, a.m))); +#endif +} + +/** + * @brief Load a vector of gathered results from an array; + */ +ASTCENC_SIMD_INLINE vfloat4 gatherf(const float* base, vint4 indices) +{ +#if ASTCENC_AVX >= 2 + return vfloat4(_mm_i32gather_ps(base, indices.m, 4)); +#else + alignas(16) int idx[4]; + storea(indices, idx); + return vfloat4(base[idx[0]], base[idx[1]], base[idx[2]], base[idx[3]]); +#endif +} + +/** + * @brief Store a vector to an unaligned memory address. + */ +ASTCENC_SIMD_INLINE void store(vfloat4 a, float* p) +{ + _mm_storeu_ps(p, a.m); +} + +/** + * @brief Store a vector to a 16B aligned memory address. + */ +ASTCENC_SIMD_INLINE void storea(vfloat4 a, float* p) +{ + _mm_store_ps(p, a.m); +} + +/** + * @brief Return a integer value for a float vector, using truncation. + */ +ASTCENC_SIMD_INLINE vint4 float_to_int(vfloat4 a) +{ + return vint4(_mm_cvttps_epi32(a.m)); +} + +/** + * @brief Return a integer value for a float vector, using round-to-nearest. + */ +ASTCENC_SIMD_INLINE vint4 float_to_int_rtn(vfloat4 a) +{ + a = round(a); + return vint4(_mm_cvttps_epi32(a.m)); +} + +/** + * @brief Return a float value for an integer vector. + */ +ASTCENC_SIMD_INLINE vfloat4 int_to_float(vint4 a) +{ + return vfloat4(_mm_cvtepi32_ps(a.m)); +} + +/** + * @brief Return a float16 value for a float vector, using round-to-nearest. + */ +ASTCENC_SIMD_INLINE vint4 float_to_float16(vfloat4 a) +{ +#if ASTCENC_F16C >= 1 + __m128i packedf16 = _mm_cvtps_ph(a.m, 0); + __m128i f16 = _mm_cvtepu16_epi32(packedf16); + return vint4(f16); +#else + return vint4( + float_to_sf16(a.lane<0>()), + float_to_sf16(a.lane<1>()), + float_to_sf16(a.lane<2>()), + float_to_sf16(a.lane<3>())); +#endif +} + +/** + * @brief Return a float16 value for a float scalar, using round-to-nearest. + */ +static inline uint16_t float_to_float16(float a) +{ +#if ASTCENC_F16C >= 1 + __m128i f16 = _mm_cvtps_ph(_mm_set1_ps(a), 0); + return static_cast<uint16_t>(_mm_cvtsi128_si32(f16)); +#else + return float_to_sf16(a); +#endif +} + +/** + * @brief Return a float value for a float16 vector. + */ +ASTCENC_SIMD_INLINE vfloat4 float16_to_float(vint4 a) +{ +#if ASTCENC_F16C >= 1 + __m128i packed = _mm_packs_epi32(a.m, a.m); + __m128 f32 = _mm_cvtph_ps(packed); + return vfloat4(f32); +#else + return vfloat4( + sf16_to_float(static_cast<uint16_t>(a.lane<0>())), + sf16_to_float(static_cast<uint16_t>(a.lane<1>())), + sf16_to_float(static_cast<uint16_t>(a.lane<2>())), + sf16_to_float(static_cast<uint16_t>(a.lane<3>()))); +#endif +} + +/** + * @brief Return a float value for a float16 scalar. + */ +ASTCENC_SIMD_INLINE float float16_to_float(uint16_t a) +{ +#if ASTCENC_F16C >= 1 + __m128i packed = _mm_set1_epi16(static_cast<short>(a)); + __m128 f32 = _mm_cvtph_ps(packed); + return _mm_cvtss_f32(f32); +#else + return sf16_to_float(a); +#endif +} + +/** + * @brief Return a float value as an integer bit pattern (i.e. no conversion). + * + * It is a common trick to convert floats into integer bit patterns, perform + * some bit hackery based on knowledge they are IEEE 754 layout, and then + * convert them back again. This is the first half of that flip. + */ +ASTCENC_SIMD_INLINE vint4 float_as_int(vfloat4 a) +{ + return vint4(_mm_castps_si128(a.m)); +} + +/** + * @brief Return a integer value as a float bit pattern (i.e. no conversion). + * + * It is a common trick to convert floats into integer bit patterns, perform + * some bit hackery based on knowledge they are IEEE 754 layout, and then + * convert them back again. This is the second half of that flip. + */ +ASTCENC_SIMD_INLINE vfloat4 int_as_float(vint4 v) +{ + return vfloat4(_mm_castsi128_ps(v.m)); +} + +/** + * @brief Prepare a vtable lookup table for use with the native SIMD size. + */ +ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4& t0p) +{ + t0p = t0; +} + +/** + * @brief Prepare a vtable lookup table for use with the native SIMD size. + */ +ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4 t1, vint4& t0p, vint4& t1p) +{ +#if ASTCENC_SSE >= 41 + t0p = t0; + t1p = t0 ^ t1; +#else + t0p = t0; + t1p = t1; +#endif +} + +/** + * @brief Prepare a vtable lookup table for use with the native SIMD size. + */ +ASTCENC_SIMD_INLINE void vtable_prepare( + vint4 t0, vint4 t1, vint4 t2, vint4 t3, + vint4& t0p, vint4& t1p, vint4& t2p, vint4& t3p) +{ +#if ASTCENC_SSE >= 41 + t0p = t0; + t1p = t0 ^ t1; + t2p = t1 ^ t2; + t3p = t2 ^ t3; +#else + t0p = t0; + t1p = t1; + t2p = t2; + t3p = t3; +#endif +} + +/** + * @brief Perform an 8-bit 16-entry table lookup, with 32-bit indexes. + */ +ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 idx) +{ +#if ASTCENC_SSE >= 41 + // Set index byte MSB to 1 for unused bytes so shuffle returns zero + __m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00))); + + __m128i result = _mm_shuffle_epi8(t0.m, idxx); + return vint4(result); +#else + alignas(ASTCENC_VECALIGN) uint8_t table[16]; + storea(t0, reinterpret_cast<int*>(table + 0)); + + return vint4(table[idx.lane<0>()], + table[idx.lane<1>()], + table[idx.lane<2>()], + table[idx.lane<3>()]); +#endif +} + +/** + * @brief Perform an 8-bit 32-entry table lookup, with 32-bit indexes. + */ +ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 idx) +{ +#if ASTCENC_SSE >= 41 + // Set index byte MSB to 1 for unused bytes so shuffle returns zero + __m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00))); + + __m128i result = _mm_shuffle_epi8(t0.m, idxx); + idxx = _mm_sub_epi8(idxx, _mm_set1_epi8(16)); + + __m128i result2 = _mm_shuffle_epi8(t1.m, idxx); + result = _mm_xor_si128(result, result2); + + return vint4(result); +#else + alignas(ASTCENC_VECALIGN) uint8_t table[32]; + storea(t0, reinterpret_cast<int*>(table + 0)); + storea(t1, reinterpret_cast<int*>(table + 16)); + + return vint4(table[idx.lane<0>()], + table[idx.lane<1>()], + table[idx.lane<2>()], + table[idx.lane<3>()]); +#endif +} + +/** + * @brief Perform an 8-bit 64-entry table lookup, with 32-bit indexes. + */ +ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 t2, vint4 t3, vint4 idx) +{ +#if ASTCENC_SSE >= 41 + // Set index byte MSB to 1 for unused bytes so shuffle returns zero + __m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00))); + + __m128i result = _mm_shuffle_epi8(t0.m, idxx); + idxx = _mm_sub_epi8(idxx, _mm_set1_epi8(16)); + + __m128i result2 = _mm_shuffle_epi8(t1.m, idxx); + result = _mm_xor_si128(result, result2); + idxx = _mm_sub_epi8(idxx, _mm_set1_epi8(16)); + + result2 = _mm_shuffle_epi8(t2.m, idxx); + result = _mm_xor_si128(result, result2); + idxx = _mm_sub_epi8(idxx, _mm_set1_epi8(16)); + + result2 = _mm_shuffle_epi8(t3.m, idxx); + result = _mm_xor_si128(result, result2); + + return vint4(result); +#else + alignas(ASTCENC_VECALIGN) uint8_t table[64]; + storea(t0, reinterpret_cast<int*>(table + 0)); + storea(t1, reinterpret_cast<int*>(table + 16)); + storea(t2, reinterpret_cast<int*>(table + 32)); + storea(t3, reinterpret_cast<int*>(table + 48)); + + return vint4(table[idx.lane<0>()], + table[idx.lane<1>()], + table[idx.lane<2>()], + table[idx.lane<3>()]); +#endif +} + +/** + * @brief Return a vector of interleaved RGBA data. + * + * Input vectors have the value stored in the bottom 8 bits of each lane, + * with high bits set to zero. + * + * Output vector stores a single RGBA texel packed in each lane. + */ +ASTCENC_SIMD_INLINE vint4 interleave_rgba8(vint4 r, vint4 g, vint4 b, vint4 a) +{ +// Workaround an XCode compiler internal fault; note is slower than slli_epi32 +// so we should revert this when we get the opportunity +#if defined(__APPLE__) + __m128i value = r.m; + value = _mm_add_epi32(value, _mm_bslli_si128(g.m, 1)); + value = _mm_add_epi32(value, _mm_bslli_si128(b.m, 2)); + value = _mm_add_epi32(value, _mm_bslli_si128(a.m, 3)); + return vint4(value); +#else + __m128i value = r.m; + value = _mm_add_epi32(value, _mm_slli_epi32(g.m, 8)); + value = _mm_add_epi32(value, _mm_slli_epi32(b.m, 16)); + value = _mm_add_epi32(value, _mm_slli_epi32(a.m, 24)); + return vint4(value); +#endif +} + +/** + * @brief Store a vector, skipping masked lanes. + * + * All masked lanes must be at the end of vector, after all non-masked lanes. + */ +ASTCENC_SIMD_INLINE void store_lanes_masked(int* base, vint4 data, vmask4 mask) +{ +#if ASTCENC_AVX >= 2 + _mm_maskstore_epi32(base, _mm_castps_si128(mask.m), data.m); +#else + // Note - we cannot use _mm_maskmoveu_si128 as the underlying hardware doesn't guarantee + // fault suppression on masked lanes so we can get page faults at the end of an image. + if (mask.lane<3>() != 0.0f) + { + store(data, base); + } + else if (mask.lane<2>() != 0.0f) + { + base[0] = data.lane<0>(); + base[1] = data.lane<1>(); + base[2] = data.lane<2>(); + } + else if (mask.lane<1>() != 0.0f) + { + base[0] = data.lane<0>(); + base[1] = data.lane<1>(); + } + else if (mask.lane<0>() != 0.0f) + { + base[0] = data.lane<0>(); + } +#endif +} + +#if defined(ASTCENC_NO_INVARIANCE) && (ASTCENC_SSE >= 41) + +#define ASTCENC_USE_NATIVE_DOT_PRODUCT 1 + +/** + * @brief Return the dot product for the full 4 lanes, returning scalar. + */ +ASTCENC_SIMD_INLINE float dot_s(vfloat4 a, vfloat4 b) +{ + return _mm_cvtss_f32(_mm_dp_ps(a.m, b.m, 0xFF)); +} + +/** + * @brief Return the dot product for the full 4 lanes, returning vector. + */ +ASTCENC_SIMD_INLINE vfloat4 dot(vfloat4 a, vfloat4 b) +{ + return vfloat4(_mm_dp_ps(a.m, b.m, 0xFF)); +} + +/** + * @brief Return the dot product for the bottom 3 lanes, returning scalar. + */ +ASTCENC_SIMD_INLINE float dot3_s(vfloat4 a, vfloat4 b) +{ + return _mm_cvtss_f32(_mm_dp_ps(a.m, b.m, 0x77)); +} + +/** + * @brief Return the dot product for the bottom 3 lanes, returning vector. + */ +ASTCENC_SIMD_INLINE vfloat4 dot3(vfloat4 a, vfloat4 b) +{ + return vfloat4(_mm_dp_ps(a.m, b.m, 0x77)); +} + +#endif // #if defined(ASTCENC_NO_INVARIANCE) && (ASTCENC_SSE >= 41) + +#if ASTCENC_POPCNT >= 1 + +#define ASTCENC_USE_NATIVE_POPCOUNT 1 + +/** + * @brief Population bit count. + * + * @param v The value to population count. + * + * @return The number of 1 bits. + */ +ASTCENC_SIMD_INLINE int popcount(uint64_t v) +{ + return static_cast<int>(_mm_popcnt_u64(v)); +} + +#endif // ASTCENC_POPCNT >= 1 + +#endif // #ifndef ASTC_VECMATHLIB_SSE_4_H_INCLUDED diff --git a/thirdparty/astcenc/astcenc_weight_align.cpp b/thirdparty/astcenc/astcenc_weight_align.cpp new file mode 100644 index 0000000000..e40a318cf5 --- /dev/null +++ b/thirdparty/astcenc/astcenc_weight_align.cpp @@ -0,0 +1,479 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2022 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +#if !defined(ASTCENC_DECOMPRESS_ONLY) + +/** + * @brief Functions for angular-sum algorithm for weight alignment. + * + * This algorithm works as follows: + * - we compute a complex number P as (cos s*i, sin s*i) for each weight, + * where i is the input value and s is a scaling factor based on the spacing between the weights. + * - we then add together complex numbers for all the weights. + * - we then compute the length and angle of the resulting sum. + * + * This should produce the following results: + * - perfect alignment results in a vector whose length is equal to the sum of lengths of all inputs + * - even distribution results in a vector of length 0. + * - all samples identical results in perfect alignment for every scaling. + * + * For each scaling factor within a given set, we compute an alignment factor from 0 to 1. This + * should then result in some scalings standing out as having particularly good alignment factors; + * we can use this to produce a set of candidate scale/shift values for various quantization levels; + * we should then actually try them and see what happens. + */ + +#include "astcenc_internal.h" +#include "astcenc_vecmathlib.h" + +#include <stdio.h> +#include <cassert> +#include <cstring> + +static constexpr unsigned int ANGULAR_STEPS { 32 }; + +static_assert((ANGULAR_STEPS % ASTCENC_SIMD_WIDTH) == 0, + "ANGULAR_STEPS must be multiple of ASTCENC_SIMD_WIDTH"); + +static_assert(ANGULAR_STEPS >= 32, + "ANGULAR_STEPS must be at least max(steps_for_quant_level)"); + +// Store a reduced sin/cos table for 64 possible weight values; this causes +// slight quality loss compared to using sin() and cos() directly. Must be 2^N. +static constexpr unsigned int SINCOS_STEPS { 64 }; + +static const uint8_t steps_for_quant_level[12] { + 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32 +}; + +alignas(ASTCENC_VECALIGN) static float sin_table[SINCOS_STEPS][ANGULAR_STEPS]; +alignas(ASTCENC_VECALIGN) static float cos_table[SINCOS_STEPS][ANGULAR_STEPS]; + +#if defined(ASTCENC_DIAGNOSTICS) + static bool print_once { true }; +#endif + +/* See header for documentation. */ +void prepare_angular_tables() +{ + for (unsigned int i = 0; i < ANGULAR_STEPS; i++) + { + float angle_step = static_cast<float>(i + 1); + + for (unsigned int j = 0; j < SINCOS_STEPS; j++) + { + sin_table[j][i] = static_cast<float>(sinf((2.0f * astc::PI / (SINCOS_STEPS - 1.0f)) * angle_step * static_cast<float>(j))); + cos_table[j][i] = static_cast<float>(cosf((2.0f * astc::PI / (SINCOS_STEPS - 1.0f)) * angle_step * static_cast<float>(j))); + } + } +} + +/** + * @brief Compute the angular alignment factors and offsets. + * + * @param weight_count The number of (decimated) weights. + * @param dec_weight_ideal_value The ideal decimated unquantized weight values. + * @param max_angular_steps The maximum number of steps to be tested. + * @param[out] offsets The output angular offsets array. + */ +static void compute_angular_offsets( + unsigned int weight_count, + const float* dec_weight_ideal_value, + unsigned int max_angular_steps, + float* offsets +) { + promise(weight_count > 0); + promise(max_angular_steps > 0); + + alignas(ASTCENC_VECALIGN) int isamplev[BLOCK_MAX_WEIGHTS]; + + // Precompute isample; arrays are always allocated 64 elements long + for (unsigned int i = 0; i < weight_count; i += ASTCENC_SIMD_WIDTH) + { + // Add 2^23 and interpreting bits extracts round-to-nearest int + vfloat sample = loada(dec_weight_ideal_value + i) * (SINCOS_STEPS - 1.0f) + vfloat(12582912.0f); + vint isample = float_as_int(sample) & vint((SINCOS_STEPS - 1)); + storea(isample, isamplev + i); + } + + // Arrays are multiple of SIMD width (ANGULAR_STEPS), safe to overshoot max + vfloat mult = vfloat(1.0f / (2.0f * astc::PI)); + + for (unsigned int i = 0; i < max_angular_steps; i += ASTCENC_SIMD_WIDTH) + { + vfloat anglesum_x = vfloat::zero(); + vfloat anglesum_y = vfloat::zero(); + + for (unsigned int j = 0; j < weight_count; j++) + { + int isample = isamplev[j]; + anglesum_x += loada(cos_table[isample] + i); + anglesum_y += loada(sin_table[isample] + i); + } + + vfloat angle = atan2(anglesum_y, anglesum_x); + vfloat ofs = angle * mult; + storea(ofs, offsets + i); + } +} + +/** + * @brief For a given step size compute the lowest and highest weight. + * + * Compute the lowest and highest weight that results from quantizing using the given stepsize and + * offset, and then compute the resulting error. The cut errors indicate the error that results from + * forcing samples that should have had one weight value one step up or down. + * + * @param weight_count The number of (decimated) weights. + * @param dec_weight_ideal_value The ideal decimated unquantized weight values. + * @param max_angular_steps The maximum number of steps to be tested. + * @param max_quant_steps The maximum quantization level to be tested. + * @param offsets The angular offsets array. + * @param[out] lowest_weight Per angular step, the lowest weight. + * @param[out] weight_span Per angular step, the span between lowest and highest weight. + * @param[out] error Per angular step, the error. + * @param[out] cut_low_weight_error Per angular step, the low weight cut error. + * @param[out] cut_high_weight_error Per angular step, the high weight cut error. + */ +static void compute_lowest_and_highest_weight( + unsigned int weight_count, + const float* dec_weight_ideal_value, + unsigned int max_angular_steps, + unsigned int max_quant_steps, + const float* offsets, + float* lowest_weight, + int* weight_span, + float* error, + float* cut_low_weight_error, + float* cut_high_weight_error +) { + promise(weight_count > 0); + promise(max_angular_steps > 0); + + vfloat rcp_stepsize = vfloat::lane_id() + vfloat(1.0f); + + // Arrays are ANGULAR_STEPS long, so always safe to run full vectors + for (unsigned int sp = 0; sp < max_angular_steps; sp += ASTCENC_SIMD_WIDTH) + { + vfloat minidx(128.0f); + vfloat maxidx(-128.0f); + vfloat errval = vfloat::zero(); + vfloat cut_low_weight_err = vfloat::zero(); + vfloat cut_high_weight_err = vfloat::zero(); + vfloat offset = loada(offsets + sp); + + for (unsigned int j = 0; j < weight_count; j++) + { + vfloat sval = load1(dec_weight_ideal_value + j) * rcp_stepsize - offset; + vfloat svalrte = round(sval); + vfloat diff = sval - svalrte; + errval += diff * diff; + + // Reset tracker on min hit + vmask mask = svalrte < minidx; + minidx = select(minidx, svalrte, mask); + cut_low_weight_err = select(cut_low_weight_err, vfloat::zero(), mask); + + // Accumulate on min hit + mask = svalrte == minidx; + vfloat accum = cut_low_weight_err + vfloat(1.0f) - vfloat(2.0f) * diff; + cut_low_weight_err = select(cut_low_weight_err, accum, mask); + + // Reset tracker on max hit + mask = svalrte > maxidx; + maxidx = select(maxidx, svalrte, mask); + cut_high_weight_err = select(cut_high_weight_err, vfloat::zero(), mask); + + // Accumulate on max hit + mask = svalrte == maxidx; + accum = cut_high_weight_err + vfloat(1.0f) + vfloat(2.0f) * diff; + cut_high_weight_err = select(cut_high_weight_err, accum, mask); + } + + // Write out min weight and weight span; clamp span to a usable range + vint span = float_to_int(maxidx - minidx + vfloat(1)); + span = min(span, vint(max_quant_steps + 3)); + span = max(span, vint(2)); + storea(minidx, lowest_weight + sp); + storea(span, weight_span + sp); + + // The cut_(lowest/highest)_weight_error indicate the error that results from forcing + // samples that should have had the weight value one step (up/down). + vfloat ssize = 1.0f / rcp_stepsize; + vfloat errscale = ssize * ssize; + storea(errval * errscale, error + sp); + storea(cut_low_weight_err * errscale, cut_low_weight_error + sp); + storea(cut_high_weight_err * errscale, cut_high_weight_error + sp); + + rcp_stepsize = rcp_stepsize + vfloat(ASTCENC_SIMD_WIDTH); + } +} + +/** + * @brief The main function for the angular algorithm. + * + * @param weight_count The number of (decimated) weights. + * @param dec_weight_ideal_value The ideal decimated unquantized weight values. + * @param max_quant_level The maximum quantization level to be tested. + * @param[out] low_value Per angular step, the lowest weight value. + * @param[out] high_value Per angular step, the highest weight value. + */ +static void compute_angular_endpoints_for_quant_levels( + unsigned int weight_count, + const float* dec_weight_ideal_value, + unsigned int max_quant_level, + float low_value[TUNE_MAX_ANGULAR_QUANT + 1], + float high_value[TUNE_MAX_ANGULAR_QUANT + 1] +) { + unsigned int max_quant_steps = steps_for_quant_level[max_quant_level]; + unsigned int max_angular_steps = steps_for_quant_level[max_quant_level]; + + alignas(ASTCENC_VECALIGN) float angular_offsets[ANGULAR_STEPS]; + + compute_angular_offsets(weight_count, dec_weight_ideal_value, + max_angular_steps, angular_offsets); + + alignas(ASTCENC_VECALIGN) float lowest_weight[ANGULAR_STEPS]; + alignas(ASTCENC_VECALIGN) int32_t weight_span[ANGULAR_STEPS]; + alignas(ASTCENC_VECALIGN) float error[ANGULAR_STEPS]; + alignas(ASTCENC_VECALIGN) float cut_low_weight_error[ANGULAR_STEPS]; + alignas(ASTCENC_VECALIGN) float cut_high_weight_error[ANGULAR_STEPS]; + + compute_lowest_and_highest_weight(weight_count, dec_weight_ideal_value, + max_angular_steps, max_quant_steps, + angular_offsets, lowest_weight, weight_span, error, + cut_low_weight_error, cut_high_weight_error); + + // For each quantization level, find the best error terms. Use packed vectors so data-dependent + // branches can become selects. This involves some integer to float casts, but the values are + // small enough so they never round the wrong way. + vfloat4 best_results[36]; + + // Initialize the array to some safe defaults + promise(max_quant_steps > 0); + for (unsigned int i = 0; i < (max_quant_steps + 4); i++) + { + // Lane<0> = Best error + // Lane<1> = Best scale; -1 indicates no solution found + // Lane<2> = Cut low weight + best_results[i] = vfloat4(ERROR_CALC_DEFAULT, -1.0f, 0.0f, 0.0f); + } + + promise(max_angular_steps > 0); + for (unsigned int i = 0; i < max_angular_steps; i++) + { + float i_flt = static_cast<float>(i); + + int idx_span = weight_span[i]; + + float error_cut_low = error[i] + cut_low_weight_error[i]; + float error_cut_high = error[i] + cut_high_weight_error[i]; + float error_cut_low_high = error[i] + cut_low_weight_error[i] + cut_high_weight_error[i]; + + // Check best error against record N + vfloat4 best_result = best_results[idx_span]; + vfloat4 new_result = vfloat4(error[i], i_flt, 0.0f, 0.0f); + vmask4 mask = vfloat4(best_result.lane<0>()) > vfloat4(error[i]); + best_results[idx_span] = select(best_result, new_result, mask); + + // Check best error against record N-1 with either cut low or cut high + best_result = best_results[idx_span - 1]; + + new_result = vfloat4(error_cut_low, i_flt, 1.0f, 0.0f); + mask = vfloat4(best_result.lane<0>()) > vfloat4(error_cut_low); + best_result = select(best_result, new_result, mask); + + new_result = vfloat4(error_cut_high, i_flt, 0.0f, 0.0f); + mask = vfloat4(best_result.lane<0>()) > vfloat4(error_cut_high); + best_results[idx_span - 1] = select(best_result, new_result, mask); + + // Check best error against record N-2 with both cut low and high + best_result = best_results[idx_span - 2]; + new_result = vfloat4(error_cut_low_high, i_flt, 1.0f, 0.0f); + mask = vfloat4(best_result.lane<0>()) > vfloat4(error_cut_low_high); + best_results[idx_span - 2] = select(best_result, new_result, mask); + } + + for (unsigned int i = 0; i <= max_quant_level; i++) + { + unsigned int q = steps_for_quant_level[i]; + int bsi = static_cast<int>(best_results[q].lane<1>()); + + // Did we find anything? +#if defined(ASTCENC_DIAGNOSTICS) + if ((bsi < 0) && print_once) + { + print_once = false; + printf("INFO: Unable to find full encoding within search error limit.\n\n"); + } +#endif + + bsi = astc::max(0, bsi); + + float lwi = lowest_weight[bsi] + best_results[q].lane<2>(); + float hwi = lwi + static_cast<float>(q) - 1.0f; + + float stepsize = 1.0f / (1.0f + static_cast<float>(bsi)); + low_value[i] = (angular_offsets[bsi] + lwi) * stepsize; + high_value[i] = (angular_offsets[bsi] + hwi) * stepsize; + } +} + +/* See header for documentation. */ +void compute_angular_endpoints_1plane( + bool only_always, + const block_size_descriptor& bsd, + const float* dec_weight_ideal_value, + unsigned int max_weight_quant, + compression_working_buffers& tmpbuf +) { + float (&low_value)[WEIGHTS_MAX_BLOCK_MODES] = tmpbuf.weight_low_value1; + float (&high_value)[WEIGHTS_MAX_BLOCK_MODES] = tmpbuf.weight_high_value1; + + float (&low_values)[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1] = tmpbuf.weight_low_values1; + float (&high_values)[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1] = tmpbuf.weight_high_values1; + + unsigned int max_decimation_modes = only_always ? bsd.decimation_mode_count_always + : bsd.decimation_mode_count_selected; + promise(max_decimation_modes > 0); + for (unsigned int i = 0; i < max_decimation_modes; i++) + { + const decimation_mode& dm = bsd.decimation_modes[i]; + if (!dm.is_ref_1_plane(static_cast<quant_method>(max_weight_quant))) + { + continue; + } + + unsigned int weight_count = bsd.get_decimation_info(i).weight_count; + + unsigned int max_precision = dm.maxprec_1plane; + if (max_precision > TUNE_MAX_ANGULAR_QUANT) + { + max_precision = TUNE_MAX_ANGULAR_QUANT; + } + + if (max_precision > max_weight_quant) + { + max_precision = max_weight_quant; + } + + compute_angular_endpoints_for_quant_levels( + weight_count, + dec_weight_ideal_value + i * BLOCK_MAX_WEIGHTS, + max_precision, low_values[i], high_values[i]); + } + + unsigned int max_block_modes = only_always ? bsd.block_mode_count_1plane_always + : bsd.block_mode_count_1plane_selected; + promise(max_block_modes > 0); + for (unsigned int i = 0; i < max_block_modes; i++) + { + const block_mode& bm = bsd.block_modes[i]; + assert(!bm.is_dual_plane); + + unsigned int quant_mode = bm.quant_mode; + unsigned int decim_mode = bm.decimation_mode; + + if (quant_mode <= TUNE_MAX_ANGULAR_QUANT) + { + low_value[i] = low_values[decim_mode][quant_mode]; + high_value[i] = high_values[decim_mode][quant_mode]; + } + else + { + low_value[i] = 0.0f; + high_value[i] = 1.0f; + } + } +} + +/* See header for documentation. */ +void compute_angular_endpoints_2planes( + const block_size_descriptor& bsd, + const float* dec_weight_ideal_value, + unsigned int max_weight_quant, + compression_working_buffers& tmpbuf +) { + float (&low_value1)[WEIGHTS_MAX_BLOCK_MODES] = tmpbuf.weight_low_value1; + float (&high_value1)[WEIGHTS_MAX_BLOCK_MODES] = tmpbuf.weight_high_value1; + float (&low_value2)[WEIGHTS_MAX_BLOCK_MODES] = tmpbuf.weight_low_value2; + float (&high_value2)[WEIGHTS_MAX_BLOCK_MODES] = tmpbuf.weight_high_value2; + + float (&low_values1)[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1] = tmpbuf.weight_low_values1; + float (&high_values1)[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1] = tmpbuf.weight_high_values1; + float (&low_values2)[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1] = tmpbuf.weight_low_values2; + float (&high_values2)[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1] = tmpbuf.weight_high_values2; + + promise(bsd.decimation_mode_count_selected > 0); + for (unsigned int i = 0; i < bsd.decimation_mode_count_selected; i++) + { + const decimation_mode& dm = bsd.decimation_modes[i]; + if (!dm.is_ref_2_plane(static_cast<quant_method>(max_weight_quant))) + { + continue; + } + + unsigned int weight_count = bsd.get_decimation_info(i).weight_count; + + unsigned int max_precision = dm.maxprec_2planes; + if (max_precision > TUNE_MAX_ANGULAR_QUANT) + { + max_precision = TUNE_MAX_ANGULAR_QUANT; + } + + if (max_precision > max_weight_quant) + { + max_precision = max_weight_quant; + } + + compute_angular_endpoints_for_quant_levels( + weight_count, + dec_weight_ideal_value + i * BLOCK_MAX_WEIGHTS, + max_precision, low_values1[i], high_values1[i]); + + compute_angular_endpoints_for_quant_levels( + weight_count, + dec_weight_ideal_value + i * BLOCK_MAX_WEIGHTS + WEIGHTS_PLANE2_OFFSET, + max_precision, low_values2[i], high_values2[i]); + } + + unsigned int start = bsd.block_mode_count_1plane_selected; + unsigned int end = bsd.block_mode_count_1plane_2plane_selected; + for (unsigned int i = start; i < end; i++) + { + const block_mode& bm = bsd.block_modes[i]; + unsigned int quant_mode = bm.quant_mode; + unsigned int decim_mode = bm.decimation_mode; + + if (quant_mode <= TUNE_MAX_ANGULAR_QUANT) + { + low_value1[i] = low_values1[decim_mode][quant_mode]; + high_value1[i] = high_values1[decim_mode][quant_mode]; + low_value2[i] = low_values2[decim_mode][quant_mode]; + high_value2[i] = high_values2[decim_mode][quant_mode]; + } + else + { + low_value1[i] = 0.0f; + high_value1[i] = 1.0f; + low_value2[i] = 0.0f; + high_value2[i] = 1.0f; + } + } +} + +#endif diff --git a/thirdparty/astcenc/astcenc_weight_quant_xfer_tables.cpp b/thirdparty/astcenc/astcenc_weight_quant_xfer_tables.cpp new file mode 100644 index 0000000000..8fdf73adc2 --- /dev/null +++ b/thirdparty/astcenc/astcenc_weight_quant_xfer_tables.cpp @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: Apache-2.0 +// ---------------------------------------------------------------------------- +// Copyright 2011-2021 Arm Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// ---------------------------------------------------------------------------- + +/** + * @brief Data tables for quantization transfer. + */ + +#include "astcenc_internal.h" + +#define _ 0 // Using _ to indicate an entry that will not be used. + +const quant_and_transfer_table quant_and_xfer_tables[12] { + // QUANT2, range 0..1 + { + {0, 64}, + {0, 1}, + {0, 64}, + {0x4000,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_, + _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_, + 0x4000} + }, + // QUANT_3, range 0..2 + { + {0, 32, 64}, + {0, 1, 2}, + {0, 32, 64}, + {0x2000,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_, + _,_,0x4000,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_, + _,_,_,_,0x4020} + }, + // QUANT_4, range 0..3 + { + {0, 21, 43, 64}, + {0, 1, 2, 3}, + {0, 21, 43, 64}, + {0x1500,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,0x2b00,_,_,_,_, + _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,0x4015,_,_,_,_,_,_,_,_,_,_,_,_, + _,_,_,_,_,_,_,_,0x402b} + }, + //QUANT_5, range 0..4 + { + {0, 16, 32, 48, 64}, + {0, 1, 2, 3, 4}, + {0, 16, 32, 48, 64}, + {0x1000,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,0x2000,_,_,_,_,_,_,_,_,_, + _,_,_,_,_,_,0x3010,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,0x4020,_,_,_, + _,_,_,_,_,_,_,_,_,_,_,_,0x4030} + }, + // QUANT_6, range 0..5 + { + {0, 12, 25, 39, 52, 64}, + {0, 2, 4, 5, 3, 1}, + {0, 64, 12, 52, 25, 39}, + {0x0c00,_,_,_,_,_,_,_,_,_,_,_,0x1900,_,_,_,_,_,_,_,_,_,_,_,_, + 0x270c,_,_,_,_,_,_,_,_,_,_,_,_,_,0x3419,_,_,_,_,_,_,_,_,_,_, + _,_,0x4027,_,_,_,_,_,_,_,_,_,_,_,0x4034} + }, + // QUANT_8, range 0..7 + { + {0, 9, 18, 27, 37, 46, 55, 64}, + {0, 1, 2, 3, 4, 5, 6, 7}, + {0, 9, 18, 27, 37, 46, 55, 64}, + {0x0900,_,_,_,_,_,_,_,_,0x1200,_,_,_,_,_,_,_,_,0x1b09,_,_, + _,_,_,_,_,_,0x2512,_,_,_,_,_,_,_,_,_,0x2e1b,_,_,_,_,_,_,_,_, + 0x3725,_,_,_,_,_,_,_,_,0x402e,_,_,_,_,_,_,_,_,0x4037} + }, + // QUANT_10, range 0..9 + { + {0, 7, 14, 21, 28, 36, 43, 50, 57, 64}, + {0, 2, 4, 6, 8, 9, 7, 5, 3, 1}, + {0, 64, 7, 57, 14, 50, 21, 43, 28, 36}, + {0x0700,_,_,_,_,_,_,0x0e00,_,_,_,_,_,_,0x1507,_,_,_,_,_,_, + 0x1c0e,_,_,_,_,_,_,0x2415,_,_,_,_,_,_,_,0x2b1c,_,_,_,_,_, + _,0x3224,_,_,_,_,_,_,0x392b,_,_,_,_,_,_,0x4032,_,_,_,_,_, + _,0x4039} + }, + // QUANT_12, range 0..11 + { + {0, 5, 11, 17, 23, 28, 36, 41, 47, 53, 59, 64}, + {0, 4, 8, 2, 6, 10, 11, 7, 3, 9, 5, 1}, + {0, 64, 17, 47, 5, 59, 23, 41, 11, 53, 28, 36}, + {0x0500,_,_,_,_,0x0b00,_,_,_,_,_,0x1105,_,_,_,_,_, + 0x170b,_,_,_,_,_,0x1c11,_,_,_,_,0x2417,_,_,_,_,_,_,_, + 0x291c,_,_,_,_,0x2f24,_,_,_,_,_,0x3529,_,_,_,_,_, + 0x3b2f,_,_,_,_,_,0x4035,_,_,_,_,0x403b} + }, + // QUANT_16, range 0..15 + { + {0, 4, 8, 12, 17, 21, 25, 29, 35, 39, 43, 47, 52, 56, 60, 64}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {0, 4, 8, 12, 17, 21, 25, 29, 35, 39, 43, 47, 52, 56, 60, 64}, + {0x0400,_,_,_,0x0800,_,_,_,0x0c04,_,_,_,0x1108,_,_,_,_, + 0x150c,_,_,_,0x1911,_,_,_,0x1d15,_,_,_,0x2319,_,_,_,_, + _,0x271d,_,_,_,0x2b23,_,_,_,0x2f27,_,_,_,0x342b,_,_,_, + _,0x382f,_,_,_,0x3c34,_,_,_,0x4038,_,_,_,0x403c} + }, + // QUANT_20, range 0..19 + { + {0, 3, 6, 9, 13, 16, 19, 23, 26, 29, 35, 38, 41, 45, 48, 51, 55, 58, 61, 64}, + {0, 4, 8, 12, 16, 2, 6, 10, 14, 18, 19, 15, 11, 7, 3, 17, 13, 9, 5, 1}, + {0, 64, 16, 48, 3, 61, 19, 45, 6, 58, 23, 41, 9, 55, 26, 38, 13, 51, 29, 35}, + {0x0300,_,_,0x0600,_,_,0x0903,_,_,0x0d06,_,_,_, + 0x1009,_,_,0x130d,_,_,0x1710,_,_,_,0x1a13,_,_, + 0x1d17,_,_,0x231a,_,_,_,_,_,0x261d,_,_,0x2923,_,_, + 0x2d26,_,_,_,0x3029,_,_,0x332d,_,_,0x3730,_,_,_, + 0x3a33,_,_,0x3d37,_,_,0x403a,_,_,0x403d} + }, + // QUANT_24, range 0..23 + { + {0, 2, 5, 8, 11, 13, 16, 19, 22, 24, 27, 30, 34, 37, 40, 42, 45, 48, 51, 53, 56, 59, 62, 64}, + {0, 8, 16, 2, 10, 18, 4, 12, 20, 6, 14, 22, 23, 15, 7, 21, 13, 5, 19, 11, 3, 17, 9, 1}, + {0, 64, 8, 56, 16, 48, 24, 40, 2, 62, 11, 53, 19, 45, 27, 37, 5, 59, 13, 51, 22, 42, 30, 34}, + {0x0200,_,0x0500,_,_,0x0802,_,_,0x0b05,_,_,0x0d08, + _,0x100b,_,_,0x130d,_,_,0x1610,_,_,0x1813,_, + 0x1b16,_,_,0x1e18,_,_,0x221b,_,_,_,0x251e,_,_, + 0x2822,_,_,0x2a25,_,0x2d28,_,_,0x302a,_,_,0x332d, + _,_,0x3530,_,0x3833,_,_,0x3b35,_,_,0x3e38,_,_, + 0x403b,_,0x403e} + }, + // QUANT_32, range 0..31 + { + {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64}, + {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}, + {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64}, + {0x0200,_,0x0400,_,0x0602,_,0x0804,_,0x0a06,_, + 0x0c08,_,0x0e0a,_,0x100c,_,0x120e,_,0x1410,_, + 0x1612,_,0x1814,_,0x1a16,_,0x1c18,_,0x1e1a,_, + 0x221c,_,_,_,0x241e,_,0x2622,_,0x2824,_,0x2a26,_, + 0x2c28,_,0x2e2a,_,0x302c,_,0x322e,_,0x3430,_, + 0x3632,_,0x3834,_,0x3a36,_,0x3c38,_,0x3e3a,_, + 0x403c,_,0x403e} + } +}; diff --git a/thirdparty/astcenc/patches/fix-build-no-ssse3.patch b/thirdparty/astcenc/patches/fix-build-no-ssse3.patch new file mode 100644 index 0000000000..9da4f3e1f3 --- /dev/null +++ b/thirdparty/astcenc/patches/fix-build-no-ssse3.patch @@ -0,0 +1,81 @@ +From 02c22d3df501dc284ba732fa82a6c408c57b3237 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= <rverschelde@gmail.com> +Date: Thu, 19 Jan 2023 23:30:13 +0100 +Subject: [PATCH] mathlib: Remove incomplete support for SSE3 which assumed + SSSE3 + +`_mm_shuffle_epi8` requires SSSE3 so the check on `ASTCENC_SSE >= 30` is +too lax and would fail if `__SSE3__` is supported, but not `__SSSE3__`. + +The only supported configurations are SSE2, SSE4.1, and AVX2, so as +discussed in #393 we drop the SSE3 checks and require SSE4.1 instead. +--- + Source/astcenc_mathlib.h | 2 -- + Source/astcenc_vecmathlib_sse_4.h | 10 +++++----- + 2 files changed, 5 insertions(+), 7 deletions(-) + +diff --git a/Source/astcenc_mathlib.h b/Source/astcenc_mathlib.h +index 67e989e..0540c4f 100644 +--- a/Source/astcenc_mathlib.h ++++ b/Source/astcenc_mathlib.h +@@ -48,8 +48,6 @@ + #define ASTCENC_SSE 42 + #elif defined(__SSE4_1__) + #define ASTCENC_SSE 41 +- #elif defined(__SSE3__) +- #define ASTCENC_SSE 30 + #elif defined(__SSE2__) + #define ASTCENC_SSE 20 + #else +diff --git a/Source/astcenc_vecmathlib_sse_4.h b/Source/astcenc_vecmathlib_sse_4.h +index 76fe577..26dcc4a 100644 +--- a/Source/astcenc_vecmathlib_sse_4.h ++++ b/Source/astcenc_vecmathlib_sse_4.h +@@ -1046,7 +1046,7 @@ ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4& t0p) + */ + ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4 t1, vint4& t0p, vint4& t1p) + { +-#if ASTCENC_SSE >= 30 ++#if ASTCENC_SSE >= 41 + t0p = t0; + t1p = t0 ^ t1; + #else +@@ -1062,7 +1062,7 @@ ASTCENC_SIMD_INLINE void vtable_prepare( + vint4 t0, vint4 t1, vint4 t2, vint4 t3, + vint4& t0p, vint4& t1p, vint4& t2p, vint4& t3p) + { +-#if ASTCENC_SSE >= 30 ++#if ASTCENC_SSE >= 41 + t0p = t0; + t1p = t0 ^ t1; + t2p = t1 ^ t2; +@@ -1080,7 +1080,7 @@ ASTCENC_SIMD_INLINE void vtable_prepare( + */ + ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 idx) + { +-#if ASTCENC_SSE >= 30 ++#if ASTCENC_SSE >= 41 + // Set index byte MSB to 1 for unused bytes so shuffle returns zero + __m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00))); + +@@ -1102,7 +1102,7 @@ ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 idx) + */ + ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 idx) + { +-#if ASTCENC_SSE >= 30 ++#if ASTCENC_SSE >= 41 + // Set index byte MSB to 1 for unused bytes so shuffle returns zero + __m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00))); + +@@ -1130,7 +1130,7 @@ ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 idx) + */ + ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 t2, vint4 t3, vint4 idx) + { +-#if ASTCENC_SSE >= 30 ++#if ASTCENC_SSE >= 41 + // Set index byte MSB to 1 for unused bytes so shuffle returns zero + __m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00))); + +-- +2.39.1 + diff --git a/thirdparty/basis_universal/encoder/basisu_comp.cpp b/thirdparty/basis_universal/encoder/basisu_comp.cpp index 166a1c4fe0..41eae2b78a 100644 --- a/thirdparty/basis_universal/encoder/basisu_comp.cpp +++ b/thirdparty/basis_universal/encoder/basisu_comp.cpp @@ -1501,7 +1501,8 @@ namespace basisu if (m_params.m_compute_stats) { - printf("Slice: %u\n", slice_index); + if (m_params.m_print_stats) + printf("Slice: %u\n", slice_index); image_stats& s = m_stats[slice_index]; @@ -1511,81 +1512,100 @@ namespace basisu // ---- .basis stats em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 3); - em.print(".basis RGB Avg: "); + if (m_params.m_print_stats) + em.print(".basis RGB Avg: "); s.m_basis_rgb_avg_psnr = em.m_psnr; em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 4); - em.print(".basis RGBA Avg: "); + if (m_params.m_print_stats) + em.print(".basis RGBA Avg: "); s.m_basis_rgba_avg_psnr = em.m_psnr; em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 1); - em.print(".basis R Avg: "); + if (m_params.m_print_stats) + em.print(".basis R Avg: "); em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 1, 1); - em.print(".basis G Avg: "); + if (m_params.m_print_stats) + em.print(".basis G Avg: "); em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 2, 1); - em.print(".basis B Avg: "); + if (m_params.m_print_stats) + em.print(".basis B Avg: "); if (m_params.m_uastc) { em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 3, 1); - em.print(".basis A Avg: "); + if (m_params.m_print_stats) + em.print(".basis A Avg: "); s.m_basis_a_avg_psnr = em.m_psnr; } em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 0); - em.print(".basis 709 Luma: "); + if (m_params.m_print_stats) + em.print(".basis 709 Luma: "); s.m_basis_luma_709_psnr = static_cast<float>(em.m_psnr); s.m_basis_luma_709_ssim = static_cast<float>(em.m_ssim); em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 0, true, true); - em.print(".basis 601 Luma: "); + if (m_params.m_print_stats) + em.print(".basis 601 Luma: "); s.m_basis_luma_601_psnr = static_cast<float>(em.m_psnr); if (m_slice_descs.size() == 1) { const uint32_t output_size = comp_size ? (uint32_t)comp_size : (uint32_t)comp_data.size(); - debug_printf(".basis RGB PSNR per bit/texel*10000: %3.3f\n", 10000.0f * s.m_basis_rgb_avg_psnr / ((output_size * 8.0f) / (slice_desc.m_orig_width * slice_desc.m_orig_height))); - debug_printf(".basis Luma 709 PSNR per bit/texel*10000: %3.3f\n", 10000.0f * s.m_basis_luma_709_psnr / ((output_size * 8.0f) / (slice_desc.m_orig_width * slice_desc.m_orig_height))); + if (m_params.m_print_stats) + { + debug_printf(".basis RGB PSNR per bit/texel*10000: %3.3f\n", 10000.0f * s.m_basis_rgb_avg_psnr / ((output_size * 8.0f) / (slice_desc.m_orig_width * slice_desc.m_orig_height))); + debug_printf(".basis Luma 709 PSNR per bit/texel*10000: %3.3f\n", 10000.0f * s.m_basis_luma_709_psnr / ((output_size * 8.0f) / (slice_desc.m_orig_width * slice_desc.m_orig_height))); + } } if (m_decoded_output_textures_unpacked_bc7[slice_index].get_width()) { // ---- BC7 stats em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 0, 3); - em.print("BC7 RGB Avg: "); + if (m_params.m_print_stats) + em.print("BC7 RGB Avg: "); s.m_bc7_rgb_avg_psnr = em.m_psnr; em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 0, 4); - em.print("BC7 RGBA Avg: "); + if (m_params.m_print_stats) + em.print("BC7 RGBA Avg: "); s.m_bc7_rgba_avg_psnr = em.m_psnr; em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 0, 1); - em.print("BC7 R Avg: "); + if (m_params.m_print_stats) + em.print("BC7 R Avg: "); em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 1, 1); - em.print("BC7 G Avg: "); + if (m_params.m_print_stats) + em.print("BC7 G Avg: "); em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 2, 1); - em.print("BC7 B Avg: "); + if (m_params.m_print_stats) + em.print("BC7 B Avg: "); if (m_params.m_uastc) { em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 3, 1); - em.print("BC7 A Avg: "); + if (m_params.m_print_stats) + em.print("BC7 A Avg: "); s.m_bc7_a_avg_psnr = em.m_psnr; } em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 0, 0); - em.print("BC7 709 Luma: "); + if (m_params.m_print_stats) + em.print("BC7 709 Luma: "); s.m_bc7_luma_709_psnr = static_cast<float>(em.m_psnr); s.m_bc7_luma_709_ssim = static_cast<float>(em.m_ssim); em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 0, 0, true, true); - em.print("BC7 601 Luma: "); + if (m_params.m_print_stats) + em.print("BC7 601 Luma: "); s.m_bc7_luma_601_psnr = static_cast<float>(em.m_psnr); } @@ -1593,16 +1613,19 @@ namespace basisu { // ---- Nearly best possible ETC1S stats em.calc(m_slice_images[slice_index], m_best_etc1s_images_unpacked[slice_index], 0, 3); - em.print("Unquantized ETC1S RGB Avg: "); + if (m_params.m_print_stats) + em.print("Unquantized ETC1S RGB Avg: "); s.m_best_etc1s_rgb_avg_psnr = static_cast<float>(em.m_psnr); em.calc(m_slice_images[slice_index], m_best_etc1s_images_unpacked[slice_index], 0, 0); - em.print("Unquantized ETC1S 709 Luma: "); + if (m_params.m_print_stats) + em.print("Unquantized ETC1S 709 Luma: "); s.m_best_etc1s_luma_709_psnr = static_cast<float>(em.m_psnr); s.m_best_etc1s_luma_709_ssim = static_cast<float>(em.m_ssim); em.calc(m_slice_images[slice_index], m_best_etc1s_images_unpacked[slice_index], 0, 0, true, true); - em.print("Unquantized ETC1S 601 Luma: "); + if (m_params.m_print_stats) + em.print("Unquantized ETC1S 601 Luma: "); s.m_best_etc1s_luma_601_psnr = static_cast<float>(em.m_psnr); } } @@ -2311,6 +2334,8 @@ namespace basisu } comp_params.m_compute_stats = (pStats != nullptr); + comp_params.m_print_stats = (flags_and_quality & cFlagPrintStats) != 0; + comp_params.m_status_output = (flags_and_quality & cFlagPrintStatus) != 0; // Create the compressor, initialize it, and process the input basis_compressor comp; @@ -2328,6 +2353,11 @@ namespace basisu return nullptr; } + if ((pStats) && (comp.get_opencl_failed())) + { + pStats->m_opencl_failed = true; + } + // Get the output file data and return it to the caller void* pFile_data = nullptr; const uint8_vec* pFile_data_vec = comp_params.m_create_ktx2_file ? &comp.get_output_ktx2_file() : &comp.get_output_basis_file(); @@ -2388,4 +2418,108 @@ namespace basisu free(p); } + bool basis_benchmark_etc1s_opencl(bool* pOpenCL_failed) + { + if (pOpenCL_failed) + *pOpenCL_failed = false; + + if (!opencl_is_available()) + { + error_printf("basis_benchmark_etc1s_opencl: OpenCL support must be enabled first!\n"); + return false; + } + + const uint32_t W = 1024, H = 1024; + basisu::vector<image> images; + image& img = images.enlarge(1)->resize(W, H); + + const uint32_t NUM_RAND_LETTERS = 6000;// 40000; + + rand r; + r.seed(200); + + for (uint32_t i = 0; i < NUM_RAND_LETTERS; i++) + { + uint32_t x = r.irand(0, W - 1), y = r.irand(0, H - 1); + uint32_t sx = r.irand(1, 4), sy = r.irand(1, 4); + color_rgba c(r.byte(), r.byte(), r.byte(), 255); + + img.debug_text(x, y, sx, sy, c, nullptr, false, "%c", static_cast<char>(r.irand(32, 127))); + } + + //save_png("test.png", img); + + image_stats stats; + + uint32_t flags_and_quality = cFlagSRGB | cFlagThreaded | 255; + size_t comp_size = 0; + + double best_cpu_time = 1e+9f, best_gpu_time = 1e+9f; + + const uint32_t TIMES_TO_ENCODE = 2; + interval_timer tm; + + for (uint32_t i = 0; i < TIMES_TO_ENCODE; i++) + { + tm.start(); + void* pComp_data = basis_compress( + images, + flags_and_quality, 1.0f, + &comp_size, + &stats); + double cpu_time = tm.get_elapsed_secs(); + if (!pComp_data) + { + error_printf("basis_benchmark_etc1s_opencl: basis_compress() failed (CPU)!\n"); + return false; + } + + best_cpu_time = minimum(best_cpu_time, cpu_time); + + basis_free_data(pComp_data); + } + + printf("Best CPU time: %3.3f\n", best_cpu_time); + + for (uint32_t i = 0; i < TIMES_TO_ENCODE; i++) + { + tm.start(); + void* pComp_data = basis_compress( + images, + flags_and_quality | cFlagUseOpenCL, 1.0f, + &comp_size, + &stats); + + if (stats.m_opencl_failed) + { + error_printf("basis_benchmark_etc1s_opencl: OpenCL failed!\n"); + + basis_free_data(pComp_data); + + if (pOpenCL_failed) + *pOpenCL_failed = true; + + return false; + } + + double gpu_time = tm.get_elapsed_secs(); + if (!pComp_data) + { + error_printf("basis_benchmark_etc1s_opencl: basis_compress() failed (GPU)!\n"); + return false; + } + + best_gpu_time = minimum(best_gpu_time, gpu_time); + + basis_free_data(pComp_data); + } + + printf("Best GPU time: %3.3f\n", best_gpu_time); + + return best_gpu_time < best_cpu_time; + } + } // namespace basisu + + + diff --git a/thirdparty/basis_universal/encoder/basisu_comp.h b/thirdparty/basis_universal/encoder/basisu_comp.h index aa5ea6fec3..b6c9fef9e2 100644 --- a/thirdparty/basis_universal/encoder/basisu_comp.h +++ b/thirdparty/basis_universal/encoder/basisu_comp.h @@ -92,6 +92,8 @@ namespace basisu m_best_etc1s_luma_709_psnr = 0.0f; m_best_etc1s_luma_601_psnr = 0.0f; m_best_etc1s_luma_709_ssim = 0.0f; + + m_opencl_failed = false; } std::string m_filename; @@ -119,6 +121,8 @@ namespace basisu float m_best_etc1s_luma_709_psnr; float m_best_etc1s_luma_601_psnr; float m_best_etc1s_luma_709_ssim; + + bool m_opencl_failed; }; template<bool def> @@ -255,6 +259,7 @@ namespace basisu m_write_output_basis_files.clear(); m_compression_level.clear(); m_compute_stats.clear(); + m_print_stats.clear(); m_check_for_alpha.clear(); m_force_alpha.clear(); m_multithreading.clear(); @@ -373,6 +378,9 @@ namespace basisu // Compute and display image metrics bool_param<false> m_compute_stats; + + // Print stats to stdout, if m_compute_stats is true. + bool_param<true> m_print_stats; // Check to see if any input image has an alpha channel, if so then the output basis file will have alpha channels bool_param<true> m_check_for_alpha; @@ -583,11 +591,16 @@ namespace basisu cFlagYFlip = 1 << 16, // flip source image on Y axis before compression cFlagUASTC = 1 << 17, // use UASTC compression vs. ETC1S - cFlagUASTCRDO = 1 << 18 // use RDO postprocessing when generating UASTC files (must set uastc_rdo_quality to the quality scalar) + cFlagUASTCRDO = 1 << 18, // use RDO postprocessing when generating UASTC files (must set uastc_rdo_quality to the quality scalar) + + cFlagPrintStats = 1 << 19, // print image stats to stdout + cFlagPrintStatus = 1 << 20 // print status to stdout }; // This function accepts an array of source images. // If more than one image is provided, it's assumed the images form a mipmap pyramid and automatic mipmap generation is disabled. + // Returns a pointer to the compressed .basis or .ktx2 file data. *pSize is the size of the compressed data. The returned block must be freed using basis_free_data(). + // basisu_encoder_init() MUST be called first! void* basis_compress( const basisu::vector<image> &source_images, uint32_t flags_and_quality, float uastc_rdo_quality, @@ -604,6 +617,12 @@ namespace basisu // Frees the dynamically allocated file data returned by basis_compress(). void basis_free_data(void* p); + // Runs a short benchmark using synthetic image data to time OpenCL encoding vs. CPU encoding, with multithreading enabled. + // Returns true if opencl is worth using on this system, otherwise false. + // If pOpenCL_failed is not null, it will be set to true if OpenCL encoding failed *on this particular machine/driver/BasisU version* and the encoder falled back to CPU encoding. + // basisu_encoder_init() MUST be called first. If OpenCL support wasn't enabled this always returns false. + bool basis_benchmark_etc1s_opencl(bool *pOpenCL_failed = nullptr); + // Parallel compression API struct parallel_results { diff --git a/thirdparty/basis_universal/encoder/basisu_enc.cpp b/thirdparty/basis_universal/encoder/basisu_enc.cpp index b427215ee3..c431ceaf12 100644 --- a/thirdparty/basis_universal/encoder/basisu_enc.cpp +++ b/thirdparty/basis_universal/encoder/basisu_enc.cpp @@ -187,6 +187,8 @@ namespace basisu opencl_init(opencl_force_serialization); } + interval_timer::init(); // make sure interval_timer globals are initialized from main thread to avoid TSAN reports + g_library_initialized = true; } @@ -227,7 +229,7 @@ namespace basisu { QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER*>(pTicks)); } -#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__EMSCRIPTEN__) #include <sys/time.h> inline void query_counter(timer_ticks* pTicks) { diff --git a/thirdparty/basis_universal/encoder/basisu_frontend.cpp b/thirdparty/basis_universal/encoder/basisu_frontend.cpp index 00210e6679..1f30a33c70 100644 --- a/thirdparty/basis_universal/encoder/basisu_frontend.cpp +++ b/thirdparty/basis_universal/encoder/basisu_frontend.cpp @@ -2328,8 +2328,6 @@ namespace basisu m_optimized_cluster_selectors.resize(total_selector_clusters); - uint32_t total_clusters_processed = 0; - // For each selector codebook entry, and for each of the 4x4 selectors, determine which selector minimizes the error across all the blocks that use that quantized selector. const uint32_t N = 256; for (uint32_t cluster_index_iter = 0; cluster_index_iter < total_selector_clusters; cluster_index_iter += N) @@ -2338,7 +2336,7 @@ namespace basisu const uint32_t last_index = minimum<uint32_t>((uint32_t)total_selector_clusters, cluster_index_iter + N); #ifndef __EMSCRIPTEN__ - m_params.m_pJob_pool->add_job([this, first_index, last_index, &total_clusters_processed, &total_selector_clusters] { + m_params.m_pJob_pool->add_job([this, first_index, last_index] { #endif for (uint32_t cluster_index = first_index; cluster_index < last_index; cluster_index++) diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp b/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp index 630731900f..3aeba0ee7a 100644 --- a/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp @@ -16867,7 +16867,7 @@ namespace basist { m_format = basist::basis_tex_format::cETC1S; - // 3.10.2: "Whether the image has 1 or 2 slices can be determined from the DFD’s sample count." + // 3.10.2: "Whether the image has 1 or 2 slices can be determined from the DFD's sample count." // If m_has_alpha is true it may be 2-channel RRRG or 4-channel RGBA, but we let the caller deal with that. m_has_alpha = (m_header.m_dfd_byte_length == 60); diff --git a/thirdparty/certs/ca-certificates.crt b/thirdparty/certs/ca-certificates.crt index 036f630d5b..5ed6adf574 100644 --- a/thirdparty/certs/ca-certificates.crt +++ b/thirdparty/certs/ca-certificates.crt @@ -1,7 +1,7 @@ ## ## Bundle of CA Root Certificates ## -## Certificate data from Mozilla as of: Tue Jul 19 14:20:01 2022 GMT +## Certificate data from Mozilla as of: Fri Oct 21 16:14:43 2022 GMT ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates @@ -14,7 +14,7 @@ ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.29. -## SHA256: 9bf3799611fb58197f61d45e71ce3dc19f30e7dd73731915872ce5108a7bb066 +## SHA256: 3ff8bd209b5f2e739b9f2b96eacb694a774114685b02978257824f37ff528f71 ## @@ -3458,3 +3458,49 @@ zPUwHQYDVR0OBBYEFP+CMXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO PQQDAwNpADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/67W4W Aie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFxvmjkI6TZraE3 -----END CERTIFICATE----- + +Security Communication RootCA3 +============================== +-----BEGIN CERTIFICATE----- +MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNVBAYTAkpQMSUw +IwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScwJQYDVQQDEx5TZWN1cml0eSBD +b21tdW5pY2F0aW9uIFJvb3RDQTMwHhcNMTYwNjE2MDYxNzE2WhcNMzgwMTE4MDYxNzE2WjBdMQsw +CQYDVQQGEwJKUDElMCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UE +AxMeU2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEA48lySfcw3gl8qUCBWNO0Ot26YQ+TUG5pPDXC7ltzkBtnTCHsXzW7OT4rCmDvu20r +hvtxosis5FaU+cmvsXLUIKx00rgVrVH+hXShuRD+BYD5UpOzQD11EKzAlrenfna84xtSGc4RHwsE +NPXY9Wk8d/Nk9A2qhd7gCVAEF5aEt8iKvE1y/By7z/MGTfmfZPd+pmaGNXHIEYBMwXFAWB6+oHP2 +/D5Q4eAvJj1+XCO1eXDe+uDRpdYMQXF79+qMHIjH7Iv10S9VlkZ8WjtYO/u62C21Jdp6Ts9EriGm +npjKIG58u4iFW/vAEGK78vknR+/RiTlDxN/e4UG/VHMgly1s2vPUB6PmudhvrvyMGS7TZ2crldtY +XLVqAvO4g160a75BflcJdURQVc1aEWEhCmHCqYj9E7wtiS/NYeCVvsq1e+F7NGcLH7YMx3weGVPK +p7FKFSBWFHA9K4IsD50VHUeAR/94mQ4xr28+j+2GaR57GIgUssL8gjMunEst+3A7caoreyYn8xrC +3PsXuKHqy6C0rtOUfnrQq8PsOC0RLoi/1D+tEjtCrI8Cbn3M0V9hvqG8OmpI6iZVIhZdXw3/JzOf +GAN0iltSIEdrRU0id4xVJ/CvHozJgyJUt5rQT9nO/NkuHJYosQLTA70lUhw0Zk8jq/R3gpYd0Vcw +CBEF/VfR2ccCAwEAAaNCMEAwHQYDVR0OBBYEFGQUfPxYchamCik0FW8qy7z8r6irMA4GA1UdDwEB +/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQDcAiMI4u8hOscNtybS +YpOnpSNyByCCYN8Y11StaSWSntkUz5m5UoHPrmyKO1o5yGwBQ8IibQLwYs1OY0PAFNr0Y/Dq9HHu +Tofjcan0yVflLl8cebsjqodEV+m9NU1Bu0soo5iyG9kLFwfl9+qd9XbXv8S2gVj/yP9kaWJ5rW4O +H3/uHWnlt3Jxs/6lATWUVCvAUm2PVcTJ0rjLyjQIUYWg9by0F1jqClx6vWPGOi//lkkZhOpn2ASx +YfQAW0q3nHE3GYV5v4GwxxMOdnE+OoAGrgYWp421wsTL/0ClXI2lyTrtcoHKXJg80jQDdwj98ClZ +XSEIx2C/pHF7uNkegr4Jr2VvKKu/S7XuPghHJ6APbw+LP6yVGPO5DtxnVW5inkYO0QR4ynKudtml ++LLfiAlhi+8kTtFZP1rUPcmTPCtk9YENFpb3ksP+MW/oKjJ0DvRMmEoYDjBU1cXrvMUVnuiZIesn +KwkK2/HmcBhWuwzkvvnoEKQTkrgc4NtnHVMDpCKn3F2SEDzq//wbEBrD2NCcnWXL0CsnMQMeNuE9 +dnUM/0Umud1RvCPHX9jYhxBAEg09ODfnRDwYwFMJZI//1ZqmfHAuc1Uh6N//g7kdPjIe1qZ9LPFm +6Vwdp6POXiUyK+OVrCoHzrQoeIY8LaadTdJ0MN1kURXbg4NR16/9M51NZg== +-----END CERTIFICATE----- + +Security Communication ECC RootCA1 +================================== +-----BEGIN CERTIFICATE----- +MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYTAkpQMSUwIwYD +VQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYDVQQDEyJTZWN1cml0eSBDb21t +dW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYxNjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTEL +MAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNV +BAMTIlNlY3VyaXR5IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+CnnfdldB9sELLo +5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpKULGjQjBAMB0GA1UdDgQW +BBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAK +BggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3L +snNdo4gIxwwCMQDAqy0Obe0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70e +N9k= +-----END CERTIFICATE----- diff --git a/thirdparty/cvtt/ConvectionKernels_BC67.cpp b/thirdparty/cvtt/ConvectionKernels_BC67.cpp index 791859b232..021d658c08 100644 --- a/thirdparty/cvtt/ConvectionKernels_BC67.cpp +++ b/thirdparty/cvtt/ConvectionKernels_BC67.cpp @@ -726,10 +726,10 @@ namespace cvtt if (carry) { uint32_t bitMask = (1 << carry) - 1; - for (int i = 0; i < 4; i++) + for (int i = 0; i < entriesRemaining; i++) { m_vector[i] >>= carry; - if (i != 3) + if (i != entriesRemaining - 1) m_vector[i] |= (m_vector[i + 1] & bitMask) << (32 - carry); } } @@ -3058,14 +3058,11 @@ void cvtt::Internal::BC6HComputer::SignExtendSingle(int &v, int bits) void cvtt::Internal::BC6HComputer::UnpackOne(PixelBlockF16 &output, const uint8_t *pBC, bool isSigned) { - UnpackingVector pv; - pv.Init(pBC); - int numModeBits = 2; - int modeBits = pv.Unpack(2); + int modeBits = pBC[0] & 0x3; if (modeBits != 0 && modeBits != 1) { - modeBits |= pv.Unpack(3) << 2; + modeBits = pBC[0] & 0x1f; numModeBits += 3; } @@ -3102,6 +3099,9 @@ void cvtt::Internal::BC6HComputer::UnpackOne(PixelBlockF16 &output, const uint8_ for (int ch = 0; ch < 3; ch++) eps[subset][epi][ch] = 0; + UnpackingVector pv; + pv.Init(pBC); + { uint32_t header[3]; uint16_t codedEPs[2][2][3]; diff --git a/thirdparty/embree/common/algorithms/parallel_for.h b/thirdparty/embree/common/algorithms/parallel_for.h index 645681ac63..6d411e4852 100644 --- a/thirdparty/embree/common/algorithms/parallel_for.h +++ b/thirdparty/embree/common/algorithms/parallel_for.h @@ -26,7 +26,6 @@ namespace embree abort(); // -- GODOT end -- } - #elif defined(TASKING_TBB) #if TBB_INTERFACE_VERSION >= 12002 tbb::task_group_context context; diff --git a/thirdparty/embree/common/algorithms/parallel_for_for.h b/thirdparty/embree/common/algorithms/parallel_for_for.h index 92c37a4a38..7838ef11b3 100644 --- a/thirdparty/embree/common/algorithms/parallel_for_for.h +++ b/thirdparty/embree/common/algorithms/parallel_for_for.h @@ -30,15 +30,20 @@ namespace embree template<typename ArrayArray> __forceinline ParallelForForState (ArrayArray& array2, const size_t minStepSize) { init(array2,minStepSize); + } + + template<typename SizeFunc> + __forceinline ParallelForForState (const size_t numArrays, const SizeFunc& getSize, const size_t minStepSize) { + init(numArrays,getSize,minStepSize); } - template<typename ArrayArray> - __forceinline void init ( ArrayArray& array2, const size_t minStepSize ) + template<typename SizeFunc> + __forceinline void init ( const size_t numArrays, const SizeFunc& getSize, const size_t minStepSize ) { /* first calculate total number of elements */ size_t N = 0; - for (size_t i=0; i<array2.size(); i++) { - N += array2[i] ? array2[i]->size() : 0; + for (size_t i=0; i<numArrays; i++) { + N += getSize(i); } this->N = N; @@ -54,8 +59,8 @@ namespace embree size_t k0 = (++taskIndex)*N/taskCount; for (size_t i=0, k=0; taskIndex < taskCount; i++) { - assert(i<array2.size()); - size_t j=0, M = array2[i] ? array2[i]->size() : 0; + assert(i<numArrays); + size_t j=0, M = getSize(i); while (j<M && k+M-j >= k0 && taskIndex < taskCount) { assert(taskIndex<taskCount); i0[taskIndex] = i; @@ -67,6 +72,12 @@ namespace embree } } + template<typename ArrayArray> + __forceinline void init ( ArrayArray& array2, const size_t minStepSize ) + { + init(array2.size(),[&](size_t i) { return array2[i] ? array2[i]->size() : 0; },minStepSize); + } + __forceinline size_t size() const { return N; } diff --git a/thirdparty/embree/common/algorithms/parallel_for_for_prefix_sum.h b/thirdparty/embree/common/algorithms/parallel_for_for_prefix_sum.h index b15b44a991..8c3f4aace7 100644 --- a/thirdparty/embree/common/algorithms/parallel_for_for_prefix_sum.h +++ b/thirdparty/embree/common/algorithms/parallel_for_for_prefix_sum.h @@ -17,15 +17,20 @@ namespace embree __forceinline ParallelForForPrefixSumState (ArrayArray& array2, const size_t minStepSize) : ParallelForForState(array2,minStepSize) {} + template<typename SizeFunc> + __forceinline ParallelForForPrefixSumState (size_t numArrays, const SizeFunc& getSize, const size_t minStepSize) + : ParallelForForState(numArrays,getSize,minStepSize) {} + ParallelPrefixSumState<Value> prefix_state; }; - template<typename ArrayArray, typename Index, typename Value, typename Func, typename Reduction> - __forceinline Value parallel_for_for_prefix_sum0( ParallelForForPrefixSumState<Value>& state, ArrayArray& array2, Index minStepSize, - const Value& identity, const Func& func, const Reduction& reduction) + template<typename SizeFunc, typename Index, typename Value, typename Func, typename Reduction> + __forceinline Value parallel_for_for_prefix_sum0_( ParallelForForPrefixSumState<Value>& state, Index minStepSize, + const SizeFunc& getSize, const Value& identity, const Func& func, const Reduction& reduction) { /* calculate number of tasks to use */ const size_t taskCount = state.taskCount; + /* perform parallel prefix sum */ parallel_for(taskCount, [&](const size_t taskIndex) { @@ -38,9 +43,9 @@ namespace embree size_t k=k0; Value N=identity; for (size_t i=i0; k<k1; i++) { - const size_t size = array2[i] ? array2[i]->size() : 0; + const size_t size = getSize(i); const size_t r0 = j0, r1 = min(size,r0+k1-k); - if (r1 > r0) N = reduction(N, func(array2[i],range<Index>((Index)r0,(Index)r1),(Index)k,(Index)i)); + if (r1 > r0) N = reduction(N, func((Index)i,range<Index>((Index)r0,(Index)r1),(Index)k)); k+=r1-r0; j0 = 0; } state.prefix_state.counts[taskIndex] = N; @@ -58,9 +63,10 @@ namespace embree return sum; } - template<typename ArrayArray, typename Index, typename Value, typename Func, typename Reduction> - __forceinline Value parallel_for_for_prefix_sum1( ParallelForForPrefixSumState<Value>& state, ArrayArray& array2, Index minStepSize, - const Value& identity, const Func& func, const Reduction& reduction) + template<typename SizeFunc, typename Index, typename Value, typename Func, typename Reduction> + __forceinline Value parallel_for_for_prefix_sum1_( ParallelForForPrefixSumState<Value>& state, Index minStepSize, + const SizeFunc& getSize, + const Value& identity, const Func& func, const Reduction& reduction) { /* calculate number of tasks to use */ const size_t taskCount = state.taskCount; @@ -76,9 +82,9 @@ namespace embree size_t k=k0; Value N=identity; for (size_t i=i0; k<k1; i++) { - const size_t size = array2[i] ? array2[i]->size() : 0; + const size_t size = getSize(i); const size_t r0 = j0, r1 = min(size,r0+k1-k); - if (r1 > r0) N = reduction(N, func(array2[i],range<Index>((Index)r0,(Index)r1),(Index)k,(Index)i,reduction(state.prefix_state.sums[taskIndex],N))); + if (r1 > r0) N = reduction(N, func((Index)i,range<Index>((Index)r0,(Index)r1),(Index)k,reduction(state.prefix_state.sums[taskIndex],N))); k+=r1-r0; j0 = 0; } state.prefix_state.counts[taskIndex] = N; @@ -96,6 +102,30 @@ namespace embree return sum; } + template<typename ArrayArray, typename Index, typename Value, typename Func, typename Reduction> + __forceinline Value parallel_for_for_prefix_sum0( ParallelForForPrefixSumState<Value>& state, + ArrayArray& array2, Index minStepSize, + const Value& identity, const Func& func, const Reduction& reduction) + { + return parallel_for_for_prefix_sum0_(state,minStepSize, + [&](Index i) { return array2[i] ? array2[i]->size() : 0; }, + identity, + [&](Index i, const range<Index>& r, Index k) { return func(array2[i], r, k, i); }, + reduction); + } + + template<typename ArrayArray, typename Index, typename Value, typename Func, typename Reduction> + __forceinline Value parallel_for_for_prefix_sum1( ParallelForForPrefixSumState<Value>& state, + ArrayArray& array2, Index minStepSize, + const Value& identity, const Func& func, const Reduction& reduction) + { + return parallel_for_for_prefix_sum1_(state,minStepSize, + [&](Index i) { return array2[i] ? array2[i]->size() : 0; }, + identity, + [&](Index i, const range<Index>& r, Index k, const Value& base) { return func(array2[i], r, k, i, base); }, + reduction); + } + template<typename ArrayArray, typename Value, typename Func, typename Reduction> __forceinline Value parallel_for_for_prefix_sum0( ParallelForForPrefixSumState<Value>& state, ArrayArray& array2, const Value& identity, const Func& func, const Reduction& reduction) diff --git a/thirdparty/embree/common/algorithms/parallel_reduce.h b/thirdparty/embree/common/algorithms/parallel_reduce.h index 8271372ea4..cd0078f2e6 100644 --- a/thirdparty/embree/common/algorithms/parallel_reduce.h +++ b/thirdparty/embree/common/algorithms/parallel_reduce.h @@ -26,7 +26,7 @@ namespace embree const Index threadCount = (Index) TaskScheduler::threadCount(); taskCount = min(taskCount,threadCount,maxTasks); - /* parallel invokation of all tasks */ + /* parallel invocation of all tasks */ dynamic_large_stack_array(Value,values,taskCount,8192); // consumes at most 8192 bytes on the stack parallel_for(taskCount, [&](const Index taskIndex) { const Index k0 = first+(taskIndex+0)*(last-first)/taskCount; diff --git a/thirdparty/embree/common/math/bbox.h b/thirdparty/embree/common/math/bbox.h index bc43155358..e4eb3df9a4 100644 --- a/thirdparty/embree/common/math/bbox.h +++ b/thirdparty/embree/common/math/bbox.h @@ -77,7 +77,7 @@ namespace embree return lower > upper; } -#if defined(__SSE__) +#if defined(__SSE__) || defined(__ARM_NEON) template<> __forceinline bool BBox<Vec3fa>::empty() const { return !all(le_mask(lower,upper)); } @@ -196,11 +196,11 @@ namespace embree } template<> __inline bool subset( const BBox<Vec3fa>& a, const BBox<Vec3fa>& b ) { - return all(ge_mask(a.lower,b.lower)) & all(le_mask(a.upper,b.upper)); + return all(ge_mask(a.lower,b.lower)) && all(le_mask(a.upper,b.upper)); } template<> __inline bool subset( const BBox<Vec3fx>& a, const BBox<Vec3fx>& b ) { - return all(ge_mask(a.lower,b.lower)) & all(le_mask(a.upper,b.upper)); + return all(ge_mask(a.lower,b.lower)) && all(le_mask(a.upper,b.upper)); } /*! blending */ @@ -228,11 +228,11 @@ namespace embree /// SSE / AVX / MIC specializations //////////////////////////////////////////////////////////////////////////////// -#if defined __SSE__ +#if defined (__SSE__) || defined(__ARM_NEON) #include "../simd/sse.h" #endif -#if defined __AVX__ +#if defined (__AVX__) #include "../simd/avx.h" #endif diff --git a/thirdparty/embree/common/math/color.h b/thirdparty/embree/common/math/color.h index 529584ea16..e62e4ad2a4 100644 --- a/thirdparty/embree/common/math/color.h +++ b/thirdparty/embree/common/math/color.h @@ -152,21 +152,38 @@ namespace embree } __forceinline const Color rcp ( const Color& a ) { +#if defined(__aarch64__) + __m128 reciprocal = _mm_rcp_ps(a.m128); + reciprocal = vmulq_f32(vrecpsq_f32(a.m128, reciprocal), reciprocal); + reciprocal = vmulq_f32(vrecpsq_f32(a.m128, reciprocal), reciprocal); + return (const Color)reciprocal; +#else #if defined(__AVX512VL__) const Color r = _mm_rcp14_ps(a.m128); #else const Color r = _mm_rcp_ps(a.m128); #endif - return _mm_sub_ps(_mm_add_ps(r, r), _mm_mul_ps(_mm_mul_ps(r, r), a)); + return _mm_add_ps(r,_mm_mul_ps(r, _mm_sub_ps(_mm_set1_ps(1.0f), _mm_mul_ps(a, r)))); // computes r + r * (1 - a * r) + +#endif //defined(__aarch64__) } __forceinline const Color rsqrt( const Color& a ) { +#if defined(__aarch64__) + __m128 r = _mm_rsqrt_ps(a.m128); + r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a.m128, r), r)); + r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a.m128, r), r)); + return r; +#else + #if defined(__AVX512VL__) __m128 r = _mm_rsqrt14_ps(a.m128); #else __m128 r = _mm_rsqrt_ps(a.m128); #endif return _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.5f),r), _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); + +#endif //defined(__aarch64__) } __forceinline const Color sqrt ( const Color& a ) { return _mm_sqrt_ps(a.m128); } diff --git a/thirdparty/embree/common/math/constants.cpp b/thirdparty/embree/common/math/constants.cpp index 03919ae20c..f51c642bfc 100644 --- a/thirdparty/embree/common/math/constants.cpp +++ b/thirdparty/embree/common/math/constants.cpp @@ -5,23 +5,4 @@ namespace embree { - TrueTy True; - FalseTy False; - ZeroTy zero; - OneTy one; - NegInfTy neg_inf; - PosInfTy inf; - PosInfTy pos_inf; - NaNTy nan; - UlpTy ulp; - PiTy pi; - OneOverPiTy one_over_pi; - TwoPiTy two_pi; - OneOverTwoPiTy one_over_two_pi; - FourPiTy four_pi; - OneOverFourPiTy one_over_four_pi; - StepTy step; - ReverseStepTy reverse_step; - EmptyTy empty; - UndefinedTy undefined; } diff --git a/thirdparty/embree/common/math/constants.h b/thirdparty/embree/common/math/constants.h index 578473a8ab..07a1a868ba 100644 --- a/thirdparty/embree/common/math/constants.h +++ b/thirdparty/embree/common/math/constants.h @@ -24,13 +24,13 @@ namespace embree __forceinline operator bool( ) const { return true; } }; - extern MAYBE_UNUSED TrueTy True; + const constexpr TrueTy True = TrueTy(); struct FalseTy { __forceinline operator bool( ) const { return false; } }; - extern MAYBE_UNUSED FalseTy False; + const constexpr FalseTy False = FalseTy(); struct ZeroTy { @@ -48,7 +48,7 @@ namespace embree __forceinline operator unsigned char ( ) const { return 0; } }; - extern MAYBE_UNUSED ZeroTy zero; + const constexpr ZeroTy zero = ZeroTy(); struct OneTy { @@ -66,7 +66,7 @@ namespace embree __forceinline operator unsigned char ( ) const { return 1; } }; - extern MAYBE_UNUSED OneTy one; + const constexpr OneTy one = OneTy(); struct NegInfTy { @@ -85,7 +85,7 @@ namespace embree }; - extern MAYBE_UNUSED NegInfTy neg_inf; + const constexpr NegInfTy neg_inf = NegInfTy(); struct PosInfTy { @@ -103,8 +103,8 @@ namespace embree __forceinline operator unsigned char ( ) const { return std::numeric_limits<unsigned char>::max(); } }; - extern MAYBE_UNUSED PosInfTy inf; - extern MAYBE_UNUSED PosInfTy pos_inf; + const constexpr PosInfTy inf = PosInfTy(); + const constexpr PosInfTy pos_inf = PosInfTy(); struct NaNTy { @@ -112,15 +112,15 @@ namespace embree __forceinline operator float ( ) const { return std::numeric_limits<float>::quiet_NaN(); } }; - extern MAYBE_UNUSED NaNTy nan; + const constexpr NaNTy nan = NaNTy(); struct UlpTy { __forceinline operator double( ) const { return std::numeric_limits<double>::epsilon(); } __forceinline operator float ( ) const { return std::numeric_limits<float>::epsilon(); } }; - - extern MAYBE_UNUSED UlpTy ulp; + + const constexpr UlpTy ulp = UlpTy(); struct PiTy { @@ -128,7 +128,7 @@ namespace embree __forceinline operator float ( ) const { return float(M_PI); } }; - extern MAYBE_UNUSED PiTy pi; + const constexpr PiTy pi = PiTy(); struct OneOverPiTy { @@ -136,7 +136,7 @@ namespace embree __forceinline operator float ( ) const { return float(M_1_PI); } }; - extern MAYBE_UNUSED OneOverPiTy one_over_pi; + const constexpr OneOverPiTy one_over_pi = OneOverPiTy(); struct TwoPiTy { @@ -144,7 +144,7 @@ namespace embree __forceinline operator float ( ) const { return float(2.0*M_PI); } }; - extern MAYBE_UNUSED TwoPiTy two_pi; + const constexpr TwoPiTy two_pi = TwoPiTy(); struct OneOverTwoPiTy { @@ -152,7 +152,7 @@ namespace embree __forceinline operator float ( ) const { return float(0.5*M_1_PI); } }; - extern MAYBE_UNUSED OneOverTwoPiTy one_over_two_pi; + const constexpr OneOverTwoPiTy one_over_two_pi = OneOverTwoPiTy(); struct FourPiTy { @@ -160,7 +160,7 @@ namespace embree __forceinline operator float ( ) const { return float(4.0*M_PI); } }; - extern MAYBE_UNUSED FourPiTy four_pi; + const constexpr FourPiTy four_pi = FourPiTy(); struct OneOverFourPiTy { @@ -168,30 +168,42 @@ namespace embree __forceinline operator float ( ) const { return float(0.25*M_1_PI); } }; - extern MAYBE_UNUSED OneOverFourPiTy one_over_four_pi; + const constexpr OneOverFourPiTy one_over_four_pi = OneOverFourPiTy(); struct StepTy { + __forceinline operator double ( ) const { return 0; } + __forceinline operator float ( ) const { return 0; } + __forceinline operator long long( ) const { return 0; } + __forceinline operator unsigned long long( ) const { return 0; } + __forceinline operator long ( ) const { return 0; } + __forceinline operator unsigned long ( ) const { return 0; } + __forceinline operator int ( ) const { return 0; } + __forceinline operator unsigned int ( ) const { return 0; } + __forceinline operator short ( ) const { return 0; } + __forceinline operator unsigned short ( ) const { return 0; } + __forceinline operator char ( ) const { return 0; } + __forceinline operator unsigned char ( ) const { return 0; } }; - extern MAYBE_UNUSED StepTy step; + const constexpr StepTy step = StepTy(); struct ReverseStepTy { }; - extern MAYBE_UNUSED ReverseStepTy reverse_step; + const constexpr ReverseStepTy reverse_step = ReverseStepTy(); struct EmptyTy { }; - extern MAYBE_UNUSED EmptyTy empty; + const constexpr EmptyTy empty = EmptyTy(); struct FullTy { }; - extern MAYBE_UNUSED FullTy full; + const constexpr FullTy full = FullTy(); struct UndefinedTy { }; - extern MAYBE_UNUSED UndefinedTy undefined; + const constexpr UndefinedTy undefined = UndefinedTy(); } diff --git a/thirdparty/embree/common/math/math.h b/thirdparty/embree/common/math/math.h index 4bc54c1a6a..7930c17727 100644 --- a/thirdparty/embree/common/math/math.h +++ b/thirdparty/embree/common/math/math.h @@ -53,6 +53,16 @@ namespace embree __forceinline float rcp ( const float x ) { +#if defined(__aarch64__) + // Move scalar to vector register and do rcp. + __m128 a; + a[0] = x; + float32x4_t reciprocal = vrecpeq_f32(a); + reciprocal = vmulq_f32(vrecpsq_f32(a, reciprocal), reciprocal); + reciprocal = vmulq_f32(vrecpsq_f32(a, reciprocal), reciprocal); + return reciprocal[0]; +#else + const __m128 a = _mm_set_ss(x); #if defined(__AVX512VL__) @@ -66,30 +76,71 @@ namespace embree #else return _mm_cvtss_f32(_mm_mul_ss(r,_mm_sub_ss(_mm_set_ss(2.0f), _mm_mul_ss(r, a)))); #endif + +#endif //defined(__aarch64__) } __forceinline float signmsk ( const float x ) { +#if defined(__aarch64__) + // FP and Neon shares same vector register in arm64 + __m128 a; + __m128i b; + a[0] = x; + b[0] = 0x80000000; + a = _mm_and_ps(a, vreinterpretq_f32_s32(b)); + return a[0]; +#else return _mm_cvtss_f32(_mm_and_ps(_mm_set_ss(x),_mm_castsi128_ps(_mm_set1_epi32(0x80000000)))); +#endif } __forceinline float xorf( const float x, const float y ) { +#if defined(__aarch64__) + // FP and Neon shares same vector register in arm64 + __m128 a; + __m128 b; + a[0] = x; + b[0] = y; + a = _mm_xor_ps(a, b); + return a[0]; +#else return _mm_cvtss_f32(_mm_xor_ps(_mm_set_ss(x),_mm_set_ss(y))); +#endif } __forceinline float andf( const float x, const unsigned y ) { +#if defined(__aarch64__) + // FP and Neon shares same vector register in arm64 + __m128 a; + __m128i b; + a[0] = x; + b[0] = y; + a = _mm_and_ps(a, vreinterpretq_f32_s32(b)); + return a[0]; +#else return _mm_cvtss_f32(_mm_and_ps(_mm_set_ss(x),_mm_castsi128_ps(_mm_set1_epi32(y)))); +#endif } __forceinline float rsqrt( const float x ) { +#if defined(__aarch64__) + // FP and Neon shares same vector register in arm64 + __m128 a; + a[0] = x; + __m128 value = _mm_rsqrt_ps(a); + value = vmulq_f32(value, vrsqrtsq_f32(vmulq_f32(a, value), value)); + value = vmulq_f32(value, vrsqrtsq_f32(vmulq_f32(a, value), value)); + return value[0]; +#else + const __m128 a = _mm_set_ss(x); #if defined(__AVX512VL__) __m128 r = _mm_rsqrt14_ss(_mm_set_ss(0.0f),a); #else __m128 r = _mm_rsqrt_ss(a); #endif - r = _mm_add_ss(_mm_mul_ss(_mm_set_ss(1.5f), r), _mm_mul_ss(_mm_mul_ss(_mm_mul_ss(a, _mm_set_ss(-0.5f)), r), _mm_mul_ss(r, r))); -#if defined(__ARM_NEON) - r = _mm_add_ss(_mm_mul_ss(_mm_set_ss(1.5f), r), _mm_mul_ss(_mm_mul_ss(_mm_mul_ss(a, _mm_set_ss(-0.5f)), r), _mm_mul_ss(r, r))); + const __m128 c = _mm_add_ss(_mm_mul_ss(_mm_set_ss(1.5f), r), + _mm_mul_ss(_mm_mul_ss(_mm_mul_ss(a, _mm_set_ss(-0.5f)), r), _mm_mul_ss(r, r))); + return _mm_cvtss_f32(c); #endif - return _mm_cvtss_f32(r); } #if defined(__WIN32__) && defined(_MSC_VER) && (_MSC_VER <= 1700) @@ -146,7 +197,17 @@ namespace embree __forceinline double floor( const double x ) { return ::floor (x); } __forceinline double ceil ( const double x ) { return ::ceil (x); } -#if defined(__SSE4_1__) +#if defined(__aarch64__) + __forceinline float mini(float a, float b) { + // FP and Neon shares same vector register in arm64 + __m128 x; + __m128 y; + x[0] = a; + y[0] = b; + x = _mm_min_ps(x, y); + return x[0]; + } +#elif defined(__SSE4_1__) __forceinline float mini(float a, float b) { const __m128i ai = _mm_castps_si128(_mm_set_ss(a)); const __m128i bi = _mm_castps_si128(_mm_set_ss(b)); @@ -155,7 +216,17 @@ namespace embree } #endif -#if defined(__SSE4_1__) +#if defined(__aarch64__) + __forceinline float maxi(float a, float b) { + // FP and Neon shares same vector register in arm64 + __m128 x; + __m128 y; + x[0] = a; + y[0] = b; + x = _mm_max_ps(x, y); + return x[0]; + } +#elif defined(__SSE4_1__) __forceinline float maxi(float a, float b) { const __m128i ai = _mm_castps_si128(_mm_set_ss(a)); const __m128i bi = _mm_castps_si128(_mm_set_ss(b)); @@ -172,9 +243,12 @@ namespace embree __forceinline int64_t min(int64_t a, int64_t b) { return a<b ? a:b; } __forceinline float min(float a, float b) { return a<b ? a:b; } __forceinline double min(double a, double b) { return a<b ? a:b; } -#if defined(__64BIT__) +#if defined(__64BIT__) || defined(__EMSCRIPTEN__) __forceinline size_t min(size_t a, size_t b) { return a<b ? a:b; } #endif +#if defined(__EMSCRIPTEN__) + __forceinline long min(long a, long b) { return a<b ? a:b; } +#endif template<typename T> __forceinline T min(const T& a, const T& b, const T& c) { return min(min(a,b),c); } template<typename T> __forceinline T min(const T& a, const T& b, const T& c, const T& d) { return min(min(a,b),min(c,d)); } @@ -189,9 +263,12 @@ namespace embree __forceinline int64_t max(int64_t a, int64_t b) { return a<b ? b:a; } __forceinline float max(float a, float b) { return a<b ? b:a; } __forceinline double max(double a, double b) { return a<b ? b:a; } -#if defined(__64BIT__) +#if defined(__64BIT__) || defined(__EMSCRIPTEN__) __forceinline size_t max(size_t a, size_t b) { return a<b ? b:a; } #endif +#if defined(__EMSCRIPTEN__) + __forceinline long max(long a, long b) { return a<b ? b:a; } +#endif template<typename T> __forceinline T max(const T& a, const T& b, const T& c) { return max(max(a,b),c); } template<typename T> __forceinline T max(const T& a, const T& b, const T& c, const T& d) { return max(max(a,b),max(c,d)); } @@ -231,6 +308,15 @@ namespace embree __forceinline float msub ( const float a, const float b, const float c) { return _mm_cvtss_f32(_mm_fmsub_ss(_mm_set_ss(a),_mm_set_ss(b),_mm_set_ss(c))); } __forceinline float nmadd ( const float a, const float b, const float c) { return _mm_cvtss_f32(_mm_fnmadd_ss(_mm_set_ss(a),_mm_set_ss(b),_mm_set_ss(c))); } __forceinline float nmsub ( const float a, const float b, const float c) { return _mm_cvtss_f32(_mm_fnmsub_ss(_mm_set_ss(a),_mm_set_ss(b),_mm_set_ss(c))); } + +#elif defined (__aarch64__) && defined(__clang__) +#pragma clang fp contract(fast) +__forceinline float madd ( const float a, const float b, const float c) { return a*b + c; } +__forceinline float msub ( const float a, const float b, const float c) { return a*b - c; } +__forceinline float nmadd ( const float a, const float b, const float c) { return c - a*b; } +__forceinline float nmsub ( const float a, const float b, const float c) { return -(c + a*b); } +#pragma clang fp contract(on) + #else __forceinline float madd ( const float a, const float b, const float c) { return a*b+c; } __forceinline float msub ( const float a, const float b, const float c) { return a*b-c; } @@ -326,7 +412,7 @@ namespace embree return x | (y << 1) | (z << 2); } -#if defined(__AVX2__) +#if defined(__AVX2__) && !defined(__aarch64__) template<> __forceinline unsigned int bitInterleave(const unsigned int &xi, const unsigned int& yi, const unsigned int& zi) diff --git a/thirdparty/embree/common/math/quaternion.h b/thirdparty/embree/common/math/quaternion.h index 080800efcd..78efccda72 100644 --- a/thirdparty/embree/common/math/quaternion.h +++ b/thirdparty/embree/common/math/quaternion.h @@ -242,13 +242,17 @@ namespace embree T cosTheta = dot(q0, q1_); QuaternionT<T> q1 = select(cosTheta < 0.f, -q1_, q1_); cosTheta = select(cosTheta < 0.f, -cosTheta, cosTheta); - if (unlikely(all(cosTheta > 0.9995f))) { - return normalize(lerp(q0, q1, t)); - } + + // spherical linear interpolation const T phi = t * fastapprox::acos(cosTheta); T sinPhi, cosPhi; fastapprox::sincos(phi, sinPhi, cosPhi); QuaternionT<T> qperp = sinPhi * normalize(msub(cosTheta, q0, q1)); - return msub(cosPhi, q0, qperp); + QuaternionT<T> qslerp = msub(cosPhi, q0, qperp); + + // regular linear interpolation as fallback + QuaternionT<T> qlerp = normalize(lerp(q0, q1, t)); + + return select(cosTheta > 0.9995f, qlerp, qslerp); } } diff --git a/thirdparty/embree/common/math/transcendental.h b/thirdparty/embree/common/math/transcendental.h index fd16c26e81..daf9dd96d2 100644 --- a/thirdparty/embree/common/math/transcendental.h +++ b/thirdparty/embree/common/math/transcendental.h @@ -27,7 +27,7 @@ __forceinline T sin(const T &v) // Reduced range version of x auto x = v - kReal * piOverTwoVec; auto kMod4 = k & 3; - auto sinUseCos = (kMod4 == 1 | kMod4 == 3); + auto sinUseCos = (kMod4 == 1) | (kMod4 == 3); auto flipSign = (kMod4 > 1); // These coefficients are from sollya with fpminimax(sin(x)/x, [|0, 2, @@ -76,8 +76,8 @@ __forceinline T cos(const T &v) auto x = v - kReal * piOverTwoVec; auto kMod4 = k & 3; - auto cosUseCos = (kMod4 == 0 | kMod4 == 2); - auto flipSign = (kMod4 == 1 | kMod4 == 2); + auto cosUseCos = (kMod4 == 0) | (kMod4 == 2); + auto flipSign = (kMod4 == 1) | (kMod4 == 2); const float sinC2 = -0.16666667163372039794921875; const float sinC4 = +8.333347737789154052734375e-3; diff --git a/thirdparty/embree/common/math/vec2.h b/thirdparty/embree/common/math/vec2.h index d62aef51f3..f6d98ffa0d 100644 --- a/thirdparty/embree/common/math/vec2.h +++ b/thirdparty/embree/common/math/vec2.h @@ -144,7 +144,7 @@ namespace embree } //////////////////////////////////////////////////////////////////////////////// - /// Euclidian Space Operators + /// Euclidean Space Operators //////////////////////////////////////////////////////////////////////////////// template<typename T> __forceinline T dot ( const Vec2<T>& a, const Vec2<T>& b ) { return madd(a.x,b.x,a.y*b.y); } @@ -205,11 +205,11 @@ namespace embree #include "vec2fa.h" -#if defined __SSE__ +#if defined(__SSE__) || defined(__ARM_NEON) #include "../simd/sse.h" #endif -#if defined __AVX__ +#if defined(__AVX__) #include "../simd/avx.h" #endif @@ -221,7 +221,7 @@ namespace embree { template<> __forceinline Vec2<float>::Vec2(const Vec2fa& a) : x(a.x), y(a.y) {} -#if defined(__SSE__) +#if defined(__SSE__) || defined(__ARM_NEON) template<> __forceinline Vec2<vfloat4>::Vec2(const Vec2fa& a) : x(a.x), y(a.y) {} #endif diff --git a/thirdparty/embree/common/math/vec2fa.h b/thirdparty/embree/common/math/vec2fa.h index a51fb68fd0..4f222894c2 100644 --- a/thirdparty/embree/common/math/vec2fa.h +++ b/thirdparty/embree/common/math/vec2fa.h @@ -97,6 +97,12 @@ namespace embree __forceinline Vec2fa rcp ( const Vec2fa& a ) { +#if defined(__aarch64__) + __m128 reciprocal = _mm_rcp_ps(a.m128); + reciprocal = vmulq_f32(vrecpsq_f32(a.m128, reciprocal), reciprocal); + reciprocal = vmulq_f32(vrecpsq_f32(a.m128, reciprocal), reciprocal); + return (const Vec2fa)reciprocal; +#else #if defined(__AVX512VL__) const Vec2fa r = _mm_rcp14_ps(a.m128); #else @@ -104,13 +110,15 @@ namespace embree #endif #if defined(__AVX2__) - const Vec2fa res = _mm_mul_ps(r,_mm_fnmadd_ps(r, a, vfloat4(2.0f))); + const Vec2fa h_n = _mm_fnmadd_ps(a, r, vfloat4(1.0)); // First, compute 1 - a * r (which will be very close to 0) + const Vec2fa res = _mm_fmadd_ps(r, h_n, r); // Then compute r + r * h_n #else - const Vec2fa res = _mm_mul_ps(r,_mm_sub_ps(vfloat4(2.0f), _mm_mul_ps(r, a))); - //return _mm_sub_ps(_mm_add_ps(r, r), _mm_mul_ps(_mm_mul_ps(r, r), a)); + const Vec2fa h_n = _mm_sub_ps(vfloat4(1.0f), _mm_mul_ps(a, r)); // First, compute 1 - a * r (which will be very close to 0) + const Vec2fa res = _mm_add_ps(r,_mm_mul_ps(r, h_n)); // Then compute r + r * h_n #endif return res; +#endif //defined(__aarch64__) } __forceinline Vec2fa sqrt ( const Vec2fa& a ) { return _mm_sqrt_ps(a.m128); } @@ -118,12 +126,21 @@ namespace embree __forceinline Vec2fa rsqrt( const Vec2fa& a ) { +#if defined(__aarch64__) + __m128 r = _mm_rsqrt_ps(a.m128); + r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a.m128, r), r)); + r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a.m128, r), r)); + return r; +#else + #if defined(__AVX512VL__) __m128 r = _mm_rsqrt14_ps(a.m128); #else __m128 r = _mm_rsqrt_ps(a.m128); #endif return _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.5f),r), _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); + +#endif } __forceinline Vec2fa zero_fix(const Vec2fa& a) { @@ -156,7 +173,7 @@ namespace embree __forceinline Vec2fa min( const Vec2fa& a, const Vec2fa& b ) { return _mm_min_ps(a.m128,b.m128); } __forceinline Vec2fa max( const Vec2fa& a, const Vec2fa& b ) { return _mm_max_ps(a.m128,b.m128); } -#if defined(__SSE4_1__) +#if defined(__aarch64__) || defined(__SSE4_1__) __forceinline Vec2fa mini(const Vec2fa& a, const Vec2fa& b) { const vint4 ai = _mm_castps_si128(a); const vint4 bi = _mm_castps_si128(b); @@ -165,7 +182,7 @@ namespace embree } #endif -#if defined(__SSE4_1__) +#if defined(__aarch64__) || defined(__SSE4_1__) __forceinline Vec2fa maxi(const Vec2fa& a, const Vec2fa& b) { const vint4 ai = _mm_castps_si128(a); const vint4 bi = _mm_castps_si128(b); @@ -227,7 +244,7 @@ namespace embree __forceinline bool operator !=( const Vec2fa& a, const Vec2fa& b ) { return (_mm_movemask_ps(_mm_cmpneq_ps(a.m128, b.m128)) & 3) != 0; } //////////////////////////////////////////////////////////////////////////////// - /// Euclidian Space Operators + /// Euclidean Space Operators //////////////////////////////////////////////////////////////////////////////// #if defined(__SSE4_1__) diff --git a/thirdparty/embree/common/math/vec3.h b/thirdparty/embree/common/math/vec3.h index ce94eff327..254f6c4011 100644 --- a/thirdparty/embree/common/math/vec3.h +++ b/thirdparty/embree/common/math/vec3.h @@ -197,7 +197,7 @@ namespace embree template<typename T> __forceinline Vec3<bool> ge_mask( const Vec3<T>& a, const Vec3<T>& b ) { return Vec3<bool>(a.x>=b.x,a.y>=b.y,a.z>=b.z); } //////////////////////////////////////////////////////////////////////////////// - /// Euclidian Space Operators + /// Euclidean Space Operators //////////////////////////////////////////////////////////////////////////////// template<typename T> __forceinline T sqr ( const Vec3<T>& a ) { return dot(a,a); } @@ -207,7 +207,6 @@ namespace embree template<typename T> __forceinline Vec3<T> normalize( const Vec3<T>& a ) { return a*rsqrt(sqr(a)); } template<typename T> __forceinline T distance ( const Vec3<T>& a, const Vec3<T>& b ) { return length(a-b); } template<typename T> __forceinline Vec3<T> cross ( const Vec3<T>& a, const Vec3<T>& b ) { return Vec3<T>(msub(a.y,b.z,a.z*b.y), msub(a.z,b.x,a.x*b.z), msub(a.x,b.y,a.y*b.x)); } - template<typename T> __forceinline Vec3<T> stable_triangle_normal( const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c ) { const T ab_x = a.z*b.y, ab_y = a.x*b.z, ab_z = a.y*b.x; @@ -266,11 +265,11 @@ namespace embree /// SSE / AVX / MIC specializations //////////////////////////////////////////////////////////////////////////////// -#if defined __SSE__ +#if defined(__SSE__) || defined(__ARM_NEON) #include "../simd/sse.h" #endif -#if defined __AVX__ +#if defined(__AVX__) #include "../simd/avx.h" #endif @@ -291,14 +290,14 @@ namespace embree template<> __forceinline Vec3<vfloat4>::Vec3(const Vec3fa& a) { x = a.x; y = a.y; z = a.z; } -#elif defined(__SSE__) +#elif defined(__SSE__) || defined(__ARM_NEON) template<> __forceinline Vec3<vfloat4>::Vec3(const Vec3fa& a) { const vfloat4 v = vfloat4(a.m128); x = shuffle<0,0,0,0>(v); y = shuffle<1,1,1,1>(v); z = shuffle<2,2,2,2>(v); } #endif -#if defined(__SSE__) +#if defined(__SSE__) || defined(__ARM_NEON) template<> __forceinline Vec3<vfloat4> broadcast<vfloat4,vfloat4>(const Vec3<vfloat4>& a, const size_t k) { return Vec3<vfloat4>(vfloat4::broadcast(&a.x[k]), vfloat4::broadcast(&a.y[k]), vfloat4::broadcast(&a.z[k])); diff --git a/thirdparty/embree/common/math/vec3fa.h b/thirdparty/embree/common/math/vec3fa.h index 586039741d..8564cf6d10 100644 --- a/thirdparty/embree/common/math/vec3fa.h +++ b/thirdparty/embree/common/math/vec3fa.h @@ -55,7 +55,13 @@ namespace embree //////////////////////////////////////////////////////////////////////////////// static __forceinline Vec3fa load( const void* const a ) { +#if defined(__aarch64__) + __m128 t = _mm_load_ps((float*)a); + t[3] = 0.0f; + return Vec3fa(t); +#else return Vec3fa(_mm_and_ps(_mm_load_ps((float*)a),_mm_castsi128_ps(_mm_set_epi32(0, -1, -1, -1)))); +#endif } static __forceinline Vec3fa loadu( const void* const a ) { @@ -89,12 +95,20 @@ namespace embree __forceinline Vec3fa operator +( const Vec3fa& a ) { return a; } __forceinline Vec3fa operator -( const Vec3fa& a ) { +#if defined(__aarch64__) + return vnegq_f32(a.m128); +#else const __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x80000000)); return _mm_xor_ps(a.m128, mask); +#endif } __forceinline Vec3fa abs ( const Vec3fa& a ) { +#if defined(__aarch64__) + return _mm_abs_ps(a.m128); +#else const __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff)); return _mm_and_ps(a.m128, mask); +#endif } __forceinline Vec3fa sign ( const Vec3fa& a ) { return blendv_ps(Vec3fa(one).m128, (-Vec3fa(one)).m128, _mm_cmplt_ps (a.m128,Vec3fa(zero).m128)); @@ -102,6 +116,10 @@ namespace embree __forceinline Vec3fa rcp ( const Vec3fa& a ) { +#if defined(__aarch64__) + return vdivq_f32(vdupq_n_f32(1.0f),a.m128); +#else + #if defined(__AVX512VL__) const Vec3fa r = _mm_rcp14_ps(a.m128); #else @@ -109,13 +127,15 @@ namespace embree #endif #if defined(__AVX2__) - const Vec3fa res = _mm_mul_ps(r.m128,_mm_fnmadd_ps(r.m128, a.m128, vfloat4(2.0f))); + const Vec3fa h_n = _mm_fnmadd_ps(a.m128, r.m128, vfloat4(1.0)); // First, compute 1 - a * r (which will be very close to 0) + const Vec3fa res = _mm_fmadd_ps(r.m128, h_n.m128, r.m128); // Then compute r + r * h_n #else - const Vec3fa res = _mm_mul_ps(r.m128,_mm_sub_ps(vfloat4(2.0f), _mm_mul_ps(r.m128, a.m128))); - //return _mm_sub_ps(_mm_add_ps(r, r), _mm_mul_ps(_mm_mul_ps(r, r), a)); + const Vec3fa h_n = _mm_sub_ps(vfloat4(1.0f), _mm_mul_ps(a.m128, r.m128)); // First, compute 1 - a * r (which will be very close to 0) + const Vec3fa res = _mm_add_ps(r.m128,_mm_mul_ps(r.m128, h_n.m128)); // Then compute r + r * h_n #endif return res; +#endif //defined(__aarch64__) } __forceinline Vec3fa sqrt ( const Vec3fa& a ) { return _mm_sqrt_ps(a.m128); } @@ -123,12 +143,20 @@ namespace embree __forceinline Vec3fa rsqrt( const Vec3fa& a ) { +#if defined(__aarch64__) + __m128 r = _mm_rsqrt_ps(a.m128); + r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a.m128, r), r)); + r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a.m128, r), r)); + return r; +#else + #if defined(__AVX512VL__) __m128 r = _mm_rsqrt14_ps(a.m128); #else __m128 r = _mm_rsqrt_ps(a.m128); #endif return _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.5f),r), _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a.m128, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); +#endif } __forceinline Vec3fa zero_fix(const Vec3fa& a) { @@ -161,7 +189,7 @@ namespace embree __forceinline Vec3fa min( const Vec3fa& a, const Vec3fa& b ) { return _mm_min_ps(a.m128,b.m128); } __forceinline Vec3fa max( const Vec3fa& a, const Vec3fa& b ) { return _mm_max_ps(a.m128,b.m128); } -#if defined(__SSE4_1__) +#if defined(__aarch64__) || defined(__SSE4_1__) __forceinline Vec3fa mini(const Vec3fa& a, const Vec3fa& b) { const vint4 ai = _mm_castps_si128(a.m128); const vint4 bi = _mm_castps_si128(b.m128); @@ -170,7 +198,7 @@ namespace embree } #endif -#if defined(__SSE4_1__) +#if defined(__aarch64__) || defined(__SSE4_1__) __forceinline Vec3fa maxi(const Vec3fa& a, const Vec3fa& b) { const vint4 ai = _mm_castps_si128(a.m128); const vint4 bi = _mm_castps_si128(b.m128); @@ -187,16 +215,16 @@ namespace embree /// Ternary Operators //////////////////////////////////////////////////////////////////////////////// -#if defined(__AVX2__) +#if defined(__AVX2__) || defined(__ARM_NEON) __forceinline Vec3fa madd ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return _mm_fmadd_ps(a.m128,b.m128,c.m128); } __forceinline Vec3fa msub ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return _mm_fmsub_ps(a.m128,b.m128,c.m128); } __forceinline Vec3fa nmadd ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return _mm_fnmadd_ps(a.m128,b.m128,c.m128); } __forceinline Vec3fa nmsub ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return _mm_fnmsub_ps(a.m128,b.m128,c.m128); } #else __forceinline Vec3fa madd ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return a*b+c; } - __forceinline Vec3fa msub ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return a*b-c; } __forceinline Vec3fa nmadd ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return -a*b+c;} __forceinline Vec3fa nmsub ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return -a*b-c; } + __forceinline Vec3fa msub ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return a*b-c; } #endif __forceinline Vec3fa madd ( const float a, const Vec3fa& b, const Vec3fa& c) { return madd(Vec3fa(a),b,c); } @@ -218,8 +246,26 @@ namespace embree //////////////////////////////////////////////////////////////////////////////// /// Reductions //////////////////////////////////////////////////////////////////////////////// +#if defined(__aarch64__) + __forceinline float reduce_add(const Vec3fa& v) { + float32x4_t t = v.m128; + t[3] = 0.0f; + return vaddvq_f32(t); + } - __forceinline float reduce_add(const Vec3fa& v) { + __forceinline float reduce_mul(const Vec3fa& v) { return v.x*v.y*v.z; } + __forceinline float reduce_min(const Vec3fa& v) { + float32x4_t t = v.m128; + t[3] = t[2]; + return vminvq_f32(t); + } + __forceinline float reduce_max(const Vec3fa& v) { + float32x4_t t = v.m128; + t[3] = t[2]; + return vmaxvq_f32(t); + } +#else + __forceinline float reduce_add(const Vec3fa& v) { const vfloat4 a(v.m128); const vfloat4 b = shuffle<1>(a); const vfloat4 c = shuffle<2>(a); @@ -229,6 +275,7 @@ namespace embree __forceinline float reduce_mul(const Vec3fa& v) { return v.x*v.y*v.z; } __forceinline float reduce_min(const Vec3fa& v) { return min(v.x,v.y,v.z); } __forceinline float reduce_max(const Vec3fa& v) { return max(v.x,v.y,v.z); } +#endif //////////////////////////////////////////////////////////////////////////////// /// Comparison Operators @@ -241,8 +288,13 @@ namespace embree __forceinline Vec3ba neq_mask(const Vec3fa& a, const Vec3fa& b ) { return _mm_cmpneq_ps(a.m128, b.m128); } __forceinline Vec3ba lt_mask( const Vec3fa& a, const Vec3fa& b ) { return _mm_cmplt_ps (a.m128, b.m128); } __forceinline Vec3ba le_mask( const Vec3fa& a, const Vec3fa& b ) { return _mm_cmple_ps (a.m128, b.m128); } - __forceinline Vec3ba gt_mask( const Vec3fa& a, const Vec3fa& b ) { return _mm_cmpnle_ps(a.m128, b.m128); } - __forceinline Vec3ba ge_mask( const Vec3fa& a, const Vec3fa& b ) { return _mm_cmpnlt_ps(a.m128, b.m128); } + #if defined(__aarch64__) + __forceinline Vec3ba gt_mask( const Vec3fa& a, const Vec3fa& b ) { return _mm_cmpgt_ps (a.m128, b.m128); } + __forceinline Vec3ba ge_mask( const Vec3fa& a, const Vec3fa& b ) { return _mm_cmpge_ps (a.m128, b.m128); } +#else + __forceinline Vec3ba gt_mask(const Vec3fa& a, const Vec3fa& b) { return _mm_cmpnle_ps(a.m128, b.m128); } + __forceinline Vec3ba ge_mask(const Vec3fa& a, const Vec3fa& b) { return _mm_cmpnlt_ps(a.m128, b.m128); } +#endif __forceinline bool isvalid ( const Vec3fa& v ) { return all(gt_mask(v,Vec3fa(-FLT_LARGE)) & lt_mask(v,Vec3fa(+FLT_LARGE))); @@ -261,7 +313,7 @@ namespace embree } //////////////////////////////////////////////////////////////////////////////// - /// Euclidian Space Operators + /// Euclidean Space Operators //////////////////////////////////////////////////////////////////////////////// #if defined(__SSE4_1__) @@ -335,7 +387,11 @@ namespace embree /// Rounding Functions //////////////////////////////////////////////////////////////////////////////// -#if defined (__SSE4_1__) +#if defined(__aarch64__) + __forceinline Vec3fa floor(const Vec3fa& a) { return vrndmq_f32(a.m128); } + __forceinline Vec3fa ceil (const Vec3fa& a) { return vrndpq_f32(a.m128); } + __forceinline Vec3fa trunc(const Vec3fa& a) { return vrndq_f32(a.m128); } +#elif defined (__SSE4_1__) __forceinline Vec3fa trunc( const Vec3fa& a ) { return _mm_round_ps(a.m128, _MM_FROUND_TO_NEAREST_INT); } __forceinline Vec3fa floor( const Vec3fa& a ) { return _mm_round_ps(a.m128, _MM_FROUND_TO_NEG_INF ); } __forceinline Vec3fa ceil ( const Vec3fa& a ) { return _mm_round_ps(a.m128, _MM_FROUND_TO_POS_INF ); } @@ -393,8 +449,10 @@ namespace embree __forceinline Vec3fx( const Vec3fa& other, const int a1) { m128 = other.m128; a = a1; } __forceinline Vec3fx( const Vec3fa& other, const unsigned a1) { m128 = other.m128; u = a1; } - __forceinline Vec3fx( const Vec3fa& other, const float w1) { -#if defined (__SSE4_1__) + __forceinline Vec3fx( const Vec3fa& other, const float w1) { +#if defined (__aarch64__) + m128 = other.m128; m128[3] = w1; +#elif defined (__SSE4_1__) m128 = _mm_insert_ps(other.m128, _mm_set_ss(w1),3 << 4); #else const vint4 mask(-1,-1,-1,0); @@ -526,7 +584,7 @@ namespace embree __forceinline Vec3fx min( const Vec3fx& a, const Vec3fx& b ) { return _mm_min_ps(a.m128,b.m128); } __forceinline Vec3fx max( const Vec3fx& a, const Vec3fx& b ) { return _mm_max_ps(a.m128,b.m128); } -#if defined(__SSE4_1__) +#if defined(__SSE4_1__) || defined(__aarch64__) __forceinline Vec3fx mini(const Vec3fx& a, const Vec3fx& b) { const vint4 ai = _mm_castps_si128(a.m128); const vint4 bi = _mm_castps_si128(b.m128); @@ -535,7 +593,7 @@ namespace embree } #endif -#if defined(__SSE4_1__) +#if defined(__SSE4_1__) || defined(__aarch64__) __forceinline Vec3fx maxi(const Vec3fx& a, const Vec3fx& b) { const vint4 ai = _mm_castps_si128(a.m128); const vint4 bi = _mm_castps_si128(b.m128); @@ -626,7 +684,7 @@ namespace embree } //////////////////////////////////////////////////////////////////////////////// - /// Euclidian Space Operators + /// Euclidean Space Operators //////////////////////////////////////////////////////////////////////////////// #if defined(__SSE4_1__) diff --git a/thirdparty/embree/common/math/vec3ia.h b/thirdparty/embree/common/math/vec3ia.h index 694804c40d..d4cc3125cd 100644 --- a/thirdparty/embree/common/math/vec3ia.h +++ b/thirdparty/embree/common/math/vec3ia.h @@ -65,7 +65,9 @@ namespace embree __forceinline Vec3ia operator +( const Vec3ia& a ) { return a; } __forceinline Vec3ia operator -( const Vec3ia& a ) { return _mm_sub_epi32(_mm_setzero_si128(), a.m128); } -#if defined(__SSSE3__) +#if (defined(__aarch64__)) + __forceinline Vec3ia abs ( const Vec3ia& a ) { return vabsq_s32(a.m128); } +#elif defined(__SSSE3__) __forceinline Vec3ia abs ( const Vec3ia& a ) { return _mm_abs_epi32(a.m128); } #endif @@ -81,7 +83,7 @@ namespace embree __forceinline Vec3ia operator -( const Vec3ia& a, const int b ) { return a-Vec3ia(b); } __forceinline Vec3ia operator -( const int a, const Vec3ia& b ) { return Vec3ia(a)-b; } -#if defined(__SSE4_1__) +#if defined(__aarch64__) || defined(__SSE4_1__) __forceinline Vec3ia operator *( const Vec3ia& a, const Vec3ia& b ) { return _mm_mullo_epi32(a.m128, b.m128); } __forceinline Vec3ia operator *( const Vec3ia& a, const int b ) { return a * Vec3ia(b); } __forceinline Vec3ia operator *( const int a, const Vec3ia& b ) { return Vec3ia(a) * b; } @@ -116,7 +118,7 @@ namespace embree __forceinline Vec3ia& operator -=( Vec3ia& a, const Vec3ia& b ) { return a = a - b; } __forceinline Vec3ia& operator -=( Vec3ia& a, const int& b ) { return a = a - b; } -#if defined(__SSE4_1__) +#if defined(__aarch64__) || defined(__SSE4_1__) __forceinline Vec3ia& operator *=( Vec3ia& a, const Vec3ia& b ) { return a = a * b; } __forceinline Vec3ia& operator *=( Vec3ia& a, const int& b ) { return a = a * b; } #endif @@ -127,18 +129,38 @@ namespace embree __forceinline Vec3ia& operator |=( Vec3ia& a, const Vec3ia& b ) { return a = a | b; } __forceinline Vec3ia& operator |=( Vec3ia& a, const int& b ) { return a = a | b; } +#if !defined(__ARM_NEON) __forceinline Vec3ia& operator <<=( Vec3ia& a, const int& b ) { return a = a << b; } __forceinline Vec3ia& operator >>=( Vec3ia& a, const int& b ) { return a = a >> b; } +#endif //////////////////////////////////////////////////////////////////////////////// - /// Reductions + /// Select //////////////////////////////////////////////////////////////////////////////// + __forceinline Vec3ia select( const Vec3ba& m, const Vec3ia& t, const Vec3ia& f ) { +#if defined(__aarch64__) || defined(__SSE4_1__) + return _mm_castps_si128(_mm_blendv_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), m)); +#else + return _mm_or_si128(_mm_and_si128(_mm_castps_si128(m), t), _mm_andnot_si128(_mm_castps_si128(m), f)); +#endif + } + + //////////////////////////////////////////////////////////////////////////////// + /// Reductions + //////////////////////////////////////////////////////////////////////////////// +#if defined(__aarch64__) + __forceinline int reduce_add(const Vec3ia& v) { return vaddvq_s32(select(Vec3ba(1,1,1),v,Vec3ia(0))); } + __forceinline int reduce_mul(const Vec3ia& v) { return v.x*v.y*v.z; } + __forceinline int reduce_min(const Vec3ia& v) { return vminvq_s32(select(Vec3ba(1,1,1),v,Vec3ia(0x7FFFFFFF))); } + __forceinline int reduce_max(const Vec3ia& v) { return vmaxvq_s32(select(Vec3ba(1,1,1),v,Vec3ia(0x80000000))); } +#else __forceinline int reduce_add(const Vec3ia& v) { return v.x+v.y+v.z; } __forceinline int reduce_mul(const Vec3ia& v) { return v.x*v.y*v.z; } __forceinline int reduce_min(const Vec3ia& v) { return min(v.x,v.y,v.z); } __forceinline int reduce_max(const Vec3ia& v) { return max(v.x,v.y,v.z); } - +#endif + //////////////////////////////////////////////////////////////////////////////// /// Comparison Operators //////////////////////////////////////////////////////////////////////////////// @@ -156,19 +178,7 @@ namespace embree __forceinline Vec3ba lt_mask( const Vec3ia& a, const Vec3ia& b ) { return _mm_castsi128_ps(_mm_cmplt_epi32 (a.m128, b.m128)); } __forceinline Vec3ba gt_mask( const Vec3ia& a, const Vec3ia& b ) { return _mm_castsi128_ps(_mm_cmpgt_epi32 (a.m128, b.m128)); } - //////////////////////////////////////////////////////////////////////////////// - /// Select - //////////////////////////////////////////////////////////////////////////////// - - __forceinline Vec3ia select( const Vec3ba& m, const Vec3ia& t, const Vec3ia& f ) { -#if defined(__SSE4_1__) - return _mm_castps_si128(_mm_blendv_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), m)); -#else - return _mm_or_si128(_mm_and_si128(_mm_castps_si128(m), t), _mm_andnot_si128(_mm_castps_si128(m), f)); -#endif - } - -#if defined(__SSE4_1__) +#if defined(__aarch64__) || defined(__SSE4_1__) __forceinline Vec3ia min( const Vec3ia& a, const Vec3ia& b ) { return _mm_min_epi32(a.m128,b.m128); } __forceinline Vec3ia max( const Vec3ia& a, const Vec3ia& b ) { return _mm_max_epi32(a.m128,b.m128); } #else diff --git a/thirdparty/embree/common/math/vec4.h b/thirdparty/embree/common/math/vec4.h index 0ed107928a..10c53f47b4 100644 --- a/thirdparty/embree/common/math/vec4.h +++ b/thirdparty/embree/common/math/vec4.h @@ -149,7 +149,7 @@ namespace embree } //////////////////////////////////////////////////////////////////////////////// - /// Euclidian Space Operators + /// Euclidean Space Operators //////////////////////////////////////////////////////////////////////////////// template<typename T> __forceinline T dot ( const Vec4<T>& a, const Vec4<T>& b ) { return madd(a.x,b.x,madd(a.y,b.y,madd(a.z,b.z,a.w*b.w))); } @@ -205,7 +205,7 @@ namespace embree /// SSE / AVX / MIC specializations //////////////////////////////////////////////////////////////////////////////// -#if defined __SSE__ +#if defined(__SSE__) || defined(__ARM_NEON) #include "../simd/sse.h" #endif @@ -225,7 +225,7 @@ namespace embree template<> __forceinline Vec4<vfloat4>::Vec4( const Vec3fx& a ) { x = a.x; y = a.y; z = a.z; w = a.w; } -#elif defined(__SSE__) +#elif defined(__SSE__) || defined(__ARM_NEON) template<> __forceinline Vec4<vfloat4>::Vec4( const Vec3fx& a ) { const vfloat4 v = vfloat4(a.m128); x = shuffle<0,0,0,0>(v); y = shuffle<1,1,1,1>(v); z = shuffle<2,2,2,2>(v); w = shuffle<3,3,3,3>(v); } diff --git a/thirdparty/embree/common/simd/arm/avx2neon.h b/thirdparty/embree/common/simd/arm/avx2neon.h new file mode 100644 index 0000000000..dd321d3d64 --- /dev/null +++ b/thirdparty/embree/common/simd/arm/avx2neon.h @@ -0,0 +1,1196 @@ +#pragma once + +#if !defined(__aarch64__) +#error "avx2neon is only supported for AARCH64" +#endif + +#include "sse2neon.h" + +#define AVX2NEON_ABI static inline __attribute__((always_inline)) + + +struct __m256 { + __m128 lo,hi; + __m256() {} +}; + + + + +struct __m256i { + __m128i lo,hi; + explicit __m256i(const __m256 a) : lo(__m128i(a.lo)),hi(__m128i(a.hi)) {} + operator __m256() const {__m256 res; res.lo = __m128(lo);res.hi = __m128(hi); return res;} + __m256i() {} +}; + + + + +struct __m256d { + float64x2_t lo,hi; + __m256d() {} + __m256d(const __m256& a) : lo(float64x2_t(a.lo)),hi(float64x2_t(a.hi)) {} + __m256d(const __m256i& a) : lo(float64x2_t(a.lo)),hi(float64x2_t(a.hi)) {} +}; + +#define UNARY_AVX_OP(type,func,basic_func) AVX2NEON_ABI type func(const type& a) {type res;res.lo=basic_func(a.lo);res.hi=basic_func(a.hi);return res;} + + +#define BINARY_AVX_OP(type,func,basic_func) AVX2NEON_ABI type func(const type& a,const type& b) {type res;res.lo=basic_func(a.lo,b.lo);res.hi=basic_func(a.hi,b.hi);return res;} +#define BINARY_AVX_OP_CAST(type,func,basic_func,bdst,bsrc) AVX2NEON_ABI type func(const type& a,const type& b) {type res;res.lo=bdst(basic_func(bsrc(a.lo),bsrc(b.lo)));res.hi=bdst(basic_func(bsrc(a.hi),bsrc(b.hi)));return res;} + +#define TERNARY_AVX_OP(type,func,basic_func) AVX2NEON_ABI type func(const type& a,const type& b,const type& c) {type res;res.lo=basic_func(a.lo,b.lo,c.lo);res.hi=basic_func(a.hi,b.hi,c.hi);return res;} + + +#define CAST_SIMD_TYPE(to,name,from,basic_dst) AVX2NEON_ABI to name(const from& a) { to res; res.lo = basic_dst(a.lo); res.hi=basic_dst(a.hi); return res;} + + + +#define _mm_stream_load_si128 _mm_load_si128 +#define _mm256_stream_load_si256 _mm256_load_si256 + + +AVX2NEON_ABI +__m128i _mm_blend_epi32 (__m128i a, __m128i b, const int imm8) +{ + __m128 af = _mm_castsi128_ps(a); + __m128 bf = _mm_castsi128_ps(b); + __m128 blendf = _mm_blend_ps(af, bf, imm8); + return _mm_castps_si128(blendf); +} + +AVX2NEON_ABI +int _mm_movemask_popcnt(__m128 a) +{ + return __builtin_popcount(_mm_movemask_ps(a)); +} + +AVX2NEON_ABI +__m128 _mm_maskload_ps (float const * mem_addr, __m128i mask) +{ + float32x4_t res; + uint32x4_t mask_u32 = vreinterpretq_u32_m128i(mask); + for (int i=0;i<4;i++) { + if (mask_u32[i] & 0x80000000) res[i] = mem_addr[i]; else res[i] = 0; + } + return vreinterpretq_m128_f32(res); +} + +AVX2NEON_ABI +void _mm_maskstore_ps (float * mem_addr, __m128i mask, __m128 a) +{ + float32x4_t a_f32 = vreinterpretq_f32_m128(a); + uint32x4_t mask_u32 = vreinterpretq_u32_m128i(mask); + for (int i=0;i<4;i++) { + if (mask_u32[i] & 0x80000000) mem_addr[i] = a_f32[i]; + } +} + +AVX2NEON_ABI +void _mm_maskstore_epi32 (int * mem_addr, __m128i mask, __m128i a) +{ + uint32x4_t mask_u32 = vreinterpretq_u32_m128i(mask); + int32x4_t a_s32 = vreinterpretq_s32_m128i(a); + for (int i=0;i<4;i++) { + if (mask_u32[i] & 0x80000000) mem_addr[i] = a_s32[i]; + } +} + + +#define _mm_fmadd_ss _mm_fmadd_ps +#define _mm_fmsub_ss _mm_fmsub_ps +#define _mm_fnmsub_ss _mm_fnmsub_ps +#define _mm_fnmadd_ss _mm_fnmadd_ps + +template<int code> +AVX2NEON_ABI float32x4_t dpps_neon(const float32x4_t& a,const float32x4_t& b) +{ + float v; + v = 0; + v += (code & 0x10) ? a[0]*b[0] : 0; + v += (code & 0x20) ? a[1]*b[1] : 0; + v += (code & 0x40) ? a[2]*b[2] : 0; + v += (code & 0x80) ? a[3]*b[3] : 0; + float32x4_t res; + res[0] = (code & 0x1) ? v : 0; + res[1] = (code & 0x2) ? v : 0; + res[2] = (code & 0x4) ? v : 0; + res[3] = (code & 0x8) ? v : 0; + return res; +} + +template<> +inline float32x4_t dpps_neon<0x7f>(const float32x4_t& a,const float32x4_t& b) +{ + float v; + float32x4_t m = _mm_mul_ps(a,b); + m[3] = 0; + v = vaddvq_f32(m); + return _mm_set1_ps(v); +} + +template<> +inline float32x4_t dpps_neon<0xff>(const float32x4_t& a,const float32x4_t& b) +{ + float v; + float32x4_t m = _mm_mul_ps(a,b); + v = vaddvq_f32(m); + return _mm_set1_ps(v); +} + +#define _mm_dp_ps(a,b,c) dpps_neon<c>((a),(b)) + + +AVX2NEON_ABI +__m128 _mm_permutevar_ps (__m128 a, __m128i b) +{ + uint32x4_t b_u32 = vreinterpretq_u32_m128i(b); + float32x4_t x; + for (int i=0;i<4;i++) + { + x[i] = a[b_u32[i]]; + } + return vreinterpretq_m128_f32(x); +} + +AVX2NEON_ABI +__m256i _mm256_setzero_si256() +{ + __m256i res; + res.lo = res.hi = vdupq_n_s32(0); + return res; +} + +AVX2NEON_ABI +__m256 _mm256_setzero_ps() +{ + __m256 res; + res.lo = res.hi = vdupq_n_f32(0.0f); + return res; +} + +AVX2NEON_ABI +__m256i _mm256_undefined_si256() +{ + return _mm256_setzero_si256(); +} + +AVX2NEON_ABI +__m256 _mm256_undefined_ps() +{ + return _mm256_setzero_ps(); +} + +CAST_SIMD_TYPE(__m256d, _mm256_castps_pd, __m256, float64x2_t) +CAST_SIMD_TYPE(__m256i, _mm256_castps_si256, __m256, __m128i) +CAST_SIMD_TYPE(__m256, _mm256_castsi256_ps, __m256i, __m128) +CAST_SIMD_TYPE(__m256, _mm256_castpd_ps , __m256d, __m128) +CAST_SIMD_TYPE(__m256d, _mm256_castsi256_pd, __m256i, float64x2_t) +CAST_SIMD_TYPE(__m256i, _mm256_castpd_si256, __m256d, __m128i) + + + + +AVX2NEON_ABI +__m128 _mm256_castps256_ps128 (__m256 a) +{ + return a.lo; +} + +AVX2NEON_ABI +__m256i _mm256_castsi128_si256 (__m128i a) +{ + __m256i res; + res.lo = a ; + res.hi = vdupq_n_s32(0); + return res; +} + +AVX2NEON_ABI +__m128i _mm256_castsi256_si128 (__m256i a) +{ + return a.lo; +} + +AVX2NEON_ABI +__m256 _mm256_castps128_ps256 (__m128 a) +{ + __m256 res; + res.lo = a; + res.hi = vdupq_n_f32(0); + return res; +} + + +AVX2NEON_ABI +__m256 _mm256_broadcast_ss (float const * mem_addr) +{ + __m256 res; + res.lo = res.hi = vdupq_n_f32(*mem_addr); + return res; +} + + +AVX2NEON_ABI +__m256i _mm256_set_epi32 (int e7, int e6, int e5, int e4, int e3, int e2, int e1, int e0) +{ + __m256i res; + res.lo = _mm_set_epi32(e3,e2,e1,e0); + res.hi = _mm_set_epi32(e7,e6,e5,e4); + return res; + +} + +AVX2NEON_ABI +__m256i _mm256_set1_epi32 (int a) +{ + __m256i res; + res.lo = res.hi = vdupq_n_s32(a); + return res; +} +AVX2NEON_ABI +__m256i _mm256_set1_epi8 (int a) +{ + __m256i res; + res.lo = res.hi = vdupq_n_s8(a); + return res; +} +AVX2NEON_ABI +__m256i _mm256_set1_epi16 (int a) +{ + __m256i res; + res.lo = res.hi = vdupq_n_s16(a); + return res; +} + + + + +AVX2NEON_ABI +int _mm256_movemask_ps(const __m256& v) +{ + return (_mm_movemask_ps(v.hi) << 4) | _mm_movemask_ps(v.lo); +} + +template<int imm8> +AVX2NEON_ABI +__m256 __mm256_permute_ps (const __m256& a) +{ + __m256 res; + res.lo = _mm_shuffle_ps(a.lo,a.lo,imm8); + res.hi = _mm_shuffle_ps(a.hi,a.hi,imm8); + return res; + +} + +#define _mm256_permute_ps(a,c) __mm256_permute_ps<c>(a) + + +template<int imm8> +AVX2NEON_ABI +__m256 __mm256_shuffle_ps (const __m256 a,const __m256& b) +{ + __m256 res; + res.lo = _mm_shuffle_ps(a.lo,b.lo,imm8); + res.hi = _mm_shuffle_ps(a.hi,b.hi,imm8); + return res; + +} + +template<int imm8> +AVX2NEON_ABI +__m256i __mm256_shuffle_epi32 (const __m256i a) +{ + __m256i res; + res.lo = _mm_shuffle_epi32(a.lo,imm8); + res.hi = _mm_shuffle_epi32(a.hi,imm8); + return res; + +} + +template<int imm8> +AVX2NEON_ABI +__m256i __mm256_srli_si256 (__m256i a) +{ + __m256i res; + res.lo = _mm_srli_si128(a.lo,imm8); + res.hi = _mm_srli_si128(a.hi,imm8); + return res; +} + +template<int imm8> +AVX2NEON_ABI +__m256i __mm256_slli_si256 (__m256i a) +{ + __m256i res; + res.lo = _mm_slli_si128(a.lo,imm8); + res.hi = _mm_slli_si128(a.hi,imm8); + return res; +} + + +#define _mm256_srli_si256(a,b) __mm256_srli_si256<b>(a) +#define _mm256_slli_si256(a,b) __mm256_slli_si256<b>(a) + + + +#define _mm256_shuffle_ps(a,b,c) __mm256_shuffle_ps<c>(a,b) +#define _mm256_shuffle_epi32(a,c) __mm256_shuffle_epi32<c>(a) + + +AVX2NEON_ABI +__m256i _mm256_set1_epi64x (long long a) +{ + __m256i res; + int64x2_t t = vdupq_n_s64(a); + res.lo = res.hi = __m128i(t); + return res; +} + + +AVX2NEON_ABI +__m256 _mm256_permute2f128_ps (__m256 a, __m256 b, int imm8) +{ + __m256 res; + __m128 tmp; + switch (imm8 & 0x7) + { + case 0: tmp = a.lo; break; + case 1: tmp = a.hi; break; + case 2: tmp = b.lo; break; + case 3: tmp = b.hi; break; + } + if (imm8 & 0x8) + tmp = _mm_setzero_ps(); + + + + res.lo = tmp; + imm8 >>= 4; + + switch (imm8 & 0x7) + { + case 0: tmp = a.lo; break; + case 1: tmp = a.hi; break; + case 2: tmp = b.lo; break; + case 3: tmp = b.hi; break; + } + if (imm8 & 0x8) + tmp = _mm_setzero_ps(); + + res.hi = tmp; + + return res; +} + +AVX2NEON_ABI +__m256 _mm256_moveldup_ps (__m256 a) +{ + __m256 res; + res.lo = _mm_moveldup_ps(a.lo); + res.hi = _mm_moveldup_ps(a.hi); + return res; +} + +AVX2NEON_ABI +__m256 _mm256_movehdup_ps (__m256 a) +{ + __m256 res; + res.lo = _mm_movehdup_ps(a.lo); + res.hi = _mm_movehdup_ps(a.hi); + return res; +} + +AVX2NEON_ABI +__m256 _mm256_insertf128_ps (__m256 a, __m128 b, int imm8) +{ + __m256 res = a; + if (imm8 & 1) res.hi = b; + else res.lo = b; + return res; +} + + +AVX2NEON_ABI +__m128 _mm256_extractf128_ps (__m256 a, const int imm8) +{ + if (imm8 & 1) return a.hi; + return a.lo; +} + + +AVX2NEON_ABI +__m256d _mm256_movedup_pd (__m256d a) +{ + __m256d res; + res.lo = _mm_movedup_pd(a.lo); + res.hi = _mm_movedup_pd(a.hi); + return res; +} + +AVX2NEON_ABI +__m256i _mm256_abs_epi32(__m256i a) +{ + __m256i res; + res.lo = vabsq_s32(a.lo); + res.hi = vabsq_s32(a.hi); + return res; +} + +UNARY_AVX_OP(__m256,_mm256_sqrt_ps,_mm_sqrt_ps) +UNARY_AVX_OP(__m256,_mm256_rsqrt_ps,_mm_rsqrt_ps) +UNARY_AVX_OP(__m256,_mm256_rcp_ps,_mm_rcp_ps) +UNARY_AVX_OP(__m256,_mm256_floor_ps,vrndmq_f32) +UNARY_AVX_OP(__m256,_mm256_ceil_ps,vrndpq_f32) +UNARY_AVX_OP(__m256i,_mm256_abs_epi16,_mm_abs_epi16) + + +BINARY_AVX_OP(__m256i,_mm256_add_epi8,_mm_add_epi8) +BINARY_AVX_OP(__m256i,_mm256_adds_epi8,_mm_adds_epi8) + +BINARY_AVX_OP(__m256i,_mm256_hadd_epi32,_mm_hadd_epi32) +BINARY_AVX_OP(__m256i,_mm256_add_epi32,_mm_add_epi32) +BINARY_AVX_OP(__m256i,_mm256_sub_epi32,_mm_sub_epi32) +BINARY_AVX_OP(__m256i,_mm256_mullo_epi32,_mm_mullo_epi32) + +BINARY_AVX_OP(__m256i,_mm256_min_epi32,_mm_min_epi32) +BINARY_AVX_OP(__m256i,_mm256_max_epi32,_mm_max_epi32) +BINARY_AVX_OP(__m256i,_mm256_min_epi16,_mm_min_epi16) +BINARY_AVX_OP(__m256i,_mm256_max_epi16,_mm_max_epi16) +BINARY_AVX_OP(__m256i,_mm256_min_epi8,_mm_min_epi8) +BINARY_AVX_OP(__m256i,_mm256_max_epi8,_mm_max_epi8) +BINARY_AVX_OP(__m256i,_mm256_min_epu16,_mm_min_epu16) +BINARY_AVX_OP(__m256i,_mm256_max_epu16,_mm_max_epu16) +BINARY_AVX_OP(__m256i,_mm256_min_epu8,_mm_min_epu8) +BINARY_AVX_OP(__m256i,_mm256_max_epu8,_mm_max_epu8) +BINARY_AVX_OP(__m256i,_mm256_sign_epi16,_mm_sign_epi16) + + +BINARY_AVX_OP_CAST(__m256i,_mm256_min_epu32,vminq_u32,__m128i,uint32x4_t) +BINARY_AVX_OP_CAST(__m256i,_mm256_max_epu32,vmaxq_u32,__m128i,uint32x4_t) + +BINARY_AVX_OP(__m256,_mm256_min_ps,_mm_min_ps) +BINARY_AVX_OP(__m256,_mm256_max_ps,_mm_max_ps) + +BINARY_AVX_OP(__m256,_mm256_add_ps,_mm_add_ps) +BINARY_AVX_OP(__m256,_mm256_mul_ps,_mm_mul_ps) +BINARY_AVX_OP(__m256,_mm256_sub_ps,_mm_sub_ps) +BINARY_AVX_OP(__m256,_mm256_div_ps,_mm_div_ps) + +BINARY_AVX_OP(__m256,_mm256_and_ps,_mm_and_ps) +BINARY_AVX_OP(__m256,_mm256_andnot_ps,_mm_andnot_ps) +BINARY_AVX_OP(__m256,_mm256_or_ps,_mm_or_ps) +BINARY_AVX_OP(__m256,_mm256_xor_ps,_mm_xor_ps) + +BINARY_AVX_OP_CAST(__m256d,_mm256_and_pd,vandq_s64,float64x2_t,int64x2_t) +BINARY_AVX_OP_CAST(__m256d,_mm256_or_pd,vorrq_s64,float64x2_t,int64x2_t) +BINARY_AVX_OP_CAST(__m256d,_mm256_xor_pd,veorq_s64,float64x2_t,int64x2_t) + + + +BINARY_AVX_OP(__m256i,_mm256_and_si256,_mm_and_si128) +BINARY_AVX_OP(__m256i,_mm256_andnot_si256,_mm_andnot_si128) +BINARY_AVX_OP(__m256i,_mm256_or_si256,_mm_or_si128) +BINARY_AVX_OP(__m256i,_mm256_xor_si256,_mm_xor_si128) + + +BINARY_AVX_OP(__m256,_mm256_unpackhi_ps,_mm_unpackhi_ps) +BINARY_AVX_OP(__m256,_mm256_unpacklo_ps,_mm_unpacklo_ps) +TERNARY_AVX_OP(__m256,_mm256_blendv_ps,_mm_blendv_ps) +TERNARY_AVX_OP(__m256i,_mm256_blendv_epi8,_mm_blendv_epi8) + + +TERNARY_AVX_OP(__m256,_mm256_fmadd_ps,_mm_fmadd_ps) +TERNARY_AVX_OP(__m256,_mm256_fnmadd_ps,_mm_fnmadd_ps) +TERNARY_AVX_OP(__m256,_mm256_fmsub_ps,_mm_fmsub_ps) +TERNARY_AVX_OP(__m256,_mm256_fnmsub_ps,_mm_fnmsub_ps) + + + +BINARY_AVX_OP(__m256i,_mm256_packs_epi32,_mm_packs_epi32) +BINARY_AVX_OP(__m256i,_mm256_packs_epi16,_mm_packs_epi16) +BINARY_AVX_OP(__m256i,_mm256_packus_epi32,_mm_packus_epi32) +BINARY_AVX_OP(__m256i,_mm256_packus_epi16,_mm_packus_epi16) + + +BINARY_AVX_OP(__m256i,_mm256_unpackhi_epi64,_mm_unpackhi_epi64) +BINARY_AVX_OP(__m256i,_mm256_unpackhi_epi32,_mm_unpackhi_epi32) +BINARY_AVX_OP(__m256i,_mm256_unpackhi_epi16,_mm_unpackhi_epi16) +BINARY_AVX_OP(__m256i,_mm256_unpackhi_epi8,_mm_unpackhi_epi8) + +BINARY_AVX_OP(__m256i,_mm256_unpacklo_epi64,_mm_unpacklo_epi64) +BINARY_AVX_OP(__m256i,_mm256_unpacklo_epi32,_mm_unpacklo_epi32) +BINARY_AVX_OP(__m256i,_mm256_unpacklo_epi16,_mm_unpacklo_epi16) +BINARY_AVX_OP(__m256i,_mm256_unpacklo_epi8,_mm_unpacklo_epi8) + +BINARY_AVX_OP(__m256i,_mm256_mulhrs_epi16,_mm_mulhrs_epi16) +BINARY_AVX_OP(__m256i,_mm256_mulhi_epu16,_mm_mulhi_epu16) +BINARY_AVX_OP(__m256i,_mm256_mulhi_epi16,_mm_mulhi_epi16) +//BINARY_AVX_OP(__m256i,_mm256_mullo_epu16,_mm_mullo_epu16) +BINARY_AVX_OP(__m256i,_mm256_mullo_epi16,_mm_mullo_epi16) + +BINARY_AVX_OP(__m256i,_mm256_subs_epu16,_mm_subs_epu16) +BINARY_AVX_OP(__m256i,_mm256_adds_epu16,_mm_adds_epu16) +BINARY_AVX_OP(__m256i,_mm256_subs_epi16,_mm_subs_epi16) +BINARY_AVX_OP(__m256i,_mm256_adds_epi16,_mm_adds_epi16) +BINARY_AVX_OP(__m256i,_mm256_sub_epi16,_mm_sub_epi16) +BINARY_AVX_OP(__m256i,_mm256_add_epi16,_mm_add_epi16) +BINARY_AVX_OP(__m256i,_mm256_sub_epi8,_mm_sub_epi8) + + +BINARY_AVX_OP(__m256i,_mm256_hadd_epi16,_mm_hadd_epi16) +BINARY_AVX_OP(__m256i,_mm256_hadds_epi16,_mm_hadds_epi16) + + + + +BINARY_AVX_OP(__m256i,_mm256_cmpeq_epi32,_mm_cmpeq_epi32) +BINARY_AVX_OP(__m256i,_mm256_cmpgt_epi32,_mm_cmpgt_epi32) + +BINARY_AVX_OP(__m256i,_mm256_cmpeq_epi8,_mm_cmpeq_epi8) +BINARY_AVX_OP(__m256i,_mm256_cmpgt_epi8,_mm_cmpgt_epi8) + +BINARY_AVX_OP(__m256i,_mm256_cmpeq_epi16,_mm_cmpeq_epi16) +BINARY_AVX_OP(__m256i,_mm256_cmpgt_epi16,_mm_cmpgt_epi16) + + +BINARY_AVX_OP(__m256i,_mm256_shuffle_epi8,_mm_shuffle_epi8) + + +BINARY_AVX_OP(__m256,_mm256_cmpeq_ps,_mm_cmpeq_ps) +BINARY_AVX_OP(__m256,_mm256_cmpneq_ps,_mm_cmpneq_ps) +BINARY_AVX_OP(__m256,_mm256_cmpnlt_ps,_mm_cmpnlt_ps) +BINARY_AVX_OP(__m256,_mm256_cmpngt_ps,_mm_cmpngt_ps) +BINARY_AVX_OP(__m256,_mm256_cmpge_ps,_mm_cmpge_ps) +BINARY_AVX_OP(__m256,_mm256_cmpnge_ps,_mm_cmpnge_ps) +BINARY_AVX_OP(__m256,_mm256_cmplt_ps,_mm_cmplt_ps) +BINARY_AVX_OP(__m256,_mm256_cmple_ps,_mm_cmple_ps) +BINARY_AVX_OP(__m256,_mm256_cmpgt_ps,_mm_cmpgt_ps) +BINARY_AVX_OP(__m256,_mm256_cmpnle_ps,_mm_cmpnle_ps) + + +AVX2NEON_ABI +__m256i _mm256_cvtps_epi32 (__m256 a) +{ + __m256i res; + res.lo = _mm_cvtps_epi32(a.lo); + res.hi = _mm_cvtps_epi32(a.hi); + return res; + +} + +AVX2NEON_ABI +__m256i _mm256_cvttps_epi32 (__m256 a) +{ + __m256i res; + res.lo = _mm_cvttps_epi32(a.lo); + res.hi = _mm_cvttps_epi32(a.hi); + return res; + +} + +AVX2NEON_ABI +__m256 _mm256_loadu_ps (float const * mem_addr) +{ + __m256 res; + res.lo = *(__m128 *)(mem_addr + 0); + res.hi = *(__m128 *)(mem_addr + 4); + return res; +} +#define _mm256_load_ps _mm256_loadu_ps + + +AVX2NEON_ABI +int _mm256_testz_ps (const __m256& a, const __m256& b) +{ + __m256 t = a; + if (&a != &b) + t = _mm256_and_ps(a,b); + + int32x4_t l = vshrq_n_s32(vreinterpretq_s32_m128(t.lo),31); + int32x4_t h = vshrq_n_s32(vreinterpretq_s32_m128(t.hi),31); + return vaddvq_s32(vaddq_s32(l,h)) == 0; +} + + +AVX2NEON_ABI +__m256i _mm256_set_epi64x (int64_t e3, int64_t e2, int64_t e1, int64_t e0) +{ + __m256i res; + int64x2_t t0 = {e0,e1}; + int64x2_t t1 = {e2,e3}; + res.lo = __m128i(t0); + res.hi = __m128i(t1); + return res; +} +AVX2NEON_ABI +__m256i _mm256_setr_epi64x (int64_t e0, int64_t e1, int64_t e2, int64_t e3) +{ + __m256i res; + int64x2_t t0 = {e0,e1}; + int64x2_t t1 = {e2,e3}; + res.lo = __m128i(t0); + res.hi = __m128i(t1); + return res; +} + + + +AVX2NEON_ABI +__m256i _mm256_set_epi8 (char e31, char e30, char e29, char e28, char e27, char e26, char e25, char e24, char e23, char e22, char e21, char e20, char e19, char e18, char e17, char e16, char e15, char e14, char e13, char e12, char e11, char e10, char e9, char e8, char e7, char e6, char e5, char e4, char e3, char e2, char e1, char e0) +{ + int8x16_t lo = {e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15}; + int8x16_t hi = {e16,e17,e18,e19,e20,e21,e22,e23,e24,e25,e26,e27,e28,e29,e30,e31}; + __m256i res; + res.lo = lo; res.hi = hi; + return res; +} + +AVX2NEON_ABI +__m256i _mm256_setr_epi8 (char e0, char e1, char e2, char e3, char e4, char e5, char e6, char e7, char e8, char e9, char e10, char e11, char e12, char e13, char e14, char e15, char e16, char e17, char e18, char e19, char e20, char e21, char e22, char e23, char e24, char e25, char e26, char e27, char e28, char e29, char e30, char e31) +{ + int8x16_t lo = {e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15}; + int8x16_t hi = {e16,e17,e18,e19,e20,e21,e22,e23,e24,e25,e26,e27,e28,e29,e30,e31}; + __m256i res; + res.lo = lo; res.hi = hi; + return res; +} + + +AVX2NEON_ABI +__m256i _mm256_set_epi16 (short e15, short e14, short e13, short e12, short e11, short e10, short e9, short e8, short e7, short e6, short e5, short e4, short e3, short e2, short e1, short e0) +{ + int16x8_t lo = {e0,e1,e2,e3,e4,e5,e6,e7}; + int16x8_t hi = {e8,e9,e10,e11,e12,e13,e14,e15}; + __m256i res; + res.lo = lo; res.hi = hi; + return res; +} + +AVX2NEON_ABI +__m256i _mm256_setr_epi16 (short e0, short e1, short e2, short e3, short e4, short e5, short e6, short e7, short e8, short e9, short e10, short e11, short e12, short e13, short e14, short e15) +{ + int16x8_t lo = {e0,e1,e2,e3,e4,e5,e6,e7}; + int16x8_t hi = {e8,e9,e10,e11,e12,e13,e14,e15}; + __m256i res; + res.lo = lo; res.hi = hi; + return res; +} + + + + +AVX2NEON_ABI +int _mm256_movemask_epi8(const __m256i& a) +{ + return (_mm_movemask_epi8(a.hi) << 16) | _mm_movemask_epi8(a.lo); +} + + +AVX2NEON_ABI +int _mm256_testz_si256(const __m256i& a,const __m256i& b) +{ + uint32x4_t lo = vandq_u32(a.lo,b.lo); + uint32x4_t hi = vandq_u32(a.hi,b.hi); + + return (vaddvq_u32(lo) + vaddvq_u32(hi)) == 0; +} + +AVX2NEON_ABI +__m256d _mm256_setzero_pd () +{ + __m256d res; + res.lo = res.hi = vdupq_n_f64(0); + return res; +} + +AVX2NEON_ABI +int _mm256_movemask_pd (__m256d a) +{ + return (_mm_movemask_pd(a.hi) << 2) | _mm_movemask_pd(a.lo); +} + +AVX2NEON_ABI +__m256i _mm256_cmpeq_epi64 (__m256i a, __m256i b) +{ + __m256i res; + res.lo = _mm_cmpeq_epi64(a.lo, b.lo); + res.hi = _mm_cmpeq_epi64(a.hi, b.hi); + return res; +} + +AVX2NEON_ABI +__m256d _mm256_cmpeq_pd (__m256d a, __m256d b) +{ + __m256d res; + res.lo = _mm_cmpeq_pd(a.lo, b.lo); + res.hi = _mm_cmpeq_pd(a.hi, b.hi); + return res; +} + + +AVX2NEON_ABI +int _mm256_testz_pd (const __m256d& a, const __m256d& b) +{ + __m256d t = a; + + if (&a != &b) + t = _mm256_and_pd(a,b); + + return _mm256_movemask_pd(t) == 0; +} + +AVX2NEON_ABI +__m256d _mm256_blendv_pd (__m256d a, __m256d b, __m256d mask) +{ + __m256d res; + res.lo = _mm_blendv_pd(a.lo, b.lo, mask.lo); + res.hi = _mm_blendv_pd(a.hi, b.hi, mask.hi); + return res; +} + +template<int imm8> +AVX2NEON_ABI +__m256 __mm256_dp_ps (__m256 a, __m256 b) +{ + __m256 res; + res.lo = _mm_dp_ps(a.lo, b.lo, imm8); + res.hi = _mm_dp_ps(a.hi, b.hi, imm8); + return res; +} + +#define _mm256_dp_ps(a,b,c) __mm256_dp_ps<c>(a,b) + +AVX2NEON_ABI +double _mm256_permute4x64_pd_select(__m256d a, const int imm8) +{ + switch (imm8 & 3) { + case 0: + return ((float64x2_t)a.lo)[0]; + case 1: + return ((float64x2_t)a.lo)[1]; + case 2: + return ((float64x2_t)a.hi)[0]; + case 3: + return ((float64x2_t)a.hi)[1]; + } + __builtin_unreachable(); + return 0; +} + +AVX2NEON_ABI +__m256d _mm256_permute4x64_pd (__m256d a, const int imm8) +{ + float64x2_t lo,hi; + lo[0] = _mm256_permute4x64_pd_select(a,imm8 >> 0); + lo[1] = _mm256_permute4x64_pd_select(a,imm8 >> 2); + hi[0] = _mm256_permute4x64_pd_select(a,imm8 >> 4); + hi[1] = _mm256_permute4x64_pd_select(a,imm8 >> 6); + + __m256d res; + res.lo = lo; res.hi = hi; + return res; +} + +AVX2NEON_ABI +__m256i _mm256_insertf128_si256 (__m256i a, __m128i b, int imm8) +{ + return __m256i(_mm256_insertf128_ps((__m256)a,(__m128)b,imm8)); +} + + +AVX2NEON_ABI +__m256i _mm256_loadu_si256 (__m256i const * mem_addr) +{ + __m256i res; + res.lo = *(__m128i *)((int32_t *)mem_addr + 0); + res.hi = *(__m128i *)((int32_t *)mem_addr + 4); + return res; +} + +#define _mm256_load_si256 _mm256_loadu_si256 + +AVX2NEON_ABI +void _mm256_storeu_ps (float * mem_addr, __m256 a) +{ + *(__m128 *)(mem_addr + 0) = a.lo; + *(__m128 *)(mem_addr + 4) = a.hi; +} + +#define _mm256_store_ps _mm256_storeu_ps +#define _mm256_stream_ps _mm256_storeu_ps + + +AVX2NEON_ABI +void _mm256_storeu_si256 (__m256i * mem_addr, __m256i a) +{ + *(__m128i *)((int32_t *)mem_addr + 0) = a.lo; + *(__m128i *)((int32_t *)mem_addr + 4) = a.hi; +} + +#define _mm256_store_si256 _mm256_storeu_si256 + + + +AVX2NEON_ABI +__m256i _mm256_permute4x64_epi64 (const __m256i a, const int imm8) +{ + uint8x16x2_t tbl = {a.lo, a.hi}; + + uint8_t sz = sizeof(uint64_t); + uint8_t u64[4] = { + (uint8_t)(((imm8 >> 0) & 0x3) * sz), + (uint8_t)(((imm8 >> 2) & 0x3) * sz), + (uint8_t)(((imm8 >> 4) & 0x3) * sz), + (uint8_t)(((imm8 >> 6) & 0x3) * sz), + }; + + uint8x16_t idx_lo = { + // lo[0] bytes + (uint8_t)(u64[0]+0), (uint8_t)(u64[0]+1), (uint8_t)(u64[0]+2), (uint8_t)(u64[0]+3), + (uint8_t)(u64[0]+4), (uint8_t)(u64[0]+5), (uint8_t)(u64[0]+6), (uint8_t)(u64[0]+7), + + // lo[1] bytes + (uint8_t)(u64[1]+0), (uint8_t)(u64[1]+1), (uint8_t)(u64[1]+2), (uint8_t)(u64[1]+3), + (uint8_t)(u64[1]+4), (uint8_t)(u64[1]+5), (uint8_t)(u64[1]+6), (uint8_t)(u64[1]+7), + }; + uint8x16_t idx_hi = { + // hi[0] bytes + (uint8_t)(u64[2]+0), (uint8_t)(u64[2]+1), (uint8_t)(u64[2]+2), (uint8_t)(u64[2]+3), + (uint8_t)(u64[2]+4), (uint8_t)(u64[2]+5), (uint8_t)(u64[2]+6), (uint8_t)(u64[2]+7), + + // hi[1] bytes + (uint8_t)(u64[3]+0), (uint8_t)(u64[3]+1), (uint8_t)(u64[3]+2), (uint8_t)(u64[3]+3), + (uint8_t)(u64[3]+4), (uint8_t)(u64[3]+5), (uint8_t)(u64[3]+6), (uint8_t)(u64[3]+7), + }; + + uint8x16_t lo = vqtbl2q_u8(tbl, idx_lo); + uint8x16_t hi = vqtbl2q_u8(tbl, idx_hi); + + __m256i res; + res.lo = lo; res.hi = hi; + return res; +} + + +AVX2NEON_ABI +__m256i _mm256_permute2x128_si256(const __m256i a,const __m256i b, const int imm8) +{ + return __m256i(_mm256_permute2f128_ps(__m256(a),__m256(b),imm8)); +} + + + +AVX2NEON_ABI +__m256 _mm256_maskload_ps (float const * mem_addr, __m256i mask) +{ + __m256 res; + res.lo = _mm_maskload_ps(mem_addr,mask.lo); + res.hi = _mm_maskload_ps(mem_addr + 4,mask.hi); + return res; +} + + +AVX2NEON_ABI +__m256i _mm256_cvtepu8_epi32 (__m128i a) +{ + uint8x16_t a_u8 = vreinterpretq_u8_m128i(a); // xxxx xxxx xxxx xxxx HHGG FFEE DDCC BBAA + uint16x8_t u16x8 = vmovl_u8(vget_low_u8(a_u8)); // 00HH 00GG 00FF 00EE 00DD 00CC 00BB 00AA + uint32x4_t lo = vmovl_u16(vget_low_u16(u16x8)); // 0000 00DD 0000 00CC 0000 00BB 0000 00AA + uint32x4_t hi = vmovl_high_u16(u16x8); // 0000 00HH 0000 00GG 0000 00FF 0000 00EE + + __m256i res; + res.lo = lo; res.hi = hi; + return res; +} + + +AVX2NEON_ABI +__m256i _mm256_cvtepi8_epi32 (__m128i a) +{ + int8x16_t a_s8 = vreinterpretq_s8_m128i(a); // xxxx xxxx xxxx xxxx HHGG FFEE DDCC BBAA + int16x8_t s16x8 = vmovl_s8(vget_low_s8(a_s8)); // ssHH ssGG ssFF ssEE ssDD ssCC ssBB ssAA + int32x4_t lo = vmovl_s16(vget_low_s16(s16x8)); // ssss ssDD ssss ssCC ssss ssBB ssss ssAA + int32x4_t hi = vmovl_high_s16(s16x8); // ssss ssHH ssss ssGG ssss ssFF ssss ssEE + + __m256i res; + res.lo = lo; res.hi = hi; + return res; +} + + +AVX2NEON_ABI +__m256i _mm256_cvtepi16_epi32 (__m128i a) +{ + int16x8_t a_s16 = vreinterpretq_s16_m128i(a); // HHHH GGGG FFFF EEEE DDDD CCCC BBBB AAAA + int32x4_t lo = vmovl_s16(vget_low_s16(a_s16)); // ssss DDDD ssss CCCC ssss BBBB ssss AAAA + int32x4_t hi = vmovl_high_s16(a_s16); // ssss HHHH ssss GGGG ssss FFFF ssss EEEE + + __m256i res; + res.lo = lo; res.hi = hi; + return res; +} + + + +AVX2NEON_ABI +void _mm256_maskstore_epi32 (int* mem_addr, __m256i mask, __m256i a) +{ + _mm_maskstore_epi32(mem_addr,mask.lo,a.lo); + _mm_maskstore_epi32(mem_addr + 4,mask.hi,a.hi); +} + +AVX2NEON_ABI +__m256i _mm256_slli_epi64 (__m256i a, int imm8) +{ + __m256i res; + res.lo = _mm_slli_epi64(a.lo,imm8); + res.hi = _mm_slli_epi64(a.hi,imm8); + return res; +} + +AVX2NEON_ABI +__m256i _mm256_slli_epi32 (__m256i a, int imm8) +{ + __m256i res; + res.lo = _mm_slli_epi32(a.lo,imm8); + res.hi = _mm_slli_epi32(a.hi,imm8); + return res; +} + + +AVX2NEON_ABI +__m256i __mm256_slli_epi16 (__m256i a, int imm8) +{ + __m256i res; + res.lo = _mm_slli_epi16(a.lo,imm8); + res.hi = _mm_slli_epi16(a.hi,imm8); + return res; +} + + +AVX2NEON_ABI +__m256i _mm256_srli_epi32 (__m256i a, int imm8) +{ + __m256i res; + res.lo = _mm_srli_epi32(a.lo,imm8); + res.hi = _mm_srli_epi32(a.hi,imm8); + return res; +} + +AVX2NEON_ABI +__m256i __mm256_srli_epi16 (__m256i a, int imm8) +{ + __m256i res; + res.lo = _mm_srli_epi16(a.lo,imm8); + res.hi = _mm_srli_epi16(a.hi,imm8); + return res; +} + +AVX2NEON_ABI +__m256i _mm256_cvtepu16_epi32(__m128i a) +{ + __m256i res; + res.lo = vmovl_u16(vget_low_u16(a)); + res.hi = vmovl_high_u16(a); + return res; +} + +AVX2NEON_ABI +__m256i _mm256_cvtepu8_epi16(__m128i a) +{ + __m256i res; + res.lo = vmovl_u8(vget_low_u8(a)); + res.hi = vmovl_high_u8(a); + return res; +} + + +AVX2NEON_ABI +__m256i _mm256_srai_epi32 (__m256i a, int imm8) +{ + __m256i res; + res.lo = _mm_srai_epi32(a.lo,imm8); + res.hi = _mm_srai_epi32(a.hi,imm8); + return res; +} + +AVX2NEON_ABI +__m256i _mm256_srai_epi16 (__m256i a, int imm8) +{ + __m256i res; + res.lo = _mm_srai_epi16(a.lo,imm8); + res.hi = _mm_srai_epi16(a.hi,imm8); + return res; +} + + +AVX2NEON_ABI +__m256i _mm256_sllv_epi32 (__m256i a, __m256i count) +{ + __m256i res; + res.lo = vshlq_s32(a.lo,count.lo); + res.hi = vshlq_s32(a.hi,count.hi); + return res; + +} + + +AVX2NEON_ABI +__m256i _mm256_srav_epi32 (__m256i a, __m256i count) +{ + __m256i res; + res.lo = vshlq_s32(a.lo,vnegq_s32(count.lo)); + res.hi = vshlq_s32(a.hi,vnegq_s32(count.hi)); + return res; + +} + +AVX2NEON_ABI +__m256i _mm256_srlv_epi32 (__m256i a, __m256i count) +{ + __m256i res; + res.lo = __m128i(vshlq_u32(uint32x4_t(a.lo),vnegq_s32(count.lo))); + res.hi = __m128i(vshlq_u32(uint32x4_t(a.hi),vnegq_s32(count.hi))); + return res; + +} + + +AVX2NEON_ABI +__m256i _mm256_permute2f128_si256 (__m256i a, __m256i b, int imm8) +{ + return __m256i(_mm256_permute2f128_ps(__m256(a),__m256(b),imm8)); +} + + +AVX2NEON_ABI +__m128i _mm256_extractf128_si256 (__m256i a, const int imm8) +{ + if (imm8 & 1) return a.hi; + return a.lo; +} + +AVX2NEON_ABI +__m256 _mm256_set1_ps(float x) +{ + __m256 res; + res.lo = res.hi = vdupq_n_f32(x); + return res; +} + +AVX2NEON_ABI +__m256 _mm256_set_ps (float e7, float e6, float e5, float e4, float e3, float e2, float e1, float e0) +{ + __m256 res; + res.lo = _mm_set_ps(e3,e2,e1,e0); + res.hi = _mm_set_ps(e7,e6,e5,e4); + return res; +} + +AVX2NEON_ABI +__m256 _mm256_broadcast_ps (__m128 const * mem_addr) +{ + __m256 res; + res.lo = res.hi = *mem_addr; + return res; +} + +AVX2NEON_ABI +__m256 _mm256_cvtepi32_ps (__m256i a) +{ + __m256 res; + res.lo = _mm_cvtepi32_ps(a.lo); + res.hi = _mm_cvtepi32_ps(a.hi); + return res; +} +AVX2NEON_ABI +void _mm256_maskstore_ps (float * mem_addr, __m256i mask, __m256 a) +{ + uint32x4_t mask_lo = mask.lo; + uint32x4_t mask_hi = mask.hi; + float32x4_t a_lo = a.lo; + float32x4_t a_hi = a.hi; + + for (int i=0;i<4;i++) { + if (mask_lo[i] & 0x80000000) mem_addr[i] = a_lo[i]; + if (mask_hi[i] & 0x80000000) mem_addr[i+4] = a_hi[i]; + } +} + +AVX2NEON_ABI +__m256d _mm256_andnot_pd (__m256d a, __m256d b) +{ + __m256d res; + res.lo = float64x2_t(_mm_andnot_ps(__m128(a.lo),__m128(b.lo))); + res.hi = float64x2_t(_mm_andnot_ps(__m128(a.hi),__m128(b.hi))); + return res; +} + +AVX2NEON_ABI +__m256 _mm256_blend_ps (__m256 a, __m256 b, const int imm8) +{ + __m256 res; + res.lo = _mm_blend_ps(a.lo,b.lo,imm8 & 0xf); + res.hi = _mm_blend_ps(a.hi,b.hi,imm8 >> 4); + return res; + +} + + +AVX2NEON_ABI +__m256i _mm256_blend_epi32 (__m256i a, __m256i b, const int imm8) +{ + return __m256i(_mm256_blend_ps(__m256(a),__m256(b),imm8)); + +} + +AVX2NEON_ABI +__m256i _mm256_blend_epi16 (__m256i a, __m256i b, const int imm8) +{ + __m256i res; + res.lo = _mm_blend_epi16(a.lo,b.lo,imm8); + res.hi = _mm_blend_epi16(a.hi,b.hi,imm8); + return res; +} + + + +AVX2NEON_ABI +__m256i _mm256_i32gather_epi32 (int const* base_addr, __m256i vindex, const int scale) +{ + int32x4_t vindex_lo = vindex.lo; + int32x4_t vindex_hi = vindex.hi; + int32x4_t lo,hi; + for (int i=0;i<4;i++) + { + lo[i] = *(int32_t *)((char *) base_addr + (vindex_lo[i]*scale)); + hi[i] = *(int32_t *)((char *) base_addr + (vindex_hi[i]*scale)); + } + + __m256i res; + res.lo = lo; res.hi = hi; + return res; +} + + +AVX2NEON_ABI +__m256i _mm256_mask_i32gather_epi32 (__m256i src, int const* base_addr, __m256i vindex, __m256i mask, const int scale) +{ + uint32x4_t mask_lo = mask.lo; + uint32x4_t mask_hi = mask.hi; + int32x4_t vindex_lo = vindex.lo; + int32x4_t vindex_hi = vindex.hi; + int32x4_t lo,hi; + lo = hi = _mm_setzero_si128(); + for (int i=0;i<4;i++) + { + if (mask_lo[i] >> 31) lo[i] = *(int32_t *)((char *) base_addr + (vindex_lo[i]*scale)); + if (mask_hi[i] >> 31) hi[i] = *(int32_t *)((char *) base_addr + (vindex_hi[i]*scale)); + } + + __m256i res; + res.lo = lo; res.hi = hi; + return res; +} diff --git a/thirdparty/embree/common/simd/arm/emulation.h b/thirdparty/embree/common/simd/arm/emulation.h index 1c3875fb27..4327298019 100644 --- a/thirdparty/embree/common/simd/arm/emulation.h +++ b/thirdparty/embree/common/simd/arm/emulation.h @@ -11,33 +11,28 @@ #include "sse2neon.h" -__forceinline __m128 _mm_fmsub_ps(__m128 a, __m128 b, __m128 c) { - __m128 neg_c = vreinterpretq_m128_f32(vnegq_f32(vreinterpretq_f32_m128(c))); - return _mm_fmadd_ps(a, b, neg_c); -} - -__forceinline __m128 _mm_fnmadd_ps(__m128 a, __m128 b, __m128 c) { -#if defined(__aarch64__) - return vreinterpretq_m128_f32(vfmsq_f32(vreinterpretq_f32_m128(c), - vreinterpretq_f32_m128(b), - vreinterpretq_f32_m128(a))); -#else - return _mm_sub_ps(c, _mm_mul_ps(a, b)); -#endif -} +__forceinline __m128 _mm_abs_ps(__m128 a) { return vabsq_f32(a); } + +__forceinline __m128 _mm_fmadd_ps (__m128 a, __m128 b, __m128 c) { return vfmaq_f32(c, a, b); } +__forceinline __m128 _mm_fnmadd_ps(__m128 a, __m128 b, __m128 c) { return vfmsq_f32(c, a, b); } +__forceinline __m128 _mm_fnmsub_ps(__m128 a, __m128 b, __m128 c) { return vnegq_f32(vfmaq_f32(c, a, b)); } +__forceinline __m128 _mm_fmsub_ps (__m128 a, __m128 b, __m128 c) { return vnegq_f32(vfmsq_f32(c, a, b)); } -__forceinline __m128 _mm_fnmsub_ps(__m128 a, __m128 b, __m128 c) { - return vreinterpretq_m128_f32(vnegq_f32(vreinterpretq_f32_m128(_mm_fmadd_ps(a,b,c)))); +__forceinline __m128 _mm_broadcast_ss (float const * mem_addr) +{ + return vdupq_n_f32(*mem_addr); } +// AVX2 emulation leverages Intel FMA defs above. Include after them. +#include "avx2neon.h" /* Dummy defines for floating point control */ #define _MM_MASK_MASK 0x1f80 #define _MM_MASK_DIV_ZERO 0x200 -#define _MM_FLUSH_ZERO_ON 0x8000 +// #define _MM_FLUSH_ZERO_ON 0x8000 #define _MM_MASK_DENORM 0x100 #define _MM_SET_EXCEPTION_MASK(x) -#define _MM_SET_FLUSH_ZERO_MODE(x) +// #define _MM_SET_FLUSH_ZERO_MODE(x) __forceinline int _mm_getcsr() { @@ -48,3 +43,43 @@ __forceinline void _mm_mfence() { __sync_synchronize(); } + +__forceinline __m128i _mm_load4epu8_epi32(__m128i *ptr) +{ + uint8x8_t t0 = vld1_u8((uint8_t*)ptr); + uint16x8_t t1 = vmovl_u8(t0); + uint32x4_t t2 = vmovl_u16(vget_low_u16(t1)); + return vreinterpretq_s32_u32(t2); +} + +__forceinline __m128i _mm_load4epu16_epi32(__m128i *ptr) +{ + uint16x8_t t0 = vld1q_u16((uint16_t*)ptr); + uint32x4_t t1 = vmovl_u16(vget_low_u16(t0)); + return vreinterpretq_s32_u32(t1); +} + +__forceinline __m128i _mm_load4epi8_f32(__m128i *ptr) +{ + int8x8_t t0 = vld1_s8((int8_t*)ptr); + int16x8_t t1 = vmovl_s8(t0); + int32x4_t t2 = vmovl_s16(vget_low_s16(t1)); + float32x4_t t3 = vcvtq_f32_s32(t2); + return vreinterpretq_s32_f32(t3); +} + +__forceinline __m128i _mm_load4epu8_f32(__m128i *ptr) +{ + uint8x8_t t0 = vld1_u8((uint8_t*)ptr); + uint16x8_t t1 = vmovl_u8(t0); + uint32x4_t t2 = vmovl_u16(vget_low_u16(t1)); + return vreinterpretq_s32_u32(t2); +} + +__forceinline __m128i _mm_load4epi16_f32(__m128i *ptr) +{ + int16x8_t t0 = vld1q_s16((int16_t*)ptr); + int32x4_t t1 = vmovl_s16(vget_low_s16(t0)); + float32x4_t t2 = vcvtq_f32_s32(t1); + return vreinterpretq_s32_f32(t2); +} diff --git a/thirdparty/embree/common/simd/arm/sse2neon.h b/thirdparty/embree/common/simd/arm/sse2neon.h index 7eb25cf2c5..43416662d7 100644 --- a/thirdparty/embree/common/simd/arm/sse2neon.h +++ b/thirdparty/embree/common/simd/arm/sse2neon.h @@ -52,7 +52,7 @@ /* Enable precise implementation of math operations * This would slow down the computation a bit, but gives consistent result with - * x86 SSE2. (e.g. would solve a hole or NaN pixel in the rendering result) + * x86 SSE. (e.g. would solve a hole or NaN pixel in the rendering result) */ /* _mm_min_ps and _mm_max_ps */ #ifndef SSE2NEON_PRECISE_MINMAX @@ -66,36 +66,29 @@ #ifndef SSE2NEON_PRECISE_SQRT #define SSE2NEON_PRECISE_SQRT (0) #endif -#ifndef SSE2NEON_PRECISE_RSQRT -#define SSE2NEON_PRECISE_RSQRT (0) +/* _mm_dp_pd */ +#ifndef SSE2NEON_PRECISE_DP +#define SSE2NEON_PRECISE_DP (0) #endif +/* compiler specific definitions */ #if defined(__GNUC__) || defined(__clang__) #pragma push_macro("FORCE_INLINE") #pragma push_macro("ALIGN_STRUCT") #define FORCE_INLINE static inline __attribute__((always_inline)) #define ALIGN_STRUCT(x) __attribute__((aligned(x))) -#ifndef likely -#define likely(x) __builtin_expect(!!(x), 1) -#endif -#ifndef unlikely -#define unlikely(x) __builtin_expect(!!(x), 0) -#endif -#else -#error "Macro name collisions may happen with unsupported compiler." -#ifdef FORCE_INLINE -#undef FORCE_INLINE -#endif +#define _sse2neon_likely(x) __builtin_expect(!!(x), 1) +#define _sse2neon_unlikely(x) __builtin_expect(!!(x), 0) +#else /* non-GNU / non-clang compilers */ +#warning "Macro name collisions may happen with unsupported compiler." +#ifndef FORCE_INLINE #define FORCE_INLINE static inline +#endif #ifndef ALIGN_STRUCT #define ALIGN_STRUCT(x) __declspec(align(x)) #endif -#endif -#ifndef likely -#define likely(x) (x) -#endif -#ifndef unlikely -#define unlikely(x) (x) +#define _sse2neon_likely(x) (x) +#define _sse2neon_unlikely(x) (x) #endif #include <stdint.h> @@ -155,6 +148,14 @@ * argument "a" of mm_shuffle_ps that will be places in fp1 of result. * fp0 is the same for fp0 of result. */ +#if defined(__aarch64__) +#define _MN_SHUFFLE(fp3,fp2,fp1,fp0) ( (uint8x16_t){ (((fp3)*4)+0), (((fp3)*4)+1), (((fp3)*4)+2), (((fp3)*4)+3), (((fp2)*4)+0), (((fp2)*4)+1), (((fp2)*4)+\ +2), (((fp2)*4)+3), (((fp1)*4)+0), (((fp1)*4)+1), (((fp1)*4)+2), (((fp1)*4)+3), (((fp0)*4)+0), (((fp0)*4)+1), (((fp0)*4)+2), (((fp0)*4)+3) } ) +#define _MF_SHUFFLE(fp3,fp2,fp1,fp0) ( (uint8x16_t){ (((fp3)*4)+0), (((fp3)*4)+1), (((fp3)*4)+2), (((fp3)*4)+3), (((fp2)*4)+0), (((fp2)*4)+1), (((fp2)*4)+\ +2), (((fp2)*4)+3), (((fp1)*4)+16+0), (((fp1)*4)+16+1), (((fp1)*4)+16+2), (((fp1)*4)+16+3), (((fp0)*4)+16+0), (((fp0)*4)+16+1), (((fp0)*4)+16+2), (((fp0)*\ +4)+16+3) } ) +#endif + #define _MM_SHUFFLE(fp3, fp2, fp1, fp0) \ (((fp3) << 6) | ((fp2) << 4) | ((fp1) << 2) | ((fp0))) @@ -169,6 +170,14 @@ #define _MM_ROUND_DOWN 0x2000 #define _MM_ROUND_UP 0x4000 #define _MM_ROUND_TOWARD_ZERO 0x6000 +/* Flush zero mode macros. */ +#define _MM_FLUSH_ZERO_MASK 0x8000 +#define _MM_FLUSH_ZERO_ON 0x8000 +#define _MM_FLUSH_ZERO_OFF 0x0000 +/* Denormals are zeros mode macros. */ +#define _MM_DENORMALS_ZERO_MASK 0x0040 +#define _MM_DENORMALS_ZERO_ON 0x0040 +#define _MM_DENORMALS_ZERO_OFF 0x0000 /* indicate immediate constant argument in a given range */ #define __constrange(a, b) const @@ -189,7 +198,10 @@ typedef float64x2_t __m128d; /* 128-bit vector containing 2 doubles */ #else typedef float32x4_t __m128d; #endif -typedef int64x2_t __m128i; /* 128-bit vector containing integers */ +// Note: upstream sse2neon declares __m128i as int64x2_t. However, there's +// many places within embree that assume __m128i can be indexed as a +// 4 element u32. +typedef int32x4_t __m128i; /* 128-bit vector containing integers */ /* type-safe casting between types */ @@ -221,28 +233,28 @@ typedef int64x2_t __m128i; /* 128-bit vector containing integers */ #define vreinterpretq_s32_m128(x) vreinterpretq_s32_f32(x) #define vreinterpretq_s64_m128(x) vreinterpretq_s64_f32(x) -#define vreinterpretq_m128i_s8(x) vreinterpretq_s64_s8(x) -#define vreinterpretq_m128i_s16(x) vreinterpretq_s64_s16(x) -#define vreinterpretq_m128i_s32(x) vreinterpretq_s64_s32(x) -#define vreinterpretq_m128i_s64(x) (x) +#define vreinterpretq_m128i_s8(x) vreinterpretq_s32_s8(x) +#define vreinterpretq_m128i_s16(x) vreinterpretq_s32_s16(x) +#define vreinterpretq_m128i_s32(x) (x) +#define vreinterpretq_m128i_s64(x) vreinterpretq_s32_s64(x) -#define vreinterpretq_m128i_u8(x) vreinterpretq_s64_u8(x) -#define vreinterpretq_m128i_u16(x) vreinterpretq_s64_u16(x) -#define vreinterpretq_m128i_u32(x) vreinterpretq_s64_u32(x) -#define vreinterpretq_m128i_u64(x) vreinterpretq_s64_u64(x) +#define vreinterpretq_m128i_u8(x) vreinterpretq_s32_u8(x) +#define vreinterpretq_m128i_u16(x) vreinterpretq_s32_u16(x) +#define vreinterpretq_m128i_u32(x) vreinterpretq_s32_u32(x) +#define vreinterpretq_m128i_u64(x) vreinterpretq_s32_u64(x) -#define vreinterpretq_f32_m128i(x) vreinterpretq_f32_s64(x) -#define vreinterpretq_f64_m128i(x) vreinterpretq_f64_s64(x) +#define vreinterpretq_f32_m128i(x) vreinterpretq_f32_s32(x) +#define vreinterpretq_f64_m128i(x) vreinterpretq_f64_s32(x) -#define vreinterpretq_s8_m128i(x) vreinterpretq_s8_s64(x) -#define vreinterpretq_s16_m128i(x) vreinterpretq_s16_s64(x) -#define vreinterpretq_s32_m128i(x) vreinterpretq_s32_s64(x) -#define vreinterpretq_s64_m128i(x) (x) +#define vreinterpretq_s8_m128i(x) vreinterpretq_s8_s32(x) +#define vreinterpretq_s16_m128i(x) vreinterpretq_s16_s32(x) +#define vreinterpretq_s32_m128i(x) (x) +#define vreinterpretq_s64_m128i(x) vreinterpretq_s64_s32(x) -#define vreinterpretq_u8_m128i(x) vreinterpretq_u8_s64(x) -#define vreinterpretq_u16_m128i(x) vreinterpretq_u16_s64(x) -#define vreinterpretq_u32_m128i(x) vreinterpretq_u32_s64(x) -#define vreinterpretq_u64_m128i(x) vreinterpretq_u64_s64(x) +#define vreinterpretq_u8_m128i(x) vreinterpretq_u8_s32(x) +#define vreinterpretq_u16_m128i(x) vreinterpretq_u16_s32(x) +#define vreinterpretq_u32_m128i(x) vreinterpretq_u32_s32(x) +#define vreinterpretq_u64_m128i(x) vreinterpretq_u64_s32(x) #define vreinterpret_m64_s8(x) vreinterpret_s64_s8(x) #define vreinterpret_m64_s16(x) vreinterpret_s64_s16(x) @@ -281,6 +293,7 @@ typedef int64x2_t __m128i; /* 128-bit vector containing integers */ #define vreinterpretq_s64_m128d(x) vreinterpretq_s64_f64(x) +#define vreinterpretq_u32_m128d(x) vreinterpretq_u32_f64(x) #define vreinterpretq_u64_m128d(x) vreinterpretq_u64_f64(x) #define vreinterpretq_f64_m128d(x) (x) @@ -303,10 +316,10 @@ typedef int64x2_t __m128i; /* 128-bit vector containing integers */ #endif // A struct is defined in this header file called 'SIMDVec' which can be used -// by applications which attempt to access the contents of an _m128 struct +// by applications which attempt to access the contents of an __m128 struct // directly. It is important to note that accessing the __m128 struct directly // is bad coding practice by Microsoft: @see: -// https://msdn.microsoft.com/en-us/library/ayeb3ayc.aspx +// https://docs.microsoft.com/en-us/cpp/cpp/m128 // // However, some legacy source code may try to access the contents of an __m128 // struct directly so the developer can use the SIMDVec as an alias for it. Any @@ -342,13 +355,48 @@ typedef union ALIGN_STRUCT(16) SIMDVec { #define vreinterpretq_nth_u32_m128i(x, n) (((SIMDVec *) &x)->m128_u32[n]) #define vreinterpretq_nth_u8_m128i(x, n) (((SIMDVec *) &x)->m128_u8[n]) +/* SSE macros */ +#define _MM_GET_FLUSH_ZERO_MODE _sse2neon_mm_get_flush_zero_mode +#define _MM_SET_FLUSH_ZERO_MODE _sse2neon_mm_set_flush_zero_mode +#define _MM_GET_DENORMALS_ZERO_MODE _sse2neon_mm_get_denormals_zero_mode +#define _MM_SET_DENORMALS_ZERO_MODE _sse2neon_mm_set_denormals_zero_mode + +// Function declaration +// SSE +FORCE_INLINE unsigned int _MM_GET_ROUNDING_MODE(); +FORCE_INLINE __m128 _mm_move_ss(__m128, __m128); +FORCE_INLINE __m128 _mm_or_ps(__m128, __m128); +FORCE_INLINE __m128 _mm_set_ps1(float); +FORCE_INLINE __m128 _mm_setzero_ps(void); +// SSE2 +FORCE_INLINE __m128i _mm_and_si128(__m128i, __m128i); +FORCE_INLINE __m128i _mm_castps_si128(__m128); +FORCE_INLINE __m128i _mm_cmpeq_epi32(__m128i, __m128i); +FORCE_INLINE __m128i _mm_cvtps_epi32(__m128); +FORCE_INLINE __m128d _mm_move_sd(__m128d, __m128d); +FORCE_INLINE __m128i _mm_or_si128(__m128i, __m128i); +FORCE_INLINE __m128i _mm_set_epi32(int, int, int, int); +FORCE_INLINE __m128i _mm_set_epi64x(int64_t, int64_t); +FORCE_INLINE __m128d _mm_set_pd(double, double); +FORCE_INLINE __m128i _mm_set1_epi32(int); +FORCE_INLINE __m128i _mm_setzero_si128(); +// SSE4.1 +FORCE_INLINE __m128d _mm_ceil_pd(__m128d); +FORCE_INLINE __m128 _mm_ceil_ps(__m128); +FORCE_INLINE __m128d _mm_floor_pd(__m128d); +FORCE_INLINE __m128 _mm_floor_ps(__m128); +FORCE_INLINE __m128d _mm_round_pd(__m128d, int); +FORCE_INLINE __m128 _mm_round_ps(__m128, int); +// SSE4.2 +FORCE_INLINE uint32_t _mm_crc32_u8(uint32_t, uint8_t); + /* Backwards compatibility for compilers with lack of specific type support */ // Older gcc does not define vld1q_u8_x4 type -#if defined(__GNUC__) && !defined(__clang__) && \ - ((__GNUC__ == 10 && (__GNUC_MINOR__ <= 1)) || \ - (__GNUC__ == 9 && (__GNUC_MINOR__ <= 3)) || \ - (__GNUC__ == 8 && (__GNUC_MINOR__ <= 4)) || __GNUC__ <= 7) +#if defined(__GNUC__) && !defined(__clang__) && \ + ((__GNUC__ <= 10 && defined(__arm__)) || \ + (__GNUC__ == 10 && __GNUC_MINOR__ < 3 && defined(__aarch64__)) || \ + (__GNUC__ <= 9 && defined(__aarch64__))) FORCE_INLINE uint8x16x4_t _sse2neon_vld1q_u8_x4(const uint8_t *p) { uint8x16x4_t ret; @@ -443,8 +491,6 @@ FORCE_INLINE uint8x16x4_t _sse2neon_vld1q_u8_x4(const uint8_t *p) +------+------+------+------+------+------+-------------+ */ -/* Set/get methods */ - /* Constants for use with _mm_prefetch. */ enum _mm_hint { _MM_HINT_NTA = 0, /* load data to L1 and L2 cache, mark it as NTA */ @@ -457,1098 +503,1568 @@ enum _mm_hint { _MM_HINT_ET2 = 7 /* exclusive version of _MM_HINT_T2 */ }; -// Loads one cache line of data from address p to a location closer to the -// processor. https://msdn.microsoft.com/en-us/library/84szxsww(v=vs.100).aspx -FORCE_INLINE void _mm_prefetch(const void *p, int i) +// The bit field mapping to the FPCR(floating-point control register) +typedef struct { + uint16_t res0; + uint8_t res1 : 6; + uint8_t bit22 : 1; + uint8_t bit23 : 1; + uint8_t bit24 : 1; + uint8_t res2 : 7; +#if defined(__aarch64__) + uint32_t res3; +#endif +} fpcr_bitfield; + +// Takes the upper 64 bits of a and places it in the low end of the result +// Takes the lower 64 bits of b and places it into the high end of the result. +FORCE_INLINE __m128 _mm_shuffle_ps_1032(__m128 a, __m128 b) { - (void) i; - __builtin_prefetch(p); + float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a)); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a32, b10)); } -// Pause the processor. This is typically used in spin-wait loops and depending -// on the x86 processor typical values are in the 40-100 cycle range. The -// 'yield' instruction isn't a good fit beacuse it's effectively a nop on most -// Arm cores. Experience with several databases has shown has shown an 'isb' is -// a reasonable approximation. -FORCE_INLINE void _mm_pause() +// takes the lower two 32-bit values from a and swaps them and places in high +// end of result takes the higher two 32 bit values from b and swaps them and +// places in low end of result. +FORCE_INLINE __m128 _mm_shuffle_ps_2301(__m128 a, __m128 b) { - __asm__ __volatile__("isb\n"); + float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); + float32x2_t b23 = vrev64_f32(vget_high_f32(vreinterpretq_f32_m128(b))); + return vreinterpretq_m128_f32(vcombine_f32(a01, b23)); } -// Copy the lower single-precision (32-bit) floating-point element of a to dst. -// -// dst[31:0] := a[31:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_f32 -FORCE_INLINE float _mm_cvtss_f32(__m128 a) +FORCE_INLINE __m128 _mm_shuffle_ps_0321(__m128 a, __m128 b) { - return vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + float32x2_t a21 = vget_high_f32( + vextq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 3)); + float32x2_t b03 = vget_low_f32( + vextq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b), 3)); + return vreinterpretq_m128_f32(vcombine_f32(a21, b03)); } -// Convert the lower single-precision (32-bit) floating-point element in b to a -// double-precision (64-bit) floating-point element, store the result in the -// lower element of dst, and copy the upper element from a to the upper element -// of dst. +FORCE_INLINE __m128 _mm_shuffle_ps_2103(__m128 a, __m128 b) +{ + float32x2_t a03 = vget_low_f32( + vextq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 3)); + float32x2_t b21 = vget_high_f32( + vextq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b), 3)); + return vreinterpretq_m128_f32(vcombine_f32(a03, b21)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_1010(__m128 a, __m128 b) +{ + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a10, b10)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_1001(__m128 a, __m128 b) +{ + float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a01, b10)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_0101(__m128 a, __m128 b) +{ + float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); + float32x2_t b01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(b))); + return vreinterpretq_m128_f32(vcombine_f32(a01, b01)); +} + +// keeps the low 64 bits of b in the low and puts the high 64 bits of a in the +// high +FORCE_INLINE __m128 _mm_shuffle_ps_3210(__m128 a, __m128 b) +{ + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a10, b32)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_0011(__m128 a, __m128 b) +{ + float32x2_t a11 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(a)), 1); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + return vreinterpretq_m128_f32(vcombine_f32(a11, b00)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_0022(__m128 a, __m128 b) +{ + float32x2_t a22 = + vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(a)), 0); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + return vreinterpretq_m128_f32(vcombine_f32(a22, b00)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_2200(__m128 a, __m128 b) +{ + float32x2_t a00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(a)), 0); + float32x2_t b22 = + vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(b)), 0); + return vreinterpretq_m128_f32(vcombine_f32(a00, b22)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_3202(__m128 a, __m128 b) +{ + float32_t a0 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + float32x2_t a22 = + vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(a)), 0); + float32x2_t a02 = vset_lane_f32(a0, a22, 1); /* TODO: use vzip ?*/ + float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a02, b32)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_1133(__m128 a, __m128 b) +{ + float32x2_t a33 = + vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(a)), 1); + float32x2_t b11 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 1); + return vreinterpretq_m128_f32(vcombine_f32(a33, b11)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_2010(__m128 a, __m128 b) +{ + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32_t b2 = vgetq_lane_f32(vreinterpretq_f32_m128(b), 2); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + float32x2_t b20 = vset_lane_f32(b2, b00, 1); + return vreinterpretq_m128_f32(vcombine_f32(a10, b20)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_2001(__m128 a, __m128 b) +{ + float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); + float32_t b2 = vgetq_lane_f32(b, 2); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + float32x2_t b20 = vset_lane_f32(b2, b00, 1); + return vreinterpretq_m128_f32(vcombine_f32(a01, b20)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_2032(__m128 a, __m128 b) +{ + float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a)); + float32_t b2 = vgetq_lane_f32(b, 2); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + float32x2_t b20 = vset_lane_f32(b2, b00, 1); + return vreinterpretq_m128_f32(vcombine_f32(a32, b20)); +} + +// Kahan summation for accurate summation of floating-point numbers. +// http://blog.zachbjornson.com/2019/08/11/fast-float-summation.html +FORCE_INLINE void _sse2neon_kadd_f32(float *sum, float *c, float y) +{ + y -= *c; + float t = *sum + y; + *c = (t - *sum) - y; + *sum = t; +} + +#if defined(__ARM_FEATURE_CRYPTO) +// Wraps vmull_p64 +FORCE_INLINE uint64x2_t _sse2neon_vmull_p64(uint64x1_t _a, uint64x1_t _b) +{ + poly64_t a = vget_lane_p64(vreinterpret_p64_u64(_a), 0); + poly64_t b = vget_lane_p64(vreinterpret_p64_u64(_b), 0); + return vreinterpretq_u64_p128(vmull_p64(a, b)); +} +#else // ARMv7 polyfill +// ARMv7/some A64 lacks vmull_p64, but it has vmull_p8. // -// dst[63:0] := Convert_FP32_To_FP64(b[31:0]) -// dst[127:64] := a[127:64] +// vmull_p8 calculates 8 8-bit->16-bit polynomial multiplies, but we need a +// 64-bit->128-bit polynomial multiply. // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_sd -FORCE_INLINE __m128d _mm_cvtss_sd(__m128d a, __m128 b) +// It needs some work and is somewhat slow, but it is still faster than all +// known scalar methods. +// +// Algorithm adapted to C from +// https://www.workofard.com/2017/07/ghash-for-low-end-cores/, which is adapted +// from "Fast Software Polynomial Multiplication on ARM Processors Using the +// NEON Engine" by Danilo Camara, Conrado Gouvea, Julio Lopez and Ricardo Dahab +// (https://hal.inria.fr/hal-01506572) +static uint64x2_t _sse2neon_vmull_p64(uint64x1_t _a, uint64x1_t _b) { - double d = (double) vgetq_lane_f32(vreinterpretq_f32_m128(b), 0); + poly8x8_t a = vreinterpret_p8_u64(_a); + poly8x8_t b = vreinterpret_p8_u64(_b); + + // Masks + uint8x16_t k48_32 = vcombine_u8(vcreate_u8(0x0000ffffffffffff), + vcreate_u8(0x00000000ffffffff)); + uint8x16_t k16_00 = vcombine_u8(vcreate_u8(0x000000000000ffff), + vcreate_u8(0x0000000000000000)); + + // Do the multiplies, rotating with vext to get all combinations + uint8x16_t d = vreinterpretq_u8_p16(vmull_p8(a, b)); // D = A0 * B0 + uint8x16_t e = + vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 1))); // E = A0 * B1 + uint8x16_t f = + vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 1), b)); // F = A1 * B0 + uint8x16_t g = + vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 2))); // G = A0 * B2 + uint8x16_t h = + vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 2), b)); // H = A2 * B0 + uint8x16_t i = + vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 3))); // I = A0 * B3 + uint8x16_t j = + vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 3), b)); // J = A3 * B0 + uint8x16_t k = + vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 4))); // L = A0 * B4 + + // Add cross products + uint8x16_t l = veorq_u8(e, f); // L = E + F + uint8x16_t m = veorq_u8(g, h); // M = G + H + uint8x16_t n = veorq_u8(i, j); // N = I + J + + // Interleave. Using vzip1 and vzip2 prevents Clang from emitting TBL + // instructions. #if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vsetq_lane_f64(d, vreinterpretq_f64_m128d(a), 0)); + uint8x16_t lm_p0 = vreinterpretq_u8_u64( + vzip1q_u64(vreinterpretq_u64_u8(l), vreinterpretq_u64_u8(m))); + uint8x16_t lm_p1 = vreinterpretq_u8_u64( + vzip2q_u64(vreinterpretq_u64_u8(l), vreinterpretq_u64_u8(m))); + uint8x16_t nk_p0 = vreinterpretq_u8_u64( + vzip1q_u64(vreinterpretq_u64_u8(n), vreinterpretq_u64_u8(k))); + uint8x16_t nk_p1 = vreinterpretq_u8_u64( + vzip2q_u64(vreinterpretq_u64_u8(n), vreinterpretq_u64_u8(k))); #else - return vreinterpretq_m128d_s64( - vsetq_lane_s64(*(int64_t *) &d, vreinterpretq_s64_m128d(a), 0)); + uint8x16_t lm_p0 = vcombine_u8(vget_low_u8(l), vget_low_u8(m)); + uint8x16_t lm_p1 = vcombine_u8(vget_high_u8(l), vget_high_u8(m)); + uint8x16_t nk_p0 = vcombine_u8(vget_low_u8(n), vget_low_u8(k)); + uint8x16_t nk_p1 = vcombine_u8(vget_high_u8(n), vget_high_u8(k)); #endif -} + // t0 = (L) (P0 + P1) << 8 + // t1 = (M) (P2 + P3) << 16 + uint8x16_t t0t1_tmp = veorq_u8(lm_p0, lm_p1); + uint8x16_t t0t1_h = vandq_u8(lm_p1, k48_32); + uint8x16_t t0t1_l = veorq_u8(t0t1_tmp, t0t1_h); -// Convert the lower single-precision (32-bit) floating-point element in a to a -// 32-bit integer, and store the result in dst. -// -// dst[31:0] := Convert_FP32_To_Int32(a[31:0]) -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_si32 -#define _mm_cvtss_si32(a) _mm_cvt_ss2si(a) + // t2 = (N) (P4 + P5) << 24 + // t3 = (K) (P6 + P7) << 32 + uint8x16_t t2t3_tmp = veorq_u8(nk_p0, nk_p1); + uint8x16_t t2t3_h = vandq_u8(nk_p1, k16_00); + uint8x16_t t2t3_l = veorq_u8(t2t3_tmp, t2t3_h); -// Convert the lower single-precision (32-bit) floating-point element in a to a -// 64-bit integer, and store the result in dst. -// -// dst[63:0] := Convert_FP32_To_Int64(a[31:0]) -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_si64 -FORCE_INLINE int _mm_cvtss_si64(__m128 a) -{ + // De-interleave #if defined(__aarch64__) - return vgetq_lane_s64( - vreinterpretq_s64_s32(vcvtnq_s32_f32(vreinterpretq_f32_m128(a))), 0); + uint8x16_t t0 = vreinterpretq_u8_u64( + vuzp1q_u64(vreinterpretq_u64_u8(t0t1_l), vreinterpretq_u64_u8(t0t1_h))); + uint8x16_t t1 = vreinterpretq_u8_u64( + vuzp2q_u64(vreinterpretq_u64_u8(t0t1_l), vreinterpretq_u64_u8(t0t1_h))); + uint8x16_t t2 = vreinterpretq_u8_u64( + vuzp1q_u64(vreinterpretq_u64_u8(t2t3_l), vreinterpretq_u64_u8(t2t3_h))); + uint8x16_t t3 = vreinterpretq_u8_u64( + vuzp2q_u64(vreinterpretq_u64_u8(t2t3_l), vreinterpretq_u64_u8(t2t3_h))); #else - float32_t data = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); - float32_t diff = data - floor(data); - if (diff > 0.5) - return (int64_t) ceil(data); - if (unlikely(diff == 0.5)) { - int64_t f = (int64_t) floor(data); - int64_t c = (int64_t) ceil(data); - return c & 1 ? f : c; - } - return (int64_t) floor(data); + uint8x16_t t1 = vcombine_u8(vget_high_u8(t0t1_l), vget_high_u8(t0t1_h)); + uint8x16_t t0 = vcombine_u8(vget_low_u8(t0t1_l), vget_low_u8(t0t1_h)); + uint8x16_t t3 = vcombine_u8(vget_high_u8(t2t3_l), vget_high_u8(t2t3_h)); + uint8x16_t t2 = vcombine_u8(vget_low_u8(t2t3_l), vget_low_u8(t2t3_h)); #endif + // Shift the cross products + uint8x16_t t0_shift = vextq_u8(t0, t0, 15); // t0 << 8 + uint8x16_t t1_shift = vextq_u8(t1, t1, 14); // t1 << 16 + uint8x16_t t2_shift = vextq_u8(t2, t2, 13); // t2 << 24 + uint8x16_t t3_shift = vextq_u8(t3, t3, 12); // t3 << 32 + + // Accumulate the products + uint8x16_t cross1 = veorq_u8(t0_shift, t1_shift); + uint8x16_t cross2 = veorq_u8(t2_shift, t3_shift); + uint8x16_t mix = veorq_u8(d, cross1); + uint8x16_t r = veorq_u8(mix, cross2); + return vreinterpretq_u64_u8(r); } +#endif // ARMv7 polyfill -// Convert packed single-precision (32-bit) floating-point elements in a to -// packed 32-bit integers with truncation, and store the results in dst. -// -// FOR j := 0 to 1 -// i := 32*j -// dst[i+31:i] := Convert_FP32_To_Int32_Truncate(a[i+31:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtt_ps2pi -FORCE_INLINE __m64 _mm_cvtt_ps2pi(__m128 a) +// C equivalent: +// __m128i _mm_shuffle_epi32_default(__m128i a, +// __constrange(0, 255) int imm) { +// __m128i ret; +// ret[0] = a[imm & 0x3]; ret[1] = a[(imm >> 2) & 0x3]; +// ret[2] = a[(imm >> 4) & 0x03]; ret[3] = a[(imm >> 6) & 0x03]; +// return ret; +// } +#define _mm_shuffle_epi32_default(a, imm) \ + __extension__({ \ + int32x4_t ret; \ + ret = vmovq_n_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm) & (0x3))); \ + ret = vsetq_lane_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 2) & 0x3), \ + ret, 1); \ + ret = vsetq_lane_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 4) & 0x3), \ + ret, 2); \ + ret = vsetq_lane_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 6) & 0x3), \ + ret, 3); \ + vreinterpretq_m128i_s32(ret); \ + }) + +// Takes the upper 64 bits of a and places it in the low end of the result +// Takes the lower 64 bits of a and places it into the high end of the result. +FORCE_INLINE __m128i _mm_shuffle_epi_1032(__m128i a) { - return vreinterpret_m64_s32( - vget_low_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a)))); + int32x2_t a32 = vget_high_s32(vreinterpretq_s32_m128i(a)); + int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); + return vreinterpretq_m128i_s32(vcombine_s32(a32, a10)); } -// Convert the lower single-precision (32-bit) floating-point element in a to a -// 32-bit integer with truncation, and store the result in dst. -// -// dst[31:0] := Convert_FP32_To_Int32_Truncate(a[31:0]) -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtt_ss2si -FORCE_INLINE int _mm_cvtt_ss2si(__m128 a) +// takes the lower two 32-bit values from a and swaps them and places in low end +// of result takes the higher two 32 bit values from a and swaps them and places +// in high end of result. +FORCE_INLINE __m128i _mm_shuffle_epi_2301(__m128i a) { - return vgetq_lane_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a)), 0); + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + int32x2_t a23 = vrev64_s32(vget_high_s32(vreinterpretq_s32_m128i(a))); + return vreinterpretq_m128i_s32(vcombine_s32(a01, a23)); } -// Convert packed single-precision (32-bit) floating-point elements in a to -// packed 32-bit integers with truncation, and store the results in dst. -// -// FOR j := 0 to 1 -// i := 32*j -// dst[i+31:i] := Convert_FP32_To_Int32_Truncate(a[i+31:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttps_pi32 -#define _mm_cvttps_pi32(a) _mm_cvtt_ps2pi(a) +// rotates the least significant 32 bits into the most significant 32 bits, and +// shifts the rest down +FORCE_INLINE __m128i _mm_shuffle_epi_0321(__m128i a) +{ + return vreinterpretq_m128i_s32( + vextq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(a), 1)); +} -// Convert the lower single-precision (32-bit) floating-point element in a to a -// 32-bit integer with truncation, and store the result in dst. -// -// dst[31:0] := Convert_FP32_To_Int32_Truncate(a[31:0]) -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttss_si32 -#define _mm_cvttss_si32(a) _mm_cvtt_ss2si(a) +// rotates the most significant 32 bits into the least significant 32 bits, and +// shifts the rest up +FORCE_INLINE __m128i _mm_shuffle_epi_2103(__m128i a) +{ + return vreinterpretq_m128i_s32( + vextq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(a), 3)); +} -// Convert the lower single-precision (32-bit) floating-point element in a to a -// 64-bit integer with truncation, and store the result in dst. -// -// dst[63:0] := Convert_FP32_To_Int64_Truncate(a[31:0]) -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttss_si64 -FORCE_INLINE int64_t _mm_cvttss_si64(__m128 a) +// gets the lower 64 bits of a, and places it in the upper 64 bits +// gets the lower 64 bits of a and places it in the lower 64 bits +FORCE_INLINE __m128i _mm_shuffle_epi_1010(__m128i a) { - return vgetq_lane_s64( - vmovl_s32(vget_low_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a)))), 0); + int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); + return vreinterpretq_m128i_s32(vcombine_s32(a10, a10)); } -// Sets the 128-bit value to zero -// https://msdn.microsoft.com/en-us/library/vstudio/ys7dw0kh(v=vs.100).aspx -FORCE_INLINE __m128i _mm_setzero_si128(void) +// gets the lower 64 bits of a, swaps the 0 and 1 elements, and places it in the +// lower 64 bits gets the lower 64 bits of a, and places it in the upper 64 bits +FORCE_INLINE __m128i _mm_shuffle_epi_1001(__m128i a) { - return vreinterpretq_m128i_s32(vdupq_n_s32(0)); + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); + return vreinterpretq_m128i_s32(vcombine_s32(a01, a10)); } -// Clears the four single-precision, floating-point values. -// https://msdn.microsoft.com/en-us/library/vstudio/tk1t2tbz(v=vs.100).aspx -FORCE_INLINE __m128 _mm_setzero_ps(void) +// gets the lower 64 bits of a, swaps the 0 and 1 elements and places it in the +// upper 64 bits gets the lower 64 bits of a, swaps the 0 and 1 elements, and +// places it in the lower 64 bits +FORCE_INLINE __m128i _mm_shuffle_epi_0101(__m128i a) { - return vreinterpretq_m128_f32(vdupq_n_f32(0)); + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + return vreinterpretq_m128i_s32(vcombine_s32(a01, a01)); } -// Return vector of type __m128d with all elements set to zero. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setzero_pd -FORCE_INLINE __m128d _mm_setzero_pd(void) +FORCE_INLINE __m128i _mm_shuffle_epi_2211(__m128i a) { + int32x2_t a11 = vdup_lane_s32(vget_low_s32(vreinterpretq_s32_m128i(a)), 1); + int32x2_t a22 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 0); + return vreinterpretq_m128i_s32(vcombine_s32(a11, a22)); +} + +FORCE_INLINE __m128i _mm_shuffle_epi_0122(__m128i a) +{ + int32x2_t a22 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 0); + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + return vreinterpretq_m128i_s32(vcombine_s32(a22, a01)); +} + +FORCE_INLINE __m128i _mm_shuffle_epi_3332(__m128i a) +{ + int32x2_t a32 = vget_high_s32(vreinterpretq_s32_m128i(a)); + int32x2_t a33 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 1); + return vreinterpretq_m128i_s32(vcombine_s32(a32, a33)); +} + +// FORCE_INLINE __m128i _mm_shuffle_epi32_splat(__m128i a, __constrange(0,255) +// int imm) #if defined(__aarch64__) - return vreinterpretq_m128d_f64(vdupq_n_f64(0)); +#define _mm_shuffle_epi32_splat(a, imm) \ + __extension__({ \ + vreinterpretq_m128i_s32( \ + vdupq_laneq_s32(vreinterpretq_s32_m128i(a), (imm))); \ + }) #else - return vreinterpretq_m128d_f32(vdupq_n_f32(0)); +#define _mm_shuffle_epi32_splat(a, imm) \ + __extension__({ \ + vreinterpretq_m128i_s32( \ + vdupq_n_s32(vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm)))); \ + }) #endif -} -// Sets the four single-precision, floating-point values to w. +// NEON does not support a general purpose permute intrinsic +// Selects four specific single-precision, floating-point values from a and b, +// based on the mask i. // -// r0 := r1 := r2 := r3 := w +// C equivalent: +// __m128 _mm_shuffle_ps_default(__m128 a, __m128 b, +// __constrange(0, 255) int imm) { +// __m128 ret; +// ret[0] = a[imm & 0x3]; ret[1] = a[(imm >> 2) & 0x3]; +// ret[2] = b[(imm >> 4) & 0x03]; ret[3] = b[(imm >> 6) & 0x03]; +// return ret; +// } // -// https://msdn.microsoft.com/en-us/library/vstudio/2x1se8ha(v=vs.100).aspx -FORCE_INLINE __m128 _mm_set1_ps(float _w) +// https://msdn.microsoft.com/en-us/library/vstudio/5f0858x0(v=vs.100).aspx +#define _mm_shuffle_ps_default(a, b, imm) \ + __extension__({ \ + float32x4_t ret; \ + ret = vmovq_n_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(a), (imm) & (0x3))); \ + ret = vsetq_lane_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(a), ((imm) >> 2) & 0x3), \ + ret, 1); \ + ret = vsetq_lane_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(b), ((imm) >> 4) & 0x3), \ + ret, 2); \ + ret = vsetq_lane_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(b), ((imm) >> 6) & 0x3), \ + ret, 3); \ + vreinterpretq_m128_f32(ret); \ + }) + +// Shuffles the lower 4 signed or unsigned 16-bit integers in a as specified +// by imm. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/y41dkk37(v=vs.100) +// FORCE_INLINE __m128i _mm_shufflelo_epi16_function(__m128i a, +// __constrange(0,255) int +// imm) +#define _mm_shufflelo_epi16_function(a, imm) \ + __extension__({ \ + int16x8_t ret = vreinterpretq_s16_m128i(a); \ + int16x4_t lowBits = vget_low_s16(ret); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, (imm) & (0x3)), ret, 0); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 2) & 0x3), ret, \ + 1); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 4) & 0x3), ret, \ + 2); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 6) & 0x3), ret, \ + 3); \ + vreinterpretq_m128i_s16(ret); \ + }) + +// Shuffles the upper 4 signed or unsigned 16-bit integers in a as specified +// by imm. +// https://msdn.microsoft.com/en-us/library/13ywktbs(v=vs.100).aspx +// FORCE_INLINE __m128i _mm_shufflehi_epi16_function(__m128i a, +// __constrange(0,255) int +// imm) +#define _mm_shufflehi_epi16_function(a, imm) \ + __extension__({ \ + int16x8_t ret = vreinterpretq_s16_m128i(a); \ + int16x4_t highBits = vget_high_s16(ret); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, (imm) & (0x3)), ret, 4); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 2) & 0x3), ret, \ + 5); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 4) & 0x3), ret, \ + 6); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 6) & 0x3), ret, \ + 7); \ + vreinterpretq_m128i_s16(ret); \ + }) + +/* SSE */ + +// Adds the four single-precision, floating-point values of a and b. +// +// r0 := a0 + b0 +// r1 := a1 + b1 +// r2 := a2 + b2 +// r3 := a3 + b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/c9848chc(v=vs.100).aspx +FORCE_INLINE __m128 _mm_add_ps(__m128 a, __m128 b) { - return vreinterpretq_m128_f32(vdupq_n_f32(_w)); + return vreinterpretq_m128_f32( + vaddq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); } -// Sets the four single-precision, floating-point values to w. -// https://msdn.microsoft.com/en-us/library/vstudio/2x1se8ha(v=vs.100).aspx -FORCE_INLINE __m128 _mm_set_ps1(float _w) +// adds the scalar single-precision floating point values of a and b. +// https://msdn.microsoft.com/en-us/library/be94x2y6(v=vs.100).aspx +FORCE_INLINE __m128 _mm_add_ss(__m128 a, __m128 b) { - return vreinterpretq_m128_f32(vdupq_n_f32(_w)); + float32_t b0 = vgetq_lane_f32(vreinterpretq_f32_m128(b), 0); + float32x4_t value = vsetq_lane_f32(b0, vdupq_n_f32(0), 0); + // the upper values in the result must be the remnants of <a>. + return vreinterpretq_m128_f32(vaddq_f32(a, value)); } -// Sets the four single-precision, floating-point values to the four inputs. -// https://msdn.microsoft.com/en-us/library/vstudio/afh0zf75(v=vs.100).aspx -FORCE_INLINE __m128 _mm_set_ps(float w, float z, float y, float x) +// Computes the bitwise AND of the four single-precision, floating-point values +// of a and b. +// +// r0 := a0 & b0 +// r1 := a1 & b1 +// r2 := a2 & b2 +// r3 := a3 & b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/73ck1xc5(v=vs.100).aspx +FORCE_INLINE __m128 _mm_and_ps(__m128 a, __m128 b) { - float ALIGN_STRUCT(16) data[4] = {x, y, z, w}; - return vreinterpretq_m128_f32(vld1q_f32(data)); + return vreinterpretq_m128_s32( + vandq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); } -// Copy single-precision (32-bit) floating-point element a to the lower element -// of dst, and zero the upper 3 elements. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_ss -FORCE_INLINE __m128 _mm_set_ss(float a) +// Computes the bitwise AND-NOT of the four single-precision, floating-point +// values of a and b. +// +// r0 := ~a0 & b0 +// r1 := ~a1 & b1 +// r2 := ~a2 & b2 +// r3 := ~a3 & b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/68h7wd02(v=vs.100).aspx +FORCE_INLINE __m128 _mm_andnot_ps(__m128 a, __m128 b) { - float ALIGN_STRUCT(16) data[4] = {a, 0, 0, 0}; - return vreinterpretq_m128_f32(vld1q_f32(data)); + return vreinterpretq_m128_s32( + vbicq_s32(vreinterpretq_s32_m128(b), + vreinterpretq_s32_m128(a))); // *NOTE* argument swap } -// Sets the four single-precision, floating-point values to the four inputs in -// reverse order. -// https://msdn.microsoft.com/en-us/library/vstudio/d2172ct3(v=vs.100).aspx -FORCE_INLINE __m128 _mm_setr_ps(float w, float z, float y, float x) +// Average packed unsigned 16-bit integers in a and b, and store the results in +// dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := (a[i+15:i] + b[i+15:i] + 1) >> 1 +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_avg_pu16 +FORCE_INLINE __m64 _mm_avg_pu16(__m64 a, __m64 b) { - float ALIGN_STRUCT(16) data[4] = {w, z, y, x}; - return vreinterpretq_m128_f32(vld1q_f32(data)); + return vreinterpret_m64_u16( + vrhadd_u16(vreinterpret_u16_m64(a), vreinterpret_u16_m64(b))); } -// Sets the 8 signed 16-bit integer values in reverse order. +// Average packed unsigned 8-bit integers in a and b, and store the results in +// dst. // -// Return Value -// r0 := w0 -// r1 := w1 -// ... -// r7 := w7 -FORCE_INLINE __m128i _mm_setr_epi16(short w0, - short w1, - short w2, - short w3, - short w4, - short w5, - short w6, - short w7) +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := (a[i+7:i] + b[i+7:i] + 1) >> 1 +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_avg_pu8 +FORCE_INLINE __m64 _mm_avg_pu8(__m64 a, __m64 b) { - int16_t ALIGN_STRUCT(16) data[8] = {w0, w1, w2, w3, w4, w5, w6, w7}; - return vreinterpretq_m128i_s16(vld1q_s16((int16_t *) data)); + return vreinterpret_m64_u8( + vrhadd_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); } -// Sets the 4 signed 32-bit integer values in reverse order -// https://technet.microsoft.com/en-us/library/security/27yb3ee5(v=vs.90).aspx -FORCE_INLINE __m128i _mm_setr_epi32(int i3, int i2, int i1, int i0) +// Compares for equality. +// https://msdn.microsoft.com/en-us/library/vstudio/36aectz5(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpeq_ps(__m128 a, __m128 b) { - int32_t ALIGN_STRUCT(16) data[4] = {i3, i2, i1, i0}; - return vreinterpretq_m128i_s32(vld1q_s32(data)); + return vreinterpretq_m128_u32( + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); } -// Set packed 64-bit integers in dst with the supplied values in reverse order. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setr_epi64 -FORCE_INLINE __m128i _mm_setr_epi64(__m64 e1, __m64 e0) +// Compares for equality. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/k423z28e(v=vs.100) +FORCE_INLINE __m128 _mm_cmpeq_ss(__m128 a, __m128 b) { - return vreinterpretq_m128i_s64(vcombine_s64(e1, e0)); + return _mm_move_ss(a, _mm_cmpeq_ps(a, b)); } -// Sets the 16 signed 8-bit integer values to b. +// Compares for greater than or equal. +// https://msdn.microsoft.com/en-us/library/vstudio/fs813y2t(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpge_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vcgeq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for greater than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/kesh3ddc(v=vs.100) +FORCE_INLINE __m128 _mm_cmpge_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpge_ps(a, b)); +} + +// Compares for greater than. // -// r0 := b -// r1 := b -// ... -// r15 := b +// r0 := (a0 > b0) ? 0xffffffff : 0x0 +// r1 := (a1 > b1) ? 0xffffffff : 0x0 +// r2 := (a2 > b2) ? 0xffffffff : 0x0 +// r3 := (a3 > b3) ? 0xffffffff : 0x0 // -// https://msdn.microsoft.com/en-us/library/6e14xhyf(v=vs.100).aspx -FORCE_INLINE __m128i _mm_set1_epi8(signed char w) +// https://msdn.microsoft.com/en-us/library/vstudio/11dy102s(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpgt_ps(__m128 a, __m128 b) { - return vreinterpretq_m128i_s8(vdupq_n_s8(w)); + return vreinterpretq_m128_u32( + vcgtq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); } -// Broadcast double-precision (64-bit) floating-point value a to all elements of -// dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set1_pd -FORCE_INLINE __m128d _mm_set1_pd(double d) +// Compares for greater than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/1xyyyy9e(v=vs.100) +FORCE_INLINE __m128 _mm_cmpgt_ss(__m128 a, __m128 b) { -#if defined(__aarch64__) - return vreinterpretq_m128d_f64(vdupq_n_f64(d)); -#else - return vreinterpretq_m128d_s64(vdupq_n_s64(*(int64_t *) &d)); -#endif + return _mm_move_ss(a, _mm_cmpgt_ps(a, b)); } -// Sets the 8 signed 16-bit integer values to w. +// Compares for less than or equal. // -// r0 := w -// r1 := w -// ... -// r7 := w +// r0 := (a0 <= b0) ? 0xffffffff : 0x0 +// r1 := (a1 <= b1) ? 0xffffffff : 0x0 +// r2 := (a2 <= b2) ? 0xffffffff : 0x0 +// r3 := (a3 <= b3) ? 0xffffffff : 0x0 // -// https://msdn.microsoft.com/en-us/library/k0ya3x0e(v=vs.90).aspx -FORCE_INLINE __m128i _mm_set1_epi16(short w) +// https://msdn.microsoft.com/en-us/library/vstudio/1s75w83z(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmple_ps(__m128 a, __m128 b) { - return vreinterpretq_m128i_s16(vdupq_n_s16(w)); + return vreinterpretq_m128_u32( + vcleq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); } -// Sets the 16 signed 8-bit integer values. -// https://msdn.microsoft.com/en-us/library/x0cx8zd3(v=vs.90).aspx -FORCE_INLINE __m128i _mm_set_epi8(signed char b15, - signed char b14, - signed char b13, - signed char b12, - signed char b11, - signed char b10, - signed char b9, - signed char b8, - signed char b7, - signed char b6, - signed char b5, - signed char b4, - signed char b3, - signed char b2, - signed char b1, - signed char b0) +// Compares for less than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/a7x0hbhw(v=vs.100) +FORCE_INLINE __m128 _mm_cmple_ss(__m128 a, __m128 b) { - int8_t ALIGN_STRUCT(16) - data[16] = {(int8_t) b0, (int8_t) b1, (int8_t) b2, (int8_t) b3, - (int8_t) b4, (int8_t) b5, (int8_t) b6, (int8_t) b7, - (int8_t) b8, (int8_t) b9, (int8_t) b10, (int8_t) b11, - (int8_t) b12, (int8_t) b13, (int8_t) b14, (int8_t) b15}; - return (__m128i) vld1q_s8(data); + return _mm_move_ss(a, _mm_cmple_ps(a, b)); } -// Sets the 8 signed 16-bit integer values. -// https://msdn.microsoft.com/en-au/library/3e0fek84(v=vs.90).aspx -FORCE_INLINE __m128i _mm_set_epi16(short i7, - short i6, - short i5, - short i4, - short i3, - short i2, - short i1, - short i0) +// Compares for less than +// https://msdn.microsoft.com/en-us/library/vstudio/f330yhc8(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmplt_ps(__m128 a, __m128 b) { - int16_t ALIGN_STRUCT(16) data[8] = {i0, i1, i2, i3, i4, i5, i6, i7}; - return vreinterpretq_m128i_s16(vld1q_s16(data)); + return vreinterpretq_m128_u32( + vcltq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); } -// Sets the 16 signed 8-bit integer values in reverse order. -// https://msdn.microsoft.com/en-us/library/2khb9c7k(v=vs.90).aspx -FORCE_INLINE __m128i _mm_setr_epi8(signed char b0, - signed char b1, - signed char b2, - signed char b3, - signed char b4, - signed char b5, - signed char b6, - signed char b7, - signed char b8, - signed char b9, - signed char b10, - signed char b11, - signed char b12, - signed char b13, - signed char b14, - signed char b15) +// Compares for less than +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/fy94wye7(v=vs.100) +FORCE_INLINE __m128 _mm_cmplt_ss(__m128 a, __m128 b) { - int8_t ALIGN_STRUCT(16) - data[16] = {(int8_t) b0, (int8_t) b1, (int8_t) b2, (int8_t) b3, - (int8_t) b4, (int8_t) b5, (int8_t) b6, (int8_t) b7, - (int8_t) b8, (int8_t) b9, (int8_t) b10, (int8_t) b11, - (int8_t) b12, (int8_t) b13, (int8_t) b14, (int8_t) b15}; - return (__m128i) vld1q_s8(data); + return _mm_move_ss(a, _mm_cmplt_ps(a, b)); } -// Sets the 4 signed 32-bit integer values to i. -// -// r0 := i -// r1 := i -// r2 := i -// r3 := I -// -// https://msdn.microsoft.com/en-us/library/vstudio/h4xscxat(v=vs.100).aspx -FORCE_INLINE __m128i _mm_set1_epi32(int _i) +// Compares for inequality. +// https://msdn.microsoft.com/en-us/library/sf44thbx(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpneq_ps(__m128 a, __m128 b) { - return vreinterpretq_m128i_s32(vdupq_n_s32(_i)); + return vreinterpretq_m128_u32(vmvnq_u32( + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)))); } -// Sets the 2 signed 64-bit integer values to i. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/whtfzhzk(v=vs.100) -FORCE_INLINE __m128i _mm_set1_epi64(__m64 _i) +// Compares for inequality. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/ekya8fh4(v=vs.100) +FORCE_INLINE __m128 _mm_cmpneq_ss(__m128 a, __m128 b) { - return vreinterpretq_m128i_s64(vdupq_n_s64((int64_t) _i)); + return _mm_move_ss(a, _mm_cmpneq_ps(a, b)); } -// Sets the 2 signed 64-bit integer values to i. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set1_epi64x -FORCE_INLINE __m128i _mm_set1_epi64x(int64_t _i) +// Compares for not greater than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/wsexys62(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnge_ps(__m128 a, __m128 b) { - return vreinterpretq_m128i_s64(vdupq_n_s64(_i)); + return vreinterpretq_m128_u32(vmvnq_u32( + vcgeq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)))); } -// Sets the 4 signed 32-bit integer values. -// https://msdn.microsoft.com/en-us/library/vstudio/019beekt(v=vs.100).aspx -FORCE_INLINE __m128i _mm_set_epi32(int i3, int i2, int i1, int i0) +// Compares for not greater than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/fk2y80s8(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnge_ss(__m128 a, __m128 b) { - int32_t ALIGN_STRUCT(16) data[4] = {i0, i1, i2, i3}; - return vreinterpretq_m128i_s32(vld1q_s32(data)); + return _mm_move_ss(a, _mm_cmpnge_ps(a, b)); } -// Returns the __m128i structure with its two 64-bit integer values -// initialized to the values of the two 64-bit integers passed in. -// https://msdn.microsoft.com/en-us/library/dk2sdw0h(v=vs.120).aspx -FORCE_INLINE __m128i _mm_set_epi64x(int64_t i1, int64_t i2) +// Compares for not greater than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/d0xh7w0s(v=vs.100) +FORCE_INLINE __m128 _mm_cmpngt_ps(__m128 a, __m128 b) { - return vreinterpretq_m128i_s64( - vcombine_s64(vcreate_s64(i2), vcreate_s64(i1))); + return vreinterpretq_m128_u32(vmvnq_u32( + vcgtq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)))); } -// Returns the __m128i structure with its two 64-bit integer values -// initialized to the values of the two 64-bit integers passed in. -// https://msdn.microsoft.com/en-us/library/dk2sdw0h(v=vs.120).aspx -FORCE_INLINE __m128i _mm_set_epi64(__m64 i1, __m64 i2) +// Compares for not greater than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/z7x9ydwh(v=vs.100) +FORCE_INLINE __m128 _mm_cmpngt_ss(__m128 a, __m128 b) { - return _mm_set_epi64x((int64_t) i1, (int64_t) i2); + return _mm_move_ss(a, _mm_cmpngt_ps(a, b)); } -// Set packed double-precision (64-bit) floating-point elements in dst with the -// supplied values. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_pd -FORCE_INLINE __m128d _mm_set_pd(double e1, double e0) +// Compares for not less than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/6a330kxw(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnle_ps(__m128 a, __m128 b) { - double ALIGN_STRUCT(16) data[2] = {e0, e1}; -#if defined(__aarch64__) - return vreinterpretq_m128d_f64(vld1q_f64((float64_t *) data)); -#else - return vreinterpretq_m128d_f32(vld1q_f32((float32_t *) data)); -#endif + return vreinterpretq_m128_u32(vmvnq_u32( + vcleq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)))); } -// Set packed double-precision (64-bit) floating-point elements in dst with the -// supplied values in reverse order. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setr_pd -FORCE_INLINE __m128d _mm_setr_pd(double e1, double e0) +// Compares for not less than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/z7x9ydwh(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnle_ss(__m128 a, __m128 b) { - return _mm_set_pd(e0, e1); + return _mm_move_ss(a, _mm_cmpnle_ps(a, b)); } -// Copy double-precision (64-bit) floating-point element a to the lower element -// of dst, and zero the upper element. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_sd -FORCE_INLINE __m128d _mm_set_sd(double a) +// Compares for not less than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/4686bbdw(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnlt_ps(__m128 a, __m128 b) { - return _mm_set_pd(0, a); + return vreinterpretq_m128_u32(vmvnq_u32( + vcltq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)))); } -// Broadcast double-precision (64-bit) floating-point value a to all elements of -// dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_pd1 -#define _mm_set_pd1 _mm_set1_pd +// Compares for not less than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/56b9z2wf(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnlt_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpnlt_ps(a, b)); +} -// Stores four single-precision, floating-point values. -// https://msdn.microsoft.com/en-us/library/vstudio/s3h4ay6y(v=vs.100).aspx -FORCE_INLINE void _mm_store_ps(float *p, __m128 a) +// Compares the four 32-bit floats in a and b to check if any values are NaN. +// Ordered compare between each value returns true for "orderable" and false for +// "not orderable" (NaN). +// https://msdn.microsoft.com/en-us/library/vstudio/0h9w00fx(v=vs.100).aspx see +// also: +// http://stackoverflow.com/questions/8627331/what-does-ordered-unordered-comparison-mean +// http://stackoverflow.com/questions/29349621/neon-isnanval-intrinsics +FORCE_INLINE __m128 _mm_cmpord_ps(__m128 a, __m128 b) { - vst1q_f32(p, vreinterpretq_f32_m128(a)); + // Note: NEON does not have ordered compare builtin + // Need to compare a eq a and b eq b to check for NaN + // Do AND of results to get final + uint32x4_t ceqaa = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t ceqbb = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_u32(vandq_u32(ceqaa, ceqbb)); } -// Store the lower single-precision (32-bit) floating-point element from a into -// 4 contiguous elements in memory. mem_addr must be aligned on a 16-byte -// boundary or a general-protection exception may be generated. -// -// MEM[mem_addr+31:mem_addr] := a[31:0] -// MEM[mem_addr+63:mem_addr+32] := a[31:0] -// MEM[mem_addr+95:mem_addr+64] := a[31:0] -// MEM[mem_addr+127:mem_addr+96] := a[31:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store_ps1 -FORCE_INLINE void _mm_store_ps1(float *p, __m128 a) +// Compares for ordered. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/343t62da(v=vs.100) +FORCE_INLINE __m128 _mm_cmpord_ss(__m128 a, __m128 b) { - float32_t a0 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); - vst1q_f32(p, vdupq_n_f32(a0)); + return _mm_move_ss(a, _mm_cmpord_ps(a, b)); } -// Store the lower single-precision (32-bit) floating-point element from a into -// 4 contiguous elements in memory. mem_addr must be aligned on a 16-byte -// boundary or a general-protection exception may be generated. -// -// MEM[mem_addr+31:mem_addr] := a[31:0] -// MEM[mem_addr+63:mem_addr+32] := a[31:0] -// MEM[mem_addr+95:mem_addr+64] := a[31:0] -// MEM[mem_addr+127:mem_addr+96] := a[31:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store1_ps -#define _mm_store1_ps _mm_store_ps1 +// Compares for unordered. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/khy6fk1t(v=vs.100) +FORCE_INLINE __m128 _mm_cmpunord_ps(__m128 a, __m128 b) +{ + uint32x4_t f32a = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t f32b = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_u32(vmvnq_u32(vandq_u32(f32a, f32b))); +} -// Store 4 single-precision (32-bit) floating-point elements from a into memory -// in reverse order. mem_addr must be aligned on a 16-byte boundary or a -// general-protection exception may be generated. -// -// MEM[mem_addr+31:mem_addr] := a[127:96] -// MEM[mem_addr+63:mem_addr+32] := a[95:64] -// MEM[mem_addr+95:mem_addr+64] := a[63:32] -// MEM[mem_addr+127:mem_addr+96] := a[31:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storer_ps -FORCE_INLINE void _mm_storer_ps(float *p, __m128 a) +// Compares for unordered. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/2as2387b(v=vs.100) +FORCE_INLINE __m128 _mm_cmpunord_ss(__m128 a, __m128 b) { - float32x4_t tmp = vrev64q_f32(vreinterpretq_f32_m128(a)); - float32x4_t rev = vextq_f32(tmp, tmp, 2); - vst1q_f32(p, rev); + return _mm_move_ss(a, _mm_cmpunord_ps(a, b)); } -// Stores four single-precision, floating-point values. -// https://msdn.microsoft.com/en-us/library/44e30x22(v=vs.100).aspx -FORCE_INLINE void _mm_storeu_ps(float *p, __m128 a) +// Compares the lower single-precision floating point scalar values of a and b +// using an equality operation. : +// https://msdn.microsoft.com/en-us/library/93yx2h2b(v=vs.100).aspx +FORCE_INLINE int _mm_comieq_ss(__m128 a, __m128 b) { - vst1q_f32(p, vreinterpretq_f32_m128(a)); + uint32x4_t a_eq_b = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return vgetq_lane_u32(a_eq_b, 0) & 0x1; } -// Stores four 32-bit integer values as (as a __m128i value) at the address p. -// https://msdn.microsoft.com/en-us/library/vstudio/edk11s13(v=vs.100).aspx -FORCE_INLINE void _mm_store_si128(__m128i *p, __m128i a) +// Compares the lower single-precision floating point scalar values of a and b +// using a greater than or equal operation. : +// https://msdn.microsoft.com/en-us/library/8t80des6(v=vs.100).aspx +FORCE_INLINE int _mm_comige_ss(__m128 a, __m128 b) { - vst1q_s32((int32_t *) p, vreinterpretq_s32_m128i(a)); + uint32x4_t a_ge_b = + vcgeq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return vgetq_lane_u32(a_ge_b, 0) & 0x1; } -// Stores four 32-bit integer values as (as a __m128i value) at the address p. -// https://msdn.microsoft.com/en-us/library/vstudio/edk11s13(v=vs.100).aspx -FORCE_INLINE void _mm_storeu_si128(__m128i *p, __m128i a) +// Compares the lower single-precision floating point scalar values of a and b +// using a greater than operation. : +// https://msdn.microsoft.com/en-us/library/b0738e0t(v=vs.100).aspx +FORCE_INLINE int _mm_comigt_ss(__m128 a, __m128 b) { - vst1q_s32((int32_t *) p, vreinterpretq_s32_m128i(a)); + uint32x4_t a_gt_b = + vcgtq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return vgetq_lane_u32(a_gt_b, 0) & 0x1; } -// Stores the lower single - precision, floating - point value. -// https://msdn.microsoft.com/en-us/library/tzz10fbx(v=vs.100).aspx -FORCE_INLINE void _mm_store_ss(float *p, __m128 a) +// Compares the lower single-precision floating point scalar values of a and b +// using a less than or equal operation. : +// https://msdn.microsoft.com/en-us/library/1w4t7c57(v=vs.90).aspx +FORCE_INLINE int _mm_comile_ss(__m128 a, __m128 b) { - vst1q_lane_f32(p, vreinterpretq_f32_m128(a), 0); + uint32x4_t a_le_b = + vcleq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return vgetq_lane_u32(a_le_b, 0) & 0x1; } -// Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point -// elements) from a into memory. mem_addr must be aligned on a 16-byte boundary -// or a general-protection exception may be generated. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store_pd -FORCE_INLINE void _mm_store_pd(double *mem_addr, __m128d a) +// Compares the lower single-precision floating point scalar values of a and b +// using a less than operation. : +// https://msdn.microsoft.com/en-us/library/2kwe606b(v=vs.90).aspx Important +// note!! The documentation on MSDN is incorrect! If either of the values is a +// NAN the docs say you will get a one, but in fact, it will return a zero!! +FORCE_INLINE int _mm_comilt_ss(__m128 a, __m128 b) { -#if defined(__aarch64__) - vst1q_f64((float64_t *) mem_addr, vreinterpretq_f64_m128d(a)); -#else - vst1q_f32((float32_t *) mem_addr, vreinterpretq_f32_m128d(a)); -#endif + uint32x4_t a_lt_b = + vcltq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return vgetq_lane_u32(a_lt_b, 0) & 0x1; } -// Store the upper double-precision (64-bit) floating-point element from a into -// memory. +// Compares the lower single-precision floating point scalar values of a and b +// using an inequality operation. : +// https://msdn.microsoft.com/en-us/library/bafh5e0a(v=vs.90).aspx +FORCE_INLINE int _mm_comineq_ss(__m128 a, __m128 b) +{ + return !_mm_comieq_ss(a, b); +} + +// Convert packed signed 32-bit integers in b to packed single-precision +// (32-bit) floating-point elements, store the results in the lower 2 elements +// of dst, and copy the upper 2 packed elements from a to the upper elements of +// dst. // -// MEM[mem_addr+63:mem_addr] := a[127:64] +// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) +// dst[63:32] := Convert_Int32_To_FP32(b[63:32]) +// dst[95:64] := a[95:64] +// dst[127:96] := a[127:96] // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeh_pd -FORCE_INLINE void _mm_storeh_pd(double *mem_addr, __m128d a) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_pi2ps +FORCE_INLINE __m128 _mm_cvt_pi2ps(__m128 a, __m64 b) { -#if defined(__aarch64__) - vst1_f64((float64_t *) mem_addr, vget_high_f64(vreinterpretq_f64_m128d(a))); -#else - vst1_f32((float32_t *) mem_addr, vget_high_f32(vreinterpretq_f32_m128d(a))); -#endif + return vreinterpretq_m128_f32( + vcombine_f32(vcvt_f32_s32(vreinterpret_s32_m64(b)), + vget_high_f32(vreinterpretq_f32_m128(a)))); } -// Store the lower double-precision (64-bit) floating-point element from a into -// memory. +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 32-bit integers, and store the results in dst. // -// MEM[mem_addr+63:mem_addr] := a[63:0] +// FOR j := 0 to 1 +// i := 32*j +// dst[i+31:i] := Convert_FP32_To_Int32(a[i+31:i]) +// ENDFOR // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storel_pd -FORCE_INLINE void _mm_storel_pd(double *mem_addr, __m128d a) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_ps2pi +FORCE_INLINE __m64 _mm_cvt_ps2pi(__m128 a) { #if defined(__aarch64__) - vst1_f64((float64_t *) mem_addr, vget_low_f64(vreinterpretq_f64_m128d(a))); + return vreinterpret_m64_s32( + vget_low_s32(vcvtnq_s32_f32(vrndiq_f32(vreinterpretq_f32_m128(a))))); #else - vst1_f32((float32_t *) mem_addr, vget_low_f32(vreinterpretq_f32_m128d(a))); + return vreinterpret_m64_s32(vcvt_s32_f32(vget_low_f32( + vreinterpretq_f32_m128(_mm_round_ps(a, _MM_FROUND_CUR_DIRECTION))))); #endif } -// Store 2 double-precision (64-bit) floating-point elements from a into memory -// in reverse order. mem_addr must be aligned on a 16-byte boundary or a -// general-protection exception may be generated. +// Convert the signed 32-bit integer b to a single-precision (32-bit) +// floating-point element, store the result in the lower element of dst, and +// copy the upper 3 packed elements from a to the upper elements of dst. // -// MEM[mem_addr+63:mem_addr] := a[127:64] -// MEM[mem_addr+127:mem_addr+64] := a[63:0] +// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) +// dst[127:32] := a[127:32] // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storer_pd -FORCE_INLINE void _mm_storer_pd(double *mem_addr, __m128d a) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_si2ss +FORCE_INLINE __m128 _mm_cvt_si2ss(__m128 a, int b) { - float32x4_t f = vreinterpretq_f32_m128d(a); - _mm_store_pd(mem_addr, vreinterpretq_m128d_f32(vextq_f32(f, f, 2))); + return vreinterpretq_m128_f32( + vsetq_lane_f32((float) b, vreinterpretq_f32_m128(a), 0)); } -// Store the lower double-precision (64-bit) floating-point element from a into -// 2 contiguous elements in memory. mem_addr must be aligned on a 16-byte -// boundary or a general-protection exception may be generated. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store_pd1 -FORCE_INLINE void _mm_store_pd1(double *mem_addr, __m128d a) +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 32-bit integer, and store the result in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_ss2si +FORCE_INLINE int _mm_cvt_ss2si(__m128 a) { #if defined(__aarch64__) - float64x1_t a_low = vget_low_f64(vreinterpretq_f64_m128d(a)); - vst1q_f64((float64_t *) mem_addr, - vreinterpretq_f64_m128d(vcombine_f64(a_low, a_low))); + return vgetq_lane_s32(vcvtnq_s32_f32(vrndiq_f32(vreinterpretq_f32_m128(a))), + 0); #else - float32x2_t a_low = vget_low_f32(vreinterpretq_f32_m128d(a)); - vst1q_f32((float32_t *) mem_addr, - vreinterpretq_f32_m128d(vcombine_f32(a_low, a_low))); + float32_t data = vgetq_lane_f32( + vreinterpretq_f32_m128(_mm_round_ps(a, _MM_FROUND_CUR_DIRECTION)), 0); + return (int32_t) data; #endif } -// Store the lower double-precision (64-bit) floating-point element from a into -// 2 contiguous elements in memory. mem_addr must be aligned on a 16-byte -// boundary or a general-protection exception may be generated. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=9,526,5601&text=_mm_store1_pd -#define _mm_store1_pd _mm_store_pd1 - -// Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point -// elements) from a into memory. mem_addr does not need to be aligned on any -// particular boundary. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_pd -FORCE_INLINE void _mm_storeu_pd(double *mem_addr, __m128d a) +// Convert packed 16-bit integers in a to packed single-precision (32-bit) +// floating-point elements, and store the results in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// m := j*32 +// dst[m+31:m] := Convert_Int16_To_FP32(a[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi16_ps +FORCE_INLINE __m128 _mm_cvtpi16_ps(__m64 a) { - _mm_store_pd(mem_addr, a); + return vreinterpretq_m128_f32( + vcvtq_f32_s32(vmovl_s16(vreinterpret_s16_m64(a)))); } -// Reads the lower 64 bits of b and stores them into the lower 64 bits of a. -// https://msdn.microsoft.com/en-us/library/hhwf428f%28v=vs.90%29.aspx -FORCE_INLINE void _mm_storel_epi64(__m128i *a, __m128i b) +// Convert packed 32-bit integers in b to packed single-precision (32-bit) +// floating-point elements, store the results in the lower 2 elements of dst, +// and copy the upper 2 packed elements from a to the upper elements of dst. +// +// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) +// dst[63:32] := Convert_Int32_To_FP32(b[63:32]) +// dst[95:64] := a[95:64] +// dst[127:96] := a[127:96] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi32_ps +FORCE_INLINE __m128 _mm_cvtpi32_ps(__m128 a, __m64 b) { - uint64x1_t hi = vget_high_u64(vreinterpretq_u64_m128i(*a)); - uint64x1_t lo = vget_low_u64(vreinterpretq_u64_m128i(b)); - *a = vreinterpretq_m128i_u64(vcombine_u64(lo, hi)); + return vreinterpretq_m128_f32( + vcombine_f32(vcvt_f32_s32(vreinterpret_s32_m64(b)), + vget_high_f32(vreinterpretq_f32_m128(a)))); } -// Stores the lower two single-precision floating point values of a to the -// address p. +// Convert packed signed 32-bit integers in a to packed single-precision +// (32-bit) floating-point elements, store the results in the lower 2 elements +// of dst, then covert the packed signed 32-bit integers in b to +// single-precision (32-bit) floating-point element, and store the results in +// the upper 2 elements of dst. // -// *p0 := a0 -// *p1 := a1 +// dst[31:0] := Convert_Int32_To_FP32(a[31:0]) +// dst[63:32] := Convert_Int32_To_FP32(a[63:32]) +// dst[95:64] := Convert_Int32_To_FP32(b[31:0]) +// dst[127:96] := Convert_Int32_To_FP32(b[63:32]) // -// https://msdn.microsoft.com/en-us/library/h54t98ks(v=vs.90).aspx -FORCE_INLINE void _mm_storel_pi(__m64 *p, __m128 a) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi32x2_ps +FORCE_INLINE __m128 _mm_cvtpi32x2_ps(__m64 a, __m64 b) { - *p = vreinterpret_m64_f32(vget_low_f32(a)); + return vreinterpretq_m128_f32(vcvtq_f32_s32( + vcombine_s32(vreinterpret_s32_m64(a), vreinterpret_s32_m64(b)))); } -// Stores the upper two single-precision, floating-point values of a to the -// address p. +// Convert the lower packed 8-bit integers in a to packed single-precision +// (32-bit) floating-point elements, and store the results in dst. // -// *p0 := a2 -// *p1 := a3 +// FOR j := 0 to 3 +// i := j*8 +// m := j*32 +// dst[m+31:m] := Convert_Int8_To_FP32(a[i+7:i]) +// ENDFOR // -// https://msdn.microsoft.com/en-us/library/a7525fs8(v%3dvs.90).aspx -FORCE_INLINE void _mm_storeh_pi(__m64 *p, __m128 a) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi8_ps +FORCE_INLINE __m128 _mm_cvtpi8_ps(__m64 a) { - *p = vreinterpret_m64_f32(vget_high_f32(a)); + return vreinterpretq_m128_f32(vcvtq_f32_s32( + vmovl_s16(vget_low_s16(vmovl_s8(vreinterpret_s8_m64(a)))))); } -// Loads a single single-precision, floating-point value, copying it into all -// four words -// https://msdn.microsoft.com/en-us/library/vstudio/5cdkf716(v=vs.100).aspx -FORCE_INLINE __m128 _mm_load1_ps(const float *p) +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 16-bit integers, and store the results in dst. Note: this intrinsic +// will generate 0x7FFF, rather than 0x8000, for input values between 0x7FFF and +// 0x7FFFFFFF. +// +// FOR j := 0 to 3 +// i := 16*j +// k := 32*j +// IF a[k+31:k] >= FP32(0x7FFF) && a[k+31:k] <= FP32(0x7FFFFFFF) +// dst[i+15:i] := 0x7FFF +// ELSE +// dst[i+15:i] := Convert_FP32_To_Int16(a[k+31:k]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pi16 +FORCE_INLINE __m64 _mm_cvtps_pi16(__m128 a) { - return vreinterpretq_m128_f32(vld1q_dup_f32(p)); + const __m128 i16Min = _mm_set_ps1((float) INT16_MIN); + const __m128 i16Max = _mm_set_ps1((float) INT16_MAX); + const __m128 i32Max = _mm_set_ps1((float) INT32_MAX); + const __m128i maxMask = _mm_castps_si128( + _mm_and_ps(_mm_cmpge_ps(a, i16Max), _mm_cmple_ps(a, i32Max))); + const __m128i betweenMask = _mm_castps_si128( + _mm_and_ps(_mm_cmpgt_ps(a, i16Min), _mm_cmplt_ps(a, i16Max))); + const __m128i minMask = _mm_cmpeq_epi32(_mm_or_si128(maxMask, betweenMask), + _mm_setzero_si128()); + __m128i max = _mm_and_si128(maxMask, _mm_set1_epi32(INT16_MAX)); + __m128i min = _mm_and_si128(minMask, _mm_set1_epi32(INT16_MIN)); + __m128i cvt = _mm_and_si128(betweenMask, _mm_cvtps_epi32(a)); + __m128i res32 = _mm_or_si128(_mm_or_si128(max, min), cvt); + return vreinterpret_m64_s16(vmovn_s32(vreinterpretq_s32_m128i(res32))); } -// Load a single-precision (32-bit) floating-point element from memory into all -// elements of dst. +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 32-bit integers, and store the results in dst. // -// dst[31:0] := MEM[mem_addr+31:mem_addr] -// dst[63:32] := MEM[mem_addr+31:mem_addr] -// dst[95:64] := MEM[mem_addr+31:mem_addr] -// dst[127:96] := MEM[mem_addr+31:mem_addr] +// FOR j := 0 to 1 +// i := 32*j +// dst[i+31:i] := Convert_FP32_To_Int32(a[i+31:i]) +// ENDFOR // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_ps1 -#define _mm_load_ps1 _mm_load1_ps +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pi32 +#define _mm_cvtps_pi32(a) _mm_cvt_ps2pi(a) -// Sets the lower two single-precision, floating-point values with 64 -// bits of data loaded from the address p; the upper two values are passed -// through from a. +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 8-bit integers, and store the results in lower 4 elements of dst. +// Note: this intrinsic will generate 0x7F, rather than 0x80, for input values +// between 0x7F and 0x7FFFFFFF. // -// Return Value -// r0 := *p0 -// r1 := *p1 -// r2 := a2 -// r3 := a3 +// FOR j := 0 to 3 +// i := 8*j +// k := 32*j +// IF a[k+31:k] >= FP32(0x7F) && a[k+31:k] <= FP32(0x7FFFFFFF) +// dst[i+7:i] := 0x7F +// ELSE +// dst[i+7:i] := Convert_FP32_To_Int8(a[k+31:k]) +// FI +// ENDFOR // -// https://msdn.microsoft.com/en-us/library/s57cyak2(v=vs.100).aspx -FORCE_INLINE __m128 _mm_loadl_pi(__m128 a, __m64 const *p) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pi8 +FORCE_INLINE __m64 _mm_cvtps_pi8(__m128 a) +{ + const __m128 i8Min = _mm_set_ps1((float) INT8_MIN); + const __m128 i8Max = _mm_set_ps1((float) INT8_MAX); + const __m128 i32Max = _mm_set_ps1((float) INT32_MAX); + const __m128i maxMask = _mm_castps_si128( + _mm_and_ps(_mm_cmpge_ps(a, i8Max), _mm_cmple_ps(a, i32Max))); + const __m128i betweenMask = _mm_castps_si128( + _mm_and_ps(_mm_cmpgt_ps(a, i8Min), _mm_cmplt_ps(a, i8Max))); + const __m128i minMask = _mm_cmpeq_epi32(_mm_or_si128(maxMask, betweenMask), + _mm_setzero_si128()); + __m128i max = _mm_and_si128(maxMask, _mm_set1_epi32(INT8_MAX)); + __m128i min = _mm_and_si128(minMask, _mm_set1_epi32(INT8_MIN)); + __m128i cvt = _mm_and_si128(betweenMask, _mm_cvtps_epi32(a)); + __m128i res32 = _mm_or_si128(_mm_or_si128(max, min), cvt); + int16x4_t res16 = vmovn_s32(vreinterpretq_s32_m128i(res32)); + int8x8_t res8 = vmovn_s16(vcombine_s16(res16, res16)); + uint32_t bitMask[2] = {0xFFFFFFFF, 0}; + int8x8_t mask = vreinterpret_s8_u32(vld1_u32(bitMask)); + + return vreinterpret_m64_s8(vorr_s8(vand_s8(mask, res8), vdup_n_s8(0))); +} + +// Convert packed unsigned 16-bit integers in a to packed single-precision +// (32-bit) floating-point elements, and store the results in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// m := j*32 +// dst[m+31:m] := Convert_UInt16_To_FP32(a[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpu16_ps +FORCE_INLINE __m128 _mm_cvtpu16_ps(__m64 a) { return vreinterpretq_m128_f32( - vcombine_f32(vld1_f32((const float32_t *) p), vget_high_f32(a))); + vcvtq_f32_u32(vmovl_u16(vreinterpret_u16_m64(a)))); } -// Load 4 single-precision (32-bit) floating-point elements from memory into dst -// in reverse order. mem_addr must be aligned on a 16-byte boundary or a -// general-protection exception may be generated. +// Convert the lower packed unsigned 8-bit integers in a to packed +// single-precision (32-bit) floating-point elements, and store the results in +// dst. // -// dst[31:0] := MEM[mem_addr+127:mem_addr+96] -// dst[63:32] := MEM[mem_addr+95:mem_addr+64] -// dst[95:64] := MEM[mem_addr+63:mem_addr+32] -// dst[127:96] := MEM[mem_addr+31:mem_addr] +// FOR j := 0 to 3 +// i := j*8 +// m := j*32 +// dst[m+31:m] := Convert_UInt8_To_FP32(a[i+7:i]) +// ENDFOR // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadr_ps -FORCE_INLINE __m128 _mm_loadr_ps(const float *p) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpu8_ps +FORCE_INLINE __m128 _mm_cvtpu8_ps(__m64 a) { - float32x4_t v = vrev64q_f32(vld1q_f32(p)); - return vreinterpretq_m128_f32(vextq_f32(v, v, 2)); + return vreinterpretq_m128_f32(vcvtq_f32_u32( + vmovl_u16(vget_low_u16(vmovl_u8(vreinterpret_u8_m64(a)))))); } -// Sets the upper two single-precision, floating-point values with 64 -// bits of data loaded from the address p; the lower two values are passed -// through from a. +// Convert the signed 32-bit integer b to a single-precision (32-bit) +// floating-point element, store the result in the lower element of dst, and +// copy the upper 3 packed elements from a to the upper elements of dst. // -// r0 := a0 -// r1 := a1 -// r2 := *p0 -// r3 := *p1 +// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) +// dst[127:32] := a[127:32] // -// https://msdn.microsoft.com/en-us/library/w92wta0x(v%3dvs.100).aspx -FORCE_INLINE __m128 _mm_loadh_pi(__m128 a, __m64 const *p) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi32_ss +#define _mm_cvtsi32_ss(a, b) _mm_cvt_si2ss(a, b) + +// Convert the signed 64-bit integer b to a single-precision (32-bit) +// floating-point element, store the result in the lower element of dst, and +// copy the upper 3 packed elements from a to the upper elements of dst. +// +// dst[31:0] := Convert_Int64_To_FP32(b[63:0]) +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi64_ss +FORCE_INLINE __m128 _mm_cvtsi64_ss(__m128 a, int64_t b) { return vreinterpretq_m128_f32( - vcombine_f32(vget_low_f32(a), vld1_f32((const float32_t *) p))); + vsetq_lane_f32((float) b, vreinterpretq_f32_m128(a), 0)); } -// Loads four single-precision, floating-point values. -// https://msdn.microsoft.com/en-us/library/vstudio/zzd50xxt(v=vs.100).aspx -FORCE_INLINE __m128 _mm_load_ps(const float *p) +// Copy the lower single-precision (32-bit) floating-point element of a to dst. +// +// dst[31:0] := a[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_f32 +FORCE_INLINE float _mm_cvtss_f32(__m128 a) { - return vreinterpretq_m128_f32(vld1q_f32(p)); + return vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); } -// Loads four single-precision, floating-point values. -// https://msdn.microsoft.com/en-us/library/x1b16s7z%28v=vs.90%29.aspx -FORCE_INLINE __m128 _mm_loadu_ps(const float *p) +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 32-bit integer, and store the result in dst. +// +// dst[31:0] := Convert_FP32_To_Int32(a[31:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_si32 +#define _mm_cvtss_si32(a) _mm_cvt_ss2si(a) + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 64-bit integer, and store the result in dst. +// +// dst[63:0] := Convert_FP32_To_Int64(a[31:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_si64 +FORCE_INLINE int64_t _mm_cvtss_si64(__m128 a) { - // for neon, alignment doesn't matter, so _mm_load_ps and _mm_loadu_ps are - // equivalent for neon - return vreinterpretq_m128_f32(vld1q_f32(p)); +#if defined(__aarch64__) + return (int64_t) vgetq_lane_f32(vrndiq_f32(vreinterpretq_f32_m128(a)), 0); +#else + float32_t data = vgetq_lane_f32( + vreinterpretq_f32_m128(_mm_round_ps(a, _MM_FROUND_CUR_DIRECTION)), 0); + return (int64_t) data; +#endif } -// Load unaligned 16-bit integer from memory into the first element of dst. +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 32-bit integers with truncation, and store the results in dst. // -// dst[15:0] := MEM[mem_addr+15:mem_addr] -// dst[MAX:16] := 0 +// FOR j := 0 to 1 +// i := 32*j +// dst[i+31:i] := Convert_FP32_To_Int32_Truncate(a[i+31:i]) +// ENDFOR // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si16 -FORCE_INLINE __m128i _mm_loadu_si16(const void *p) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtt_ps2pi +FORCE_INLINE __m64 _mm_cvtt_ps2pi(__m128 a) { - return vreinterpretq_m128i_s16( - vsetq_lane_s16(*(const int16_t *) p, vdupq_n_s16(0), 0)); + return vreinterpret_m64_s32( + vget_low_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a)))); } -// Load unaligned 64-bit integer from memory into the first element of dst. +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 32-bit integer with truncation, and store the result in dst. // -// dst[63:0] := MEM[mem_addr+63:mem_addr] -// dst[MAX:64] := 0 +// dst[31:0] := Convert_FP32_To_Int32_Truncate(a[31:0]) // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si64 -FORCE_INLINE __m128i _mm_loadu_si64(const void *p) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtt_ss2si +FORCE_INLINE int _mm_cvtt_ss2si(__m128 a) { - return vreinterpretq_m128i_s64( - vcombine_s64(vld1_s64((const int64_t *) p), vdup_n_s64(0))); + return vgetq_lane_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a)), 0); } -// Load a double-precision (64-bit) floating-point element from memory into the -// lower of dst, and zero the upper element. mem_addr does not need to be -// aligned on any particular boundary. +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 32-bit integers with truncation, and store the results in dst. // -// dst[63:0] := MEM[mem_addr+63:mem_addr] -// dst[127:64] := 0 +// FOR j := 0 to 1 +// i := 32*j +// dst[i+31:i] := Convert_FP32_To_Int32_Truncate(a[i+31:i]) +// ENDFOR // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_sd -FORCE_INLINE __m128d _mm_load_sd(const double *p) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttps_pi32 +#define _mm_cvttps_pi32(a) _mm_cvtt_ps2pi(a) + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 32-bit integer with truncation, and store the result in dst. +// +// dst[31:0] := Convert_FP32_To_Int32_Truncate(a[31:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttss_si32 +#define _mm_cvttss_si32(a) _mm_cvtt_ss2si(a) + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 64-bit integer with truncation, and store the result in dst. +// +// dst[63:0] := Convert_FP32_To_Int64_Truncate(a[31:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttss_si64 +FORCE_INLINE int64_t _mm_cvttss_si64(__m128 a) { -#if defined(__aarch64__) - return vreinterpretq_m128d_f64(vsetq_lane_f64(*p, vdupq_n_f64(0), 0)); -#else - const float *fp = (const float *) p; - float ALIGN_STRUCT(16) data[4] = {fp[0], fp[1], 0, 0}; - return vreinterpretq_m128d_f32(vld1q_f32(data)); -#endif + return (int64_t) vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); } -// Loads two double-precision from 16-byte aligned memory, floating-point -// values. +// Divides the four single-precision, floating-point values of a and b. // -// dst[127:0] := MEM[mem_addr+127:mem_addr] +// r0 := a0 / b0 +// r1 := a1 / b1 +// r2 := a2 / b2 +// r3 := a3 / b3 // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_pd -FORCE_INLINE __m128d _mm_load_pd(const double *p) +// https://msdn.microsoft.com/en-us/library/edaw8147(v=vs.100).aspx +FORCE_INLINE __m128 _mm_div_ps(__m128 a, __m128 b) { -#if defined(__aarch64__) - return vreinterpretq_m128d_f64(vld1q_f64(p)); +#if defined(__aarch64__) && !SSE2NEON_PRECISE_DIV + return vreinterpretq_m128_f32( + vdivq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); #else - const float *fp = (const float *) p; - float ALIGN_STRUCT(16) data[4] = {fp[0], fp[1], fp[2], fp[3]}; - return vreinterpretq_m128d_f32(vld1q_f32(data)); + float32x4_t recip = vrecpeq_f32(vreinterpretq_f32_m128(b)); + recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(b))); +#if SSE2NEON_PRECISE_DIV + // Additional Netwon-Raphson iteration for accuracy + recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(b))); +#endif + return vreinterpretq_m128_f32(vmulq_f32(vreinterpretq_f32_m128(a), recip)); #endif } -// Loads two double-precision from unaligned memory, floating-point values. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_pd -FORCE_INLINE __m128d _mm_loadu_pd(const double *p) +// Divides the scalar single-precision floating point value of a by b. +// https://msdn.microsoft.com/en-us/library/4y73xa49(v=vs.100).aspx +FORCE_INLINE __m128 _mm_div_ss(__m128 a, __m128 b) { - return _mm_load_pd(p); + float32_t value = + vgetq_lane_f32(vreinterpretq_f32_m128(_mm_div_ps(a, b)), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); } -// Loads an single - precision, floating - point value into the low word and -// clears the upper three words. -// https://msdn.microsoft.com/en-us/library/548bb9h4%28v=vs.90%29.aspx -FORCE_INLINE __m128 _mm_load_ss(const float *p) -{ - return vreinterpretq_m128_f32(vsetq_lane_f32(*p, vdupq_n_f32(0), 0)); -} +// Extract a 16-bit integer from a, selected with imm8, and store the result in +// the lower element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_extract_pi16 +#define _mm_extract_pi16(a, imm) \ + (int32_t) vget_lane_u16(vreinterpret_u16_m64(a), (imm)) -// Load 64-bit integer from memory into the first element of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadl_epi64 -FORCE_INLINE __m128i _mm_loadl_epi64(__m128i const *p) +// Free aligned memory that was allocated with _mm_malloc. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_free +FORCE_INLINE void _mm_free(void *addr) { - /* Load the lower 64 bits of the value pointed to by p into the - * lower 64 bits of the result, zeroing the upper 64 bits of the result. - */ - return vreinterpretq_m128i_s32( - vcombine_s32(vld1_s32((int32_t const *) p), vcreate_s32(0))); + free(addr); } -// Load a double-precision (64-bit) floating-point element from memory into the -// lower element of dst, and copy the upper element from a to dst. mem_addr does -// not need to be aligned on any particular boundary. -// -// dst[63:0] := MEM[mem_addr+63:mem_addr] -// dst[127:64] := a[127:64] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadl_pd -FORCE_INLINE __m128d _mm_loadl_pd(__m128d a, const double *p) +// Macro: Get the flush zero bits from the MXCSR control and status register. +// The flush zero may contain any of the following flags: _MM_FLUSH_ZERO_ON or +// _MM_FLUSH_ZERO_OFF +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_MM_GET_FLUSH_ZERO_MODE +FORCE_INLINE unsigned int _sse2neon_mm_get_flush_zero_mode() { + union { + fpcr_bitfield field; #if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vcombine_f64(vld1_f64(p), vget_high_f64(vreinterpretq_f64_m128d(a)))); + uint64_t value; #else - return vreinterpretq_m128d_f32( - vcombine_f32(vld1_f32((const float *) p), - vget_high_f32(vreinterpretq_f32_m128d(a)))); + uint32_t value; #endif -} + } r; -// Load 2 double-precision (64-bit) floating-point elements from memory into dst -// in reverse order. mem_addr must be aligned on a 16-byte boundary or a -// general-protection exception may be generated. -// -// dst[63:0] := MEM[mem_addr+127:mem_addr+64] -// dst[127:64] := MEM[mem_addr+63:mem_addr] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadr_pd -FORCE_INLINE __m128d _mm_loadr_pd(const double *p) -{ #if defined(__aarch64__) - float64x2_t v = vld1q_f64(p); - return vreinterpretq_m128d_f64(vextq_f64(v, v, 1)); + asm volatile("mrs %0, FPCR" : "=r"(r.value)); /* read */ #else - int64x2_t v = vld1q_s64((const int64_t *) p); - return vreinterpretq_m128d_s64(vextq_s64(v, v, 1)); + asm volatile("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ #endif + + return r.field.bit24 ? _MM_FLUSH_ZERO_ON : _MM_FLUSH_ZERO_OFF; } -// Sets the low word to the single-precision, floating-point value of b -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/35hdzazd(v=vs.100) -FORCE_INLINE __m128 _mm_move_ss(__m128 a, __m128 b) +// Macro: Get the rounding mode bits from the MXCSR control and status register. +// The rounding mode may contain any of the following flags: _MM_ROUND_NEAREST, +// _MM_ROUND_DOWN, _MM_ROUND_UP, _MM_ROUND_TOWARD_ZERO +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_MM_GET_ROUNDING_MODE +FORCE_INLINE unsigned int _MM_GET_ROUNDING_MODE() { - return vreinterpretq_m128_f32( - vsetq_lane_f32(vgetq_lane_f32(vreinterpretq_f32_m128(b), 0), - vreinterpretq_f32_m128(a), 0)); + union { + fpcr_bitfield field; +#if defined(__aarch64__) + uint64_t value; +#else + uint32_t value; +#endif + } r; + +#if defined(__aarch64__) + asm volatile("mrs %0, FPCR" : "=r"(r.value)); /* read */ +#else + asm volatile("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ +#endif + + if (r.field.bit22) { + return r.field.bit23 ? _MM_ROUND_TOWARD_ZERO : _MM_ROUND_UP; + } else { + return r.field.bit23 ? _MM_ROUND_DOWN : _MM_ROUND_NEAREST; + } } -// Move the lower double-precision (64-bit) floating-point element from b to the -// lower element of dst, and copy the upper element from a to the upper element -// of dst. -// -// dst[63:0] := b[63:0] -// dst[127:64] := a[127:64] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_move_sd -FORCE_INLINE __m128d _mm_move_sd(__m128d a, __m128d b) +// Copy a to dst, and insert the 16-bit integer i into dst at the location +// specified by imm8. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_insert_pi16 +#define _mm_insert_pi16(a, b, imm) \ + __extension__({ \ + vreinterpret_m64_s16( \ + vset_lane_s16((b), vreinterpret_s16_m64(a), (imm))); \ + }) + +// Loads four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/zzd50xxt(v=vs.100).aspx +FORCE_INLINE __m128 _mm_load_ps(const float *p) { - return vreinterpretq_m128d_f32( - vcombine_f32(vget_low_f32(vreinterpretq_f32_m128d(b)), - vget_high_f32(vreinterpretq_f32_m128d(a)))); + return vreinterpretq_m128_f32(vld1q_f32(p)); } -// Copy the lower 64-bit integer in a to the lower element of dst, and zero the -// upper element. +// Load a single-precision (32-bit) floating-point element from memory into all +// elements of dst. // -// dst[63:0] := a[63:0] -// dst[127:64] := 0 +// dst[31:0] := MEM[mem_addr+31:mem_addr] +// dst[63:32] := MEM[mem_addr+31:mem_addr] +// dst[95:64] := MEM[mem_addr+31:mem_addr] +// dst[127:96] := MEM[mem_addr+31:mem_addr] // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_move_epi64 -FORCE_INLINE __m128i _mm_move_epi64(__m128i a) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_ps1 +#define _mm_load_ps1 _mm_load1_ps + +// Loads an single - precision, floating - point value into the low word and +// clears the upper three words. +// https://msdn.microsoft.com/en-us/library/548bb9h4%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_load_ss(const float *p) { - return vreinterpretq_m128i_s64( - vsetq_lane_s64(0, vreinterpretq_s64_m128i(a), 1)); + return vreinterpretq_m128_f32(vsetq_lane_f32(*p, vdupq_n_f32(0), 0)); } -// Return vector of type __m128 with undefined elements. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_undefined_ps -FORCE_INLINE __m128 _mm_undefined_ps(void) +// Loads a single single-precision, floating-point value, copying it into all +// four words +// https://msdn.microsoft.com/en-us/library/vstudio/5cdkf716(v=vs.100).aspx +FORCE_INLINE __m128 _mm_load1_ps(const float *p) { -#if defined(__GNUC__) || defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wuninitialized" -#endif - __m128 a; - return a; -#if defined(__GNUC__) || defined(__clang__) -#pragma GCC diagnostic pop -#endif + return vreinterpretq_m128_f32(vld1q_dup_f32(p)); } -/* Logic/Binary operations */ - -// Computes the bitwise AND-NOT of the four single-precision, floating-point -// values of a and b. +// Sets the upper two single-precision, floating-point values with 64 +// bits of data loaded from the address p; the lower two values are passed +// through from a. // -// r0 := ~a0 & b0 -// r1 := ~a1 & b1 -// r2 := ~a2 & b2 -// r3 := ~a3 & b3 +// r0 := a0 +// r1 := a1 +// r2 := *p0 +// r3 := *p1 // -// https://msdn.microsoft.com/en-us/library/vstudio/68h7wd02(v=vs.100).aspx -FORCE_INLINE __m128 _mm_andnot_ps(__m128 a, __m128 b) +// https://msdn.microsoft.com/en-us/library/w92wta0x(v%3dvs.100).aspx +FORCE_INLINE __m128 _mm_loadh_pi(__m128 a, __m64 const *p) { - return vreinterpretq_m128_s32( - vbicq_s32(vreinterpretq_s32_m128(b), - vreinterpretq_s32_m128(a))); // *NOTE* argument swap + return vreinterpretq_m128_f32( + vcombine_f32(vget_low_f32(a), vld1_f32((const float32_t *) p))); } -// Compute the bitwise NOT of packed double-precision (64-bit) floating-point -// elements in a and then AND with b, and store the results in dst. +// Sets the lower two single-precision, floating-point values with 64 +// bits of data loaded from the address p; the upper two values are passed +// through from a. // -// FOR j := 0 to 1 -// i := j*64 -// dst[i+63:i] := ((NOT a[i+63:i]) AND b[i+63:i]) -// ENDFOR +// Return Value +// r0 := *p0 +// r1 := *p1 +// r2 := a2 +// r3 := a3 // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_andnot_pd -FORCE_INLINE __m128d _mm_andnot_pd(__m128d a, __m128d b) +// https://msdn.microsoft.com/en-us/library/s57cyak2(v=vs.100).aspx +FORCE_INLINE __m128 _mm_loadl_pi(__m128 a, __m64 const *p) { - // *NOTE* argument swap - return vreinterpretq_m128d_s64( - vbicq_s64(vreinterpretq_s64_m128d(b), vreinterpretq_s64_m128d(a))); + return vreinterpretq_m128_f32( + vcombine_f32(vld1_f32((const float32_t *) p), vget_high_f32(a))); } -// Computes the bitwise AND of the 128-bit value in b and the bitwise NOT of the -// 128-bit value in a. +// Load 4 single-precision (32-bit) floating-point elements from memory into dst +// in reverse order. mem_addr must be aligned on a 16-byte boundary or a +// general-protection exception may be generated. // -// r := (~a) & b +// dst[31:0] := MEM[mem_addr+127:mem_addr+96] +// dst[63:32] := MEM[mem_addr+95:mem_addr+64] +// dst[95:64] := MEM[mem_addr+63:mem_addr+32] +// dst[127:96] := MEM[mem_addr+31:mem_addr] // -// https://msdn.microsoft.com/en-us/library/vstudio/1beaceh8(v=vs.100).aspx -FORCE_INLINE __m128i _mm_andnot_si128(__m128i a, __m128i b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadr_ps +FORCE_INLINE __m128 _mm_loadr_ps(const float *p) { - return vreinterpretq_m128i_s32( - vbicq_s32(vreinterpretq_s32_m128i(b), - vreinterpretq_s32_m128i(a))); // *NOTE* argument swap + float32x4_t v = vrev64q_f32(vld1q_f32(p)); + return vreinterpretq_m128_f32(vextq_f32(v, v, 2)); } -// Computes the bitwise AND of the 128-bit value in a and the 128-bit value in -// b. -// -// r := a & b -// -// https://msdn.microsoft.com/en-us/library/vstudio/6d1txsa8(v=vs.100).aspx -FORCE_INLINE __m128i _mm_and_si128(__m128i a, __m128i b) +// Loads four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/x1b16s7z%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_loadu_ps(const float *p) { - return vreinterpretq_m128i_s32( - vandq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); + // for neon, alignment doesn't matter, so _mm_load_ps and _mm_loadu_ps are + // equivalent for neon + return vreinterpretq_m128_f32(vld1q_f32(p)); } -// Computes the bitwise AND of the four single-precision, floating-point values -// of a and b. +// Load unaligned 16-bit integer from memory into the first element of dst. // -// r0 := a0 & b0 -// r1 := a1 & b1 -// r2 := a2 & b2 -// r3 := a3 & b3 +// dst[15:0] := MEM[mem_addr+15:mem_addr] +// dst[MAX:16] := 0 // -// https://msdn.microsoft.com/en-us/library/vstudio/73ck1xc5(v=vs.100).aspx -FORCE_INLINE __m128 _mm_and_ps(__m128 a, __m128 b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si16 +FORCE_INLINE __m128i _mm_loadu_si16(const void *p) { - return vreinterpretq_m128_s32( - vandq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); + return vreinterpretq_m128i_s16( + vsetq_lane_s16(*(const int16_t *) p, vdupq_n_s16(0), 0)); } -// Compute the bitwise AND of packed double-precision (64-bit) floating-point -// elements in a and b, and store the results in dst. +// Load unaligned 64-bit integer from memory into the first element of dst. // -// FOR j := 0 to 1 -// i := j*64 -// dst[i+63:i] := a[i+63:i] AND b[i+63:i] -// ENDFOR +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[MAX:64] := 0 // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_and_pd -FORCE_INLINE __m128d _mm_and_pd(__m128d a, __m128d b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si64 +FORCE_INLINE __m128i _mm_loadu_si64(const void *p) { - return vreinterpretq_m128d_s64( - vandq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b))); + return vreinterpretq_m128i_s64( + vcombine_s64(vld1_s64((const int64_t *) p), vdup_n_s64(0))); } -// Computes the bitwise OR of the four single-precision, floating-point values -// of a and b. -// https://msdn.microsoft.com/en-us/library/vstudio/7ctdsyy0(v=vs.100).aspx -FORCE_INLINE __m128 _mm_or_ps(__m128 a, __m128 b) +// Allocate aligned blocks of memory. +// https://software.intel.com/en-us/ +// cpp-compiler-developer-guide-and-reference-allocating-and-freeing-aligned-memory-blocks +FORCE_INLINE void *_mm_malloc(size_t size, size_t align) { - return vreinterpretq_m128_s32( - vorrq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); + void *ptr; + if (align == 1) + return malloc(size); + if (align == 2 || (sizeof(void *) == 8 && align == 4)) + align = sizeof(void *); + if (!posix_memalign(&ptr, align, size)) + return ptr; + return NULL; } -// Computes bitwise EXOR (exclusive-or) of the four single-precision, -// floating-point values of a and b. -// https://msdn.microsoft.com/en-us/library/ss6k3wk8(v=vs.100).aspx -FORCE_INLINE __m128 _mm_xor_ps(__m128 a, __m128 b) +// Conditionally store 8-bit integer elements from a into memory using mask +// (elements are not stored when the highest bit is not set in the corresponding +// element) and a non-temporal memory hint. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_maskmove_si64 +FORCE_INLINE void _mm_maskmove_si64(__m64 a, __m64 mask, char *mem_addr) { - return vreinterpretq_m128_s32( - veorq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); + int8x8_t shr_mask = vshr_n_s8(vreinterpret_s8_m64(mask), 7); + __m128 b = _mm_load_ps((const float *) mem_addr); + int8x8_t masked = + vbsl_s8(vreinterpret_u8_s8(shr_mask), vreinterpret_s8_m64(a), + vreinterpret_s8_u64(vget_low_u64(vreinterpretq_u64_m128(b)))); + vst1_s8((int8_t *) mem_addr, masked); } -// Compute the bitwise XOR of packed double-precision (64-bit) floating-point -// elements in a and b, and store the results in dst. +// Conditionally store 8-bit integer elements from a into memory using mask +// (elements are not stored when the highest bit is not set in the corresponding +// element) and a non-temporal memory hint. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_maskmovq +#define _m_maskmovq(a, mask, mem_addr) _mm_maskmove_si64(a, mask, mem_addr) + +// Compare packed signed 16-bit integers in a and b, and store packed maximum +// values in dst. // -// FOR j := 0 to 1 -// i := j*64 -// dst[i+63:i] := a[i+63:i] XOR b[i+63:i] +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := MAX(a[i+15:i], b[i+15:i]) // ENDFOR // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_xor_pd -FORCE_INLINE __m128d _mm_xor_pd(__m128d a, __m128d b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pi16 +FORCE_INLINE __m64 _mm_max_pi16(__m64 a, __m64 b) { - return vreinterpretq_m128d_s64( - veorq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b))); + return vreinterpret_m64_s16( + vmax_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b))); } -// Compute the bitwise OR of packed double-precision (64-bit) floating-point -// elements in a and b, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_or_pd -FORCE_INLINE __m128d _mm_or_pd(__m128d a, __m128d b) +// Computes the maximums of the four single-precision, floating-point values of +// a and b. +// https://msdn.microsoft.com/en-us/library/vstudio/ff5d607a(v=vs.100).aspx +FORCE_INLINE __m128 _mm_max_ps(__m128 a, __m128 b) { - return vreinterpretq_m128d_s64( - vorrq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b))); +#if SSE2NEON_PRECISE_MINMAX + float32x4_t _a = vreinterpretq_f32_m128(a); + float32x4_t _b = vreinterpretq_f32_m128(b); + return vbslq_f32(vcltq_f32(_b, _a), _a, _b); +#else + return vreinterpretq_m128_f32( + vmaxq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#endif } -// Computes the bitwise OR of the 128-bit value in a and the 128-bit value in b. +// Compare packed unsigned 8-bit integers in a and b, and store packed maximum +// values in dst. // -// r := a | b +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := MAX(a[i+7:i], b[i+7:i]) +// ENDFOR // -// https://msdn.microsoft.com/en-us/library/vstudio/ew8ty0db(v=vs.100).aspx -FORCE_INLINE __m128i _mm_or_si128(__m128i a, __m128i b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pu8 +FORCE_INLINE __m64 _mm_max_pu8(__m64 a, __m64 b) { - return vreinterpretq_m128i_s32( - vorrq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); + return vreinterpret_m64_u8( + vmax_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); } -// Computes the bitwise XOR of the 128-bit value in a and the 128-bit value in -// b. https://msdn.microsoft.com/en-us/library/fzt08www(v=vs.100).aspx -FORCE_INLINE __m128i _mm_xor_si128(__m128i a, __m128i b) +// Computes the maximum of the two lower scalar single-precision floating point +// values of a and b. +// https://msdn.microsoft.com/en-us/library/s6db5esz(v=vs.100).aspx +FORCE_INLINE __m128 _mm_max_ss(__m128 a, __m128 b) { - return vreinterpretq_m128i_s32( - veorq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); + float32_t value = vgetq_lane_f32(_mm_max_ps(a, b), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); } -// Duplicate the low double-precision (64-bit) floating-point element from a, -// and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movedup_pd -FORCE_INLINE __m128d _mm_movedup_pd(__m128d a) +// Compare packed signed 16-bit integers in a and b, and store packed minimum +// values in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := MIN(a[i+15:i], b[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pi16 +FORCE_INLINE __m64 _mm_min_pi16(__m64 a, __m64 b) { -#if (__aarch64__) - return vreinterpretq_m128d_f64( - vdupq_laneq_f64(vreinterpretq_f64_m128d(a), 0)); -#else - return vreinterpretq_m128d_u64( - vdupq_n_u64(vgetq_lane_u64(vreinterpretq_u64_m128d(a), 0))); -#endif + return vreinterpret_m64_s16( + vmin_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b))); } -// Duplicate odd-indexed single-precision (32-bit) floating-point elements -// from a, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movehdup_ps -FORCE_INLINE __m128 _mm_movehdup_ps(__m128 a) +// Computes the minima of the four single-precision, floating-point values of a +// and b. +// https://msdn.microsoft.com/en-us/library/vstudio/wh13kadz(v=vs.100).aspx +FORCE_INLINE __m128 _mm_min_ps(__m128 a, __m128 b) { -#if __has_builtin(__builtin_shufflevector) - return vreinterpretq_m128_f32(__builtin_shufflevector( - vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 1, 1, 3, 3)); +#if SSE2NEON_PRECISE_MINMAX + float32x4_t _a = vreinterpretq_f32_m128(a); + float32x4_t _b = vreinterpretq_f32_m128(b); + return vbslq_f32(vcltq_f32(_a, _b), _a, _b); #else - float32_t a1 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 1); - float32_t a3 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 3); - float ALIGN_STRUCT(16) data[4] = {a1, a1, a3, a3}; - return vreinterpretq_m128_f32(vld1q_f32(data)); + return vreinterpretq_m128_f32( + vminq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); #endif } -// Duplicate even-indexed single-precision (32-bit) floating-point elements -// from a, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_moveldup_ps -FORCE_INLINE __m128 _mm_moveldup_ps(__m128 a) +// Compare packed unsigned 8-bit integers in a and b, and store packed minimum +// values in dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := MIN(a[i+7:i], b[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pu8 +FORCE_INLINE __m64 _mm_min_pu8(__m64 a, __m64 b) { -#if __has_builtin(__builtin_shufflevector) - return vreinterpretq_m128_f32(__builtin_shufflevector( - vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 0, 0, 2, 2)); -#else - float32_t a0 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); - float32_t a2 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 2); - float ALIGN_STRUCT(16) data[4] = {a0, a0, a2, a2}; - return vreinterpretq_m128_f32(vld1q_f32(data)); -#endif + return vreinterpret_m64_u8( + vmin_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); +} + +// Computes the minimum of the two lower scalar single-precision floating point +// values of a and b. +// https://msdn.microsoft.com/en-us/library/0a9y7xaa(v=vs.100).aspx +FORCE_INLINE __m128 _mm_min_ss(__m128 a, __m128 b) +{ + float32_t value = vgetq_lane_f32(_mm_min_ps(a, b), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); +} + +// Sets the low word to the single-precision, floating-point value of b +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/35hdzazd(v=vs.100) +FORCE_INLINE __m128 _mm_move_ss(__m128 a, __m128 b) +{ + return vreinterpretq_m128_f32( + vsetq_lane_f32(vgetq_lane_f32(vreinterpretq_f32_m128(b), 0), + vreinterpretq_f32_m128(a), 0)); } // Moves the upper two values of B into the lower two values of A. @@ -1577,315 +2093,419 @@ FORCE_INLINE __m128 _mm_movelh_ps(__m128 __A, __m128 __B) return vreinterpretq_m128_f32(vcombine_f32(a10, b10)); } -// Compute the absolute value of packed signed 32-bit integers in a, and store -// the unsigned results in dst. -// -// FOR j := 0 to 3 -// i := j*32 -// dst[i+31:i] := ABS(a[i+31:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi32 -FORCE_INLINE __m128i _mm_abs_epi32(__m128i a) +// Create mask from the most significant bit of each 8-bit element in a, and +// store the result in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movemask_pi8 +FORCE_INLINE int _mm_movemask_pi8(__m64 a) { - return vreinterpretq_m128i_s32(vabsq_s32(vreinterpretq_s32_m128i(a))); + uint8x8_t input = vreinterpret_u8_m64(a); +#if defined(__aarch64__) + static const int8x8_t shift = {0, 1, 2, 3, 4, 5, 6, 7}; + uint8x8_t tmp = vshr_n_u8(input, 7); + return vaddv_u8(vshl_u8(tmp, shift)); +#else + // Refer the implementation of `_mm_movemask_epi8` + uint16x4_t high_bits = vreinterpret_u16_u8(vshr_n_u8(input, 7)); + uint32x2_t paired16 = + vreinterpret_u32_u16(vsra_n_u16(high_bits, high_bits, 7)); + uint8x8_t paired32 = + vreinterpret_u8_u32(vsra_n_u32(paired16, paired16, 14)); + return vget_lane_u8(paired32, 0) | ((int) vget_lane_u8(paired32, 4) << 4); +#endif } -// Compute the absolute value of packed signed 16-bit integers in a, and store -// the unsigned results in dst. -// -// FOR j := 0 to 7 -// i := j*16 -// dst[i+15:i] := ABS(a[i+15:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi16 -FORCE_INLINE __m128i _mm_abs_epi16(__m128i a) +// NEON does not provide this method +// Creates a 4-bit mask from the most significant bits of the four +// single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/4490ys29(v=vs.100).aspx +FORCE_INLINE int _mm_movemask_ps(__m128 a) { - return vreinterpretq_m128i_s16(vabsq_s16(vreinterpretq_s16_m128i(a))); + uint32x4_t input = vreinterpretq_u32_m128(a); +#if defined(__aarch64__) + static const int32x4_t shift = {0, 1, 2, 3}; + uint32x4_t tmp = vshrq_n_u32(input, 31); + return vaddvq_u32(vshlq_u32(tmp, shift)); +#else + // Uses the exact same method as _mm_movemask_epi8, see that for details. + // Shift out everything but the sign bits with a 32-bit unsigned shift + // right. + uint64x2_t high_bits = vreinterpretq_u64_u32(vshrq_n_u32(input, 31)); + // Merge the two pairs together with a 64-bit unsigned shift right + add. + uint8x16_t paired = + vreinterpretq_u8_u64(vsraq_n_u64(high_bits, high_bits, 31)); + // Extract the result. + return vgetq_lane_u8(paired, 0) | (vgetq_lane_u8(paired, 8) << 2); +#endif } -// Compute the absolute value of packed signed 8-bit integers in a, and store -// the unsigned results in dst. +// Multiplies the four single-precision, floating-point values of a and b. // -// FOR j := 0 to 15 -// i := j*8 -// dst[i+7:i] := ABS(a[i+7:i]) -// ENDFOR +// r0 := a0 * b0 +// r1 := a1 * b1 +// r2 := a2 * b2 +// r3 := a3 * b3 // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi8 -FORCE_INLINE __m128i _mm_abs_epi8(__m128i a) +// https://msdn.microsoft.com/en-us/library/vstudio/22kbk6t9(v=vs.100).aspx +FORCE_INLINE __m128 _mm_mul_ps(__m128 a, __m128 b) { - return vreinterpretq_m128i_s8(vabsq_s8(vreinterpretq_s8_m128i(a))); + return vreinterpretq_m128_f32( + vmulq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); } -// Compute the absolute value of packed signed 32-bit integers in a, and store -// the unsigned results in dst. +// Multiply the lower single-precision (32-bit) floating-point element in a and +// b, store the result in the lower element of dst, and copy the upper 3 packed +// elements from a to the upper elements of dst. // -// FOR j := 0 to 1 -// i := j*32 -// dst[i+31:i] := ABS(a[i+31:i]) -// ENDFOR +// dst[31:0] := a[31:0] * b[31:0] +// dst[127:32] := a[127:32] // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi32 -FORCE_INLINE __m64 _mm_abs_pi32(__m64 a) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_ss +FORCE_INLINE __m128 _mm_mul_ss(__m128 a, __m128 b) { - return vreinterpret_m64_s32(vabs_s32(vreinterpret_s32_m64(a))); + return _mm_move_ss(a, _mm_mul_ps(a, b)); } -// Compute the absolute value of packed signed 16-bit integers in a, and store -// the unsigned results in dst. -// -// FOR j := 0 to 3 -// i := j*16 -// dst[i+15:i] := ABS(a[i+15:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi16 -FORCE_INLINE __m64 _mm_abs_pi16(__m64 a) +// Multiply the packed unsigned 16-bit integers in a and b, producing +// intermediate 32-bit integers, and store the high 16 bits of the intermediate +// integers in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mulhi_pu16 +FORCE_INLINE __m64 _mm_mulhi_pu16(__m64 a, __m64 b) { - return vreinterpret_m64_s16(vabs_s16(vreinterpret_s16_m64(a))); + return vreinterpret_m64_u16(vshrn_n_u32( + vmull_u16(vreinterpret_u16_m64(a), vreinterpret_u16_m64(b)), 16)); } -// Compute the absolute value of packed signed 8-bit integers in a, and store -// the unsigned results in dst. +// Computes the bitwise OR of the four single-precision, floating-point values +// of a and b. +// https://msdn.microsoft.com/en-us/library/vstudio/7ctdsyy0(v=vs.100).aspx +FORCE_INLINE __m128 _mm_or_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_s32( + vorrq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); +} + +// Average packed unsigned 8-bit integers in a and b, and store the results in +// dst. // // FOR j := 0 to 7 // i := j*8 -// dst[i+7:i] := ABS(a[i+7:i]) +// dst[i+7:i] := (a[i+7:i] + b[i+7:i] + 1) >> 1 // ENDFOR // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi8 -FORCE_INLINE __m64 _mm_abs_pi8(__m64 a) -{ - return vreinterpret_m64_s8(vabs_s8(vreinterpret_s8_m64(a))); -} +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pavgb +#define _m_pavgb(a, b) _mm_avg_pu8(a, b) -// Concatenate 16-byte blocks in a and b into a 32-byte temporary result, shift -// the result right by imm8 bytes, and store the low 16 bytes in dst. +// Average packed unsigned 16-bit integers in a and b, and store the results in +// dst. // -// tmp[255:0] := ((a[127:0] << 128)[255:0] OR b[127:0]) >> (imm8*8) -// dst[127:0] := tmp[127:0] +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := (a[i+15:i] + b[i+15:i] + 1) >> 1 +// ENDFOR // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_alignr_epi8 -#define _mm_alignr_epi8(a, b, imm) \ - __extension__({ \ - __m128i ret; \ - if (unlikely((imm) >= 32)) { \ - ret = _mm_setzero_si128(); \ - } else { \ - uint8x16_t tmp_low, tmp_high; \ - if (imm >= 16) { \ - const int idx = imm - 16; \ - tmp_low = vreinterpretq_u8_m128i(a); \ - tmp_high = vdupq_n_u8(0); \ - ret = \ - vreinterpretq_m128i_u8(vextq_u8(tmp_low, tmp_high, idx)); \ - } else { \ - const int idx = imm; \ - tmp_low = vreinterpretq_u8_m128i(b); \ - tmp_high = vreinterpretq_u8_m128i(a); \ - ret = \ - vreinterpretq_m128i_u8(vextq_u8(tmp_low, tmp_high, idx)); \ - } \ - } \ - ret; \ - }) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pavgw +#define _m_pavgw(a, b) _mm_avg_pu16(a, b) -// Concatenate 8-byte blocks in a and b into a 16-byte temporary result, shift -// the result right by imm8 bytes, and store the low 8 bytes in dst. -// -// tmp[127:0] := ((a[63:0] << 64)[127:0] OR b[63:0]) >> (imm8*8) -// dst[63:0] := tmp[63:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_alignr_pi8 -#define _mm_alignr_pi8(a, b, imm) \ - __extension__({ \ - __m64 ret; \ - if (unlikely((imm) >= 16)) { \ - ret = vreinterpret_m64_s8(vdup_n_s8(0)); \ - } else { \ - uint8x8_t tmp_low, tmp_high; \ - if (imm >= 8) { \ - const int idx = imm - 8; \ - tmp_low = vreinterpret_u8_m64(a); \ - tmp_high = vdup_n_u8(0); \ - ret = vreinterpret_m64_u8(vext_u8(tmp_low, tmp_high, idx)); \ - } else { \ - const int idx = imm; \ - tmp_low = vreinterpret_u8_m64(b); \ - tmp_high = vreinterpret_u8_m64(a); \ - ret = vreinterpret_m64_u8(vext_u8(tmp_low, tmp_high, idx)); \ - } \ - } \ - ret; \ - }) +// Extract a 16-bit integer from a, selected with imm8, and store the result in +// the lower element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pextrw +#define _m_pextrw(a, imm) _mm_extract_pi16(a, imm) -// Takes the upper 64 bits of a and places it in the low end of the result -// Takes the lower 64 bits of b and places it into the high end of the result. -FORCE_INLINE __m128 _mm_shuffle_ps_1032(__m128 a, __m128 b) -{ - float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a)); - float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); - return vreinterpretq_m128_f32(vcombine_f32(a32, b10)); -} +// Copy a to dst, and insert the 16-bit integer i into dst at the location +// specified by imm8. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=m_pinsrw +#define _m_pinsrw(a, i, imm) _mm_insert_pi16(a, i, imm) -// takes the lower two 32-bit values from a and swaps them and places in high -// end of result takes the higher two 32 bit values from b and swaps them and -// places in low end of result. -FORCE_INLINE __m128 _mm_shuffle_ps_2301(__m128 a, __m128 b) +// Compare packed signed 16-bit integers in a and b, and store packed maximum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmaxsw +#define _m_pmaxsw(a, b) _mm_max_pi16(a, b) + +// Compare packed unsigned 8-bit integers in a and b, and store packed maximum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmaxub +#define _m_pmaxub(a, b) _mm_max_pu8(a, b) + +// Compare packed signed 16-bit integers in a and b, and store packed minimum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pminsw +#define _m_pminsw(a, b) _mm_min_pi16(a, b) + +// Compare packed unsigned 8-bit integers in a and b, and store packed minimum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pminub +#define _m_pminub(a, b) _mm_min_pu8(a, b) + +// Create mask from the most significant bit of each 8-bit element in a, and +// store the result in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmovmskb +#define _m_pmovmskb(a) _mm_movemask_pi8(a) + +// Multiply the packed unsigned 16-bit integers in a and b, producing +// intermediate 32-bit integers, and store the high 16 bits of the intermediate +// integers in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmulhuw +#define _m_pmulhuw(a, b) _mm_mulhi_pu16(a, b) + +// Loads one cache line of data from address p to a location closer to the +// processor. https://msdn.microsoft.com/en-us/library/84szxsww(v=vs.100).aspx +FORCE_INLINE void _mm_prefetch(const void *p, int i) { - float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); - float32x2_t b23 = vrev64_f32(vget_high_f32(vreinterpretq_f32_m128(b))); - return vreinterpretq_m128_f32(vcombine_f32(a01, b23)); + (void) i; + __builtin_prefetch(p); } -FORCE_INLINE __m128 _mm_shuffle_ps_0321(__m128 a, __m128 b) +// Compute the absolute differences of packed unsigned 8-bit integers in a and +// b, then horizontally sum each consecutive 8 differences to produce four +// unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low +// 16 bits of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=m_psadbw +#define _m_psadbw(a, b) _mm_sad_pu8(a, b) + +// Shuffle 16-bit integers in a using the control in imm8, and store the results +// in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pshufw +#define _m_pshufw(a, imm) _mm_shuffle_pi16(a, imm) + +// Compute the approximate reciprocal of packed single-precision (32-bit) +// floating-point elements in a, and store the results in dst. The maximum +// relative error for this approximation is less than 1.5*2^-12. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rcp_ps +FORCE_INLINE __m128 _mm_rcp_ps(__m128 in) { - float32x2_t a21 = vget_high_f32( - vextq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 3)); - float32x2_t b03 = vget_low_f32( - vextq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b), 3)); - return vreinterpretq_m128_f32(vcombine_f32(a21, b03)); + float32x4_t recip = vrecpeq_f32(vreinterpretq_f32_m128(in)); + recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(in))); +#if SSE2NEON_PRECISE_DIV + // Additional Netwon-Raphson iteration for accuracy + recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(in))); +#endif + return vreinterpretq_m128_f32(recip); } -FORCE_INLINE __m128 _mm_shuffle_ps_2103(__m128 a, __m128 b) +// Compute the approximate reciprocal of the lower single-precision (32-bit) +// floating-point element in a, store the result in the lower element of dst, +// and copy the upper 3 packed elements from a to the upper elements of dst. The +// maximum relative error for this approximation is less than 1.5*2^-12. +// +// dst[31:0] := (1.0 / a[31:0]) +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rcp_ss +FORCE_INLINE __m128 _mm_rcp_ss(__m128 a) { - float32x2_t a03 = vget_low_f32( - vextq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 3)); - float32x2_t b21 = vget_high_f32( - vextq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b), 3)); - return vreinterpretq_m128_f32(vcombine_f32(a03, b21)); + return _mm_move_ss(a, _mm_rcp_ps(a)); } -FORCE_INLINE __m128 _mm_shuffle_ps_1010(__m128 a, __m128 b) +// Computes the approximations of the reciprocal square roots of the four +// single-precision floating point values of in. +// The current precision is 1% error. +// https://msdn.microsoft.com/en-us/library/22hfsh53(v=vs.100).aspx +FORCE_INLINE __m128 _mm_rsqrt_ps(__m128 in) { - float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); - float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); - return vreinterpretq_m128_f32(vcombine_f32(a10, b10)); + float32x4_t out = vrsqrteq_f32(vreinterpretq_f32_m128(in)); +#if SSE2NEON_PRECISE_SQRT + // Additional Netwon-Raphson iteration for accuracy + out = vmulq_f32( + out, vrsqrtsq_f32(vmulq_f32(vreinterpretq_f32_m128(in), out), out)); + out = vmulq_f32( + out, vrsqrtsq_f32(vmulq_f32(vreinterpretq_f32_m128(in), out), out)); +#endif + return vreinterpretq_m128_f32(out); } -FORCE_INLINE __m128 _mm_shuffle_ps_1001(__m128 a, __m128 b) +// Compute the approximate reciprocal square root of the lower single-precision +// (32-bit) floating-point element in a, store the result in the lower element +// of dst, and copy the upper 3 packed elements from a to the upper elements of +// dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rsqrt_ss +FORCE_INLINE __m128 _mm_rsqrt_ss(__m128 in) { - float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); - float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); - return vreinterpretq_m128_f32(vcombine_f32(a01, b10)); + return vsetq_lane_f32(vgetq_lane_f32(_mm_rsqrt_ps(in), 0), in, 0); } -FORCE_INLINE __m128 _mm_shuffle_ps_0101(__m128 a, __m128 b) +// Compute the absolute differences of packed unsigned 8-bit integers in a and +// b, then horizontally sum each consecutive 8 differences to produce four +// unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low +// 16 bits of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sad_pu8 +FORCE_INLINE __m64 _mm_sad_pu8(__m64 a, __m64 b) { - float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); - float32x2_t b01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(b))); - return vreinterpretq_m128_f32(vcombine_f32(a01, b01)); + uint64x1_t t = vpaddl_u32(vpaddl_u16( + vpaddl_u8(vabd_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))))); + return vreinterpret_m64_u16( + vset_lane_u16(vget_lane_u64(t, 0), vdup_n_u16(0), 0)); } -// keeps the low 64 bits of b in the low and puts the high 64 bits of a in the -// high -FORCE_INLINE __m128 _mm_shuffle_ps_3210(__m128 a, __m128 b) +// Macro: Set the flush zero bits of the MXCSR control and status register to +// the value in unsigned 32-bit integer a. The flush zero may contain any of the +// following flags: _MM_FLUSH_ZERO_ON or _MM_FLUSH_ZERO_OFF +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_MM_SET_FLUSH_ZERO_MODE +FORCE_INLINE void _sse2neon_mm_set_flush_zero_mode(unsigned int flag) { - float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); - float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b)); - return vreinterpretq_m128_f32(vcombine_f32(a10, b32)); + // AArch32 Advanced SIMD arithmetic always uses the Flush-to-zero setting, + // regardless of the value of the FZ bit. + union { + fpcr_bitfield field; +#if defined(__aarch64__) + uint64_t value; +#else + uint32_t value; +#endif + } r; + +#if defined(__aarch64__) + asm volatile("mrs %0, FPCR" : "=r"(r.value)); /* read */ +#else + asm volatile("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ +#endif + + r.field.bit24 = (flag & _MM_FLUSH_ZERO_MASK) == _MM_FLUSH_ZERO_ON; + +#if defined(__aarch64__) + asm volatile("msr FPCR, %0" ::"r"(r)); /* write */ +#else + asm volatile("vmsr FPSCR, %0" ::"r"(r)); /* write */ +#endif } -FORCE_INLINE __m128 _mm_shuffle_ps_0011(__m128 a, __m128 b) +// Sets the four single-precision, floating-point values to the four inputs. +// https://msdn.microsoft.com/en-us/library/vstudio/afh0zf75(v=vs.100).aspx +FORCE_INLINE __m128 _mm_set_ps(float w, float z, float y, float x) { - float32x2_t a11 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(a)), 1); - float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); - return vreinterpretq_m128_f32(vcombine_f32(a11, b00)); + float ALIGN_STRUCT(16) data[4] = {x, y, z, w}; + return vreinterpretq_m128_f32(vld1q_f32(data)); } -FORCE_INLINE __m128 _mm_shuffle_ps_0022(__m128 a, __m128 b) +// Sets the four single-precision, floating-point values to w. +// https://msdn.microsoft.com/en-us/library/vstudio/2x1se8ha(v=vs.100).aspx +FORCE_INLINE __m128 _mm_set_ps1(float _w) { - float32x2_t a22 = - vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(a)), 0); - float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); - return vreinterpretq_m128_f32(vcombine_f32(a22, b00)); + return vreinterpretq_m128_f32(vdupq_n_f32(_w)); } -FORCE_INLINE __m128 _mm_shuffle_ps_2200(__m128 a, __m128 b) +// Macro: Set the rounding mode bits of the MXCSR control and status register to +// the value in unsigned 32-bit integer a. The rounding mode may contain any of +// the following flags: _MM_ROUND_NEAREST, _MM_ROUND_DOWN, _MM_ROUND_UP, +// _MM_ROUND_TOWARD_ZERO +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_MM_SET_ROUNDING_MODE +FORCE_INLINE void _MM_SET_ROUNDING_MODE(int rounding) { - float32x2_t a00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(a)), 0); - float32x2_t b22 = - vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(b)), 0); - return vreinterpretq_m128_f32(vcombine_f32(a00, b22)); + union { + fpcr_bitfield field; +#if defined(__aarch64__) + uint64_t value; +#else + uint32_t value; +#endif + } r; + +#if defined(__aarch64__) + asm volatile("mrs %0, FPCR" : "=r"(r.value)); /* read */ +#else + asm volatile("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ +#endif + + switch (rounding) { + case _MM_ROUND_TOWARD_ZERO: + r.field.bit22 = 1; + r.field.bit23 = 1; + break; + case _MM_ROUND_DOWN: + r.field.bit22 = 0; + r.field.bit23 = 1; + break; + case _MM_ROUND_UP: + r.field.bit22 = 1; + r.field.bit23 = 0; + break; + default: //_MM_ROUND_NEAREST + r.field.bit22 = 0; + r.field.bit23 = 0; + } + +#if defined(__aarch64__) + asm volatile("msr FPCR, %0" ::"r"(r)); /* write */ +#else + asm volatile("vmsr FPSCR, %0" ::"r"(r)); /* write */ +#endif } -FORCE_INLINE __m128 _mm_shuffle_ps_3202(__m128 a, __m128 b) +// Copy single-precision (32-bit) floating-point element a to the lower element +// of dst, and zero the upper 3 elements. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_ss +FORCE_INLINE __m128 _mm_set_ss(float a) { - float32_t a0 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); - float32x2_t a22 = - vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(a)), 0); - float32x2_t a02 = vset_lane_f32(a0, a22, 1); /* TODO: use vzip ?*/ - float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b)); - return vreinterpretq_m128_f32(vcombine_f32(a02, b32)); + float ALIGN_STRUCT(16) data[4] = {a, 0, 0, 0}; + return vreinterpretq_m128_f32(vld1q_f32(data)); } -FORCE_INLINE __m128 _mm_shuffle_ps_1133(__m128 a, __m128 b) +// Sets the four single-precision, floating-point values to w. +// +// r0 := r1 := r2 := r3 := w +// +// https://msdn.microsoft.com/en-us/library/vstudio/2x1se8ha(v=vs.100).aspx +FORCE_INLINE __m128 _mm_set1_ps(float _w) { - float32x2_t a33 = - vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(a)), 1); - float32x2_t b11 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 1); - return vreinterpretq_m128_f32(vcombine_f32(a33, b11)); + return vreinterpretq_m128_f32(vdupq_n_f32(_w)); } -FORCE_INLINE __m128 _mm_shuffle_ps_2010(__m128 a, __m128 b) +FORCE_INLINE void _mm_setcsr(unsigned int a) { - float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); - float32_t b2 = vgetq_lane_f32(vreinterpretq_f32_m128(b), 2); - float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); - float32x2_t b20 = vset_lane_f32(b2, b00, 1); - return vreinterpretq_m128_f32(vcombine_f32(a10, b20)); + _MM_SET_ROUNDING_MODE(a); } -FORCE_INLINE __m128 _mm_shuffle_ps_2001(__m128 a, __m128 b) +// Sets the four single-precision, floating-point values to the four inputs in +// reverse order. +// https://msdn.microsoft.com/en-us/library/vstudio/d2172ct3(v=vs.100).aspx +FORCE_INLINE __m128 _mm_setr_ps(float w, float z, float y, float x) { - float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); - float32_t b2 = vgetq_lane_f32(b, 2); - float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); - float32x2_t b20 = vset_lane_f32(b2, b00, 1); - return vreinterpretq_m128_f32(vcombine_f32(a01, b20)); + float ALIGN_STRUCT(16) data[4] = {w, z, y, x}; + return vreinterpretq_m128_f32(vld1q_f32(data)); } -FORCE_INLINE __m128 _mm_shuffle_ps_2032(__m128 a, __m128 b) +// Clears the four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/tk1t2tbz(v=vs.100).aspx +FORCE_INLINE __m128 _mm_setzero_ps(void) { - float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a)); - float32_t b2 = vgetq_lane_f32(b, 2); - float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); - float32x2_t b20 = vset_lane_f32(b2, b00, 1); - return vreinterpretq_m128_f32(vcombine_f32(a32, b20)); + return vreinterpretq_m128_f32(vdupq_n_f32(0)); } -// NEON does not support a general purpose permute intrinsic -// Selects four specific single-precision, floating-point values from a and b, -// based on the mask i. -// -// C equivalent: -// __m128 _mm_shuffle_ps_default(__m128 a, __m128 b, -// __constrange(0, 255) int imm) { -// __m128 ret; -// ret[0] = a[imm & 0x3]; ret[1] = a[(imm >> 2) & 0x3]; -// ret[2] = b[(imm >> 4) & 0x03]; ret[3] = b[(imm >> 6) & 0x03]; -// return ret; -// } -// -// https://msdn.microsoft.com/en-us/library/vstudio/5f0858x0(v=vs.100).aspx -#define _mm_shuffle_ps_default(a, b, imm) \ +// Shuffle 16-bit integers in a using the control in imm8, and store the results +// in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_pi16 +#if __has_builtin(__builtin_shufflevector) +#define _mm_shuffle_pi16(a, imm) \ __extension__({ \ - float32x4_t ret; \ - ret = vmovq_n_f32( \ - vgetq_lane_f32(vreinterpretq_f32_m128(a), (imm) & (0x3))); \ - ret = vsetq_lane_f32( \ - vgetq_lane_f32(vreinterpretq_f32_m128(a), ((imm) >> 2) & 0x3), \ - ret, 1); \ - ret = vsetq_lane_f32( \ - vgetq_lane_f32(vreinterpretq_f32_m128(b), ((imm) >> 4) & 0x3), \ - ret, 2); \ - ret = vsetq_lane_f32( \ - vgetq_lane_f32(vreinterpretq_f32_m128(b), ((imm) >> 6) & 0x3), \ - ret, 3); \ - vreinterpretq_m128_f32(ret); \ + vreinterpret_m64_s16(__builtin_shufflevector( \ + vreinterpret_s16_m64(a), vreinterpret_s16_m64(a), (imm & 0x3), \ + ((imm >> 2) & 0x3), ((imm >> 4) & 0x3), ((imm >> 6) & 0x3))); \ }) +#else +#define _mm_shuffle_pi16(a, imm) \ + __extension__({ \ + int16x4_t ret; \ + ret = \ + vmov_n_s16(vget_lane_s16(vreinterpret_s16_m64(a), (imm) & (0x3))); \ + ret = vset_lane_s16( \ + vget_lane_s16(vreinterpret_s16_m64(a), ((imm) >> 2) & 0x3), ret, \ + 1); \ + ret = vset_lane_s16( \ + vget_lane_s16(vreinterpret_s16_m64(a), ((imm) >> 4) & 0x3), ret, \ + 2); \ + ret = vset_lane_s16( \ + vget_lane_s16(vreinterpret_s16_m64(a), ((imm) >> 6) & 0x3), ret, \ + 3); \ + vreinterpret_m64_s16(ret); \ + }) +#endif + +// Guarantees that every preceding store is globally visible before any +// subsequent store. +// https://msdn.microsoft.com/en-us/library/5h2w73d1%28v=vs.90%29.aspx +FORCE_INLINE void _mm_sfence(void) +{ + __sync_synchronize(); +} // FORCE_INLINE __m128 _mm_shuffle_ps(__m128 a, __m128 b, __constrange(0,255) // int imm) @@ -1963,1876 +2583,1721 @@ FORCE_INLINE __m128 _mm_shuffle_ps_2032(__m128 a, __m128 b) }) #endif -// Takes the upper 64 bits of a and places it in the low end of the result -// Takes the lower 64 bits of a and places it into the high end of the result. -FORCE_INLINE __m128i _mm_shuffle_epi_1032(__m128i a) +// Computes the approximations of square roots of the four single-precision, +// floating-point values of a. First computes reciprocal square roots and then +// reciprocals of the four values. +// +// r0 := sqrt(a0) +// r1 := sqrt(a1) +// r2 := sqrt(a2) +// r3 := sqrt(a3) +// +// https://msdn.microsoft.com/en-us/library/vstudio/8z67bwwk(v=vs.100).aspx +FORCE_INLINE __m128 _mm_sqrt_ps(__m128 in) { - int32x2_t a32 = vget_high_s32(vreinterpretq_s32_m128i(a)); - int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); - return vreinterpretq_m128i_s32(vcombine_s32(a32, a10)); +#if SSE2NEON_PRECISE_SQRT + float32x4_t recip = vrsqrteq_f32(vreinterpretq_f32_m128(in)); + + // Test for vrsqrteq_f32(0) -> positive infinity case. + // Change to zero, so that s * 1/sqrt(s) result is zero too. + const uint32x4_t pos_inf = vdupq_n_u32(0x7F800000); + const uint32x4_t div_by_zero = + vceqq_u32(pos_inf, vreinterpretq_u32_f32(recip)); + recip = vreinterpretq_f32_u32( + vandq_u32(vmvnq_u32(div_by_zero), vreinterpretq_u32_f32(recip))); + + // Additional Netwon-Raphson iteration for accuracy + recip = vmulq_f32( + vrsqrtsq_f32(vmulq_f32(recip, recip), vreinterpretq_f32_m128(in)), + recip); + recip = vmulq_f32( + vrsqrtsq_f32(vmulq_f32(recip, recip), vreinterpretq_f32_m128(in)), + recip); + + // sqrt(s) = s * 1/sqrt(s) + return vreinterpretq_m128_f32(vmulq_f32(vreinterpretq_f32_m128(in), recip)); +#elif defined(__aarch64__) + return vreinterpretq_m128_f32(vsqrtq_f32(vreinterpretq_f32_m128(in))); +#else + float32x4_t recipsq = vrsqrteq_f32(vreinterpretq_f32_m128(in)); + float32x4_t sq = vrecpeq_f32(recipsq); + return vreinterpretq_m128_f32(sq); +#endif } -// takes the lower two 32-bit values from a and swaps them and places in low end -// of result takes the higher two 32 bit values from a and swaps them and places -// in high end of result. -FORCE_INLINE __m128i _mm_shuffle_epi_2301(__m128i a) +// Computes the approximation of the square root of the scalar single-precision +// floating point value of in. +// https://msdn.microsoft.com/en-us/library/ahfsc22d(v=vs.100).aspx +FORCE_INLINE __m128 _mm_sqrt_ss(__m128 in) { - int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); - int32x2_t a23 = vrev64_s32(vget_high_s32(vreinterpretq_s32_m128i(a))); - return vreinterpretq_m128i_s32(vcombine_s32(a01, a23)); + float32_t value = + vgetq_lane_f32(vreinterpretq_f32_m128(_mm_sqrt_ps(in)), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(in), 0)); } -// rotates the least significant 32 bits into the most signficant 32 bits, and -// shifts the rest down -FORCE_INLINE __m128i _mm_shuffle_epi_0321(__m128i a) +// Stores four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/s3h4ay6y(v=vs.100).aspx +FORCE_INLINE void _mm_store_ps(float *p, __m128 a) { - return vreinterpretq_m128i_s32( - vextq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(a), 1)); + vst1q_f32(p, vreinterpretq_f32_m128(a)); } -// rotates the most significant 32 bits into the least signficant 32 bits, and -// shifts the rest up -FORCE_INLINE __m128i _mm_shuffle_epi_2103(__m128i a) +// Store the lower single-precision (32-bit) floating-point element from a into +// 4 contiguous elements in memory. mem_addr must be aligned on a 16-byte +// boundary or a general-protection exception may be generated. +// +// MEM[mem_addr+31:mem_addr] := a[31:0] +// MEM[mem_addr+63:mem_addr+32] := a[31:0] +// MEM[mem_addr+95:mem_addr+64] := a[31:0] +// MEM[mem_addr+127:mem_addr+96] := a[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store_ps1 +FORCE_INLINE void _mm_store_ps1(float *p, __m128 a) { - return vreinterpretq_m128i_s32( - vextq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(a), 3)); + float32_t a0 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + vst1q_f32(p, vdupq_n_f32(a0)); } -// gets the lower 64 bits of a, and places it in the upper 64 bits -// gets the lower 64 bits of a and places it in the lower 64 bits -FORCE_INLINE __m128i _mm_shuffle_epi_1010(__m128i a) +// Stores the lower single - precision, floating - point value. +// https://msdn.microsoft.com/en-us/library/tzz10fbx(v=vs.100).aspx +FORCE_INLINE void _mm_store_ss(float *p, __m128 a) { - int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); - return vreinterpretq_m128i_s32(vcombine_s32(a10, a10)); + vst1q_lane_f32(p, vreinterpretq_f32_m128(a), 0); } -// gets the lower 64 bits of a, swaps the 0 and 1 elements, and places it in the -// lower 64 bits gets the lower 64 bits of a, and places it in the upper 64 bits -FORCE_INLINE __m128i _mm_shuffle_epi_1001(__m128i a) +// Store the lower single-precision (32-bit) floating-point element from a into +// 4 contiguous elements in memory. mem_addr must be aligned on a 16-byte +// boundary or a general-protection exception may be generated. +// +// MEM[mem_addr+31:mem_addr] := a[31:0] +// MEM[mem_addr+63:mem_addr+32] := a[31:0] +// MEM[mem_addr+95:mem_addr+64] := a[31:0] +// MEM[mem_addr+127:mem_addr+96] := a[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store1_ps +#define _mm_store1_ps _mm_store_ps1 + +// Stores the upper two single-precision, floating-point values of a to the +// address p. +// +// *p0 := a2 +// *p1 := a3 +// +// https://msdn.microsoft.com/en-us/library/a7525fs8(v%3dvs.90).aspx +FORCE_INLINE void _mm_storeh_pi(__m64 *p, __m128 a) { - int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); - int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); - return vreinterpretq_m128i_s32(vcombine_s32(a01, a10)); + *p = vreinterpret_m64_f32(vget_high_f32(a)); } -// gets the lower 64 bits of a, swaps the 0 and 1 elements and places it in the -// upper 64 bits gets the lower 64 bits of a, swaps the 0 and 1 elements, and -// places it in the lower 64 bits -FORCE_INLINE __m128i _mm_shuffle_epi_0101(__m128i a) +// Stores the lower two single-precision floating point values of a to the +// address p. +// +// *p0 := a0 +// *p1 := a1 +// +// https://msdn.microsoft.com/en-us/library/h54t98ks(v=vs.90).aspx +FORCE_INLINE void _mm_storel_pi(__m64 *p, __m128 a) { - int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); - return vreinterpretq_m128i_s32(vcombine_s32(a01, a01)); + *p = vreinterpret_m64_f32(vget_low_f32(a)); } -FORCE_INLINE __m128i _mm_shuffle_epi_2211(__m128i a) +// Store 4 single-precision (32-bit) floating-point elements from a into memory +// in reverse order. mem_addr must be aligned on a 16-byte boundary or a +// general-protection exception may be generated. +// +// MEM[mem_addr+31:mem_addr] := a[127:96] +// MEM[mem_addr+63:mem_addr+32] := a[95:64] +// MEM[mem_addr+95:mem_addr+64] := a[63:32] +// MEM[mem_addr+127:mem_addr+96] := a[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storer_ps +FORCE_INLINE void _mm_storer_ps(float *p, __m128 a) { - int32x2_t a11 = vdup_lane_s32(vget_low_s32(vreinterpretq_s32_m128i(a)), 1); - int32x2_t a22 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 0); - return vreinterpretq_m128i_s32(vcombine_s32(a11, a22)); + float32x4_t tmp = vrev64q_f32(vreinterpretq_f32_m128(a)); + float32x4_t rev = vextq_f32(tmp, tmp, 2); + vst1q_f32(p, rev); } -FORCE_INLINE __m128i _mm_shuffle_epi_0122(__m128i a) +// Stores four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/44e30x22(v=vs.100).aspx +FORCE_INLINE void _mm_storeu_ps(float *p, __m128 a) { - int32x2_t a22 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 0); - int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); - return vreinterpretq_m128i_s32(vcombine_s32(a22, a01)); + vst1q_f32(p, vreinterpretq_f32_m128(a)); } -FORCE_INLINE __m128i _mm_shuffle_epi_3332(__m128i a) +// Stores 16-bits of integer data a at the address p. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si16 +FORCE_INLINE void _mm_storeu_si16(void *p, __m128i a) { - int32x2_t a32 = vget_high_s32(vreinterpretq_s32_m128i(a)); - int32x2_t a33 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 1); - return vreinterpretq_m128i_s32(vcombine_s32(a32, a33)); + vst1q_lane_s16((int16_t *) p, vreinterpretq_s16_m128i(a), 0); } -// Shuffle packed 8-bit integers in a according to shuffle control mask in the -// corresponding 8-bit element of b, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_epi8 -FORCE_INLINE __m128i _mm_shuffle_epi8(__m128i a, __m128i b) +// Stores 64-bits of integer data a at the address p. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si64 +FORCE_INLINE void _mm_storeu_si64(void *p, __m128i a) { - int8x16_t tbl = vreinterpretq_s8_m128i(a); // input a - uint8x16_t idx = vreinterpretq_u8_m128i(b); // input b - uint8x16_t idx_masked = - vandq_u8(idx, vdupq_n_u8(0x8F)); // avoid using meaningless bits -#if defined(__aarch64__) - return vreinterpretq_m128i_s8(vqtbl1q_s8(tbl, idx_masked)); -#elif defined(__GNUC__) - int8x16_t ret; - // %e and %f represent the even and odd D registers - // respectively. - __asm__ __volatile__( - "vtbl.8 %e[ret], {%e[tbl], %f[tbl]}, %e[idx]\n" - "vtbl.8 %f[ret], {%e[tbl], %f[tbl]}, %f[idx]\n" - : [ret] "=&w"(ret) - : [tbl] "w"(tbl), [idx] "w"(idx_masked)); - return vreinterpretq_m128i_s8(ret); -#else - // use this line if testing on aarch64 - int8x8x2_t a_split = {vget_low_s8(tbl), vget_high_s8(tbl)}; - return vreinterpretq_m128i_s8( - vcombine_s8(vtbl2_s8(a_split, vget_low_u8(idx_masked)), - vtbl2_s8(a_split, vget_high_u8(idx_masked)))); -#endif + vst1q_lane_s64((int64_t *) p, vreinterpretq_s64_m128i(a), 0); } -// C equivalent: -// __m128i _mm_shuffle_epi32_default(__m128i a, -// __constrange(0, 255) int imm) { -// __m128i ret; -// ret[0] = a[imm & 0x3]; ret[1] = a[(imm >> 2) & 0x3]; -// ret[2] = a[(imm >> 4) & 0x03]; ret[3] = a[(imm >> 6) & 0x03]; -// return ret; -// } -#define _mm_shuffle_epi32_default(a, imm) \ - __extension__({ \ - int32x4_t ret; \ - ret = vmovq_n_s32( \ - vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm) & (0x3))); \ - ret = vsetq_lane_s32( \ - vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 2) & 0x3), \ - ret, 1); \ - ret = vsetq_lane_s32( \ - vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 4) & 0x3), \ - ret, 2); \ - ret = vsetq_lane_s32( \ - vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 6) & 0x3), \ - ret, 3); \ - vreinterpretq_m128i_s32(ret); \ - }) +// Store 64-bits of integer data from a into memory using a non-temporal memory +// hint. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_pi +FORCE_INLINE void _mm_stream_pi(__m64 *p, __m64 a) +{ + vst1_s64((int64_t *) p, vreinterpret_s64_m64(a)); +} -// FORCE_INLINE __m128i _mm_shuffle_epi32_splat(__m128i a, __constrange(0,255) -// int imm) -#if defined(__aarch64__) -#define _mm_shuffle_epi32_splat(a, imm) \ - __extension__({ \ - vreinterpretq_m128i_s32( \ - vdupq_laneq_s32(vreinterpretq_s32_m128i(a), (imm))); \ - }) +// Store 128-bits (composed of 4 packed single-precision (32-bit) floating- +// point elements) from a into memory using a non-temporal memory hint. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_ps +FORCE_INLINE void _mm_stream_ps(float *p, __m128 a) +{ +#if __has_builtin(__builtin_nontemporal_store) + __builtin_nontemporal_store(a, (float32x4_t *) p); #else -#define _mm_shuffle_epi32_splat(a, imm) \ - __extension__({ \ - vreinterpretq_m128i_s32( \ - vdupq_n_s32(vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm)))); \ - }) + vst1q_f32(p, vreinterpretq_f32_m128(a)); #endif +} -// Shuffles the 4 signed or unsigned 32-bit integers in a as specified by imm. -// https://msdn.microsoft.com/en-us/library/56f67xbk%28v=vs.90%29.aspx -// FORCE_INLINE __m128i _mm_shuffle_epi32(__m128i a, -// __constrange(0,255) int imm) -#if __has_builtin(__builtin_shufflevector) -#define _mm_shuffle_epi32(a, imm) \ - __extension__({ \ - int32x4_t _input = vreinterpretq_s32_m128i(a); \ - int32x4_t _shuf = __builtin_shufflevector( \ - _input, _input, (imm) & (0x3), ((imm) >> 2) & 0x3, \ - ((imm) >> 4) & 0x3, ((imm) >> 6) & 0x3); \ - vreinterpretq_m128i_s32(_shuf); \ - }) -#else // generic -#define _mm_shuffle_epi32(a, imm) \ - __extension__({ \ - __m128i ret; \ - switch (imm) { \ - case _MM_SHUFFLE(1, 0, 3, 2): \ - ret = _mm_shuffle_epi_1032((a)); \ - break; \ - case _MM_SHUFFLE(2, 3, 0, 1): \ - ret = _mm_shuffle_epi_2301((a)); \ - break; \ - case _MM_SHUFFLE(0, 3, 2, 1): \ - ret = _mm_shuffle_epi_0321((a)); \ - break; \ - case _MM_SHUFFLE(2, 1, 0, 3): \ - ret = _mm_shuffle_epi_2103((a)); \ - break; \ - case _MM_SHUFFLE(1, 0, 1, 0): \ - ret = _mm_shuffle_epi_1010((a)); \ - break; \ - case _MM_SHUFFLE(1, 0, 0, 1): \ - ret = _mm_shuffle_epi_1001((a)); \ - break; \ - case _MM_SHUFFLE(0, 1, 0, 1): \ - ret = _mm_shuffle_epi_0101((a)); \ - break; \ - case _MM_SHUFFLE(2, 2, 1, 1): \ - ret = _mm_shuffle_epi_2211((a)); \ - break; \ - case _MM_SHUFFLE(0, 1, 2, 2): \ - ret = _mm_shuffle_epi_0122((a)); \ - break; \ - case _MM_SHUFFLE(3, 3, 3, 2): \ - ret = _mm_shuffle_epi_3332((a)); \ - break; \ - case _MM_SHUFFLE(0, 0, 0, 0): \ - ret = _mm_shuffle_epi32_splat((a), 0); \ - break; \ - case _MM_SHUFFLE(1, 1, 1, 1): \ - ret = _mm_shuffle_epi32_splat((a), 1); \ - break; \ - case _MM_SHUFFLE(2, 2, 2, 2): \ - ret = _mm_shuffle_epi32_splat((a), 2); \ - break; \ - case _MM_SHUFFLE(3, 3, 3, 3): \ - ret = _mm_shuffle_epi32_splat((a), 3); \ - break; \ - default: \ - ret = _mm_shuffle_epi32_default((a), (imm)); \ - break; \ - } \ - ret; \ - }) -#endif +// Subtracts the four single-precision, floating-point values of a and b. +// +// r0 := a0 - b0 +// r1 := a1 - b1 +// r2 := a2 - b2 +// r3 := a3 - b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/1zad2k61(v=vs.100).aspx +FORCE_INLINE __m128 _mm_sub_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_f32( + vsubq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} -// Shuffles the lower 4 signed or unsigned 16-bit integers in a as specified -// by imm. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/y41dkk37(v=vs.100) -// FORCE_INLINE __m128i _mm_shufflelo_epi16_function(__m128i a, -// __constrange(0,255) int -// imm) -#define _mm_shufflelo_epi16_function(a, imm) \ - __extension__({ \ - int16x8_t ret = vreinterpretq_s16_m128i(a); \ - int16x4_t lowBits = vget_low_s16(ret); \ - ret = vsetq_lane_s16(vget_lane_s16(lowBits, (imm) & (0x3)), ret, 0); \ - ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 2) & 0x3), ret, \ - 1); \ - ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 4) & 0x3), ret, \ - 2); \ - ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 6) & 0x3), ret, \ - 3); \ - vreinterpretq_m128i_s16(ret); \ - }) +// Subtract the lower single-precision (32-bit) floating-point element in b from +// the lower single-precision (32-bit) floating-point element in a, store the +// result in the lower element of dst, and copy the upper 3 packed elements from +// a to the upper elements of dst. +// +// dst[31:0] := a[31:0] - b[31:0] +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_ss +FORCE_INLINE __m128 _mm_sub_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_sub_ps(a, b)); +} -// FORCE_INLINE __m128i _mm_shufflelo_epi16(__m128i a, -// __constrange(0,255) int imm) -#if __has_builtin(__builtin_shufflevector) -#define _mm_shufflelo_epi16(a, imm) \ - __extension__({ \ - int16x8_t _input = vreinterpretq_s16_m128i(a); \ - int16x8_t _shuf = __builtin_shufflevector( \ - _input, _input, ((imm) & (0x3)), (((imm) >> 2) & 0x3), \ - (((imm) >> 4) & 0x3), (((imm) >> 6) & 0x3), 4, 5, 6, 7); \ - vreinterpretq_m128i_s16(_shuf); \ - }) -#else // generic -#define _mm_shufflelo_epi16(a, imm) _mm_shufflelo_epi16_function((a), (imm)) -#endif +// Macro: Transpose the 4x4 matrix formed by the 4 rows of single-precision +// (32-bit) floating-point elements in row0, row1, row2, and row3, and store the +// transposed matrix in these vectors (row0 now contains column 0, etc.). +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=MM_TRANSPOSE4_PS +#define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \ + do { \ + float32x4x2_t ROW01 = vtrnq_f32(row0, row1); \ + float32x4x2_t ROW23 = vtrnq_f32(row2, row3); \ + row0 = vcombine_f32(vget_low_f32(ROW01.val[0]), \ + vget_low_f32(ROW23.val[0])); \ + row1 = vcombine_f32(vget_low_f32(ROW01.val[1]), \ + vget_low_f32(ROW23.val[1])); \ + row2 = vcombine_f32(vget_high_f32(ROW01.val[0]), \ + vget_high_f32(ROW23.val[0])); \ + row3 = vcombine_f32(vget_high_f32(ROW01.val[1]), \ + vget_high_f32(ROW23.val[1])); \ + } while (0) -// Shuffles the upper 4 signed or unsigned 16-bit integers in a as specified -// by imm. -// https://msdn.microsoft.com/en-us/library/13ywktbs(v=vs.100).aspx -// FORCE_INLINE __m128i _mm_shufflehi_epi16_function(__m128i a, -// __constrange(0,255) int -// imm) -#define _mm_shufflehi_epi16_function(a, imm) \ - __extension__({ \ - int16x8_t ret = vreinterpretq_s16_m128i(a); \ - int16x4_t highBits = vget_high_s16(ret); \ - ret = vsetq_lane_s16(vget_lane_s16(highBits, (imm) & (0x3)), ret, 4); \ - ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 2) & 0x3), ret, \ - 5); \ - ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 4) & 0x3), ret, \ - 6); \ - ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 6) & 0x3), ret, \ - 7); \ - vreinterpretq_m128i_s16(ret); \ - }) +// according to the documentation, these intrinsics behave the same as the +// non-'u' versions. We'll just alias them here. +#define _mm_ucomieq_ss _mm_comieq_ss +#define _mm_ucomige_ss _mm_comige_ss +#define _mm_ucomigt_ss _mm_comigt_ss +#define _mm_ucomile_ss _mm_comile_ss +#define _mm_ucomilt_ss _mm_comilt_ss +#define _mm_ucomineq_ss _mm_comineq_ss -// FORCE_INLINE __m128i _mm_shufflehi_epi16(__m128i a, -// __constrange(0,255) int imm) -#if __has_builtin(__builtin_shufflevector) -#define _mm_shufflehi_epi16(a, imm) \ - __extension__({ \ - int16x8_t _input = vreinterpretq_s16_m128i(a); \ - int16x8_t _shuf = __builtin_shufflevector( \ - _input, _input, 0, 1, 2, 3, ((imm) & (0x3)) + 4, \ - (((imm) >> 2) & 0x3) + 4, (((imm) >> 4) & 0x3) + 4, \ - (((imm) >> 6) & 0x3) + 4); \ - vreinterpretq_m128i_s16(_shuf); \ - }) -#else // generic -#define _mm_shufflehi_epi16(a, imm) _mm_shufflehi_epi16_function((a), (imm)) +// Return vector of type __m128i with undefined elements. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_undefined_si128 +FORCE_INLINE __m128i _mm_undefined_si128(void) +{ +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wuninitialized" #endif + __m128i a; + return a; +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif +} -// Shuffle double-precision (64-bit) floating-point elements using the control -// in imm8, and store the results in dst. +// Return vector of type __m128 with undefined elements. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_undefined_ps +FORCE_INLINE __m128 _mm_undefined_ps(void) +{ +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wuninitialized" +#endif + __m128 a; + return a; +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif +} + +// Selects and interleaves the upper two single-precision, floating-point values +// from a and b. // -// dst[63:0] := (imm8[0] == 0) ? a[63:0] : a[127:64] -// dst[127:64] := (imm8[1] == 0) ? b[63:0] : b[127:64] +// r0 := a2 +// r1 := b2 +// r2 := a3 +// r3 := b3 // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_pd -#if __has_builtin(__builtin_shufflevector) -#define _mm_shuffle_pd(a, b, imm8) \ - vreinterpretq_m128d_s64(__builtin_shufflevector( \ - vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b), imm8 & 0x1, \ - ((imm8 & 0x2) >> 1) + 2)) +// https://msdn.microsoft.com/en-us/library/skccxx7d%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_unpackhi_ps(__m128 a, __m128 b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32( + vzip2q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); #else -#define _mm_shuffle_pd(a, b, imm8) \ - _mm_castsi128_pd(_mm_set_epi64x( \ - vgetq_lane_s64(vreinterpretq_s64_m128d(b), (imm8 & 0x2) >> 1), \ - vgetq_lane_s64(vreinterpretq_s64_m128d(a), imm8 & 0x1))) + float32x2_t a1 = vget_high_f32(vreinterpretq_f32_m128(a)); + float32x2_t b1 = vget_high_f32(vreinterpretq_f32_m128(b)); + float32x2x2_t result = vzip_f32(a1, b1); + return vreinterpretq_m128_f32(vcombine_f32(result.val[0], result.val[1])); #endif +} -// Blend packed 16-bit integers from a and b using control mask imm8, and store -// the results in dst. +// Selects and interleaves the lower two single-precision, floating-point values +// from a and b. // -// FOR j := 0 to 7 -// i := j*16 -// IF imm8[j] -// dst[i+15:i] := b[i+15:i] -// ELSE -// dst[i+15:i] := a[i+15:i] -// FI -// ENDFOR -// FORCE_INLINE __m128i _mm_blend_epi16(__m128i a, __m128i b, -// __constrange(0,255) int imm) -#define _mm_blend_epi16(a, b, imm) \ - __extension__({ \ - const uint16_t _mask[8] = {((imm) & (1 << 0)) ? 0xFFFF : 0x0000, \ - ((imm) & (1 << 1)) ? 0xFFFF : 0x0000, \ - ((imm) & (1 << 2)) ? 0xFFFF : 0x0000, \ - ((imm) & (1 << 3)) ? 0xFFFF : 0x0000, \ - ((imm) & (1 << 4)) ? 0xFFFF : 0x0000, \ - ((imm) & (1 << 5)) ? 0xFFFF : 0x0000, \ - ((imm) & (1 << 6)) ? 0xFFFF : 0x0000, \ - ((imm) & (1 << 7)) ? 0xFFFF : 0x0000}; \ - uint16x8_t _mask_vec = vld1q_u16(_mask); \ - uint16x8_t _a = vreinterpretq_u16_m128i(a); \ - uint16x8_t _b = vreinterpretq_u16_m128i(b); \ - vreinterpretq_m128i_u16(vbslq_u16(_mask_vec, _b, _a)); \ - }) - -// Blend packed 8-bit integers from a and b using mask, and store the results in -// dst. +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 // -// FOR j := 0 to 15 -// i := j*8 -// IF mask[i+7] -// dst[i+7:i] := b[i+7:i] -// ELSE -// dst[i+7:i] := a[i+7:i] -// FI -// ENDFOR -FORCE_INLINE __m128i _mm_blendv_epi8(__m128i _a, __m128i _b, __m128i _mask) +// https://msdn.microsoft.com/en-us/library/25st103b%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_unpacklo_ps(__m128 a, __m128 b) { - // Use a signed shift right to create a mask with the sign bit - uint8x16_t mask = - vreinterpretq_u8_s8(vshrq_n_s8(vreinterpretq_s8_m128i(_mask), 7)); - uint8x16_t a = vreinterpretq_u8_m128i(_a); - uint8x16_t b = vreinterpretq_u8_m128i(_b); - return vreinterpretq_m128i_u8(vbslq_u8(mask, b, a)); +#if defined(__aarch64__) + return vreinterpretq_m128_f32( + vzip1q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#else + float32x2_t a1 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32x2_t b1 = vget_low_f32(vreinterpretq_f32_m128(b)); + float32x2x2_t result = vzip_f32(a1, b1); + return vreinterpretq_m128_f32(vcombine_f32(result.val[0], result.val[1])); +#endif } -/* Shifts */ +// Computes bitwise EXOR (exclusive-or) of the four single-precision, +// floating-point values of a and b. +// https://msdn.microsoft.com/en-us/library/ss6k3wk8(v=vs.100).aspx +FORCE_INLINE __m128 _mm_xor_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_s32( + veorq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); +} +/* SSE2 */ -// Shift packed 16-bit integers in a right by imm while shifting in sign -// bits, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srai_epi16 -FORCE_INLINE __m128i _mm_srai_epi16(__m128i a, int imm) +// Adds the 8 signed or unsigned 16-bit integers in a to the 8 signed or +// unsigned 16-bit integers in b. +// https://msdn.microsoft.com/en-us/library/fceha5k4(v=vs.100).aspx +FORCE_INLINE __m128i _mm_add_epi16(__m128i a, __m128i b) { - const int count = (imm & ~15) ? 15 : imm; - return (__m128i) vshlq_s16((int16x8_t) a, vdupq_n_s16(-count)); + return vreinterpretq_m128i_s16( + vaddq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); } -// Shifts the 8 signed or unsigned 16-bit integers in a left by count bits while -// shifting in zeros. +// Adds the 4 signed or unsigned 32-bit integers in a to the 4 signed or +// unsigned 32-bit integers in b. // -// r0 := a0 << count -// r1 := a1 << count -// ... -// r7 := a7 << count +// r0 := a0 + b0 +// r1 := a1 + b1 +// r2 := a2 + b2 +// r3 := a3 + b3 // -// https://msdn.microsoft.com/en-us/library/es73bcsy(v=vs.90).aspx -#define _mm_slli_epi16(a, imm) \ - __extension__({ \ - __m128i ret; \ - if (unlikely((imm)) <= 0) { \ - ret = a; \ - } \ - if (unlikely((imm) > 15)) { \ - ret = _mm_setzero_si128(); \ - } else { \ - ret = vreinterpretq_m128i_s16( \ - vshlq_n_s16(vreinterpretq_s16_m128i(a), (imm))); \ - } \ - ret; \ - }) - -// Shifts the 4 signed or unsigned 32-bit integers in a left by count bits while -// shifting in zeros. : -// https://msdn.microsoft.com/en-us/library/z2k3bbtb%28v=vs.90%29.aspx -// FORCE_INLINE __m128i _mm_slli_epi32(__m128i a, __constrange(0,255) int imm) -FORCE_INLINE __m128i _mm_slli_epi32(__m128i a, int imm) +// https://msdn.microsoft.com/en-us/library/vstudio/09xs4fkk(v=vs.100).aspx +FORCE_INLINE __m128i _mm_add_epi32(__m128i a, __m128i b) { - if (unlikely(imm <= 0)) /* TODO: add constant range macro: [0, 255] */ - return a; - if (unlikely(imm > 31)) - return _mm_setzero_si128(); return vreinterpretq_m128i_s32( - vshlq_s32(vreinterpretq_s32_m128i(a), vdupq_n_s32(imm))); + vaddq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); } -// Shift packed 64-bit integers in a left by imm8 while shifting in zeros, and -// store the results in dst. -FORCE_INLINE __m128i _mm_slli_epi64(__m128i a, int imm) +// Adds the 4 signed or unsigned 64-bit integers in a to the 4 signed or +// unsigned 32-bit integers in b. +// https://msdn.microsoft.com/en-us/library/vstudio/09xs4fkk(v=vs.100).aspx +FORCE_INLINE __m128i _mm_add_epi64(__m128i a, __m128i b) { - if (unlikely(imm <= 0)) /* TODO: add constant range macro: [0, 255] */ - return a; - if (unlikely(imm > 63)) - return _mm_setzero_si128(); return vreinterpretq_m128i_s64( - vshlq_s64(vreinterpretq_s64_m128i(a), vdupq_n_s64(imm))); + vaddq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); } -// Shift packed 16-bit integers in a right by imm8 while shifting in zeros, and +// Adds the 16 signed or unsigned 8-bit integers in a to the 16 signed or +// unsigned 8-bit integers in b. +// https://technet.microsoft.com/en-us/subscriptions/yc7tcyzs(v=vs.90) +FORCE_INLINE __m128i _mm_add_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vaddq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Add packed double-precision (64-bit) floating-point elements in a and b, and // store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_pd +FORCE_INLINE __m128d _mm_add_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vaddq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[2]; + c[0] = da[0] + db[0]; + c[1] = da[1] + db[1]; + return vld1q_f32((float32_t *) c); +#endif +} + +// Add the lower double-precision (64-bit) floating-point element in a and b, +// store the result in the lower element of dst, and copy the upper element from +// a to the upper element of dst. // -// FOR j := 0 to 7 -// i := j*16 -// IF imm8[7:0] > 15 -// dst[i+15:i] := 0 -// ELSE -// dst[i+15:i] := ZeroExtend16(a[i+15:i] >> imm8[7:0]) -// FI -// ENDFOR +// dst[63:0] := a[63:0] + b[63:0] +// dst[127:64] := a[127:64] // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi16 -#define _mm_srli_epi16(a, imm) \ - __extension__({ \ - __m128i ret; \ - if (unlikely(imm) == 0) { \ - ret = a; \ - } \ - if (likely(0 < (imm) && (imm) < 16)) { \ - ret = vreinterpretq_m128i_u16( \ - vshlq_u16(vreinterpretq_u16_m128i(a), vdupq_n_s16(-imm))); \ - } else { \ - ret = _mm_setzero_si128(); \ - } \ - ret; \ - }) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_sd +FORCE_INLINE __m128d _mm_add_sd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return _mm_move_sd(a, _mm_add_pd(a, b)); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[2]; + c[0] = da[0] + db[0]; + c[1] = da[1]; + return vld1q_f32((float32_t *) c); +#endif +} -// Shift packed 32-bit integers in a right by imm8 while shifting in zeros, and -// store the results in dst. +// Add 64-bit integers a and b, and store the result in dst. // -// FOR j := 0 to 3 -// i := j*32 -// IF imm8[7:0] > 31 -// dst[i+31:i] := 0 -// ELSE -// dst[i+31:i] := ZeroExtend32(a[i+31:i] >> imm8[7:0]) -// FI -// ENDFOR +// dst[63:0] := a[63:0] + b[63:0] // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi32 -// FORCE_INLINE __m128i _mm_srli_epi32(__m128i a, __constrange(0,255) int imm) -#define _mm_srli_epi32(a, imm) \ - __extension__({ \ - __m128i ret; \ - if (unlikely((imm) == 0)) { \ - ret = a; \ - } \ - if (likely(0 < (imm) && (imm) < 32)) { \ - ret = vreinterpretq_m128i_u32( \ - vshlq_u32(vreinterpretq_u32_m128i(a), vdupq_n_s32(-imm))); \ - } else { \ - ret = _mm_setzero_si128(); \ - } \ - ret; \ - }) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_si64 +FORCE_INLINE __m64 _mm_add_si64(__m64 a, __m64 b) +{ + return vreinterpret_m64_s64( + vadd_s64(vreinterpret_s64_m64(a), vreinterpret_s64_m64(b))); +} -// Shift packed 64-bit integers in a right by imm8 while shifting in zeros, and -// store the results in dst. +// Adds the 8 signed 16-bit integers in a to the 8 signed 16-bit integers in b +// and saturates. // -// FOR j := 0 to 1 -// i := j*64 -// IF imm8[7:0] > 63 -// dst[i+63:i] := 0 -// ELSE -// dst[i+63:i] := ZeroExtend64(a[i+63:i] >> imm8[7:0]) -// FI -// ENDFOR +// r0 := SignedSaturate(a0 + b0) +// r1 := SignedSaturate(a1 + b1) +// ... +// r7 := SignedSaturate(a7 + b7) // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi64 -#define _mm_srli_epi64(a, imm) \ - __extension__({ \ - __m128i ret; \ - if (unlikely((imm) == 0)) { \ - ret = a; \ - } \ - if (likely(0 < (imm) && (imm) < 64)) { \ - ret = vreinterpretq_m128i_u64( \ - vshlq_u64(vreinterpretq_u64_m128i(a), vdupq_n_s64(-imm))); \ - } else { \ - ret = _mm_setzero_si128(); \ - } \ - ret; \ - }) +// https://msdn.microsoft.com/en-us/library/1a306ef8(v=vs.100).aspx +FORCE_INLINE __m128i _mm_adds_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vqaddq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} -// Shift packed 32-bit integers in a right by imm8 while shifting in sign bits, -// and store the results in dst. +// Add packed signed 8-bit integers in a and b using saturation, and store the +// results in dst. // -// FOR j := 0 to 3 -// i := j*32 -// IF imm8[7:0] > 31 -// dst[i+31:i] := (a[i+31] ? 0xFFFFFFFF : 0x0) -// ELSE -// dst[i+31:i] := SignExtend32(a[i+31:i] >> imm8[7:0]) -// FI +// FOR j := 0 to 15 +// i := j*8 +// dst[i+7:i] := Saturate8( a[i+7:i] + b[i+7:i] ) // ENDFOR // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srai_epi32 -// FORCE_INLINE __m128i _mm_srai_epi32(__m128i a, __constrange(0,255) int imm) -#define _mm_srai_epi32(a, imm) \ - __extension__({ \ - __m128i ret; \ - if (unlikely((imm) == 0)) { \ - ret = a; \ - } \ - if (likely(0 < (imm) && (imm) < 32)) { \ - ret = vreinterpretq_m128i_s32( \ - vshlq_s32(vreinterpretq_s32_m128i(a), vdupq_n_s32(-imm))); \ - } else { \ - ret = vreinterpretq_m128i_s32( \ - vshrq_n_s32(vreinterpretq_s32_m128i(a), 31)); \ - } \ - ret; \ - }) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_adds_epi8 +FORCE_INLINE __m128i _mm_adds_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vqaddq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} -// Shifts the 128 - bit value in a right by imm bytes while shifting in -// zeros.imm must be an immediate. -// -// r := srl(a, imm*8) -// -// https://msdn.microsoft.com/en-us/library/305w28yz(v=vs.100).aspx -// FORCE_INLINE _mm_srli_si128(__m128i a, __constrange(0,255) int imm) -#define _mm_srli_si128(a, imm) \ - __extension__({ \ - __m128i ret; \ - if (unlikely((imm) <= 0)) { \ - ret = a; \ - } \ - if (unlikely((imm) > 15)) { \ - ret = _mm_setzero_si128(); \ - } else { \ - ret = vreinterpretq_m128i_s8( \ - vextq_s8(vreinterpretq_s8_m128i(a), vdupq_n_s8(0), (imm))); \ - } \ - ret; \ - }) +// Add packed unsigned 16-bit integers in a and b using saturation, and store +// the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_adds_epu16 +FORCE_INLINE __m128i _mm_adds_epu16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vqaddq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); +} -// Shifts the 128-bit value in a left by imm bytes while shifting in zeros. imm -// must be an immediate. -// -// r := a << (imm * 8) -// -// https://msdn.microsoft.com/en-us/library/34d3k2kt(v=vs.100).aspx -// FORCE_INLINE __m128i _mm_slli_si128(__m128i a, __constrange(0,255) int imm) -#define _mm_slli_si128(a, imm) \ - __extension__({ \ - __m128i ret; \ - if (unlikely((imm) <= 0)) { \ - ret = a; \ - } \ - if (unlikely((imm) > 15)) { \ - ret = _mm_setzero_si128(); \ - } else { \ - ret = vreinterpretq_m128i_s8(vextq_s8( \ - vdupq_n_s8(0), vreinterpretq_s8_m128i(a), 16 - (imm))); \ - } \ - ret; \ - }) +// Adds the 16 unsigned 8-bit integers in a to the 16 unsigned 8-bit integers in +// b and saturates.. +// https://msdn.microsoft.com/en-us/library/9hahyddy(v=vs.100).aspx +FORCE_INLINE __m128i _mm_adds_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vqaddq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} -// Shifts the 8 signed or unsigned 16-bit integers in a left by count bits while -// shifting in zeros. +// Compute the bitwise AND of packed double-precision (64-bit) floating-point +// elements in a and b, and store the results in dst. // -// r0 := a0 << count -// r1 := a1 << count -// ... -// r7 := a7 << count +// FOR j := 0 to 1 +// i := j*64 +// dst[i+63:i] := a[i+63:i] AND b[i+63:i] +// ENDFOR // -// https://msdn.microsoft.com/en-us/library/c79w388h(v%3dvs.90).aspx -FORCE_INLINE __m128i _mm_sll_epi16(__m128i a, __m128i count) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_and_pd +FORCE_INLINE __m128d _mm_and_pd(__m128d a, __m128d b) { - uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); - if (unlikely(c > 15)) - return _mm_setzero_si128(); - - int16x8_t vc = vdupq_n_s16((int16_t) c); - return vreinterpretq_m128i_s16(vshlq_s16(vreinterpretq_s16_m128i(a), vc)); + return vreinterpretq_m128d_s64( + vandq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b))); } -// Shifts the 4 signed or unsigned 32-bit integers in a left by count bits while -// shifting in zeros. +// Computes the bitwise AND of the 128-bit value in a and the 128-bit value in +// b. // -// r0 := a0 << count -// r1 := a1 << count -// r2 := a2 << count -// r3 := a3 << count +// r := a & b // -// https://msdn.microsoft.com/en-us/library/6fe5a6s9(v%3dvs.90).aspx -FORCE_INLINE __m128i _mm_sll_epi32(__m128i a, __m128i count) +// https://msdn.microsoft.com/en-us/library/vstudio/6d1txsa8(v=vs.100).aspx +FORCE_INLINE __m128i _mm_and_si128(__m128i a, __m128i b) { - uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); - if (unlikely(c > 31)) - return _mm_setzero_si128(); - - int32x4_t vc = vdupq_n_s32((int32_t) c); - return vreinterpretq_m128i_s32(vshlq_s32(vreinterpretq_s32_m128i(a), vc)); + return vreinterpretq_m128i_s32( + vandq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); } -// Shifts the 2 signed or unsigned 64-bit integers in a left by count bits while -// shifting in zeros. +// Compute the bitwise NOT of packed double-precision (64-bit) floating-point +// elements in a and then AND with b, and store the results in dst. // -// r0 := a0 << count -// r1 := a1 << count +// FOR j := 0 to 1 +// i := j*64 +// dst[i+63:i] := ((NOT a[i+63:i]) AND b[i+63:i]) +// ENDFOR // -// https://msdn.microsoft.com/en-us/library/6ta9dffd(v%3dvs.90).aspx -FORCE_INLINE __m128i _mm_sll_epi64(__m128i a, __m128i count) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_andnot_pd +FORCE_INLINE __m128d _mm_andnot_pd(__m128d a, __m128d b) { - uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); - if (unlikely(c > 63)) - return _mm_setzero_si128(); - - int64x2_t vc = vdupq_n_s64((int64_t) c); - return vreinterpretq_m128i_s64(vshlq_s64(vreinterpretq_s64_m128i(a), vc)); + // *NOTE* argument swap + return vreinterpretq_m128d_s64( + vbicq_s64(vreinterpretq_s64_m128d(b), vreinterpretq_s64_m128d(a))); } -// Shifts the 8 signed or unsigned 16-bit integers in a right by count bits -// while shifting in zeros. +// Computes the bitwise AND of the 128-bit value in b and the bitwise NOT of the +// 128-bit value in a. // -// r0 := srl(a0, count) -// r1 := srl(a1, count) -// ... -// r7 := srl(a7, count) +// r := (~a) & b // -// https://msdn.microsoft.com/en-us/library/wd5ax830(v%3dvs.90).aspx -FORCE_INLINE __m128i _mm_srl_epi16(__m128i a, __m128i count) +// https://msdn.microsoft.com/en-us/library/vstudio/1beaceh8(v=vs.100).aspx +FORCE_INLINE __m128i _mm_andnot_si128(__m128i a, __m128i b) { - uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); - if (unlikely(c > 15)) - return _mm_setzero_si128(); - - int16x8_t vc = vdupq_n_s16(-(int16_t) c); - return vreinterpretq_m128i_u16(vshlq_u16(vreinterpretq_u16_m128i(a), vc)); + return vreinterpretq_m128i_s32( + vbicq_s32(vreinterpretq_s32_m128i(b), + vreinterpretq_s32_m128i(a))); // *NOTE* argument swap } -// Shifts the 4 signed or unsigned 32-bit integers in a right by count bits -// while shifting in zeros. +// Computes the average of the 8 unsigned 16-bit integers in a and the 8 +// unsigned 16-bit integers in b and rounds. // -// r0 := srl(a0, count) -// r1 := srl(a1, count) -// r2 := srl(a2, count) -// r3 := srl(a3, count) +// r0 := (a0 + b0) / 2 +// r1 := (a1 + b1) / 2 +// ... +// r7 := (a7 + b7) / 2 // -// https://msdn.microsoft.com/en-us/library/a9cbttf4(v%3dvs.90).aspx -FORCE_INLINE __m128i _mm_srl_epi32(__m128i a, __m128i count) +// https://msdn.microsoft.com/en-us/library/vstudio/y13ca3c8(v=vs.90).aspx +FORCE_INLINE __m128i _mm_avg_epu16(__m128i a, __m128i b) { - uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); - if (unlikely(c > 31)) - return _mm_setzero_si128(); - - int32x4_t vc = vdupq_n_s32(-(int32_t) c); - return vreinterpretq_m128i_u32(vshlq_u32(vreinterpretq_u32_m128i(a), vc)); + return (__m128i) vrhaddq_u16(vreinterpretq_u16_m128i(a), + vreinterpretq_u16_m128i(b)); } -// Shifts the 2 signed or unsigned 64-bit integers in a right by count bits -// while shifting in zeros. +// Computes the average of the 16 unsigned 8-bit integers in a and the 16 +// unsigned 8-bit integers in b and rounds. // -// r0 := srl(a0, count) -// r1 := srl(a1, count) +// r0 := (a0 + b0) / 2 +// r1 := (a1 + b1) / 2 +// ... +// r15 := (a15 + b15) / 2 // -// https://msdn.microsoft.com/en-us/library/yf6cf9k8(v%3dvs.90).aspx -FORCE_INLINE __m128i _mm_srl_epi64(__m128i a, __m128i count) +// https://msdn.microsoft.com/en-us/library/vstudio/8zwh554a(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_avg_epu8(__m128i a, __m128i b) { - uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); - if (unlikely(c > 63)) - return _mm_setzero_si128(); - - int64x2_t vc = vdupq_n_s64(-(int64_t) c); - return vreinterpretq_m128i_u64(vshlq_u64(vreinterpretq_u64_m128i(a), vc)); + return vreinterpretq_m128i_u8( + vrhaddq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); } -// NEON does not provide a version of this function. -// Creates a 16-bit mask from the most significant bits of the 16 signed or -// unsigned 8-bit integers in a and zero extends the upper bits. -// https://msdn.microsoft.com/en-us/library/vstudio/s090c8fk(v=vs.100).aspx -FORCE_INLINE int _mm_movemask_epi8(__m128i a) -{ - // Use increasingly wide shifts+adds to collect the sign bits - // together. - // Since the widening shifts would be rather confusing to follow in little - // endian, everything will be illustrated in big endian order instead. This - // has a different result - the bits would actually be reversed on a big - // endian machine. - - // Starting input (only half the elements are shown): - // 89 ff 1d c0 00 10 99 33 - uint8x16_t input = vreinterpretq_u8_m128i(a); - - // Shift out everything but the sign bits with an unsigned shift right. - // - // Bytes of the vector:: - // 89 ff 1d c0 00 10 99 33 - // \ \ \ \ \ \ \ \ high_bits = (uint16x4_t)(input >> 7) - // | | | | | | | | - // 01 01 00 01 00 00 01 00 - // - // Bits of first important lane(s): - // 10001001 (89) - // \______ - // | - // 00000001 (01) - uint16x8_t high_bits = vreinterpretq_u16_u8(vshrq_n_u8(input, 7)); - - // Merge the even lanes together with a 16-bit unsigned shift right + add. - // 'xx' represents garbage data which will be ignored in the final result. - // In the important bytes, the add functions like a binary OR. - // - // 01 01 00 01 00 00 01 00 - // \_ | \_ | \_ | \_ | paired16 = (uint32x4_t)(input + (input >> 7)) - // \| \| \| \| - // xx 03 xx 01 xx 00 xx 02 - // - // 00000001 00000001 (01 01) - // \_______ | - // \| - // xxxxxxxx xxxxxx11 (xx 03) - uint32x4_t paired16 = - vreinterpretq_u32_u16(vsraq_n_u16(high_bits, high_bits, 7)); +// Shift a left by imm8 bytes while shifting in zeros, and store the results in +// dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_bslli_si128 +#define _mm_bslli_si128(a, imm) _mm_slli_si128(a, imm) - // Repeat with a wider 32-bit shift + add. - // xx 03 xx 01 xx 00 xx 02 - // \____ | \____ | paired32 = (uint64x1_t)(paired16 + (paired16 >> - // 14)) - // \| \| - // xx xx xx 0d xx xx xx 02 - // - // 00000011 00000001 (03 01) - // \\_____ || - // '----.\|| - // xxxxxxxx xxxx1101 (xx 0d) - uint64x2_t paired32 = - vreinterpretq_u64_u32(vsraq_n_u32(paired16, paired16, 14)); +// Shift a right by imm8 bytes while shifting in zeros, and store the results in +// dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_bsrli_si128 +#define _mm_bsrli_si128(a, imm) _mm_srli_si128(a, imm) - // Last, an even wider 64-bit shift + add to get our result in the low 8 bit - // lanes. xx xx xx 0d xx xx xx 02 - // \_________ | paired64 = (uint8x8_t)(paired32 + (paired32 >> - // 28)) - // \| - // xx xx xx xx xx xx xx d2 - // - // 00001101 00000010 (0d 02) - // \ \___ | | - // '---. \| | - // xxxxxxxx 11010010 (xx d2) - uint8x16_t paired64 = - vreinterpretq_u8_u64(vsraq_n_u64(paired32, paired32, 28)); +// Cast vector of type __m128d to type __m128. This intrinsic is only used for +// compilation and does not generate any instructions, thus it has zero latency. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castpd_ps +FORCE_INLINE __m128 _mm_castpd_ps(__m128d a) +{ + return vreinterpretq_m128_s64(vreinterpretq_s64_m128d(a)); +} - // Extract the low 8 bits from each 64-bit lane with 2 8-bit extracts. - // xx xx xx xx xx xx xx d2 - // || return paired64[0] - // d2 - // Note: Little endian would return the correct value 4b (01001011) instead. - return vgetq_lane_u8(paired64, 0) | ((int) vgetq_lane_u8(paired64, 8) << 8); +// Cast vector of type __m128d to type __m128i. This intrinsic is only used for +// compilation and does not generate any instructions, thus it has zero latency. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castpd_si128 +FORCE_INLINE __m128i _mm_castpd_si128(__m128d a) +{ + return vreinterpretq_m128i_s64(vreinterpretq_s64_m128d(a)); } -// Copy the lower 64-bit integer in a to dst. -// -// dst[63:0] := a[63:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movepi64_pi64 -FORCE_INLINE __m64 _mm_movepi64_pi64(__m128i a) +// Cast vector of type __m128 to type __m128d. This intrinsic is only used for +// compilation and does not generate any instructions, thus it has zero latency. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castps_pd +FORCE_INLINE __m128d _mm_castps_pd(__m128 a) { - return vreinterpret_m64_s64(vget_low_s64(vreinterpretq_s64_m128i(a))); + return vreinterpretq_m128d_s32(vreinterpretq_s32_m128(a)); } -// Copy the 64-bit integer a to the lower element of dst, and zero the upper -// element. -// -// dst[63:0] := a[63:0] -// dst[127:64] := 0 -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movpi64_epi64 -FORCE_INLINE __m128i _mm_movpi64_epi64(__m64 a) +// Applies a type cast to reinterpret four 32-bit floating point values passed +// in as a 128-bit parameter as packed 32-bit integers. +// https://msdn.microsoft.com/en-us/library/bb514099.aspx +FORCE_INLINE __m128i _mm_castps_si128(__m128 a) { - return vreinterpretq_m128i_s64( - vcombine_s64(vreinterpret_s64_m64(a), vdup_n_s64(0))); + return vreinterpretq_m128i_s32(vreinterpretq_s32_m128(a)); } -// NEON does not provide this method -// Creates a 4-bit mask from the most significant bits of the four -// single-precision, floating-point values. -// https://msdn.microsoft.com/en-us/library/vstudio/4490ys29(v=vs.100).aspx -FORCE_INLINE int _mm_movemask_ps(__m128 a) +// Cast vector of type __m128i to type __m128d. This intrinsic is only used for +// compilation and does not generate any instructions, thus it has zero latency. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castsi128_pd +FORCE_INLINE __m128d _mm_castsi128_pd(__m128i a) { - uint32x4_t input = vreinterpretq_u32_m128(a); #if defined(__aarch64__) - static const int32x4_t shift = {0, 1, 2, 3}; - uint32x4_t tmp = vshrq_n_u32(input, 31); - return vaddvq_u32(vshlq_u32(tmp, shift)); + return vreinterpretq_m128d_f64(vreinterpretq_f64_m128i(a)); #else - // Uses the exact same method as _mm_movemask_epi8, see that for details. - // Shift out everything but the sign bits with a 32-bit unsigned shift - // right. - uint64x2_t high_bits = vreinterpretq_u64_u32(vshrq_n_u32(input, 31)); - // Merge the two pairs together with a 64-bit unsigned shift right + add. - uint8x16_t paired = - vreinterpretq_u8_u64(vsraq_n_u64(high_bits, high_bits, 31)); - // Extract the result. - return vgetq_lane_u8(paired, 0) | (vgetq_lane_u8(paired, 8) << 2); + return vreinterpretq_m128d_f32(vreinterpretq_f32_m128i(a)); #endif } -// Compute the bitwise NOT of a and then AND with a 128-bit vector containing -// all 1's, and return 1 if the result is zero, otherwise return 0. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_test_all_ones -FORCE_INLINE int _mm_test_all_ones(__m128i a) +// Applies a type cast to reinterpret four 32-bit integers passed in as a +// 128-bit parameter as packed 32-bit floating point values. +// https://msdn.microsoft.com/en-us/library/bb514029.aspx +FORCE_INLINE __m128 _mm_castsi128_ps(__m128i a) { - return (uint64_t)(vgetq_lane_s64(a, 0) & vgetq_lane_s64(a, 1)) == - ~(uint64_t) 0; + return vreinterpretq_m128_s32(vreinterpretq_s32_m128i(a)); } -// Compute the bitwise AND of 128 bits (representing integer data) in a and -// mask, and return 1 if the result is zero, otherwise return 0. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_test_all_zeros -FORCE_INLINE int _mm_test_all_zeros(__m128i a, __m128i mask) +// Cache line containing p is flushed and invalidated from all caches in the +// coherency domain. : +// https://msdn.microsoft.com/en-us/library/ba08y07y(v=vs.100).aspx +FORCE_INLINE void _mm_clflush(void const *p) { - int64x2_t a_and_mask = - vandq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(mask)); - return (vgetq_lane_s64(a_and_mask, 0) | vgetq_lane_s64(a_and_mask, 1)) ? 0 - : 1; + (void) p; + // no corollary for Neon? } -/* Math operations */ +// Compares the 8 signed or unsigned 16-bit integers in a and the 8 signed or +// unsigned 16-bit integers in b for equality. +// https://msdn.microsoft.com/en-us/library/2ay060te(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpeq_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vceqq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} -// Subtracts the four single-precision, floating-point values of a and b. -// -// r0 := a0 - b0 -// r1 := a1 - b1 -// r2 := a2 - b2 -// r3 := a3 - b3 -// -// https://msdn.microsoft.com/en-us/library/vstudio/1zad2k61(v=vs.100).aspx -FORCE_INLINE __m128 _mm_sub_ps(__m128 a, __m128 b) +// Compare packed 32-bit integers in a and b for equality, and store the results +// in dst +FORCE_INLINE __m128i _mm_cmpeq_epi32(__m128i a, __m128i b) { - return vreinterpretq_m128_f32( - vsubq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); + return vreinterpretq_m128i_u32( + vceqq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); } -// Subtract the lower single-precision (32-bit) floating-point element in b from -// the lower single-precision (32-bit) floating-point element in a, store the -// result in the lower element of dst, and copy the upper 3 packed elements from -// a to the upper elements of dst. -// -// dst[31:0] := a[31:0] - b[31:0] -// dst[127:32] := a[127:32] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_ss -FORCE_INLINE __m128 _mm_sub_ss(__m128 a, __m128 b) +// Compares the 16 signed or unsigned 8-bit integers in a and the 16 signed or +// unsigned 8-bit integers in b for equality. +// https://msdn.microsoft.com/en-us/library/windows/desktop/bz5xk21a(v=vs.90).aspx +FORCE_INLINE __m128i _mm_cmpeq_epi8(__m128i a, __m128i b) { - return _mm_move_ss(a, _mm_sub_ps(a, b)); + return vreinterpretq_m128i_u8( + vceqq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); } -// Subtract 2 packed 64-bit integers in b from 2 packed 64-bit integers in a, -// and store the results in dst. -// r0 := a0 - b0 -// r1 := a1 - b1 -FORCE_INLINE __m128i _mm_sub_epi64(__m128i a, __m128i b) +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for equality, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpeq_pd +FORCE_INLINE __m128d _mm_cmpeq_pd(__m128d a, __m128d b) { - return vreinterpretq_m128i_s64( - vsubq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); +#if defined(__aarch64__) + return vreinterpretq_m128d_u64( + vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + // (a == b) -> (a_lo == b_lo) && (a_hi == b_hi) + uint32x4_t cmp = + vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(b)); + uint32x4_t swapped = vrev64q_u32(cmp); + return vreinterpretq_m128d_u32(vandq_u32(cmp, swapped)); +#endif } -// Subtracts the 4 signed or unsigned 32-bit integers of b from the 4 signed or -// unsigned 32-bit integers of a. -// -// r0 := a0 - b0 -// r1 := a1 - b1 -// r2 := a2 - b2 -// r3 := a3 - b3 -// -// https://msdn.microsoft.com/en-us/library/vstudio/fhh866h0(v=vs.100).aspx -FORCE_INLINE __m128i _mm_sub_epi32(__m128i a, __m128i b) +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for equality, store the result in the lower element of dst, and copy the +// upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpeq_sd +FORCE_INLINE __m128d _mm_cmpeq_sd(__m128d a, __m128d b) { - return vreinterpretq_m128i_s32( - vsubq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); + return _mm_move_sd(a, _mm_cmpeq_pd(a, b)); } -// Subtract packed 16-bit integers in b from packed 16-bit integers in a, and -// store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_epi16 -FORCE_INLINE __m128i _mm_sub_epi16(__m128i a, __m128i b) +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for greater-than-or-equal, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpge_pd +FORCE_INLINE __m128d _mm_cmpge_pd(__m128d a, __m128d b) { - return vreinterpretq_m128i_s16( - vsubq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +#if defined(__aarch64__) + return vreinterpretq_m128d_u64( + vcgeq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) >= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = (*(double *) &a1) >= (*(double *) &b1) ? ~UINT64_C(0) : UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif } -// Subtract packed 8-bit integers in b from packed 8-bit integers in a, and -// store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_epi8 -FORCE_INLINE __m128i _mm_sub_epi8(__m128i a, __m128i b) +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for greater-than-or-equal, store the result in the lower element of dst, +// and copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpge_sd +FORCE_INLINE __m128d _mm_cmpge_sd(__m128d a, __m128d b) { - return vreinterpretq_m128i_s8( - vsubq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +#if defined(__aarch64__) + return _mm_move_sd(a, _mm_cmpge_pd(a, b)); +#else + // expand "_mm_cmpge_pd()" to reduce unnecessary operations + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) >= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = a1; + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif } -// Subtract 64-bit integer b from 64-bit integer a, and store the result in dst. +// Compares the 8 signed 16-bit integers in a and the 8 signed 16-bit integers +// in b for greater than. // -// dst[63:0] := a[63:0] - b[63:0] +// r0 := (a0 > b0) ? 0xffff : 0x0 +// r1 := (a1 > b1) ? 0xffff : 0x0 +// ... +// r7 := (a7 > b7) ? 0xffff : 0x0 // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_si64 -FORCE_INLINE __m64 _mm_sub_si64(__m64 a, __m64 b) +// https://technet.microsoft.com/en-us/library/xd43yfsa(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpgt_epi16(__m128i a, __m128i b) { - return vreinterpret_m64_s64( - vsub_s64(vreinterpret_s64_m64(a), vreinterpret_s64_m64(b))); + return vreinterpretq_m128i_u16( + vcgtq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); } -// Subtracts the 8 unsigned 16-bit integers of bfrom the 8 unsigned 16-bit -// integers of a and saturates.. -// https://technet.microsoft.com/en-us/subscriptions/index/f44y0s19(v=vs.90).aspx -FORCE_INLINE __m128i _mm_subs_epu16(__m128i a, __m128i b) +// Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers +// in b for greater than. +// https://msdn.microsoft.com/en-us/library/vstudio/1s9f2z0y(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpgt_epi32(__m128i a, __m128i b) { - return vreinterpretq_m128i_u16( - vqsubq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); + return vreinterpretq_m128i_u32( + vcgtq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); } -// Subtracts the 16 unsigned 8-bit integers of b from the 16 unsigned 8-bit -// integers of a and saturates. +// Compares the 16 signed 8-bit integers in a and the 16 signed 8-bit integers +// in b for greater than. // -// r0 := UnsignedSaturate(a0 - b0) -// r1 := UnsignedSaturate(a1 - b1) +// r0 := (a0 > b0) ? 0xff : 0x0 +// r1 := (a1 > b1) ? 0xff : 0x0 // ... -// r15 := UnsignedSaturate(a15 - b15) +// r15 := (a15 > b15) ? 0xff : 0x0 // -// https://technet.microsoft.com/en-us/subscriptions/yadkxc18(v=vs.90) -FORCE_INLINE __m128i _mm_subs_epu8(__m128i a, __m128i b) +// https://msdn.microsoft.com/zh-tw/library/wf45zt2b(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpgt_epi8(__m128i a, __m128i b) { return vreinterpretq_m128i_u8( - vqsubq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); + vcgtq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); } -// Subtracts the 16 signed 8-bit integers of b from the 16 signed 8-bit integers -// of a and saturates. -// -// r0 := SignedSaturate(a0 - b0) -// r1 := SignedSaturate(a1 - b1) -// ... -// r15 := SignedSaturate(a15 - b15) -// -// https://technet.microsoft.com/en-us/subscriptions/by7kzks1(v=vs.90) -FORCE_INLINE __m128i _mm_subs_epi8(__m128i a, __m128i b) +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for greater-than, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpgt_pd +FORCE_INLINE __m128d _mm_cmpgt_pd(__m128d a, __m128d b) { - return vreinterpretq_m128i_s8( - vqsubq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +#if defined(__aarch64__) + return vreinterpretq_m128d_u64( + vcgtq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) > (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = (*(double *) &a1) > (*(double *) &b1) ? ~UINT64_C(0) : UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif } -// Subtracts the 8 signed 16-bit integers of b from the 8 signed 16-bit integers -// of a and saturates. -// -// r0 := SignedSaturate(a0 - b0) -// r1 := SignedSaturate(a1 - b1) -// ... -// r7 := SignedSaturate(a7 - b7) -// -// https://technet.microsoft.com/en-us/subscriptions/3247z5b8(v=vs.90) -FORCE_INLINE __m128i _mm_subs_epi16(__m128i a, __m128i b) +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for greater-than, store the result in the lower element of dst, and copy +// the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpgt_sd +FORCE_INLINE __m128d _mm_cmpgt_sd(__m128d a, __m128d b) { - return vreinterpretq_m128i_s16( - vqsubq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +#if defined(__aarch64__) + return _mm_move_sd(a, _mm_cmpgt_pd(a, b)); +#else + // expand "_mm_cmpge_pd()" to reduce unnecessary operations + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) > (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = a1; + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif } -// Subtract packed double-precision (64-bit) floating-point elements in b from -// packed double-precision (64-bit) floating-point elements in a, and store the -// results in dst. -// -// FOR j := 0 to 1 -// i := j*64 -// dst[i+63:i] := a[i+63:i] - b[i+63:i] -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_sub_pd -FORCE_INLINE __m128d _mm_sub_pd(__m128d a, __m128d b) +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for less-than-or-equal, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmple_pd +FORCE_INLINE __m128d _mm_cmple_pd(__m128d a, __m128d b) { #if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vsubq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); + return vreinterpretq_m128d_u64( + vcleq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); #else - double *da = (double *) &a; - double *db = (double *) &b; - double c[2]; - c[0] = da[0] - db[0]; - c[1] = da[1] - db[1]; - return vld1q_f32((float32_t *) c); + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) <= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = (*(double *) &a1) <= (*(double *) &b1) ? ~UINT64_C(0) : UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); #endif } -// Subtract the lower double-precision (64-bit) floating-point element in b from -// the lower double-precision (64-bit) floating-point element in a, store the -// result in the lower element of dst, and copy the upper element from a to the -// upper element of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_sd -FORCE_INLINE __m128d _mm_sub_sd(__m128d a, __m128d b) +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for less-than-or-equal, store the result in the lower element of dst, and +// copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmple_sd +FORCE_INLINE __m128d _mm_cmple_sd(__m128d a, __m128d b) { - return _mm_move_sd(a, _mm_sub_pd(a, b)); +#if defined(__aarch64__) + return _mm_move_sd(a, _mm_cmple_pd(a, b)); +#else + // expand "_mm_cmpge_pd()" to reduce unnecessary operations + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) <= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = a1; + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif } -// Add packed unsigned 16-bit integers in a and b using saturation, and store -// the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_adds_epu16 -FORCE_INLINE __m128i _mm_adds_epu16(__m128i a, __m128i b) +// Compares the 8 signed 16-bit integers in a and the 8 signed 16-bit integers +// in b for less than. +// +// r0 := (a0 < b0) ? 0xffff : 0x0 +// r1 := (a1 < b1) ? 0xffff : 0x0 +// ... +// r7 := (a7 < b7) ? 0xffff : 0x0 +// +// https://technet.microsoft.com/en-us/library/t863edb2(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmplt_epi16(__m128i a, __m128i b) { return vreinterpretq_m128i_u16( - vqaddq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); + vcltq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); } -// Negate packed 8-bit integers in a when the corresponding signed -// 8-bit integer in b is negative, and store the results in dst. -// Element in dst are zeroed out when the corresponding element -// in b is zero. -// -// for i in 0..15 -// if b[i] < 0 -// r[i] := -a[i] -// else if b[i] == 0 -// r[i] := 0 -// else -// r[i] := a[i] -// fi -// done -FORCE_INLINE __m128i _mm_sign_epi8(__m128i _a, __m128i _b) + +// Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers +// in b for less than. +// https://msdn.microsoft.com/en-us/library/vstudio/4ak0bf5d(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmplt_epi32(__m128i a, __m128i b) { - int8x16_t a = vreinterpretq_s8_m128i(_a); - int8x16_t b = vreinterpretq_s8_m128i(_b); + return vreinterpretq_m128i_u32( + vcltq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} - // signed shift right: faster than vclt - // (b < 0) ? 0xFF : 0 - uint8x16_t ltMask = vreinterpretq_u8_s8(vshrq_n_s8(b, 7)); +// Compares the 16 signed 8-bit integers in a and the 16 signed 8-bit integers +// in b for lesser than. +// https://msdn.microsoft.com/en-us/library/windows/desktop/9s46csht(v=vs.90).aspx +FORCE_INLINE __m128i _mm_cmplt_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vcltq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} - // (b == 0) ? 0xFF : 0 +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for less-than, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmplt_pd +FORCE_INLINE __m128d _mm_cmplt_pd(__m128d a, __m128d b) +{ #if defined(__aarch64__) - int8x16_t zeroMask = vreinterpretq_s8_u8(vceqzq_s8(b)); + return vreinterpretq_m128d_u64( + vcltq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); #else - int8x16_t zeroMask = vreinterpretq_s8_u8(vceqq_s8(b, vdupq_n_s8(0))); + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) < (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = (*(double *) &a1) < (*(double *) &b1) ? ~UINT64_C(0) : UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); #endif - - // bitwise select either a or nagative 'a' (vnegq_s8(a) return nagative 'a') - // based on ltMask - int8x16_t masked = vbslq_s8(ltMask, vnegq_s8(a), a); - // res = masked & (~zeroMask) - int8x16_t res = vbicq_s8(masked, zeroMask); - - return vreinterpretq_m128i_s8(res); } -// Negate packed 16-bit integers in a when the corresponding signed -// 16-bit integer in b is negative, and store the results in dst. -// Element in dst are zeroed out when the corresponding element -// in b is zero. -// -// for i in 0..7 -// if b[i] < 0 -// r[i] := -a[i] -// else if b[i] == 0 -// r[i] := 0 -// else -// r[i] := a[i] -// fi -// done -FORCE_INLINE __m128i _mm_sign_epi16(__m128i _a, __m128i _b) +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for less-than, store the result in the lower element of dst, and copy the +// upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmplt_sd +FORCE_INLINE __m128d _mm_cmplt_sd(__m128d a, __m128d b) { - int16x8_t a = vreinterpretq_s16_m128i(_a); - int16x8_t b = vreinterpretq_s16_m128i(_b); - - // signed shift right: faster than vclt - // (b < 0) ? 0xFFFF : 0 - uint16x8_t ltMask = vreinterpretq_u16_s16(vshrq_n_s16(b, 15)); - // (b == 0) ? 0xFFFF : 0 #if defined(__aarch64__) - int16x8_t zeroMask = vreinterpretq_s16_u16(vceqzq_s16(b)); + return _mm_move_sd(a, _mm_cmplt_pd(a, b)); #else - int16x8_t zeroMask = vreinterpretq_s16_u16(vceqq_s16(b, vdupq_n_s16(0))); + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) < (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = a1; + + return vreinterpretq_m128d_u64(vld1q_u64(d)); #endif - - // bitwise select either a or negative 'a' (vnegq_s16(a) equals to negative - // 'a') based on ltMask - int16x8_t masked = vbslq_s16(ltMask, vnegq_s16(a), a); - // res = masked & (~zeroMask) - int16x8_t res = vbicq_s16(masked, zeroMask); - return vreinterpretq_m128i_s16(res); } -// Negate packed 32-bit integers in a when the corresponding signed -// 32-bit integer in b is negative, and store the results in dst. -// Element in dst are zeroed out when the corresponding element -// in b is zero. -// -// for i in 0..3 -// if b[i] < 0 -// r[i] := -a[i] -// else if b[i] == 0 -// r[i] := 0 -// else -// r[i] := a[i] -// fi -// done -FORCE_INLINE __m128i _mm_sign_epi32(__m128i _a, __m128i _b) +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for not-equal, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpneq_pd +FORCE_INLINE __m128d _mm_cmpneq_pd(__m128d a, __m128d b) { - int32x4_t a = vreinterpretq_s32_m128i(_a); - int32x4_t b = vreinterpretq_s32_m128i(_b); - - // signed shift right: faster than vclt - // (b < 0) ? 0xFFFFFFFF : 0 - uint32x4_t ltMask = vreinterpretq_u32_s32(vshrq_n_s32(b, 31)); - - // (b == 0) ? 0xFFFFFFFF : 0 #if defined(__aarch64__) - int32x4_t zeroMask = vreinterpretq_s32_u32(vceqzq_s32(b)); + return vreinterpretq_m128d_s32(vmvnq_s32(vreinterpretq_s32_u64( + vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))))); #else - int32x4_t zeroMask = vreinterpretq_s32_u32(vceqq_s32(b, vdupq_n_s32(0))); + // (a == b) -> (a_lo == b_lo) && (a_hi == b_hi) + uint32x4_t cmp = + vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(b)); + uint32x4_t swapped = vrev64q_u32(cmp); + return vreinterpretq_m128d_u32(vmvnq_u32(vandq_u32(cmp, swapped))); #endif - - // bitwise select either a or negative 'a' (vnegq_s32(a) equals to negative - // 'a') based on ltMask - int32x4_t masked = vbslq_s32(ltMask, vnegq_s32(a), a); - // res = masked & (~zeroMask) - int32x4_t res = vbicq_s32(masked, zeroMask); - return vreinterpretq_m128i_s32(res); } -// Negate packed 16-bit integers in a when the corresponding signed 16-bit -// integer in b is negative, and store the results in dst. Element in dst are -// zeroed out when the corresponding element in b is zero. -// -// FOR j := 0 to 3 -// i := j*16 -// IF b[i+15:i] < 0 -// dst[i+15:i] := -(a[i+15:i]) -// ELSE IF b[i+15:i] == 0 -// dst[i+15:i] := 0 -// ELSE -// dst[i+15:i] := a[i+15:i] -// FI -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sign_pi16 -FORCE_INLINE __m64 _mm_sign_pi16(__m64 _a, __m64 _b) +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for not-equal, store the result in the lower element of dst, and copy the +// upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpneq_sd +FORCE_INLINE __m128d _mm_cmpneq_sd(__m128d a, __m128d b) { - int16x4_t a = vreinterpret_s16_m64(_a); - int16x4_t b = vreinterpret_s16_m64(_b); - - // signed shift right: faster than vclt - // (b < 0) ? 0xFFFF : 0 - uint16x4_t ltMask = vreinterpret_u16_s16(vshr_n_s16(b, 15)); + return _mm_move_sd(a, _mm_cmpneq_pd(a, b)); +} - // (b == 0) ? 0xFFFF : 0 +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for not-greater-than-or-equal, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnge_pd +FORCE_INLINE __m128d _mm_cmpnge_pd(__m128d a, __m128d b) +{ #if defined(__aarch64__) - int16x4_t zeroMask = vreinterpret_s16_u16(vceqz_s16(b)); + return vreinterpretq_m128d_u64(veorq_u64( + vcgeq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)), + vdupq_n_u64(UINT64_MAX))); #else - int16x4_t zeroMask = vreinterpret_s16_u16(vceq_s16(b, vdup_n_s16(0))); + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = + !((*(double *) &a0) >= (*(double *) &b0)) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = + !((*(double *) &a1) >= (*(double *) &b1)) ? ~UINT64_C(0) : UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); #endif - - // bitwise select either a or nagative 'a' (vneg_s16(a) return nagative 'a') - // based on ltMask - int16x4_t masked = vbsl_s16(ltMask, vneg_s16(a), a); - // res = masked & (~zeroMask) - int16x4_t res = vbic_s16(masked, zeroMask); - - return vreinterpret_m64_s16(res); } -// Negate packed 32-bit integers in a when the corresponding signed 32-bit -// integer in b is negative, and store the results in dst. Element in dst are -// zeroed out when the corresponding element in b is zero. -// -// FOR j := 0 to 1 -// i := j*32 -// IF b[i+31:i] < 0 -// dst[i+31:i] := -(a[i+31:i]) -// ELSE IF b[i+31:i] == 0 -// dst[i+31:i] := 0 -// ELSE -// dst[i+31:i] := a[i+31:i] -// FI -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sign_pi32 -FORCE_INLINE __m64 _mm_sign_pi32(__m64 _a, __m64 _b) +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for not-greater-than-or-equal, store the result in the lower element of +// dst, and copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnge_sd +FORCE_INLINE __m128d _mm_cmpnge_sd(__m128d a, __m128d b) { - int32x2_t a = vreinterpret_s32_m64(_a); - int32x2_t b = vreinterpret_s32_m64(_b); - - // signed shift right: faster than vclt - // (b < 0) ? 0xFFFFFFFF : 0 - uint32x2_t ltMask = vreinterpret_u32_s32(vshr_n_s32(b, 31)); + return _mm_move_sd(a, _mm_cmpnge_pd(a, b)); +} - // (b == 0) ? 0xFFFFFFFF : 0 +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for not-greater-than, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_cmpngt_pd +FORCE_INLINE __m128d _mm_cmpngt_pd(__m128d a, __m128d b) +{ #if defined(__aarch64__) - int32x2_t zeroMask = vreinterpret_s32_u32(vceqz_s32(b)); + return vreinterpretq_m128d_u64(veorq_u64( + vcgtq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)), + vdupq_n_u64(UINT64_MAX))); #else - int32x2_t zeroMask = vreinterpret_s32_u32(vceq_s32(b, vdup_n_s32(0))); + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = + !((*(double *) &a0) > (*(double *) &b0)) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = + !((*(double *) &a1) > (*(double *) &b1)) ? ~UINT64_C(0) : UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); #endif - - // bitwise select either a or nagative 'a' (vneg_s32(a) return nagative 'a') - // based on ltMask - int32x2_t masked = vbsl_s32(ltMask, vneg_s32(a), a); - // res = masked & (~zeroMask) - int32x2_t res = vbic_s32(masked, zeroMask); - - return vreinterpret_m64_s32(res); } -// Negate packed 8-bit integers in a when the corresponding signed 8-bit integer -// in b is negative, and store the results in dst. Element in dst are zeroed out -// when the corresponding element in b is zero. -// -// FOR j := 0 to 7 -// i := j*8 -// IF b[i+7:i] < 0 -// dst[i+7:i] := -(a[i+7:i]) -// ELSE IF b[i+7:i] == 0 -// dst[i+7:i] := 0 -// ELSE -// dst[i+7:i] := a[i+7:i] -// FI -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sign_pi8 -FORCE_INLINE __m64 _mm_sign_pi8(__m64 _a, __m64 _b) +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for not-greater-than, store the result in the lower element of dst, and +// copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpngt_sd +FORCE_INLINE __m128d _mm_cmpngt_sd(__m128d a, __m128d b) { - int8x8_t a = vreinterpret_s8_m64(_a); - int8x8_t b = vreinterpret_s8_m64(_b); - - // signed shift right: faster than vclt - // (b < 0) ? 0xFF : 0 - uint8x8_t ltMask = vreinterpret_u8_s8(vshr_n_s8(b, 7)); + return _mm_move_sd(a, _mm_cmpngt_pd(a, b)); +} - // (b == 0) ? 0xFF : 0 +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for not-less-than-or-equal, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnle_pd +FORCE_INLINE __m128d _mm_cmpnle_pd(__m128d a, __m128d b) +{ #if defined(__aarch64__) - int8x8_t zeroMask = vreinterpret_s8_u8(vceqz_s8(b)); + return vreinterpretq_m128d_u64(veorq_u64( + vcleq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)), + vdupq_n_u64(UINT64_MAX))); #else - int8x8_t zeroMask = vreinterpret_s8_u8(vceq_s8(b, vdup_n_s8(0))); + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = + !((*(double *) &a0) <= (*(double *) &b0)) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = + !((*(double *) &a1) <= (*(double *) &b1)) ? ~UINT64_C(0) : UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); #endif - - // bitwise select either a or nagative 'a' (vneg_s8(a) return nagative 'a') - // based on ltMask - int8x8_t masked = vbsl_s8(ltMask, vneg_s8(a), a); - // res = masked & (~zeroMask) - int8x8_t res = vbic_s8(masked, zeroMask); - - return vreinterpret_m64_s8(res); } -// Average packed unsigned 16-bit integers in a and b, and store the results in -// dst. -// -// FOR j := 0 to 3 -// i := j*16 -// dst[i+15:i] := (a[i+15:i] + b[i+15:i] + 1) >> 1 -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_avg_pu16 -FORCE_INLINE __m64 _mm_avg_pu16(__m64 a, __m64 b) +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for not-less-than-or-equal, store the result in the lower element of dst, +// and copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnle_sd +FORCE_INLINE __m128d _mm_cmpnle_sd(__m128d a, __m128d b) { - return vreinterpret_m64_u16( - vrhadd_u16(vreinterpret_u16_m64(a), vreinterpret_u16_m64(b))); + return _mm_move_sd(a, _mm_cmpnle_pd(a, b)); } -// Average packed unsigned 8-bit integers in a and b, and store the results in -// dst. -// -// FOR j := 0 to 7 -// i := j*8 -// dst[i+7:i] := (a[i+7:i] + b[i+7:i] + 1) >> 1 -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_avg_pu8 -FORCE_INLINE __m64 _mm_avg_pu8(__m64 a, __m64 b) +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for not-less-than, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnlt_pd +FORCE_INLINE __m128d _mm_cmpnlt_pd(__m128d a, __m128d b) { - return vreinterpret_m64_u8( - vrhadd_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); +#if defined(__aarch64__) + return vreinterpretq_m128d_u64(veorq_u64( + vcltq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)), + vdupq_n_u64(UINT64_MAX))); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = + !((*(double *) &a0) < (*(double *) &b0)) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = + !((*(double *) &a1) < (*(double *) &b1)) ? ~UINT64_C(0) : UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif } -// Average packed unsigned 8-bit integers in a and b, and store the results in -// dst. -// -// FOR j := 0 to 7 -// i := j*8 -// dst[i+7:i] := (a[i+7:i] + b[i+7:i] + 1) >> 1 -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pavgb -#define _m_pavgb(a, b) _mm_avg_pu8(a, b) - -// Average packed unsigned 16-bit integers in a and b, and store the results in -// dst. -// -// FOR j := 0 to 3 -// i := j*16 -// dst[i+15:i] := (a[i+15:i] + b[i+15:i] + 1) >> 1 -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pavgw -#define _m_pavgw(a, b) _mm_avg_pu16(a, b) - -// Extract a 16-bit integer from a, selected with imm8, and store the result in -// the lower element of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pextrw -#define _m_pextrw(a, imm) _mm_extract_pi16(a, imm) - -// Copy a to dst, and insert the 16-bit integer i into dst at the location -// specified by imm8. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=m_pinsrw -#define _m_pinsrw(a, i, imm) _mm_insert_pi16(a, i, imm) - -// Compare packed signed 16-bit integers in a and b, and store packed maximum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmaxsw -#define _m_pmaxsw(a, b) _mm_max_pi16(a, b) - -// Compare packed unsigned 8-bit integers in a and b, and store packed maximum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmaxub -#define _m_pmaxub(a, b) _mm_max_pu8(a, b) - -// Compare packed signed 16-bit integers in a and b, and store packed minimum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pminsw -#define _m_pminsw(a, b) _mm_min_pi16(a, b) - -// Compare packed unsigned 8-bit integers in a and b, and store packed minimum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pminub -#define _m_pminub(a, b) _mm_min_pu8(a, b) - -// Computes the average of the 16 unsigned 8-bit integers in a and the 16 -// unsigned 8-bit integers in b and rounds. -// -// r0 := (a0 + b0) / 2 -// r1 := (a1 + b1) / 2 -// ... -// r15 := (a15 + b15) / 2 -// -// https://msdn.microsoft.com/en-us/library/vstudio/8zwh554a(v%3dvs.90).aspx -FORCE_INLINE __m128i _mm_avg_epu8(__m128i a, __m128i b) +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for not-less-than, store the result in the lower element of dst, and copy +// the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnlt_sd +FORCE_INLINE __m128d _mm_cmpnlt_sd(__m128d a, __m128d b) { - return vreinterpretq_m128i_u8( - vrhaddq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); + return _mm_move_sd(a, _mm_cmpnlt_pd(a, b)); } -// Computes the average of the 8 unsigned 16-bit integers in a and the 8 -// unsigned 16-bit integers in b and rounds. -// -// r0 := (a0 + b0) / 2 -// r1 := (a1 + b1) / 2 -// ... -// r7 := (a7 + b7) / 2 -// -// https://msdn.microsoft.com/en-us/library/vstudio/y13ca3c8(v=vs.90).aspx -FORCE_INLINE __m128i _mm_avg_epu16(__m128i a, __m128i b) +// Compare packed double-precision (64-bit) floating-point elements in a and b +// to see if neither is NaN, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpord_pd +FORCE_INLINE __m128d _mm_cmpord_pd(__m128d a, __m128d b) { - return (__m128i) vrhaddq_u16(vreinterpretq_u16_m128i(a), - vreinterpretq_u16_m128i(b)); +#if defined(__aarch64__) + // Excluding NaNs, any two floating point numbers can be compared. + uint64x2_t not_nan_a = + vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(a)); + uint64x2_t not_nan_b = + vceqq_f64(vreinterpretq_f64_m128d(b), vreinterpretq_f64_m128d(b)); + return vreinterpretq_m128d_u64(vandq_u64(not_nan_a, not_nan_b)); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = ((*(double *) &a0) == (*(double *) &a0) && + (*(double *) &b0) == (*(double *) &b0)) + ? ~UINT64_C(0) + : UINT64_C(0); + d[1] = ((*(double *) &a1) == (*(double *) &a1) && + (*(double *) &b1) == (*(double *) &b1)) + ? ~UINT64_C(0) + : UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif } -// Adds the four single-precision, floating-point values of a and b. -// -// r0 := a0 + b0 -// r1 := a1 + b1 -// r2 := a2 + b2 -// r3 := a3 + b3 -// -// https://msdn.microsoft.com/en-us/library/vstudio/c9848chc(v=vs.100).aspx -FORCE_INLINE __m128 _mm_add_ps(__m128 a, __m128 b) +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b to see if neither is NaN, store the result in the lower element of dst, and +// copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpord_sd +FORCE_INLINE __m128d _mm_cmpord_sd(__m128d a, __m128d b) { - return vreinterpretq_m128_f32( - vaddq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#if defined(__aarch64__) + return _mm_move_sd(a, _mm_cmpord_pd(a, b)); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t d[2]; + d[0] = ((*(double *) &a0) == (*(double *) &a0) && + (*(double *) &b0) == (*(double *) &b0)) + ? ~UINT64_C(0) + : UINT64_C(0); + d[1] = a1; + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif } -// Add packed double-precision (64-bit) floating-point elements in a and b, and -// store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_pd -FORCE_INLINE __m128d _mm_add_pd(__m128d a, __m128d b) +// Compare packed double-precision (64-bit) floating-point elements in a and b +// to see if either is NaN, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpunord_pd +FORCE_INLINE __m128d _mm_cmpunord_pd(__m128d a, __m128d b) { #if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vaddq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); + // Two NaNs are not equal in comparison operation. + uint64x2_t not_nan_a = + vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(a)); + uint64x2_t not_nan_b = + vceqq_f64(vreinterpretq_f64_m128d(b), vreinterpretq_f64_m128d(b)); + return vreinterpretq_m128d_s32( + vmvnq_s32(vreinterpretq_s32_u64(vandq_u64(not_nan_a, not_nan_b)))); #else - double *da = (double *) &a; - double *db = (double *) &b; - double c[2]; - c[0] = da[0] + db[0]; - c[1] = da[1] + db[1]; - return vld1q_f32((float32_t *) c); + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = ((*(double *) &a0) == (*(double *) &a0) && + (*(double *) &b0) == (*(double *) &b0)) + ? UINT64_C(0) + : ~UINT64_C(0); + d[1] = ((*(double *) &a1) == (*(double *) &a1) && + (*(double *) &b1) == (*(double *) &b1)) + ? UINT64_C(0) + : ~UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); #endif } -// Add the lower double-precision (64-bit) floating-point element in a and b, -// store the result in the lower element of dst, and copy the upper element from -// a to the upper element of dst. -// -// dst[63:0] := a[63:0] + b[63:0] -// dst[127:64] := a[127:64] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_sd -FORCE_INLINE __m128d _mm_add_sd(__m128d a, __m128d b) +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b to see if either is NaN, store the result in the lower element of dst, and +// copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpunord_sd +FORCE_INLINE __m128d _mm_cmpunord_sd(__m128d a, __m128d b) { #if defined(__aarch64__) - return _mm_move_sd(a, _mm_add_pd(a, b)); + return _mm_move_sd(a, _mm_cmpunord_pd(a, b)); #else - double *da = (double *) &a; - double *db = (double *) &b; - double c[2]; - c[0] = da[0] + db[0]; - c[1] = da[1]; - return vld1q_f32((float32_t *) c); + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t d[2]; + d[0] = ((*(double *) &a0) == (*(double *) &a0) && + (*(double *) &b0) == (*(double *) &b0)) + ? UINT64_C(0) + : ~UINT64_C(0); + d[1] = a1; + + return vreinterpretq_m128d_u64(vld1q_u64(d)); #endif } -// Add 64-bit integers a and b, and store the result in dst. -// -// dst[63:0] := a[63:0] + b[63:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_si64 -FORCE_INLINE __m64 _mm_add_si64(__m64 a, __m64 b) +// Compare the lower double-precision (64-bit) floating-point element in a and b +// for greater-than-or-equal, and return the boolean result (0 or 1). +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comige_sd +FORCE_INLINE int _mm_comige_sd(__m128d a, __m128d b) { - return vreinterpret_m64_s64( - vadd_s64(vreinterpret_s64_m64(a), vreinterpret_s64_m64(b))); -} +#if defined(__aarch64__) + return vgetq_lane_u64(vcgeq_f64(a, b), 0) & 0x1; +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); -// adds the scalar single-precision floating point values of a and b. -// https://msdn.microsoft.com/en-us/library/be94x2y6(v=vs.100).aspx -FORCE_INLINE __m128 _mm_add_ss(__m128 a, __m128 b) -{ - float32_t b0 = vgetq_lane_f32(vreinterpretq_f32_m128(b), 0); - float32x4_t value = vsetq_lane_f32(b0, vdupq_n_f32(0), 0); - // the upper values in the result must be the remnants of <a>. - return vreinterpretq_m128_f32(vaddq_f32(a, value)); + return (*(double *) &a0 >= *(double *) &b0); +#endif } -// Adds the 4 signed or unsigned 64-bit integers in a to the 4 signed or -// unsigned 32-bit integers in b. -// https://msdn.microsoft.com/en-us/library/vstudio/09xs4fkk(v=vs.100).aspx -FORCE_INLINE __m128i _mm_add_epi64(__m128i a, __m128i b) +// Compare the lower double-precision (64-bit) floating-point element in a and b +// for greater-than, and return the boolean result (0 or 1). +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comigt_sd +FORCE_INLINE int _mm_comigt_sd(__m128d a, __m128d b) { - return vreinterpretq_m128i_s64( - vaddq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); +#if defined(__aarch64__) + return vgetq_lane_u64(vcgtq_f64(a, b), 0) & 0x1; +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + + return (*(double *) &a0 > *(double *) &b0); +#endif } -// Adds the 4 signed or unsigned 32-bit integers in a to the 4 signed or -// unsigned 32-bit integers in b. -// -// r0 := a0 + b0 -// r1 := a1 + b1 -// r2 := a2 + b2 -// r3 := a3 + b3 -// -// https://msdn.microsoft.com/en-us/library/vstudio/09xs4fkk(v=vs.100).aspx -FORCE_INLINE __m128i _mm_add_epi32(__m128i a, __m128i b) +// Compare the lower double-precision (64-bit) floating-point element in a and b +// for less-than-or-equal, and return the boolean result (0 or 1). +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comile_sd +FORCE_INLINE int _mm_comile_sd(__m128d a, __m128d b) { - return vreinterpretq_m128i_s32( - vaddq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +#if defined(__aarch64__) + return vgetq_lane_u64(vcleq_f64(a, b), 0) & 0x1; +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + + return (*(double *) &a0 <= *(double *) &b0); +#endif } -// Adds the 8 signed or unsigned 16-bit integers in a to the 8 signed or -// unsigned 16-bit integers in b. -// https://msdn.microsoft.com/en-us/library/fceha5k4(v=vs.100).aspx -FORCE_INLINE __m128i _mm_add_epi16(__m128i a, __m128i b) +// Compare the lower double-precision (64-bit) floating-point element in a and b +// for less-than, and return the boolean result (0 or 1). +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comilt_sd +FORCE_INLINE int _mm_comilt_sd(__m128d a, __m128d b) { - return vreinterpretq_m128i_s16( - vaddq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +#if defined(__aarch64__) + return vgetq_lane_u64(vcltq_f64(a, b), 0) & 0x1; +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + + return (*(double *) &a0 < *(double *) &b0); +#endif } -// Adds the 16 signed or unsigned 8-bit integers in a to the 16 signed or -// unsigned 8-bit integers in b. -// https://technet.microsoft.com/en-us/subscriptions/yc7tcyzs(v=vs.90) -FORCE_INLINE __m128i _mm_add_epi8(__m128i a, __m128i b) +// Compare the lower double-precision (64-bit) floating-point element in a and b +// for equality, and return the boolean result (0 or 1). +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comieq_sd +FORCE_INLINE int _mm_comieq_sd(__m128d a, __m128d b) { - return vreinterpretq_m128i_s8( - vaddq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +#if defined(__aarch64__) + return vgetq_lane_u64(vceqq_f64(a, b), 0) & 0x1; +#else + uint32x4_t a_not_nan = + vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(a)); + uint32x4_t b_not_nan = + vceqq_u32(vreinterpretq_u32_m128d(b), vreinterpretq_u32_m128d(b)); + uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); + uint32x4_t a_eq_b = + vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(b)); + uint64x2_t and_results = vandq_u64(vreinterpretq_u64_u32(a_and_b_not_nan), + vreinterpretq_u64_u32(a_eq_b)); + return vgetq_lane_u64(and_results, 0) & 0x1; +#endif } -// Adds the 8 signed 16-bit integers in a to the 8 signed 16-bit integers in b -// and saturates. -// -// r0 := SignedSaturate(a0 + b0) -// r1 := SignedSaturate(a1 + b1) -// ... -// r7 := SignedSaturate(a7 + b7) -// -// https://msdn.microsoft.com/en-us/library/1a306ef8(v=vs.100).aspx -FORCE_INLINE __m128i _mm_adds_epi16(__m128i a, __m128i b) +// Compare the lower double-precision (64-bit) floating-point element in a and b +// for not-equal, and return the boolean result (0 or 1). +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comineq_sd +FORCE_INLINE int _mm_comineq_sd(__m128d a, __m128d b) { - return vreinterpretq_m128i_s16( - vqaddq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); + return !_mm_comieq_sd(a, b); } -// Add packed signed 8-bit integers in a and b using saturation, and store the -// results in dst. +// Convert packed signed 32-bit integers in a to packed double-precision +// (64-bit) floating-point elements, and store the results in dst. // -// FOR j := 0 to 15 -// i := j*8 -// dst[i+7:i] := Saturate8( a[i+7:i] + b[i+7:i] ) +// FOR j := 0 to 1 +// i := j*32 +// m := j*64 +// dst[m+63:m] := Convert_Int32_To_FP64(a[i+31:i]) // ENDFOR // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_adds_epi8 -FORCE_INLINE __m128i _mm_adds_epi8(__m128i a, __m128i b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtepi32_pd +FORCE_INLINE __m128d _mm_cvtepi32_pd(__m128i a) { - return vreinterpretq_m128i_s8( - vqaddq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vcvtq_f64_s64(vmovl_s32(vget_low_s32(vreinterpretq_s32_m128i(a))))); +#else + double a0 = (double) vgetq_lane_s32(vreinterpretq_s32_m128i(a), 0); + double a1 = (double) vgetq_lane_s32(vreinterpretq_s32_m128i(a), 1); + return _mm_set_pd(a1, a0); +#endif } -// Adds the 16 unsigned 8-bit integers in a to the 16 unsigned 8-bit integers in -// b and saturates.. -// https://msdn.microsoft.com/en-us/library/9hahyddy(v=vs.100).aspx -FORCE_INLINE __m128i _mm_adds_epu8(__m128i a, __m128i b) +// Converts the four signed 32-bit integer values of a to single-precision, +// floating-point values +// https://msdn.microsoft.com/en-us/library/vstudio/36bwxcx5(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cvtepi32_ps(__m128i a) { - return vreinterpretq_m128i_u8( - vqaddq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); + return vreinterpretq_m128_f32(vcvtq_f32_s32(vreinterpretq_s32_m128i(a))); } -// Multiplies the 8 signed or unsigned 16-bit integers from a by the 8 signed or -// unsigned 16-bit integers from b. +// Convert packed double-precision (64-bit) floating-point elements in a to +// packed 32-bit integers, and store the results in dst. // -// r0 := (a0 * b0)[15:0] -// r1 := (a1 * b1)[15:0] -// ... -// r7 := (a7 * b7)[15:0] +// FOR j := 0 to 1 +// i := 32*j +// k := 64*j +// dst[i+31:i] := Convert_FP64_To_Int32(a[k+63:k]) +// ENDFOR // -// https://msdn.microsoft.com/en-us/library/vstudio/9ks1472s(v=vs.100).aspx -FORCE_INLINE __m128i _mm_mullo_epi16(__m128i a, __m128i b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpd_epi32 +FORCE_INLINE __m128i _mm_cvtpd_epi32(__m128d a) { - return vreinterpretq_m128i_s16( - vmulq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); + __m128d rnd = _mm_round_pd(a, _MM_FROUND_CUR_DIRECTION); + double d0 = ((double *) &rnd)[0]; + double d1 = ((double *) &rnd)[1]; + return _mm_set_epi32(0, 0, (int32_t) d1, (int32_t) d0); } -// Multiplies the 4 signed or unsigned 32-bit integers from a by the 4 signed or -// unsigned 32-bit integers from b. -// https://msdn.microsoft.com/en-us/library/vstudio/bb531409(v=vs.100).aspx -FORCE_INLINE __m128i _mm_mullo_epi32(__m128i a, __m128i b) +// Convert packed double-precision (64-bit) floating-point elements in a to +// packed 32-bit integers, and store the results in dst. +// +// FOR j := 0 to 1 +// i := 32*j +// k := 64*j +// dst[i+31:i] := Convert_FP64_To_Int32(a[k+63:k]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpd_pi32 +FORCE_INLINE __m64 _mm_cvtpd_pi32(__m128d a) { - return vreinterpretq_m128i_s32( - vmulq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); + __m128d rnd = _mm_round_pd(a, _MM_FROUND_CUR_DIRECTION); + double d0 = ((double *) &rnd)[0]; + double d1 = ((double *) &rnd)[1]; + int32_t ALIGN_STRUCT(16) data[2] = {(int32_t) d0, (int32_t) d1}; + return vreinterpret_m64_s32(vld1_s32(data)); } -// Multiply the packed unsigned 16-bit integers in a and b, producing -// intermediate 32-bit integers, and store the high 16 bits of the intermediate -// integers in dst. +// Convert packed double-precision (64-bit) floating-point elements in a to +// packed single-precision (32-bit) floating-point elements, and store the +// results in dst. // -// FOR j := 0 to 3 -// i := j*16 -// tmp[31:0] := a[i+15:i] * b[i+15:i] -// dst[i+15:i] := tmp[31:16] +// FOR j := 0 to 1 +// i := 32*j +// k := 64*j +// dst[i+31:i] := Convert_FP64_To_FP32(a[k+64:k]) // ENDFOR +// dst[127:64] := 0 // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmulhuw -#define _m_pmulhuw(a, b) _mm_mulhi_pu16(a, b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpd_ps +FORCE_INLINE __m128 _mm_cvtpd_ps(__m128d a) +{ +#if defined(__aarch64__) + float32x2_t tmp = vcvt_f32_f64(vreinterpretq_f64_m128d(a)); + return vreinterpretq_m128_f32(vcombine_f32(tmp, vdup_n_f32(0))); +#else + float a0 = (float) ((double *) &a)[0]; + float a1 = (float) ((double *) &a)[1]; + return _mm_set_ps(0, 0, a1, a0); +#endif +} -// Multiplies the four single-precision, floating-point values of a and b. +// Convert packed signed 32-bit integers in a to packed double-precision +// (64-bit) floating-point elements, and store the results in dst. // -// r0 := a0 * b0 -// r1 := a1 * b1 -// r2 := a2 * b2 -// r3 := a3 * b3 +// FOR j := 0 to 1 +// i := j*32 +// m := j*64 +// dst[m+63:m] := Convert_Int32_To_FP64(a[i+31:i]) +// ENDFOR // -// https://msdn.microsoft.com/en-us/library/vstudio/22kbk6t9(v=vs.100).aspx -FORCE_INLINE __m128 _mm_mul_ps(__m128 a, __m128 b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi32_pd +FORCE_INLINE __m128d _mm_cvtpi32_pd(__m64 a) { - return vreinterpretq_m128_f32( - vmulq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vcvtq_f64_s64(vmovl_s32(vreinterpret_s32_m64(a)))); +#else + double a0 = (double) vget_lane_s32(vreinterpret_s32_m64(a), 0); + double a1 = (double) vget_lane_s32(vreinterpret_s32_m64(a), 1); + return _mm_set_pd(a1, a0); +#endif } -// Multiply packed double-precision (64-bit) floating-point elements in a and b, -// and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_pd -FORCE_INLINE __m128d _mm_mul_pd(__m128d a, __m128d b) +// Converts the four single-precision, floating-point values of a to signed +// 32-bit integer values. +// +// r0 := (int) a0 +// r1 := (int) a1 +// r2 := (int) a2 +// r3 := (int) a3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/xdc42k5e(v=vs.100).aspx +// *NOTE*. The default rounding mode on SSE is 'round to even', which ARMv7-A +// does not support! It is supported on ARMv8-A however. +FORCE_INLINE __m128i _mm_cvtps_epi32(__m128 a) { #if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vmulq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); + switch (_MM_GET_ROUNDING_MODE()) { + case _MM_ROUND_NEAREST: + return vreinterpretq_m128i_s32(vcvtnq_s32_f32(a)); + case _MM_ROUND_DOWN: + return vreinterpretq_m128i_s32(vcvtmq_s32_f32(a)); + case _MM_ROUND_UP: + return vreinterpretq_m128i_s32(vcvtpq_s32_f32(a)); + default: // _MM_ROUND_TOWARD_ZERO + return vreinterpretq_m128i_s32(vcvtq_s32_f32(a)); + } #else - double *da = (double *) &a; - double *db = (double *) &b; - double c[2]; - c[0] = da[0] * db[0]; - c[1] = da[1] * db[1]; - return vld1q_f32((float32_t *) c); + float *f = (float *) &a; + switch (_MM_GET_ROUNDING_MODE()) { + case _MM_ROUND_NEAREST: { + uint32x4_t signmask = vdupq_n_u32(0x80000000); + float32x4_t half = vbslq_f32(signmask, vreinterpretq_f32_m128(a), + vdupq_n_f32(0.5f)); /* +/- 0.5 */ + int32x4_t r_normal = vcvtq_s32_f32(vaddq_f32( + vreinterpretq_f32_m128(a), half)); /* round to integer: [a + 0.5]*/ + int32x4_t r_trunc = vcvtq_s32_f32( + vreinterpretq_f32_m128(a)); /* truncate to integer: [a] */ + int32x4_t plusone = vreinterpretq_s32_u32(vshrq_n_u32( + vreinterpretq_u32_s32(vnegq_s32(r_trunc)), 31)); /* 1 or 0 */ + int32x4_t r_even = vbicq_s32(vaddq_s32(r_trunc, plusone), + vdupq_n_s32(1)); /* ([a] + {0,1}) & ~1 */ + float32x4_t delta = vsubq_f32( + vreinterpretq_f32_m128(a), + vcvtq_f32_s32(r_trunc)); /* compute delta: delta = (a - [a]) */ + uint32x4_t is_delta_half = + vceqq_f32(delta, half); /* delta == +/- 0.5 */ + return vreinterpretq_m128i_s32( + vbslq_s32(is_delta_half, r_even, r_normal)); + } + case _MM_ROUND_DOWN: + return _mm_set_epi32(floorf(f[3]), floorf(f[2]), floorf(f[1]), + floorf(f[0])); + case _MM_ROUND_UP: + return _mm_set_epi32(ceilf(f[3]), ceilf(f[2]), ceilf(f[1]), + ceilf(f[0])); + default: // _MM_ROUND_TOWARD_ZERO + return _mm_set_epi32((int32_t) f[3], (int32_t) f[2], (int32_t) f[1], + (int32_t) f[0]); + } #endif } -// Multiply the lower double-precision (64-bit) floating-point element in a and -// b, store the result in the lower element of dst, and copy the upper element -// from a to the upper element of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_mul_sd -FORCE_INLINE __m128d _mm_mul_sd(__m128d a, __m128d b) +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed double-precision (64-bit) floating-point elements, and store the +// results in dst. +// +// FOR j := 0 to 1 +// i := 64*j +// k := 32*j +// dst[i+63:i] := Convert_FP32_To_FP64(a[k+31:k]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pd +FORCE_INLINE __m128d _mm_cvtps_pd(__m128 a) { - return _mm_move_sd(a, _mm_mul_pd(a, b)); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vcvt_f64_f32(vget_low_f32(vreinterpretq_f32_m128(a)))); +#else + double a0 = (double) vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + double a1 = (double) vgetq_lane_f32(vreinterpretq_f32_m128(a), 1); + return _mm_set_pd(a1, a0); +#endif } -// Multiply the lower single-precision (32-bit) floating-point element in a and -// b, store the result in the lower element of dst, and copy the upper 3 packed -// elements from a to the upper elements of dst. +// Copy the lower double-precision (64-bit) floating-point element of a to dst. // -// dst[31:0] := a[31:0] * b[31:0] -// dst[127:32] := a[127:32] +// dst[63:0] := a[63:0] // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_ss -FORCE_INLINE __m128 _mm_mul_ss(__m128 a, __m128 b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsd_f64 +FORCE_INLINE double _mm_cvtsd_f64(__m128d a) { - return _mm_move_ss(a, _mm_mul_ps(a, b)); +#if defined(__aarch64__) + return (double) vgetq_lane_f64(vreinterpretq_f64_m128d(a), 0); +#else + return ((double *) &a)[0]; +#endif } -// Multiply the low unsigned 32-bit integers from each packed 64-bit element in -// a and b, and store the unsigned 64-bit results in dst. +// Convert the lower double-precision (64-bit) floating-point element in a to a +// 32-bit integer, and store the result in dst. // -// r0 := (a0 & 0xFFFFFFFF) * (b0 & 0xFFFFFFFF) -// r1 := (a2 & 0xFFFFFFFF) * (b2 & 0xFFFFFFFF) -FORCE_INLINE __m128i _mm_mul_epu32(__m128i a, __m128i b) +// dst[31:0] := Convert_FP64_To_Int32(a[63:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsd_si32 +FORCE_INLINE int32_t _mm_cvtsd_si32(__m128d a) { - // vmull_u32 upcasts instead of masking, so we downcast. - uint32x2_t a_lo = vmovn_u64(vreinterpretq_u64_m128i(a)); - uint32x2_t b_lo = vmovn_u64(vreinterpretq_u64_m128i(b)); - return vreinterpretq_m128i_u64(vmull_u32(a_lo, b_lo)); +#if defined(__aarch64__) + return (int32_t) vgetq_lane_f64(vrndiq_f64(vreinterpretq_f64_m128d(a)), 0); +#else + __m128d rnd = _mm_round_pd(a, _MM_FROUND_CUR_DIRECTION); + double ret = ((double *) &rnd)[0]; + return (int32_t) ret; +#endif } -// Multiply the low unsigned 32-bit integers from a and b, and store the -// unsigned 64-bit result in dst. +// Convert the lower double-precision (64-bit) floating-point element in a to a +// 64-bit integer, and store the result in dst. // -// dst[63:0] := a[31:0] * b[31:0] +// dst[63:0] := Convert_FP64_To_Int64(a[63:0]) // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_su32 -FORCE_INLINE __m64 _mm_mul_su32(__m64 a, __m64 b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsd_si64 +FORCE_INLINE int64_t _mm_cvtsd_si64(__m128d a) { - return vreinterpret_m64_u64(vget_low_u64( - vmull_u32(vreinterpret_u32_m64(a), vreinterpret_u32_m64(b)))); +#if defined(__aarch64__) + return (int64_t) vgetq_lane_f64(vrndiq_f64(vreinterpretq_f64_m128d(a)), 0); +#else + __m128d rnd = _mm_round_pd(a, _MM_FROUND_CUR_DIRECTION); + double ret = ((double *) &rnd)[0]; + return (int64_t) ret; +#endif } -// Multiply the low signed 32-bit integers from each packed 64-bit element in -// a and b, and store the signed 64-bit results in dst. +// Convert the lower double-precision (64-bit) floating-point element in a to a +// 64-bit integer, and store the result in dst. // -// r0 := (int64_t)(int32_t)a0 * (int64_t)(int32_t)b0 -// r1 := (int64_t)(int32_t)a2 * (int64_t)(int32_t)b2 -FORCE_INLINE __m128i _mm_mul_epi32(__m128i a, __m128i b) +// dst[63:0] := Convert_FP64_To_Int64(a[63:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsd_si64x +#define _mm_cvtsd_si64x _mm_cvtsd_si64 + +// Convert the lower double-precision (64-bit) floating-point element in b to a +// single-precision (32-bit) floating-point element, store the result in the +// lower element of dst, and copy the upper 3 packed elements from a to the +// upper elements of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsd_ss +FORCE_INLINE __m128 _mm_cvtsd_ss(__m128 a, __m128d b) { - // vmull_s32 upcasts instead of masking, so we downcast. - int32x2_t a_lo = vmovn_s64(vreinterpretq_s64_m128i(a)); - int32x2_t b_lo = vmovn_s64(vreinterpretq_s64_m128i(b)); - return vreinterpretq_m128i_s64(vmull_s32(a_lo, b_lo)); +#if defined(__aarch64__) + return vreinterpretq_m128_f32(vsetq_lane_f32( + vget_lane_f32(vcvt_f32_f64(vreinterpretq_f64_m128d(b)), 0), + vreinterpretq_f32_m128(a), 0)); +#else + return vreinterpretq_m128_f32(vsetq_lane_f32((float) ((double *) &b)[0], + vreinterpretq_f32_m128(a), 0)); +#endif } -// Multiplies the 8 signed 16-bit integers from a by the 8 signed 16-bit -// integers from b. +// Copy the lower 32-bit integer in a to dst. // -// r0 := (a0 * b0) + (a1 * b1) -// r1 := (a2 * b2) + (a3 * b3) -// r2 := (a4 * b4) + (a5 * b5) -// r3 := (a6 * b6) + (a7 * b7) -// https://msdn.microsoft.com/en-us/library/yht36sa6(v=vs.90).aspx -FORCE_INLINE __m128i _mm_madd_epi16(__m128i a, __m128i b) +// dst[31:0] := a[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si32 +FORCE_INLINE int _mm_cvtsi128_si32(__m128i a) { - int32x4_t low = vmull_s16(vget_low_s16(vreinterpretq_s16_m128i(a)), - vget_low_s16(vreinterpretq_s16_m128i(b))); - int32x4_t high = vmull_s16(vget_high_s16(vreinterpretq_s16_m128i(a)), - vget_high_s16(vreinterpretq_s16_m128i(b))); - - int32x2_t low_sum = vpadd_s32(vget_low_s32(low), vget_high_s32(low)); - int32x2_t high_sum = vpadd_s32(vget_low_s32(high), vget_high_s32(high)); - - return vreinterpretq_m128i_s32(vcombine_s32(low_sum, high_sum)); + return vgetq_lane_s32(vreinterpretq_s32_m128i(a), 0); } -// Multiply packed signed 16-bit integers in a and b, producing intermediate -// signed 32-bit integers. Shift right by 15 bits while rounding up, and store -// the packed 16-bit integers in dst. +// Copy the lower 64-bit integer in a to dst. // -// r0 := Round(((int32_t)a0 * (int32_t)b0) >> 15) -// r1 := Round(((int32_t)a1 * (int32_t)b1) >> 15) -// r2 := Round(((int32_t)a2 * (int32_t)b2) >> 15) -// ... -// r7 := Round(((int32_t)a7 * (int32_t)b7) >> 15) -FORCE_INLINE __m128i _mm_mulhrs_epi16(__m128i a, __m128i b) +// dst[63:0] := a[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si64 +FORCE_INLINE int64_t _mm_cvtsi128_si64(__m128i a) { - // Has issues due to saturation - // return vreinterpretq_m128i_s16(vqrdmulhq_s16(a, b)); - - // Multiply - int32x4_t mul_lo = vmull_s16(vget_low_s16(vreinterpretq_s16_m128i(a)), - vget_low_s16(vreinterpretq_s16_m128i(b))); - int32x4_t mul_hi = vmull_s16(vget_high_s16(vreinterpretq_s16_m128i(a)), - vget_high_s16(vreinterpretq_s16_m128i(b))); - - // Rounding narrowing shift right - // narrow = (int16_t)((mul + 16384) >> 15); - int16x4_t narrow_lo = vrshrn_n_s32(mul_lo, 15); - int16x4_t narrow_hi = vrshrn_n_s32(mul_hi, 15); - - // Join together - return vreinterpretq_m128i_s16(vcombine_s16(narrow_lo, narrow_hi)); + return vgetq_lane_s64(vreinterpretq_s64_m128i(a), 0); } -// Vertically multiply each unsigned 8-bit integer from a with the corresponding -// signed 8-bit integer from b, producing intermediate signed 16-bit integers. -// Horizontally add adjacent pairs of intermediate signed 16-bit integers, -// and pack the saturated results in dst. -// -// FOR j := 0 to 7 -// i := j*16 -// dst[i+15:i] := Saturate_To_Int16( a[i+15:i+8]*b[i+15:i+8] + -// a[i+7:i]*b[i+7:i] ) -// ENDFOR -FORCE_INLINE __m128i _mm_maddubs_epi16(__m128i _a, __m128i _b) +// Copy the lower 64-bit integer in a to dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si64x +#define _mm_cvtsi128_si64x(a) _mm_cvtsi128_si64(a) + +// Convert the signed 32-bit integer b to a double-precision (64-bit) +// floating-point element, store the result in the lower element of dst, and +// copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi32_sd +FORCE_INLINE __m128d _mm_cvtsi32_sd(__m128d a, int32_t b) { #if defined(__aarch64__) - uint8x16_t a = vreinterpretq_u8_m128i(_a); - int8x16_t b = vreinterpretq_s8_m128i(_b); - int16x8_t tl = vmulq_s16(vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(a))), - vmovl_s8(vget_low_s8(b))); - int16x8_t th = vmulq_s16(vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(a))), - vmovl_s8(vget_high_s8(b))); - return vreinterpretq_m128i_s16( - vqaddq_s16(vuzp1q_s16(tl, th), vuzp2q_s16(tl, th))); + return vreinterpretq_m128d_f64( + vsetq_lane_f64((double) b, vreinterpretq_f64_m128d(a), 0)); #else - // This would be much simpler if x86 would choose to zero extend OR sign - // extend, not both. This could probably be optimized better. - uint16x8_t a = vreinterpretq_u16_m128i(_a); - int16x8_t b = vreinterpretq_s16_m128i(_b); - - // Zero extend a - int16x8_t a_odd = vreinterpretq_s16_u16(vshrq_n_u16(a, 8)); - int16x8_t a_even = vreinterpretq_s16_u16(vbicq_u16(a, vdupq_n_u16(0xff00))); - - // Sign extend by shifting left then shifting right. - int16x8_t b_even = vshrq_n_s16(vshlq_n_s16(b, 8), 8); - int16x8_t b_odd = vshrq_n_s16(b, 8); - - // multiply - int16x8_t prod1 = vmulq_s16(a_even, b_even); - int16x8_t prod2 = vmulq_s16(a_odd, b_odd); - - // saturated add - return vreinterpretq_m128i_s16(vqaddq_s16(prod1, prod2)); + double bf = (double) b; + return vreinterpretq_m128d_s64( + vsetq_lane_s64(*(int64_t *) &bf, vreinterpretq_s64_m128d(a), 0)); #endif } -// Computes the fused multiple add product of 32-bit floating point numbers. +// Copy the lower 64-bit integer in a to dst. // -// Return Value -// Multiplies A and B, and adds C to the temporary result before returning it. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_fmadd -FORCE_INLINE __m128 _mm_fmadd_ps(__m128 a, __m128 b, __m128 c) +// dst[63:0] := a[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si64x +#define _mm_cvtsi128_si64x(a) _mm_cvtsi128_si64(a) + +// Moves 32-bit integer a to the least significant 32 bits of an __m128 object, +// zero extending the upper bits. +// +// r0 := a +// r1 := 0x0 +// r2 := 0x0 +// r3 := 0x0 +// +// https://msdn.microsoft.com/en-us/library/ct3539ha%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_cvtsi32_si128(int a) +{ + return vreinterpretq_m128i_s32(vsetq_lane_s32(a, vdupq_n_s32(0), 0)); +} + +// Convert the signed 64-bit integer b to a double-precision (64-bit) +// floating-point element, store the result in the lower element of dst, and +// copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi64_sd +FORCE_INLINE __m128d _mm_cvtsi64_sd(__m128d a, int64_t b) { #if defined(__aarch64__) - return vreinterpretq_m128_f32(vfmaq_f32(vreinterpretq_f32_m128(c), - vreinterpretq_f32_m128(b), - vreinterpretq_f32_m128(a))); + return vreinterpretq_m128d_f64( + vsetq_lane_f64((double) b, vreinterpretq_f64_m128d(a), 0)); #else - return _mm_add_ps(_mm_mul_ps(a, b), c); + double bf = (double) b; + return vreinterpretq_m128d_s64( + vsetq_lane_s64(*(int64_t *) &bf, vreinterpretq_s64_m128d(a), 0)); #endif } -// Alternatively add and subtract packed single-precision (32-bit) -// floating-point elements in a to/from packed elements in b, and store the -// results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=addsub_ps -FORCE_INLINE __m128 _mm_addsub_ps(__m128 a, __m128 b) +// Moves 64-bit integer a to the least significant 64 bits of an __m128 object, +// zero extending the upper bits. +// +// r0 := a +// r1 := 0x0 +FORCE_INLINE __m128i _mm_cvtsi64_si128(int64_t a) { - __m128 mask = {-1.0f, 1.0f, -1.0f, 1.0f}; - return _mm_fmadd_ps(b, mask, a); + return vreinterpretq_m128i_s64(vsetq_lane_s64(a, vdupq_n_s64(0), 0)); } -// Horizontally add adjacent pairs of double-precision (64-bit) floating-point -// elements in a and b, and pack the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pd -FORCE_INLINE __m128d _mm_hadd_pd(__m128d a, __m128d b) +// Copy 64-bit integer a to the lower element of dst, and zero the upper +// element. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi64x_si128 +#define _mm_cvtsi64x_si128(a) _mm_cvtsi64_si128(a) + +// Convert the signed 64-bit integer b to a double-precision (64-bit) +// floating-point element, store the result in the lower element of dst, and +// copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi64x_sd +#define _mm_cvtsi64x_sd(a, b) _mm_cvtsi64_sd(a, b) + +// Convert the lower single-precision (32-bit) floating-point element in b to a +// double-precision (64-bit) floating-point element, store the result in the +// lower element of dst, and copy the upper element from a to the upper element +// of dst. +// +// dst[63:0] := Convert_FP32_To_FP64(b[31:0]) +// dst[127:64] := a[127:64] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_sd +FORCE_INLINE __m128d _mm_cvtss_sd(__m128d a, __m128 b) { + double d = (double) vgetq_lane_f32(vreinterpretq_f32_m128(b), 0); #if defined(__aarch64__) return vreinterpretq_m128d_f64( - vpaddq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); + vsetq_lane_f64(d, vreinterpretq_f64_m128d(a), 0)); #else - double *da = (double *) &a; - double *db = (double *) &b; - double c[] = {da[0] + da[1], db[0] + db[1]}; - return vreinterpretq_m128d_u64(vld1q_u64((uint64_t *) c)); + return vreinterpretq_m128d_s64( + vsetq_lane_s64(*(int64_t *) &d, vreinterpretq_s64_m128d(a), 0)); #endif } -// Compute the absolute differences of packed unsigned 8-bit integers in a and -// b, then horizontally sum each consecutive 8 differences to produce two -// unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low -// 16 bits of 64-bit elements in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sad_epu8 -FORCE_INLINE __m128i _mm_sad_epu8(__m128i a, __m128i b) +// Convert packed double-precision (64-bit) floating-point elements in a to +// packed 32-bit integers with truncation, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttpd_epi32 +FORCE_INLINE __m128i _mm_cvttpd_epi32(__m128d a) { - uint16x8_t t = vpaddlq_u8(vabdq_u8((uint8x16_t) a, (uint8x16_t) b)); - uint16_t r0 = t[0] + t[1] + t[2] + t[3]; - uint16_t r4 = t[4] + t[5] + t[6] + t[7]; - uint16x8_t r = vsetq_lane_u16(r0, vdupq_n_u16(0), 0); - return (__m128i) vsetq_lane_u16(r4, r, 4); + double a0 = ((double *) &a)[0]; + double a1 = ((double *) &a)[1]; + return _mm_set_epi32(0, 0, (int32_t) a1, (int32_t) a0); } -// Compute the absolute differences of packed unsigned 8-bit integers in a and -// b, then horizontally sum each consecutive 8 differences to produce four -// unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low -// 16 bits of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sad_pu8 -FORCE_INLINE __m64 _mm_sad_pu8(__m64 a, __m64 b) +// Convert packed double-precision (64-bit) floating-point elements in a to +// packed 32-bit integers with truncation, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttpd_pi32 +FORCE_INLINE __m64 _mm_cvttpd_pi32(__m128d a) { - uint16x4_t t = - vpaddl_u8(vabd_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); - uint16_t r0 = t[0] + t[1] + t[2] + t[3]; - return vreinterpret_m64_u16(vset_lane_u16(r0, vdup_n_u16(0), 0)); + double a0 = ((double *) &a)[0]; + double a1 = ((double *) &a)[1]; + int32_t ALIGN_STRUCT(16) data[2] = {(int32_t) a0, (int32_t) a1}; + return vreinterpret_m64_s32(vld1_s32(data)); } -// Compute the absolute differences of packed unsigned 8-bit integers in a and -// b, then horizontally sum each consecutive 8 differences to produce four -// unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low -// 16 bits of dst. +// Converts the four single-precision, floating-point values of a to signed +// 32-bit integer values using truncate. +// https://msdn.microsoft.com/en-us/library/vstudio/1h005y6x(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cvttps_epi32(__m128 a) +{ + return vreinterpretq_m128i_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a))); +} + +// Convert the lower double-precision (64-bit) floating-point element in a to a +// 32-bit integer with truncation, and store the result in dst. // -// FOR j := 0 to 7 -// i := j*8 -// tmp[i+7:i] := ABS(a[i+7:i] - b[i+7:i]) -// ENDFOR -// dst[15:0] := tmp[7:0] + tmp[15:8] + tmp[23:16] + tmp[31:24] + tmp[39:32] + -// tmp[47:40] + tmp[55:48] + tmp[63:56] dst[63:16] := 0 +// dst[63:0] := Convert_FP64_To_Int32_Truncate(a[63:0]) // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_psadbw -#define _m_psadbw(a, b) _mm_sad_pu8(a, b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttsd_si32 +FORCE_INLINE int32_t _mm_cvttsd_si32(__m128d a) +{ + double ret = *((double *) &a); + return (int32_t) ret; +} -// Divides the four single-precision, floating-point values of a and b. +// Convert the lower double-precision (64-bit) floating-point element in a to a +// 64-bit integer with truncation, and store the result in dst. // -// r0 := a0 / b0 -// r1 := a1 / b1 -// r2 := a2 / b2 -// r3 := a3 / b3 +// dst[63:0] := Convert_FP64_To_Int64_Truncate(a[63:0]) // -// https://msdn.microsoft.com/en-us/library/edaw8147(v=vs.100).aspx -FORCE_INLINE __m128 _mm_div_ps(__m128 a, __m128 b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttsd_si64 +FORCE_INLINE int64_t _mm_cvttsd_si64(__m128d a) { -#if defined(__aarch64__) && !SSE2NEON_PRECISE_DIV - return vreinterpretq_m128_f32( - vdivq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#if defined(__aarch64__) + return vgetq_lane_s64(vcvtq_s64_f64(vreinterpretq_f64_m128d(a)), 0); #else - float32x4_t recip = vrecpeq_f32(vreinterpretq_f32_m128(b)); - recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(b))); -#if SSE2NEON_PRECISE_DIV - // Additional Netwon-Raphson iteration for accuracy - recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(b))); -#endif - return vreinterpretq_m128_f32(vmulq_f32(vreinterpretq_f32_m128(a), recip)); + double ret = *((double *) &a); + return (int64_t) ret; #endif } -// Divides the scalar single-precision floating point value of a by b. -// https://msdn.microsoft.com/en-us/library/4y73xa49(v=vs.100).aspx -FORCE_INLINE __m128 _mm_div_ss(__m128 a, __m128 b) -{ - float32_t value = - vgetq_lane_f32(vreinterpretq_f32_m128(_mm_div_ps(a, b)), 0); - return vreinterpretq_m128_f32( - vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); -} +// Convert the lower double-precision (64-bit) floating-point element in a to a +// 64-bit integer with truncation, and store the result in dst. +// +// dst[63:0] := Convert_FP64_To_Int64_Truncate(a[63:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttsd_si64x +#define _mm_cvttsd_si64x(a) _mm_cvttsd_si64(a) // Divide packed double-precision (64-bit) floating-point elements in a by // packed elements in b, and store the results in dst. @@ -3875,266 +4340,230 @@ FORCE_INLINE __m128d _mm_div_sd(__m128d a, __m128d b) #endif } -// Compute the approximate reciprocal of packed single-precision (32-bit) -// floating-point elements in a, and store the results in dst. The maximum -// relative error for this approximation is less than 1.5*2^-12. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rcp_ps -FORCE_INLINE __m128 _mm_rcp_ps(__m128 in) +// Extracts the selected signed or unsigned 16-bit integer from a and zero +// extends. +// https://msdn.microsoft.com/en-us/library/6dceta0c(v=vs.100).aspx +// FORCE_INLINE int _mm_extract_epi16(__m128i a, __constrange(0,8) int imm) +#define _mm_extract_epi16(a, imm) \ + vgetq_lane_u16(vreinterpretq_u16_m128i(a), (imm)) + +// Inserts the least significant 16 bits of b into the selected 16-bit integer +// of a. +// https://msdn.microsoft.com/en-us/library/kaze8hz1%28v=vs.100%29.aspx +// FORCE_INLINE __m128i _mm_insert_epi16(__m128i a, int b, +// __constrange(0,8) int imm) +#define _mm_insert_epi16(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s16( \ + vsetq_lane_s16((b), vreinterpretq_s16_m128i(a), (imm))); \ + }) + +// Loads two double-precision from 16-byte aligned memory, floating-point +// values. +// +// dst[127:0] := MEM[mem_addr+127:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_pd +FORCE_INLINE __m128d _mm_load_pd(const double *p) { - float32x4_t recip = vrecpeq_f32(vreinterpretq_f32_m128(in)); - recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(in))); -#if SSE2NEON_PRECISE_DIV - // Additional Netwon-Raphson iteration for accuracy - recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(in))); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vld1q_f64(p)); +#else + const float *fp = (const float *) p; + float ALIGN_STRUCT(16) data[4] = {fp[0], fp[1], fp[2], fp[3]}; + return vreinterpretq_m128d_f32(vld1q_f32(data)); #endif - return vreinterpretq_m128_f32(recip); } -// Compute the approximate reciprocal of the lower single-precision (32-bit) -// floating-point element in a, store the result in the lower element of dst, -// and copy the upper 3 packed elements from a to the upper elements of dst. The -// maximum relative error for this approximation is less than 1.5*2^-12. +// Load a double-precision (64-bit) floating-point element from memory into both +// elements of dst. // -// dst[31:0] := (1.0 / a[31:0]) -// dst[127:32] := a[127:32] +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := MEM[mem_addr+63:mem_addr] // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rcp_ss -FORCE_INLINE __m128 _mm_rcp_ss(__m128 a) -{ - return _mm_move_ss(a, _mm_rcp_ps(a)); -} +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_pd1 +#define _mm_load_pd1 _mm_load1_pd -// Computes the approximations of square roots of the four single-precision, -// floating-point values of a. First computes reciprocal square roots and then -// reciprocals of the four values. +// Load a double-precision (64-bit) floating-point element from memory into the +// lower of dst, and zero the upper element. mem_addr does not need to be +// aligned on any particular boundary. // -// r0 := sqrt(a0) -// r1 := sqrt(a1) -// r2 := sqrt(a2) -// r3 := sqrt(a3) +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := 0 // -// https://msdn.microsoft.com/en-us/library/vstudio/8z67bwwk(v=vs.100).aspx -FORCE_INLINE __m128 _mm_sqrt_ps(__m128 in) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_sd +FORCE_INLINE __m128d _mm_load_sd(const double *p) { -#if SSE2NEON_PRECISE_SQRT - float32x4_t recip = vrsqrteq_f32(vreinterpretq_f32_m128(in)); - - // Test for vrsqrteq_f32(0) -> positive infinity case. - // Change to zero, so that s * 1/sqrt(s) result is zero too. - const uint32x4_t pos_inf = vdupq_n_u32(0x7F800000); - const uint32x4_t div_by_zero = - vceqq_u32(pos_inf, vreinterpretq_u32_f32(recip)); - recip = vreinterpretq_f32_u32( - vandq_u32(vmvnq_u32(div_by_zero), vreinterpretq_u32_f32(recip))); - - // Additional Netwon-Raphson iteration for accuracy - recip = vmulq_f32( - vrsqrtsq_f32(vmulq_f32(recip, recip), vreinterpretq_f32_m128(in)), - recip); - recip = vmulq_f32( - vrsqrtsq_f32(vmulq_f32(recip, recip), vreinterpretq_f32_m128(in)), - recip); - - // sqrt(s) = s * 1/sqrt(s) - return vreinterpretq_m128_f32(vmulq_f32(vreinterpretq_f32_m128(in), recip)); -#elif defined(__aarch64__) - return vreinterpretq_m128_f32(vsqrtq_f32(vreinterpretq_f32_m128(in))); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vsetq_lane_f64(*p, vdupq_n_f64(0), 0)); #else - float32x4_t recipsq = vrsqrteq_f32(vreinterpretq_f32_m128(in)); - float32x4_t sq = vrecpeq_f32(recipsq); - return vreinterpretq_m128_f32(sq); + const float *fp = (const float *) p; + float ALIGN_STRUCT(16) data[4] = {fp[0], fp[1], 0, 0}; + return vreinterpretq_m128d_f32(vld1q_f32(data)); #endif } -// Computes the approximation of the square root of the scalar single-precision -// floating point value of in. -// https://msdn.microsoft.com/en-us/library/ahfsc22d(v=vs.100).aspx -FORCE_INLINE __m128 _mm_sqrt_ss(__m128 in) +// Loads 128-bit value. : +// https://msdn.microsoft.com/en-us/library/atzzad1h(v=vs.80).aspx +FORCE_INLINE __m128i _mm_load_si128(const __m128i *p) { - float32_t value = - vgetq_lane_f32(vreinterpretq_f32_m128(_mm_sqrt_ps(in)), 0); - return vreinterpretq_m128_f32( - vsetq_lane_f32(value, vreinterpretq_f32_m128(in), 0)); + return vreinterpretq_m128i_s32(vld1q_s32((const int32_t *) p)); } -// Computes the approximations of the reciprocal square roots of the four -// single-precision floating point values of in. -// https://msdn.microsoft.com/en-us/library/22hfsh53(v=vs.100).aspx -FORCE_INLINE __m128 _mm_rsqrt_ps(__m128 in) +// Load a double-precision (64-bit) floating-point element from memory into both +// elements of dst. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := MEM[mem_addr+63:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load1_pd +FORCE_INLINE __m128d _mm_load1_pd(const double *p) { - float32x4_t out = vrsqrteq_f32(vreinterpretq_f32_m128(in)); -#if SSE2NEON_PRECISE_RSQRT - // Additional Netwon-Raphson iteration for accuracy - out = vmulq_f32( - out, vrsqrtsq_f32(vmulq_f32(vreinterpretq_f32_m128(in), out), out)); - out = vmulq_f32( - out, vrsqrtsq_f32(vmulq_f32(vreinterpretq_f32_m128(in), out), out)); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vld1q_dup_f64(p)); +#else + return vreinterpretq_m128d_s64(vdupq_n_s64(*(const int64_t *) p)); #endif - return vreinterpretq_m128_f32(out); } -// Compute the approximate reciprocal square root of the lower single-precision -// (32-bit) floating-point element in a, store the result in the lower element -// of dst, and copy the upper 3 packed elements from a to the upper elements of -// dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rsqrt_ss -FORCE_INLINE __m128 _mm_rsqrt_ss(__m128 in) +// Load a double-precision (64-bit) floating-point element from memory into the +// upper element of dst, and copy the lower element from a to dst. mem_addr does +// not need to be aligned on any particular boundary. +// +// dst[63:0] := a[63:0] +// dst[127:64] := MEM[mem_addr+63:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadh_pd +FORCE_INLINE __m128d _mm_loadh_pd(__m128d a, const double *p) { - return vsetq_lane_f32(vgetq_lane_f32(_mm_rsqrt_ps(in), 0), in, 0); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vcombine_f64(vget_low_f64(vreinterpretq_f64_m128d(a)), vld1_f64(p))); +#else + return vreinterpretq_m128d_f32(vcombine_f32( + vget_low_f32(vreinterpretq_f32_m128d(a)), vld1_f32((const float *) p))); +#endif } -// Compare packed signed 16-bit integers in a and b, and store packed maximum -// values in dst. -// -// FOR j := 0 to 3 -// i := j*16 -// dst[i+15:i] := MAX(a[i+15:i], b[i+15:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pi16 -FORCE_INLINE __m64 _mm_max_pi16(__m64 a, __m64 b) +// Load 64-bit integer from memory into the first element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadl_epi64 +FORCE_INLINE __m128i _mm_loadl_epi64(__m128i const *p) { - return vreinterpret_m64_s16( - vmax_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b))); + /* Load the lower 64 bits of the value pointed to by p into the + * lower 64 bits of the result, zeroing the upper 64 bits of the result. + */ + return vreinterpretq_m128i_s32( + vcombine_s32(vld1_s32((int32_t const *) p), vcreate_s32(0))); } -// Compare packed signed 16-bit integers in a and b, and store packed maximum -// values in dst. +// Load a double-precision (64-bit) floating-point element from memory into the +// lower element of dst, and copy the upper element from a to dst. mem_addr does +// not need to be aligned on any particular boundary. // -// FOR j := 0 to 3 -// i := j*16 -// dst[i+15:i] := MAX(a[i+15:i], b[i+15:i]) -// ENDFOR +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := a[127:64] // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pi16 -#define _m_pmaxsw(a, b) _mm_max_pi16(a, b) - -// Computes the maximums of the four single-precision, floating-point values of -// a and b. -// https://msdn.microsoft.com/en-us/library/vstudio/ff5d607a(v=vs.100).aspx -FORCE_INLINE __m128 _mm_max_ps(__m128 a, __m128 b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadl_pd +FORCE_INLINE __m128d _mm_loadl_pd(__m128d a, const double *p) { -#if SSE2NEON_PRECISE_MINMAX - float32x4_t _a = vreinterpretq_f32_m128(a); - float32x4_t _b = vreinterpretq_f32_m128(b); - return vbslq_f32(vcltq_f32(_b, _a), _a, _b); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vcombine_f64(vld1_f64(p), vget_high_f64(vreinterpretq_f64_m128d(a)))); #else - return vreinterpretq_m128_f32( - vmaxq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); + return vreinterpretq_m128d_f32( + vcombine_f32(vld1_f32((const float *) p), + vget_high_f32(vreinterpretq_f32_m128d(a)))); #endif } -// Compare packed unsigned 8-bit integers in a and b, and store packed maximum -// values in dst. +// Load 2 double-precision (64-bit) floating-point elements from memory into dst +// in reverse order. mem_addr must be aligned on a 16-byte boundary or a +// general-protection exception may be generated. // -// FOR j := 0 to 7 -// i := j*8 -// dst[i+7:i] := MAX(a[i+7:i], b[i+7:i]) -// ENDFOR +// dst[63:0] := MEM[mem_addr+127:mem_addr+64] +// dst[127:64] := MEM[mem_addr+63:mem_addr] // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pu8 -FORCE_INLINE __m64 _mm_max_pu8(__m64 a, __m64 b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadr_pd +FORCE_INLINE __m128d _mm_loadr_pd(const double *p) { - return vreinterpret_m64_u8( - vmax_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); +#if defined(__aarch64__) + float64x2_t v = vld1q_f64(p); + return vreinterpretq_m128d_f64(vextq_f64(v, v, 1)); +#else + int64x2_t v = vld1q_s64((const int64_t *) p); + return vreinterpretq_m128d_s64(vextq_s64(v, v, 1)); +#endif } -// Compare packed unsigned 8-bit integers in a and b, and store packed maximum -// values in dst. -// -// FOR j := 0 to 7 -// i := j*8 -// dst[i+7:i] := MAX(a[i+7:i], b[i+7:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pu8 -#define _m_pmaxub(a, b) _mm_max_pu8(a, b) - -// Compare packed signed 16-bit integers in a and b, and store packed minimum -// values in dst. -// -// FOR j := 0 to 3 -// i := j*16 -// dst[i+15:i] := MIN(a[i+15:i], b[i+15:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pi16 -FORCE_INLINE __m64 _mm_min_pi16(__m64 a, __m64 b) +// Loads two double-precision from unaligned memory, floating-point values. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_pd +FORCE_INLINE __m128d _mm_loadu_pd(const double *p) { - return vreinterpret_m64_s16( - vmin_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b))); + return _mm_load_pd(p); } -// Compare packed signed 16-bit integers in a and b, and store packed minimum -// values in dst. -// -// FOR j := 0 to 3 -// i := j*16 -// dst[i+15:i] := MIN(a[i+15:i], b[i+15:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pi16 -#define _m_pminsw(a, b) _mm_min_pi16(a, b) - -// Computes the minima of the four single-precision, floating-point values of a -// and b. -// https://msdn.microsoft.com/en-us/library/vstudio/wh13kadz(v=vs.100).aspx -FORCE_INLINE __m128 _mm_min_ps(__m128 a, __m128 b) +// Loads 128-bit value. : +// https://msdn.microsoft.com/zh-cn/library/f4k12ae8(v=vs.90).aspx +FORCE_INLINE __m128i _mm_loadu_si128(const __m128i *p) { -#if SSE2NEON_PRECISE_MINMAX - float32x4_t _a = vreinterpretq_f32_m128(a); - float32x4_t _b = vreinterpretq_f32_m128(b); - return vbslq_f32(vcltq_f32(_a, _b), _a, _b); -#else - return vreinterpretq_m128_f32( - vminq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); -#endif + return vreinterpretq_m128i_s32(vld1q_s32((const int32_t *) p)); } -// Compare packed unsigned 8-bit integers in a and b, and store packed minimum -// values in dst. +// Load unaligned 32-bit integer from memory into the first element of dst. // -// FOR j := 0 to 7 -// i := j*8 -// dst[i+7:i] := MIN(a[i+7:i], b[i+7:i]) -// ENDFOR +// dst[31:0] := MEM[mem_addr+31:mem_addr] +// dst[MAX:32] := 0 // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pu8 -FORCE_INLINE __m64 _mm_min_pu8(__m64 a, __m64 b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si32 +FORCE_INLINE __m128i _mm_loadu_si32(const void *p) { - return vreinterpret_m64_u8( - vmin_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); + return vreinterpretq_m128i_s32( + vsetq_lane_s32(*(const int32_t *) p, vdupq_n_s32(0), 0)); } -// Compare packed unsigned 8-bit integers in a and b, and store packed minimum -// values in dst. -// -// FOR j := 0 to 7 -// i := j*8 -// dst[i+7:i] := MIN(a[i+7:i], b[i+7:i]) -// ENDFOR +// Multiplies the 8 signed 16-bit integers from a by the 8 signed 16-bit +// integers from b. // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pu8 -#define _m_pminub(a, b) _mm_min_pu8(a, b) +// r0 := (a0 * b0) + (a1 * b1) +// r1 := (a2 * b2) + (a3 * b3) +// r2 := (a4 * b4) + (a5 * b5) +// r3 := (a6 * b6) + (a7 * b7) +// https://msdn.microsoft.com/en-us/library/yht36sa6(v=vs.90).aspx +FORCE_INLINE __m128i _mm_madd_epi16(__m128i a, __m128i b) +{ + int32x4_t low = vmull_s16(vget_low_s16(vreinterpretq_s16_m128i(a)), + vget_low_s16(vreinterpretq_s16_m128i(b))); + int32x4_t high = vmull_s16(vget_high_s16(vreinterpretq_s16_m128i(a)), + vget_high_s16(vreinterpretq_s16_m128i(b))); -// Computes the maximum of the two lower scalar single-precision floating point -// values of a and b. -// https://msdn.microsoft.com/en-us/library/s6db5esz(v=vs.100).aspx -FORCE_INLINE __m128 _mm_max_ss(__m128 a, __m128 b) + int32x2_t low_sum = vpadd_s32(vget_low_s32(low), vget_high_s32(low)); + int32x2_t high_sum = vpadd_s32(vget_low_s32(high), vget_high_s32(high)); + + return vreinterpretq_m128i_s32(vcombine_s32(low_sum, high_sum)); +} + +// Conditionally store 8-bit integer elements from a into memory using mask +// (elements are not stored when the highest bit is not set in the corresponding +// element) and a non-temporal memory hint. mem_addr does not need to be aligned +// on any particular boundary. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_maskmoveu_si128 +FORCE_INLINE void _mm_maskmoveu_si128(__m128i a, __m128i mask, char *mem_addr) { - float32_t value = vgetq_lane_f32(_mm_max_ps(a, b), 0); - return vreinterpretq_m128_f32( - vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); + int8x16_t shr_mask = vshrq_n_s8(vreinterpretq_s8_m128i(mask), 7); + __m128 b = _mm_load_ps((const float *) mem_addr); + int8x16_t masked = + vbslq_s8(vreinterpretq_u8_s8(shr_mask), vreinterpretq_s8_m128i(a), + vreinterpretq_s8_m128(b)); + vst1q_s8((int8_t *) mem_addr, masked); } -// Computes the minimum of the two lower scalar single-precision floating point -// values of a and b. -// https://msdn.microsoft.com/en-us/library/0a9y7xaa(v=vs.100).aspx -FORCE_INLINE __m128 _mm_min_ss(__m128 a, __m128 b) +// Computes the pairwise maxima of the 8 signed 16-bit integers from a and the 8 +// signed 16-bit integers from b. +// https://msdn.microsoft.com/en-us/LIBRary/3x060h7c(v=vs.100).aspx +FORCE_INLINE __m128i _mm_max_epi16(__m128i a, __m128i b) { - float32_t value = vgetq_lane_f32(_mm_min_ps(a, b), 0); - return vreinterpretq_m128_f32( - vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); + return vreinterpretq_m128i_s16( + vmaxq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); } // Computes the pairwise maxima of the 16 unsigned 8-bit integers from a and the @@ -4146,13 +4575,41 @@ FORCE_INLINE __m128i _mm_max_epu8(__m128i a, __m128i b) vmaxq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); } -// Computes the pairwise minima of the 16 unsigned 8-bit integers from a and the -// 16 unsigned 8-bit integers from b. -// https://msdn.microsoft.com/ko-kr/library/17k8cf58(v=vs.100).aspxx -FORCE_INLINE __m128i _mm_min_epu8(__m128i a, __m128i b) +// Compare packed double-precision (64-bit) floating-point elements in a and b, +// and store packed maximum values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pd +FORCE_INLINE __m128d _mm_max_pd(__m128d a, __m128d b) { - return vreinterpretq_m128i_u8( - vminq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vmaxq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) > (*(double *) &b0) ? a0 : b0; + d[1] = (*(double *) &a1) > (*(double *) &b1) ? a1 : b1; + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b, store the maximum value in the lower element of dst, and copy the upper +// element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_sd +FORCE_INLINE __m128d _mm_max_sd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return _mm_move_sd(a, _mm_max_pd(a, b)); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[2] = {fmax(da[0], db[0]), da[1]}; + return vld1q_f32((float32_t *) c); +#endif } // Computes the pairwise minima of the 8 signed 16-bit integers from a and the 8 @@ -4164,110 +4621,246 @@ FORCE_INLINE __m128i _mm_min_epi16(__m128i a, __m128i b) vminq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); } -// Compare packed signed 8-bit integers in a and b, and store packed maximum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epi8 -FORCE_INLINE __m128i _mm_max_epi8(__m128i a, __m128i b) +// Computes the pairwise minima of the 16 unsigned 8-bit integers from a and the +// 16 unsigned 8-bit integers from b. +// https://msdn.microsoft.com/ko-kr/library/17k8cf58(v=vs.100).aspxx +FORCE_INLINE __m128i _mm_min_epu8(__m128i a, __m128i b) { - return vreinterpretq_m128i_s8( - vmaxq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); + return vreinterpretq_m128i_u8( + vminq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); } -// Compare packed unsigned 16-bit integers in a and b, and store packed maximum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu16 -FORCE_INLINE __m128i _mm_max_epu16(__m128i a, __m128i b) +// Compare packed double-precision (64-bit) floating-point elements in a and b, +// and store packed minimum values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pd +FORCE_INLINE __m128d _mm_min_pd(__m128d a, __m128d b) { - return vreinterpretq_m128i_u16( - vmaxq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vminq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) < (*(double *) &b0) ? a0 : b0; + d[1] = (*(double *) &a1) < (*(double *) &b1) ? a1 : b1; + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif } -// Compare packed signed 8-bit integers in a and b, and store packed minimum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_epi8 -FORCE_INLINE __m128i _mm_min_epi8(__m128i a, __m128i b) +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b, store the minimum value in the lower element of dst, and copy the upper +// element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_sd +FORCE_INLINE __m128d _mm_min_sd(__m128d a, __m128d b) { - return vreinterpretq_m128i_s8( - vminq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +#if defined(__aarch64__) + return _mm_move_sd(a, _mm_min_pd(a, b)); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[2] = {fmin(da[0], db[0]), da[1]}; + return vld1q_f32((float32_t *) c); +#endif } -// Compare packed unsigned 16-bit integers in a and b, and store packed minimum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_epu16 -FORCE_INLINE __m128i _mm_min_epu16(__m128i a, __m128i b) +// Copy the lower 64-bit integer in a to the lower element of dst, and zero the +// upper element. +// +// dst[63:0] := a[63:0] +// dst[127:64] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_move_epi64 +FORCE_INLINE __m128i _mm_move_epi64(__m128i a) { - return vreinterpretq_m128i_u16( - vminq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); + return vreinterpretq_m128i_s64( + vsetq_lane_s64(0, vreinterpretq_s64_m128i(a), 1)); } -// Computes the pairwise maxima of the 8 signed 16-bit integers from a and the 8 -// signed 16-bit integers from b. -// https://msdn.microsoft.com/en-us/LIBRary/3x060h7c(v=vs.100).aspx -FORCE_INLINE __m128i _mm_max_epi16(__m128i a, __m128i b) +// Move the lower double-precision (64-bit) floating-point element from b to the +// lower element of dst, and copy the upper element from a to the upper element +// of dst. +// +// dst[63:0] := b[63:0] +// dst[127:64] := a[127:64] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_move_sd +FORCE_INLINE __m128d _mm_move_sd(__m128d a, __m128d b) { - return vreinterpretq_m128i_s16( - vmaxq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); + return vreinterpretq_m128d_f32( + vcombine_f32(vget_low_f32(vreinterpretq_f32_m128d(b)), + vget_high_f32(vreinterpretq_f32_m128d(a)))); } -// epi versions of min/max -// Computes the pariwise maximums of the four signed 32-bit integer values of a -// and b. +// NEON does not provide a version of this function. +// Creates a 16-bit mask from the most significant bits of the 16 signed or +// unsigned 8-bit integers in a and zero extends the upper bits. +// https://msdn.microsoft.com/en-us/library/vstudio/s090c8fk(v=vs.100).aspx +FORCE_INLINE int _mm_movemask_epi8(__m128i a) +{ + // Use increasingly wide shifts+adds to collect the sign bits + // together. + // Since the widening shifts would be rather confusing to follow in little + // endian, everything will be illustrated in big endian order instead. This + // has a different result - the bits would actually be reversed on a big + // endian machine. + + // Starting input (only half the elements are shown): + // 89 ff 1d c0 00 10 99 33 + uint8x16_t input = vreinterpretq_u8_m128i(a); + + // Shift out everything but the sign bits with an unsigned shift right. + // + // Bytes of the vector:: + // 89 ff 1d c0 00 10 99 33 + // \ \ \ \ \ \ \ \ high_bits = (uint16x4_t)(input >> 7) + // | | | | | | | | + // 01 01 00 01 00 00 01 00 + // + // Bits of first important lane(s): + // 10001001 (89) + // \______ + // | + // 00000001 (01) + uint16x8_t high_bits = vreinterpretq_u16_u8(vshrq_n_u8(input, 7)); + + // Merge the even lanes together with a 16-bit unsigned shift right + add. + // 'xx' represents garbage data which will be ignored in the final result. + // In the important bytes, the add functions like a binary OR. + // + // 01 01 00 01 00 00 01 00 + // \_ | \_ | \_ | \_ | paired16 = (uint32x4_t)(input + (input >> 7)) + // \| \| \| \| + // xx 03 xx 01 xx 00 xx 02 + // + // 00000001 00000001 (01 01) + // \_______ | + // \| + // xxxxxxxx xxxxxx11 (xx 03) + uint32x4_t paired16 = + vreinterpretq_u32_u16(vsraq_n_u16(high_bits, high_bits, 7)); + + // Repeat with a wider 32-bit shift + add. + // xx 03 xx 01 xx 00 xx 02 + // \____ | \____ | paired32 = (uint64x1_t)(paired16 + (paired16 >> + // 14)) + // \| \| + // xx xx xx 0d xx xx xx 02 + // + // 00000011 00000001 (03 01) + // \\_____ || + // '----.\|| + // xxxxxxxx xxxx1101 (xx 0d) + uint64x2_t paired32 = + vreinterpretq_u64_u32(vsraq_n_u32(paired16, paired16, 14)); + + // Last, an even wider 64-bit shift + add to get our result in the low 8 bit + // lanes. xx xx xx 0d xx xx xx 02 + // \_________ | paired64 = (uint8x8_t)(paired32 + (paired32 >> + // 28)) + // \| + // xx xx xx xx xx xx xx d2 + // + // 00001101 00000010 (0d 02) + // \ \___ | | + // '---. \| | + // xxxxxxxx 11010010 (xx d2) + uint8x16_t paired64 = + vreinterpretq_u8_u64(vsraq_n_u64(paired32, paired32, 28)); + + // Extract the low 8 bits from each 64-bit lane with 2 8-bit extracts. + // xx xx xx xx xx xx xx d2 + // || return paired64[0] + // d2 + // Note: Little endian would return the correct value 4b (01001011) instead. + return vgetq_lane_u8(paired64, 0) | ((int) vgetq_lane_u8(paired64, 8) << 8); +} + +// Set each bit of mask dst based on the most significant bit of the +// corresponding packed double-precision (64-bit) floating-point element in a. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movemask_pd +FORCE_INLINE int _mm_movemask_pd(__m128d a) +{ + uint64x2_t input = vreinterpretq_u64_m128d(a); + uint64x2_t high_bits = vshrq_n_u64(input, 63); + return vgetq_lane_u64(high_bits, 0) | (vgetq_lane_u64(high_bits, 1) << 1); +} + +// Copy the lower 64-bit integer in a to dst. // -// A 128-bit parameter that can be defined with the following equations: -// r0 := (a0 > b0) ? a0 : b0 -// r1 := (a1 > b1) ? a1 : b1 -// r2 := (a2 > b2) ? a2 : b2 -// r3 := (a3 > b3) ? a3 : b3 +// dst[63:0] := a[63:0] // -// https://msdn.microsoft.com/en-us/library/vstudio/bb514055(v=vs.100).aspx -FORCE_INLINE __m128i _mm_max_epi32(__m128i a, __m128i b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movepi64_pi64 +FORCE_INLINE __m64 _mm_movepi64_pi64(__m128i a) { - return vreinterpretq_m128i_s32( - vmaxq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); + return vreinterpret_m64_s64(vget_low_s64(vreinterpretq_s64_m128i(a))); } -// Computes the pariwise minima of the four signed 32-bit integer values of a -// and b. +// Copy the 64-bit integer a to the lower element of dst, and zero the upper +// element. // -// A 128-bit parameter that can be defined with the following equations: -// r0 := (a0 < b0) ? a0 : b0 -// r1 := (a1 < b1) ? a1 : b1 -// r2 := (a2 < b2) ? a2 : b2 -// r3 := (a3 < b3) ? a3 : b3 +// dst[63:0] := a[63:0] +// dst[127:64] := 0 // -// https://msdn.microsoft.com/en-us/library/vstudio/bb531476(v=vs.100).aspx -FORCE_INLINE __m128i _mm_min_epi32(__m128i a, __m128i b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movpi64_epi64 +FORCE_INLINE __m128i _mm_movpi64_epi64(__m64 a) { - return vreinterpretq_m128i_s32( - vminq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); + return vreinterpretq_m128i_s64( + vcombine_s64(vreinterpret_s64_m64(a), vdup_n_s64(0))); } -// Compare packed unsigned 32-bit integers in a and b, and store packed maximum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu32 -FORCE_INLINE __m128i _mm_max_epu32(__m128i a, __m128i b) +// Multiply the low unsigned 32-bit integers from each packed 64-bit element in +// a and b, and store the unsigned 64-bit results in dst. +// +// r0 := (a0 & 0xFFFFFFFF) * (b0 & 0xFFFFFFFF) +// r1 := (a2 & 0xFFFFFFFF) * (b2 & 0xFFFFFFFF) +FORCE_INLINE __m128i _mm_mul_epu32(__m128i a, __m128i b) { - return vreinterpretq_m128i_u32( - vmaxq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b))); + // vmull_u32 upcasts instead of masking, so we downcast. + uint32x2_t a_lo = vmovn_u64(vreinterpretq_u64_m128i(a)); + uint32x2_t b_lo = vmovn_u64(vreinterpretq_u64_m128i(b)); + return vreinterpretq_m128i_u64(vmull_u32(a_lo, b_lo)); } -// Compare packed unsigned 32-bit integers in a and b, and store packed minimum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu32 -FORCE_INLINE __m128i _mm_min_epu32(__m128i a, __m128i b) +// Multiply packed double-precision (64-bit) floating-point elements in a and b, +// and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_pd +FORCE_INLINE __m128d _mm_mul_pd(__m128d a, __m128d b) { - return vreinterpretq_m128i_u32( - vminq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b))); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vmulq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[2]; + c[0] = da[0] * db[0]; + c[1] = da[1] * db[1]; + return vld1q_f32((float32_t *) c); +#endif } -// Multiply the packed unsigned 16-bit integers in a and b, producing -// intermediate 32-bit integers, and store the high 16 bits of the intermediate -// integers in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mulhi_pu16 -FORCE_INLINE __m64 _mm_mulhi_pu16(__m64 a, __m64 b) +// Multiply the lower double-precision (64-bit) floating-point element in a and +// b, store the result in the lower element of dst, and copy the upper element +// from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_mul_sd +FORCE_INLINE __m128d _mm_mul_sd(__m128d a, __m128d b) { - return vreinterpret_m64_u16(vshrn_n_u32( - vmull_u16(vreinterpret_u16_m64(a), vreinterpret_u16_m64(b)), 16)); + return _mm_move_sd(a, _mm_mul_pd(a, b)); +} + +// Multiply the low unsigned 32-bit integers from a and b, and store the +// unsigned 64-bit result in dst. +// +// dst[63:0] := a[31:0] * b[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_su32 +FORCE_INLINE __m64 _mm_mul_su32(__m64 a, __m64 b) +{ + return vreinterpret_m64_u64(vget_low_u64( + vmull_u32(vreinterpret_u32_m64(a), vreinterpret_u32_m64(b)))); } // Multiplies the 8 signed 16-bit integers from a by the 8 signed 16-bit @@ -4321,1341 +4914,2413 @@ FORCE_INLINE __m128i _mm_mulhi_epu16(__m128i a, __m128i b) #endif } -// Computes pairwise add of each argument as single-precision, floating-point -// values a and b. -// https://msdn.microsoft.com/en-us/library/yd9wecaa.aspx -FORCE_INLINE __m128 _mm_hadd_ps(__m128 a, __m128 b) +// Multiplies the 8 signed or unsigned 16-bit integers from a by the 8 signed or +// unsigned 16-bit integers from b. +// +// r0 := (a0 * b0)[15:0] +// r1 := (a1 * b1)[15:0] +// ... +// r7 := (a7 * b7)[15:0] +// +// https://msdn.microsoft.com/en-us/library/vstudio/9ks1472s(v=vs.100).aspx +FORCE_INLINE __m128i _mm_mullo_epi16(__m128i a, __m128i b) { -#if defined(__aarch64__) - return vreinterpretq_m128_f32( - vpaddq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); -#else - float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); - float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a)); - float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); - float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b)); - return vreinterpretq_m128_f32( - vcombine_f32(vpadd_f32(a10, a32), vpadd_f32(b10, b32))); -#endif + return vreinterpretq_m128i_s16( + vmulq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); } -// Computes pairwise add of each argument as a 16-bit signed or unsigned integer -// values a and b. -FORCE_INLINE __m128i _mm_hadd_epi16(__m128i _a, __m128i _b) +// Compute the bitwise OR of packed double-precision (64-bit) floating-point +// elements in a and b, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_or_pd +FORCE_INLINE __m128d _mm_or_pd(__m128d a, __m128d b) { - int16x8_t a = vreinterpretq_s16_m128i(_a); - int16x8_t b = vreinterpretq_s16_m128i(_b); -#if defined(__aarch64__) - return vreinterpretq_m128i_s16(vpaddq_s16(a, b)); -#else - return vreinterpretq_m128i_s16( - vcombine_s16(vpadd_s16(vget_low_s16(a), vget_high_s16(a)), - vpadd_s16(vget_low_s16(b), vget_high_s16(b)))); -#endif + return vreinterpretq_m128d_s64( + vorrq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b))); } -// Horizontally substract adjacent pairs of single-precision (32-bit) -// floating-point elements in a and b, and pack the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsub_ps -FORCE_INLINE __m128 _mm_hsub_ps(__m128 _a, __m128 _b) +// Computes the bitwise OR of the 128-bit value in a and the 128-bit value in b. +// +// r := a | b +// +// https://msdn.microsoft.com/en-us/library/vstudio/ew8ty0db(v=vs.100).aspx +FORCE_INLINE __m128i _mm_or_si128(__m128i a, __m128i b) { -#if defined(__aarch64__) - return vreinterpretq_m128_f32(vsubq_f32( - vuzp1q_f32(vreinterpretq_f32_m128(_a), vreinterpretq_f32_m128(_b)), - vuzp2q_f32(vreinterpretq_f32_m128(_a), vreinterpretq_f32_m128(_b)))); -#else - float32x4x2_t c = - vuzpq_f32(vreinterpretq_f32_m128(_a), vreinterpretq_f32_m128(_b)); - return vreinterpretq_m128_f32(vsubq_f32(c.val[0], c.val[1])); -#endif + return vreinterpretq_m128i_s32( + vorrq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); } -// Horizontally add adjacent pairs of 16-bit integers in a and b, and pack the -// signed 16-bit results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pi16 -FORCE_INLINE __m64 _mm_hadd_pi16(__m64 a, __m64 b) +// Packs the 16 signed 16-bit integers from a and b into 8-bit integers and +// saturates. +// https://msdn.microsoft.com/en-us/library/k4y4f7w5%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_packs_epi16(__m128i a, __m128i b) { - return vreinterpret_m64_s16( - vpadd_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b))); + return vreinterpretq_m128i_s8( + vcombine_s8(vqmovn_s16(vreinterpretq_s16_m128i(a)), + vqmovn_s16(vreinterpretq_s16_m128i(b)))); } -// Horizontally add adjacent pairs of 32-bit integers in a and b, and pack the -// signed 32-bit results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pi32 -FORCE_INLINE __m64 _mm_hadd_pi32(__m64 a, __m64 b) +// Packs the 8 signed 32-bit integers from a and b into signed 16-bit integers +// and saturates. +// +// r0 := SignedSaturate(a0) +// r1 := SignedSaturate(a1) +// r2 := SignedSaturate(a2) +// r3 := SignedSaturate(a3) +// r4 := SignedSaturate(b0) +// r5 := SignedSaturate(b1) +// r6 := SignedSaturate(b2) +// r7 := SignedSaturate(b3) +// +// https://msdn.microsoft.com/en-us/library/393t56f9%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_packs_epi32(__m128i a, __m128i b) { - return vreinterpret_m64_s32( - vpadd_s32(vreinterpret_s32_m64(a), vreinterpret_s32_m64(b))); + return vreinterpretq_m128i_s16( + vcombine_s16(vqmovn_s32(vreinterpretq_s32_m128i(a)), + vqmovn_s32(vreinterpretq_s32_m128i(b)))); } -// Computes pairwise difference of each argument as a 16-bit signed or unsigned -// integer values a and b. -FORCE_INLINE __m128i _mm_hsub_epi16(__m128i _a, __m128i _b) +// Packs the 16 signed 16 - bit integers from a and b into 8 - bit unsigned +// integers and saturates. +// +// r0 := UnsignedSaturate(a0) +// r1 := UnsignedSaturate(a1) +// ... +// r7 := UnsignedSaturate(a7) +// r8 := UnsignedSaturate(b0) +// r9 := UnsignedSaturate(b1) +// ... +// r15 := UnsignedSaturate(b7) +// +// https://msdn.microsoft.com/en-us/library/07ad1wx4(v=vs.100).aspx +FORCE_INLINE __m128i _mm_packus_epi16(const __m128i a, const __m128i b) { - int32x4_t a = vreinterpretq_s32_m128i(_a); - int32x4_t b = vreinterpretq_s32_m128i(_b); - // Interleave using vshrn/vmovn - // [a0|a2|a4|a6|b0|b2|b4|b6] - // [a1|a3|a5|a7|b1|b3|b5|b7] - int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b)); - int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16)); - // Subtract - return vreinterpretq_m128i_s16(vsubq_s16(ab0246, ab1357)); + return vreinterpretq_m128i_u8( + vcombine_u8(vqmovun_s16(vreinterpretq_s16_m128i(a)), + vqmovun_s16(vreinterpretq_s16_m128i(b)))); } -// Computes saturated pairwise sub of each argument as a 16-bit signed -// integer values a and b. -FORCE_INLINE __m128i _mm_hadds_epi16(__m128i _a, __m128i _b) +// Pause the processor. This is typically used in spin-wait loops and depending +// on the x86 processor typical values are in the 40-100 cycle range. The +// 'yield' instruction isn't a good fit beacuse it's effectively a nop on most +// Arm cores. Experience with several databases has shown has shown an 'isb' is +// a reasonable approximation. +FORCE_INLINE void _mm_pause() { -#if defined(__aarch64__) - int16x8_t a = vreinterpretq_s16_m128i(_a); - int16x8_t b = vreinterpretq_s16_m128i(_b); - return vreinterpretq_s64_s16( - vqaddq_s16(vuzp1q_s16(a, b), vuzp2q_s16(a, b))); -#else - int32x4_t a = vreinterpretq_s32_m128i(_a); - int32x4_t b = vreinterpretq_s32_m128i(_b); - // Interleave using vshrn/vmovn - // [a0|a2|a4|a6|b0|b2|b4|b6] - // [a1|a3|a5|a7|b1|b3|b5|b7] - int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b)); - int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16)); - // Saturated add - return vreinterpretq_m128i_s16(vqaddq_s16(ab0246, ab1357)); -#endif + __asm__ __volatile__("isb\n"); } -// Computes saturated pairwise difference of each argument as a 16-bit signed -// integer values a and b. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsubs_epi16 -FORCE_INLINE __m128i _mm_hsubs_epi16(__m128i _a, __m128i _b) +// Compute the absolute differences of packed unsigned 8-bit integers in a and +// b, then horizontally sum each consecutive 8 differences to produce two +// unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low +// 16 bits of 64-bit elements in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sad_epu8 +FORCE_INLINE __m128i _mm_sad_epu8(__m128i a, __m128i b) { -#if defined(__aarch64__) - int16x8_t a = vreinterpretq_s16_m128i(_a); - int16x8_t b = vreinterpretq_s16_m128i(_b); - return vreinterpretq_s64_s16( - vqsubq_s16(vuzp1q_s16(a, b), vuzp2q_s16(a, b))); -#else - int32x4_t a = vreinterpretq_s32_m128i(_a); - int32x4_t b = vreinterpretq_s32_m128i(_b); - // Interleave using vshrn/vmovn - // [a0|a2|a4|a6|b0|b2|b4|b6] - // [a1|a3|a5|a7|b1|b3|b5|b7] - int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b)); - int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16)); - // Saturated subtract - return vreinterpretq_m128i_s16(vqsubq_s16(ab0246, ab1357)); -#endif + uint16x8_t t = vpaddlq_u8(vabdq_u8((uint8x16_t) a, (uint8x16_t) b)); + return vreinterpretq_m128i_u64(vpaddlq_u32(vpaddlq_u16(t))); } -// Computes pairwise add of each argument as a 32-bit signed or unsigned integer -// values a and b. -FORCE_INLINE __m128i _mm_hadd_epi32(__m128i _a, __m128i _b) +// Sets the 8 signed 16-bit integer values. +// https://msdn.microsoft.com/en-au/library/3e0fek84(v=vs.90).aspx +FORCE_INLINE __m128i _mm_set_epi16(short i7, + short i6, + short i5, + short i4, + short i3, + short i2, + short i1, + short i0) { - int32x4_t a = vreinterpretq_s32_m128i(_a); - int32x4_t b = vreinterpretq_s32_m128i(_b); - return vreinterpretq_m128i_s32( - vcombine_s32(vpadd_s32(vget_low_s32(a), vget_high_s32(a)), - vpadd_s32(vget_low_s32(b), vget_high_s32(b)))); + int16_t ALIGN_STRUCT(16) data[8] = {i0, i1, i2, i3, i4, i5, i6, i7}; + return vreinterpretq_m128i_s16(vld1q_s16(data)); } -// Computes pairwise difference of each argument as a 32-bit signed or unsigned -// integer values a and b. -FORCE_INLINE __m128i _mm_hsub_epi32(__m128i _a, __m128i _b) +// Sets the 4 signed 32-bit integer values. +// https://msdn.microsoft.com/en-us/library/vstudio/019beekt(v=vs.100).aspx +FORCE_INLINE __m128i _mm_set_epi32(int i3, int i2, int i1, int i0) { - int64x2_t a = vreinterpretq_s64_m128i(_a); - int64x2_t b = vreinterpretq_s64_m128i(_b); - // Interleave using vshrn/vmovn - // [a0|a2|b0|b2] - // [a1|a2|b1|b3] - int32x4_t ab02 = vcombine_s32(vmovn_s64(a), vmovn_s64(b)); - int32x4_t ab13 = vcombine_s32(vshrn_n_s64(a, 32), vshrn_n_s64(b, 32)); - // Subtract - return vreinterpretq_m128i_s32(vsubq_s32(ab02, ab13)); + int32_t ALIGN_STRUCT(16) data[4] = {i0, i1, i2, i3}; + return vreinterpretq_m128i_s32(vld1q_s32(data)); } -// Kahan summation for accurate summation of floating-point numbers. -// http://blog.zachbjornson.com/2019/08/11/fast-float-summation.html -FORCE_INLINE void _sse2neon_kadd_f32(float *sum, float *c, float y) +// Returns the __m128i structure with its two 64-bit integer values +// initialized to the values of the two 64-bit integers passed in. +// https://msdn.microsoft.com/en-us/library/dk2sdw0h(v=vs.120).aspx +FORCE_INLINE __m128i _mm_set_epi64(__m64 i1, __m64 i2) { - y -= *c; - float t = *sum + y; - *c = (t - *sum) - y; - *sum = t; + return _mm_set_epi64x((int64_t) i1, (int64_t) i2); } -// Conditionally multiply the packed single-precision (32-bit) floating-point -// elements in a and b using the high 4 bits in imm8, sum the four products, -// and conditionally store the sum in dst using the low 4 bits of imm. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_dp_ps -FORCE_INLINE __m128 _mm_dp_ps(__m128 a, __m128 b, const int imm) +// Returns the __m128i structure with its two 64-bit integer values +// initialized to the values of the two 64-bit integers passed in. +// https://msdn.microsoft.com/en-us/library/dk2sdw0h(v=vs.120).aspx +FORCE_INLINE __m128i _mm_set_epi64x(int64_t i1, int64_t i2) { -#if defined(__aarch64__) - /* shortcuts */ - if (imm == 0xFF) { - return _mm_set1_ps(vaddvq_f32(_mm_mul_ps(a, b))); - } - if (imm == 0x7F) { - float32x4_t m = _mm_mul_ps(a, b); - m[3] = 0; - return _mm_set1_ps(vaddvq_f32(m)); - } -#endif - - float s = 0, c = 0; - float32x4_t f32a = vreinterpretq_f32_m128(a); - float32x4_t f32b = vreinterpretq_f32_m128(b); - - /* To improve the accuracy of floating-point summation, Kahan algorithm - * is used for each operation. - */ - if (imm & (1 << 4)) - _sse2neon_kadd_f32(&s, &c, f32a[0] * f32b[0]); - if (imm & (1 << 5)) - _sse2neon_kadd_f32(&s, &c, f32a[1] * f32b[1]); - if (imm & (1 << 6)) - _sse2neon_kadd_f32(&s, &c, f32a[2] * f32b[2]); - if (imm & (1 << 7)) - _sse2neon_kadd_f32(&s, &c, f32a[3] * f32b[3]); - s += c; - - float32x4_t res = { - (imm & 0x1) ? s : 0, - (imm & 0x2) ? s : 0, - (imm & 0x4) ? s : 0, - (imm & 0x8) ? s : 0, - }; - return vreinterpretq_m128_f32(res); + return vreinterpretq_m128i_s64( + vcombine_s64(vcreate_s64(i2), vcreate_s64(i1))); } -/* Compare operations */ +// Sets the 16 signed 8-bit integer values. +// https://msdn.microsoft.com/en-us/library/x0cx8zd3(v=vs.90).aspx +FORCE_INLINE __m128i _mm_set_epi8(signed char b15, + signed char b14, + signed char b13, + signed char b12, + signed char b11, + signed char b10, + signed char b9, + signed char b8, + signed char b7, + signed char b6, + signed char b5, + signed char b4, + signed char b3, + signed char b2, + signed char b1, + signed char b0) +{ + int8_t ALIGN_STRUCT(16) + data[16] = {(int8_t) b0, (int8_t) b1, (int8_t) b2, (int8_t) b3, + (int8_t) b4, (int8_t) b5, (int8_t) b6, (int8_t) b7, + (int8_t) b8, (int8_t) b9, (int8_t) b10, (int8_t) b11, + (int8_t) b12, (int8_t) b13, (int8_t) b14, (int8_t) b15}; + return (__m128i) vld1q_s8(data); +} -// Compares for less than -// https://msdn.microsoft.com/en-us/library/vstudio/f330yhc8(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cmplt_ps(__m128 a, __m128 b) +// Set packed double-precision (64-bit) floating-point elements in dst with the +// supplied values. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_pd +FORCE_INLINE __m128d _mm_set_pd(double e1, double e0) { - return vreinterpretq_m128_u32( - vcltq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); + double ALIGN_STRUCT(16) data[2] = {e0, e1}; +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vld1q_f64((float64_t *) data)); +#else + return vreinterpretq_m128d_f32(vld1q_f32((float32_t *) data)); +#endif } -// Compares for less than -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/fy94wye7(v=vs.100) -FORCE_INLINE __m128 _mm_cmplt_ss(__m128 a, __m128 b) +// Broadcast double-precision (64-bit) floating-point value a to all elements of +// dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_pd1 +#define _mm_set_pd1 _mm_set1_pd + +// Copy double-precision (64-bit) floating-point element a to the lower element +// of dst, and zero the upper element. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_sd +FORCE_INLINE __m128d _mm_set_sd(double a) { - return _mm_move_ss(a, _mm_cmplt_ps(a, b)); + return _mm_set_pd(0, a); } -// Compares for greater than. +// Sets the 8 signed 16-bit integer values to w. // -// r0 := (a0 > b0) ? 0xffffffff : 0x0 -// r1 := (a1 > b1) ? 0xffffffff : 0x0 -// r2 := (a2 > b2) ? 0xffffffff : 0x0 -// r3 := (a3 > b3) ? 0xffffffff : 0x0 +// r0 := w +// r1 := w +// ... +// r7 := w // -// https://msdn.microsoft.com/en-us/library/vstudio/11dy102s(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cmpgt_ps(__m128 a, __m128 b) +// https://msdn.microsoft.com/en-us/library/k0ya3x0e(v=vs.90).aspx +FORCE_INLINE __m128i _mm_set1_epi16(short w) { - return vreinterpretq_m128_u32( - vcgtq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); + return vreinterpretq_m128i_s16(vdupq_n_s16(w)); } -// Compares for greater than. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/1xyyyy9e(v=vs.100) -FORCE_INLINE __m128 _mm_cmpgt_ss(__m128 a, __m128 b) +// Sets the 4 signed 32-bit integer values to i. +// +// r0 := i +// r1 := i +// r2 := i +// r3 := I +// +// https://msdn.microsoft.com/en-us/library/vstudio/h4xscxat(v=vs.100).aspx +FORCE_INLINE __m128i _mm_set1_epi32(int _i) { - return _mm_move_ss(a, _mm_cmpgt_ps(a, b)); + return vreinterpretq_m128i_s32(vdupq_n_s32(_i)); } -// Compares for greater than or equal. -// https://msdn.microsoft.com/en-us/library/vstudio/fs813y2t(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cmpge_ps(__m128 a, __m128 b) +// Sets the 2 signed 64-bit integer values to i. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/whtfzhzk(v=vs.100) +FORCE_INLINE __m128i _mm_set1_epi64(__m64 _i) { - return vreinterpretq_m128_u32( - vcgeq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); + return vreinterpretq_m128i_s64(vdupq_n_s64((int64_t) _i)); } -// Compares for greater than or equal. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/kesh3ddc(v=vs.100) -FORCE_INLINE __m128 _mm_cmpge_ss(__m128 a, __m128 b) +// Sets the 2 signed 64-bit integer values to i. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set1_epi64x +FORCE_INLINE __m128i _mm_set1_epi64x(int64_t _i) { - return _mm_move_ss(a, _mm_cmpge_ps(a, b)); + return vreinterpretq_m128i_s64(vdupq_n_s64(_i)); } -// Compares for less than or equal. +// Sets the 16 signed 8-bit integer values to b. // -// r0 := (a0 <= b0) ? 0xffffffff : 0x0 -// r1 := (a1 <= b1) ? 0xffffffff : 0x0 -// r2 := (a2 <= b2) ? 0xffffffff : 0x0 -// r3 := (a3 <= b3) ? 0xffffffff : 0x0 +// r0 := b +// r1 := b +// ... +// r15 := b // -// https://msdn.microsoft.com/en-us/library/vstudio/1s75w83z(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cmple_ps(__m128 a, __m128 b) +// https://msdn.microsoft.com/en-us/library/6e14xhyf(v=vs.100).aspx +FORCE_INLINE __m128i _mm_set1_epi8(signed char w) { - return vreinterpretq_m128_u32( - vcleq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); + return vreinterpretq_m128i_s8(vdupq_n_s8(w)); } -// Compares for less than or equal. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/a7x0hbhw(v=vs.100) -FORCE_INLINE __m128 _mm_cmple_ss(__m128 a, __m128 b) +// Broadcast double-precision (64-bit) floating-point value a to all elements of +// dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set1_pd +FORCE_INLINE __m128d _mm_set1_pd(double d) { - return _mm_move_ss(a, _mm_cmple_ps(a, b)); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vdupq_n_f64(d)); +#else + return vreinterpretq_m128d_s64(vdupq_n_s64(*(int64_t *) &d)); +#endif } -// Compares for equality. -// https://msdn.microsoft.com/en-us/library/vstudio/36aectz5(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cmpeq_ps(__m128 a, __m128 b) +// Sets the 8 signed 16-bit integer values in reverse order. +// +// Return Value +// r0 := w0 +// r1 := w1 +// ... +// r7 := w7 +FORCE_INLINE __m128i _mm_setr_epi16(short w0, + short w1, + short w2, + short w3, + short w4, + short w5, + short w6, + short w7) { - return vreinterpretq_m128_u32( - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); + int16_t ALIGN_STRUCT(16) data[8] = {w0, w1, w2, w3, w4, w5, w6, w7}; + return vreinterpretq_m128i_s16(vld1q_s16((int16_t *) data)); } -// Compares for equality. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/k423z28e(v=vs.100) -FORCE_INLINE __m128 _mm_cmpeq_ss(__m128 a, __m128 b) +// Sets the 4 signed 32-bit integer values in reverse order +// https://technet.microsoft.com/en-us/library/security/27yb3ee5(v=vs.90).aspx +FORCE_INLINE __m128i _mm_setr_epi32(int i3, int i2, int i1, int i0) { - return _mm_move_ss(a, _mm_cmpeq_ps(a, b)); + int32_t ALIGN_STRUCT(16) data[4] = {i3, i2, i1, i0}; + return vreinterpretq_m128i_s32(vld1q_s32(data)); } -// Compares for inequality. -// https://msdn.microsoft.com/en-us/library/sf44thbx(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cmpneq_ps(__m128 a, __m128 b) +// Set packed 64-bit integers in dst with the supplied values in reverse order. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setr_epi64 +FORCE_INLINE __m128i _mm_setr_epi64(__m64 e1, __m64 e0) { - return vreinterpretq_m128_u32(vmvnq_u32( - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)))); + return vreinterpretq_m128i_s64(vcombine_s64(e1, e0)); } -// Compares for inequality. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/ekya8fh4(v=vs.100) -FORCE_INLINE __m128 _mm_cmpneq_ss(__m128 a, __m128 b) +// Sets the 16 signed 8-bit integer values in reverse order. +// https://msdn.microsoft.com/en-us/library/2khb9c7k(v=vs.90).aspx +FORCE_INLINE __m128i _mm_setr_epi8(signed char b0, + signed char b1, + signed char b2, + signed char b3, + signed char b4, + signed char b5, + signed char b6, + signed char b7, + signed char b8, + signed char b9, + signed char b10, + signed char b11, + signed char b12, + signed char b13, + signed char b14, + signed char b15) { - return _mm_move_ss(a, _mm_cmpneq_ps(a, b)); + int8_t ALIGN_STRUCT(16) + data[16] = {(int8_t) b0, (int8_t) b1, (int8_t) b2, (int8_t) b3, + (int8_t) b4, (int8_t) b5, (int8_t) b6, (int8_t) b7, + (int8_t) b8, (int8_t) b9, (int8_t) b10, (int8_t) b11, + (int8_t) b12, (int8_t) b13, (int8_t) b14, (int8_t) b15}; + return (__m128i) vld1q_s8(data); } -// Compares for not greater than or equal. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/wsexys62(v=vs.100) -FORCE_INLINE __m128 _mm_cmpnge_ps(__m128 a, __m128 b) +// Set packed double-precision (64-bit) floating-point elements in dst with the +// supplied values in reverse order. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setr_pd +FORCE_INLINE __m128d _mm_setr_pd(double e1, double e0) { - return _mm_cmplt_ps(a, b); + return _mm_set_pd(e0, e1); } -// Compares for not greater than or equal. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/fk2y80s8(v=vs.100) -FORCE_INLINE __m128 _mm_cmpnge_ss(__m128 a, __m128 b) +// Return vector of type __m128d with all elements set to zero. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setzero_pd +FORCE_INLINE __m128d _mm_setzero_pd(void) { - return _mm_cmplt_ss(a, b); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vdupq_n_f64(0)); +#else + return vreinterpretq_m128d_f32(vdupq_n_f32(0)); +#endif } -// Compares for not greater than. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/d0xh7w0s(v=vs.100) -FORCE_INLINE __m128 _mm_cmpngt_ps(__m128 a, __m128 b) +// Sets the 128-bit value to zero +// https://msdn.microsoft.com/en-us/library/vstudio/ys7dw0kh(v=vs.100).aspx +FORCE_INLINE __m128i _mm_setzero_si128(void) { - return _mm_cmple_ps(a, b); + return vreinterpretq_m128i_s32(vdupq_n_s32(0)); } -// Compares for not greater than. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/z7x9ydwh(v=vs.100) -FORCE_INLINE __m128 _mm_cmpngt_ss(__m128 a, __m128 b) +// Shuffles the 4 signed or unsigned 32-bit integers in a as specified by imm. +// https://msdn.microsoft.com/en-us/library/56f67xbk%28v=vs.90%29.aspx +// FORCE_INLINE __m128i _mm_shuffle_epi32(__m128i a, +// __constrange(0,255) int imm) +#if __has_builtin(__builtin_shufflevector) +#define _mm_shuffle_epi32(a, imm) \ + __extension__({ \ + int32x4_t _input = vreinterpretq_s32_m128i(a); \ + int32x4_t _shuf = __builtin_shufflevector( \ + _input, _input, (imm) & (0x3), ((imm) >> 2) & 0x3, \ + ((imm) >> 4) & 0x3, ((imm) >> 6) & 0x3); \ + vreinterpretq_m128i_s32(_shuf); \ + }) +#else // generic +#define _mm_shuffle_epi32(a, imm) \ + __extension__({ \ + __m128i ret; \ + switch (imm) { \ + case _MM_SHUFFLE(1, 0, 3, 2): \ + ret = _mm_shuffle_epi_1032((a)); \ + break; \ + case _MM_SHUFFLE(2, 3, 0, 1): \ + ret = _mm_shuffle_epi_2301((a)); \ + break; \ + case _MM_SHUFFLE(0, 3, 2, 1): \ + ret = _mm_shuffle_epi_0321((a)); \ + break; \ + case _MM_SHUFFLE(2, 1, 0, 3): \ + ret = _mm_shuffle_epi_2103((a)); \ + break; \ + case _MM_SHUFFLE(1, 0, 1, 0): \ + ret = _mm_shuffle_epi_1010((a)); \ + break; \ + case _MM_SHUFFLE(1, 0, 0, 1): \ + ret = _mm_shuffle_epi_1001((a)); \ + break; \ + case _MM_SHUFFLE(0, 1, 0, 1): \ + ret = _mm_shuffle_epi_0101((a)); \ + break; \ + case _MM_SHUFFLE(2, 2, 1, 1): \ + ret = _mm_shuffle_epi_2211((a)); \ + break; \ + case _MM_SHUFFLE(0, 1, 2, 2): \ + ret = _mm_shuffle_epi_0122((a)); \ + break; \ + case _MM_SHUFFLE(3, 3, 3, 2): \ + ret = _mm_shuffle_epi_3332((a)); \ + break; \ + case _MM_SHUFFLE(0, 0, 0, 0): \ + ret = _mm_shuffle_epi32_splat((a), 0); \ + break; \ + case _MM_SHUFFLE(1, 1, 1, 1): \ + ret = _mm_shuffle_epi32_splat((a), 1); \ + break; \ + case _MM_SHUFFLE(2, 2, 2, 2): \ + ret = _mm_shuffle_epi32_splat((a), 2); \ + break; \ + case _MM_SHUFFLE(3, 3, 3, 3): \ + ret = _mm_shuffle_epi32_splat((a), 3); \ + break; \ + default: \ + ret = _mm_shuffle_epi32_default((a), (imm)); \ + break; \ + } \ + ret; \ + }) +#endif + +// Shuffle double-precision (64-bit) floating-point elements using the control +// in imm8, and store the results in dst. +// +// dst[63:0] := (imm8[0] == 0) ? a[63:0] : a[127:64] +// dst[127:64] := (imm8[1] == 0) ? b[63:0] : b[127:64] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_pd +#if __has_builtin(__builtin_shufflevector) +#define _mm_shuffle_pd(a, b, imm8) \ + vreinterpretq_m128d_s64(__builtin_shufflevector( \ + vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b), imm8 & 0x1, \ + ((imm8 & 0x2) >> 1) + 2)) +#else +#define _mm_shuffle_pd(a, b, imm8) \ + _mm_castsi128_pd(_mm_set_epi64x( \ + vgetq_lane_s64(vreinterpretq_s64_m128d(b), (imm8 & 0x2) >> 1), \ + vgetq_lane_s64(vreinterpretq_s64_m128d(a), imm8 & 0x1))) +#endif + +// FORCE_INLINE __m128i _mm_shufflehi_epi16(__m128i a, +// __constrange(0,255) int imm) +#if __has_builtin(__builtin_shufflevector) +#define _mm_shufflehi_epi16(a, imm) \ + __extension__({ \ + int16x8_t _input = vreinterpretq_s16_m128i(a); \ + int16x8_t _shuf = __builtin_shufflevector( \ + _input, _input, 0, 1, 2, 3, ((imm) & (0x3)) + 4, \ + (((imm) >> 2) & 0x3) + 4, (((imm) >> 4) & 0x3) + 4, \ + (((imm) >> 6) & 0x3) + 4); \ + vreinterpretq_m128i_s16(_shuf); \ + }) +#else // generic +#define _mm_shufflehi_epi16(a, imm) _mm_shufflehi_epi16_function((a), (imm)) +#endif + +// FORCE_INLINE __m128i _mm_shufflelo_epi16(__m128i a, +// __constrange(0,255) int imm) +#if __has_builtin(__builtin_shufflevector) +#define _mm_shufflelo_epi16(a, imm) \ + __extension__({ \ + int16x8_t _input = vreinterpretq_s16_m128i(a); \ + int16x8_t _shuf = __builtin_shufflevector( \ + _input, _input, ((imm) & (0x3)), (((imm) >> 2) & 0x3), \ + (((imm) >> 4) & 0x3), (((imm) >> 6) & 0x3), 4, 5, 6, 7); \ + vreinterpretq_m128i_s16(_shuf); \ + }) +#else // generic +#define _mm_shufflelo_epi16(a, imm) _mm_shufflelo_epi16_function((a), (imm)) +#endif + +// Shift packed 16-bit integers in a left by count while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// IF count[63:0] > 15 +// dst[i+15:i] := 0 +// ELSE +// dst[i+15:i] := ZeroExtend16(a[i+15:i] << count[63:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sll_epi16 +FORCE_INLINE __m128i _mm_sll_epi16(__m128i a, __m128i count) { - return _mm_cmple_ss(a, b); + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (_sse2neon_unlikely(c & ~15)) + return _mm_setzero_si128(); + + int16x8_t vc = vdupq_n_s16((int16_t) c); + return vreinterpretq_m128i_s16(vshlq_s16(vreinterpretq_s16_m128i(a), vc)); } -// Compares for not less than or equal. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/6a330kxw(v=vs.100) -FORCE_INLINE __m128 _mm_cmpnle_ps(__m128 a, __m128 b) +// Shift packed 32-bit integers in a left by count while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 3 +// i := j*32 +// IF count[63:0] > 31 +// dst[i+31:i] := 0 +// ELSE +// dst[i+31:i] := ZeroExtend32(a[i+31:i] << count[63:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sll_epi32 +FORCE_INLINE __m128i _mm_sll_epi32(__m128i a, __m128i count) { - return _mm_cmpgt_ps(a, b); + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (_sse2neon_unlikely(c & ~31)) + return _mm_setzero_si128(); + + int32x4_t vc = vdupq_n_s32((int32_t) c); + return vreinterpretq_m128i_s32(vshlq_s32(vreinterpretq_s32_m128i(a), vc)); } -// Compares for not less than or equal. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/z7x9ydwh(v=vs.100) -FORCE_INLINE __m128 _mm_cmpnle_ss(__m128 a, __m128 b) +// Shift packed 64-bit integers in a left by count while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// IF count[63:0] > 63 +// dst[i+63:i] := 0 +// ELSE +// dst[i+63:i] := ZeroExtend64(a[i+63:i] << count[63:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sll_epi64 +FORCE_INLINE __m128i _mm_sll_epi64(__m128i a, __m128i count) { - return _mm_cmpgt_ss(a, b); + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (_sse2neon_unlikely(c & ~63)) + return _mm_setzero_si128(); + + int64x2_t vc = vdupq_n_s64((int64_t) c); + return vreinterpretq_m128i_s64(vshlq_s64(vreinterpretq_s64_m128i(a), vc)); } -// Compares for not less than. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/4686bbdw(v=vs.100) -FORCE_INLINE __m128 _mm_cmpnlt_ps(__m128 a, __m128 b) +// Shift packed 16-bit integers in a left by imm8 while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// IF imm8[7:0] > 15 +// dst[i+15:i] := 0 +// ELSE +// dst[i+15:i] := ZeroExtend16(a[i+15:i] << imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_slli_epi16 +FORCE_INLINE __m128i _mm_slli_epi16(__m128i a, int imm) { - return _mm_cmpge_ps(a, b); + if (_sse2neon_unlikely(imm & ~15)) + return _mm_setzero_si128(); + return vreinterpretq_m128i_s16( + vshlq_s16(vreinterpretq_s16_m128i(a), vdupq_n_s16(imm))); } -// Compares for not less than. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/56b9z2wf(v=vs.100) -FORCE_INLINE __m128 _mm_cmpnlt_ss(__m128 a, __m128 b) +// Shift packed 32-bit integers in a left by imm8 while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 3 +// i := j*32 +// IF imm8[7:0] > 31 +// dst[i+31:i] := 0 +// ELSE +// dst[i+31:i] := ZeroExtend32(a[i+31:i] << imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_slli_epi32 +FORCE_INLINE __m128i _mm_slli_epi32(__m128i a, int imm) { - return _mm_cmpge_ss(a, b); + if (_sse2neon_unlikely(imm & ~31)) + return _mm_setzero_si128(); + return vreinterpretq_m128i_s32( + vshlq_s32(vreinterpretq_s32_m128i(a), vdupq_n_s32(imm))); } -// Compares the 16 signed or unsigned 8-bit integers in a and the 16 signed or -// unsigned 8-bit integers in b for equality. -// https://msdn.microsoft.com/en-us/library/windows/desktop/bz5xk21a(v=vs.90).aspx -FORCE_INLINE __m128i _mm_cmpeq_epi8(__m128i a, __m128i b) +// Shift packed 64-bit integers in a left by imm8 while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// IF imm8[7:0] > 63 +// dst[i+63:i] := 0 +// ELSE +// dst[i+63:i] := ZeroExtend64(a[i+63:i] << imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_slli_epi64 +FORCE_INLINE __m128i _mm_slli_epi64(__m128i a, int imm) +{ + if (_sse2neon_unlikely(imm & ~63)) + return _mm_setzero_si128(); + return vreinterpretq_m128i_s64( + vshlq_s64(vreinterpretq_s64_m128i(a), vdupq_n_s64(imm))); +} + +// Shift a left by imm8 bytes while shifting in zeros, and store the results in +// dst. +// +// tmp := imm8[7:0] +// IF tmp > 15 +// tmp := 16 +// FI +// dst[127:0] := a[127:0] << (tmp*8) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_slli_si128 +FORCE_INLINE __m128i _mm_slli_si128(__m128i a, int imm) { + if (_sse2neon_unlikely(imm & ~15)) + return _mm_setzero_si128(); + uint8x16_t tmp[2] = {vdupq_n_u8(0), vreinterpretq_u8_m128i(a)}; return vreinterpretq_m128i_u8( - vceqq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); + vld1q_u8(((uint8_t const *) tmp) + (16 - imm))); } -// Compare packed double-precision (64-bit) floating-point elements in a and b -// for equality, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpeq_pd -FORCE_INLINE __m128d _mm_cmpeq_pd(__m128d a, __m128d b) +// Compute the square root of packed double-precision (64-bit) floating-point +// elements in a, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sqrt_pd +FORCE_INLINE __m128d _mm_sqrt_pd(__m128d a) { #if defined(__aarch64__) - return vreinterpretq_m128d_u64( - vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); + return vreinterpretq_m128d_f64(vsqrtq_f64(vreinterpretq_f64_m128d(a))); #else - // (a == b) -> (a_lo == b_lo) && (a_hi == b_hi) - uint32x4_t cmp = - vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(b)); - uint32x4_t swapped = vrev64q_u32(cmp); - return vreinterpretq_m128d_u32(vandq_u32(cmp, swapped)); + double a0 = sqrt(((double *) &a)[0]); + double a1 = sqrt(((double *) &a)[1]); + return _mm_set_pd(a1, a0); #endif } -// Compares the 8 signed or unsigned 16-bit integers in a and the 8 signed or -// unsigned 16-bit integers in b for equality. -// https://msdn.microsoft.com/en-us/library/2ay060te(v=vs.100).aspx -FORCE_INLINE __m128i _mm_cmpeq_epi16(__m128i a, __m128i b) +// Compute the square root of the lower double-precision (64-bit) floating-point +// element in b, store the result in the lower element of dst, and copy the +// upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sqrt_sd +FORCE_INLINE __m128d _mm_sqrt_sd(__m128d a, __m128d b) { - return vreinterpretq_m128i_u16( - vceqq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +#if defined(__aarch64__) + return _mm_move_sd(a, _mm_sqrt_pd(b)); +#else + return _mm_set_pd(((double *) &a)[1], sqrt(((double *) &b)[0])); +#endif } -// Compare packed 32-bit integers in a and b for equality, and store the results -// in dst -FORCE_INLINE __m128i _mm_cmpeq_epi32(__m128i a, __m128i b) +// Shift packed 16-bit integers in a right by count while shifting in sign bits, +// and store the results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// IF count[63:0] > 15 +// dst[i+15:i] := (a[i+15] ? 0xFFFF : 0x0) +// ELSE +// dst[i+15:i] := SignExtend16(a[i+15:i] >> count[63:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sra_epi16 +FORCE_INLINE __m128i _mm_sra_epi16(__m128i a, __m128i count) { - return vreinterpretq_m128i_u32( - vceqq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); + int64_t c = (int64_t) vget_low_s64((int64x2_t) count); + if (_sse2neon_unlikely(c & ~15)) + return _mm_cmplt_epi16(a, _mm_setzero_si128()); + return vreinterpretq_m128i_s16(vshlq_s16((int16x8_t) a, vdupq_n_s16(-c))); } -// Compare packed 64-bit integers in a and b for equality, and store the results -// in dst -FORCE_INLINE __m128i _mm_cmpeq_epi64(__m128i a, __m128i b) +// Shift packed 32-bit integers in a right by count while shifting in sign bits, +// and store the results in dst. +// +// FOR j := 0 to 3 +// i := j*32 +// IF count[63:0] > 31 +// dst[i+31:i] := (a[i+31] ? 0xFFFFFFFF : 0x0) +// ELSE +// dst[i+31:i] := SignExtend32(a[i+31:i] >> count[63:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sra_epi32 +FORCE_INLINE __m128i _mm_sra_epi32(__m128i a, __m128i count) { -#if defined(__aarch64__) - return vreinterpretq_m128i_u64( - vceqq_u64(vreinterpretq_u64_m128i(a), vreinterpretq_u64_m128i(b))); -#else - // ARMv7 lacks vceqq_u64 - // (a == b) -> (a_lo == b_lo) && (a_hi == b_hi) - uint32x4_t cmp = - vceqq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b)); - uint32x4_t swapped = vrev64q_u32(cmp); - return vreinterpretq_m128i_u32(vandq_u32(cmp, swapped)); -#endif + int64_t c = (int64_t) vget_low_s64((int64x2_t) count); + if (_sse2neon_unlikely(c & ~31)) + return _mm_cmplt_epi32(a, _mm_setzero_si128()); + return vreinterpretq_m128i_s32(vshlq_s32((int32x4_t) a, vdupq_n_s32(-c))); } -// Compares the 16 signed 8-bit integers in a and the 16 signed 8-bit integers -// in b for lesser than. -// https://msdn.microsoft.com/en-us/library/windows/desktop/9s46csht(v=vs.90).aspx -FORCE_INLINE __m128i _mm_cmplt_epi8(__m128i a, __m128i b) +// Shift packed 16-bit integers in a right by imm8 while shifting in sign +// bits, and store the results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// IF imm8[7:0] > 15 +// dst[i+15:i] := (a[i+15] ? 0xFFFF : 0x0) +// ELSE +// dst[i+15:i] := SignExtend16(a[i+15:i] >> imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srai_epi16 +FORCE_INLINE __m128i _mm_srai_epi16(__m128i a, int imm) { - return vreinterpretq_m128i_u8( - vcltq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); + const int count = (imm & ~15) ? 15 : imm; + return (__m128i) vshlq_s16((int16x8_t) a, vdupq_n_s16(-count)); } -// Compares the 16 signed 8-bit integers in a and the 16 signed 8-bit integers -// in b for greater than. +// Shift packed 32-bit integers in a right by imm8 while shifting in sign bits, +// and store the results in dst. // -// r0 := (a0 > b0) ? 0xff : 0x0 -// r1 := (a1 > b1) ? 0xff : 0x0 -// ... -// r15 := (a15 > b15) ? 0xff : 0x0 +// FOR j := 0 to 3 +// i := j*32 +// IF imm8[7:0] > 31 +// dst[i+31:i] := (a[i+31] ? 0xFFFFFFFF : 0x0) +// ELSE +// dst[i+31:i] := SignExtend32(a[i+31:i] >> imm8[7:0]) +// FI +// ENDFOR // -// https://msdn.microsoft.com/zh-tw/library/wf45zt2b(v=vs.100).aspx -FORCE_INLINE __m128i _mm_cmpgt_epi8(__m128i a, __m128i b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srai_epi32 +// FORCE_INLINE __m128i _mm_srai_epi32(__m128i a, __constrange(0,255) int imm) +#define _mm_srai_epi32(a, imm) \ + __extension__({ \ + __m128i ret; \ + if (_sse2neon_unlikely((imm) == 0)) { \ + ret = a; \ + } else if (_sse2neon_likely(0 < (imm) && (imm) < 32)) { \ + ret = vreinterpretq_m128i_s32( \ + vshlq_s32(vreinterpretq_s32_m128i(a), vdupq_n_s32(-imm))); \ + } else { \ + ret = vreinterpretq_m128i_s32( \ + vshrq_n_s32(vreinterpretq_s32_m128i(a), 31)); \ + } \ + ret; \ + }) + +// Shift packed 16-bit integers in a right by count while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// IF count[63:0] > 15 +// dst[i+15:i] := 0 +// ELSE +// dst[i+15:i] := ZeroExtend16(a[i+15:i] >> count[63:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srl_epi16 +FORCE_INLINE __m128i _mm_srl_epi16(__m128i a, __m128i count) { - return vreinterpretq_m128i_u8( - vcgtq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (_sse2neon_unlikely(c & ~15)) + return _mm_setzero_si128(); + + int16x8_t vc = vdupq_n_s16(-(int16_t) c); + return vreinterpretq_m128i_u16(vshlq_u16(vreinterpretq_u16_m128i(a), vc)); } -// Compares the 8 signed 16-bit integers in a and the 8 signed 16-bit integers -// in b for less than. +// Shift packed 32-bit integers in a right by count while shifting in zeros, and +// store the results in dst. // -// r0 := (a0 < b0) ? 0xffff : 0x0 -// r1 := (a1 < b1) ? 0xffff : 0x0 -// ... -// r7 := (a7 < b7) ? 0xffff : 0x0 +// FOR j := 0 to 3 +// i := j*32 +// IF count[63:0] > 31 +// dst[i+31:i] := 0 +// ELSE +// dst[i+31:i] := ZeroExtend32(a[i+31:i] >> count[63:0]) +// FI +// ENDFOR // -// https://technet.microsoft.com/en-us/library/t863edb2(v=vs.100).aspx -FORCE_INLINE __m128i _mm_cmplt_epi16(__m128i a, __m128i b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srl_epi32 +FORCE_INLINE __m128i _mm_srl_epi32(__m128i a, __m128i count) { - return vreinterpretq_m128i_u16( - vcltq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (_sse2neon_unlikely(c & ~31)) + return _mm_setzero_si128(); + + int32x4_t vc = vdupq_n_s32(-(int32_t) c); + return vreinterpretq_m128i_u32(vshlq_u32(vreinterpretq_u32_m128i(a), vc)); } -// Compares the 8 signed 16-bit integers in a and the 8 signed 16-bit integers -// in b for greater than. +// Shift packed 64-bit integers in a right by count while shifting in zeros, and +// store the results in dst. // -// r0 := (a0 > b0) ? 0xffff : 0x0 -// r1 := (a1 > b1) ? 0xffff : 0x0 -// ... -// r7 := (a7 > b7) ? 0xffff : 0x0 +// FOR j := 0 to 1 +// i := j*64 +// IF count[63:0] > 63 +// dst[i+63:i] := 0 +// ELSE +// dst[i+63:i] := ZeroExtend64(a[i+63:i] >> count[63:0]) +// FI +// ENDFOR // -// https://technet.microsoft.com/en-us/library/xd43yfsa(v=vs.100).aspx -FORCE_INLINE __m128i _mm_cmpgt_epi16(__m128i a, __m128i b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srl_epi64 +FORCE_INLINE __m128i _mm_srl_epi64(__m128i a, __m128i count) { - return vreinterpretq_m128i_u16( - vcgtq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (_sse2neon_unlikely(c & ~63)) + return _mm_setzero_si128(); + + int64x2_t vc = vdupq_n_s64(-(int64_t) c); + return vreinterpretq_m128i_u64(vshlq_u64(vreinterpretq_u64_m128i(a), vc)); } +// Shift packed 16-bit integers in a right by imm8 while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// IF imm8[7:0] > 15 +// dst[i+15:i] := 0 +// ELSE +// dst[i+15:i] := ZeroExtend16(a[i+15:i] >> imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi16 +#define _mm_srli_epi16(a, imm) \ + __extension__({ \ + __m128i ret; \ + if (_sse2neon_unlikely(imm & ~15)) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_u16( \ + vshlq_u16(vreinterpretq_u16_m128i(a), vdupq_n_s16(-imm))); \ + } \ + ret; \ + }) + +// Shift packed 32-bit integers in a right by imm8 while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 3 +// i := j*32 +// IF imm8[7:0] > 31 +// dst[i+31:i] := 0 +// ELSE +// dst[i+31:i] := ZeroExtend32(a[i+31:i] >> imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi32 +// FORCE_INLINE __m128i _mm_srli_epi32(__m128i a, __constrange(0,255) int imm) +#define _mm_srli_epi32(a, imm) \ + __extension__({ \ + __m128i ret; \ + if (_sse2neon_unlikely(imm & ~31)) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_u32( \ + vshlq_u32(vreinterpretq_u32_m128i(a), vdupq_n_s32(-imm))); \ + } \ + ret; \ + }) -// Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers -// in b for less than. -// https://msdn.microsoft.com/en-us/library/vstudio/4ak0bf5d(v=vs.100).aspx -FORCE_INLINE __m128i _mm_cmplt_epi32(__m128i a, __m128i b) +// Shift packed 64-bit integers in a right by imm8 while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// IF imm8[7:0] > 63 +// dst[i+63:i] := 0 +// ELSE +// dst[i+63:i] := ZeroExtend64(a[i+63:i] >> imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi64 +#define _mm_srli_epi64(a, imm) \ + __extension__({ \ + __m128i ret; \ + if (_sse2neon_unlikely(imm & ~63)) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_u64( \ + vshlq_u64(vreinterpretq_u64_m128i(a), vdupq_n_s64(-imm))); \ + } \ + ret; \ + }) + +// Shift a right by imm8 bytes while shifting in zeros, and store the results in +// dst. +// +// tmp := imm8[7:0] +// IF tmp > 15 +// tmp := 16 +// FI +// dst[127:0] := a[127:0] >> (tmp*8) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_si128 +FORCE_INLINE __m128i _mm_srli_si128(__m128i a, int imm) { - return vreinterpretq_m128i_u32( - vcltq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); + if (_sse2neon_unlikely(imm & ~15)) + return _mm_setzero_si128(); + uint8x16_t tmp[2] = {vreinterpretq_u8_m128i(a), vdupq_n_u8(0)}; + return vreinterpretq_m128i_u8(vld1q_u8(((uint8_t const *) tmp) + imm)); } -// Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers -// in b for greater than. -// https://msdn.microsoft.com/en-us/library/vstudio/1s9f2z0y(v=vs.100).aspx -FORCE_INLINE __m128i _mm_cmpgt_epi32(__m128i a, __m128i b) +// Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point +// elements) from a into memory. mem_addr must be aligned on a 16-byte boundary +// or a general-protection exception may be generated. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store_pd +FORCE_INLINE void _mm_store_pd(double *mem_addr, __m128d a) { - return vreinterpretq_m128i_u32( - vcgtq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +#if defined(__aarch64__) + vst1q_f64((float64_t *) mem_addr, vreinterpretq_f64_m128d(a)); +#else + vst1q_f32((float32_t *) mem_addr, vreinterpretq_f32_m128d(a)); +#endif } -// Compares the 2 signed 64-bit integers in a and the 2 signed 64-bit integers -// in b for greater than. -FORCE_INLINE __m128i _mm_cmpgt_epi64(__m128i a, __m128i b) +// Store the lower double-precision (64-bit) floating-point element from a into +// 2 contiguous elements in memory. mem_addr must be aligned on a 16-byte +// boundary or a general-protection exception may be generated. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store_pd1 +FORCE_INLINE void _mm_store_pd1(double *mem_addr, __m128d a) { #if defined(__aarch64__) - return vreinterpretq_m128i_u64( - vcgtq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); + float64x1_t a_low = vget_low_f64(vreinterpretq_f64_m128d(a)); + vst1q_f64((float64_t *) mem_addr, + vreinterpretq_f64_m128d(vcombine_f64(a_low, a_low))); #else - // ARMv7 lacks vcgtq_s64. - // This is based off of Clang's SSE2 polyfill: - // (a > b) -> ((a_hi > b_hi) || (a_lo > b_lo && a_hi == b_hi)) - - // Mask the sign bit out since we need a signed AND an unsigned comparison - // and it is ugly to try and split them. - int32x4_t mask = vreinterpretq_s32_s64(vdupq_n_s64(0x80000000ull)); - int32x4_t a_mask = veorq_s32(vreinterpretq_s32_m128i(a), mask); - int32x4_t b_mask = veorq_s32(vreinterpretq_s32_m128i(b), mask); - // Check if a > b - int64x2_t greater = vreinterpretq_s64_u32(vcgtq_s32(a_mask, b_mask)); - // Copy upper mask to lower mask - // a_hi > b_hi - int64x2_t gt_hi = vshrq_n_s64(greater, 63); - // Copy lower mask to upper mask - // a_lo > b_lo - int64x2_t gt_lo = vsliq_n_s64(greater, greater, 32); - // Compare for equality - int64x2_t equal = vreinterpretq_s64_u32(vceqq_s32(a_mask, b_mask)); - // Copy upper mask to lower mask - // a_hi == b_hi - int64x2_t eq_hi = vshrq_n_s64(equal, 63); - // a_hi > b_hi || (a_lo > b_lo && a_hi == b_hi) - int64x2_t ret = vorrq_s64(gt_hi, vandq_s64(gt_lo, eq_hi)); - return vreinterpretq_m128i_s64(ret); + float32x2_t a_low = vget_low_f32(vreinterpretq_f32_m128d(a)); + vst1q_f32((float32_t *) mem_addr, + vreinterpretq_f32_m128d(vcombine_f32(a_low, a_low))); #endif } -// Compares the four 32-bit floats in a and b to check if any values are NaN. -// Ordered compare between each value returns true for "orderable" and false for -// "not orderable" (NaN). -// https://msdn.microsoft.com/en-us/library/vstudio/0h9w00fx(v=vs.100).aspx see -// also: -// http://stackoverflow.com/questions/8627331/what-does-ordered-unordered-comparison-mean -// http://stackoverflow.com/questions/29349621/neon-isnanval-intrinsics -FORCE_INLINE __m128 _mm_cmpord_ps(__m128 a, __m128 b) +// Store the lower double-precision (64-bit) floating-point element from a into +// memory. mem_addr does not need to be aligned on any particular boundary. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_store_sd +FORCE_INLINE void _mm_store_sd(double *mem_addr, __m128d a) { - // Note: NEON does not have ordered compare builtin - // Need to compare a eq a and b eq b to check for NaN - // Do AND of results to get final - uint32x4_t ceqaa = - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); - uint32x4_t ceqbb = - vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); - return vreinterpretq_m128_u32(vandq_u32(ceqaa, ceqbb)); +#if defined(__aarch64__) + vst1_f64((float64_t *) mem_addr, vget_low_f64(vreinterpretq_f64_m128d(a))); +#else + vst1_u64((uint64_t *) mem_addr, vget_low_u64(vreinterpretq_u64_m128d(a))); +#endif } -// Compares for ordered. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/343t62da(v=vs.100) -FORCE_INLINE __m128 _mm_cmpord_ss(__m128 a, __m128 b) +// Stores four 32-bit integer values as (as a __m128i value) at the address p. +// https://msdn.microsoft.com/en-us/library/vstudio/edk11s13(v=vs.100).aspx +FORCE_INLINE void _mm_store_si128(__m128i *p, __m128i a) { - return _mm_move_ss(a, _mm_cmpord_ps(a, b)); + vst1q_s32((int32_t *) p, vreinterpretq_s32_m128i(a)); } -// Compares for unordered. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/khy6fk1t(v=vs.100) -FORCE_INLINE __m128 _mm_cmpunord_ps(__m128 a, __m128 b) +// Store the lower double-precision (64-bit) floating-point element from a into +// 2 contiguous elements in memory. mem_addr must be aligned on a 16-byte +// boundary or a general-protection exception may be generated. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=9,526,5601&text=_mm_store1_pd +#define _mm_store1_pd _mm_store_pd1 + +// Store the upper double-precision (64-bit) floating-point element from a into +// memory. +// +// MEM[mem_addr+63:mem_addr] := a[127:64] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeh_pd +FORCE_INLINE void _mm_storeh_pd(double *mem_addr, __m128d a) { - uint32x4_t f32a = - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); - uint32x4_t f32b = - vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); - return vreinterpretq_m128_u32(vmvnq_u32(vandq_u32(f32a, f32b))); +#if defined(__aarch64__) + vst1_f64((float64_t *) mem_addr, vget_high_f64(vreinterpretq_f64_m128d(a))); +#else + vst1_f32((float32_t *) mem_addr, vget_high_f32(vreinterpretq_f32_m128d(a))); +#endif } -// Compares for unordered. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/2as2387b(v=vs.100) -FORCE_INLINE __m128 _mm_cmpunord_ss(__m128 a, __m128 b) +// Reads the lower 64 bits of b and stores them into the lower 64 bits of a. +// https://msdn.microsoft.com/en-us/library/hhwf428f%28v=vs.90%29.aspx +FORCE_INLINE void _mm_storel_epi64(__m128i *a, __m128i b) { - return _mm_move_ss(a, _mm_cmpunord_ps(a, b)); + uint64x1_t hi = vget_high_u64(vreinterpretq_u64_m128i(*a)); + uint64x1_t lo = vget_low_u64(vreinterpretq_u64_m128i(b)); + *a = vreinterpretq_m128i_u64(vcombine_u64(lo, hi)); } -// Compares the lower single-precision floating point scalar values of a and b -// using a less than operation. : -// https://msdn.microsoft.com/en-us/library/2kwe606b(v=vs.90).aspx Important -// note!! The documentation on MSDN is incorrect! If either of the values is a -// NAN the docs say you will get a one, but in fact, it will return a zero!! -FORCE_INLINE int _mm_comilt_ss(__m128 a, __m128 b) +// Store the lower double-precision (64-bit) floating-point element from a into +// memory. +// +// MEM[mem_addr+63:mem_addr] := a[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storel_pd +FORCE_INLINE void _mm_storel_pd(double *mem_addr, __m128d a) { - uint32x4_t a_not_nan = - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); - uint32x4_t b_not_nan = - vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); - uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); - uint32x4_t a_lt_b = - vcltq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); - return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_lt_b), 0) != 0) ? 1 : 0; +#if defined(__aarch64__) + vst1_f64((float64_t *) mem_addr, vget_low_f64(vreinterpretq_f64_m128d(a))); +#else + vst1_f32((float32_t *) mem_addr, vget_low_f32(vreinterpretq_f32_m128d(a))); +#endif } -// Compares the lower single-precision floating point scalar values of a and b -// using a greater than operation. : -// https://msdn.microsoft.com/en-us/library/b0738e0t(v=vs.100).aspx -FORCE_INLINE int _mm_comigt_ss(__m128 a, __m128 b) +// Store 2 double-precision (64-bit) floating-point elements from a into memory +// in reverse order. mem_addr must be aligned on a 16-byte boundary or a +// general-protection exception may be generated. +// +// MEM[mem_addr+63:mem_addr] := a[127:64] +// MEM[mem_addr+127:mem_addr+64] := a[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storer_pd +FORCE_INLINE void _mm_storer_pd(double *mem_addr, __m128d a) { - // return vgetq_lane_u32(vcgtq_f32(vreinterpretq_f32_m128(a), - // vreinterpretq_f32_m128(b)), 0); - uint32x4_t a_not_nan = - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); - uint32x4_t b_not_nan = - vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); - uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); - uint32x4_t a_gt_b = - vcgtq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); - return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_gt_b), 0) != 0) ? 1 : 0; + float32x4_t f = vreinterpretq_f32_m128d(a); + _mm_store_pd(mem_addr, vreinterpretq_m128d_f32(vextq_f32(f, f, 2))); } -// Compares the lower single-precision floating point scalar values of a and b -// using a less than or equal operation. : -// https://msdn.microsoft.com/en-us/library/1w4t7c57(v=vs.90).aspx -FORCE_INLINE int _mm_comile_ss(__m128 a, __m128 b) +// Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point +// elements) from a into memory. mem_addr does not need to be aligned on any +// particular boundary. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_pd +FORCE_INLINE void _mm_storeu_pd(double *mem_addr, __m128d a) { - // return vgetq_lane_u32(vcleq_f32(vreinterpretq_f32_m128(a), - // vreinterpretq_f32_m128(b)), 0); - uint32x4_t a_not_nan = - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); - uint32x4_t b_not_nan = - vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); - uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); - uint32x4_t a_le_b = - vcleq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); - return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_le_b), 0) != 0) ? 1 : 0; + _mm_store_pd(mem_addr, a); } -// Compares the lower single-precision floating point scalar values of a and b -// using a greater than or equal operation. : -// https://msdn.microsoft.com/en-us/library/8t80des6(v=vs.100).aspx -FORCE_INLINE int _mm_comige_ss(__m128 a, __m128 b) +// Stores 128-bits of integer data a at the address p. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si128 +FORCE_INLINE void _mm_storeu_si128(__m128i *p, __m128i a) { - // return vgetq_lane_u32(vcgeq_f32(vreinterpretq_f32_m128(a), - // vreinterpretq_f32_m128(b)), 0); - uint32x4_t a_not_nan = - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); - uint32x4_t b_not_nan = - vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); - uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); - uint32x4_t a_ge_b = - vcgeq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); - return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_ge_b), 0) != 0) ? 1 : 0; + vst1q_s32((int32_t *) p, vreinterpretq_s32_m128i(a)); } -// Compares the lower single-precision floating point scalar values of a and b -// using an equality operation. : -// https://msdn.microsoft.com/en-us/library/93yx2h2b(v=vs.100).aspx -FORCE_INLINE int _mm_comieq_ss(__m128 a, __m128 b) +// Stores 32-bits of integer data a at the address p. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si32 +FORCE_INLINE void _mm_storeu_si32(void *p, __m128i a) { - // return vgetq_lane_u32(vceqq_f32(vreinterpretq_f32_m128(a), - // vreinterpretq_f32_m128(b)), 0); - uint32x4_t a_not_nan = - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); - uint32x4_t b_not_nan = - vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); - uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); - uint32x4_t a_eq_b = - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); - return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_eq_b), 0) != 0) ? 1 : 0; + vst1q_lane_s32((int32_t *) p, vreinterpretq_s32_m128i(a), 0); } -// Compares the lower single-precision floating point scalar values of a and b -// using an inequality operation. : -// https://msdn.microsoft.com/en-us/library/bafh5e0a(v=vs.90).aspx -FORCE_INLINE int _mm_comineq_ss(__m128 a, __m128 b) +// Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point +// elements) from a into memory using a non-temporal memory hint. mem_addr must +// be aligned on a 16-byte boundary or a general-protection exception may be +// generated. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_pd +FORCE_INLINE void _mm_stream_pd(double *p, __m128d a) { - // return !vgetq_lane_u32(vceqq_f32(vreinterpretq_f32_m128(a), - // vreinterpretq_f32_m128(b)), 0); - uint32x4_t a_not_nan = - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); - uint32x4_t b_not_nan = - vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); - uint32x4_t a_or_b_nan = vmvnq_u32(vandq_u32(a_not_nan, b_not_nan)); - uint32x4_t a_neq_b = vmvnq_u32( - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); - return (vgetq_lane_u32(vorrq_u32(a_or_b_nan, a_neq_b), 0) != 0) ? 1 : 0; +#if __has_builtin(__builtin_nontemporal_store) + __builtin_nontemporal_store(a, (float32x4_t *) p); +#elif defined(__aarch64__) + vst1q_f64(p, vreinterpretq_f64_m128d(a)); +#else + vst1q_s64((int64_t *) p, vreinterpretq_s64_m128d(a)); +#endif } -// according to the documentation, these intrinsics behave the same as the -// non-'u' versions. We'll just alias them here. -#define _mm_ucomieq_ss _mm_comieq_ss -#define _mm_ucomige_ss _mm_comige_ss -#define _mm_ucomigt_ss _mm_comigt_ss -#define _mm_ucomile_ss _mm_comile_ss -#define _mm_ucomilt_ss _mm_comilt_ss -#define _mm_ucomineq_ss _mm_comineq_ss +// Stores the data in a to the address p without polluting the caches. If the +// cache line containing address p is already in the cache, the cache will be +// updated. +// https://msdn.microsoft.com/en-us/library/ba08y07y%28v=vs.90%29.aspx +FORCE_INLINE void _mm_stream_si128(__m128i *p, __m128i a) +{ +#if __has_builtin(__builtin_nontemporal_store) + __builtin_nontemporal_store(a, p); +#else + vst1q_s64((int64_t *) p, vreinterpretq_s64_m128i(a)); +#endif +} -/* Conversions */ +// Store 32-bit integer a into memory using a non-temporal hint to minimize +// cache pollution. If the cache line containing address mem_addr is already in +// the cache, the cache will be updated. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_si32 +FORCE_INLINE void _mm_stream_si32(int *p, int a) +{ + vst1q_lane_s32((int32_t *) p, vdupq_n_s32(a), 0); +} -// Convert packed signed 32-bit integers in b to packed single-precision -// (32-bit) floating-point elements, store the results in the lower 2 elements -// of dst, and copy the upper 2 packed elements from a to the upper elements of -// dst. +// Subtract packed 16-bit integers in b from packed 16-bit integers in a, and +// store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_epi16 +FORCE_INLINE __m128i _mm_sub_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vsubq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Subtracts the 4 signed or unsigned 32-bit integers of b from the 4 signed or +// unsigned 32-bit integers of a. // -// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) -// dst[63:32] := Convert_Int32_To_FP32(b[63:32]) -// dst[95:64] := a[95:64] -// dst[127:96] := a[127:96] +// r0 := a0 - b0 +// r1 := a1 - b1 +// r2 := a2 - b2 +// r3 := a3 - b3 // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_pi2ps -FORCE_INLINE __m128 _mm_cvt_pi2ps(__m128 a, __m64 b) +// https://msdn.microsoft.com/en-us/library/vstudio/fhh866h0(v=vs.100).aspx +FORCE_INLINE __m128i _mm_sub_epi32(__m128i a, __m128i b) { - return vreinterpretq_m128_f32( - vcombine_f32(vcvt_f32_s32(vreinterpret_s32_m64(b)), - vget_high_f32(vreinterpretq_f32_m128(a)))); + return vreinterpretq_m128i_s32( + vsubq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); } -// Convert the signed 32-bit integer b to a single-precision (32-bit) -// floating-point element, store the result in the lower element of dst, and -// copy the upper 3 packed elements from a to the upper elements of dst. +// Subtract 2 packed 64-bit integers in b from 2 packed 64-bit integers in a, +// and store the results in dst. +// r0 := a0 - b0 +// r1 := a1 - b1 +FORCE_INLINE __m128i _mm_sub_epi64(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s64( + vsubq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); +} + +// Subtract packed 8-bit integers in b from packed 8-bit integers in a, and +// store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_epi8 +FORCE_INLINE __m128i _mm_sub_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vsubq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Subtract packed double-precision (64-bit) floating-point elements in b from +// packed double-precision (64-bit) floating-point elements in a, and store the +// results in dst. // -// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) -// dst[127:32] := a[127:32] +// FOR j := 0 to 1 +// i := j*64 +// dst[i+63:i] := a[i+63:i] - b[i+63:i] +// ENDFOR // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_si2ss -FORCE_INLINE __m128 _mm_cvt_si2ss(__m128 a, int b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_sub_pd +FORCE_INLINE __m128d _mm_sub_pd(__m128d a, __m128d b) { - return vreinterpretq_m128_f32( - vsetq_lane_f32((float) b, vreinterpretq_f32_m128(a), 0)); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vsubq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[2]; + c[0] = da[0] - db[0]; + c[1] = da[1] - db[1]; + return vld1q_f32((float32_t *) c); +#endif } -// Convert the signed 32-bit integer b to a single-precision (32-bit) -// floating-point element, store the result in the lower element of dst, and -// copy the upper 3 packed elements from a to the upper elements of dst. +// Subtract the lower double-precision (64-bit) floating-point element in b from +// the lower double-precision (64-bit) floating-point element in a, store the +// result in the lower element of dst, and copy the upper element from a to the +// upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_sd +FORCE_INLINE __m128d _mm_sub_sd(__m128d a, __m128d b) +{ + return _mm_move_sd(a, _mm_sub_pd(a, b)); +} + +// Subtract 64-bit integer b from 64-bit integer a, and store the result in dst. // -// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) -// dst[127:32] := a[127:32] +// dst[63:0] := a[63:0] - b[63:0] // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi32_ss -#define _mm_cvtsi32_ss(a, b) _mm_cvt_si2ss(a, b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_si64 +FORCE_INLINE __m64 _mm_sub_si64(__m64 a, __m64 b) +{ + return vreinterpret_m64_s64( + vsub_s64(vreinterpret_s64_m64(a), vreinterpret_s64_m64(b))); +} -// Convert the signed 64-bit integer b to a single-precision (32-bit) -// floating-point element, store the result in the lower element of dst, and -// copy the upper 3 packed elements from a to the upper elements of dst. +// Subtracts the 8 signed 16-bit integers of b from the 8 signed 16-bit integers +// of a and saturates. // -// dst[31:0] := Convert_Int64_To_FP32(b[63:0]) -// dst[127:32] := a[127:32] +// r0 := SignedSaturate(a0 - b0) +// r1 := SignedSaturate(a1 - b1) +// ... +// r7 := SignedSaturate(a7 - b7) // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi64_ss -FORCE_INLINE __m128 _mm_cvtsi64_ss(__m128 a, int64_t b) +// https://technet.microsoft.com/en-us/subscriptions/3247z5b8(v=vs.90) +FORCE_INLINE __m128i _mm_subs_epi16(__m128i a, __m128i b) { - return vreinterpretq_m128_f32( - vsetq_lane_f32((float) b, vreinterpretq_f32_m128(a), 0)); + return vreinterpretq_m128i_s16( + vqsubq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); } -// Convert the lower single-precision (32-bit) floating-point element in a to a -// 32-bit integer, and store the result in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_ss2si -FORCE_INLINE int _mm_cvt_ss2si(__m128 a) +// Subtracts the 16 signed 8-bit integers of b from the 16 signed 8-bit integers +// of a and saturates. +// +// r0 := SignedSaturate(a0 - b0) +// r1 := SignedSaturate(a1 - b1) +// ... +// r15 := SignedSaturate(a15 - b15) +// +// https://technet.microsoft.com/en-us/subscriptions/by7kzks1(v=vs.90) +FORCE_INLINE __m128i _mm_subs_epi8(__m128i a, __m128i b) { -#if defined(__aarch64__) - return vgetq_lane_s32(vcvtnq_s32_f32(vreinterpretq_f32_m128(a)), 0); -#else - float32_t data = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); - float32_t diff = data - floor(data); - if (diff > 0.5) - return (int32_t) ceil(data); - if (unlikely(diff == 0.5)) { - int32_t f = (int32_t) floor(data); - int32_t c = (int32_t) ceil(data); - return c & 1 ? f : c; - } - return (int32_t) floor(data); -#endif + return vreinterpretq_m128i_s8( + vqsubq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); } -// Convert packed 16-bit integers in a to packed single-precision (32-bit) -// floating-point elements, and store the results in dst. +// Subtracts the 8 unsigned 16-bit integers of bfrom the 8 unsigned 16-bit +// integers of a and saturates.. +// https://technet.microsoft.com/en-us/subscriptions/index/f44y0s19(v=vs.90).aspx +FORCE_INLINE __m128i _mm_subs_epu16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vqsubq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); +} + +// Subtracts the 16 unsigned 8-bit integers of b from the 16 unsigned 8-bit +// integers of a and saturates. // -// FOR j := 0 to 3 -// i := j*16 -// m := j*32 -// dst[m+31:m] := Convert_Int16_To_FP32(a[i+15:i]) -// ENDFOR +// r0 := UnsignedSaturate(a0 - b0) +// r1 := UnsignedSaturate(a1 - b1) +// ... +// r15 := UnsignedSaturate(a15 - b15) // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi16_ps -FORCE_INLINE __m128 _mm_cvtpi16_ps(__m64 a) +// https://technet.microsoft.com/en-us/subscriptions/yadkxc18(v=vs.90) +FORCE_INLINE __m128i _mm_subs_epu8(__m128i a, __m128i b) { - return vreinterpretq_m128_f32( - vcvtq_f32_s32(vmovl_s16(vreinterpret_s16_m64(a)))); + return vreinterpretq_m128i_u8( + vqsubq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); } -// Convert packed 32-bit integers in b to packed single-precision (32-bit) -// floating-point elements, store the results in the lower 2 elements of dst, -// and copy the upper 2 packed elements from a to the upper elements of dst. +#define _mm_ucomieq_sd _mm_comieq_sd +#define _mm_ucomige_sd _mm_comige_sd +#define _mm_ucomigt_sd _mm_comigt_sd +#define _mm_ucomile_sd _mm_comile_sd +#define _mm_ucomilt_sd _mm_comilt_sd +#define _mm_ucomineq_sd _mm_comineq_sd + +// Return vector of type __m128d with undefined elements. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_undefined_pd +FORCE_INLINE __m128d _mm_undefined_pd(void) +{ +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wuninitialized" +#endif + __m128d a; + return a; +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif +} + +// Interleaves the upper 4 signed or unsigned 16-bit integers in a with the +// upper 4 signed or unsigned 16-bit integers in b. // -// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) -// dst[63:32] := Convert_Int32_To_FP32(b[63:32]) -// dst[95:64] := a[95:64] -// dst[127:96] := a[127:96] +// r0 := a4 +// r1 := b4 +// r2 := a5 +// r3 := b5 +// r4 := a6 +// r5 := b6 +// r6 := a7 +// r7 := b7 // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi32_ps -FORCE_INLINE __m128 _mm_cvtpi32_ps(__m128 a, __m64 b) +// https://msdn.microsoft.com/en-us/library/03196cz7(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpackhi_epi16(__m128i a, __m128i b) { - return vreinterpretq_m128_f32( - vcombine_f32(vcvt_f32_s32(vreinterpret_s32_m64(b)), - vget_high_f32(vreinterpretq_f32_m128(a)))); +#if defined(__aarch64__) + return vreinterpretq_m128i_s16( + vzip2q_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +#else + int16x4_t a1 = vget_high_s16(vreinterpretq_s16_m128i(a)); + int16x4_t b1 = vget_high_s16(vreinterpretq_s16_m128i(b)); + int16x4x2_t result = vzip_s16(a1, b1); + return vreinterpretq_m128i_s16(vcombine_s16(result.val[0], result.val[1])); +#endif } -// Convert packed signed 32-bit integers in a to packed single-precision -// (32-bit) floating-point elements, store the results in the lower 2 elements -// of dst, then covert the packed signed 32-bit integers in b to -// single-precision (32-bit) floating-point element, and store the results in -// the upper 2 elements of dst. +// Interleaves the upper 2 signed or unsigned 32-bit integers in a with the +// upper 2 signed or unsigned 32-bit integers in b. +// https://msdn.microsoft.com/en-us/library/65sa7cbs(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpackhi_epi32(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s32( + vzip2q_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +#else + int32x2_t a1 = vget_high_s32(vreinterpretq_s32_m128i(a)); + int32x2_t b1 = vget_high_s32(vreinterpretq_s32_m128i(b)); + int32x2x2_t result = vzip_s32(a1, b1); + return vreinterpretq_m128i_s32(vcombine_s32(result.val[0], result.val[1])); +#endif +} + +// Interleaves the upper signed or unsigned 64-bit integer in a with the +// upper signed or unsigned 64-bit integer in b. // -// dst[31:0] := Convert_Int32_To_FP32(a[31:0]) -// dst[63:32] := Convert_Int32_To_FP32(a[63:32]) -// dst[95:64] := Convert_Int32_To_FP32(b[31:0]) -// dst[127:96] := Convert_Int32_To_FP32(b[63:32]) +// r0 := a1 +// r1 := b1 +FORCE_INLINE __m128i _mm_unpackhi_epi64(__m128i a, __m128i b) +{ + int64x1_t a_h = vget_high_s64(vreinterpretq_s64_m128i(a)); + int64x1_t b_h = vget_high_s64(vreinterpretq_s64_m128i(b)); + return vreinterpretq_m128i_s64(vcombine_s64(a_h, b_h)); +} + +// Interleaves the upper 8 signed or unsigned 8-bit integers in a with the upper +// 8 signed or unsigned 8-bit integers in b. // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi32x2_ps -FORCE_INLINE __m128 _mm_cvtpi32x2_ps(__m64 a, __m64 b) +// r0 := a8 +// r1 := b8 +// r2 := a9 +// r3 := b9 +// ... +// r14 := a15 +// r15 := b15 +// +// https://msdn.microsoft.com/en-us/library/t5h7783k(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpackhi_epi8(__m128i a, __m128i b) { - return vreinterpretq_m128_f32(vcvtq_f32_s32( - vcombine_s32(vreinterpret_s32_m64(a), vreinterpret_s32_m64(b)))); +#if defined(__aarch64__) + return vreinterpretq_m128i_s8( + vzip2q_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +#else + int8x8_t a1 = + vreinterpret_s8_s16(vget_high_s16(vreinterpretq_s16_m128i(a))); + int8x8_t b1 = + vreinterpret_s8_s16(vget_high_s16(vreinterpretq_s16_m128i(b))); + int8x8x2_t result = vzip_s8(a1, b1); + return vreinterpretq_m128i_s8(vcombine_s8(result.val[0], result.val[1])); +#endif } -// Convert the lower packed 8-bit integers in a to packed single-precision -// (32-bit) floating-point elements, and store the results in dst. +// Unpack and interleave double-precision (64-bit) floating-point elements from +// the high half of a and b, and store the results in dst. // -// FOR j := 0 to 3 -// i := j*8 -// m := j*32 -// dst[m+31:m] := Convert_Int8_To_FP32(a[i+7:i]) -// ENDFOR +// DEFINE INTERLEAVE_HIGH_QWORDS(src1[127:0], src2[127:0]) { +// dst[63:0] := src1[127:64] +// dst[127:64] := src2[127:64] +// RETURN dst[127:0] +// } +// dst[127:0] := INTERLEAVE_HIGH_QWORDS(a[127:0], b[127:0]) // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi8_ps -FORCE_INLINE __m128 _mm_cvtpi8_ps(__m64 a) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_unpackhi_pd +FORCE_INLINE __m128d _mm_unpackhi_pd(__m128d a, __m128d b) { - return vreinterpretq_m128_f32(vcvtq_f32_s32( - vmovl_s16(vget_low_s16(vmovl_s8(vreinterpret_s8_m64(a)))))); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vzip2q_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + return vreinterpretq_m128d_s64( + vcombine_s64(vget_high_s64(vreinterpretq_s64_m128d(a)), + vget_high_s64(vreinterpretq_s64_m128d(b)))); +#endif } -// Convert packed unsigned 16-bit integers in a to packed single-precision -// (32-bit) floating-point elements, and store the results in dst. +// Interleaves the lower 4 signed or unsigned 16-bit integers in a with the +// lower 4 signed or unsigned 16-bit integers in b. // -// FOR j := 0 to 3 -// i := j*16 -// m := j*32 -// dst[m+31:m] := Convert_UInt16_To_FP32(a[i+15:i]) -// ENDFOR +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 +// r4 := a2 +// r5 := b2 +// r6 := a3 +// r7 := b3 // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpu16_ps -FORCE_INLINE __m128 _mm_cvtpu16_ps(__m64 a) +// https://msdn.microsoft.com/en-us/library/btxb17bw%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_unpacklo_epi16(__m128i a, __m128i b) { - return vreinterpretq_m128_f32( - vcvtq_f32_u32(vmovl_u16(vreinterpret_u16_m64(a)))); +#if defined(__aarch64__) + return vreinterpretq_m128i_s16( + vzip1q_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +#else + int16x4_t a1 = vget_low_s16(vreinterpretq_s16_m128i(a)); + int16x4_t b1 = vget_low_s16(vreinterpretq_s16_m128i(b)); + int16x4x2_t result = vzip_s16(a1, b1); + return vreinterpretq_m128i_s16(vcombine_s16(result.val[0], result.val[1])); +#endif } -// Convert the lower packed unsigned 8-bit integers in a to packed -// single-precision (32-bit) floating-point elements, and store the results in -// dst. +// Interleaves the lower 2 signed or unsigned 32 - bit integers in a with the +// lower 2 signed or unsigned 32 - bit integers in b. // -// FOR j := 0 to 3 -// i := j*8 -// m := j*32 -// dst[m+31:m] := Convert_UInt8_To_FP32(a[i+7:i]) -// ENDFOR +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpu8_ps -FORCE_INLINE __m128 _mm_cvtpu8_ps(__m64 a) +// https://msdn.microsoft.com/en-us/library/x8atst9d(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpacklo_epi32(__m128i a, __m128i b) { - return vreinterpretq_m128_f32(vcvtq_f32_u32( - vmovl_u16(vget_low_u16(vmovl_u8(vreinterpret_u8_m64(a)))))); +#if defined(__aarch64__) + return vreinterpretq_m128i_s32( + vzip1q_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +#else + int32x2_t a1 = vget_low_s32(vreinterpretq_s32_m128i(a)); + int32x2_t b1 = vget_low_s32(vreinterpretq_s32_m128i(b)); + int32x2x2_t result = vzip_s32(a1, b1); + return vreinterpretq_m128i_s32(vcombine_s32(result.val[0], result.val[1])); +#endif } -// Converts the four single-precision, floating-point values of a to signed -// 32-bit integer values using truncate. -// https://msdn.microsoft.com/en-us/library/vstudio/1h005y6x(v=vs.100).aspx -FORCE_INLINE __m128i _mm_cvttps_epi32(__m128 a) +FORCE_INLINE __m128i _mm_unpacklo_epi64(__m128i a, __m128i b) { - return vreinterpretq_m128i_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a))); + int64x1_t a_l = vget_low_s64(vreinterpretq_s64_m128i(a)); + int64x1_t b_l = vget_low_s64(vreinterpretq_s64_m128i(b)); + return vreinterpretq_m128i_s64(vcombine_s64(a_l, b_l)); } -// Convert the lower double-precision (64-bit) floating-point element in a to a -// 64-bit integer with truncation, and store the result in dst. +// Interleaves the lower 8 signed or unsigned 8-bit integers in a with the lower +// 8 signed or unsigned 8-bit integers in b. // -// dst[63:0] := Convert_FP64_To_Int64_Truncate(a[63:0]) +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 +// ... +// r14 := a7 +// r15 := b7 // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttsd_si64 -FORCE_INLINE int64_t _mm_cvttsd_si64(__m128d a) +// https://msdn.microsoft.com/en-us/library/xf7k860c%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_unpacklo_epi8(__m128i a, __m128i b) { #if defined(__aarch64__) - return vgetq_lane_s64(vcvtq_s64_f64(vreinterpretq_f64_m128d(a)), 0); + return vreinterpretq_m128i_s8( + vzip1q_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); #else - double ret = *((double *) &a); - return (int64_t) ret; + int8x8_t a1 = vreinterpret_s8_s16(vget_low_s16(vreinterpretq_s16_m128i(a))); + int8x8_t b1 = vreinterpret_s8_s16(vget_low_s16(vreinterpretq_s16_m128i(b))); + int8x8x2_t result = vzip_s8(a1, b1); + return vreinterpretq_m128i_s8(vcombine_s8(result.val[0], result.val[1])); #endif } -// Convert the lower double-precision (64-bit) floating-point element in a to a -// 64-bit integer with truncation, and store the result in dst. +// Unpack and interleave double-precision (64-bit) floating-point elements from +// the low half of a and b, and store the results in dst. // -// dst[63:0] := Convert_FP64_To_Int64_Truncate(a[63:0]) +// DEFINE INTERLEAVE_QWORDS(src1[127:0], src2[127:0]) { +// dst[63:0] := src1[63:0] +// dst[127:64] := src2[63:0] +// RETURN dst[127:0] +// } +// dst[127:0] := INTERLEAVE_QWORDS(a[127:0], b[127:0]) // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttsd_si64x -#define _mm_cvttsd_si64x(a) _mm_cvttsd_si64(a) - -// Converts the four signed 32-bit integer values of a to single-precision, -// floating-point values -// https://msdn.microsoft.com/en-us/library/vstudio/36bwxcx5(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cvtepi32_ps(__m128i a) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_unpacklo_pd +FORCE_INLINE __m128d _mm_unpacklo_pd(__m128d a, __m128d b) { - return vreinterpretq_m128_f32(vcvtq_f32_s32(vreinterpretq_s32_m128i(a))); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vzip1q_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + return vreinterpretq_m128d_s64( + vcombine_s64(vget_low_s64(vreinterpretq_s64_m128d(a)), + vget_low_s64(vreinterpretq_s64_m128d(b)))); +#endif } -// Converts the four unsigned 8-bit integers in the lower 16 bits to four -// unsigned 32-bit integers. -FORCE_INLINE __m128i _mm_cvtepu8_epi16(__m128i a) +// Compute the bitwise XOR of packed double-precision (64-bit) floating-point +// elements in a and b, and store the results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// dst[i+63:i] := a[i+63:i] XOR b[i+63:i] +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_xor_pd +FORCE_INLINE __m128d _mm_xor_pd(__m128d a, __m128d b) { - uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx DCBA */ - uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0D0C 0B0A */ - return vreinterpretq_m128i_u16(u16x8); + return vreinterpretq_m128d_s64( + veorq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b))); } -// Converts the four unsigned 8-bit integers in the lower 32 bits to four -// unsigned 32-bit integers. -// https://msdn.microsoft.com/en-us/library/bb531467%28v=vs.100%29.aspx -FORCE_INLINE __m128i _mm_cvtepu8_epi32(__m128i a) +// Computes the bitwise XOR of the 128-bit value in a and the 128-bit value in +// b. https://msdn.microsoft.com/en-us/library/fzt08www(v=vs.100).aspx +FORCE_INLINE __m128i _mm_xor_si128(__m128i a, __m128i b) { - uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx DCBA */ - uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0D0C 0B0A */ - uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000D 000C 000B 000A */ - return vreinterpretq_m128i_u32(u32x4); + return vreinterpretq_m128i_s32( + veorq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); } -// Converts the two unsigned 8-bit integers in the lower 16 bits to two -// unsigned 64-bit integers. -FORCE_INLINE __m128i _mm_cvtepu8_epi64(__m128i a) +/* SSE3 */ + +// Alternatively add and subtract packed double-precision (64-bit) +// floating-point elements in a to/from packed elements in b, and store the +// results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// IF ((j & 1) == 0) +// dst[i+63:i] := a[i+63:i] - b[i+63:i] +// ELSE +// dst[i+63:i] := a[i+63:i] + b[i+63:i] +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_addsub_pd +FORCE_INLINE __m128d _mm_addsub_pd(__m128d a, __m128d b) { - uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx xxBA */ - uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0x0x 0B0A */ - uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000x 000x 000B 000A */ - uint64x2_t u64x2 = vmovl_u32(vget_low_u32(u32x4)); /* 0000 000B 0000 000A */ - return vreinterpretq_m128i_u64(u64x2); + __m128d mask = _mm_set_pd(1.0f, -1.0f); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vfmaq_f64(vreinterpretq_f64_m128d(a), + vreinterpretq_f64_m128d(b), + vreinterpretq_f64_m128d(mask))); +#else + return _mm_add_pd(_mm_mul_pd(b, mask), a); +#endif } -// Converts the four unsigned 8-bit integers in the lower 16 bits to four -// unsigned 32-bit integers. -FORCE_INLINE __m128i _mm_cvtepi8_epi16(__m128i a) +// Alternatively add and subtract packed single-precision (32-bit) +// floating-point elements in a to/from packed elements in b, and store the +// results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=addsub_ps +FORCE_INLINE __m128 _mm_addsub_ps(__m128 a, __m128 b) { - int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx DCBA */ - int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0D0C 0B0A */ - return vreinterpretq_m128i_s16(s16x8); + __m128 mask = {-1.0f, 1.0f, -1.0f, 1.0f}; +#if defined(__aarch64__) || defined(__ARM_FEATURE_FMA) /* VFPv4+ */ + return vreinterpretq_m128_f32(vfmaq_f32(vreinterpretq_f32_m128(a), + vreinterpretq_f32_m128(mask), + vreinterpretq_f32_m128(b))); +#else + return _mm_add_ps(_mm_mul_ps(b, mask), a); +#endif } -// Converts the four unsigned 8-bit integers in the lower 32 bits to four -// unsigned 32-bit integers. -FORCE_INLINE __m128i _mm_cvtepi8_epi32(__m128i a) +// Horizontally add adjacent pairs of double-precision (64-bit) floating-point +// elements in a and b, and pack the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pd +FORCE_INLINE __m128d _mm_hadd_pd(__m128d a, __m128d b) { - int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx DCBA */ - int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0D0C 0B0A */ - int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000D 000C 000B 000A */ - return vreinterpretq_m128i_s32(s32x4); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vpaddq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[] = {da[0] + da[1], db[0] + db[1]}; + return vreinterpretq_m128d_u64(vld1q_u64((uint64_t *) c)); +#endif } -// Converts the two signed 8-bit integers in the lower 32 bits to four -// signed 64-bit integers. -FORCE_INLINE __m128i _mm_cvtepi8_epi64(__m128i a) +// Computes pairwise add of each argument as single-precision, floating-point +// values a and b. +// https://msdn.microsoft.com/en-us/library/yd9wecaa.aspx +FORCE_INLINE __m128 _mm_hadd_ps(__m128 a, __m128 b) { - int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx xxBA */ - int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0x0x 0B0A */ - int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000x 000x 000B 000A */ - int64x2_t s64x2 = vmovl_s32(vget_low_s32(s32x4)); /* 0000 000B 0000 000A */ - return vreinterpretq_m128i_s64(s64x2); +#if defined(__aarch64__) + return vreinterpretq_m128_f32( + vpaddq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#else + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a)); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); + float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32( + vcombine_f32(vpadd_f32(a10, a32), vpadd_f32(b10, b32))); +#endif } -// Converts the four signed 16-bit integers in the lower 64 bits to four signed -// 32-bit integers. -FORCE_INLINE __m128i _mm_cvtepi16_epi32(__m128i a) +// Horizontally subtract adjacent pairs of double-precision (64-bit) +// floating-point elements in a and b, and pack the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsub_pd +FORCE_INLINE __m128d _mm_hsub_pd(__m128d _a, __m128d _b) { - return vreinterpretq_m128i_s32( - vmovl_s16(vget_low_s16(vreinterpretq_s16_m128i(a)))); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vsubq_f64( + vuzp1q_f64(vreinterpretq_f64_m128d(_a), vreinterpretq_f64_m128d(_b)), + vuzp2q_f64(vreinterpretq_f64_m128d(_a), vreinterpretq_f64_m128d(_b)))); +#else + double *da = (double *) &_a; + double *db = (double *) &_b; + double c[] = {da[0] - da[1], db[0] - db[1]}; + return vreinterpretq_m128d_u64(vld1q_u64((uint64_t *) c)); +#endif } -// Converts the two signed 16-bit integers in the lower 32 bits two signed -// 32-bit integers. -FORCE_INLINE __m128i _mm_cvtepi16_epi64(__m128i a) +// Horizontally substract adjacent pairs of single-precision (32-bit) +// floating-point elements in a and b, and pack the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsub_ps +FORCE_INLINE __m128 _mm_hsub_ps(__m128 _a, __m128 _b) { - int16x8_t s16x8 = vreinterpretq_s16_m128i(a); /* xxxx xxxx xxxx 0B0A */ - int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000x 000x 000B 000A */ - int64x2_t s64x2 = vmovl_s32(vget_low_s32(s32x4)); /* 0000 000B 0000 000A */ - return vreinterpretq_m128i_s64(s64x2); +#if defined(__aarch64__) + return vreinterpretq_m128_f32(vsubq_f32( + vuzp1q_f32(vreinterpretq_f32_m128(_a), vreinterpretq_f32_m128(_b)), + vuzp2q_f32(vreinterpretq_f32_m128(_a), vreinterpretq_f32_m128(_b)))); +#else + float32x4x2_t c = + vuzpq_f32(vreinterpretq_f32_m128(_a), vreinterpretq_f32_m128(_b)); + return vreinterpretq_m128_f32(vsubq_f32(c.val[0], c.val[1])); +#endif } -// Converts the four unsigned 16-bit integers in the lower 64 bits to four -// unsigned 32-bit integers. -FORCE_INLINE __m128i _mm_cvtepu16_epi32(__m128i a) +// Load 128-bits of integer data from unaligned memory into dst. This intrinsic +// may perform better than _mm_loadu_si128 when the data crosses a cache line +// boundary. +// +// dst[127:0] := MEM[mem_addr+127:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_lddqu_si128 +#define _mm_lddqu_si128 _mm_loadu_si128 + +// Load a double-precision (64-bit) floating-point element from memory into both +// elements of dst. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := MEM[mem_addr+63:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loaddup_pd +#define _mm_loaddup_pd _mm_load1_pd + +// Duplicate the low double-precision (64-bit) floating-point element from a, +// and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movedup_pd +FORCE_INLINE __m128d _mm_movedup_pd(__m128d a) { - return vreinterpretq_m128i_u32( - vmovl_u16(vget_low_u16(vreinterpretq_u16_m128i(a)))); +#if (__aarch64__) + return vreinterpretq_m128d_f64( + vdupq_laneq_f64(vreinterpretq_f64_m128d(a), 0)); +#else + return vreinterpretq_m128d_u64( + vdupq_n_u64(vgetq_lane_u64(vreinterpretq_u64_m128d(a), 0))); +#endif } -// Converts the two unsigned 16-bit integers in the lower 32 bits to two -// unsigned 64-bit integers. -FORCE_INLINE __m128i _mm_cvtepu16_epi64(__m128i a) +// Duplicate odd-indexed single-precision (32-bit) floating-point elements +// from a, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movehdup_ps +FORCE_INLINE __m128 _mm_movehdup_ps(__m128 a) { - uint16x8_t u16x8 = vreinterpretq_u16_m128i(a); /* xxxx xxxx xxxx 0B0A */ - uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000x 000x 000B 000A */ - uint64x2_t u64x2 = vmovl_u32(vget_low_u32(u32x4)); /* 0000 000B 0000 000A */ - return vreinterpretq_m128i_u64(u64x2); +#if __has_builtin(__builtin_shufflevector) + return vreinterpretq_m128_f32(__builtin_shufflevector( + vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 1, 1, 3, 3)); +#else + float32_t a1 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 1); + float32_t a3 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 3); + float ALIGN_STRUCT(16) data[4] = {a1, a1, a3, a3}; + return vreinterpretq_m128_f32(vld1q_f32(data)); +#endif } -// Converts the two unsigned 32-bit integers in the lower 64 bits to two -// unsigned 64-bit integers. -FORCE_INLINE __m128i _mm_cvtepu32_epi64(__m128i a) +// Duplicate even-indexed single-precision (32-bit) floating-point elements +// from a, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_moveldup_ps +FORCE_INLINE __m128 _mm_moveldup_ps(__m128 a) { - return vreinterpretq_m128i_u64( - vmovl_u32(vget_low_u32(vreinterpretq_u32_m128i(a)))); +#if __has_builtin(__builtin_shufflevector) + return vreinterpretq_m128_f32(__builtin_shufflevector( + vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 0, 0, 2, 2)); +#else + float32_t a0 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + float32_t a2 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 2); + float ALIGN_STRUCT(16) data[4] = {a0, a0, a2, a2}; + return vreinterpretq_m128_f32(vld1q_f32(data)); +#endif } -// Converts the two signed 32-bit integers in the lower 64 bits to two signed -// 64-bit integers. -FORCE_INLINE __m128i _mm_cvtepi32_epi64(__m128i a) +/* SSSE3 */ + +// Compute the absolute value of packed signed 16-bit integers in a, and store +// the unsigned results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// dst[i+15:i] := ABS(a[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi16 +FORCE_INLINE __m128i _mm_abs_epi16(__m128i a) { - return vreinterpretq_m128i_s64( - vmovl_s32(vget_low_s32(vreinterpretq_s32_m128i(a)))); + return vreinterpretq_m128i_s16(vabsq_s16(vreinterpretq_s16_m128i(a))); } -// Converts the four single-precision, floating-point values of a to signed -// 32-bit integer values. +// Compute the absolute value of packed signed 32-bit integers in a, and store +// the unsigned results in dst. // -// r0 := (int) a0 -// r1 := (int) a1 -// r2 := (int) a2 -// r3 := (int) a3 +// FOR j := 0 to 3 +// i := j*32 +// dst[i+31:i] := ABS(a[i+31:i]) +// ENDFOR // -// https://msdn.microsoft.com/en-us/library/vstudio/xdc42k5e(v=vs.100).aspx -// *NOTE*. The default rounding mode on SSE is 'round to even', which ARMv7-A -// does not support! It is supported on ARMv8-A however. -FORCE_INLINE __m128i _mm_cvtps_epi32(__m128 a) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi32 +FORCE_INLINE __m128i _mm_abs_epi32(__m128i a) { -#if defined(__aarch64__) - return vreinterpretq_m128i_s32(vcvtnq_s32_f32(a)); -#else - uint32x4_t signmask = vdupq_n_u32(0x80000000); - float32x4_t half = vbslq_f32(signmask, vreinterpretq_f32_m128(a), - vdupq_n_f32(0.5f)); /* +/- 0.5 */ - int32x4_t r_normal = vcvtq_s32_f32(vaddq_f32( - vreinterpretq_f32_m128(a), half)); /* round to integer: [a + 0.5]*/ - int32x4_t r_trunc = - vcvtq_s32_f32(vreinterpretq_f32_m128(a)); /* truncate to integer: [a] */ - int32x4_t plusone = vreinterpretq_s32_u32(vshrq_n_u32( - vreinterpretq_u32_s32(vnegq_s32(r_trunc)), 31)); /* 1 or 0 */ - int32x4_t r_even = vbicq_s32(vaddq_s32(r_trunc, plusone), - vdupq_n_s32(1)); /* ([a] + {0,1}) & ~1 */ - float32x4_t delta = vsubq_f32( - vreinterpretq_f32_m128(a), - vcvtq_f32_s32(r_trunc)); /* compute delta: delta = (a - [a]) */ - uint32x4_t is_delta_half = vceqq_f32(delta, half); /* delta == +/- 0.5 */ - return vreinterpretq_m128i_s32(vbslq_s32(is_delta_half, r_even, r_normal)); -#endif + return vreinterpretq_m128i_s32(vabsq_s32(vreinterpretq_s32_m128i(a))); } -// Convert packed single-precision (32-bit) floating-point elements in a to -// packed 16-bit integers, and store the results in dst. Note: this intrinsic -// will generate 0x7FFF, rather than 0x8000, for input values between 0x7FFF and -// 0x7FFFFFFF. +// Compute the absolute value of packed signed 8-bit integers in a, and store +// the unsigned results in dst. // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pi16 -FORCE_INLINE __m64 _mm_cvtps_pi16(__m128 a) +// FOR j := 0 to 15 +// i := j*8 +// dst[i+7:i] := ABS(a[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi8 +FORCE_INLINE __m128i _mm_abs_epi8(__m128i a) { - return vreinterpret_m64_s16( - vmovn_s32(vreinterpretq_s32_m128i(_mm_cvtps_epi32(a)))); + return vreinterpretq_m128i_s8(vabsq_s8(vreinterpretq_s8_m128i(a))); } -// Copy the lower 32-bit integer in a to dst. +// Compute the absolute value of packed signed 16-bit integers in a, and store +// the unsigned results in dst. // -// dst[31:0] := a[31:0] +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := ABS(a[i+15:i]) +// ENDFOR // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si32 -FORCE_INLINE int _mm_cvtsi128_si32(__m128i a) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi16 +FORCE_INLINE __m64 _mm_abs_pi16(__m64 a) { - return vgetq_lane_s32(vreinterpretq_s32_m128i(a), 0); + return vreinterpret_m64_s16(vabs_s16(vreinterpret_s16_m64(a))); } -// Copy the lower 64-bit integer in a to dst. +// Compute the absolute value of packed signed 32-bit integers in a, and store +// the unsigned results in dst. // -// dst[63:0] := a[63:0] +// FOR j := 0 to 1 +// i := j*32 +// dst[i+31:i] := ABS(a[i+31:i]) +// ENDFOR // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si64 -FORCE_INLINE int64_t _mm_cvtsi128_si64(__m128i a) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi32 +FORCE_INLINE __m64 _mm_abs_pi32(__m64 a) { - return vgetq_lane_s64(vreinterpretq_s64_m128i(a), 0); + return vreinterpret_m64_s32(vabs_s32(vreinterpret_s32_m64(a))); } -// Copy the lower 64-bit integer in a to dst. +// Compute the absolute value of packed signed 8-bit integers in a, and store +// the unsigned results in dst. // -// dst[63:0] := a[63:0] +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := ABS(a[i+7:i]) +// ENDFOR // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si64x -#define _mm_cvtsi128_si64x(a) _mm_cvtsi128_si64(a) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi8 +FORCE_INLINE __m64 _mm_abs_pi8(__m64 a) +{ + return vreinterpret_m64_s8(vabs_s8(vreinterpret_s8_m64(a))); +} -// Moves 32-bit integer a to the least significant 32 bits of an __m128 object, -// zero extending the upper bits. +// Concatenate 16-byte blocks in a and b into a 32-byte temporary result, shift +// the result right by imm8 bytes, and store the low 16 bytes in dst. // -// r0 := a -// r1 := 0x0 -// r2 := 0x0 -// r3 := 0x0 +// tmp[255:0] := ((a[127:0] << 128)[255:0] OR b[127:0]) >> (imm8*8) +// dst[127:0] := tmp[127:0] // -// https://msdn.microsoft.com/en-us/library/ct3539ha%28v=vs.90%29.aspx -FORCE_INLINE __m128i _mm_cvtsi32_si128(int a) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_alignr_epi8 +FORCE_INLINE __m128i _mm_alignr_epi8(__m128i a, __m128i b, int imm) { - return vreinterpretq_m128i_s32(vsetq_lane_s32(a, vdupq_n_s32(0), 0)); + if (_sse2neon_unlikely(imm & ~31)) + return _mm_setzero_si128(); + int idx; + uint8x16_t tmp[2]; + if (imm >= 16) { + idx = imm - 16; + tmp[0] = vreinterpretq_u8_m128i(a); + tmp[1] = vdupq_n_u8(0); + } else { + idx = imm; + tmp[0] = vreinterpretq_u8_m128i(b); + tmp[1] = vreinterpretq_u8_m128i(a); + } + return vreinterpretq_m128i_u8(vld1q_u8(((uint8_t const *) tmp) + idx)); } -// Moves 64-bit integer a to the least significant 64 bits of an __m128 object, -// zero extending the upper bits. +// Concatenate 8-byte blocks in a and b into a 16-byte temporary result, shift +// the result right by imm8 bytes, and store the low 8 bytes in dst. // -// r0 := a -// r1 := 0x0 -FORCE_INLINE __m128i _mm_cvtsi64_si128(int64_t a) +// tmp[127:0] := ((a[63:0] << 64)[127:0] OR b[63:0]) >> (imm8*8) +// dst[63:0] := tmp[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_alignr_pi8 +#define _mm_alignr_pi8(a, b, imm) \ + __extension__({ \ + __m64 ret; \ + if (_sse2neon_unlikely((imm) >= 16)) { \ + ret = vreinterpret_m64_s8(vdup_n_s8(0)); \ + } else { \ + uint8x8_t tmp_low, tmp_high; \ + if (imm >= 8) { \ + const int idx = imm - 8; \ + tmp_low = vreinterpret_u8_m64(a); \ + tmp_high = vdup_n_u8(0); \ + ret = vreinterpret_m64_u8(vext_u8(tmp_low, tmp_high, idx)); \ + } else { \ + const int idx = imm; \ + tmp_low = vreinterpret_u8_m64(b); \ + tmp_high = vreinterpret_u8_m64(a); \ + ret = vreinterpret_m64_u8(vext_u8(tmp_low, tmp_high, idx)); \ + } \ + } \ + ret; \ + }) + +// Computes pairwise add of each argument as a 16-bit signed or unsigned integer +// values a and b. +FORCE_INLINE __m128i _mm_hadd_epi16(__m128i _a, __m128i _b) { - return vreinterpretq_m128i_s64(vsetq_lane_s64(a, vdupq_n_s64(0), 0)); + int16x8_t a = vreinterpretq_s16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); +#if defined(__aarch64__) + return vreinterpretq_m128i_s16(vpaddq_s16(a, b)); +#else + return vreinterpretq_m128i_s16( + vcombine_s16(vpadd_s16(vget_low_s16(a), vget_high_s16(a)), + vpadd_s16(vget_low_s16(b), vget_high_s16(b)))); +#endif } -// Cast vector of type __m128 to type __m128d. This intrinsic is only used for -// compilation and does not generate any instructions, thus it has zero latency. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castps_pd -FORCE_INLINE __m128d _mm_castps_pd(__m128 a) +// Computes pairwise add of each argument as a 32-bit signed or unsigned integer +// values a and b. +FORCE_INLINE __m128i _mm_hadd_epi32(__m128i _a, __m128i _b) { - return vreinterpretq_m128d_s32(vreinterpretq_s32_m128(a)); + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + return vreinterpretq_m128i_s32( + vcombine_s32(vpadd_s32(vget_low_s32(a), vget_high_s32(a)), + vpadd_s32(vget_low_s32(b), vget_high_s32(b)))); } -// Applies a type cast to reinterpret four 32-bit floating point values passed -// in as a 128-bit parameter as packed 32-bit integers. -// https://msdn.microsoft.com/en-us/library/bb514099.aspx -FORCE_INLINE __m128i _mm_castps_si128(__m128 a) +// Horizontally add adjacent pairs of 16-bit integers in a and b, and pack the +// signed 16-bit results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pi16 +FORCE_INLINE __m64 _mm_hadd_pi16(__m64 a, __m64 b) { - return vreinterpretq_m128i_s32(vreinterpretq_s32_m128(a)); + return vreinterpret_m64_s16( + vpadd_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b))); } -// Cast vector of type __m128i to type __m128d. This intrinsic is only used for -// compilation and does not generate any instructions, thus it has zero latency. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castsi128_pd -FORCE_INLINE __m128d _mm_castsi128_pd(__m128i a) +// Horizontally add adjacent pairs of 32-bit integers in a and b, and pack the +// signed 32-bit results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pi32 +FORCE_INLINE __m64 _mm_hadd_pi32(__m64 a, __m64 b) +{ + return vreinterpret_m64_s32( + vpadd_s32(vreinterpret_s32_m64(a), vreinterpret_s32_m64(b))); +} + +// Computes saturated pairwise sub of each argument as a 16-bit signed +// integer values a and b. +FORCE_INLINE __m128i _mm_hadds_epi16(__m128i _a, __m128i _b) { #if defined(__aarch64__) - return vreinterpretq_m128d_f64(vreinterpretq_f64_m128i(a)); + int16x8_t a = vreinterpretq_s16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); + return vreinterpretq_s64_s16( + vqaddq_s16(vuzp1q_s16(a, b), vuzp2q_s16(a, b))); #else - return vreinterpretq_m128d_f32(vreinterpretq_f32_m128i(a)); + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + // Interleave using vshrn/vmovn + // [a0|a2|a4|a6|b0|b2|b4|b6] + // [a1|a3|a5|a7|b1|b3|b5|b7] + int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b)); + int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16)); + // Saturated add + return vreinterpretq_m128i_s16(vqaddq_s16(ab0246, ab1357)); #endif } -// Applies a type cast to reinterpret four 32-bit integers passed in as a -// 128-bit parameter as packed 32-bit floating point values. -// https://msdn.microsoft.com/en-us/library/bb514029.aspx -FORCE_INLINE __m128 _mm_castsi128_ps(__m128i a) +// Horizontally add adjacent pairs of signed 16-bit integers in a and b using +// saturation, and pack the signed 16-bit results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadds_pi16 +FORCE_INLINE __m64 _mm_hadds_pi16(__m64 _a, __m64 _b) { - return vreinterpretq_m128_s32(vreinterpretq_s32_m128i(a)); + int16x4_t a = vreinterpret_s16_m64(_a); + int16x4_t b = vreinterpret_s16_m64(_b); +#if defined(__aarch64__) + return vreinterpret_s64_s16(vqadd_s16(vuzp1_s16(a, b), vuzp2_s16(a, b))); +#else + int16x4x2_t res = vuzp_s16(a, b); + return vreinterpret_s64_s16(vqadd_s16(res.val[0], res.val[1])); +#endif } -// Loads 128-bit value. : -// https://msdn.microsoft.com/en-us/library/atzzad1h(v=vs.80).aspx -FORCE_INLINE __m128i _mm_load_si128(const __m128i *p) +// Computes pairwise difference of each argument as a 16-bit signed or unsigned +// integer values a and b. +FORCE_INLINE __m128i _mm_hsub_epi16(__m128i _a, __m128i _b) { - return vreinterpretq_m128i_s32(vld1q_s32((const int32_t *) p)); + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + // Interleave using vshrn/vmovn + // [a0|a2|a4|a6|b0|b2|b4|b6] + // [a1|a3|a5|a7|b1|b3|b5|b7] + int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b)); + int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16)); + // Subtract + return vreinterpretq_m128i_s16(vsubq_s16(ab0246, ab1357)); } -// Load a double-precision (64-bit) floating-point element from memory into both -// elements of dst. -// -// dst[63:0] := MEM[mem_addr+63:mem_addr] -// dst[127:64] := MEM[mem_addr+63:mem_addr] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load1_pd -FORCE_INLINE __m128d _mm_load1_pd(const double *p) +// Computes pairwise difference of each argument as a 32-bit signed or unsigned +// integer values a and b. +FORCE_INLINE __m128i _mm_hsub_epi32(__m128i _a, __m128i _b) +{ + int64x2_t a = vreinterpretq_s64_m128i(_a); + int64x2_t b = vreinterpretq_s64_m128i(_b); + // Interleave using vshrn/vmovn + // [a0|a2|b0|b2] + // [a1|a2|b1|b3] + int32x4_t ab02 = vcombine_s32(vmovn_s64(a), vmovn_s64(b)); + int32x4_t ab13 = vcombine_s32(vshrn_n_s64(a, 32), vshrn_n_s64(b, 32)); + // Subtract + return vreinterpretq_m128i_s32(vsubq_s32(ab02, ab13)); +} + +// Horizontally subtract adjacent pairs of 16-bit integers in a and b, and pack +// the signed 16-bit results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsub_pi16 +FORCE_INLINE __m64 _mm_hsub_pi16(__m64 _a, __m64 _b) +{ + int32x4_t ab = + vcombine_s32(vreinterpret_s32_m64(_a), vreinterpret_s32_m64(_b)); + + int16x4_t ab_low_bits = vmovn_s32(ab); + int16x4_t ab_high_bits = vshrn_n_s32(ab, 16); + + return vreinterpret_m64_s16(vsub_s16(ab_low_bits, ab_high_bits)); +} + +// Horizontally subtract adjacent pairs of 32-bit integers in a and b, and pack +// the signed 32-bit results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_hsub_pi32 +FORCE_INLINE __m64 _mm_hsub_pi32(__m64 _a, __m64 _b) { #if defined(__aarch64__) - return vreinterpretq_m128d_f64(vld1q_dup_f64(p)); + int32x2_t a = vreinterpret_s32_m64(_a); + int32x2_t b = vreinterpret_s32_m64(_b); + return vreinterpret_m64_s32(vsub_s32(vtrn1_s32(a, b), vtrn2_s32(a, b))); #else - return vreinterpretq_m128d_s64(vdupq_n_s64(*(const int64_t *) p)); + int32x2x2_t trn_ab = + vtrn_s32(vreinterpret_s32_m64(_a), vreinterpret_s32_m64(_b)); + return vreinterpret_m64_s32(vsub_s32(trn_ab.val[0], trn_ab.val[1])); #endif } -// Load a double-precision (64-bit) floating-point element from memory into both -// elements of dst. -// -// dst[63:0] := MEM[mem_addr+63:mem_addr] -// dst[127:64] := MEM[mem_addr+63:mem_addr] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_pd1 -#define _mm_load_pd1 _mm_load1_pd +// Computes saturated pairwise difference of each argument as a 16-bit signed +// integer values a and b. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsubs_epi16 +FORCE_INLINE __m128i _mm_hsubs_epi16(__m128i _a, __m128i _b) +{ +#if defined(__aarch64__) + int16x8_t a = vreinterpretq_s16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); + return vreinterpretq_s64_s16( + vqsubq_s16(vuzp1q_s16(a, b), vuzp2q_s16(a, b))); +#else + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + // Interleave using vshrn/vmovn + // [a0|a2|a4|a6|b0|b2|b4|b6] + // [a1|a3|a5|a7|b1|b3|b5|b7] + int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b)); + int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16)); + // Saturated subtract + return vreinterpretq_m128i_s16(vqsubq_s16(ab0246, ab1357)); +#endif +} -// Load a double-precision (64-bit) floating-point element from memory into the -// upper element of dst, and copy the lower element from a to dst. mem_addr does -// not need to be aligned on any particular boundary. -// -// dst[63:0] := a[63:0] -// dst[127:64] := MEM[mem_addr+63:mem_addr] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadh_pd -FORCE_INLINE __m128d _mm_loadh_pd(__m128d a, const double *p) +// Horizontally subtract adjacent pairs of signed 16-bit integers in a and b +// using saturation, and pack the signed 16-bit results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsubs_pi16 +FORCE_INLINE __m64 _mm_hsubs_pi16(__m64 _a, __m64 _b) { + int16x4_t a = vreinterpret_s16_m64(_a); + int16x4_t b = vreinterpret_s16_m64(_b); #if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vcombine_f64(vget_low_f64(vreinterpretq_f64_m128d(a)), vld1_f64(p))); + return vreinterpret_s64_s16(vqsub_s16(vuzp1_s16(a, b), vuzp2_s16(a, b))); #else - return vreinterpretq_m128d_f32(vcombine_f32( - vget_low_f32(vreinterpretq_f32_m128d(a)), vld1_f32((const float *) p))); + int16x4x2_t res = vuzp_s16(a, b); + return vreinterpret_s64_s16(vqsub_s16(res.val[0], res.val[1])); #endif } -// Load a double-precision (64-bit) floating-point element from memory into both -// elements of dst. -// -// dst[63:0] := MEM[mem_addr+63:mem_addr] -// dst[127:64] := MEM[mem_addr+63:mem_addr] +// Vertically multiply each unsigned 8-bit integer from a with the corresponding +// signed 8-bit integer from b, producing intermediate signed 16-bit integers. +// Horizontally add adjacent pairs of intermediate signed 16-bit integers, +// and pack the saturated results in dst. // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_pd1 -#define _mm_load_pd1 _mm_load1_pd +// FOR j := 0 to 7 +// i := j*16 +// dst[i+15:i] := Saturate_To_Int16( a[i+15:i+8]*b[i+15:i+8] + +// a[i+7:i]*b[i+7:i] ) +// ENDFOR +FORCE_INLINE __m128i _mm_maddubs_epi16(__m128i _a, __m128i _b) +{ +#if defined(__aarch64__) + uint8x16_t a = vreinterpretq_u8_m128i(_a); + int8x16_t b = vreinterpretq_s8_m128i(_b); + int16x8_t tl = vmulq_s16(vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(a))), + vmovl_s8(vget_low_s8(b))); + int16x8_t th = vmulq_s16(vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(a))), + vmovl_s8(vget_high_s8(b))); + return vreinterpretq_m128i_s16( + vqaddq_s16(vuzp1q_s16(tl, th), vuzp2q_s16(tl, th))); +#else + // This would be much simpler if x86 would choose to zero extend OR sign + // extend, not both. This could probably be optimized better. + uint16x8_t a = vreinterpretq_u16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); -// Load a double-precision (64-bit) floating-point element from memory into both -// elements of dst. -// -// dst[63:0] := MEM[mem_addr+63:mem_addr] -// dst[127:64] := MEM[mem_addr+63:mem_addr] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loaddup_pd -#define _mm_loaddup_pd _mm_load1_pd + // Zero extend a + int16x8_t a_odd = vreinterpretq_s16_u16(vshrq_n_u16(a, 8)); + int16x8_t a_even = vreinterpretq_s16_u16(vbicq_u16(a, vdupq_n_u16(0xff00))); -// Loads 128-bit value. : -// https://msdn.microsoft.com/zh-cn/library/f4k12ae8(v=vs.90).aspx -FORCE_INLINE __m128i _mm_loadu_si128(const __m128i *p) + // Sign extend by shifting left then shifting right. + int16x8_t b_even = vshrq_n_s16(vshlq_n_s16(b, 8), 8); + int16x8_t b_odd = vshrq_n_s16(b, 8); + + // multiply + int16x8_t prod1 = vmulq_s16(a_even, b_even); + int16x8_t prod2 = vmulq_s16(a_odd, b_odd); + + // saturated add + return vreinterpretq_m128i_s16(vqaddq_s16(prod1, prod2)); +#endif +} + +// Vertically multiply each unsigned 8-bit integer from a with the corresponding +// signed 8-bit integer from b, producing intermediate signed 16-bit integers. +// Horizontally add adjacent pairs of intermediate signed 16-bit integers, and +// pack the saturated results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_maddubs_pi16 +FORCE_INLINE __m64 _mm_maddubs_pi16(__m64 _a, __m64 _b) { - return vreinterpretq_m128i_s32(vld1q_s32((const int32_t *) p)); + uint16x4_t a = vreinterpret_u16_m64(_a); + int16x4_t b = vreinterpret_s16_m64(_b); + + // Zero extend a + int16x4_t a_odd = vreinterpret_s16_u16(vshr_n_u16(a, 8)); + int16x4_t a_even = vreinterpret_s16_u16(vand_u16(a, vdup_n_u16(0xff))); + + // Sign extend by shifting left then shifting right. + int16x4_t b_even = vshr_n_s16(vshl_n_s16(b, 8), 8); + int16x4_t b_odd = vshr_n_s16(b, 8); + + // multiply + int16x4_t prod1 = vmul_s16(a_even, b_even); + int16x4_t prod2 = vmul_s16(a_odd, b_odd); + + // saturated add + return vreinterpret_m64_s16(vqadd_s16(prod1, prod2)); } -// Load unaligned 32-bit integer from memory into the first element of dst. -// -// dst[31:0] := MEM[mem_addr+31:mem_addr] -// dst[MAX:32] := 0 +// Multiply packed signed 16-bit integers in a and b, producing intermediate +// signed 32-bit integers. Shift right by 15 bits while rounding up, and store +// the packed 16-bit integers in dst. // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si32 -FORCE_INLINE __m128i _mm_loadu_si32(const void *p) +// r0 := Round(((int32_t)a0 * (int32_t)b0) >> 15) +// r1 := Round(((int32_t)a1 * (int32_t)b1) >> 15) +// r2 := Round(((int32_t)a2 * (int32_t)b2) >> 15) +// ... +// r7 := Round(((int32_t)a7 * (int32_t)b7) >> 15) +FORCE_INLINE __m128i _mm_mulhrs_epi16(__m128i a, __m128i b) { - return vreinterpretq_m128i_s32( - vsetq_lane_s32(*(const int32_t *) p, vdupq_n_s32(0), 0)); + // Has issues due to saturation + // return vreinterpretq_m128i_s16(vqrdmulhq_s16(a, b)); + + // Multiply + int32x4_t mul_lo = vmull_s16(vget_low_s16(vreinterpretq_s16_m128i(a)), + vget_low_s16(vreinterpretq_s16_m128i(b))); + int32x4_t mul_hi = vmull_s16(vget_high_s16(vreinterpretq_s16_m128i(a)), + vget_high_s16(vreinterpretq_s16_m128i(b))); + + // Rounding narrowing shift right + // narrow = (int16_t)((mul + 16384) >> 15); + int16x4_t narrow_lo = vrshrn_n_s32(mul_lo, 15); + int16x4_t narrow_hi = vrshrn_n_s32(mul_hi, 15); + + // Join together + return vreinterpretq_m128i_s16(vcombine_s16(narrow_lo, narrow_hi)); } -// Convert packed double-precision (64-bit) floating-point elements in a to -// packed single-precision (32-bit) floating-point elements, and store the -// results in dst. +// Multiply packed signed 16-bit integers in a and b, producing intermediate +// signed 32-bit integers. Truncate each intermediate integer to the 18 most +// significant bits, round by adding 1, and store bits [16:1] to dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mulhrs_pi16 +FORCE_INLINE __m64 _mm_mulhrs_pi16(__m64 a, __m64 b) +{ + int32x4_t mul_extend = + vmull_s16((vreinterpret_s16_m64(a)), (vreinterpret_s16_m64(b))); + + // Rounding narrowing shift right + return vreinterpret_m64_s16(vrshrn_n_s32(mul_extend, 15)); +} + +// Shuffle packed 8-bit integers in a according to shuffle control mask in the +// corresponding 8-bit element of b, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_epi8 +FORCE_INLINE __m128i _mm_shuffle_epi8(__m128i a, __m128i b) +{ + int8x16_t tbl = vreinterpretq_s8_m128i(a); // input a + uint8x16_t idx = vreinterpretq_u8_m128i(b); // input b + uint8x16_t idx_masked = + vandq_u8(idx, vdupq_n_u8(0x8F)); // avoid using meaningless bits +#if defined(__aarch64__) + return vreinterpretq_m128i_s8(vqtbl1q_s8(tbl, idx_masked)); +#elif defined(__GNUC__) + int8x16_t ret; + // %e and %f represent the even and odd D registers + // respectively. + __asm__ __volatile__( + "vtbl.8 %e[ret], {%e[tbl], %f[tbl]}, %e[idx]\n" + "vtbl.8 %f[ret], {%e[tbl], %f[tbl]}, %f[idx]\n" + : [ret] "=&w"(ret) + : [tbl] "w"(tbl), [idx] "w"(idx_masked)); + return vreinterpretq_m128i_s8(ret); +#else + // use this line if testing on aarch64 + int8x8x2_t a_split = {vget_low_s8(tbl), vget_high_s8(tbl)}; + return vreinterpretq_m128i_s8( + vcombine_s8(vtbl2_s8(a_split, vget_low_u8(idx_masked)), + vtbl2_s8(a_split, vget_high_u8(idx_masked)))); +#endif +} + +// Shuffle packed 8-bit integers in a according to shuffle control mask in the +// corresponding 8-bit element of b, and store the results in dst. // -// FOR j := 0 to 1 -// i := 32*j -// k := 64*j -// dst[i+31:i] := Convert_FP64_To_FP32(a[k+64:k]) +// FOR j := 0 to 7 +// i := j*8 +// IF b[i+7] == 1 +// dst[i+7:i] := 0 +// ELSE +// index[2:0] := b[i+2:i] +// dst[i+7:i] := a[index*8+7:index*8] +// FI // ENDFOR -// dst[127:64] := 0 // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpd_ps -FORCE_INLINE __m128 _mm_cvtpd_ps(__m128d a) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_pi8 +FORCE_INLINE __m64 _mm_shuffle_pi8(__m64 a, __m64 b) +{ + const int8x8_t controlMask = + vand_s8(vreinterpret_s8_m64(b), vdup_n_s8((int8_t)(0x1 << 7 | 0x07))); + int8x8_t res = vtbl1_s8(vreinterpret_s8_m64(a), controlMask); + return vreinterpret_m64_s8(res); +} + +// Negate packed 16-bit integers in a when the corresponding signed +// 16-bit integer in b is negative, and store the results in dst. +// Element in dst are zeroed out when the corresponding element +// in b is zero. +// +// for i in 0..7 +// if b[i] < 0 +// r[i] := -a[i] +// else if b[i] == 0 +// r[i] := 0 +// else +// r[i] := a[i] +// fi +// done +FORCE_INLINE __m128i _mm_sign_epi16(__m128i _a, __m128i _b) { + int16x8_t a = vreinterpretq_s16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); + + // signed shift right: faster than vclt + // (b < 0) ? 0xFFFF : 0 + uint16x8_t ltMask = vreinterpretq_u16_s16(vshrq_n_s16(b, 15)); + // (b == 0) ? 0xFFFF : 0 #if defined(__aarch64__) - float32x2_t tmp = vcvt_f32_f64(vreinterpretq_f64_m128d(a)); - return vreinterpretq_m128_f32(vcombine_f32(tmp, vdup_n_f32(0))); + int16x8_t zeroMask = vreinterpretq_s16_u16(vceqzq_s16(b)); #else - float a0 = (float) ((double *) &a)[0]; - float a1 = (float) ((double *) &a)[1]; - return _mm_set_ps(0, 0, a1, a0); + int16x8_t zeroMask = vreinterpretq_s16_u16(vceqq_s16(b, vdupq_n_s16(0))); #endif + + // bitwise select either a or negative 'a' (vnegq_s16(a) equals to negative + // 'a') based on ltMask + int16x8_t masked = vbslq_s16(ltMask, vnegq_s16(a), a); + // res = masked & (~zeroMask) + int16x8_t res = vbicq_s16(masked, zeroMask); + return vreinterpretq_m128i_s16(res); } -// Copy the lower double-precision (64-bit) floating-point element of a to dst. +// Negate packed 32-bit integers in a when the corresponding signed +// 32-bit integer in b is negative, and store the results in dst. +// Element in dst are zeroed out when the corresponding element +// in b is zero. // -// dst[63:0] := a[63:0] +// for i in 0..3 +// if b[i] < 0 +// r[i] := -a[i] +// else if b[i] == 0 +// r[i] := 0 +// else +// r[i] := a[i] +// fi +// done +FORCE_INLINE __m128i _mm_sign_epi32(__m128i _a, __m128i _b) +{ + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + + // signed shift right: faster than vclt + // (b < 0) ? 0xFFFFFFFF : 0 + uint32x4_t ltMask = vreinterpretq_u32_s32(vshrq_n_s32(b, 31)); + + // (b == 0) ? 0xFFFFFFFF : 0 +#if defined(__aarch64__) + int32x4_t zeroMask = vreinterpretq_s32_u32(vceqzq_s32(b)); +#else + int32x4_t zeroMask = vreinterpretq_s32_u32(vceqq_s32(b, vdupq_n_s32(0))); +#endif + + // bitwise select either a or negative 'a' (vnegq_s32(a) equals to negative + // 'a') based on ltMask + int32x4_t masked = vbslq_s32(ltMask, vnegq_s32(a), a); + // res = masked & (~zeroMask) + int32x4_t res = vbicq_s32(masked, zeroMask); + return vreinterpretq_m128i_s32(res); +} + +// Negate packed 8-bit integers in a when the corresponding signed +// 8-bit integer in b is negative, and store the results in dst. +// Element in dst are zeroed out when the corresponding element +// in b is zero. // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsd_f64 -FORCE_INLINE double _mm_cvtsd_f64(__m128d a) +// for i in 0..15 +// if b[i] < 0 +// r[i] := -a[i] +// else if b[i] == 0 +// r[i] := 0 +// else +// r[i] := a[i] +// fi +// done +FORCE_INLINE __m128i _mm_sign_epi8(__m128i _a, __m128i _b) { + int8x16_t a = vreinterpretq_s8_m128i(_a); + int8x16_t b = vreinterpretq_s8_m128i(_b); + + // signed shift right: faster than vclt + // (b < 0) ? 0xFF : 0 + uint8x16_t ltMask = vreinterpretq_u8_s8(vshrq_n_s8(b, 7)); + + // (b == 0) ? 0xFF : 0 #if defined(__aarch64__) - return (double) vgetq_lane_f64(vreinterpretq_f64_m128d(a), 0); + int8x16_t zeroMask = vreinterpretq_s8_u8(vceqzq_s8(b)); #else - return ((double *) &a)[0]; + int8x16_t zeroMask = vreinterpretq_s8_u8(vceqq_s8(b, vdupq_n_s8(0))); #endif + + // bitwise select either a or nagative 'a' (vnegq_s8(a) return nagative 'a') + // based on ltMask + int8x16_t masked = vbslq_s8(ltMask, vnegq_s8(a), a); + // res = masked & (~zeroMask) + int8x16_t res = vbicq_s8(masked, zeroMask); + + return vreinterpretq_m128i_s8(res); } -// Convert packed single-precision (32-bit) floating-point elements in a to -// packed double-precision (64-bit) floating-point elements, and store the -// results in dst. +// Negate packed 16-bit integers in a when the corresponding signed 16-bit +// integer in b is negative, and store the results in dst. Element in dst are +// zeroed out when the corresponding element in b is zero. // -// FOR j := 0 to 1 -// i := 64*j -// k := 32*j -// dst[i+63:i] := Convert_FP32_To_FP64(a[k+31:k]) +// FOR j := 0 to 3 +// i := j*16 +// IF b[i+15:i] < 0 +// dst[i+15:i] := -(a[i+15:i]) +// ELSE IF b[i+15:i] == 0 +// dst[i+15:i] := 0 +// ELSE +// dst[i+15:i] := a[i+15:i] +// FI // ENDFOR // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pd -FORCE_INLINE __m128d _mm_cvtps_pd(__m128 a) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sign_pi16 +FORCE_INLINE __m64 _mm_sign_pi16(__m64 _a, __m64 _b) { + int16x4_t a = vreinterpret_s16_m64(_a); + int16x4_t b = vreinterpret_s16_m64(_b); + + // signed shift right: faster than vclt + // (b < 0) ? 0xFFFF : 0 + uint16x4_t ltMask = vreinterpret_u16_s16(vshr_n_s16(b, 15)); + + // (b == 0) ? 0xFFFF : 0 #if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vcvt_f64_f32(vget_low_f32(vreinterpretq_f32_m128(a)))); + int16x4_t zeroMask = vreinterpret_s16_u16(vceqz_s16(b)); #else - double a0 = (double) vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); - double a1 = (double) vgetq_lane_f32(vreinterpretq_f32_m128(a), 1); - return _mm_set_pd(a1, a0); + int16x4_t zeroMask = vreinterpret_s16_u16(vceq_s16(b, vdup_n_s16(0))); #endif -} -// Cast vector of type __m128d to type __m128i. This intrinsic is only used for -// compilation and does not generate any instructions, thus it has zero latency. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castpd_si128 -FORCE_INLINE __m128i _mm_castpd_si128(__m128d a) -{ - return vreinterpretq_m128i_s64(vreinterpretq_s64_m128d(a)); + // bitwise select either a or nagative 'a' (vneg_s16(a) return nagative 'a') + // based on ltMask + int16x4_t masked = vbsl_s16(ltMask, vneg_s16(a), a); + // res = masked & (~zeroMask) + int16x4_t res = vbic_s16(masked, zeroMask); + + return vreinterpret_m64_s16(res); } -// Cast vector of type __m128d to type __m128. This intrinsic is only used for -// compilation and does not generate any instructions, thus it has zero latency. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castpd_ps -FORCE_INLINE __m128 _mm_castpd_ps(__m128d a) +// Negate packed 32-bit integers in a when the corresponding signed 32-bit +// integer in b is negative, and store the results in dst. Element in dst are +// zeroed out when the corresponding element in b is zero. +// +// FOR j := 0 to 1 +// i := j*32 +// IF b[i+31:i] < 0 +// dst[i+31:i] := -(a[i+31:i]) +// ELSE IF b[i+31:i] == 0 +// dst[i+31:i] := 0 +// ELSE +// dst[i+31:i] := a[i+31:i] +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sign_pi32 +FORCE_INLINE __m64 _mm_sign_pi32(__m64 _a, __m64 _b) { - return vreinterpretq_m128_s64(vreinterpretq_s64_m128d(a)); + int32x2_t a = vreinterpret_s32_m64(_a); + int32x2_t b = vreinterpret_s32_m64(_b); + + // signed shift right: faster than vclt + // (b < 0) ? 0xFFFFFFFF : 0 + uint32x2_t ltMask = vreinterpret_u32_s32(vshr_n_s32(b, 31)); + + // (b == 0) ? 0xFFFFFFFF : 0 +#if defined(__aarch64__) + int32x2_t zeroMask = vreinterpret_s32_u32(vceqz_s32(b)); +#else + int32x2_t zeroMask = vreinterpret_s32_u32(vceq_s32(b, vdup_n_s32(0))); +#endif + + // bitwise select either a or nagative 'a' (vneg_s32(a) return nagative 'a') + // based on ltMask + int32x2_t masked = vbsl_s32(ltMask, vneg_s32(a), a); + // res = masked & (~zeroMask) + int32x2_t res = vbic_s32(masked, zeroMask); + + return vreinterpret_m64_s32(res); } -// Blend packed single-precision (32-bit) floating-point elements from a and b -// using mask, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blendv_ps -FORCE_INLINE __m128 _mm_blendv_ps(__m128 _a, __m128 _b, __m128 _mask) +// Negate packed 8-bit integers in a when the corresponding signed 8-bit integer +// in b is negative, and store the results in dst. Element in dst are zeroed out +// when the corresponding element in b is zero. +// +// FOR j := 0 to 7 +// i := j*8 +// IF b[i+7:i] < 0 +// dst[i+7:i] := -(a[i+7:i]) +// ELSE IF b[i+7:i] == 0 +// dst[i+7:i] := 0 +// ELSE +// dst[i+7:i] := a[i+7:i] +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sign_pi8 +FORCE_INLINE __m64 _mm_sign_pi8(__m64 _a, __m64 _b) { - // Use a signed shift right to create a mask with the sign bit - uint32x4_t mask = - vreinterpretq_u32_s32(vshrq_n_s32(vreinterpretq_s32_m128(_mask), 31)); - float32x4_t a = vreinterpretq_f32_m128(_a); - float32x4_t b = vreinterpretq_f32_m128(_b); - return vreinterpretq_m128_f32(vbslq_f32(mask, b, a)); + int8x8_t a = vreinterpret_s8_m64(_a); + int8x8_t b = vreinterpret_s8_m64(_b); + + // signed shift right: faster than vclt + // (b < 0) ? 0xFF : 0 + uint8x8_t ltMask = vreinterpret_u8_s8(vshr_n_s8(b, 7)); + + // (b == 0) ? 0xFF : 0 +#if defined(__aarch64__) + int8x8_t zeroMask = vreinterpret_s8_u8(vceqz_s8(b)); +#else + int8x8_t zeroMask = vreinterpret_s8_u8(vceq_s8(b, vdup_n_s8(0))); +#endif + + // bitwise select either a or nagative 'a' (vneg_s8(a) return nagative 'a') + // based on ltMask + int8x8_t masked = vbsl_s8(ltMask, vneg_s8(a), a); + // res = masked & (~zeroMask) + int8x8_t res = vbic_s8(masked, zeroMask); + + return vreinterpret_m64_s8(res); } +/* SSE4.1 */ + +// Blend packed 16-bit integers from a and b using control mask imm8, and store +// the results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// IF imm8[j] +// dst[i+15:i] := b[i+15:i] +// ELSE +// dst[i+15:i] := a[i+15:i] +// FI +// ENDFOR +// FORCE_INLINE __m128i _mm_blend_epi16(__m128i a, __m128i b, +// __constrange(0,255) int imm) +#define _mm_blend_epi16(a, b, imm) \ + __extension__({ \ + const uint16_t ones = 0xffff; \ + const uint16_t zeros = 0x0000; \ + const uint16_t _mask[8] = {((imm) & (1 << 0)) ? ones : zeros, \ + ((imm) & (1 << 1)) ? ones : zeros, \ + ((imm) & (1 << 2)) ? ones : zeros, \ + ((imm) & (1 << 3)) ? ones : zeros, \ + ((imm) & (1 << 4)) ? ones : zeros, \ + ((imm) & (1 << 5)) ? ones : zeros, \ + ((imm) & (1 << 6)) ? ones : zeros, \ + ((imm) & (1 << 7)) ? ones : zeros}; \ + uint16x8_t _mask_vec = vld1q_u16(_mask); \ + uint16x8_t _a = vreinterpretq_u16_m128i(a); \ + uint16x8_t _b = vreinterpretq_u16_m128i(b); \ + vreinterpretq_m128i_u16(vbslq_u16(_mask_vec, _b, _a)); \ + }) + +// Blend packed double-precision (64-bit) floating-point elements from a and b +// using control mask imm8, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blend_pd +#define _mm_blend_pd(a, b, imm) \ + __extension__({ \ + const uint64_t _mask[2] = { \ + ((imm) & (1 << 0)) ? ~UINT64_C(0) : UINT64_C(0), \ + ((imm) & (1 << 1)) ? ~UINT64_C(0) : UINT64_C(0)}; \ + uint64x2_t _mask_vec = vld1q_u64(_mask); \ + uint64x2_t _a = vreinterpretq_u64_m128d(a); \ + uint64x2_t _b = vreinterpretq_u64_m128d(b); \ + vreinterpretq_m128d_u64(vbslq_u64(_mask_vec, _b, _a)); \ + }) + // Blend packed single-precision (32-bit) floating-point elements from a and b // using mask, and store the results in dst. // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blend_ps @@ -5672,6 +7337,27 @@ FORCE_INLINE __m128 _mm_blend_ps(__m128 _a, __m128 _b, const char imm8) return vreinterpretq_m128_f32(vbslq_f32(mask, b, a)); } +// Blend packed 8-bit integers from a and b using mask, and store the results in +// dst. +// +// FOR j := 0 to 15 +// i := j*8 +// IF mask[i+7] +// dst[i+7:i] := b[i+7:i] +// ELSE +// dst[i+7:i] := a[i+7:i] +// FI +// ENDFOR +FORCE_INLINE __m128i _mm_blendv_epi8(__m128i _a, __m128i _b, __m128i _mask) +{ + // Use a signed shift right to create a mask with the sign bit + uint8x16_t mask = + vreinterpretq_u8_s8(vshrq_n_s8(vreinterpretq_s8_m128i(_mask), 7)); + uint8x16_t a = vreinterpretq_u8_m128i(_a); + uint8x16_t b = vreinterpretq_u8_m128i(_b); + return vreinterpretq_m128i_u8(vbslq_u8(mask, b, a)); +} + // Blend packed double-precision (64-bit) floating-point elements from a and b // using mask, and store the results in dst. // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blendv_pd @@ -5690,154 +7376,55 @@ FORCE_INLINE __m128d _mm_blendv_pd(__m128d _a, __m128d _b, __m128d _mask) #endif } -typedef struct { - uint16_t res0; - uint8_t res1 : 6; - uint8_t bit22 : 1; - uint8_t bit23 : 1; - uint8_t res2; -#if defined(__aarch64__) - uint32_t res3; -#endif -} fpcr_bitfield; - -// Macro: Set the rounding mode bits of the MXCSR control and status register to -// the value in unsigned 32-bit integer a. The rounding mode may contain any of -// the following flags: _MM_ROUND_NEAREST, _MM_ROUND_DOWN, _MM_ROUND_UP, -// _MM_ROUND_TOWARD_ZERO -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_MM_SET_ROUNDING_MODE -FORCE_INLINE void _MM_SET_ROUNDING_MODE(int rounding) -{ - union { - fpcr_bitfield field; -#if defined(__aarch64__) - uint64_t value; -#else - uint32_t value; -#endif - } r; - -#if defined(__aarch64__) - asm volatile("mrs %0, FPCR" : "=r"(r.value)); /* read */ -#else - asm volatile("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ -#endif - - switch (rounding) { - case _MM_ROUND_TOWARD_ZERO: - r.field.bit22 = 1; - r.field.bit23 = 1; - break; - case _MM_ROUND_DOWN: - r.field.bit22 = 0; - r.field.bit23 = 1; - break; - case _MM_ROUND_UP: - r.field.bit22 = 1; - r.field.bit23 = 0; - break; - default: //_MM_ROUND_NEAREST - r.field.bit22 = 0; - r.field.bit23 = 0; - } - -#if defined(__aarch64__) - asm volatile("msr FPCR, %0" ::"r"(r)); /* write */ -#else - asm volatile("vmsr FPSCR, %0" ::"r"(r)); /* write */ -#endif -} - -FORCE_INLINE void _mm_setcsr(unsigned int a) +// Blend packed single-precision (32-bit) floating-point elements from a and b +// using mask, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blendv_ps +FORCE_INLINE __m128 _mm_blendv_ps(__m128 _a, __m128 _b, __m128 _mask) { - _MM_SET_ROUNDING_MODE(a); + // Use a signed shift right to create a mask with the sign bit + uint32x4_t mask = + vreinterpretq_u32_s32(vshrq_n_s32(vreinterpretq_s32_m128(_mask), 31)); + float32x4_t a = vreinterpretq_f32_m128(_a); + float32x4_t b = vreinterpretq_f32_m128(_b); + return vreinterpretq_m128_f32(vbslq_f32(mask, b, a)); } -// Round the packed single-precision (32-bit) floating-point elements in a using -// the rounding parameter, and store the results as packed single-precision +// Round the packed double-precision (64-bit) floating-point elements in a up +// to an integer value, and store the results as packed double-precision // floating-point elements in dst. -// software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_round_ps -FORCE_INLINE __m128 _mm_round_ps(__m128 a, int rounding) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ceil_pd +FORCE_INLINE __m128d _mm_ceil_pd(__m128d a) { #if defined(__aarch64__) - switch (rounding) { - case (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC): - return vreinterpretq_m128_f32(vrndnq_f32(vreinterpretq_f32_m128(a))); - case (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC): - return vreinterpretq_m128_f32(vrndmq_f32(vreinterpretq_f32_m128(a))); - case (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC): - return vreinterpretq_m128_f32(vrndpq_f32(vreinterpretq_f32_m128(a))); - case (_MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC): - return vreinterpretq_m128_f32(vrndq_f32(vreinterpretq_f32_m128(a))); - default: //_MM_FROUND_CUR_DIRECTION - return vreinterpretq_m128_f32(vrndiq_f32(vreinterpretq_f32_m128(a))); - } + return vreinterpretq_m128d_f64(vrndpq_f64(vreinterpretq_f64_m128d(a))); #else - float *v_float = (float *) &a; - __m128 zero, neg_inf, pos_inf; - - switch (rounding) { - case (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC): - return _mm_cvtepi32_ps(_mm_cvtps_epi32(a)); - case (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC): - return (__m128){floorf(v_float[0]), floorf(v_float[1]), - floorf(v_float[2]), floorf(v_float[3])}; - case (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC): - return (__m128){ceilf(v_float[0]), ceilf(v_float[1]), ceilf(v_float[2]), - ceilf(v_float[3])}; - case (_MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC): - zero = _mm_set_ps(0.0f, 0.0f, 0.0f, 0.0f); - neg_inf = _mm_set_ps(floorf(v_float[0]), floorf(v_float[1]), - floorf(v_float[2]), floorf(v_float[3])); - pos_inf = _mm_set_ps(ceilf(v_float[0]), ceilf(v_float[1]), - ceilf(v_float[2]), ceilf(v_float[3])); - return _mm_blendv_ps(pos_inf, neg_inf, _mm_cmple_ps(a, zero)); - default: //_MM_FROUND_CUR_DIRECTION - return (__m128){roundf(v_float[0]), roundf(v_float[1]), - roundf(v_float[2]), roundf(v_float[3])}; - } + double *f = (double *) &a; + return _mm_set_pd(ceil(f[1]), ceil(f[0])); #endif } -// Convert packed single-precision (32-bit) floating-point elements in a to -// packed 32-bit integers, and store the results in dst. -// -// FOR j := 0 to 1 -// i := 32*j -// dst[i+31:i] := Convert_FP32_To_Int32(a[i+31:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_ps2pi -FORCE_INLINE __m64 _mm_cvt_ps2pi(__m128 a) +// Round the packed single-precision (32-bit) floating-point elements in a up to +// an integer value, and store the results as packed single-precision +// floating-point elements in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ceil_ps +FORCE_INLINE __m128 _mm_ceil_ps(__m128 a) { #if defined(__aarch64__) - return vreinterpret_m64_s32( - vget_low_s32(vcvtnq_s32_f32(vreinterpretq_f32_m128(a)))); + return vreinterpretq_m128_f32(vrndpq_f32(vreinterpretq_f32_m128(a))); #else - return vreinterpret_m64_s32( - vcvt_s32_f32(vget_low_f32(vreinterpretq_f32_m128( - _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC))))); + float *f = (float *) &a; + return _mm_set_ps(ceilf(f[3]), ceilf(f[2]), ceilf(f[1]), ceilf(f[0])); #endif } -// Convert packed single-precision (32-bit) floating-point elements in a to -// packed 32-bit integers, and store the results in dst. -// -// FOR j := 0 to 1 -// i := 32*j -// dst[i+31:i] := Convert_FP32_To_Int32(a[i+31:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pi32 -#define _mm_cvtps_pi32(a) _mm_cvt_ps2pi(a) - -// Round the packed single-precision (32-bit) floating-point elements in a up to -// an integer value, and store the results as packed single-precision -// floating-point elements in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ceil_ps -FORCE_INLINE __m128 _mm_ceil_ps(__m128 a) +// Round the lower double-precision (64-bit) floating-point element in b up to +// an integer value, store the result as a double-precision floating-point +// element in the lower element of dst, and copy the upper element from a to the +// upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ceil_sd +FORCE_INLINE __m128d _mm_ceil_sd(__m128d a, __m128d b) { - return _mm_round_ps(a, _MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); + return _mm_move_sd(a, _mm_ceil_pd(b)); } // Round the lower single-precision (32-bit) floating-point element in b up to @@ -5851,396 +7438,442 @@ FORCE_INLINE __m128 _mm_ceil_ps(__m128 a) // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ceil_ss FORCE_INLINE __m128 _mm_ceil_ss(__m128 a, __m128 b) { - return _mm_move_ss( - a, _mm_round_ps(b, _MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC)); + return _mm_move_ss(a, _mm_ceil_ps(b)); } -// Round the packed single-precision (32-bit) floating-point elements in a down -// to an integer value, and store the results as packed single-precision -// floating-point elements in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_floor_ps -FORCE_INLINE __m128 _mm_floor_ps(__m128 a) +// Compare packed 64-bit integers in a and b for equality, and store the results +// in dst +FORCE_INLINE __m128i _mm_cmpeq_epi64(__m128i a, __m128i b) { - return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); +#if defined(__aarch64__) + return vreinterpretq_m128i_u64( + vceqq_u64(vreinterpretq_u64_m128i(a), vreinterpretq_u64_m128i(b))); +#else + // ARMv7 lacks vceqq_u64 + // (a == b) -> (a_lo == b_lo) && (a_hi == b_hi) + uint32x4_t cmp = + vceqq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b)); + uint32x4_t swapped = vrev64q_u32(cmp); + return vreinterpretq_m128i_u32(vandq_u32(cmp, swapped)); +#endif } -// Round the lower single-precision (32-bit) floating-point element in b down to -// an integer value, store the result as a single-precision floating-point -// element in the lower element of dst, and copy the upper 3 packed elements -// from a to the upper elements of dst. -// -// dst[31:0] := FLOOR(b[31:0]) -// dst[127:32] := a[127:32] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_floor_ss -FORCE_INLINE __m128 _mm_floor_ss(__m128 a, __m128 b) +// Converts the four signed 16-bit integers in the lower 64 bits to four signed +// 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi16_epi32(__m128i a) { - return _mm_move_ss( - a, _mm_round_ps(b, _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC)); + return vreinterpretq_m128i_s32( + vmovl_s16(vget_low_s16(vreinterpretq_s16_m128i(a)))); } -// Load 128-bits of integer data from unaligned memory into dst. This intrinsic -// may perform better than _mm_loadu_si128 when the data crosses a cache line -// boundary. -// -// dst[127:0] := MEM[mem_addr+127:mem_addr] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_lddqu_si128 -#define _mm_lddqu_si128 _mm_loadu_si128 +// Converts the two signed 16-bit integers in the lower 32 bits two signed +// 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi16_epi64(__m128i a) +{ + int16x8_t s16x8 = vreinterpretq_s16_m128i(a); /* xxxx xxxx xxxx 0B0A */ + int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000x 000x 000B 000A */ + int64x2_t s64x2 = vmovl_s32(vget_low_s32(s32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_s64(s64x2); +} -/* Miscellaneous Operations */ +// Converts the two signed 32-bit integers in the lower 64 bits to two signed +// 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepi32_epi64(__m128i a) +{ + return vreinterpretq_m128i_s64( + vmovl_s32(vget_low_s32(vreinterpretq_s32_m128i(a)))); +} -// Shifts the 8 signed 16-bit integers in a right by count bits while shifting -// in the sign bit. -// -// r0 := a0 >> count -// r1 := a1 >> count -// ... -// r7 := a7 >> count -// -// https://msdn.microsoft.com/en-us/library/3c9997dk(v%3dvs.90).aspx -FORCE_INLINE __m128i _mm_sra_epi16(__m128i a, __m128i count) +// Converts the four unsigned 8-bit integers in the lower 16 bits to four +// unsigned 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi8_epi16(__m128i a) { - int64_t c = (int64_t) vget_low_s64((int64x2_t) count); - if (unlikely(c > 15)) - return _mm_cmplt_epi16(a, _mm_setzero_si128()); - return vreinterpretq_m128i_s16(vshlq_s16((int16x8_t) a, vdupq_n_s16(-c))); + int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx DCBA */ + int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0D0C 0B0A */ + return vreinterpretq_m128i_s16(s16x8); } -// Shifts the 4 signed 32-bit integers in a right by count bits while shifting -// in the sign bit. -// -// r0 := a0 >> count -// r1 := a1 >> count -// r2 := a2 >> count -// r3 := a3 >> count -// -// https://msdn.microsoft.com/en-us/library/ce40009e(v%3dvs.100).aspx -FORCE_INLINE __m128i _mm_sra_epi32(__m128i a, __m128i count) +// Converts the four unsigned 8-bit integers in the lower 32 bits to four +// unsigned 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi8_epi32(__m128i a) { - int64_t c = (int64_t) vget_low_s64((int64x2_t) count); - if (unlikely(c > 31)) - return _mm_cmplt_epi32(a, _mm_setzero_si128()); - return vreinterpretq_m128i_s32(vshlq_s32((int32x4_t) a, vdupq_n_s32(-c))); + int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx DCBA */ + int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0D0C 0B0A */ + int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000D 000C 000B 000A */ + return vreinterpretq_m128i_s32(s32x4); } -// Packs the 16 signed 16-bit integers from a and b into 8-bit integers and -// saturates. -// https://msdn.microsoft.com/en-us/library/k4y4f7w5%28v=vs.90%29.aspx -FORCE_INLINE __m128i _mm_packs_epi16(__m128i a, __m128i b) +// Converts the two signed 8-bit integers in the lower 32 bits to four +// signed 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepi8_epi64(__m128i a) { - return vreinterpretq_m128i_s8( - vcombine_s8(vqmovn_s16(vreinterpretq_s16_m128i(a)), - vqmovn_s16(vreinterpretq_s16_m128i(b)))); + int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx xxBA */ + int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0x0x 0B0A */ + int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000x 000x 000B 000A */ + int64x2_t s64x2 = vmovl_s32(vget_low_s32(s32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_s64(s64x2); } -// Packs the 16 signed 16 - bit integers from a and b into 8 - bit unsigned -// integers and saturates. -// -// r0 := UnsignedSaturate(a0) -// r1 := UnsignedSaturate(a1) -// ... -// r7 := UnsignedSaturate(a7) -// r8 := UnsignedSaturate(b0) -// r9 := UnsignedSaturate(b1) -// ... -// r15 := UnsignedSaturate(b7) -// -// https://msdn.microsoft.com/en-us/library/07ad1wx4(v=vs.100).aspx -FORCE_INLINE __m128i _mm_packus_epi16(const __m128i a, const __m128i b) +// Converts the four unsigned 16-bit integers in the lower 64 bits to four +// unsigned 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepu16_epi32(__m128i a) { - return vreinterpretq_m128i_u8( - vcombine_u8(vqmovun_s16(vreinterpretq_s16_m128i(a)), - vqmovun_s16(vreinterpretq_s16_m128i(b)))); + return vreinterpretq_m128i_u32( + vmovl_u16(vget_low_u16(vreinterpretq_u16_m128i(a)))); } -// Packs the 8 signed 32-bit integers from a and b into signed 16-bit integers -// and saturates. -// -// r0 := SignedSaturate(a0) -// r1 := SignedSaturate(a1) -// r2 := SignedSaturate(a2) -// r3 := SignedSaturate(a3) -// r4 := SignedSaturate(b0) -// r5 := SignedSaturate(b1) -// r6 := SignedSaturate(b2) -// r7 := SignedSaturate(b3) -// -// https://msdn.microsoft.com/en-us/library/393t56f9%28v=vs.90%29.aspx -FORCE_INLINE __m128i _mm_packs_epi32(__m128i a, __m128i b) +// Converts the two unsigned 16-bit integers in the lower 32 bits to two +// unsigned 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepu16_epi64(__m128i a) { - return vreinterpretq_m128i_s16( - vcombine_s16(vqmovn_s32(vreinterpretq_s32_m128i(a)), - vqmovn_s32(vreinterpretq_s32_m128i(b)))); + uint16x8_t u16x8 = vreinterpretq_u16_m128i(a); /* xxxx xxxx xxxx 0B0A */ + uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000x 000x 000B 000A */ + uint64x2_t u64x2 = vmovl_u32(vget_low_u32(u32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_u64(u64x2); } -// Packs the 8 unsigned 32-bit integers from a and b into unsigned 16-bit -// integers and saturates. -// -// r0 := UnsignedSaturate(a0) -// r1 := UnsignedSaturate(a1) -// r2 := UnsignedSaturate(a2) -// r3 := UnsignedSaturate(a3) -// r4 := UnsignedSaturate(b0) -// r5 := UnsignedSaturate(b1) -// r6 := UnsignedSaturate(b2) -// r7 := UnsignedSaturate(b3) -FORCE_INLINE __m128i _mm_packus_epi32(__m128i a, __m128i b) +// Converts the two unsigned 32-bit integers in the lower 64 bits to two +// unsigned 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepu32_epi64(__m128i a) { - return vreinterpretq_m128i_u16( - vcombine_u16(vqmovun_s32(vreinterpretq_s32_m128i(a)), - vqmovun_s32(vreinterpretq_s32_m128i(b)))); + return vreinterpretq_m128i_u64( + vmovl_u32(vget_low_u32(vreinterpretq_u32_m128i(a)))); } -// Interleaves the lower 8 signed or unsigned 8-bit integers in a with the lower -// 8 signed or unsigned 8-bit integers in b. -// -// r0 := a0 -// r1 := b0 -// r2 := a1 -// r3 := b1 -// ... -// r14 := a7 -// r15 := b7 -// -// https://msdn.microsoft.com/en-us/library/xf7k860c%28v=vs.90%29.aspx -FORCE_INLINE __m128i _mm_unpacklo_epi8(__m128i a, __m128i b) +// Zero extend packed unsigned 8-bit integers in a to packed 16-bit integers, +// and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtepu8_epi16 +FORCE_INLINE __m128i _mm_cvtepu8_epi16(__m128i a) { -#if defined(__aarch64__) - return vreinterpretq_m128i_s8( - vzip1q_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); -#else - int8x8_t a1 = vreinterpret_s8_s16(vget_low_s16(vreinterpretq_s16_m128i(a))); - int8x8_t b1 = vreinterpret_s8_s16(vget_low_s16(vreinterpretq_s16_m128i(b))); - int8x8x2_t result = vzip_s8(a1, b1); - return vreinterpretq_m128i_s8(vcombine_s8(result.val[0], result.val[1])); -#endif + uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx HGFE DCBA */ + uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0H0G 0F0E 0D0C 0B0A */ + return vreinterpretq_m128i_u16(u16x8); } -// Interleaves the lower 4 signed or unsigned 16-bit integers in a with the -// lower 4 signed or unsigned 16-bit integers in b. -// -// r0 := a0 -// r1 := b0 -// r2 := a1 -// r3 := b1 -// r4 := a2 -// r5 := b2 -// r6 := a3 -// r7 := b3 -// -// https://msdn.microsoft.com/en-us/library/btxb17bw%28v=vs.90%29.aspx -FORCE_INLINE __m128i _mm_unpacklo_epi16(__m128i a, __m128i b) +// Converts the four unsigned 8-bit integers in the lower 32 bits to four +// unsigned 32-bit integers. +// https://msdn.microsoft.com/en-us/library/bb531467%28v=vs.100%29.aspx +FORCE_INLINE __m128i _mm_cvtepu8_epi32(__m128i a) { -#if defined(__aarch64__) - return vreinterpretq_m128i_s16( - vzip1q_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); -#else - int16x4_t a1 = vget_low_s16(vreinterpretq_s16_m128i(a)); - int16x4_t b1 = vget_low_s16(vreinterpretq_s16_m128i(b)); - int16x4x2_t result = vzip_s16(a1, b1); - return vreinterpretq_m128i_s16(vcombine_s16(result.val[0], result.val[1])); -#endif + uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx DCBA */ + uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0D0C 0B0A */ + uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000D 000C 000B 000A */ + return vreinterpretq_m128i_u32(u32x4); } -// Interleaves the lower 2 signed or unsigned 32 - bit integers in a with the -// lower 2 signed or unsigned 32 - bit integers in b. -// -// r0 := a0 -// r1 := b0 -// r2 := a1 -// r3 := b1 -// -// https://msdn.microsoft.com/en-us/library/x8atst9d(v=vs.100).aspx -FORCE_INLINE __m128i _mm_unpacklo_epi32(__m128i a, __m128i b) +// Converts the two unsigned 8-bit integers in the lower 16 bits to two +// unsigned 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepu8_epi64(__m128i a) +{ + uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx xxBA */ + uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0x0x 0B0A */ + uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000x 000x 000B 000A */ + uint64x2_t u64x2 = vmovl_u32(vget_low_u32(u32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_u64(u64x2); +} + +// Conditionally multiply the packed double-precision (64-bit) floating-point +// elements in a and b using the high 4 bits in imm8, sum the four products, and +// conditionally store the sum in dst using the low 4 bits of imm8. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_dp_pd +FORCE_INLINE __m128d _mm_dp_pd(__m128d a, __m128d b, const int imm) { + // Generate mask value from constant immediate bit value + const int64_t bit0Mask = imm & 0x01 ? UINT64_MAX : 0; + const int64_t bit1Mask = imm & 0x02 ? UINT64_MAX : 0; +#if !SSE2NEON_PRECISE_DP + const int64_t bit4Mask = imm & 0x10 ? UINT64_MAX : 0; + const int64_t bit5Mask = imm & 0x20 ? UINT64_MAX : 0; +#endif + // Conditional multiplication +#if !SSE2NEON_PRECISE_DP + __m128d mul = _mm_mul_pd(a, b); + const __m128d mulMask = + _mm_castsi128_pd(_mm_set_epi64x(bit5Mask, bit4Mask)); + __m128d tmp = _mm_and_pd(mul, mulMask); +#else #if defined(__aarch64__) - return vreinterpretq_m128i_s32( - vzip1q_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); + double d0 = (imm & 0x10) ? vgetq_lane_f64(vreinterpretq_f64_m128d(a), 0) * + vgetq_lane_f64(vreinterpretq_f64_m128d(b), 0) + : 0; + double d1 = (imm & 0x20) ? vgetq_lane_f64(vreinterpretq_f64_m128d(a), 1) * + vgetq_lane_f64(vreinterpretq_f64_m128d(b), 1) + : 0; #else - int32x2_t a1 = vget_low_s32(vreinterpretq_s32_m128i(a)); - int32x2_t b1 = vget_low_s32(vreinterpretq_s32_m128i(b)); - int32x2x2_t result = vzip_s32(a1, b1); - return vreinterpretq_m128i_s32(vcombine_s32(result.val[0], result.val[1])); + double d0 = (imm & 0x10) ? ((double *) &a)[0] * ((double *) &b)[0] : 0; + double d1 = (imm & 0x20) ? ((double *) &a)[1] * ((double *) &b)[1] : 0; +#endif + __m128d tmp = _mm_set_pd(d1, d0); #endif + // Sum the products +#if defined(__aarch64__) + double sum = vpaddd_f64(vreinterpretq_f64_m128d(tmp)); +#else + double sum = *((double *) &tmp) + *(((double *) &tmp) + 1); +#endif + // Conditionally store the sum + const __m128d sumMask = + _mm_castsi128_pd(_mm_set_epi64x(bit1Mask, bit0Mask)); + __m128d res = _mm_and_pd(_mm_set_pd1(sum), sumMask); + return res; } -FORCE_INLINE __m128i _mm_unpacklo_epi64(__m128i a, __m128i b) +// Conditionally multiply the packed single-precision (32-bit) floating-point +// elements in a and b using the high 4 bits in imm8, sum the four products, +// and conditionally store the sum in dst using the low 4 bits of imm. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_dp_ps +FORCE_INLINE __m128 _mm_dp_ps(__m128 a, __m128 b, const int imm) { - int64x1_t a_l = vget_low_s64(vreinterpretq_s64_m128i(a)); - int64x1_t b_l = vget_low_s64(vreinterpretq_s64_m128i(b)); - return vreinterpretq_m128i_s64(vcombine_s64(a_l, b_l)); +#if defined(__aarch64__) + /* shortcuts */ + if (imm == 0xFF) { + return _mm_set1_ps(vaddvq_f32(_mm_mul_ps(a, b))); + } + if (imm == 0x7F) { + float32x4_t m = _mm_mul_ps(a, b); + m[3] = 0; + return _mm_set1_ps(vaddvq_f32(m)); + } +#endif + + float s = 0, c = 0; + float32x4_t f32a = vreinterpretq_f32_m128(a); + float32x4_t f32b = vreinterpretq_f32_m128(b); + + /* To improve the accuracy of floating-point summation, Kahan algorithm + * is used for each operation. + */ + if (imm & (1 << 4)) + _sse2neon_kadd_f32(&s, &c, f32a[0] * f32b[0]); + if (imm & (1 << 5)) + _sse2neon_kadd_f32(&s, &c, f32a[1] * f32b[1]); + if (imm & (1 << 6)) + _sse2neon_kadd_f32(&s, &c, f32a[2] * f32b[2]); + if (imm & (1 << 7)) + _sse2neon_kadd_f32(&s, &c, f32a[3] * f32b[3]); + s += c; + + float32x4_t res = { + (imm & 0x1) ? s : 0, + (imm & 0x2) ? s : 0, + (imm & 0x4) ? s : 0, + (imm & 0x8) ? s : 0, + }; + return vreinterpretq_m128_f32(res); } -// Selects and interleaves the lower two single-precision, floating-point values -// from a and b. -// -// r0 := a0 -// r1 := b0 -// r2 := a1 -// r3 := b1 -// -// https://msdn.microsoft.com/en-us/library/25st103b%28v=vs.90%29.aspx -FORCE_INLINE __m128 _mm_unpacklo_ps(__m128 a, __m128 b) +// Extracts the selected signed or unsigned 32-bit integer from a and zero +// extends. +// FORCE_INLINE int _mm_extract_epi32(__m128i a, __constrange(0,4) int imm) +#define _mm_extract_epi32(a, imm) \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm)) + +// Extracts the selected signed or unsigned 64-bit integer from a and zero +// extends. +// FORCE_INLINE __int64 _mm_extract_epi64(__m128i a, __constrange(0,2) int imm) +#define _mm_extract_epi64(a, imm) \ + vgetq_lane_s64(vreinterpretq_s64_m128i(a), (imm)) + +// Extracts the selected signed or unsigned 8-bit integer from a and zero +// extends. +// FORCE_INLINE int _mm_extract_epi8(__m128i a, __constrange(0,16) int imm) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_extract_epi8 +#define _mm_extract_epi8(a, imm) vgetq_lane_u8(vreinterpretq_u8_m128i(a), (imm)) + +// Extracts the selected single-precision (32-bit) floating-point from a. +// FORCE_INLINE int _mm_extract_ps(__m128 a, __constrange(0,4) int imm) +#define _mm_extract_ps(a, imm) vgetq_lane_s32(vreinterpretq_s32_m128(a), (imm)) + +// Round the packed double-precision (64-bit) floating-point elements in a down +// to an integer value, and store the results as packed double-precision +// floating-point elements in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_floor_pd +FORCE_INLINE __m128d _mm_floor_pd(__m128d a) { #if defined(__aarch64__) - return vreinterpretq_m128_f32( - vzip1q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); + return vreinterpretq_m128d_f64(vrndmq_f64(vreinterpretq_f64_m128d(a))); #else - float32x2_t a1 = vget_low_f32(vreinterpretq_f32_m128(a)); - float32x2_t b1 = vget_low_f32(vreinterpretq_f32_m128(b)); - float32x2x2_t result = vzip_f32(a1, b1); - return vreinterpretq_m128_f32(vcombine_f32(result.val[0], result.val[1])); + double *f = (double *) &a; + return _mm_set_pd(floor(f[1]), floor(f[0])); #endif } -// Unpack and interleave double-precision (64-bit) floating-point elements from -// the low half of a and b, and store the results in dst. -// -// DEFINE INTERLEAVE_QWORDS(src1[127:0], src2[127:0]) { -// dst[63:0] := src1[63:0] -// dst[127:64] := src2[63:0] -// RETURN dst[127:0] -// } -// dst[127:0] := INTERLEAVE_QWORDS(a[127:0], b[127:0]) -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_unpacklo_pd -FORCE_INLINE __m128d _mm_unpacklo_pd(__m128d a, __m128d b) +// Round the packed single-precision (32-bit) floating-point elements in a down +// to an integer value, and store the results as packed single-precision +// floating-point elements in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_floor_ps +FORCE_INLINE __m128 _mm_floor_ps(__m128 a) { #if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vzip1q_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); + return vreinterpretq_m128_f32(vrndmq_f32(vreinterpretq_f32_m128(a))); #else - return vreinterpretq_m128d_s64( - vcombine_s64(vget_low_s64(vreinterpretq_s64_m128d(a)), - vget_low_s64(vreinterpretq_s64_m128d(b)))); + float *f = (float *) &a; + return _mm_set_ps(floorf(f[3]), floorf(f[2]), floorf(f[1]), floorf(f[0])); #endif } -// Unpack and interleave double-precision (64-bit) floating-point elements from -// the high half of a and b, and store the results in dst. -// -// DEFINE INTERLEAVE_HIGH_QWORDS(src1[127:0], src2[127:0]) { -// dst[63:0] := src1[127:64] -// dst[127:64] := src2[127:64] -// RETURN dst[127:0] -// } -// dst[127:0] := INTERLEAVE_HIGH_QWORDS(a[127:0], b[127:0]) -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_unpackhi_pd -FORCE_INLINE __m128d _mm_unpackhi_pd(__m128d a, __m128d b) +// Round the lower double-precision (64-bit) floating-point element in b down to +// an integer value, store the result as a double-precision floating-point +// element in the lower element of dst, and copy the upper element from a to the +// upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_floor_sd +FORCE_INLINE __m128d _mm_floor_sd(__m128d a, __m128d b) { -#if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vzip2q_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); -#else - return vreinterpretq_m128d_s64( - vcombine_s64(vget_high_s64(vreinterpretq_s64_m128d(a)), - vget_high_s64(vreinterpretq_s64_m128d(b)))); -#endif + return _mm_move_sd(a, _mm_floor_pd(b)); } -// Selects and interleaves the upper two single-precision, floating-point values -// from a and b. +// Round the lower single-precision (32-bit) floating-point element in b down to +// an integer value, store the result as a single-precision floating-point +// element in the lower element of dst, and copy the upper 3 packed elements +// from a to the upper elements of dst. // -// r0 := a2 -// r1 := b2 -// r2 := a3 -// r3 := b3 +// dst[31:0] := FLOOR(b[31:0]) +// dst[127:32] := a[127:32] // -// https://msdn.microsoft.com/en-us/library/skccxx7d%28v=vs.90%29.aspx -FORCE_INLINE __m128 _mm_unpackhi_ps(__m128 a, __m128 b) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_floor_ss +FORCE_INLINE __m128 _mm_floor_ss(__m128 a, __m128 b) { -#if defined(__aarch64__) - return vreinterpretq_m128_f32( - vzip2q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); -#else - float32x2_t a1 = vget_high_f32(vreinterpretq_f32_m128(a)); - float32x2_t b1 = vget_high_f32(vreinterpretq_f32_m128(b)); - float32x2x2_t result = vzip_f32(a1, b1); - return vreinterpretq_m128_f32(vcombine_f32(result.val[0], result.val[1])); -#endif + return _mm_move_ss(a, _mm_floor_ps(b)); } -// Interleaves the upper 8 signed or unsigned 8-bit integers in a with the upper -// 8 signed or unsigned 8-bit integers in b. +// Inserts the least significant 32 bits of b into the selected 32-bit integer +// of a. +// FORCE_INLINE __m128i _mm_insert_epi32(__m128i a, int b, +// __constrange(0,4) int imm) +#define _mm_insert_epi32(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s32( \ + vsetq_lane_s32((b), vreinterpretq_s32_m128i(a), (imm))); \ + }) + +// Inserts the least significant 64 bits of b into the selected 64-bit integer +// of a. +// FORCE_INLINE __m128i _mm_insert_epi64(__m128i a, __int64 b, +// __constrange(0,2) int imm) +#define _mm_insert_epi64(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s64( \ + vsetq_lane_s64((b), vreinterpretq_s64_m128i(a), (imm))); \ + }) + +// Inserts the least significant 8 bits of b into the selected 8-bit integer +// of a. +// FORCE_INLINE __m128i _mm_insert_epi8(__m128i a, int b, +// __constrange(0,16) int imm) +#define _mm_insert_epi8(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s8( \ + vsetq_lane_s8((b), vreinterpretq_s8_m128i(a), (imm))); \ + }) + +// Copy a to tmp, then insert a single-precision (32-bit) floating-point +// element from b into tmp using the control in imm8. Store tmp to dst using +// the mask in imm8 (elements are zeroed out when the corresponding bit is set). +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=insert_ps +#define _mm_insert_ps(a, b, imm8) \ + __extension__({ \ + float32x4_t tmp1 = \ + vsetq_lane_f32(vgetq_lane_f32(b, (imm8 >> 6) & 0x3), \ + vreinterpretq_f32_m128(a), 0); \ + float32x4_t tmp2 = \ + vsetq_lane_f32(vgetq_lane_f32(tmp1, 0), vreinterpretq_f32_m128(a), \ + ((imm8 >> 4) & 0x3)); \ + const uint32_t data[4] = {((imm8) & (1 << 0)) ? UINT32_MAX : 0, \ + ((imm8) & (1 << 1)) ? UINT32_MAX : 0, \ + ((imm8) & (1 << 2)) ? UINT32_MAX : 0, \ + ((imm8) & (1 << 3)) ? UINT32_MAX : 0}; \ + uint32x4_t mask = vld1q_u32(data); \ + float32x4_t all_zeros = vdupq_n_f32(0); \ + \ + vreinterpretq_m128_f32( \ + vbslq_f32(mask, all_zeros, vreinterpretq_f32_m128(tmp2))); \ + }) + +// epi versions of min/max +// Computes the pariwise maximums of the four signed 32-bit integer values of a +// and b. // -// r0 := a8 -// r1 := b8 -// r2 := a9 -// r3 := b9 -// ... -// r14 := a15 -// r15 := b15 +// A 128-bit parameter that can be defined with the following equations: +// r0 := (a0 > b0) ? a0 : b0 +// r1 := (a1 > b1) ? a1 : b1 +// r2 := (a2 > b2) ? a2 : b2 +// r3 := (a3 > b3) ? a3 : b3 // -// https://msdn.microsoft.com/en-us/library/t5h7783k(v=vs.100).aspx -FORCE_INLINE __m128i _mm_unpackhi_epi8(__m128i a, __m128i b) +// https://msdn.microsoft.com/en-us/library/vstudio/bb514055(v=vs.100).aspx +FORCE_INLINE __m128i _mm_max_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vmaxq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Compare packed signed 8-bit integers in a and b, and store packed maximum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epi8 +FORCE_INLINE __m128i _mm_max_epi8(__m128i a, __m128i b) { -#if defined(__aarch64__) return vreinterpretq_m128i_s8( - vzip2q_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); -#else - int8x8_t a1 = - vreinterpret_s8_s16(vget_high_s16(vreinterpretq_s16_m128i(a))); - int8x8_t b1 = - vreinterpret_s8_s16(vget_high_s16(vreinterpretq_s16_m128i(b))); - int8x8x2_t result = vzip_s8(a1, b1); - return vreinterpretq_m128i_s8(vcombine_s8(result.val[0], result.val[1])); -#endif + vmaxq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); } -// Interleaves the upper 4 signed or unsigned 16-bit integers in a with the -// upper 4 signed or unsigned 16-bit integers in b. +// Compare packed unsigned 16-bit integers in a and b, and store packed maximum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu16 +FORCE_INLINE __m128i _mm_max_epu16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vmaxq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); +} + +// Compare packed unsigned 32-bit integers in a and b, and store packed maximum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu32 +FORCE_INLINE __m128i _mm_max_epu32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u32( + vmaxq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b))); +} + +// Computes the pariwise minima of the four signed 32-bit integer values of a +// and b. // -// r0 := a4 -// r1 := b4 -// r2 := a5 -// r3 := b5 -// r4 := a6 -// r5 := b6 -// r6 := a7 -// r7 := b7 +// A 128-bit parameter that can be defined with the following equations: +// r0 := (a0 < b0) ? a0 : b0 +// r1 := (a1 < b1) ? a1 : b1 +// r2 := (a2 < b2) ? a2 : b2 +// r3 := (a3 < b3) ? a3 : b3 // -// https://msdn.microsoft.com/en-us/library/03196cz7(v=vs.100).aspx -FORCE_INLINE __m128i _mm_unpackhi_epi16(__m128i a, __m128i b) +// https://msdn.microsoft.com/en-us/library/vstudio/bb531476(v=vs.100).aspx +FORCE_INLINE __m128i _mm_min_epi32(__m128i a, __m128i b) { -#if defined(__aarch64__) - return vreinterpretq_m128i_s16( - vzip2q_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); -#else - int16x4_t a1 = vget_high_s16(vreinterpretq_s16_m128i(a)); - int16x4_t b1 = vget_high_s16(vreinterpretq_s16_m128i(b)); - int16x4x2_t result = vzip_s16(a1, b1); - return vreinterpretq_m128i_s16(vcombine_s16(result.val[0], result.val[1])); -#endif + return vreinterpretq_m128i_s32( + vminq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); } -// Interleaves the upper 2 signed or unsigned 32-bit integers in a with the -// upper 2 signed or unsigned 32-bit integers in b. -// https://msdn.microsoft.com/en-us/library/65sa7cbs(v=vs.100).aspx -FORCE_INLINE __m128i _mm_unpackhi_epi32(__m128i a, __m128i b) +// Compare packed signed 8-bit integers in a and b, and store packed minimum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_epi8 +FORCE_INLINE __m128i _mm_min_epi8(__m128i a, __m128i b) { -#if defined(__aarch64__) - return vreinterpretq_m128i_s32( - vzip2q_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); -#else - int32x2_t a1 = vget_high_s32(vreinterpretq_s32_m128i(a)); - int32x2_t b1 = vget_high_s32(vreinterpretq_s32_m128i(b)); - int32x2x2_t result = vzip_s32(a1, b1); - return vreinterpretq_m128i_s32(vcombine_s32(result.val[0], result.val[1])); -#endif + return vreinterpretq_m128i_s8( + vminq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); } -// Interleaves the upper signed or unsigned 64-bit integer in a with the -// upper signed or unsigned 64-bit integer in b. -// -// r0 := a1 -// r1 := b1 -FORCE_INLINE __m128i _mm_unpackhi_epi64(__m128i a, __m128i b) +// Compare packed unsigned 16-bit integers in a and b, and store packed minimum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_epu16 +FORCE_INLINE __m128i _mm_min_epu16(__m128i a, __m128i b) { - int64x1_t a_h = vget_high_s64(vreinterpretq_s64_m128i(a)); - int64x1_t b_h = vget_high_s64(vreinterpretq_s64_m128i(b)); - return vreinterpretq_m128i_s64(vcombine_s64(a_h, b_h)); + return vreinterpretq_m128i_u16( + vminq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); +} + +// Compare packed unsigned 32-bit integers in a and b, and store packed minimum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu32 +FORCE_INLINE __m128i _mm_min_epu32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u32( + vminq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b))); } // Horizontally compute the minimum amongst the packed unsigned 16-bit integers @@ -6296,6 +7929,339 @@ FORCE_INLINE __m128i _mm_minpos_epu16(__m128i a) return dst; } +// Compute the sum of absolute differences (SADs) of quadruplets of unsigned +// 8-bit integers in a compared to those in b, and store the 16-bit results in +// dst. Eight SADs are performed using one quadruplet from b and eight +// quadruplets from a. One quadruplet is selected from b starting at on the +// offset specified in imm8. Eight quadruplets are formed from sequential 8-bit +// integers selected from a starting at the offset specified in imm8. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mpsadbw_epu8 +FORCE_INLINE __m128i _mm_mpsadbw_epu8(__m128i a, __m128i b, const int imm) +{ + uint8x16_t _a, _b; + + switch (imm & 0x4) { + case 0: + // do nothing + _a = vreinterpretq_u8_m128i(a); + break; + case 4: + _a = vreinterpretq_u8_u32(vextq_u32(vreinterpretq_u32_m128i(a), + vreinterpretq_u32_m128i(a), 1)); + break; + default: +#if defined(__GNUC__) || defined(__clang__) + __builtin_unreachable(); +#endif + break; + } + + switch (imm & 0x3) { + case 0: + _b = vreinterpretq_u8_u32( + vdupq_n_u32(vgetq_lane_u32(vreinterpretq_u32_m128i(b), 0))); + break; + case 1: + _b = vreinterpretq_u8_u32( + vdupq_n_u32(vgetq_lane_u32(vreinterpretq_u32_m128i(b), 1))); + break; + case 2: + _b = vreinterpretq_u8_u32( + vdupq_n_u32(vgetq_lane_u32(vreinterpretq_u32_m128i(b), 2))); + break; + case 3: + _b = vreinterpretq_u8_u32( + vdupq_n_u32(vgetq_lane_u32(vreinterpretq_u32_m128i(b), 3))); + break; + default: +#if defined(__GNUC__) || defined(__clang__) + __builtin_unreachable(); +#endif + break; + } + + int16x8_t c04, c15, c26, c37; + uint8x8_t low_b = vget_low_u8(_b); + c04 = vabsq_s16(vreinterpretq_s16_u16(vsubl_u8(vget_low_u8(_a), low_b))); + _a = vextq_u8(_a, _a, 1); + c15 = vabsq_s16(vreinterpretq_s16_u16(vsubl_u8(vget_low_u8(_a), low_b))); + _a = vextq_u8(_a, _a, 1); + c26 = vabsq_s16(vreinterpretq_s16_u16(vsubl_u8(vget_low_u8(_a), low_b))); + _a = vextq_u8(_a, _a, 1); + c37 = vabsq_s16(vreinterpretq_s16_u16(vsubl_u8(vget_low_u8(_a), low_b))); +#if defined(__aarch64__) + // |0|4|2|6| + c04 = vpaddq_s16(c04, c26); + // |1|5|3|7| + c15 = vpaddq_s16(c15, c37); + + int32x4_t trn1_c = + vtrn1q_s32(vreinterpretq_s32_s16(c04), vreinterpretq_s32_s16(c15)); + int32x4_t trn2_c = + vtrn2q_s32(vreinterpretq_s32_s16(c04), vreinterpretq_s32_s16(c15)); + return vreinterpretq_m128i_s16(vpaddq_s16(vreinterpretq_s16_s32(trn1_c), + vreinterpretq_s16_s32(trn2_c))); +#else + int16x4_t c01, c23, c45, c67; + c01 = vpadd_s16(vget_low_s16(c04), vget_low_s16(c15)); + c23 = vpadd_s16(vget_low_s16(c26), vget_low_s16(c37)); + c45 = vpadd_s16(vget_high_s16(c04), vget_high_s16(c15)); + c67 = vpadd_s16(vget_high_s16(c26), vget_high_s16(c37)); + + return vreinterpretq_m128i_s16( + vcombine_s16(vpadd_s16(c01, c23), vpadd_s16(c45, c67))); +#endif +} + +// Multiply the low signed 32-bit integers from each packed 64-bit element in +// a and b, and store the signed 64-bit results in dst. +// +// r0 := (int64_t)(int32_t)a0 * (int64_t)(int32_t)b0 +// r1 := (int64_t)(int32_t)a2 * (int64_t)(int32_t)b2 +FORCE_INLINE __m128i _mm_mul_epi32(__m128i a, __m128i b) +{ + // vmull_s32 upcasts instead of masking, so we downcast. + int32x2_t a_lo = vmovn_s64(vreinterpretq_s64_m128i(a)); + int32x2_t b_lo = vmovn_s64(vreinterpretq_s64_m128i(b)); + return vreinterpretq_m128i_s64(vmull_s32(a_lo, b_lo)); +} + +// Multiplies the 4 signed or unsigned 32-bit integers from a by the 4 signed or +// unsigned 32-bit integers from b. +// https://msdn.microsoft.com/en-us/library/vstudio/bb531409(v=vs.100).aspx +FORCE_INLINE __m128i _mm_mullo_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vmulq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Packs the 8 unsigned 32-bit integers from a and b into unsigned 16-bit +// integers and saturates. +// +// r0 := UnsignedSaturate(a0) +// r1 := UnsignedSaturate(a1) +// r2 := UnsignedSaturate(a2) +// r3 := UnsignedSaturate(a3) +// r4 := UnsignedSaturate(b0) +// r5 := UnsignedSaturate(b1) +// r6 := UnsignedSaturate(b2) +// r7 := UnsignedSaturate(b3) +FORCE_INLINE __m128i _mm_packus_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vcombine_u16(vqmovun_s32(vreinterpretq_s32_m128i(a)), + vqmovun_s32(vreinterpretq_s32_m128i(b)))); +} + +// Round the packed double-precision (64-bit) floating-point elements in a using +// the rounding parameter, and store the results as packed double-precision +// floating-point elements in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_round_pd +FORCE_INLINE __m128d _mm_round_pd(__m128d a, int rounding) +{ +#if defined(__aarch64__) + switch (rounding) { + case (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC): + return vreinterpretq_m128d_f64(vrndnq_f64(vreinterpretq_f64_m128d(a))); + case (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC): + return _mm_floor_pd(a); + case (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC): + return _mm_ceil_pd(a); + case (_MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC): + return vreinterpretq_m128d_f64(vrndq_f64(vreinterpretq_f64_m128d(a))); + default: //_MM_FROUND_CUR_DIRECTION + return vreinterpretq_m128d_f64(vrndiq_f64(vreinterpretq_f64_m128d(a))); + } +#else + double *v_double = (double *) &a; + + if (rounding == (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC) || + (rounding == _MM_FROUND_CUR_DIRECTION && + _MM_GET_ROUNDING_MODE() == _MM_ROUND_NEAREST)) { + double res[2], tmp; + for (int i = 0; i < 2; i++) { + tmp = (v_double[i] < 0) ? -v_double[i] : v_double[i]; + double roundDown = floor(tmp); // Round down value + double roundUp = ceil(tmp); // Round up value + double diffDown = tmp - roundDown; + double diffUp = roundUp - tmp; + if (diffDown < diffUp) { + /* If it's closer to the round down value, then use it */ + res[i] = roundDown; + } else if (diffDown > diffUp) { + /* If it's closer to the round up value, then use it */ + res[i] = roundUp; + } else { + /* If it's equidistant between round up and round down value, + * pick the one which is an even number */ + double half = roundDown / 2; + if (half != floor(half)) { + /* If the round down value is odd, return the round up value + */ + res[i] = roundUp; + } else { + /* If the round up value is odd, return the round down value + */ + res[i] = roundDown; + } + } + res[i] = (v_double[i] < 0) ? -res[i] : res[i]; + } + return _mm_set_pd(res[1], res[0]); + } else if (rounding == (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC) || + (rounding == _MM_FROUND_CUR_DIRECTION && + _MM_GET_ROUNDING_MODE() == _MM_ROUND_DOWN)) { + return _mm_floor_pd(a); + } else if (rounding == (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC) || + (rounding == _MM_FROUND_CUR_DIRECTION && + _MM_GET_ROUNDING_MODE() == _MM_ROUND_UP)) { + return _mm_ceil_pd(a); + } + return _mm_set_pd(v_double[1] > 0 ? floor(v_double[1]) : ceil(v_double[1]), + v_double[0] > 0 ? floor(v_double[0]) : ceil(v_double[0])); +#endif +} + +// Round the packed single-precision (32-bit) floating-point elements in a using +// the rounding parameter, and store the results as packed single-precision +// floating-point elements in dst. +// software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_round_ps +FORCE_INLINE __m128 _mm_round_ps(__m128 a, int rounding) +{ +#if defined(__aarch64__) + switch (rounding) { + case (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC): + return vreinterpretq_m128_f32(vrndnq_f32(vreinterpretq_f32_m128(a))); + case (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC): + return _mm_floor_ps(a); + case (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC): + return _mm_ceil_ps(a); + case (_MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC): + return vreinterpretq_m128_f32(vrndq_f32(vreinterpretq_f32_m128(a))); + default: //_MM_FROUND_CUR_DIRECTION + return vreinterpretq_m128_f32(vrndiq_f32(vreinterpretq_f32_m128(a))); + } +#else + float *v_float = (float *) &a; + + if (rounding == (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC) || + (rounding == _MM_FROUND_CUR_DIRECTION && + _MM_GET_ROUNDING_MODE() == _MM_ROUND_NEAREST)) { + uint32x4_t signmask = vdupq_n_u32(0x80000000); + float32x4_t half = vbslq_f32(signmask, vreinterpretq_f32_m128(a), + vdupq_n_f32(0.5f)); /* +/- 0.5 */ + int32x4_t r_normal = vcvtq_s32_f32(vaddq_f32( + vreinterpretq_f32_m128(a), half)); /* round to integer: [a + 0.5]*/ + int32x4_t r_trunc = vcvtq_s32_f32( + vreinterpretq_f32_m128(a)); /* truncate to integer: [a] */ + int32x4_t plusone = vreinterpretq_s32_u32(vshrq_n_u32( + vreinterpretq_u32_s32(vnegq_s32(r_trunc)), 31)); /* 1 or 0 */ + int32x4_t r_even = vbicq_s32(vaddq_s32(r_trunc, plusone), + vdupq_n_s32(1)); /* ([a] + {0,1}) & ~1 */ + float32x4_t delta = vsubq_f32( + vreinterpretq_f32_m128(a), + vcvtq_f32_s32(r_trunc)); /* compute delta: delta = (a - [a]) */ + uint32x4_t is_delta_half = + vceqq_f32(delta, half); /* delta == +/- 0.5 */ + return vreinterpretq_m128_f32( + vcvtq_f32_s32(vbslq_s32(is_delta_half, r_even, r_normal))); + } else if (rounding == (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC) || + (rounding == _MM_FROUND_CUR_DIRECTION && + _MM_GET_ROUNDING_MODE() == _MM_ROUND_DOWN)) { + return _mm_floor_ps(a); + } else if (rounding == (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC) || + (rounding == _MM_FROUND_CUR_DIRECTION && + _MM_GET_ROUNDING_MODE() == _MM_ROUND_UP)) { + return _mm_ceil_ps(a); + } + return _mm_set_ps(v_float[3] > 0 ? floorf(v_float[3]) : ceilf(v_float[3]), + v_float[2] > 0 ? floorf(v_float[2]) : ceilf(v_float[2]), + v_float[1] > 0 ? floorf(v_float[1]) : ceilf(v_float[1]), + v_float[0] > 0 ? floorf(v_float[0]) : ceilf(v_float[0])); +#endif +} + +// Round the lower double-precision (64-bit) floating-point element in b using +// the rounding parameter, store the result as a double-precision floating-point +// element in the lower element of dst, and copy the upper element from a to the +// upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_round_sd +FORCE_INLINE __m128d _mm_round_sd(__m128d a, __m128d b, int rounding) +{ + return _mm_move_sd(a, _mm_round_pd(b, rounding)); +} + +// Round the lower single-precision (32-bit) floating-point element in b using +// the rounding parameter, store the result as a single-precision floating-point +// element in the lower element of dst, and copy the upper 3 packed elements +// from a to the upper elements of dst. Rounding is done according to the +// rounding[3:0] parameter, which can be one of: +// (_MM_FROUND_TO_NEAREST_INT |_MM_FROUND_NO_EXC) // round to nearest, and +// suppress exceptions +// (_MM_FROUND_TO_NEG_INF |_MM_FROUND_NO_EXC) // round down, and +// suppress exceptions +// (_MM_FROUND_TO_POS_INF |_MM_FROUND_NO_EXC) // round up, and suppress +// exceptions +// (_MM_FROUND_TO_ZERO |_MM_FROUND_NO_EXC) // truncate, and suppress +// exceptions _MM_FROUND_CUR_DIRECTION // use MXCSR.RC; see +// _MM_SET_ROUNDING_MODE +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_round_ss +FORCE_INLINE __m128 _mm_round_ss(__m128 a, __m128 b, int rounding) +{ + return _mm_move_ss(a, _mm_round_ps(b, rounding)); +} + +// Load 128-bits of integer data from memory into dst using a non-temporal +// memory hint. mem_addr must be aligned on a 16-byte boundary or a +// general-protection exception may be generated. +// +// dst[127:0] := MEM[mem_addr+127:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_load_si128 +FORCE_INLINE __m128i _mm_stream_load_si128(__m128i *p) +{ +#if __has_builtin(__builtin_nontemporal_store) + return __builtin_nontemporal_load(p); +#else + return vreinterpretq_m128i_s64(vld1q_s64((int64_t *) p)); +#endif +} + +// Compute the bitwise NOT of a and then AND with a 128-bit vector containing +// all 1's, and return 1 if the result is zero, otherwise return 0. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_test_all_ones +FORCE_INLINE int _mm_test_all_ones(__m128i a) +{ + return (uint64_t)(vgetq_lane_s64(a, 0) & vgetq_lane_s64(a, 1)) == + ~(uint64_t) 0; +} + +// Compute the bitwise AND of 128 bits (representing integer data) in a and +// mask, and return 1 if the result is zero, otherwise return 0. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_test_all_zeros +FORCE_INLINE int _mm_test_all_zeros(__m128i a, __m128i mask) +{ + int64x2_t a_and_mask = + vandq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(mask)); + return !(vgetq_lane_s64(a_and_mask, 0) | vgetq_lane_s64(a_and_mask, 1)); +} + +// Compute the bitwise AND of 128 bits (representing integer data) in a and +// mask, and set ZF to 1 if the result is zero, otherwise set ZF to 0. Compute +// the bitwise NOT of a and then AND with mask, and set CF to 1 if the result is +// zero, otherwise set CF to 0. Return 1 if both the ZF and CF values are zero, +// otherwise return 0. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_test_mix_ones_zero +FORCE_INLINE int _mm_test_mix_ones_zeros(__m128i a, __m128i mask) +{ + uint64x2_t zf = + vandq_u64(vreinterpretq_u64_m128i(mask), vreinterpretq_u64_m128i(a)); + uint64x2_t cf = + vbicq_u64(vreinterpretq_u64_m128i(mask), vreinterpretq_u64_m128i(a)); + uint64x2_t result = vandq_u64(zf, cf); + return !(vgetq_lane_u64(result, 0) | vgetq_lane_u64(result, 1)); +} + // Compute the bitwise AND of 128 bits (representing integer data) in a and b, // and set ZF to 1 if the result is zero, otherwise set ZF to 0. Compute the // bitwise NOT of a and then AND with b, and set CF to 1 if the result is zero, @@ -6312,6 +8278,14 @@ FORCE_INLINE int _mm_testc_si128(__m128i a, __m128i b) // Compute the bitwise AND of 128 bits (representing integer data) in a and b, // and set ZF to 1 if the result is zero, otherwise set ZF to 0. Compute the // bitwise NOT of a and then AND with b, and set CF to 1 if the result is zero, +// otherwise set CF to 0. Return 1 if both the ZF and CF values are zero, +// otherwise return 0. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_testnzc_si128 +#define _mm_testnzc_si128(a, b) _mm_test_mix_ones_zeros(a, b) + +// Compute the bitwise AND of 128 bits (representing integer data) in a and b, +// and set ZF to 1 if the result is zero, otherwise set ZF to 0. Compute the +// bitwise NOT of a and then AND with b, and set CF to 1 if the result is zero, // otherwise set CF to 0. Return the ZF value. // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_testz_si128 FORCE_INLINE int _mm_testz_si128(__m128i a, __m128i b) @@ -6321,299 +8295,93 @@ FORCE_INLINE int _mm_testz_si128(__m128i a, __m128i b) return !(vgetq_lane_s64(s64, 0) | vgetq_lane_s64(s64, 1)); } -// Extracts the selected signed or unsigned 8-bit integer from a and zero -// extends. -// FORCE_INLINE int _mm_extract_epi8(__m128i a, __constrange(0,16) int imm) -#define _mm_extract_epi8(a, imm) vgetq_lane_u8(vreinterpretq_u8_m128i(a), (imm)) - -// Inserts the least significant 8 bits of b into the selected 8-bit integer -// of a. -// FORCE_INLINE __m128i _mm_insert_epi8(__m128i a, int b, -// __constrange(0,16) int imm) -#define _mm_insert_epi8(a, b, imm) \ - __extension__({ \ - vreinterpretq_m128i_s8( \ - vsetq_lane_s8((b), vreinterpretq_s8_m128i(a), (imm))); \ - }) - -// Extracts the selected signed or unsigned 16-bit integer from a and zero -// extends. -// https://msdn.microsoft.com/en-us/library/6dceta0c(v=vs.100).aspx -// FORCE_INLINE int _mm_extract_epi16(__m128i a, __constrange(0,8) int imm) -#define _mm_extract_epi16(a, imm) \ - vgetq_lane_u16(vreinterpretq_u16_m128i(a), (imm)) - -// Inserts the least significant 16 bits of b into the selected 16-bit integer -// of a. -// https://msdn.microsoft.com/en-us/library/kaze8hz1%28v=vs.100%29.aspx -// FORCE_INLINE __m128i _mm_insert_epi16(__m128i a, int b, -// __constrange(0,8) int imm) -#define _mm_insert_epi16(a, b, imm) \ - __extension__({ \ - vreinterpretq_m128i_s16( \ - vsetq_lane_s16((b), vreinterpretq_s16_m128i(a), (imm))); \ - }) - -// Copy a to dst, and insert the 16-bit integer i into dst at the location -// specified by imm8. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_insert_pi16 -#define _mm_insert_pi16(a, b, imm) \ - __extension__({ \ - vreinterpret_m64_s16( \ - vset_lane_s16((b), vreinterpret_s16_m64(a), (imm))); \ - }) - -// Extracts the selected signed or unsigned 32-bit integer from a and zero -// extends. -// FORCE_INLINE int _mm_extract_epi32(__m128i a, __constrange(0,4) int imm) -#define _mm_extract_epi32(a, imm) \ - vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm)) - -// Extracts the selected single-precision (32-bit) floating-point from a. -// FORCE_INLINE int _mm_extract_ps(__m128 a, __constrange(0,4) int imm) -#define _mm_extract_ps(a, imm) vgetq_lane_s32(vreinterpretq_s32_m128(a), (imm)) - -// Inserts the least significant 32 bits of b into the selected 32-bit integer -// of a. -// FORCE_INLINE __m128i _mm_insert_epi32(__m128i a, int b, -// __constrange(0,4) int imm) -#define _mm_insert_epi32(a, b, imm) \ - __extension__({ \ - vreinterpretq_m128i_s32( \ - vsetq_lane_s32((b), vreinterpretq_s32_m128i(a), (imm))); \ - }) - -// Extracts the selected signed or unsigned 64-bit integer from a and zero -// extends. -// FORCE_INLINE __int64 _mm_extract_epi64(__m128i a, __constrange(0,2) int imm) -#define _mm_extract_epi64(a, imm) \ - vgetq_lane_s64(vreinterpretq_s64_m128i(a), (imm)) - -// Inserts the least significant 64 bits of b into the selected 64-bit integer -// of a. -// FORCE_INLINE __m128i _mm_insert_epi64(__m128i a, __int64 b, -// __constrange(0,2) int imm) -#define _mm_insert_epi64(a, b, imm) \ - __extension__({ \ - vreinterpretq_m128i_s64( \ - vsetq_lane_s64((b), vreinterpretq_s64_m128i(a), (imm))); \ - }) +/* SSE4.2 */ -// Count the number of bits set to 1 in unsigned 32-bit integer a, and -// return that count in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_popcnt_u32 -FORCE_INLINE int _mm_popcnt_u32(unsigned int a) +// Compares the 2 signed 64-bit integers in a and the 2 signed 64-bit integers +// in b for greater than. +FORCE_INLINE __m128i _mm_cmpgt_epi64(__m128i a, __m128i b) { #if defined(__aarch64__) -#if __has_builtin(__builtin_popcount) - return __builtin_popcount(a); + return vreinterpretq_m128i_u64( + vcgtq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); #else - return (int) vaddlv_u8(vcnt_u8(vcreate_u8((uint64_t) a))); -#endif -#else - uint32_t count = 0; - uint8x8_t input_val, count8x8_val; - uint16x4_t count16x4_val; - uint32x2_t count32x2_val; - - input_val = vld1_u8((uint8_t *) &a); - count8x8_val = vcnt_u8(input_val); - count16x4_val = vpaddl_u8(count8x8_val); - count32x2_val = vpaddl_u16(count16x4_val); - - vst1_u32(&count, count32x2_val); - return count; + return vreinterpretq_m128i_s64(vshrq_n_s64( + vqsubq_s64(vreinterpretq_s64_m128i(b), vreinterpretq_s64_m128i(a)), + 63)); #endif } -// Count the number of bits set to 1 in unsigned 64-bit integer a, and -// return that count in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_popcnt_u64 -FORCE_INLINE int64_t _mm_popcnt_u64(uint64_t a) +// Starting with the initial value in crc, accumulates a CRC32 value for +// unsigned 16-bit integer v. +// https://msdn.microsoft.com/en-us/library/bb531411(v=vs.100) +FORCE_INLINE uint32_t _mm_crc32_u16(uint32_t crc, uint16_t v) { -#if defined(__aarch64__) -#if __has_builtin(__builtin_popcountll) - return __builtin_popcountll(a); -#else - return (int64_t) vaddlv_u8(vcnt_u8(vcreate_u8(a))); -#endif +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) + __asm__ __volatile__("crc32ch %w[c], %w[c], %w[v]\n\t" + : [c] "+r"(crc) + : [v] "r"(v)); #else - uint64_t count = 0; - uint8x8_t input_val, count8x8_val; - uint16x4_t count16x4_val; - uint32x2_t count32x2_val; - uint64x1_t count64x1_val; - - input_val = vld1_u8((uint8_t *) &a); - count8x8_val = vcnt_u8(input_val); - count16x4_val = vpaddl_u8(count8x8_val); - count32x2_val = vpaddl_u16(count16x4_val); - count64x1_val = vpaddl_u32(count32x2_val); - vst1_u64(&count, count64x1_val); - return count; + crc = _mm_crc32_u8(crc, v & 0xff); + crc = _mm_crc32_u8(crc, (v >> 8) & 0xff); #endif + return crc; } -// Macro: Transpose the 4x4 matrix formed by the 4 rows of single-precision -// (32-bit) floating-point elements in row0, row1, row2, and row3, and store the -// transposed matrix in these vectors (row0 now contains column 0, etc.). -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=MM_TRANSPOSE4_PS -#define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \ - do { \ - float32x4x2_t ROW01 = vtrnq_f32(row0, row1); \ - float32x4x2_t ROW23 = vtrnq_f32(row2, row3); \ - row0 = vcombine_f32(vget_low_f32(ROW01.val[0]), \ - vget_low_f32(ROW23.val[0])); \ - row1 = vcombine_f32(vget_low_f32(ROW01.val[1]), \ - vget_low_f32(ROW23.val[1])); \ - row2 = vcombine_f32(vget_high_f32(ROW01.val[0]), \ - vget_high_f32(ROW23.val[0])); \ - row3 = vcombine_f32(vget_high_f32(ROW01.val[1]), \ - vget_high_f32(ROW23.val[1])); \ - } while (0) - -/* Crypto Extensions */ - -#if defined(__ARM_FEATURE_CRYPTO) -// Wraps vmull_p64 -FORCE_INLINE uint64x2_t _sse2neon_vmull_p64(uint64x1_t _a, uint64x1_t _b) -{ - poly64_t a = vget_lane_p64(vreinterpret_p64_u64(_a), 0); - poly64_t b = vget_lane_p64(vreinterpret_p64_u64(_b), 0); - return vreinterpretq_u64_p128(vmull_p64(a, b)); -} -#else // ARMv7 polyfill -// ARMv7/some A64 lacks vmull_p64, but it has vmull_p8. -// -// vmull_p8 calculates 8 8-bit->16-bit polynomial multiplies, but we need a -// 64-bit->128-bit polynomial multiply. -// -// It needs some work and is somewhat slow, but it is still faster than all -// known scalar methods. -// -// Algorithm adapted to C from -// https://www.workofard.com/2017/07/ghash-for-low-end-cores/, which is adapted -// from "Fast Software Polynomial Multiplication on ARM Processors Using the -// NEON Engine" by Danilo Camara, Conrado Gouvea, Julio Lopez and Ricardo Dahab -// (https://hal.inria.fr/hal-01506572) -static uint64x2_t _sse2neon_vmull_p64(uint64x1_t _a, uint64x1_t _b) +// Starting with the initial value in crc, accumulates a CRC32 value for +// unsigned 32-bit integer v. +// https://msdn.microsoft.com/en-us/library/bb531394(v=vs.100) +FORCE_INLINE uint32_t _mm_crc32_u32(uint32_t crc, uint32_t v) { - poly8x8_t a = vreinterpret_p8_u64(_a); - poly8x8_t b = vreinterpret_p8_u64(_b); - - // Masks - uint8x16_t k48_32 = vcombine_u8(vcreate_u8(0x0000ffffffffffff), - vcreate_u8(0x00000000ffffffff)); - uint8x16_t k16_00 = vcombine_u8(vcreate_u8(0x000000000000ffff), - vcreate_u8(0x0000000000000000)); - - // Do the multiplies, rotating with vext to get all combinations - uint8x16_t d = vreinterpretq_u8_p16(vmull_p8(a, b)); // D = A0 * B0 - uint8x16_t e = - vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 1))); // E = A0 * B1 - uint8x16_t f = - vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 1), b)); // F = A1 * B0 - uint8x16_t g = - vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 2))); // G = A0 * B2 - uint8x16_t h = - vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 2), b)); // H = A2 * B0 - uint8x16_t i = - vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 3))); // I = A0 * B3 - uint8x16_t j = - vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 3), b)); // J = A3 * B0 - uint8x16_t k = - vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 4))); // L = A0 * B4 - - // Add cross products - uint8x16_t l = veorq_u8(e, f); // L = E + F - uint8x16_t m = veorq_u8(g, h); // M = G + H - uint8x16_t n = veorq_u8(i, j); // N = I + J - - // Interleave. Using vzip1 and vzip2 prevents Clang from emitting TBL - // instructions. -#if defined(__aarch64__) - uint8x16_t lm_p0 = vreinterpretq_u8_u64( - vzip1q_u64(vreinterpretq_u64_u8(l), vreinterpretq_u64_u8(m))); - uint8x16_t lm_p1 = vreinterpretq_u8_u64( - vzip2q_u64(vreinterpretq_u64_u8(l), vreinterpretq_u64_u8(m))); - uint8x16_t nk_p0 = vreinterpretq_u8_u64( - vzip1q_u64(vreinterpretq_u64_u8(n), vreinterpretq_u64_u8(k))); - uint8x16_t nk_p1 = vreinterpretq_u8_u64( - vzip2q_u64(vreinterpretq_u64_u8(n), vreinterpretq_u64_u8(k))); +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) + __asm__ __volatile__("crc32cw %w[c], %w[c], %w[v]\n\t" + : [c] "+r"(crc) + : [v] "r"(v)); #else - uint8x16_t lm_p0 = vcombine_u8(vget_low_u8(l), vget_low_u8(m)); - uint8x16_t lm_p1 = vcombine_u8(vget_high_u8(l), vget_high_u8(m)); - uint8x16_t nk_p0 = vcombine_u8(vget_low_u8(n), vget_low_u8(k)); - uint8x16_t nk_p1 = vcombine_u8(vget_high_u8(n), vget_high_u8(k)); + crc = _mm_crc32_u16(crc, v & 0xffff); + crc = _mm_crc32_u16(crc, (v >> 16) & 0xffff); #endif - // t0 = (L) (P0 + P1) << 8 - // t1 = (M) (P2 + P3) << 16 - uint8x16_t t0t1_tmp = veorq_u8(lm_p0, lm_p1); - uint8x16_t t0t1_h = vandq_u8(lm_p1, k48_32); - uint8x16_t t0t1_l = veorq_u8(t0t1_tmp, t0t1_h); - - // t2 = (N) (P4 + P5) << 24 - // t3 = (K) (P6 + P7) << 32 - uint8x16_t t2t3_tmp = veorq_u8(nk_p0, nk_p1); - uint8x16_t t2t3_h = vandq_u8(nk_p1, k16_00); - uint8x16_t t2t3_l = veorq_u8(t2t3_tmp, t2t3_h); + return crc; +} - // De-interleave -#if defined(__aarch64__) - uint8x16_t t0 = vreinterpretq_u8_u64( - vuzp1q_u64(vreinterpretq_u64_u8(t0t1_l), vreinterpretq_u64_u8(t0t1_h))); - uint8x16_t t1 = vreinterpretq_u8_u64( - vuzp2q_u64(vreinterpretq_u64_u8(t0t1_l), vreinterpretq_u64_u8(t0t1_h))); - uint8x16_t t2 = vreinterpretq_u8_u64( - vuzp1q_u64(vreinterpretq_u64_u8(t2t3_l), vreinterpretq_u64_u8(t2t3_h))); - uint8x16_t t3 = vreinterpretq_u8_u64( - vuzp2q_u64(vreinterpretq_u64_u8(t2t3_l), vreinterpretq_u64_u8(t2t3_h))); +// Starting with the initial value in crc, accumulates a CRC32 value for +// unsigned 64-bit integer v. +// https://msdn.microsoft.com/en-us/library/bb514033(v=vs.100) +FORCE_INLINE uint64_t _mm_crc32_u64(uint64_t crc, uint64_t v) +{ +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) + __asm__ __volatile__("crc32cx %w[c], %w[c], %x[v]\n\t" + : [c] "+r"(crc) + : [v] "r"(v)); #else - uint8x16_t t1 = vcombine_u8(vget_high_u8(t0t1_l), vget_high_u8(t0t1_h)); - uint8x16_t t0 = vcombine_u8(vget_low_u8(t0t1_l), vget_low_u8(t0t1_h)); - uint8x16_t t3 = vcombine_u8(vget_high_u8(t2t3_l), vget_high_u8(t2t3_h)); - uint8x16_t t2 = vcombine_u8(vget_low_u8(t2t3_l), vget_low_u8(t2t3_h)); + crc = _mm_crc32_u32((uint32_t)(crc), v & 0xffffffff); + crc = _mm_crc32_u32((uint32_t)(crc), (v >> 32) & 0xffffffff); #endif - // Shift the cross products - uint8x16_t t0_shift = vextq_u8(t0, t0, 15); // t0 << 8 - uint8x16_t t1_shift = vextq_u8(t1, t1, 14); // t1 << 16 - uint8x16_t t2_shift = vextq_u8(t2, t2, 13); // t2 << 24 - uint8x16_t t3_shift = vextq_u8(t3, t3, 12); // t3 << 32 - - // Accumulate the products - uint8x16_t cross1 = veorq_u8(t0_shift, t1_shift); - uint8x16_t cross2 = veorq_u8(t2_shift, t3_shift); - uint8x16_t mix = veorq_u8(d, cross1); - uint8x16_t r = veorq_u8(mix, cross2); - return vreinterpretq_u64_u8(r); + return crc; } -#endif // ARMv7 polyfill -// Perform a carry-less multiplication of two 64-bit integers, selected from a -// and b according to imm8, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_clmulepi64_si128 -FORCE_INLINE __m128i _mm_clmulepi64_si128(__m128i _a, __m128i _b, const int imm) +// Starting with the initial value in crc, accumulates a CRC32 value for +// unsigned 8-bit integer v. +// https://msdn.microsoft.com/en-us/library/bb514036(v=vs.100) +FORCE_INLINE uint32_t _mm_crc32_u8(uint32_t crc, uint8_t v) { - uint64x2_t a = vreinterpretq_u64_m128i(_a); - uint64x2_t b = vreinterpretq_u64_m128i(_b); - switch (imm & 0x11) { - case 0x00: - return vreinterpretq_m128i_u64( - _sse2neon_vmull_p64(vget_low_u64(a), vget_low_u64(b))); - case 0x01: - return vreinterpretq_m128i_u64( - _sse2neon_vmull_p64(vget_high_u64(a), vget_low_u64(b))); - case 0x10: - return vreinterpretq_m128i_u64( - _sse2neon_vmull_p64(vget_low_u64(a), vget_high_u64(b))); - case 0x11: - return vreinterpretq_m128i_u64( - _sse2neon_vmull_p64(vget_high_u64(a), vget_high_u64(b))); - default: - abort(); +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) + __asm__ __volatile__("crc32cb %w[c], %w[c], %w[v]\n\t" + : [c] "+r"(crc) + : [v] "r"(v)); +#else + crc ^= v; + for (int bit = 0; bit < 8; bit++) { + if (crc & 1) + crc = (crc >> 1) ^ UINT32_C(0x82f63b78); + else + crc = (crc >> 1); } +#endif + return crc; } +/* AES */ + #if !defined(__ARM_FEATURE_CRYPTO) /* clang-format off */ #define SSE2NEON_AES_DATA(w) \ @@ -6752,22 +8520,22 @@ FORCE_INLINE __m128i _mm_aesenclast_si128(__m128i a, __m128i RoundKey) { /* FIXME: optimized for NEON */ uint8_t v[4][4] = { - [0] = {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 0)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 5)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 10)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 15)]}, - [1] = {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 4)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 9)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 14)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 3)]}, - [2] = {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 8)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 13)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 2)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 7)]}, - [3] = {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 12)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 1)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 6)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 11)]}, + {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 0)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 5)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 10)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 15)]}, + {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 4)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 9)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 14)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 3)]}, + {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 8)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 13)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 2)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 7)]}, + {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 12)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 1)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 6)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 11)]}, }; for (int i = 0; i < 16; i++) vreinterpretq_nth_u8_m128i(a, i) = @@ -6833,155 +8601,134 @@ FORCE_INLINE __m128i _mm_aeskeygenassist_si128(__m128i a, const int rcon) } #endif -/* Streaming Extensions */ +/* Others */ -// Guarantees that every preceding store is globally visible before any -// subsequent store. -// https://msdn.microsoft.com/en-us/library/5h2w73d1%28v=vs.90%29.aspx -FORCE_INLINE void _mm_sfence(void) +// Perform a carry-less multiplication of two 64-bit integers, selected from a +// and b according to imm8, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_clmulepi64_si128 +FORCE_INLINE __m128i _mm_clmulepi64_si128(__m128i _a, __m128i _b, const int imm) { - __sync_synchronize(); + uint64x2_t a = vreinterpretq_u64_m128i(_a); + uint64x2_t b = vreinterpretq_u64_m128i(_b); + switch (imm & 0x11) { + case 0x00: + return vreinterpretq_m128i_u64( + _sse2neon_vmull_p64(vget_low_u64(a), vget_low_u64(b))); + case 0x01: + return vreinterpretq_m128i_u64( + _sse2neon_vmull_p64(vget_high_u64(a), vget_low_u64(b))); + case 0x10: + return vreinterpretq_m128i_u64( + _sse2neon_vmull_p64(vget_low_u64(a), vget_high_u64(b))); + case 0x11: + return vreinterpretq_m128i_u64( + _sse2neon_vmull_p64(vget_high_u64(a), vget_high_u64(b))); + default: + abort(); + } } -// Store 128-bits (composed of 4 packed single-precision (32-bit) floating- -// point elements) from a into memory using a non-temporal memory hint. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_ps -FORCE_INLINE void _mm_stream_ps(float *p, __m128 a) +FORCE_INLINE unsigned int _sse2neon_mm_get_denormals_zero_mode() { -#if __has_builtin(__builtin_nontemporal_store) - __builtin_nontemporal_store(a, (float32x4_t *) p); + union { + fpcr_bitfield field; +#if defined(__aarch64__) + uint64_t value; #else - vst1q_f32(p, vreinterpretq_f32_m128(a)); + uint32_t value; #endif -} + } r; -// Stores the data in a to the address p without polluting the caches. If the -// cache line containing address p is already in the cache, the cache will be -// updated. -// https://msdn.microsoft.com/en-us/library/ba08y07y%28v=vs.90%29.aspx -FORCE_INLINE void _mm_stream_si128(__m128i *p, __m128i a) -{ -#if __has_builtin(__builtin_nontemporal_store) - __builtin_nontemporal_store(a, p); +#if defined(__aarch64__) + asm volatile("mrs %0, FPCR" : "=r"(r.value)); /* read */ #else - vst1q_s64((int64_t *) p, vreinterpretq_s64_m128i(a)); + asm volatile("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ #endif + + return r.field.bit24 ? _MM_DENORMALS_ZERO_ON : _MM_DENORMALS_ZERO_OFF; } -// Load 128-bits of integer data from memory into dst using a non-temporal -// memory hint. mem_addr must be aligned on a 16-byte boundary or a -// general-protection exception may be generated. -// -// dst[127:0] := MEM[mem_addr+127:mem_addr] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_load_si128 -FORCE_INLINE __m128i _mm_stream_load_si128(__m128i *p) +// Count the number of bits set to 1 in unsigned 32-bit integer a, and +// return that count in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_popcnt_u32 +FORCE_INLINE int _mm_popcnt_u32(unsigned int a) { -#if __has_builtin(__builtin_nontemporal_store) - return __builtin_nontemporal_load(p); +#if defined(__aarch64__) +#if __has_builtin(__builtin_popcount) + return __builtin_popcount(a); #else - return vreinterpretq_m128i_s64(vld1q_s64((int64_t *) p)); + return (int) vaddlv_u8(vcnt_u8(vcreate_u8((uint64_t) a))); #endif -} - -// Cache line containing p is flushed and invalidated from all caches in the -// coherency domain. : -// https://msdn.microsoft.com/en-us/library/ba08y07y(v=vs.100).aspx -FORCE_INLINE void _mm_clflush(void const *p) -{ - (void) p; - // no corollary for Neon? -} +#else + uint32_t count = 0; + uint8x8_t input_val, count8x8_val; + uint16x4_t count16x4_val; + uint32x2_t count32x2_val; -// Allocate aligned blocks of memory. -// https://software.intel.com/en-us/ -// cpp-compiler-developer-guide-and-reference-allocating-and-freeing-aligned-memory-blocks -FORCE_INLINE void *_mm_malloc(size_t size, size_t align) -{ - void *ptr; - if (align == 1) - return malloc(size); - if (align == 2 || (sizeof(void *) == 8 && align == 4)) - align = sizeof(void *); - if (!posix_memalign(&ptr, align, size)) - return ptr; - return NULL; -} + input_val = vld1_u8((uint8_t *) &a); + count8x8_val = vcnt_u8(input_val); + count16x4_val = vpaddl_u8(count8x8_val); + count32x2_val = vpaddl_u16(count16x4_val); -// Free aligned memory that was allocated with _mm_malloc. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_free -FORCE_INLINE void _mm_free(void *addr) -{ - free(addr); + vst1_u32(&count, count32x2_val); + return count; +#endif } -// Starting with the initial value in crc, accumulates a CRC32 value for -// unsigned 8-bit integer v. -// https://msdn.microsoft.com/en-us/library/bb514036(v=vs.100) -FORCE_INLINE uint32_t _mm_crc32_u8(uint32_t crc, uint8_t v) +// Count the number of bits set to 1 in unsigned 64-bit integer a, and +// return that count in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_popcnt_u64 +FORCE_INLINE int64_t _mm_popcnt_u64(uint64_t a) { -#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) - __asm__ __volatile__("crc32cb %w[c], %w[c], %w[v]\n\t" - : [c] "+r"(crc) - : [v] "r"(v)); +#if defined(__aarch64__) +#if __has_builtin(__builtin_popcountll) + return __builtin_popcountll(a); #else - crc ^= v; - for (int bit = 0; bit < 8; bit++) { - if (crc & 1) - crc = (crc >> 1) ^ UINT32_C(0x82f63b78); - else - crc = (crc >> 1); - } + return (int64_t) vaddlv_u8(vcnt_u8(vcreate_u8(a))); +#endif +#else + uint64_t count = 0; + uint8x8_t input_val, count8x8_val; + uint16x4_t count16x4_val; + uint32x2_t count32x2_val; + uint64x1_t count64x1_val; + + input_val = vld1_u8((uint8_t *) &a); + count8x8_val = vcnt_u8(input_val); + count16x4_val = vpaddl_u8(count8x8_val); + count32x2_val = vpaddl_u16(count16x4_val); + count64x1_val = vpaddl_u32(count32x2_val); + vst1_u64(&count, count64x1_val); + return count; #endif - return crc; } -// Starting with the initial value in crc, accumulates a CRC32 value for -// unsigned 16-bit integer v. -// https://msdn.microsoft.com/en-us/library/bb531411(v=vs.100) -FORCE_INLINE uint32_t _mm_crc32_u16(uint32_t crc, uint16_t v) +FORCE_INLINE void _sse2neon_mm_set_denormals_zero_mode(unsigned int flag) { -#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) - __asm__ __volatile__("crc32ch %w[c], %w[c], %w[v]\n\t" - : [c] "+r"(crc) - : [v] "r"(v)); + // AArch32 Advanced SIMD arithmetic always uses the Flush-to-zero setting, + // regardless of the value of the FZ bit. + union { + fpcr_bitfield field; +#if defined(__aarch64__) + uint64_t value; #else - crc = _mm_crc32_u8(crc, v & 0xff); - crc = _mm_crc32_u8(crc, (v >> 8) & 0xff); + uint32_t value; #endif - return crc; -} + } r; -// Starting with the initial value in crc, accumulates a CRC32 value for -// unsigned 32-bit integer v. -// https://msdn.microsoft.com/en-us/library/bb531394(v=vs.100) -FORCE_INLINE uint32_t _mm_crc32_u32(uint32_t crc, uint32_t v) -{ -#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) - __asm__ __volatile__("crc32cw %w[c], %w[c], %w[v]\n\t" - : [c] "+r"(crc) - : [v] "r"(v)); +#if defined(__aarch64__) + asm volatile("mrs %0, FPCR" : "=r"(r.value)); /* read */ #else - crc = _mm_crc32_u16(crc, v & 0xffff); - crc = _mm_crc32_u16(crc, (v >> 16) & 0xffff); + asm volatile("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ #endif - return crc; -} -// Starting with the initial value in crc, accumulates a CRC32 value for -// unsigned 64-bit integer v. -// https://msdn.microsoft.com/en-us/library/bb514033(v=vs.100) -FORCE_INLINE uint64_t _mm_crc32_u64(uint64_t crc, uint64_t v) -{ -#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) - __asm__ __volatile__("crc32cx %w[c], %w[c], %x[v]\n\t" - : [c] "+r"(crc) - : [v] "r"(v)); + r.field.bit24 = (flag & _MM_DENORMALS_ZERO_MASK) == _MM_DENORMALS_ZERO_ON; + +#if defined(__aarch64__) + asm volatile("msr FPCR, %0" ::"r"(r)); /* write */ #else - crc = _mm_crc32_u32((uint32_t)(crc), v & 0xffffffff); - crc = _mm_crc32_u32((uint32_t)(crc), (v >> 32) & 0xffffffff); + asm volatile("vmsr FPSCR, %0" ::"r"(r)); /* write */ #endif - return crc; } #if defined(__GNUC__) || defined(__clang__) @@ -6993,4 +8740,4 @@ FORCE_INLINE uint64_t _mm_crc32_u64(uint64_t crc, uint64_t v) #pragma GCC pop_options #endif -#endif +#endif
\ No newline at end of file diff --git a/thirdparty/embree/common/simd/simd.h b/thirdparty/embree/common/simd/simd.h index 195506b530..34e37b08b1 100644 --- a/thirdparty/embree/common/simd/simd.h +++ b/thirdparty/embree/common/simd/simd.h @@ -6,7 +6,7 @@ #include "../math/math.h" /* include SSE wrapper classes */ -#if defined(__SSE__) +#if defined(__SSE__) || defined(__ARM_NEON) # include "sse.h" #endif diff --git a/thirdparty/embree/common/simd/sse.h b/thirdparty/embree/common/simd/sse.h index 1465fb4fb0..04d90533dd 100644 --- a/thirdparty/embree/common/simd/sse.h +++ b/thirdparty/embree/common/simd/sse.h @@ -11,7 +11,7 @@ namespace embree { -#if defined(__SSE4_1__) +#if defined(__aarch64__) || defined(__SSE4_1__) __forceinline __m128 blendv_ps(__m128 f, __m128 t, __m128 mask) { return _mm_blendv_ps(f,t,mask); } diff --git a/thirdparty/embree/common/simd/vboold4_avx.h b/thirdparty/embree/common/simd/vboold4_avx.h index 7db0d1c5c1..450bd7a4eb 100644 --- a/thirdparty/embree/common/simd/vboold4_avx.h +++ b/thirdparty/embree/common/simd/vboold4_avx.h @@ -62,7 +62,11 @@ namespace embree //////////////////////////////////////////////////////////////////////////////// __forceinline vboold(FalseTy) : v(_mm256_setzero_pd()) {} +#if !defined(__aarch64__) __forceinline vboold(TrueTy) : v(_mm256_cmp_pd(_mm256_setzero_pd(), _mm256_setzero_pd(), _CMP_EQ_OQ)) {} +#else + __forceinline vboold(TrueTy) : v(_mm256_cmpeq_pd(_mm256_setzero_pd(), _mm256_setzero_pd())) {} +#endif //////////////////////////////////////////////////////////////////////////////// /// Array Access @@ -107,9 +111,10 @@ namespace embree /// Movement/Shifting/Shuffling Functions //////////////////////////////////////////////////////////////////////////////// +#if !defined(__aarch64__) __forceinline vboold4 unpacklo(const vboold4& a, const vboold4& b) { return _mm256_unpacklo_pd(a, b); } __forceinline vboold4 unpackhi(const vboold4& a, const vboold4& b) { return _mm256_unpackhi_pd(a, b); } - +#endif #if defined(__AVX2__) template<int i0, int i1, int i2, int i3> diff --git a/thirdparty/embree/common/simd/vboolf16_avx512.h b/thirdparty/embree/common/simd/vboolf16_avx512.h index 19841dcea8..86b718f025 100644 --- a/thirdparty/embree/common/simd/vboolf16_avx512.h +++ b/thirdparty/embree/common/simd/vboolf16_avx512.h @@ -116,7 +116,7 @@ namespace embree __forceinline size_t popcnt (const vboolf16& a) { return popcnt(a.v); } //////////////////////////////////////////////////////////////////////////////// - /// Convertion Operations + /// Conversion Operations //////////////////////////////////////////////////////////////////////////////// __forceinline unsigned int toInt (const vboolf16& a) { return mm512_mask2int(a); } diff --git a/thirdparty/embree/common/simd/vboolf4_sse2.h b/thirdparty/embree/common/simd/vboolf4_sse2.h index fa84b1b6ee..9e0fdf5c6f 100644 --- a/thirdparty/embree/common/simd/vboolf4_sse2.h +++ b/thirdparty/embree/common/simd/vboolf4_sse2.h @@ -36,9 +36,11 @@ namespace embree __forceinline vboolf(__m128 input) : v(input) {} __forceinline operator const __m128&() const { return v; } + #if !defined(__EMSCRIPTEN__) __forceinline operator const __m128i() const { return _mm_castps_si128(v); } __forceinline operator const __m128d() const { return _mm_castps_pd(v); } - + #endif + __forceinline vboolf(bool a) : v(mm_lookupmask_ps[(size_t(a) << 3) | (size_t(a) << 2) | (size_t(a) << 1) | size_t(a)]) {} __forceinline vboolf(bool a, bool b) @@ -100,7 +102,7 @@ namespace embree __forceinline vboolf4 operator ==(const vboolf4& a, const vboolf4& b) { return _mm_castsi128_ps(_mm_cmpeq_epi32(a, b)); } __forceinline vboolf4 select(const vboolf4& m, const vboolf4& t, const vboolf4& f) { -#if defined(__SSE4_1__) +#if defined(__aarch64__) || defined(__SSE4_1__) return _mm_blendv_ps(f, t, m); #else return _mm_or_ps(_mm_and_ps(m, t), _mm_andnot_ps(m, f)); @@ -114,6 +116,17 @@ namespace embree __forceinline vboolf4 unpacklo(const vboolf4& a, const vboolf4& b) { return _mm_unpacklo_ps(a, b); } __forceinline vboolf4 unpackhi(const vboolf4& a, const vboolf4& b) { return _mm_unpackhi_ps(a, b); } +#if defined(__aarch64__) + template<int i0, int i1, int i2, int i3> + __forceinline vboolf4 shuffle(const vboolf4& v) { + return vreinterpretq_f32_u8(vqtbl1q_u8( vreinterpretq_u8_s32(v), _MN_SHUFFLE(i0, i1, i2, i3))); + } + + template<int i0, int i1, int i2, int i3> + __forceinline vboolf4 shuffle(const vboolf4& a, const vboolf4& b) { + return vreinterpretq_f32_u8(vqtbl2q_u8( (uint8x16x2_t){(uint8x16_t)a.v, (uint8x16_t)b.v}, _MF_SHUFFLE(i0, i1, i2, i3))); + } +#else template<int i0, int i1, int i2, int i3> __forceinline vboolf4 shuffle(const vboolf4& v) { return _mm_castsi128_ps(_mm_shuffle_epi32(v, _MM_SHUFFLE(i3, i2, i1, i0))); @@ -123,6 +136,7 @@ namespace embree __forceinline vboolf4 shuffle(const vboolf4& a, const vboolf4& b) { return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0)); } +#endif template<int i0> __forceinline vboolf4 shuffle(const vboolf4& v) { @@ -135,7 +149,7 @@ namespace embree template<> __forceinline vboolf4 shuffle<0, 1, 0, 1>(const vboolf4& v) { return _mm_castpd_ps(_mm_movedup_pd(v)); } #endif -#if defined(__SSE4_1__) +#if defined(__SSE4_1__) && !defined(__aarch64__) template<int dst, int src, int clr> __forceinline vboolf4 insert(const vboolf4& a, const vboolf4& b) { return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr); } template<int dst, int src> __forceinline vboolf4 insert(const vboolf4& a, const vboolf4& b) { return insert<dst, src, 0>(a, b); } template<int dst> __forceinline vboolf4 insert(const vboolf4& a, const bool b) { return insert<dst, 0>(a, vboolf4(b)); } @@ -157,7 +171,9 @@ namespace embree __forceinline bool none(const vboolf4& valid, const vboolf4& b) { return none(valid & b); } __forceinline size_t movemask(const vboolf4& a) { return _mm_movemask_ps(a); } -#if defined(__SSE4_2__) +#if defined(__aarch64__) + __forceinline size_t popcnt(const vboolf4& a) { return vaddvq_s32(vandq_u32(vreinterpretq_u32_f32(a.v),_mm_set1_epi32(1))); } +#elif defined(__SSE4_2__) __forceinline size_t popcnt(const vboolf4& a) { return popcnt((size_t)_mm_movemask_ps(a)); } #else __forceinline size_t popcnt(const vboolf4& a) { return bool(a[0])+bool(a[1])+bool(a[2])+bool(a[3]); } diff --git a/thirdparty/embree/common/simd/vboolf8_avx.h b/thirdparty/embree/common/simd/vboolf8_avx.h index ba77cc3c5e..18cede19c6 100644 --- a/thirdparty/embree/common/simd/vboolf8_avx.h +++ b/thirdparty/embree/common/simd/vboolf8_avx.h @@ -76,7 +76,7 @@ namespace embree //////////////////////////////////////////////////////////////////////////////// __forceinline vboolf(FalseTy) : v(_mm256_setzero_ps()) {} - __forceinline vboolf(TrueTy) : v(_mm256_cmp_ps(_mm256_setzero_ps(), _mm256_setzero_ps(), _CMP_EQ_OQ)) {} + __forceinline vboolf(TrueTy) : v(_mm256_castsi256_ps(_mm256_set1_epi32(0xFFFFFFFF))) {} //////////////////////////////////////////////////////////////////////////////// /// Array Access diff --git a/thirdparty/embree/common/simd/vdouble4_avx.h b/thirdparty/embree/common/simd/vdouble4_avx.h index 55326de7dd..208bb7ac99 100644 --- a/thirdparty/embree/common/simd/vdouble4_avx.h +++ b/thirdparty/embree/common/simd/vdouble4_avx.h @@ -189,13 +189,20 @@ namespace embree __forceinline vboold4 operator >=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd_mask(a, b, _MM_CMPINT_GE); } __forceinline vboold4 operator > (const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd_mask(a, b, _MM_CMPINT_GT); } __forceinline vboold4 operator <=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd_mask(a, b, _MM_CMPINT_LE); } -#else +#elif !defined(__aarch64__) __forceinline vboold4 operator ==(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a, b, _CMP_EQ_OQ); } __forceinline vboold4 operator !=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a, b, _CMP_NEQ_UQ); } __forceinline vboold4 operator < (const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a, b, _CMP_LT_OS); } __forceinline vboold4 operator >=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a, b, _CMP_NLT_US); } __forceinline vboold4 operator > (const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a, b, _CMP_NLE_US); } __forceinline vboold4 operator <=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a, b, _CMP_LE_OS); } +#else + __forceinline vboold4 operator ==(const vdouble4& a, const vdouble4& b) { return _mm256_cmpeq_pd(a, b); } + __forceinline vboold4 operator !=(const vdouble4& a, const vdouble4& b) { return _mm256_cmpneq_pd(a, b); } + __forceinline vboold4 operator < (const vdouble4& a, const vdouble4& b) { return _mm256_cmplt_pd(a, b); } + __forceinline vboold4 operator >=(const vdouble4& a, const vdouble4& b) { return _mm256_cmpnlt_pd(a, b); } + __forceinline vboold4 operator > (const vdouble4& a, const vdouble4& b) { return _mm256_cmpnle_pd(a, b); } + __forceinline vboold4 operator <=(const vdouble4& a, const vdouble4& b) { return _mm256_cmple_pd(a, b); } #endif __forceinline vboold4 operator ==(const vdouble4& a, double b) { return a == vdouble4(b); } diff --git a/thirdparty/embree/common/simd/vfloat16_avx512.h b/thirdparty/embree/common/simd/vfloat16_avx512.h index 9f1e2459c4..75c471cc0c 100644 --- a/thirdparty/embree/common/simd/vfloat16_avx512.h +++ b/thirdparty/embree/common/simd/vfloat16_avx512.h @@ -177,9 +177,10 @@ namespace embree __forceinline vfloat16 abs (const vfloat16& a) { return _mm512_castsi512_ps(_mm512_and_epi32(_mm512_castps_si512(a),_mm512_set1_epi32(0x7FFFFFFF))); } __forceinline vfloat16 signmsk(const vfloat16& a) { return _mm512_castsi512_ps(_mm512_and_epi32(_mm512_castps_si512(a),_mm512_set1_epi32(0x80000000))); } - __forceinline vfloat16 rcp(const vfloat16& a) { + __forceinline vfloat16 rcp(const vfloat16& a) + { const vfloat16 r = _mm512_rcp14_ps(a); - return _mm512_mul_ps(r, _mm512_fnmadd_ps(r, a, vfloat16(2.0f))); + return _mm512_fmadd_ps(r, _mm512_fnmadd_ps(a, r, vfloat16(1.0)), r); // computes r + r * (1 - a*r) } __forceinline vfloat16 sqr (const vfloat16& a) { return _mm512_mul_ps(a,a); } diff --git a/thirdparty/embree/common/simd/vfloat4_sse2.h b/thirdparty/embree/common/simd/vfloat4_sse2.h index 5215bf9730..6d7e11fe72 100644 --- a/thirdparty/embree/common/simd/vfloat4_sse2.h +++ b/thirdparty/embree/common/simd/vfloat4_sse2.h @@ -42,6 +42,11 @@ namespace embree __forceinline vfloat(float a, float b, float c, float d) : v(_mm_set_ps(d, c, b, a)) {} __forceinline explicit vfloat(const vint4& a) : v(_mm_cvtepi32_ps(a)) {} +#if defined(__aarch64__) + __forceinline explicit vfloat(const vuint4& x) { + v = vcvtq_f32_u32(vreinterpretq_u32_s32(x.v)); + } +#else __forceinline explicit vfloat(const vuint4& x) { const __m128i a = _mm_and_si128(x,_mm_set1_epi32(0x7FFFFFFF)); const __m128i b = _mm_and_si128(_mm_srai_epi32(x,31),_mm_set1_epi32(0x4F000000)); //0x4F000000 = 2^31 @@ -49,7 +54,7 @@ namespace embree const __m128 bf = _mm_castsi128_ps(b); v = _mm_add_ps(af,bf); } - +#endif //////////////////////////////////////////////////////////////////////////////// /// Constants //////////////////////////////////////////////////////////////////////////////// @@ -107,7 +112,11 @@ namespace embree #endif } -#if defined(__SSE4_1__) +#if defined(__aarch64__) + static __forceinline vfloat4 load(const char* ptr) { + return __m128(_mm_load4epi8_f32(((__m128i*)ptr))); + } +#elif defined(__SSE4_1__) static __forceinline vfloat4 load(const char* ptr) { return _mm_cvtepi32_ps(_mm_cvtepi8_epi32(_mm_loadu_si128((__m128i*)ptr))); } @@ -117,7 +126,11 @@ namespace embree } #endif -#if defined(__SSE4_1__) +#if defined(__aarch64__) + static __forceinline vfloat4 load(const unsigned char* ptr) { + return __m128(_mm_load4epu8_f32(((__m128i*)ptr))); + } +#elif defined(__SSE4_1__) static __forceinline vfloat4 load(const unsigned char* ptr) { return _mm_cvtepi32_ps(_mm_cvtepu8_epi32(_mm_loadu_si128((__m128i*)ptr))); } @@ -128,7 +141,11 @@ namespace embree } #endif -#if defined(__SSE4_1__) +#if defined(__aarch64__) + static __forceinline vfloat4 load(const short* ptr) { + return __m128(_mm_load4epi16_f32(((__m128i*)ptr))); + } +#elif defined(__SSE4_1__) static __forceinline vfloat4 load(const short* ptr) { return _mm_cvtepi32_ps(_mm_cvtepi16_epi32(_mm_loadu_si128((__m128i*)ptr))); } @@ -145,15 +162,19 @@ namespace embree static __forceinline void store_nt(void* ptr, const vfloat4& v) { #if defined (__SSE4_1__) +#if defined(__aarch64__) _mm_stream_ps((float*)ptr,v); #else + _mm_stream_ps((float*)ptr,v); +#endif +#else _mm_store_ps((float*)ptr,v); #endif } template<int scale = 4> static __forceinline vfloat4 gather(const float* ptr, const vint4& index) { -#if defined(__AVX2__) +#if defined(__AVX2__) && !defined(__aarch64__) return _mm_i32gather_ps(ptr, index, scale); #else return vfloat4( @@ -169,7 +190,7 @@ namespace embree vfloat4 r = zero; #if defined(__AVX512VL__) return _mm_mmask_i32gather_ps(r, mask, index, ptr, scale); -#elif defined(__AVX2__) +#elif defined(__AVX2__) && !defined(__aarch64__) return _mm_mask_i32gather_ps(r, ptr, index, mask, scale); #else if (likely(mask[0])) r[0] = *(float*)(((char*)ptr)+scale*index[0]); @@ -223,8 +244,8 @@ namespace embree friend __forceinline vfloat4 select(const vboolf4& m, const vfloat4& t, const vfloat4& f) { #if defined(__AVX512VL__) return _mm_mask_blend_ps(m, f, t); -#elif defined(__SSE4_1__) - return _mm_blendv_ps(f, t, m); +#elif defined(__SSE4_1__) || (defined(__aarch64__)) + return _mm_blendv_ps(f, t, m); #else return _mm_or_ps(_mm_and_ps(m, t), _mm_andnot_ps(m, f)); #endif @@ -256,18 +277,34 @@ namespace embree __forceinline vfloat4 toFloat(const vint4& a) { return vfloat4(a); } __forceinline vfloat4 operator +(const vfloat4& a) { return a; } +#if defined(__aarch64__) + __forceinline vfloat4 operator -(const vfloat4& a) { + return vnegq_f32(a); + } +#else __forceinline vfloat4 operator -(const vfloat4& a) { return _mm_xor_ps(a, _mm_castsi128_ps(_mm_set1_epi32(0x80000000))); } +#endif +#if defined(__aarch64__) + __forceinline vfloat4 abs(const vfloat4& a) { return _mm_abs_ps(a); } +#else __forceinline vfloat4 abs(const vfloat4& a) { return _mm_and_ps(a, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff))); } +#endif + #if defined(__AVX512VL__) __forceinline vfloat4 sign(const vfloat4& a) { return _mm_mask_blend_ps(_mm_cmp_ps_mask(a, vfloat4(zero), _CMP_LT_OQ), vfloat4(one), -vfloat4(one)); } #else __forceinline vfloat4 sign(const vfloat4& a) { return blendv_ps(vfloat4(one), -vfloat4(one), _mm_cmplt_ps(a, vfloat4(zero))); } #endif + __forceinline vfloat4 signmsk(const vfloat4& a) { return _mm_and_ps(a,_mm_castsi128_ps(_mm_set1_epi32(0x80000000))); } - + __forceinline vfloat4 rcp(const vfloat4& a) { +#if defined(__aarch64__) + return vfloat4(vdivq_f32(vdupq_n_f32(1.0f),a.v)); +#else + #if defined(__AVX512VL__) const vfloat4 r = _mm_rcp14_ps(a); #else @@ -275,30 +312,39 @@ namespace embree #endif #if defined(__AVX2__) - return _mm_mul_ps(r,_mm_fnmadd_ps(r, a, vfloat4(2.0f))); + return _mm_fmadd_ps(r, _mm_fnmadd_ps(a, r, vfloat4(1.0f)), r); // computes r + r * (1 - a * r) #else - return _mm_mul_ps(r,_mm_sub_ps(vfloat4(2.0f), _mm_mul_ps(r, a))); + return _mm_add_ps(r,_mm_mul_ps(r, _mm_sub_ps(vfloat4(1.0f), _mm_mul_ps(a, r)))); // computes r + r * (1 - a * r) #endif + +#endif //defined(__aarch64__) } __forceinline vfloat4 sqr (const vfloat4& a) { return _mm_mul_ps(a,a); } __forceinline vfloat4 sqrt(const vfloat4& a) { return _mm_sqrt_ps(a); } __forceinline vfloat4 rsqrt(const vfloat4& a) { +#if defined(__aarch64__) + vfloat4 r = _mm_rsqrt_ps(a); + r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a, r), r)); + r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a, r), r)); + r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a, r), r)); + return r; +#else + #if defined(__AVX512VL__) vfloat4 r = _mm_rsqrt14_ps(a); #else vfloat4 r = _mm_rsqrt_ps(a); #endif -#if defined(__ARM_NEON) - r = _mm_fmadd_ps(_mm_set1_ps(1.5f), r, _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); - r = _mm_fmadd_ps(_mm_set1_ps(1.5f), r, _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); -#elif defined(__AVX2__) +#if defined(__AVX2__) r = _mm_fmadd_ps(_mm_set1_ps(1.5f), r, _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); #else r = _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.5f), r), _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); #endif + +#endif return r; } @@ -344,7 +390,8 @@ namespace embree __forceinline vfloat4 max(const vfloat4& a, float b) { return _mm_max_ps(a,vfloat4(b)); } __forceinline vfloat4 max(float a, const vfloat4& b) { return _mm_max_ps(vfloat4(a),b); } -#if defined(__SSE4_1__) +#if defined(__SSE4_1__) || defined(__aarch64__) + __forceinline vfloat4 mini(const vfloat4& a, const vfloat4& b) { const vint4 ai = _mm_castps_si128(a); const vint4 bi = _mm_castps_si128(b); @@ -393,9 +440,10 @@ namespace embree __forceinline vfloat4 nmsub(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fnmsub_ps(a,b,c); } #else __forceinline vfloat4 madd (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return a*b+c; } - __forceinline vfloat4 msub (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return a*b-c; } __forceinline vfloat4 nmadd(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return -a*b+c;} __forceinline vfloat4 nmsub(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return -a*b-c; } + __forceinline vfloat4 msub (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return a*b-c; } + #endif //////////////////////////////////////////////////////////////////////////////// @@ -429,8 +477,13 @@ namespace embree __forceinline vboolf4 operator ==(const vfloat4& a, const vfloat4& b) { return _mm_cmpeq_ps (a, b); } __forceinline vboolf4 operator !=(const vfloat4& a, const vfloat4& b) { return _mm_cmpneq_ps(a, b); } __forceinline vboolf4 operator < (const vfloat4& a, const vfloat4& b) { return _mm_cmplt_ps (a, b); } +#if defined(__aarch64__) + __forceinline vboolf4 operator >=(const vfloat4& a, const vfloat4& b) { return _mm_cmpge_ps (a, b); } + __forceinline vboolf4 operator > (const vfloat4& a, const vfloat4& b) { return _mm_cmpgt_ps (a, b); } +#else __forceinline vboolf4 operator >=(const vfloat4& a, const vfloat4& b) { return _mm_cmpnlt_ps(a, b); } __forceinline vboolf4 operator > (const vfloat4& a, const vfloat4& b) { return _mm_cmpnle_ps(a, b); } +#endif __forceinline vboolf4 operator <=(const vfloat4& a, const vfloat4& b) { return _mm_cmple_ps (a, b); } #endif @@ -484,7 +537,7 @@ namespace embree return select(vboolf4(mask), t, f); #endif } - + __forceinline vfloat4 lerp(const vfloat4& a, const vfloat4& b, const vfloat4& t) { return madd(t,b-a,a); } @@ -506,10 +559,10 @@ namespace embree //////////////////////////////////////////////////////////////////////////////// #if defined(__aarch64__) - __forceinline vfloat4 floor(const vfloat4& a) { return vrndmq_f32(a.v); } - __forceinline vfloat4 ceil (const vfloat4& a) { return vrndpq_f32(a.v); } - __forceinline vfloat4 trunc(const vfloat4& a) { return vrndq_f32(a.v); } - __forceinline vfloat4 round(const vfloat4& a) { return vrndnq_f32(a.v); } + __forceinline vfloat4 floor(const vfloat4& a) { return vrndmq_f32(a.v); } // towards -inf + __forceinline vfloat4 ceil (const vfloat4& a) { return vrndpq_f32(a.v); } // toward +inf + __forceinline vfloat4 trunc(const vfloat4& a) { return vrndq_f32(a.v); } // towards 0 + __forceinline vfloat4 round(const vfloat4& a) { return vrndnq_f32(a.v); } // to nearest, ties to even. NOTE(LTE): arm clang uses vrndnq, old gcc uses vrndqn? #elif defined (__SSE4_1__) __forceinline vfloat4 floor(const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF ); } __forceinline vfloat4 ceil (const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_POS_INF ); } @@ -524,7 +577,9 @@ namespace embree __forceinline vfloat4 frac(const vfloat4& a) { return a-floor(a); } __forceinline vint4 floori(const vfloat4& a) { -#if defined(__SSE4_1__) +#if defined(__aarch64__) + return vcvtq_s32_f32(floor(a)); +#elif defined(__SSE4_1__) return vint4(floor(a)); #else return vint4(a-vfloat4(0.5f)); @@ -538,6 +593,16 @@ namespace embree __forceinline vfloat4 unpacklo(const vfloat4& a, const vfloat4& b) { return _mm_unpacklo_ps(a, b); } __forceinline vfloat4 unpackhi(const vfloat4& a, const vfloat4& b) { return _mm_unpackhi_ps(a, b); } +#if defined(__aarch64__) + template<int i0, int i1, int i2, int i3> + __forceinline vfloat4 shuffle(const vfloat4& v) { + return vreinterpretq_f32_u8(vqtbl1q_u8( (uint8x16_t)v.v, _MN_SHUFFLE(i0, i1, i2, i3))); + } + template<int i0, int i1, int i2, int i3> + __forceinline vfloat4 shuffle(const vfloat4& a, const vfloat4& b) { + return vreinterpretq_f32_u8(vqtbl2q_u8( (uint8x16x2_t){(uint8x16_t)a.v, (uint8x16_t)b.v}, _MF_SHUFFLE(i0, i1, i2, i3))); + } +#else template<int i0, int i1, int i2, int i3> __forceinline vfloat4 shuffle(const vfloat4& v) { return _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(v), _MM_SHUFFLE(i3, i2, i1, i0))); @@ -547,8 +612,9 @@ namespace embree __forceinline vfloat4 shuffle(const vfloat4& a, const vfloat4& b) { return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0)); } +#endif -#if defined(__SSE3__) +#if defined(__SSE3__) && !defined(__aarch64__) template<> __forceinline vfloat4 shuffle<0, 0, 2, 2>(const vfloat4& v) { return _mm_moveldup_ps(v); } template<> __forceinline vfloat4 shuffle<1, 1, 3, 3>(const vfloat4& v) { return _mm_movehdup_ps(v); } template<> __forceinline vfloat4 shuffle<0, 1, 0, 1>(const vfloat4& v) { return _mm_castpd_ps(_mm_movedup_pd(_mm_castps_pd(v))); } @@ -559,10 +625,14 @@ namespace embree return shuffle<i,i,i,i>(v); } +#if defined(__aarch64__) + template<int i> __forceinline float extract(const vfloat4& a) { return a[i]; } +#else template<int i> __forceinline float extract (const vfloat4& a) { return _mm_cvtss_f32(shuffle<i>(a)); } template<> __forceinline float extract<0>(const vfloat4& a) { return _mm_cvtss_f32(a); } +#endif -#if defined (__SSE4_1__) +#if defined (__SSE4_1__) && !defined(__aarch64__) template<int dst, int src, int clr> __forceinline vfloat4 insert(const vfloat4& a, const vfloat4& b) { return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr); } template<int dst, int src> __forceinline vfloat4 insert(const vfloat4& a, const vfloat4& b) { return insert<dst, src, 0>(a, b); } template<int dst> __forceinline vfloat4 insert(const vfloat4& a, const float b) { return insert<dst, 0>(a, _mm_set_ss(b)); } @@ -664,14 +734,25 @@ namespace embree //////////////////////////////////////////////////////////////////////////////// /// Reductions //////////////////////////////////////////////////////////////////////////////// - +#if defined(__aarch64__) + __forceinline vfloat4 vreduce_min(const vfloat4& v) { float h = vminvq_f32(v); return vdupq_n_f32(h); } + __forceinline vfloat4 vreduce_max(const vfloat4& v) { float h = vmaxvq_f32(v); return vdupq_n_f32(h); } + __forceinline vfloat4 vreduce_add(const vfloat4& v) { float h = vaddvq_f32(v); return vdupq_n_f32(h); } +#else __forceinline vfloat4 vreduce_min(const vfloat4& v) { vfloat4 h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); } __forceinline vfloat4 vreduce_max(const vfloat4& v) { vfloat4 h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); } __forceinline vfloat4 vreduce_add(const vfloat4& v) { vfloat4 h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; } +#endif +#if defined(__aarch64__) + __forceinline float reduce_min(const vfloat4& v) { return vminvq_f32(v); } + __forceinline float reduce_max(const vfloat4& v) { return vmaxvq_f32(v); } + __forceinline float reduce_add(const vfloat4& v) { return vaddvq_f32(v); } +#else __forceinline float reduce_min(const vfloat4& v) { return _mm_cvtss_f32(vreduce_min(v)); } __forceinline float reduce_max(const vfloat4& v) { return _mm_cvtss_f32(vreduce_max(v)); } __forceinline float reduce_add(const vfloat4& v) { return _mm_cvtss_f32(vreduce_add(v)); } +#endif __forceinline size_t select_min(const vboolf4& valid, const vfloat4& v) { @@ -687,7 +768,7 @@ namespace embree } //////////////////////////////////////////////////////////////////////////////// - /// Euclidian Space Operators + /// Euclidean Space Operators //////////////////////////////////////////////////////////////////////////////// __forceinline float dot(const vfloat4& a, const vfloat4& b) { diff --git a/thirdparty/embree/common/simd/vfloat8_avx.h b/thirdparty/embree/common/simd/vfloat8_avx.h index 13446454e8..b09d5e641d 100644 --- a/thirdparty/embree/common/simd/vfloat8_avx.h +++ b/thirdparty/embree/common/simd/vfloat8_avx.h @@ -107,11 +107,11 @@ namespace embree static __forceinline void store (const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_mask_store_ps ((float*)ptr,mask,v); } static __forceinline void storeu(const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_mask_storeu_ps((float*)ptr,mask,v); } #else - static __forceinline vfloat8 load (const vboolf8& mask, const void* ptr) { return _mm256_maskload_ps((float*)ptr,(__m256i)mask); } - static __forceinline vfloat8 loadu(const vboolf8& mask, const void* ptr) { return _mm256_maskload_ps((float*)ptr,(__m256i)mask); } + static __forceinline vfloat8 load (const vboolf8& mask, const void* ptr) { return _mm256_maskload_ps((float*)ptr,_mm256_castps_si256(mask.v)); } + static __forceinline vfloat8 loadu(const vboolf8& mask, const void* ptr) { return _mm256_maskload_ps((float*)ptr,_mm256_castps_si256(mask.v)); } - static __forceinline void store (const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,v); } - static __forceinline void storeu(const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,v); } + static __forceinline void store (const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_maskstore_ps((float*)ptr,_mm256_castps_si256(mask.v),v); } + static __forceinline void storeu(const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_maskstore_ps((float*)ptr,_mm256_castps_si256(mask.v),v); } #endif #if defined(__AVX2__) @@ -126,7 +126,7 @@ namespace embree template<int scale = 4> static __forceinline vfloat8 gather(const float* ptr, const vint8& index) { -#if defined(__AVX2__) +#if defined(__AVX2__) && !defined(__aarch64__) return _mm256_i32gather_ps(ptr, index ,scale); #else return vfloat8( @@ -146,7 +146,7 @@ namespace embree vfloat8 r = zero; #if defined(__AVX512VL__) return _mm256_mmask_i32gather_ps(r, mask, index, ptr, scale); -#elif defined(__AVX2__) +#elif defined(__AVX2__) && !defined(__aarch64__) return _mm256_mask_i32gather_ps(r, ptr, index, mask, scale); #else if (likely(mask[0])) r[0] = *(float*)(((char*)ptr)+scale*index[0]); @@ -215,20 +215,52 @@ namespace embree __forceinline vfloat8 toFloat(const vint8& a) { return vfloat8(a); } __forceinline vfloat8 operator +(const vfloat8& a) { return a; } +#if !defined(__aarch64__) __forceinline vfloat8 operator -(const vfloat8& a) { const __m256 mask = _mm256_castsi256_ps(_mm256_set1_epi32(0x80000000)); return _mm256_xor_ps(a, mask); } +#else + __forceinline vfloat8 operator -(const vfloat8& a) { + __m256 res; + res.lo = vnegq_f32(a.v.lo); + res.hi = vnegq_f32(a.v.hi); + return res; +} +#endif + +#if !defined(__aarch64__) __forceinline vfloat8 abs(const vfloat8& a) { const __m256 mask = _mm256_castsi256_ps(_mm256_set1_epi32(0x7fffffff)); return _mm256_and_ps(a, mask); } +#else +__forceinline vfloat8 abs(const vfloat8& a) { + __m256 res; + res.lo = vabsq_f32(a.v.lo); + res.hi = vabsq_f32(a.v.hi); + return res; +} +#endif + +#if !defined(__aarch64__) __forceinline vfloat8 sign (const vfloat8& a) { return _mm256_blendv_ps(vfloat8(one), -vfloat8(one), _mm256_cmp_ps(a, vfloat8(zero), _CMP_NGE_UQ)); } +#else + __forceinline vfloat8 sign (const vfloat8& a) { return _mm256_blendv_ps(vfloat8(one), -vfloat8(one), _mm256_cmplt_ps(a, vfloat8(zero))); } +#endif __forceinline vfloat8 signmsk(const vfloat8& a) { return _mm256_and_ps(a,_mm256_castsi256_ps(_mm256_set1_epi32(0x80000000))); } static __forceinline vfloat8 rcp(const vfloat8& a) { +#if defined(__aarch64__) + vfloat8 ret; + const float32x4_t one = vdupq_n_f32(1.0f); + ret.v.lo = vdivq_f32(one, a.v.lo); + ret.v.hi = vdivq_f32(one, a.v.hi); + return ret; +#endif + #if defined(__AVX512VL__) const vfloat8 r = _mm256_rcp14_ps(a); #else @@ -236,9 +268,12 @@ namespace embree #endif #if defined(__AVX2__) - return _mm256_mul_ps(r, _mm256_fnmadd_ps(r, a, vfloat8(2.0f))); + // First, compute 1 - a * r (which will be very close to 0) + const vfloat8 h_n = _mm256_fnmadd_ps(a, r, vfloat8(1.0f)); + // Then compute r + r * h_n + return _mm256_fmadd_ps(r, h_n, r); #else - return _mm256_mul_ps(r, _mm256_sub_ps(vfloat8(2.0f), _mm256_mul_ps(r, a))); + return _mm256_add_ps(r,_mm256_mul_ps(r, _mm256_sub_ps(vfloat8(1.0f), _mm256_mul_ps(a, r)))); // computes r + r * (1 - a * r) #endif } __forceinline vfloat8 sqr (const vfloat8& a) { return _mm256_mul_ps(a,a); } @@ -384,7 +419,7 @@ namespace embree static __forceinline vfloat8 select(const vboolf8& m, const vfloat8& t, const vfloat8& f) { return _mm256_mask_blend_ps(m, f, t); } -#else +#elif !defined(__aarch64__) static __forceinline vboolf8 operator ==(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_EQ_OQ); } static __forceinline vboolf8 operator !=(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_NEQ_UQ); } static __forceinline vboolf8 operator < (const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_LT_OS); } @@ -395,6 +430,18 @@ namespace embree static __forceinline vfloat8 select(const vboolf8& m, const vfloat8& t, const vfloat8& f) { return _mm256_blendv_ps(f, t, m); } +#else + static __forceinline vboolf8 operator ==(const vfloat8& a, const vfloat8& b) { return _mm256_cmpeq_ps(a, b); } + static __forceinline vboolf8 operator !=(const vfloat8& a, const vfloat8& b) { return _mm256_cmpneq_ps(a, b); } + static __forceinline vboolf8 operator < (const vfloat8& a, const vfloat8& b) { return _mm256_cmplt_ps(a, b); } + static __forceinline vboolf8 operator >=(const vfloat8& a, const vfloat8& b) { return _mm256_cmpge_ps(a, b); } + static __forceinline vboolf8 operator > (const vfloat8& a, const vfloat8& b) { return _mm256_cmpgt_ps(a, b); } + static __forceinline vboolf8 operator <=(const vfloat8& a, const vfloat8& b) { return _mm256_cmple_ps(a, b); } + + static __forceinline vfloat8 select(const vboolf8& m, const vfloat8& t, const vfloat8& f) { + return _mm256_blendv_ps(f, t, m); + } + #endif template<int mask> @@ -463,10 +510,17 @@ namespace embree /// Rounding Functions //////////////////////////////////////////////////////////////////////////////// +#if !defined(__aarch64__) __forceinline vfloat8 floor(const vfloat8& a) { return _mm256_round_ps(a, _MM_FROUND_TO_NEG_INF ); } __forceinline vfloat8 ceil (const vfloat8& a) { return _mm256_round_ps(a, _MM_FROUND_TO_POS_INF ); } __forceinline vfloat8 trunc(const vfloat8& a) { return _mm256_round_ps(a, _MM_FROUND_TO_ZERO ); } __forceinline vfloat8 round(const vfloat8& a) { return _mm256_round_ps(a, _MM_FROUND_TO_NEAREST_INT); } +#else + __forceinline vfloat8 floor(const vfloat8& a) { return _mm256_floor_ps(a); } + __forceinline vfloat8 ceil (const vfloat8& a) { return _mm256_ceil_ps(a); } +#endif + + __forceinline vfloat8 frac (const vfloat8& a) { return a-floor(a); } //////////////////////////////////////////////////////////////////////////////// @@ -501,9 +555,11 @@ namespace embree return _mm256_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0)); } +#if !defined(__aarch64__) template<> __forceinline vfloat8 shuffle<0, 0, 2, 2>(const vfloat8& v) { return _mm256_moveldup_ps(v); } template<> __forceinline vfloat8 shuffle<1, 1, 3, 3>(const vfloat8& v) { return _mm256_movehdup_ps(v); } template<> __forceinline vfloat8 shuffle<0, 1, 0, 1>(const vfloat8& v) { return _mm256_castpd_ps(_mm256_movedup_pd(_mm256_castps_pd(v))); } +#endif __forceinline vfloat8 broadcast(const float* ptr) { return _mm256_broadcast_ss(ptr); } template<size_t i> __forceinline vfloat8 insert4(const vfloat8& a, const vfloat4& b) { return _mm256_insertf128_ps(a, b, i); } @@ -512,7 +568,7 @@ namespace embree __forceinline float toScalar(const vfloat8& v) { return _mm_cvtss_f32(_mm256_castps256_ps128(v)); } -#if defined (__AVX2__) +#if defined (__AVX2__) && !defined(__aarch64__) static __forceinline vfloat8 permute(const vfloat8& a, const __m256i& index) { return _mm256_permutevar8x32_ps(a, index); } @@ -609,7 +665,7 @@ namespace embree //////////////////////////////////////////////////////////////////////////////// /// Reductions //////////////////////////////////////////////////////////////////////////////// - +#if !defined(__aarch64__) __forceinline vfloat8 vreduce_min2(const vfloat8& v) { return min(v,shuffle<1,0,3,2>(v)); } __forceinline vfloat8 vreduce_min4(const vfloat8& v) { vfloat8 v1 = vreduce_min2(v); return min(v1,shuffle<2,3,0,1>(v1)); } __forceinline vfloat8 vreduce_min (const vfloat8& v) { vfloat8 v1 = vreduce_min4(v); return min(v1,shuffle4<1,0>(v1)); } @@ -625,7 +681,14 @@ namespace embree __forceinline float reduce_min(const vfloat8& v) { return toScalar(vreduce_min(v)); } __forceinline float reduce_max(const vfloat8& v) { return toScalar(vreduce_max(v)); } __forceinline float reduce_add(const vfloat8& v) { return toScalar(vreduce_add(v)); } +#else + __forceinline float reduce_min(const vfloat8& v) { return vminvq_f32(_mm_min_ps(v.v.lo,v.v.hi)); } + __forceinline float reduce_max(const vfloat8& v) { return vmaxvq_f32(_mm_max_ps(v.v.lo,v.v.hi)); } + __forceinline vfloat8 vreduce_min(const vfloat8& v) { return vfloat8(reduce_min(v)); } + __forceinline vfloat8 vreduce_max(const vfloat8& v) { return vfloat8(reduce_max(v)); } + __forceinline float reduce_add(const vfloat8& v) { return vaddvq_f32(_mm_add_ps(v.v.lo,v.v.hi)); } +#endif __forceinline size_t select_min(const vboolf8& valid, const vfloat8& v) { const vfloat8 a = select(valid,v,vfloat8(pos_inf)); @@ -642,7 +705,7 @@ namespace embree //////////////////////////////////////////////////////////////////////////////// - /// Euclidian Space Operators (pairs of Vec3fa's) + /// Euclidean Space Operators (pairs of Vec3fa's) //////////////////////////////////////////////////////////////////////////////// //__forceinline vfloat8 dot(const vfloat8& a, const vfloat8& b) { diff --git a/thirdparty/embree/common/simd/vint4_sse2.h b/thirdparty/embree/common/simd/vint4_sse2.h index 9814d5c71c..eea03a771e 100644 --- a/thirdparty/embree/common/simd/vint4_sse2.h +++ b/thirdparty/embree/common/simd/vint4_sse2.h @@ -106,7 +106,14 @@ namespace embree #endif -#if defined(__SSE4_1__) +#if defined(__aarch64__) + static __forceinline vint4 load(const unsigned char* ptr) { + return _mm_load4epu8_epi32(((__m128i*)ptr)); + } + static __forceinline vint4 loadu(const unsigned char* ptr) { + return _mm_load4epu8_epi32(((__m128i*)ptr)); + } +#elif defined(__SSE4_1__) static __forceinline vint4 load(const unsigned char* ptr) { return _mm_cvtepu8_epi32(_mm_loadl_epi64((__m128i*)ptr)); } @@ -127,7 +134,9 @@ namespace embree #endif static __forceinline vint4 load(const unsigned short* ptr) { -#if defined (__SSE4_1__) +#if defined(__aarch64__) + return __m128i(vmovl_u16(vld1_u16(ptr))); +#elif defined (__SSE4_1__) return _mm_cvtepu16_epi32(_mm_loadu_si128((__m128i*)ptr)); #else return vint4(ptr[0],ptr[1],ptr[2],ptr[3]); @@ -135,7 +144,12 @@ namespace embree } static __forceinline void store(unsigned char* ptr, const vint4& v) { -#if defined(__SSE4_1__) +#if defined(__aarch64__) + int32x4_t x = v; + uint16x4_t y = vqmovn_u32(uint32x4_t(x)); + uint8x8_t z = vqmovn_u16(vcombine_u16(y, y)); + vst1_lane_u32((uint32_t *)ptr,uint32x2_t(z), 0); +#elif defined(__SSE4_1__) __m128i x = v; x = _mm_packus_epi32(x, x); x = _mm_packus_epi16(x, x); @@ -147,20 +161,26 @@ namespace embree } static __forceinline void store(unsigned short* ptr, const vint4& v) { +#if defined(__aarch64__) + uint32x4_t x = uint32x4_t(v.v); + uint16x4_t y = vqmovn_u32(x); + vst1_u16(ptr, y); +#else for (size_t i=0;i<4;i++) ptr[i] = (unsigned short)v[i]; +#endif } static __forceinline vint4 load_nt(void* ptr) { -#if defined(__SSE4_1__) - return _mm_stream_load_si128((__m128i*)ptr); +#if defined(__aarch64__) || defined(__SSE4_1__) + return _mm_stream_load_si128((__m128i*)ptr); #else return _mm_load_si128((__m128i*)ptr); #endif } static __forceinline void store_nt(void* ptr, const vint4& v) { -#if defined(__SSE4_1__) +#if !defined(__aarch64__) && defined(__SSE4_1__) _mm_stream_ps((float*)ptr, _mm_castsi128_ps(v)); #else _mm_store_si128((__m128i*)ptr,v); @@ -169,7 +189,7 @@ namespace embree template<int scale = 4> static __forceinline vint4 gather(const int* ptr, const vint4& index) { -#if defined(__AVX2__) +#if defined(__AVX2__) && !defined(__aarch64__) return _mm_i32gather_epi32(ptr, index, scale); #else return vint4( @@ -185,7 +205,7 @@ namespace embree vint4 r = zero; #if defined(__AVX512VL__) return _mm_mmask_i32gather_epi32(r, mask, index, ptr, scale); -#elif defined(__AVX2__) +#elif defined(__AVX2__) && !defined(__aarch64__) return _mm_mask_i32gather_epi32(r, ptr, index, mask, scale); #else if (likely(mask[0])) r[0] = *(int*)(((char*)ptr)+scale*index[0]); @@ -222,7 +242,7 @@ namespace embree #endif } -#if defined(__x86_64__) +#if defined(__x86_64__) || defined(__aarch64__) static __forceinline vint4 broadcast64(long long a) { return _mm_set1_epi64x(a); } #endif @@ -236,6 +256,8 @@ namespace embree friend __forceinline vint4 select(const vboolf4& m, const vint4& t, const vint4& f) { #if defined(__AVX512VL__) return _mm_mask_blend_epi32(m, (__m128i)f, (__m128i)t); +#elif defined(__aarch64__) + return _mm_castps_si128(_mm_blendv_ps((__m128)f.v,(__m128) t.v, (__m128)m.v)); #elif defined(__SSE4_1__) return _mm_castps_si128(_mm_blendv_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), m)); #else @@ -256,7 +278,9 @@ namespace embree __forceinline vint4 operator +(const vint4& a) { return a; } __forceinline vint4 operator -(const vint4& a) { return _mm_sub_epi32(_mm_setzero_si128(), a); } -#if defined(__SSSE3__) +#if defined(__aarch64__) + __forceinline vint4 abs(const vint4& a) { return vabsq_s32(a.v); } +#elif defined(__SSSE3__) __forceinline vint4 abs(const vint4& a) { return _mm_abs_epi32(a); } #endif @@ -272,7 +296,7 @@ namespace embree __forceinline vint4 operator -(const vint4& a, int b) { return a - vint4(b); } __forceinline vint4 operator -(int a, const vint4& b) { return vint4(a) - b; } -#if defined(__SSE4_1__) +#if (defined(__aarch64__)) || defined(__SSE4_1__) __forceinline vint4 operator *(const vint4& a, const vint4& b) { return _mm_mullo_epi32(a, b); } #else __forceinline vint4 operator *(const vint4& a, const vint4& b) { return vint4(a[0]*b[0],a[1]*b[1],a[2]*b[2],a[3]*b[3]); } @@ -292,8 +316,8 @@ namespace embree __forceinline vint4 operator ^(const vint4& a, int b) { return a ^ vint4(b); } __forceinline vint4 operator ^(int a, const vint4& b) { return vint4(a) ^ b; } - __forceinline vint4 operator <<(const vint4& a, int n) { return _mm_slli_epi32(a, n); } - __forceinline vint4 operator >>(const vint4& a, int n) { return _mm_srai_epi32(a, n); } + __forceinline vint4 operator <<(const vint4& a, const int n) { return _mm_slli_epi32(a, n); } + __forceinline vint4 operator >>(const vint4& a, const int n) { return _mm_srai_epi32(a, n); } __forceinline vint4 sll (const vint4& a, int b) { return _mm_slli_epi32(a, b); } __forceinline vint4 sra (const vint4& a, int b) { return _mm_srai_epi32(a, b); } @@ -309,7 +333,7 @@ namespace embree __forceinline vint4& operator -=(vint4& a, const vint4& b) { return a = a - b; } __forceinline vint4& operator -=(vint4& a, int b) { return a = a - b; } -#if defined(__SSE4_1__) +#if (defined(__aarch64__)) || defined(__SSE4_1__) __forceinline vint4& operator *=(vint4& a, const vint4& b) { return a = a * b; } __forceinline vint4& operator *=(vint4& a, int b) { return a = a * b; } #endif @@ -393,7 +417,7 @@ namespace embree #endif } -#if defined(__SSE4_1__) +#if defined(__aarch64__) || defined(__SSE4_1__) __forceinline vint4 min(const vint4& a, const vint4& b) { return _mm_min_epi32(a, b); } __forceinline vint4 max(const vint4& a, const vint4& b) { return _mm_max_epi32(a, b); } @@ -417,6 +441,16 @@ namespace embree __forceinline vint4 unpacklo(const vint4& a, const vint4& b) { return _mm_castps_si128(_mm_unpacklo_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b))); } __forceinline vint4 unpackhi(const vint4& a, const vint4& b) { return _mm_castps_si128(_mm_unpackhi_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b))); } +#if defined(__aarch64__) + template<int i0, int i1, int i2, int i3> + __forceinline vint4 shuffle(const vint4& v) { + return vreinterpretq_s32_u8(vqtbl1q_u8( (uint8x16_t)v.v, _MN_SHUFFLE(i0, i1, i2, i3))); + } + template<int i0, int i1, int i2, int i3> + __forceinline vint4 shuffle(const vint4& a, const vint4& b) { + return vreinterpretq_s32_u8(vqtbl2q_u8( (uint8x16x2_t){(uint8x16_t)a.v, (uint8x16_t)b.v}, _MF_SHUFFLE(i0, i1, i2, i3))); + } +#else template<int i0, int i1, int i2, int i3> __forceinline vint4 shuffle(const vint4& v) { return _mm_shuffle_epi32(v, _MM_SHUFFLE(i3, i2, i1, i0)); @@ -426,7 +460,7 @@ namespace embree __forceinline vint4 shuffle(const vint4& a, const vint4& b) { return _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), _MM_SHUFFLE(i3, i2, i1, i0))); } - +#endif #if defined(__SSE3__) template<> __forceinline vint4 shuffle<0, 0, 2, 2>(const vint4& v) { return _mm_castps_si128(_mm_moveldup_ps(_mm_castsi128_ps(v))); } template<> __forceinline vint4 shuffle<1, 1, 3, 3>(const vint4& v) { return _mm_castps_si128(_mm_movehdup_ps(_mm_castsi128_ps(v))); } @@ -438,7 +472,7 @@ namespace embree return shuffle<i,i,i,i>(v); } -#if defined(__SSE4_1__) +#if defined(__SSE4_1__) && !defined(__aarch64__) template<int src> __forceinline int extract(const vint4& b) { return _mm_extract_epi32(b, src); } template<int dst> __forceinline vint4 insert(const vint4& a, const int b) { return _mm_insert_epi32(a, b, dst); } #else @@ -446,18 +480,27 @@ namespace embree template<int dst> __forceinline vint4 insert(const vint4& a, int b) { vint4 c = a; c[dst&3] = b; return c; } #endif - template<> __forceinline int extract<0>(const vint4& b) { return _mm_cvtsi128_si32(b); } - + __forceinline int toScalar(const vint4& v) { return _mm_cvtsi128_si32(v); } - - __forceinline size_t toSizeT(const vint4& v) { + +#if defined(__aarch64__) + __forceinline size_t toSizeT(const vint4& v) { + uint64x2_t x = uint64x2_t(v.v); + return x[0]; + } +#else +__forceinline size_t toSizeT(const vint4& v) { #if defined(__WIN32__) && !defined(__X86_64__) // win32 workaround return toScalar(v); +#elif defined(__ARM_NEON) + // FIXME(LTE): Do we need a swap(i.e. use lane 1)? + return vgetq_lane_u64(*(reinterpret_cast<const uint64x2_t *>(&v)), 0); #else return _mm_cvtsi128_si64(v); #endif } +#endif #if defined(__AVX512VL__) @@ -475,7 +518,17 @@ namespace embree /// Reductions //////////////////////////////////////////////////////////////////////////////// -#if defined(__SSE4_1__) +#if defined(__aarch64__) || defined(__SSE4_1__) + +#if defined(__aarch64__) + __forceinline vint4 vreduce_min(const vint4& v) { int h = vminvq_s32(v); return vdupq_n_s32(h); } + __forceinline vint4 vreduce_max(const vint4& v) { int h = vmaxvq_s32(v); return vdupq_n_s32(h); } + __forceinline vint4 vreduce_add(const vint4& v) { int h = vaddvq_s32(v); return vdupq_n_s32(h); } + + __forceinline int reduce_min(const vint4& v) { return vminvq_s32(v); } + __forceinline int reduce_max(const vint4& v) { return vmaxvq_s32(v); } + __forceinline int reduce_add(const vint4& v) { return vaddvq_s32(v); } +#else __forceinline vint4 vreduce_min(const vint4& v) { vint4 h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); } __forceinline vint4 vreduce_max(const vint4& v) { vint4 h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); } __forceinline vint4 vreduce_add(const vint4& v) { vint4 h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; } @@ -483,6 +536,7 @@ namespace embree __forceinline int reduce_min(const vint4& v) { return toScalar(vreduce_min(v)); } __forceinline int reduce_max(const vint4& v) { return toScalar(vreduce_max(v)); } __forceinline int reduce_add(const vint4& v) { return toScalar(vreduce_add(v)); } +#endif __forceinline size_t select_min(const vint4& v) { return bsf(movemask(v == vreduce_min(v))); } __forceinline size_t select_max(const vint4& v) { return bsf(movemask(v == vreduce_max(v))); } @@ -502,7 +556,7 @@ namespace embree /// Sorting networks //////////////////////////////////////////////////////////////////////////////// -#if defined(__SSE4_1__) +#if (defined(__aarch64__)) || defined(__SSE4_1__) __forceinline vint4 usort_ascending(const vint4& v) { diff --git a/thirdparty/embree/common/simd/vint8_avx.h b/thirdparty/embree/common/simd/vint8_avx.h index f43e9a8c22..48f5a9b203 100644 --- a/thirdparty/embree/common/simd/vint8_avx.h +++ b/thirdparty/embree/common/simd/vint8_avx.h @@ -79,8 +79,8 @@ namespace embree static __forceinline void store (void* ptr, const vint8& f) { _mm256_store_ps((float*)ptr,_mm256_castsi256_ps(f)); } static __forceinline void storeu(void* ptr, const vint8& f) { _mm256_storeu_ps((float*)ptr,_mm256_castsi256_ps(f)); } - static __forceinline void store (const vboolf8& mask, void* ptr, const vint8& f) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,_mm256_castsi256_ps(f)); } - static __forceinline void storeu(const vboolf8& mask, void* ptr, const vint8& f) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,_mm256_castsi256_ps(f)); } + static __forceinline void store (const vboolf8& mask, void* ptr, const vint8& f) { _mm256_maskstore_ps((float*)ptr,_mm256_castps_si256(mask.v),_mm256_castsi256_ps(f)); } + static __forceinline void storeu(const vboolf8& mask, void* ptr, const vint8& f) { _mm256_maskstore_ps((float*)ptr,_mm256_castps_si256(mask.v),_mm256_castsi256_ps(f)); } static __forceinline void store_nt(void* ptr, const vint8& v) { _mm256_stream_ps((float*)ptr,_mm256_castsi256_ps(v)); diff --git a/thirdparty/embree/common/simd/vint8_avx2.h b/thirdparty/embree/common/simd/vint8_avx2.h index e04737ffbe..d48efac3f4 100644 --- a/thirdparty/embree/common/simd/vint8_avx2.h +++ b/thirdparty/embree/common/simd/vint8_avx2.h @@ -393,6 +393,7 @@ namespace embree __forceinline int toScalar(const vint8& v) { return _mm_cvtsi128_si32(_mm256_castsi256_si128(v)); } +#if !defined(__aarch64__) __forceinline vint8 permute(const vint8& v, const __m256i& index) { return _mm256_permutevar8x32_epi32(v, index); } @@ -410,6 +411,9 @@ namespace embree #endif } +#endif + + //////////////////////////////////////////////////////////////////////////////// /// Reductions //////////////////////////////////////////////////////////////////////////////// diff --git a/thirdparty/embree/common/simd/vuint4_sse2.h b/thirdparty/embree/common/simd/vuint4_sse2.h index 0601b9ab80..f7817da6be 100644 --- a/thirdparty/embree/common/simd/vuint4_sse2.h +++ b/thirdparty/embree/common/simd/vuint4_sse2.h @@ -95,7 +95,14 @@ namespace embree static __forceinline void storeu(const vboolf4& mask, void* ptr, const vuint4& i) { storeu(ptr,select(mask,i,loadu(ptr))); } #endif -#if defined(__SSE4_1__) +#if defined(__aarch64__) + static __forceinline vuint4 load(const unsigned char* ptr) { + return _mm_load4epu8_epi32(((__m128i*)ptr)); + } + static __forceinline vuint4 loadu(const unsigned char* ptr) { + return _mm_load4epu8_epi32(((__m128i*)ptr)); + } +#elif defined(__SSE4_1__) static __forceinline vuint4 load(const unsigned char* ptr) { return _mm_cvtepu8_epi32(_mm_loadl_epi64((__m128i*)ptr)); } @@ -107,7 +114,9 @@ namespace embree #endif static __forceinline vuint4 load(const unsigned short* ptr) { -#if defined (__SSE4_1__) +#if defined(__aarch64__) + return _mm_load4epu16_epi32(((__m128i*)ptr)); +#elif defined (__SSE4_1__) return _mm_cvtepu16_epi32(_mm_loadu_si128((__m128i*)ptr)); #else return vuint4(ptr[0],ptr[1],ptr[2],ptr[3]); @@ -115,7 +124,7 @@ namespace embree } static __forceinline vuint4 load_nt(void* ptr) { -#if defined(__SSE4_1__) +#if (defined(__aarch64__)) || defined(__SSE4_1__) return _mm_stream_load_si128((__m128i*)ptr); #else return _mm_load_si128((__m128i*)ptr); @@ -123,8 +132,8 @@ namespace embree } static __forceinline void store_nt(void* ptr, const vuint4& v) { -#if defined(__SSE4_1__) - _mm_stream_ps((float*)ptr,_mm_castsi128_ps(v)); +#if !defined(__aarch64__) && defined(__SSE4_1__) + _mm_stream_ps((float*)ptr, _mm_castsi128_ps(v)); #else _mm_store_si128((__m128i*)ptr,v); #endif @@ -132,7 +141,7 @@ namespace embree template<int scale = 4> static __forceinline vuint4 gather(const unsigned int* ptr, const vint4& index) { -#if defined(__AVX2__) +#if defined(__AVX2__) && !defined(__aarch64__) return _mm_i32gather_epi32((const int*)ptr, index, scale); #else return vuint4( @@ -148,7 +157,7 @@ namespace embree vuint4 r = zero; #if defined(__AVX512VL__) return _mm_mmask_i32gather_epi32(r, mask, index, ptr, scale); -#elif defined(__AVX2__) +#elif defined(__AVX2__) && !defined(__aarch64__) return _mm_mask_i32gather_epi32(r, (const int*)ptr, index, mask, scale); #else if (likely(mask[0])) r[0] = *(unsigned int*)(((char*)ptr)+scale*index[0]); @@ -344,6 +353,16 @@ namespace embree __forceinline vuint4 unpacklo(const vuint4& a, const vuint4& b) { return _mm_castps_si128(_mm_unpacklo_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b))); } __forceinline vuint4 unpackhi(const vuint4& a, const vuint4& b) { return _mm_castps_si128(_mm_unpackhi_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b))); } +#if defined(__aarch64__) + template<int i0, int i1, int i2, int i3> + __forceinline vuint4 shuffle(const vuint4& v) { + return vreinterpretq_s32_u8(vqtbl1q_u8( (uint8x16_t)v.v, _MN_SHUFFLE(i0, i1, i2, i3))); + } + template<int i0, int i1, int i2, int i3> + __forceinline vuint4 shuffle(const vuint4& a, const vuint4& b) { + return vreinterpretq_s32_u8(vqtbl2q_u8( (uint8x16x2_t){(uint8x16_t)a.v, (uint8x16_t)b.v}, _MF_SHUFFLE(i0, i1, i2, i3))); + } +#else template<int i0, int i1, int i2, int i3> __forceinline vuint4 shuffle(const vuint4& v) { return _mm_shuffle_epi32(v, _MM_SHUFFLE(i3, i2, i1, i0)); @@ -353,7 +372,7 @@ namespace embree __forceinline vuint4 shuffle(const vuint4& a, const vuint4& b) { return _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), _MM_SHUFFLE(i3, i2, i1, i0))); } - +#endif #if defined(__SSE3__) template<> __forceinline vuint4 shuffle<0, 0, 2, 2>(const vuint4& v) { return _mm_castps_si128(_mm_moveldup_ps(_mm_castsi128_ps(v))); } template<> __forceinline vuint4 shuffle<1, 1, 3, 3>(const vuint4& v) { return _mm_castps_si128(_mm_movehdup_ps(_mm_castsi128_ps(v))); } @@ -365,7 +384,7 @@ namespace embree return shuffle<i,i,i,i>(v); } -#if defined(__SSE4_1__) +#if defined(__SSE4_1__) && !defined(__aarch64__) template<int src> __forceinline unsigned int extract(const vuint4& b) { return _mm_extract_epi32(b, src); } template<int dst> __forceinline vuint4 insert(const vuint4& a, const unsigned b) { return _mm_insert_epi32(a, b, dst); } #else @@ -373,7 +392,6 @@ namespace embree template<int dst> __forceinline vuint4 insert(const vuint4& a, const unsigned b) { vuint4 c = a; c[dst&3] = b; return c; } #endif - template<> __forceinline unsigned int extract<0>(const vuint4& b) { return _mm_cvtsi128_si32(b); } __forceinline unsigned int toScalar(const vuint4& v) { return _mm_cvtsi128_si32(v); } diff --git a/thirdparty/embree/common/simd/vuint8_avx.h b/thirdparty/embree/common/simd/vuint8_avx.h index 589cd9d731..cb8b5158c1 100644 --- a/thirdparty/embree/common/simd/vuint8_avx.h +++ b/thirdparty/embree/common/simd/vuint8_avx.h @@ -77,8 +77,8 @@ namespace embree static __forceinline void store (void* ptr, const vuint8& f) { _mm256_store_ps((float*)ptr,_mm256_castsi256_ps(f)); } static __forceinline void storeu(void* ptr, const vuint8& f) { _mm256_storeu_ps((float*)ptr,_mm256_castsi256_ps(f)); } - static __forceinline void store (const vboolf8& mask, void* ptr, const vuint8& f) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,_mm256_castsi256_ps(f)); } - static __forceinline void storeu(const vboolf8& mask, void* ptr, const vuint8& f) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,_mm256_castsi256_ps(f)); } + static __forceinline void store (const vboolf8& mask, void* ptr, const vuint8& f) { _mm256_maskstore_ps((float*)ptr,_mm256_castps_si256(mask.v),_mm256_castsi256_ps(f)); } + static __forceinline void storeu(const vboolf8& mask, void* ptr, const vuint8& f) { _mm256_maskstore_ps((float*)ptr,_mm256_castps_si256(mask.v),_mm256_castsi256_ps(f)); } static __forceinline void store_nt(void* ptr, const vuint8& v) { _mm256_stream_ps((float*)ptr,_mm256_castsi256_ps(v)); diff --git a/thirdparty/embree/common/simd/vuint8_avx2.h b/thirdparty/embree/common/simd/vuint8_avx2.h index 17b994522f..959143724b 100644 --- a/thirdparty/embree/common/simd/vuint8_avx2.h +++ b/thirdparty/embree/common/simd/vuint8_avx2.h @@ -385,6 +385,7 @@ namespace embree __forceinline int toScalar(const vuint8& v) { return _mm_cvtsi128_si32(_mm256_castsi256_si128(v)); } +#if !defined(__aarch64__) __forceinline vuint8 permute(const vuint8& v, const __m256i& index) { return _mm256_permutevar8x32_epi32(v, index); } @@ -401,6 +402,7 @@ namespace embree return _mm256_alignr_epi8(a, b, 4*i); #endif } +#endif // !defined(__aarch64__) //////////////////////////////////////////////////////////////////////////////// /// Reductions diff --git a/thirdparty/embree/common/simd/wasm/emulation.h b/thirdparty/embree/common/simd/wasm/emulation.h new file mode 100644 index 0000000000..778ab4ae6a --- /dev/null +++ b/thirdparty/embree/common/simd/wasm/emulation.h @@ -0,0 +1,13 @@ +// Copyright 2009-2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +// According to https://emscripten.org/docs/porting/simd.html, _MM_SET_EXCEPTION_MASK and +// _mm_setcsr are unavailable in WebAssembly. + +#define _MM_SET_EXCEPTION_MASK(x) + +__forceinline void _mm_setcsr(unsigned int) +{ +} diff --git a/thirdparty/embree/common/sys/array.h b/thirdparty/embree/common/sys/array.h index dd9190c52a..e96939b63d 100644 --- a/thirdparty/embree/common/sys/array.h +++ b/thirdparty/embree/common/sys/array.h @@ -59,8 +59,8 @@ namespace embree /********************** Iterators ****************************/ - __forceinline T* begin() const { return items; }; - __forceinline T* end () const { return items+M; }; + __forceinline T* begin() const { return (T*)items; }; + __forceinline T* end () const { return (T*)items+M; }; /********************** Capacity ****************************/ @@ -101,8 +101,8 @@ namespace embree __forceinline T& at(size_t i) { assert(i < M); return items[i]; } __forceinline const T& at(size_t i) const { assert(i < M); return items[i]; } - __forceinline T& front() const { assert(M > 0); return items[0]; }; - __forceinline T& back () const { assert(M > 0); return items[M-1]; }; + __forceinline T& front() { assert(M > 0); return items[0]; }; + __forceinline T& back () { assert(M > 0); return items[M-1]; }; __forceinline T* data() { return items; }; __forceinline const T* data() const { return items; }; @@ -139,7 +139,7 @@ namespace embree __forceinline Ty& operator[](const unsigned i) { assert(i<N); return data[i]; } __forceinline const Ty& operator[](const unsigned i) const { assert(i<N); return data[i]; } -#if defined(__64BIT__) +#if defined(__64BIT__) || defined(__EMSCRIPTEN__) __forceinline Ty& operator[](const size_t i) { assert(i<N); return data[i]; } __forceinline const Ty& operator[](const size_t i) const { assert(i<N); return data[i]; } #endif @@ -196,7 +196,7 @@ namespace embree __forceinline Ty& operator[](const int i) { assert(i>=0 && i<max_total_elements); resize(i+1); return data[i]; } __forceinline Ty& operator[](const unsigned i) { assert(i<max_total_elements); resize(i+1); return data[i]; } -#if defined(__64BIT__) +#if defined(__64BIT__) || defined(__EMSCRIPTEN__) __forceinline Ty& operator[](const size_t i) { assert(i<max_total_elements); resize(i+1); return data[i]; } #endif diff --git a/thirdparty/embree/common/sys/barrier.h b/thirdparty/embree/common/sys/barrier.h index 37fc036291..c56513a2ed 100644 --- a/thirdparty/embree/common/sys/barrier.h +++ b/thirdparty/embree/common/sys/barrier.h @@ -24,7 +24,7 @@ namespace embree BarrierSys& operator= (const BarrierSys& other) DELETED; // do not implement public: - /*! intializes the barrier with some number of threads */ + /*! initializes the barrier with some number of threads */ void init(size_t count); /*! lets calling thread wait in barrier */ @@ -94,7 +94,7 @@ namespace embree LinearBarrierActive& operator= (const LinearBarrierActive& other) DELETED; // do not implement public: - /*! intializes the barrier with some number of threads */ + /*! initializes the barrier with some number of threads */ void init(size_t threadCount); /*! thread with threadIndex waits in the barrier */ diff --git a/thirdparty/embree/common/sys/intrinsics.h b/thirdparty/embree/common/sys/intrinsics.h index ed8dd7d40a..2c2f6eccda 100644 --- a/thirdparty/embree/common/sys/intrinsics.h +++ b/thirdparty/embree/common/sys/intrinsics.h @@ -13,6 +13,9 @@ #include "../simd/arm/emulation.h" #else #include <immintrin.h> +#if defined(__EMSCRIPTEN__) +#include "../simd/wasm/emulation.h" +#endif #endif #if defined(__BMI__) && defined(__GNUC__) && !defined(__INTEL_COMPILER) @@ -24,24 +27,26 @@ #endif #endif -#if defined(__LZCNT__) +#if defined(__aarch64__) #if !defined(_lzcnt_u32) - #define _lzcnt_u32 __lzcnt32 + #define _lzcnt_u32 __builtin_clz #endif - #if !defined(_lzcnt_u64) - #define _lzcnt_u64 __lzcnt64 +#else + #if defined(__LZCNT__) + #if !defined(_lzcnt_u32) + #define _lzcnt_u32 __lzcnt32 + #endif + #if !defined(_lzcnt_u64) + #define _lzcnt_u64 __lzcnt64 + #endif #endif #endif #if defined(__WIN32__) -// -- GODOT start -- -#if !defined(NOMINMAX) -// -- GODOT end -- -#define NOMINMAX -// -- GODOT start -- -#endif -#include "windows.h" -// -- GODOT end -- +# if !defined(NOMINMAX) +# define NOMINMAX +# endif +# include <windows.h> #endif /* normally defined in pmmintrin.h, but we always need this */ @@ -69,7 +74,7 @@ namespace embree } __forceinline int bsf(int v) { -#if defined(__AVX2__) +#if defined(__AVX2__) && !defined(__aarch64__) return _tzcnt_u32(v); #else unsigned long r = 0; _BitScanForward(&r,v); return r; @@ -77,7 +82,7 @@ namespace embree } __forceinline unsigned bsf(unsigned v) { -#if defined(__AVX2__) +#if defined(__AVX2__) && !defined(__aarch64__) return _tzcnt_u32(v); #else unsigned long r = 0; _BitScanForward(&r,v); return r; @@ -118,7 +123,7 @@ namespace embree #endif __forceinline int bsr(int v) { -#if defined(__AVX2__) +#if defined(__AVX2__) && !defined(__aarch64__) return 31 - _lzcnt_u32(v); #else unsigned long r = 0; _BitScanReverse(&r,v); return r; @@ -126,7 +131,7 @@ namespace embree } __forceinline unsigned bsr(unsigned v) { -#if defined(__AVX2__) +#if defined(__AVX2__) && !defined(__aarch64__) return 31 - _lzcnt_u32(v); #else unsigned long r = 0; _BitScanReverse(&r,v); return r; @@ -145,7 +150,7 @@ namespace embree __forceinline int lzcnt(const int x) { -#if defined(__AVX2__) +#if defined(__AVX2__) && !defined(__aarch64__) return _lzcnt_u32(x); #else if (unlikely(x == 0)) return 32; @@ -214,15 +219,26 @@ namespace embree #elif defined(__X86_ASM__) __forceinline void __cpuid(int out[4], int op) { - asm volatile ("cpuid" : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) : "a"(op)); +#if defined(__ARM_NEON) + if (op == 0) { // Get CPU name + out[0] = 0x41524d20; + out[1] = 0x41524d20; + out[2] = 0x41524d20; + out[3] = 0x41524d20; + } +#else + asm volatile ("cpuid" : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) : "a"(op)); +#endif } - + +#if !defined(__ARM_NEON) __forceinline void __cpuid_count(int out[4], int op1, int op2) { asm volatile ("cpuid" : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) : "a"(op1), "c"(op2)); } - #endif - + +#endif + __forceinline uint64_t read_tsc() { #if defined(__X86_ASM__) uint32_t high,low; @@ -235,30 +251,38 @@ namespace embree } __forceinline int bsf(int v) { -#if defined(__AVX2__) +#if defined(__ARM_NEON) + return __builtin_ctz(v); +#else +#if defined(__AVX2__) return _tzcnt_u32(v); #elif defined(__X86_ASM__) int r = 0; asm ("bsf %1,%0" : "=r"(r) : "r"(v)); return r; #else return __builtin_ctz(v); #endif +#endif } #if defined(__64BIT__) __forceinline unsigned bsf(unsigned v) { -#if defined(__AVX2__) +#if defined(__ARM_NEON) + return __builtin_ctz(v); +#else +#if defined(__AVX2__) return _tzcnt_u32(v); #elif defined(__X86_ASM__) unsigned r = 0; asm ("bsf %1,%0" : "=r"(r) : "r"(v)); return r; #else return __builtin_ctz(v); #endif +#endif } #endif __forceinline size_t bsf(size_t v) { -#if defined(__AVX2__) +#if defined(__AVX2__) && !defined(__aarch64__) #if defined(__X86_64__) return _tzcnt_u64(v); #else @@ -295,7 +319,7 @@ namespace embree } __forceinline int bsr(int v) { -#if defined(__AVX2__) +#if defined(__AVX2__) && !defined(__aarch64__) return 31 - _lzcnt_u32(v); #elif defined(__X86_ASM__) int r = 0; asm ("bsr %1,%0" : "=r"(r) : "r"(v)); return r; @@ -304,7 +328,7 @@ namespace embree #endif } -#if defined(__64BIT__) +#if defined(__64BIT__) || defined(__EMSCRIPTEN__) __forceinline unsigned bsr(unsigned v) { #if defined(__AVX2__) return 31 - _lzcnt_u32(v); @@ -317,7 +341,7 @@ namespace embree #endif __forceinline size_t bsr(size_t v) { -#if defined(__AVX2__) +#if defined(__AVX2__) && !defined(__aarch64__) #if defined(__X86_64__) return 63 - _lzcnt_u64(v); #else @@ -332,7 +356,7 @@ namespace embree __forceinline int lzcnt(const int x) { -#if defined(__AVX2__) +#if defined(__AVX2__) && !defined(__aarch64__) return _lzcnt_u32(x); #else if (unlikely(x == 0)) return 32; @@ -341,18 +365,18 @@ namespace embree } __forceinline size_t blsr(size_t v) { -#if defined(__AVX2__) -#if defined(__INTEL_COMPILER) +#if defined(__AVX2__) && !defined(__aarch64__) + #if defined(__INTEL_COMPILER) return _blsr_u64(v); + #else + #if defined(__X86_64__) + return __blsr_u64(v); + #else + return __blsr_u32(v); + #endif + #endif #else -#if defined(__X86_64__) - return __blsr_u64(v); -#else - return __blsr_u32(v); -#endif -#endif -#else - return v & (v-1); + return v & (v-1); #endif } @@ -368,7 +392,7 @@ namespace embree #if defined(__X86_ASM__) int r = 0; asm ("bts %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r; #else - return (v | (v << i)); + return (v | (1 << i)); #endif } @@ -376,7 +400,7 @@ namespace embree #if defined(__X86_ASM__) int r = 0; asm ("btr %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r; #else - return (v & ~(v << i)); + return (v & ~(1 << i)); #endif } @@ -392,7 +416,7 @@ namespace embree #if defined(__X86_ASM__) size_t r = 0; asm ("bts %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r; #else - return (v | (v << i)); + return (v | (1 << i)); #endif } @@ -400,7 +424,7 @@ namespace embree #if defined(__X86_ASM__) size_t r = 0; asm ("btr %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r; #else - return (v & ~(v << i)); + return (v & ~(1 << i)); #endif } @@ -435,8 +459,8 @@ namespace embree #endif #endif -#if defined(__SSE4_2__) - +#if defined(__SSE4_2__) || defined(__ARM_NEON) + __forceinline int popcnt(int in) { return _mm_popcnt_u32(in); } @@ -483,14 +507,14 @@ namespace embree #endif } - __forceinline void prefetchL1EX(const void* ptr) { - prefetchEX(ptr); + __forceinline void prefetchL1EX(const void* ptr) { + prefetchEX(ptr); } - - __forceinline void prefetchL2EX(const void* ptr) { - prefetchEX(ptr); + + __forceinline void prefetchL2EX(const void* ptr) { + prefetchEX(ptr); } -#if defined(__AVX2__) +#if defined(__AVX2__) && !defined(__aarch64__) __forceinline unsigned int pext(unsigned int a, unsigned int b) { return _pext_u32(a, b); } __forceinline unsigned int pdep(unsigned int a, unsigned int b) { return _pdep_u32(a, b); } #if defined(__X86_64__) diff --git a/thirdparty/embree/common/sys/mutex.cpp b/thirdparty/embree/common/sys/mutex.cpp index 789feaf2d8..8212deaa49 100644 --- a/thirdparty/embree/common/sys/mutex.cpp +++ b/thirdparty/embree/common/sys/mutex.cpp @@ -36,6 +36,7 @@ namespace embree MAYBE_UNUSED bool ok = pthread_mutex_destroy((pthread_mutex_t*)mutex) == 0; assert(ok); delete (pthread_mutex_t*)mutex; + mutex = nullptr; } void MutexSys::lock() diff --git a/thirdparty/embree/common/sys/mutex.h b/thirdparty/embree/common/sys/mutex.h index 4cb3626d92..26af6c582c 100644 --- a/thirdparty/embree/common/sys/mutex.h +++ b/thirdparty/embree/common/sys/mutex.h @@ -7,6 +7,7 @@ #include "intrinsics.h" #include "atomic.h" +#define CPU_CACHELINE_SIZE 64 namespace embree { /*! system mutex */ @@ -83,6 +84,11 @@ namespace embree atomic<bool> flag; }; + class PaddedSpinLock : public SpinLock + { + private: + char padding[CPU_CACHELINE_SIZE - sizeof(SpinLock)]; + }; /*! safe mutex lock and unlock helper */ template<typename Mutex> class Lock { public: diff --git a/thirdparty/embree/common/sys/platform.h b/thirdparty/embree/common/sys/platform.h index 3e386c4944..728bf6ed7d 100644 --- a/thirdparty/embree/common/sys/platform.h +++ b/thirdparty/embree/common/sys/platform.h @@ -92,16 +92,19 @@ //////////////////////////////////////////////////////////////////////////////// #ifdef __WIN32__ -#define dll_export __declspec(dllexport) -#define dll_import __declspec(dllimport) +# if defined(EMBREE_STATIC_LIB) +# define dll_export +# define dll_import +# else +# define dll_export __declspec(dllexport) +# define dll_import __declspec(dllimport) +# endif #else -#define dll_export __attribute__ ((visibility ("default"))) -#define dll_import +# define dll_export __attribute__ ((visibility ("default"))) +# define dll_import #endif -// -- GODOT start -- #if defined(__WIN32__) && !defined(__MINGW32__) -// -- GODOT end -- #if !defined(__noinline) #define __noinline __declspec(noinline) #endif @@ -151,9 +154,7 @@ #define DELETED = delete #endif -// -- GODOT start -- #if !defined(likely) -// -- GODOT end -- #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) #define likely(expr) (expr) #define unlikely(expr) (expr) @@ -161,9 +162,7 @@ #define likely(expr) __builtin_expect((bool)(expr),true ) #define unlikely(expr) __builtin_expect((bool)(expr),false) #endif -// -- GODOT start -- #endif -// -- GODOT end -- //////////////////////////////////////////////////////////////////////////////// /// Error handling and debugging @@ -252,6 +251,7 @@ __forceinline std::string toString(long long value) { #pragma warning(disable:4800) // forcing value to bool 'true' or 'false' (performance warning) //#pragma warning(disable:4267) // '=' : conversion from 'size_t' to 'unsigned long', possible loss of data #pragma warning(disable:4244) // 'argument' : conversion from 'ssize_t' to 'unsigned int', possible loss of data +#pragma warning(disable:4267) // conversion from 'size_t' to 'const int', possible loss of data //#pragma warning(disable:4355) // 'this' : used in base member initializer list //#pragma warning(disable:391 ) // '<=' : signed / unsigned mismatch //#pragma warning(disable:4018) // '<' : signed / unsigned mismatch diff --git a/thirdparty/embree/common/sys/sysinfo.cpp b/thirdparty/embree/common/sys/sysinfo.cpp index f1a59e511e..7f7a009a1e 100644 --- a/thirdparty/embree/common/sys/sysinfo.cpp +++ b/thirdparty/embree/common/sys/sysinfo.cpp @@ -21,7 +21,11 @@ namespace embree std::string getPlatformName() { -#if defined(__LINUX__) && !defined(__64BIT__) +#if defined(__ANDROID__) && !defined(__64BIT__) + return "Android (32bit)"; +#elif defined(__ANDROID__) && defined(__64BIT__) + return "Android (64bit)"; +#elif defined(__LINUX__) && !defined(__64BIT__) return "Linux (32bit)"; #elif defined(__LINUX__) && defined(__64BIT__) return "Linux (64bit)"; @@ -248,9 +252,7 @@ namespace embree #if defined(__X86_ASM__) __noinline int64_t get_xcr0() { -// -- GODOT start -- -#if defined (__WIN32__) && !defined (__MINGW32__) -// -- GODOT end -- +#if defined (__WIN32__) && !defined (__MINGW32__) && defined(_XCR_XFEATURE_ENABLED_MASK) int64_t xcr0 = 0; // int64_t is workaround for compiler bug under VS2013, Win32 xcr0 = _xgetbv(0); return xcr0; @@ -337,9 +339,24 @@ namespace embree if (cpuid_leaf_7[ECX] & CPU_FEATURE_BIT_AVX512VBMI) cpu_features |= CPU_FEATURE_AVX512VBMI; return cpu_features; -#elif defined(__ARM_NEON) - /* emulated features with sse2neon */ - return CPU_FEATURE_SSE|CPU_FEATURE_SSE2|CPU_FEATURE_XMM_ENABLED; + +#elif defined(__ARM_NEON) || defined(__EMSCRIPTEN__) + + int cpu_features = CPU_FEATURE_NEON|CPU_FEATURE_SSE|CPU_FEATURE_SSE2; + cpu_features |= CPU_FEATURE_SSE3|CPU_FEATURE_SSSE3|CPU_FEATURE_SSE42; + cpu_features |= CPU_FEATURE_XMM_ENABLED; + cpu_features |= CPU_FEATURE_YMM_ENABLED; + cpu_features |= CPU_FEATURE_SSE41 | CPU_FEATURE_RDRAND | CPU_FEATURE_F16C; + cpu_features |= CPU_FEATURE_POPCNT; + cpu_features |= CPU_FEATURE_AVX; + cpu_features |= CPU_FEATURE_AVX2; + cpu_features |= CPU_FEATURE_FMA3; + cpu_features |= CPU_FEATURE_LZCNT; + cpu_features |= CPU_FEATURE_BMI1; + cpu_features |= CPU_FEATURE_BMI2; + cpu_features |= CPU_FEATURE_NEON_2X; + return cpu_features; + #else /* Unknown CPU. */ return 0; @@ -376,6 +393,8 @@ namespace embree if (features & CPU_FEATURE_AVX512VL) str += "AVX512VL "; if (features & CPU_FEATURE_AVX512IFMA) str += "AVX512IFMA "; if (features & CPU_FEATURE_AVX512VBMI) str += "AVX512VBMI "; + if (features & CPU_FEATURE_NEON) str += "NEON "; + if (features & CPU_FEATURE_NEON_2X) str += "2xNEON "; return str; } @@ -390,6 +409,9 @@ namespace embree if (isa == AVX) return "AVX"; if (isa == AVX2) return "AVX2"; if (isa == AVX512) return "AVX512"; + + if (isa == NEON) return "NEON"; + if (isa == NEON_2X) return "2xNEON"; return "UNKNOWN"; } @@ -410,6 +432,9 @@ namespace embree if (hasISA(features,AVXI)) v += "AVXI "; if (hasISA(features,AVX2)) v += "AVX2 "; if (hasISA(features,AVX512)) v += "AVX512 "; + + if (hasISA(features,NEON)) v += "NEON "; + if (hasISA(features,NEON_2X)) v += "2xNEON "; return v; } } @@ -613,6 +638,16 @@ namespace embree #include <sys/time.h> #include <pthread.h> +#if defined(__EMSCRIPTEN__) +#include <emscripten.h> + +// -- GODOT start -- +extern "C" { +extern int godot_js_os_hw_concurrency_get(); +} +// -- GODOT end -- +#endif + namespace embree { unsigned int getNumberOfLogicalThreads() @@ -620,12 +655,13 @@ namespace embree static int nThreads = -1; if (nThreads != -1) return nThreads; -// -- GODOT start -- -// #if defined(__MACOSX__) #if defined(__MACOSX__) || defined(__ANDROID__) -// -- GODOT end -- nThreads = sysconf(_SC_NPROCESSORS_ONLN); // does not work in Linux LXC container assert(nThreads); +#elif defined(__EMSCRIPTEN__) + // -- GODOT start -- + nThreads = godot_js_os_hw_concurrency_get(); + // -- GODOT end -- #else cpu_set_t set; if (pthread_getaffinity_np(pthread_self(), sizeof(set), &set) == 0) diff --git a/thirdparty/embree/common/sys/sysinfo.h b/thirdparty/embree/common/sys/sysinfo.h index 72351d12e4..cefd39a0f6 100644 --- a/thirdparty/embree/common/sys/sysinfo.h +++ b/thirdparty/embree/common/sys/sysinfo.h @@ -55,7 +55,12 @@ # define isa sse # define ISA SSE # define ISA_STR "SSE" -#else +#elif defined(__ARM_NEON) +// NOTE(LTE): Use sse2 for `isa` for the compatibility at the moment. +#define isa sse2 +#define ISA NEON +#define ISA_STR "NEON" +#else #error Unknown ISA #endif @@ -133,7 +138,9 @@ namespace embree static const int CPU_FEATURE_XMM_ENABLED = 1 << 25; static const int CPU_FEATURE_YMM_ENABLED = 1 << 26; static const int CPU_FEATURE_ZMM_ENABLED = 1 << 27; - + static const int CPU_FEATURE_NEON = 1 << 28; + static const int CPU_FEATURE_NEON_2X = 1 << 29; + /*! get CPU features */ int getCPUFeatures(); @@ -154,6 +161,8 @@ namespace embree static const int AVXI = AVX | CPU_FEATURE_F16C | CPU_FEATURE_RDRAND; static const int AVX2 = AVXI | CPU_FEATURE_AVX2 | CPU_FEATURE_FMA3 | CPU_FEATURE_BMI1 | CPU_FEATURE_BMI2 | CPU_FEATURE_LZCNT; static const int AVX512 = AVX2 | CPU_FEATURE_AVX512F | CPU_FEATURE_AVX512DQ | CPU_FEATURE_AVX512CD | CPU_FEATURE_AVX512BW | CPU_FEATURE_AVX512VL | CPU_FEATURE_ZMM_ENABLED; + static const int NEON = CPU_FEATURE_NEON | CPU_FEATURE_SSE | CPU_FEATURE_SSE2; + static const int NEON_2X = CPU_FEATURE_NEON_2X | AVX2; /*! converts ISA bitvector into a string */ std::string stringOfISA(int features); diff --git a/thirdparty/embree/common/sys/thread.cpp b/thirdparty/embree/common/sys/thread.cpp index f4014be89b..530c3c7810 100644 --- a/thirdparty/embree/common/sys/thread.cpp +++ b/thirdparty/embree/common/sys/thread.cpp @@ -10,6 +10,9 @@ #include "../simd/arm/emulation.h" #else #include <xmmintrin.h> +#if defined(__EMSCRIPTEN__) +#include "../simd/wasm/emulation.h" +#endif #endif #if defined(PTHREADS_WIN32) @@ -158,9 +161,7 @@ namespace embree /// Linux Platform //////////////////////////////////////////////////////////////////////////////// -// -- GODOT start -- #if defined(__LINUX__) && !defined(__ANDROID__) -// -- GODOT end -- #include <fstream> #include <sstream> @@ -219,6 +220,8 @@ namespace embree /* find correct thread to affinitize to */ cpu_set_t set; + CPU_ZERO(&set); + if (pthread_getaffinity_np(pthread_self(), sizeof(set), &set) == 0) { for (int i=0, j=0; i<CPU_SETSIZE; i++) @@ -241,7 +244,8 @@ namespace embree { cpu_set_t cset; CPU_ZERO(&cset); - size_t threadID = mapThreadID(affinity); + //size_t threadID = mapThreadID(affinity); // this is not working properly in LXC containers when some processors are disabled + size_t threadID = affinity; CPU_SET(threadID, &cset); pthread_setaffinity_np(pthread_self(), sizeof(cset), &cset); @@ -249,7 +253,6 @@ namespace embree } #endif -// -- GODOT start -- //////////////////////////////////////////////////////////////////////////////// /// Android Platform //////////////////////////////////////////////////////////////////////////////// @@ -269,7 +272,6 @@ namespace embree } } #endif -// -- GODOT end -- //////////////////////////////////////////////////////////////////////////////// /// FreeBSD Platform @@ -294,6 +296,21 @@ namespace embree #endif //////////////////////////////////////////////////////////////////////////////// +/// WebAssembly Platform +//////////////////////////////////////////////////////////////////////////////// + +#if defined(__EMSCRIPTEN__) +namespace embree +{ + /*! set affinity of the calling thread */ + void setAffinity(ssize_t affinity) + { + // Setting thread affinity is not supported in WASM. + } +} +#endif + +//////////////////////////////////////////////////////////////////////////////// /// MacOSX Platform //////////////////////////////////////////////////////////////////////////////// @@ -379,9 +396,7 @@ namespace embree pthread_attr_destroy(&attr); /* set affinity */ -// -- GODOT start -- #if defined(__LINUX__) && !defined(__ANDROID__) -// -- GODOT end -- if (threadID >= 0) { cpu_set_t cset; CPU_ZERO(&cset); @@ -396,7 +411,6 @@ namespace embree CPU_SET(threadID, &cset); pthread_setaffinity_np(*tid, sizeof(cset), &cset); } -// -- GODOT start -- #elif defined(__ANDROID__) if (threadID >= 0) { cpu_set_t cset; @@ -405,7 +419,6 @@ namespace embree sched_setaffinity(pthread_gettid_np(*tid), sizeof(cset), &cset); } #endif -// -- GODOT end -- return thread_t(tid); } @@ -424,14 +437,12 @@ namespace embree /*! destroy a hardware thread by its handle */ void destroyThread(thread_t tid) { -// -- GODOT start -- #if defined(__ANDROID__) - FATAL("Can't destroy threads on Android."); + FATAL("Can't destroy threads on Android."); // pthread_cancel not implemented. #else pthread_cancel(*(pthread_t*)tid); delete (pthread_t*)tid; #endif -// -- GODOT end -- } /*! creates thread local storage */ diff --git a/thirdparty/embree/common/sys/vector.h b/thirdparty/embree/common/sys/vector.h index f832626789..d05e1deb18 100644 --- a/thirdparty/embree/common/sys/vector.h +++ b/thirdparty/embree/common/sys/vector.h @@ -127,14 +127,15 @@ namespace embree { assert(!empty()); size_active--; - alloc.destroy(&items[size_active]); + items[size_active].~T(); } __forceinline void clear() { /* destroy elements */ - for (size_t i=0; i<size_active; i++) - alloc.destroy(&items[i]); + for (size_t i=0; i<size_active; i++){ + items[i].~T(); + } /* free memory */ alloc.deallocate(items,size_alloced); @@ -178,8 +179,9 @@ namespace embree /* destroy elements */ if (new_active < size_active) { - for (size_t i=new_active; i<size_active; i++) - alloc.destroy(&items[i]); + for (size_t i=new_active; i<size_active; i++){ + items[i].~T(); + } size_active = new_active; } @@ -195,7 +197,7 @@ namespace embree items = alloc.allocate(new_alloced); for (size_t i=0; i<size_active; i++) { ::new (&items[i]) T(std::move(old_items[i])); - alloc.destroy(&old_items[i]); + old_items[i].~T(); } for (size_t i=size_active; i<new_active; i++) { diff --git a/thirdparty/embree/common/tasking/taskschedulerinternal.h b/thirdparty/embree/common/tasking/taskschedulerinternal.h index 8fa6bb12fa..6cc2495195 100644 --- a/thirdparty/embree/common/tasking/taskschedulerinternal.h +++ b/thirdparty/embree/common/tasking/taskschedulerinternal.h @@ -143,7 +143,7 @@ namespace embree /* allocate new task on right side of stack */ size_t oldStackPtr = stackPtr; TaskFunction* func = new (alloc(sizeof(ClosureTaskFunction<Closure>))) ClosureTaskFunction<Closure>(closure); - new (&tasks[right]) Task(func,thread.task,oldStackPtr,size); + new (&(tasks[right.load()])) Task(func,thread.task,oldStackPtr,size); right++; /* also move left pointer */ diff --git a/thirdparty/embree/common/tasking/taskschedulertbb.h b/thirdparty/embree/common/tasking/taskschedulertbb.h index 35bd49849f..042ba7bc4c 100644 --- a/thirdparty/embree/common/tasking/taskschedulertbb.h +++ b/thirdparty/embree/common/tasking/taskschedulertbb.h @@ -11,14 +11,8 @@ #include "../sys/condition.h" #include "../sys/ref.h" -#if defined(__WIN32__) -// -- GODOT start -- -#if !defined(NOMINMAX) -// -- GODOT end -- +#if defined(__WIN32__) && !defined(NOMINMAX) # define NOMINMAX -// -- GODOT start -- -#endif -// -- GODOT end -- #endif // We need to define these to avoid implicit linkage against diff --git a/thirdparty/embree/include/embree3/rtcore_common.h b/thirdparty/embree/include/embree3/rtcore_common.h index 4857e1e05e..894628e47c 100644 --- a/thirdparty/embree/include/embree3/rtcore_common.h +++ b/thirdparty/embree/include/embree3/rtcore_common.h @@ -19,9 +19,7 @@ typedef int ssize_t; #endif #endif -// -- GODOT start -- -#if defined(_WIN32) && defined(_MSC_VER) -// -- GODOT end -- +#if defined(_WIN32) && !defined(__MINGW32__) # define RTC_ALIGN(...) __declspec(align(__VA_ARGS__)) #else # define RTC_ALIGN(...) __attribute__((aligned(__VA_ARGS__))) diff --git a/thirdparty/embree/include/embree3/rtcore_config.h b/thirdparty/embree/include/embree3/rtcore_config.h index 62b7b6f4dc..0b399ef040 100644 --- a/thirdparty/embree/include/embree3/rtcore_config.h +++ b/thirdparty/embree/include/embree3/rtcore_config.h @@ -1,4 +1,3 @@ - // Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 @@ -6,23 +5,25 @@ #define RTC_VERSION_MAJOR 3 #define RTC_VERSION_MINOR 13 -#define RTC_VERSION_PATCH 1 -#define RTC_VERSION 31301 -#define RTC_VERSION_STRING "3.13.1" +#define RTC_VERSION_PATCH 5 +#define RTC_VERSION 31305 +#define RTC_VERSION_STRING "3.13.5" #define RTC_MAX_INSTANCE_LEVEL_COUNT 1 #define EMBREE_MIN_WIDTH 0 #define RTC_MIN_WIDTH EMBREE_MIN_WIDTH -#define EMBREE_STATIC_LIB -/* #undef EMBREE_API_NAMESPACE */ +#if !defined(EMBREE_STATIC_LIB) +# define EMBREE_STATIC_LIB +#endif +/* #undef EMBREE_API_NAMESPACE*/ #if defined(EMBREE_API_NAMESPACE) # define RTC_NAMESPACE -# define RTC_NAMESPACE_BEGIN namespace { +# define RTC_NAMESPACE_BEGIN namespace { # define RTC_NAMESPACE_END } -# define RTC_NAMESPACE_USE using namespace ; +# define RTC_NAMESPACE_USE using namespace; # define RTC_API_EXTERN_C # undef EMBREE_API_NAMESPACE #else diff --git a/thirdparty/embree/include/embree3/rtcore_quaternion.h b/thirdparty/embree/include/embree3/rtcore_quaternion.h index 6489fa3467..bd5fe1d89a 100644 --- a/thirdparty/embree/include/embree3/rtcore_quaternion.h +++ b/thirdparty/embree/include/embree3/rtcore_quaternion.h @@ -8,7 +8,7 @@ RTC_NAMESPACE_BEGIN /* - * Structure for transformation respresentation as a matrix decomposition using + * Structure for transformation representation as a matrix decomposition using * a quaternion */ struct RTC_ALIGN(16) RTCQuaternionDecomposition diff --git a/thirdparty/embree/include/embree3/rtcore_scene.h b/thirdparty/embree/include/embree3/rtcore_scene.h index 5878a3d402..34d87a2ce4 100644 --- a/thirdparty/embree/include/embree3/rtcore_scene.h +++ b/thirdparty/embree/include/embree3/rtcore_scene.h @@ -47,9 +47,12 @@ RTC_API void rtcAttachGeometryByID(RTCScene scene, RTCGeometry geometry, unsigne /* Detaches the geometry from the scene. */ RTC_API void rtcDetachGeometry(RTCScene scene, unsigned int geomID); -/* Gets a geometry handle from the scene. */ +/* Gets a geometry handle from the scene. This function is not thread safe and should get used during rendering. */ RTC_API RTCGeometry rtcGetGeometry(RTCScene scene, unsigned int geomID); +/* Gets a geometry handle from the scene. This function is thread safe and should NOT get used during rendering. */ +RTC_API RTCGeometry rtcGetGeometryThreadSafe(RTCScene scene, unsigned int geomID); + /* Commits the scene. */ RTC_API void rtcCommitScene(RTCScene scene); diff --git a/thirdparty/embree/kernels/builders/bvh_builder_morton.h b/thirdparty/embree/kernels/builders/bvh_builder_morton.h index 8f21e3254f..cba32ca73c 100644 --- a/thirdparty/embree/kernels/builders/bvh_builder_morton.h +++ b/thirdparty/embree/kernels/builders/bvh_builder_morton.h @@ -411,7 +411,7 @@ namespace embree ReductionTy bounds[MAX_BRANCHING_FACTOR]; if (current.size() > singleThreadThreshold) { - /*! parallel_for is faster than spawing sub-tasks */ + /*! parallel_for is faster than spawning sub-tasks */ parallel_for(size_t(0), numChildren, [&] (const range<size_t>& r) { for (size_t i=r.begin(); i<r.end(); i++) { bounds[i] = recurse(depth+1,children[i],nullptr,true); diff --git a/thirdparty/embree/kernels/builders/bvh_builder_msmblur.h b/thirdparty/embree/kernels/builders/bvh_builder_msmblur.h index f9a08d65cd..6e73c0d250 100644 --- a/thirdparty/embree/kernels/builders/bvh_builder_msmblur.h +++ b/thirdparty/embree/kernels/builders/bvh_builder_msmblur.h @@ -374,7 +374,7 @@ namespace embree const size_t begin = set.begin(); const size_t end = set.end(); - const size_t center = (begin + end)/2; + const size_t center = (begin + end + 1) / 2; PrimInfoMB linfo = empty; for (size_t i=begin; i<center; i++) @@ -594,7 +594,7 @@ namespace embree /* spawn tasks */ if (unlikely(current.size() > cfg.singleThreadThreshold)) { - /*! parallel_for is faster than spawing sub-tasks */ + /*! parallel_for is faster than spawning sub-tasks */ parallel_for(size_t(0), children.size(), [&] (const range<size_t>& r) { for (size_t i=r.begin(); i<r.end(); i++) { values[i] = recurse(children[i],nullptr,true); diff --git a/thirdparty/embree/kernels/builders/bvh_builder_sah.h b/thirdparty/embree/kernels/builders/bvh_builder_sah.h index fff4bf2a35..24c5faf8be 100644 --- a/thirdparty/embree/kernels/builders/bvh_builder_sah.h +++ b/thirdparty/embree/kernels/builders/bvh_builder_sah.h @@ -298,7 +298,7 @@ namespace embree /* spawn tasks */ if (current.size() > cfg.singleThreadThreshold) { - /*! parallel_for is faster than spawing sub-tasks */ + /*! parallel_for is faster than spawning sub-tasks */ parallel_for(size_t(0), numChildren, [&] (const range<size_t>& r) { // FIXME: no range here for (size_t i=r.begin(); i<r.end(); i++) { values[i] = recurse(children[i],nullptr,true); diff --git a/thirdparty/embree/kernels/builders/heuristic_binning.h b/thirdparty/embree/kernels/builders/heuristic_binning.h index ee29d09ac9..41be6183b8 100644 --- a/thirdparty/embree/kernels/builders/heuristic_binning.h +++ b/thirdparty/embree/kernels/builders/heuristic_binning.h @@ -57,14 +57,12 @@ namespace embree __forceinline Vec3ia bin(const Vec3fa& p) const { const vint4 i = floori((vfloat4(p)-ofs)*scale); -#if 1 assert(i[0] >= 0 && (size_t)i[0] < num); assert(i[1] >= 0 && (size_t)i[1] < num); assert(i[2] >= 0 && (size_t)i[2] < num); - return Vec3ia(i); -#else + + // we clamp to handle corner cases that could calculate out of bounds bin return Vec3ia(clamp(i,vint4(0),vint4(num-1))); -#endif } /*! faster but unsafe binning */ diff --git a/thirdparty/embree/kernels/builders/heuristic_openmerge_array.h b/thirdparty/embree/kernels/builders/heuristic_openmerge_array.h index 4249d16ea1..354e283557 100644 --- a/thirdparty/embree/kernels/builders/heuristic_openmerge_array.h +++ b/thirdparty/embree/kernels/builders/heuristic_openmerge_array.h @@ -275,7 +275,7 @@ namespace embree openNodesBasedOnExtend(set); #endif - /* disable opening when unsufficient space for opening a node available */ + /* disable opening when insufficient space for opening a node available */ if (set.ext_range_size() < max_open_size-1) set.set_ext_range(set.end()); /* disable opening */ } diff --git a/thirdparty/embree/kernels/builders/heuristic_spatial.h b/thirdparty/embree/kernels/builders/heuristic_spatial.h index a6939ba258..8b3499ac8d 100644 --- a/thirdparty/embree/kernels/builders/heuristic_spatial.h +++ b/thirdparty/embree/kernels/builders/heuristic_spatial.h @@ -159,27 +159,25 @@ namespace embree assert(binID < BINS); bounds [binID][dim].extend(b); } - - /*! bins an array of triangles */ - template<typename SplitPrimitive> - __forceinline void bin(const SplitPrimitive& splitPrimitive, const PrimRef* prims, size_t N, const SpatialBinMapping<BINS>& mapping) + + /*! bins an array of primitives */ + template<typename PrimitiveSplitterFactory> + __forceinline void bin2(const PrimitiveSplitterFactory& splitterFactory, const PrimRef* source, size_t begin, size_t end, const SpatialBinMapping<BINS>& mapping) { - for (size_t i=0; i<N; i++) + for (size_t i=begin; i<end; i++) { - const PrimRef prim = prims[i]; + const PrimRef& prim = source[i]; unsigned splits = prim.geomID() >> (32-RESERVED_NUM_SPATIAL_SPLITS_GEOMID_BITS); - - if (unlikely(splits == 1)) + + if (unlikely(splits <= 1)) { const vint4 bin = mapping.bin(center(prim.bounds())); for (size_t dim=0; dim<3; dim++) { assert(bin[dim] >= (int)0 && bin[dim] < (int)BINS); - numBegin[bin[dim]][dim]++; - numEnd [bin[dim]][dim]++; - bounds [bin[dim]][dim].extend(prim.bounds()); + add(dim,bin[dim],bin[dim],bin[dim],prim.bounds()); } - } + } else { const vint4 bin0 = mapping.bin(prim.bounds().lower); @@ -187,89 +185,44 @@ namespace embree for (size_t dim=0; dim<3; dim++) { + if (unlikely(mapping.invalid(dim))) + continue; + size_t bin; - PrimRef rest = prim; size_t l = bin0[dim]; size_t r = bin1[dim]; - + // same bin optimization if (likely(l == r)) { - numBegin[l][dim]++; - numEnd [l][dim]++; - bounds [l][dim].extend(prim.bounds()); + add(dim,l,l,l,prim.bounds()); continue; } - - for (bin=(size_t)bin0[dim]; bin<(size_t)bin1[dim]; bin++) + size_t bin_start = bin0[dim]; + size_t bin_end = bin1[dim]; + BBox3fa rest = prim.bounds(); + + /* assure that split position always overlaps the primitive bounds */ + while (bin_start < bin_end && mapping.pos(bin_start+1,dim) <= rest.lower[dim]) bin_start++; + while (bin_start < bin_end && mapping.pos(bin_end ,dim) >= rest.upper[dim]) bin_end--; + + const auto splitter = splitterFactory(prim); + for (bin=bin_start; bin<bin_end; bin++) { const float pos = mapping.pos(bin+1,dim); + BBox3fa left,right; + splitter(rest,dim,pos,left,right); - PrimRef left,right; - splitPrimitive(rest,(int)dim,pos,left,right); - if (unlikely(left.bounds().empty())) l++; - bounds[bin][dim].extend(left.bounds()); + if (unlikely(left.empty())) l++; + extend(dim,bin,left); rest = right; } - if (unlikely(rest.bounds().empty())) r--; - numBegin[l][dim]++; - numEnd [r][dim]++; - bounds [bin][dim].extend(rest.bounds()); + if (unlikely(rest.empty())) r--; + add(dim,l,r,bin,rest); } - } + } } } - - /*! bins a range of primitives inside an array */ - template<typename SplitPrimitive> - void bin(const SplitPrimitive& splitPrimitive, const PrimRef* prims, size_t begin, size_t end, const SpatialBinMapping<BINS>& mapping) { - bin(splitPrimitive,prims+begin,end-begin,mapping); - } - - /*! bins an array of primitives */ - template<typename PrimitiveSplitterFactory> - __forceinline void bin2(const PrimitiveSplitterFactory& splitterFactory, const PrimRef* source, size_t begin, size_t end, const SpatialBinMapping<BINS>& mapping) - { - for (size_t i=begin; i<end; i++) - { - const PrimRef &prim = source[i]; - const vint4 bin0 = mapping.bin(prim.bounds().lower); - const vint4 bin1 = mapping.bin(prim.bounds().upper); - - for (size_t dim=0; dim<3; dim++) - { - if (unlikely(mapping.invalid(dim))) - continue; - - size_t bin; - size_t l = bin0[dim]; - size_t r = bin1[dim]; - - // same bin optimization - if (likely(l == r)) - { - add(dim,l,l,l,prim.bounds()); - continue; - } - const size_t bin_start = bin0[dim]; - const size_t bin_end = bin1[dim]; - BBox3fa rest = prim.bounds(); - const auto splitter = splitterFactory(prim); - for (bin=bin_start; bin<bin_end; bin++) - { - const float pos = mapping.pos(bin+1,dim); - BBox3fa left,right; - splitter(rest,dim,pos,left,right); - if (unlikely(left.empty())) l++; - extend(dim,bin,left); - rest = right; - } - if (unlikely(rest.empty())) r--; - add(dim,l,r,bin,rest); - } - } - } - /*! bins an array of primitives */ diff --git a/thirdparty/embree/kernels/builders/heuristic_spatial_array.h b/thirdparty/embree/kernels/builders/heuristic_spatial_array.h index 60d235f48d..2584c19bda 100644 --- a/thirdparty/embree/kernels/builders/heuristic_spatial_array.h +++ b/thirdparty/embree/kernels/builders/heuristic_spatial_array.h @@ -241,7 +241,7 @@ namespace embree SpatialBinner binner(empty); const SpatialBinMapping<SPATIAL_BINS> mapping(set); binner.bin2(splitterFactory,prims0,set.begin(),set.end(),mapping); - /* todo: best spatial split not exeeding the extended range does not provide any benefit ?*/ + /* todo: best spatial split not exceeding the extended range does not provide any benefit ?*/ return binner.best(mapping,logBlockSize); //,set.ext_size()); } @@ -256,7 +256,7 @@ namespace embree binner.bin2(splitterFactory,prims0,r.begin(),r.end(),_mapping); return binner; }, [&] (const SpatialBinner& b0, const SpatialBinner& b1) -> SpatialBinner { return SpatialBinner::reduce(b0,b1); }); - /* todo: best spatial split not exeeding the extended range does not provide any benefit ?*/ + /* todo: best spatial split not exceeding the extended range does not provide any benefit ?*/ return binner.best(mapping,logBlockSize); //,set.ext_size()); } @@ -286,6 +286,7 @@ namespace embree //int bin0 = split.mapping.bin(prims0[i].lower)[split.dim]; //int bin1 = split.mapping.bin(prims0[i].upper)[split.dim]; //if (unlikely(bin0 < split.pos && bin1 >= split.pos)) + if (unlikely(prims0[i].lower[split.dim] < fpos && prims0[i].upper[split.dim] > fpos)) { assert(splits > 1); @@ -384,8 +385,8 @@ namespace embree new (&lset) PrimInfoExtRange(begin,center,center,local_left); new (&rset) PrimInfoExtRange(center,end,end,local_right); - assert(area(lset.geomBounds) >= 0.0f); - assert(area(rset.geomBounds) >= 0.0f); + assert(!lset.geomBounds.empty() && area(lset.geomBounds) >= 0.0f); + assert(!rset.geomBounds.empty() && area(rset.geomBounds) >= 0.0f); return std::pair<size_t,size_t>(left_weight,right_weight); } @@ -410,7 +411,7 @@ namespace embree begin,end,local_left,local_right, [&] (const PrimRef& ref) { const Vec3fa c = ref.bounds().center(); - return any(((vint4)mapping.bin(c) < vSplitPos) & vSplitMask); + return any(((vint4)mapping.bin(c) < vSplitPos) & vSplitMask); }, [] (PrimInfo& pinfo,const PrimRef& ref) { pinfo.add_center2(ref,ref.lower.u >> (32-RESERVED_NUM_SPATIAL_SPLITS_GEOMID_BITS)); }); @@ -419,8 +420,8 @@ namespace embree new (&lset) PrimInfoExtRange(begin,center,center,local_left); new (&rset) PrimInfoExtRange(center,end,end,local_right); - assert(area(lset.geomBounds) >= 0.0f); - assert(area(rset.geomBounds) >= 0.0f); + assert(!lset.geomBounds.empty() && area(lset.geomBounds) >= 0.0f); + assert(!rset.geomBounds.empty() && area(rset.geomBounds) >= 0.0f); return std::pair<size_t,size_t>(left_weight,right_weight); } diff --git a/thirdparty/embree/kernels/builders/primrefgen.cpp b/thirdparty/embree/kernels/builders/primrefgen.cpp index d279dc4993..e2d7c27bd8 100644 --- a/thirdparty/embree/kernels/builders/primrefgen.cpp +++ b/thirdparty/embree/kernels/builders/primrefgen.cpp @@ -184,9 +184,7 @@ namespace embree // special variants for grid meshes -// -- GODOT start -- #if defined(EMBREE_GEOMETRY_GRID) -// -- GODOT end -- PrimInfo createPrimRefArrayGrids(Scene* scene, mvector<PrimRef>& prims, mvector<SubGridBuildData>& sgrids) { PrimInfo pinfo(empty); @@ -296,9 +294,7 @@ namespace embree return pinfo; } -// -- GODOT start -- #endif -// -- GODOT end -- // ==================================================================================================== // ==================================================================================================== diff --git a/thirdparty/embree/kernels/builders/primrefgen_presplit.h b/thirdparty/embree/kernels/builders/primrefgen_presplit.h index 8cd251ddd2..aa2026a85e 100644 --- a/thirdparty/embree/kernels/builders/primrefgen_presplit.h +++ b/thirdparty/embree/kernels/builders/primrefgen_presplit.h @@ -266,7 +266,7 @@ namespace embree /* anything to split ? */ if (center < numPrimitives) { - const size_t numPrimitivesToSplit = numPrimitives - center; + size_t numPrimitivesToSplit = numPrimitives - center; assert(presplitItem[center].priority >= 1.0f); /* sort presplit items in ascending order */ @@ -279,8 +279,8 @@ namespace embree }); ); - unsigned int *const primOffset0 = (unsigned int*)tmp_presplitItem; - unsigned int *const primOffset1 = (unsigned int*)tmp_presplitItem + numPrimitivesToSplit; + unsigned int* primOffset0 = (unsigned int*)tmp_presplitItem; + unsigned int* primOffset1 = (unsigned int*)tmp_presplitItem + numPrimitivesToSplit; /* compute actual number of sub-primitives generated within the [center;numPrimitives-1] range */ const size_t totalNumSubPrims = parallel_reduce( size_t(center), numPrimitives, size_t(MIN_STEP_SIZE), size_t(0), [&](const range<size_t>& t) -> size_t { @@ -317,11 +317,16 @@ namespace embree sum += numSubPrims; } new_center++; + + primOffset0 += new_center - center; + numPrimitivesToSplit -= new_center - center; center = new_center; + assert(numPrimitivesToSplit == (numPrimitives - center)); } /* parallel prefix sum to compute offsets for storing sub-primitives */ const unsigned int offset = parallel_prefix_sum(primOffset0,primOffset1,numPrimitivesToSplit,(unsigned int)0,std::plus<unsigned int>()); + assert(numPrimitives+offset <= alloc_numPrimitives); /* iterate over range, and split primitives into sub primitives and append them to prims array */ parallel_for( size_t(center), numPrimitives, size_t(MIN_STEP_SIZE), [&](const range<size_t>& rn) -> void { @@ -338,7 +343,7 @@ namespace embree unsigned int numSubPrims = 0; splitPrimitive(Splitter,prims[primrefID],geomID,primID,split_levels,grid_base,grid_scale,grid_extend,subPrims,numSubPrims); const size_t newID = numPrimitives + primOffset1[j-center]; - assert(newID+numSubPrims <= alloc_numPrimitives); + assert(newID+numSubPrims-1 <= alloc_numPrimitives); prims[primrefID] = subPrims[0]; for (size_t i=1;i<numSubPrims;i++) prims[newID+i-1] = subPrims[i]; diff --git a/thirdparty/embree/kernels/builders/splitter.h b/thirdparty/embree/kernels/builders/splitter.h index f7720bd284..da89d0b178 100644 --- a/thirdparty/embree/kernels/builders/splitter.h +++ b/thirdparty/embree/kernels/builders/splitter.h @@ -128,28 +128,30 @@ namespace embree const unsigned int mask = 0xFFFFFFFF >> RESERVED_NUM_SPATIAL_SPLITS_GEOMID_BITS; const QuadMesh* mesh = (const QuadMesh*) scene->get(prim.geomID() & mask ); QuadMesh::Quad quad = mesh->quad(prim.primID()); - v[0] = mesh->vertex(quad.v[0]); - v[1] = mesh->vertex(quad.v[1]); - v[2] = mesh->vertex(quad.v[2]); - v[3] = mesh->vertex(quad.v[3]); - v[4] = mesh->vertex(quad.v[0]); - inv_length[0] = Vec3fa(1.0f) / (v[1]-v[0]); - inv_length[1] = Vec3fa(1.0f) / (v[2]-v[1]); - inv_length[2] = Vec3fa(1.0f) / (v[3]-v[2]); - inv_length[3] = Vec3fa(1.0f) / (v[0]-v[3]); + v[0] = mesh->vertex(quad.v[1]); + v[1] = mesh->vertex(quad.v[2]); + v[2] = mesh->vertex(quad.v[3]); + v[3] = mesh->vertex(quad.v[0]); + v[4] = mesh->vertex(quad.v[1]); + v[5] = mesh->vertex(quad.v[3]); + inv_length[0] = Vec3fa(1.0f) / (v[1] - v[0]); + inv_length[1] = Vec3fa(1.0f) / (v[2] - v[1]); + inv_length[2] = Vec3fa(1.0f) / (v[3] - v[2]); + inv_length[3] = Vec3fa(1.0f) / (v[4] - v[3]); + inv_length[4] = Vec3fa(1.0f) / (v[5] - v[4]); } __forceinline void operator() (const PrimRef& prim, const size_t dim, const float pos, PrimRef& left_o, PrimRef& right_o) const { - splitPolygon<4>(prim,dim,pos,v,left_o,right_o); + splitPolygon<5>(prim,dim,pos,v,left_o,right_o); } __forceinline void operator() (const BBox3fa& prim, const size_t dim, const float pos, BBox3fa& left_o, BBox3fa& right_o) const { - splitPolygon<4>(prim,dim,pos,v,inv_length,left_o,right_o); + splitPolygon<5>(prim,dim,pos,v,inv_length,left_o,right_o); } private: - Vec3fa v[5]; - Vec3fa inv_length[4]; + Vec3fa v[6]; + Vec3fa inv_length[5]; }; struct QuadSplitterFactory diff --git a/thirdparty/embree/kernels/bvh/bvh.cpp b/thirdparty/embree/kernels/bvh/bvh.cpp index a84295f0da..f6cf626465 100644 --- a/thirdparty/embree/kernels/bvh/bvh.cpp +++ b/thirdparty/embree/kernels/bvh/bvh.cpp @@ -183,7 +183,7 @@ namespace embree template class BVHN<8>; #endif -#if !defined(__AVX__) || !defined(EMBREE_TARGET_SSE2) && !defined(EMBREE_TARGET_SSE42) +#if !defined(__AVX__) || !defined(EMBREE_TARGET_SSE2) && !defined(EMBREE_TARGET_SSE42) || defined(__aarch64__) template class BVHN<4>; #endif } diff --git a/thirdparty/embree/kernels/bvh/bvh_intersector_hybrid.cpp b/thirdparty/embree/kernels/bvh/bvh_intersector_hybrid.cpp index 6e9a5a538e..1d393fd06b 100644 --- a/thirdparty/embree/kernels/bvh/bvh_intersector_hybrid.cpp +++ b/thirdparty/embree/kernels/bvh/bvh_intersector_hybrid.cpp @@ -230,7 +230,7 @@ namespace embree continue; /* switch to single ray traversal */ -#if (!defined(__WIN32__) || defined(__X86_64__)) && defined(__SSE4_2__) +#if (!defined(__WIN32__) || defined(__X86_64__)) && ((defined(__aarch64__)) || defined(__SSE4_2__)) #if FORCE_SINGLE_MODE == 0 if (single) #endif @@ -676,7 +676,7 @@ namespace embree continue; /* switch to single ray traversal */ -#if (!defined(__WIN32__) || defined(__X86_64__)) && defined(__SSE4_2__) +#if (!defined(__WIN32__) || defined(__X86_64__)) && ((defined(__aarch64__)) || defined(__SSE4_2__)) #if FORCE_SINGLE_MODE == 0 if (single) #endif diff --git a/thirdparty/embree/kernels/bvh/bvh_intersector_stream.h b/thirdparty/embree/kernels/bvh/bvh_intersector_stream.h index 717f559677..c7e040fadb 100644 --- a/thirdparty/embree/kernels/bvh/bvh_intersector_stream.h +++ b/thirdparty/embree/kernels/bvh/bvh_intersector_stream.h @@ -170,12 +170,23 @@ namespace embree TravRayKStream<K,robust> &p = packets[rayID / K]; const size_t i = rayID % K; const vint<N> bitmask(shiftTable[rayID]); + +#if defined (__aarch64__) + const vfloat<N> tNearX = madd(bminX, p.rdir.x[i], p.neg_org_rdir.x[i]); + const vfloat<N> tNearY = madd(bminY, p.rdir.y[i], p.neg_org_rdir.y[i]); + const vfloat<N> tNearZ = madd(bminZ, p.rdir.z[i], p.neg_org_rdir.z[i]); + const vfloat<N> tFarX = madd(bmaxX, p.rdir.x[i], p.neg_org_rdir.x[i]); + const vfloat<N> tFarY = madd(bmaxY, p.rdir.y[i], p.neg_org_rdir.y[i]); + const vfloat<N> tFarZ = madd(bmaxZ, p.rdir.z[i], p.neg_org_rdir.z[i]); +#else const vfloat<N> tNearX = msub(bminX, p.rdir.x[i], p.org_rdir.x[i]); const vfloat<N> tNearY = msub(bminY, p.rdir.y[i], p.org_rdir.y[i]); const vfloat<N> tNearZ = msub(bminZ, p.rdir.z[i], p.org_rdir.z[i]); const vfloat<N> tFarX = msub(bmaxX, p.rdir.x[i], p.org_rdir.x[i]); const vfloat<N> tFarY = msub(bmaxY, p.rdir.y[i], p.org_rdir.y[i]); const vfloat<N> tFarZ = msub(bmaxZ, p.rdir.z[i], p.org_rdir.z[i]); +#endif + const vfloat<N> tNear = maxi(tNearX, tNearY, tNearZ, vfloat<N>(p.tnear[i])); const vfloat<N> tFar = mini(tFarX , tFarY , tFarZ, vfloat<N>(p.tfar[i])); diff --git a/thirdparty/embree/kernels/bvh/bvh_node_aabb.h b/thirdparty/embree/kernels/bvh/bvh_node_aabb.h index 57530692bc..3fd9fc7d18 100644 --- a/thirdparty/embree/kernels/bvh/bvh_node_aabb.h +++ b/thirdparty/embree/kernels/bvh/bvh_node_aabb.h @@ -46,6 +46,14 @@ namespace embree template<typename BuildRecord> __forceinline NodeRef operator() (const BuildRecord& precord, const BuildRecord* crecords, NodeRef ref, NodeRef* children, const size_t num) const { +#if defined(DEBUG) + // check that empty children are only at the end of the child list + bool emptyChild = false; + for (size_t i=0; i<num; i++) { + emptyChild |= (children[i] == NodeRef::emptyNode); + assert(emptyChild == (children[i] == NodeRef::emptyNode)); + } +#endif AABBNode_t* node = ref.getAABBNode(); for (size_t i=0; i<num; i++) node->setRef(i,children[i]); return ref; @@ -60,6 +68,14 @@ namespace embree template<typename BuildRecord> __forceinline NodeRef operator() (const BuildRecord& precord, const BuildRecord* crecords, NodeRef ref, NodeRef* children, const size_t num) const { +#if defined(DEBUG) + // check that empty children are only at the end of the child list + bool emptyChild = false; + for (size_t i=0; i<num; i++) { + emptyChild |= (children[i] == NodeRef::emptyNode); + assert(emptyChild == (children[i] == NodeRef::emptyNode)); + } +#endif AABBNode_t* node = ref.getAABBNode(); for (size_t i=0; i<num; i++) node->setRef(i,children[i]); diff --git a/thirdparty/embree/kernels/bvh/bvh_node_aabb_mb.h b/thirdparty/embree/kernels/bvh/bvh_node_aabb_mb.h index c4cea7d8ba..001f526c25 100644 --- a/thirdparty/embree/kernels/bvh/bvh_node_aabb_mb.h +++ b/thirdparty/embree/kernels/bvh/bvh_node_aabb_mb.h @@ -31,6 +31,14 @@ namespace embree template<typename BuildRecord> __forceinline NodeRecordMB operator() (const BuildRecord& precord, const BuildRecord* crecords, NodeRef ref, NodeRecordMB* children, const size_t num) const { +#if defined(DEBUG) + // check that empty children are only at the end of the child list + bool emptyChild = false; + for (size_t i=0; i<num; i++) { + emptyChild |= (children[i].ref == NodeRef::emptyNode); + assert(emptyChild == (children[i].ref == NodeRef::emptyNode)); + } +#endif AABBNodeMB_t* node = ref.getAABBNodeMB(); LBBox3fa bounds = empty; diff --git a/thirdparty/embree/kernels/bvh/bvh_node_aabb_mb4d.h b/thirdparty/embree/kernels/bvh/bvh_node_aabb_mb4d.h index 46a81d7581..3b966fd054 100644 --- a/thirdparty/embree/kernels/bvh/bvh_node_aabb_mb4d.h +++ b/thirdparty/embree/kernels/bvh/bvh_node_aabb_mb4d.h @@ -41,6 +41,14 @@ namespace embree template<typename BuildRecord> __forceinline void operator() (const BuildRecord&, const BuildRecord*, NodeRef ref, NodeRecordMB4D* children, const size_t num) const { +#if defined(DEBUG) + // check that empty children are only at the end of the child list + bool emptyChild = false; + for (size_t i=0; i<num; i++) { + emptyChild |= (children[i].ref == NodeRef::emptyNode); + assert(emptyChild == (children[i].ref == NodeRef::emptyNode)); + } +#endif if (likely(ref.isAABBNodeMB())) { for (size_t i=0; i<num; i++) ref.getAABBNodeMB()->set(i, children[i]); diff --git a/thirdparty/embree/kernels/bvh/bvh_node_qaabb.h b/thirdparty/embree/kernels/bvh/bvh_node_qaabb.h index 2afc8c98e7..99671ddc5a 100644 --- a/thirdparty/embree/kernels/bvh/bvh_node_qaabb.h +++ b/thirdparty/embree/kernels/bvh/bvh_node_qaabb.h @@ -190,6 +190,14 @@ namespace embree template<typename BuildRecord> __forceinline NodeRef operator() (const BuildRecord& precord, const BuildRecord* crecords, NodeRef ref, NodeRef* children, const size_t num) const { +#if defined(DEBUG) + // check that empty children are only at the end of the child list + bool emptyChild = false; + for (size_t i=0; i<num; i++) { + emptyChild |= (children[i] == NodeRef::emptyNode); + assert(emptyChild == (children[i] == NodeRef::emptyNode)); + } +#endif QuantizedNode_t* node = ref.quantizedNode(); for (size_t i=0; i<num; i++) node->setRef(i,children[i]); return ref; diff --git a/thirdparty/embree/kernels/bvh/bvh_statistics.cpp b/thirdparty/embree/kernels/bvh/bvh_statistics.cpp index d857ff7d95..57f75bfd7e 100644 --- a/thirdparty/embree/kernels/bvh/bvh_statistics.cpp +++ b/thirdparty/embree/kernels/bvh/bvh_statistics.cpp @@ -162,7 +162,7 @@ namespace embree template class BVHNStatistics<8>; #endif -#if !defined(__AVX__) || !defined(EMBREE_TARGET_SSE2) && !defined(EMBREE_TARGET_SSE42) +#if !defined(__AVX__) || (!defined(EMBREE_TARGET_SSE2) && !defined(EMBREE_TARGET_SSE42)) || defined(__aarch64__) template class BVHNStatistics<4>; #endif } diff --git a/thirdparty/embree/kernels/bvh/node_intersector1.h b/thirdparty/embree/kernels/bvh/node_intersector1.h index 1ec4fc63fc..17641fa888 100644 --- a/thirdparty/embree/kernels/bvh/node_intersector1.h +++ b/thirdparty/embree/kernels/bvh/node_intersector1.h @@ -5,6 +5,15 @@ #include "node_intersector.h" +#if defined(__AVX2__) +#define __FMA_X4__ +#endif + +#if defined(__aarch64__) +#define __FMA_X4__ +#endif + + namespace embree { namespace isa @@ -29,9 +38,15 @@ namespace embree org = Vec3vf<N>(ray_org.x,ray_org.y,ray_org.z); dir = Vec3vf<N>(ray_dir.x,ray_dir.y,ray_dir.z); rdir = Vec3vf<N>(ray_rdir.x,ray_rdir.y,ray_rdir.z); -#if defined(__AVX2__) || defined(__ARM_NEON) +#if defined(__FMA_X4__) const Vec3fa ray_org_rdir = ray_org*ray_rdir; +#if !defined(__aarch64__) org_rdir = Vec3vf<N>(ray_org_rdir.x,ray_org_rdir.y,ray_org_rdir.z); +#else + //for aarch64, we do not have msub equal instruction, so we negeate orig and use madd + //x86 will use msub + neg_org_rdir = Vec3vf<N>(-ray_org_rdir.x,-ray_org_rdir.y,-ray_org_rdir.z); +#endif #endif nearX = ray_rdir.x >= 0.0f ? 0*sizeof(vfloat<N>) : 1*sizeof(vfloat<N>); nearY = ray_rdir.y >= 0.0f ? 2*sizeof(vfloat<N>) : 3*sizeof(vfloat<N>); @@ -49,8 +64,12 @@ namespace embree org = Vec3vf<N>(ray_org.x[k], ray_org.y[k], ray_org.z[k]); dir = Vec3vf<N>(ray_dir.x[k], ray_dir.y[k], ray_dir.z[k]); rdir = Vec3vf<N>(ray_rdir.x[k], ray_rdir.y[k], ray_rdir.z[k]); -#if defined(__AVX2__) || defined(__ARM_NEON) - org_rdir = org*rdir; +#if defined(__FMA_X4__) +#if !defined(__aarch64__) + org_rdir = org*rdir; +#else + neg_org_rdir = -(org*rdir); +#endif #endif nearX = nearXYZ.x[k]; nearY = nearXYZ.y[k]; @@ -62,8 +81,14 @@ namespace embree Vec3fa org_xyz, dir_xyz; Vec3vf<N> org, dir, rdir; -#if defined(__AVX2__) || defined(__ARM_NEON) +#if defined(__FMA_X4__) +#if !defined(__aarch64__) Vec3vf<N> org_rdir; +#else + //aarch64 version are keeping negation of the org_rdir and use madd + //x86 uses msub + Vec3vf<N> neg_org_rdir; +#endif #endif size_t nearX, nearY, nearZ; size_t farX, farY, farZ; @@ -404,13 +429,22 @@ namespace embree template<> __forceinline size_t intersectNode<4>(const typename BVH4::AABBNode* node, const TravRay<4,false>& ray, vfloat4& dist) { -#if defined(__AVX2__) || defined(__ARM_NEON) +#if defined(__FMA_X4__) +#if defined(__aarch64__) + const vfloat4 tNearX = madd(vfloat4::load((float*)((const char*)&node->lower_x+ray.nearX)), ray.rdir.x, ray.neg_org_rdir.x); + const vfloat4 tNearY = madd(vfloat4::load((float*)((const char*)&node->lower_x+ray.nearY)), ray.rdir.y, ray.neg_org_rdir.y); + const vfloat4 tNearZ = madd(vfloat4::load((float*)((const char*)&node->lower_x+ray.nearZ)), ray.rdir.z, ray.neg_org_rdir.z); + const vfloat4 tFarX = madd(vfloat4::load((float*)((const char*)&node->lower_x+ray.farX )), ray.rdir.x, ray.neg_org_rdir.x); + const vfloat4 tFarY = madd(vfloat4::load((float*)((const char*)&node->lower_x+ray.farY )), ray.rdir.y, ray.neg_org_rdir.y); + const vfloat4 tFarZ = madd(vfloat4::load((float*)((const char*)&node->lower_x+ray.farZ )), ray.rdir.z, ray.neg_org_rdir.z); +#else const vfloat4 tNearX = msub(vfloat4::load((float*)((const char*)&node->lower_x+ray.nearX)), ray.rdir.x, ray.org_rdir.x); const vfloat4 tNearY = msub(vfloat4::load((float*)((const char*)&node->lower_x+ray.nearY)), ray.rdir.y, ray.org_rdir.y); const vfloat4 tNearZ = msub(vfloat4::load((float*)((const char*)&node->lower_x+ray.nearZ)), ray.rdir.z, ray.org_rdir.z); const vfloat4 tFarX = msub(vfloat4::load((float*)((const char*)&node->lower_x+ray.farX )), ray.rdir.x, ray.org_rdir.x); const vfloat4 tFarY = msub(vfloat4::load((float*)((const char*)&node->lower_x+ray.farY )), ray.rdir.y, ray.org_rdir.y); const vfloat4 tFarZ = msub(vfloat4::load((float*)((const char*)&node->lower_x+ray.farZ )), ray.rdir.z, ray.org_rdir.z); +#endif #else const vfloat4 tNearX = (vfloat4::load((float*)((const char*)&node->lower_x+ray.nearX)) - ray.org.x) * ray.rdir.x; const vfloat4 tNearY = (vfloat4::load((float*)((const char*)&node->lower_x+ray.nearY)) - ray.org.y) * ray.rdir.y; @@ -450,13 +484,23 @@ namespace embree template<> __forceinline size_t intersectNode<8>(const typename BVH8::AABBNode* node, const TravRay<8,false>& ray, vfloat8& dist) { -#if defined(__AVX2__) || defined(__ARM_NEON) +#if defined(__AVX2__) +#if defined(__aarch64__) + const vfloat8 tNearX = madd(vfloat8::load((float*)((const char*)&node->lower_x+ray.nearX)), ray.rdir.x, ray.neg_org_rdir.x); + const vfloat8 tNearY = madd(vfloat8::load((float*)((const char*)&node->lower_x+ray.nearY)), ray.rdir.y, ray.neg_org_rdir.y); + const vfloat8 tNearZ = madd(vfloat8::load((float*)((const char*)&node->lower_x+ray.nearZ)), ray.rdir.z, ray.neg_org_rdir.z); + const vfloat8 tFarX = madd(vfloat8::load((float*)((const char*)&node->lower_x+ray.farX )), ray.rdir.x, ray.neg_org_rdir.x); + const vfloat8 tFarY = madd(vfloat8::load((float*)((const char*)&node->lower_x+ray.farY )), ray.rdir.y, ray.neg_org_rdir.y); + const vfloat8 tFarZ = madd(vfloat8::load((float*)((const char*)&node->lower_x+ray.farZ )), ray.rdir.z, ray.neg_org_rdir.z); +#else const vfloat8 tNearX = msub(vfloat8::load((float*)((const char*)&node->lower_x+ray.nearX)), ray.rdir.x, ray.org_rdir.x); const vfloat8 tNearY = msub(vfloat8::load((float*)((const char*)&node->lower_x+ray.nearY)), ray.rdir.y, ray.org_rdir.y); const vfloat8 tNearZ = msub(vfloat8::load((float*)((const char*)&node->lower_x+ray.nearZ)), ray.rdir.z, ray.org_rdir.z); const vfloat8 tFarX = msub(vfloat8::load((float*)((const char*)&node->lower_x+ray.farX )), ray.rdir.x, ray.org_rdir.x); const vfloat8 tFarY = msub(vfloat8::load((float*)((const char*)&node->lower_x+ray.farY )), ray.rdir.y, ray.org_rdir.y); const vfloat8 tFarZ = msub(vfloat8::load((float*)((const char*)&node->lower_x+ray.farZ )), ray.rdir.z, ray.org_rdir.z); +#endif + #else const vfloat8 tNearX = (vfloat8::load((float*)((const char*)&node->lower_x+ray.nearX)) - ray.org.x) * ray.rdir.x; const vfloat8 tNearY = (vfloat8::load((float*)((const char*)&node->lower_x+ray.nearY)) - ray.org.y) * ray.rdir.y; @@ -522,13 +566,22 @@ namespace embree const vfloat<N>* pFarX = (const vfloat<N>*)((const char*)&node->lower_x+ray.farX); const vfloat<N>* pFarY = (const vfloat<N>*)((const char*)&node->lower_x+ray.farY); const vfloat<N>* pFarZ = (const vfloat<N>*)((const char*)&node->lower_x+ray.farZ); -#if defined(__AVX2__) || defined(__ARM_NEON) +#if defined(__FMA_X4__) +#if defined(__aarch64__) + const vfloat<N> tNearX = madd(madd(time,pNearX[6],vfloat<N>(pNearX[0])), ray.rdir.x, ray.neg_org_rdir.x); + const vfloat<N> tNearY = madd(madd(time,pNearY[6],vfloat<N>(pNearY[0])), ray.rdir.y, ray.neg_org_rdir.y); + const vfloat<N> tNearZ = madd(madd(time,pNearZ[6],vfloat<N>(pNearZ[0])), ray.rdir.z, ray.neg_org_rdir.z); + const vfloat<N> tFarX = madd(madd(time,pFarX [6],vfloat<N>(pFarX [0])), ray.rdir.x, ray.neg_org_rdir.x); + const vfloat<N> tFarY = madd(madd(time,pFarY [6],vfloat<N>(pFarY [0])), ray.rdir.y, ray.neg_org_rdir.y); + const vfloat<N> tFarZ = madd(madd(time,pFarZ [6],vfloat<N>(pFarZ [0])), ray.rdir.z, ray.neg_org_rdir.z); +#else const vfloat<N> tNearX = msub(madd(time,pNearX[6],vfloat<N>(pNearX[0])), ray.rdir.x, ray.org_rdir.x); const vfloat<N> tNearY = msub(madd(time,pNearY[6],vfloat<N>(pNearY[0])), ray.rdir.y, ray.org_rdir.y); const vfloat<N> tNearZ = msub(madd(time,pNearZ[6],vfloat<N>(pNearZ[0])), ray.rdir.z, ray.org_rdir.z); const vfloat<N> tFarX = msub(madd(time,pFarX [6],vfloat<N>(pFarX [0])), ray.rdir.x, ray.org_rdir.x); const vfloat<N> tFarY = msub(madd(time,pFarY [6],vfloat<N>(pFarY [0])), ray.rdir.y, ray.org_rdir.y); const vfloat<N> tFarZ = msub(madd(time,pFarZ [6],vfloat<N>(pFarZ [0])), ray.rdir.z, ray.org_rdir.z); +#endif #else const vfloat<N> tNearX = (madd(time,pNearX[6],vfloat<N>(pNearX[0])) - ray.org.x) * ray.rdir.x; const vfloat<N> tNearY = (madd(time,pNearY[6],vfloat<N>(pNearY[0])) - ray.org.y) * ray.rdir.y; @@ -537,7 +590,7 @@ namespace embree const vfloat<N> tFarY = (madd(time,pFarY [6],vfloat<N>(pFarY [0])) - ray.org.y) * ray.rdir.y; const vfloat<N> tFarZ = (madd(time,pFarZ [6],vfloat<N>(pFarZ [0])) - ray.org.z) * ray.rdir.z; #endif -#if defined(__AVX2__) && !defined(__AVX512F__) // HSW +#if defined(__FMA_X4__) && !defined(__AVX512F__) // HSW const vfloat<N> tNear = maxi(tNearX,tNearY,tNearZ,ray.tnear); const vfloat<N> tFar = mini(tFarX ,tFarY ,tFarZ ,ray.tfar); const vbool<N> vmask = asInt(tNear) > asInt(tFar); @@ -598,13 +651,22 @@ namespace embree const vfloat<N>* pFarX = (const vfloat<N>*)((const char*)&node->lower_x+ray.farX); const vfloat<N>* pFarY = (const vfloat<N>*)((const char*)&node->lower_x+ray.farY); const vfloat<N>* pFarZ = (const vfloat<N>*)((const char*)&node->lower_x+ray.farZ); -#if defined (__AVX2__) || defined(__ARM_NEON) +#if defined (__FMA_X4__) +#if defined(__aarch64__) + const vfloat<N> tNearX = madd(madd(time,pNearX[6],vfloat<N>(pNearX[0])), ray.rdir.x, ray.neg_org_rdir.x); + const vfloat<N> tNearY = madd(madd(time,pNearY[6],vfloat<N>(pNearY[0])), ray.rdir.y, ray.neg_org_rdir.y); + const vfloat<N> tNearZ = madd(madd(time,pNearZ[6],vfloat<N>(pNearZ[0])), ray.rdir.z, ray.neg_org_rdir.z); + const vfloat<N> tFarX = madd(madd(time,pFarX [6],vfloat<N>(pFarX [0])), ray.rdir.x, ray.neg_org_rdir.x); + const vfloat<N> tFarY = madd(madd(time,pFarY [6],vfloat<N>(pFarY [0])), ray.rdir.y, ray.neg_org_rdir.y); + const vfloat<N> tFarZ = madd(madd(time,pFarZ [6],vfloat<N>(pFarZ [0])), ray.rdir.z, ray.neg_org_rdir.z); +#else const vfloat<N> tNearX = msub(madd(time,pNearX[6],vfloat<N>(pNearX[0])), ray.rdir.x, ray.org_rdir.x); const vfloat<N> tNearY = msub(madd(time,pNearY[6],vfloat<N>(pNearY[0])), ray.rdir.y, ray.org_rdir.y); const vfloat<N> tNearZ = msub(madd(time,pNearZ[6],vfloat<N>(pNearZ[0])), ray.rdir.z, ray.org_rdir.z); const vfloat<N> tFarX = msub(madd(time,pFarX [6],vfloat<N>(pFarX [0])), ray.rdir.x, ray.org_rdir.x); const vfloat<N> tFarY = msub(madd(time,pFarY [6],vfloat<N>(pFarY [0])), ray.rdir.y, ray.org_rdir.y); const vfloat<N> tFarZ = msub(madd(time,pFarZ [6],vfloat<N>(pFarZ [0])), ray.rdir.z, ray.org_rdir.z); +#endif #else const vfloat<N> tNearX = (madd(time,pNearX[6],vfloat<N>(pNearX[0])) - ray.org.x) * ray.rdir.x; const vfloat<N> tNearY = (madd(time,pNearY[6],vfloat<N>(pNearY[0])) - ray.org.y) * ray.rdir.y; @@ -613,7 +675,7 @@ namespace embree const vfloat<N> tFarY = (madd(time,pFarY [6],vfloat<N>(pFarY [0])) - ray.org.y) * ray.rdir.y; const vfloat<N> tFarZ = (madd(time,pFarZ [6],vfloat<N>(pFarZ [0])) - ray.org.z) * ray.rdir.z; #endif -#if defined(__AVX2__) && !defined(__AVX512F__) +#if defined(__FMA_X4__) && !defined(__AVX512F__) const vfloat<N> tNear = maxi(maxi(tNearX,tNearY),maxi(tNearZ,ray.tnear)); const vfloat<N> tFar = mini(mini(tFarX ,tFarY ),mini(tFarZ ,ray.tfar )); #else @@ -687,13 +749,22 @@ namespace embree const vfloat4 lower_z = madd(node->dequantize<4>(ray.nearZ >> 2),scale_z,start_z); const vfloat4 upper_z = madd(node->dequantize<4>(ray.farZ >> 2),scale_z,start_z); -#if defined(__AVX2__) || defined(__ARM_NEON) +#if defined(__FMA_X4__) +#if defined(__aarch64__) + const vfloat4 tNearX = madd(lower_x, ray.rdir.x, ray.neg_org_rdir.x); + const vfloat4 tNearY = madd(lower_y, ray.rdir.y, ray.neg_org_rdir.y); + const vfloat4 tNearZ = madd(lower_z, ray.rdir.z, ray.neg_org_rdir.z); + const vfloat4 tFarX = madd(upper_x, ray.rdir.x, ray.neg_org_rdir.x); + const vfloat4 tFarY = madd(upper_y, ray.rdir.y, ray.neg_org_rdir.y); + const vfloat4 tFarZ = madd(upper_z, ray.rdir.z, ray.neg_org_rdir.z); +#else const vfloat4 tNearX = msub(lower_x, ray.rdir.x, ray.org_rdir.x); const vfloat4 tNearY = msub(lower_y, ray.rdir.y, ray.org_rdir.y); const vfloat4 tNearZ = msub(lower_z, ray.rdir.z, ray.org_rdir.z); const vfloat4 tFarX = msub(upper_x, ray.rdir.x, ray.org_rdir.x); const vfloat4 tFarY = msub(upper_y, ray.rdir.y, ray.org_rdir.y); const vfloat4 tFarZ = msub(upper_z, ray.rdir.z, ray.org_rdir.z); +#endif #else const vfloat4 tNearX = (lower_x - ray.org.x) * ray.rdir.x; const vfloat4 tNearY = (lower_y - ray.org.y) * ray.rdir.y; @@ -703,7 +774,7 @@ namespace embree const vfloat4 tFarZ = (upper_z - ray.org.z) * ray.rdir.z; #endif -#if defined(__SSE4_1__) && !defined(__AVX512F__) // up to HSW +#if defined(__aarch64__) || defined(__SSE4_1__) && !defined(__AVX512F__) // up to HSW const vfloat4 tNear = maxi(tNearX,tNearY,tNearZ,ray.tnear); const vfloat4 tFar = mini(tFarX ,tFarY ,tFarZ ,ray.tfar); const vbool4 vmask = asInt(tNear) > asInt(tFar); @@ -775,13 +846,22 @@ namespace embree const vfloat8 lower_z = madd(node->dequantize<8>(ray.nearZ >> 2),scale_z,start_z); const vfloat8 upper_z = madd(node->dequantize<8>(ray.farZ >> 2),scale_z,start_z); -#if defined(__AVX2__) || defined(__ARM_NEON) +#if defined(__AVX2__) +#if defined(__aarch64__) + const vfloat8 tNearX = madd(lower_x, ray.rdir.x, ray.neg_org_rdir.x); + const vfloat8 tNearY = madd(lower_y, ray.rdir.y, ray.neg_org_rdir.y); + const vfloat8 tNearZ = madd(lower_z, ray.rdir.z, ray.neg_org_rdir.z); + const vfloat8 tFarX = madd(upper_x, ray.rdir.x, ray.neg_org_rdir.x); + const vfloat8 tFarY = madd(upper_y, ray.rdir.y, ray.neg_org_rdir.y); + const vfloat8 tFarZ = madd(upper_z, ray.rdir.z, ray.neg_org_rdir.z); +#else const vfloat8 tNearX = msub(lower_x, ray.rdir.x, ray.org_rdir.x); const vfloat8 tNearY = msub(lower_y, ray.rdir.y, ray.org_rdir.y); const vfloat8 tNearZ = msub(lower_z, ray.rdir.z, ray.org_rdir.z); const vfloat8 tFarX = msub(upper_x, ray.rdir.x, ray.org_rdir.x); const vfloat8 tFarY = msub(upper_y, ray.rdir.y, ray.org_rdir.y); const vfloat8 tFarZ = msub(upper_z, ray.rdir.z, ray.org_rdir.z); +#endif #else const vfloat8 tNearX = (lower_x - ray.org.x) * ray.rdir.x; const vfloat8 tNearY = (lower_y - ray.org.y) * ray.rdir.y; @@ -857,13 +937,22 @@ namespace embree const vfloat<N> upper_y = node->dequantizeUpperY(time); const vfloat<N> lower_z = node->dequantizeLowerZ(time); const vfloat<N> upper_z = node->dequantizeUpperZ(time); -#if defined(__AVX2__) || defined(__ARM_NEON) +#if defined(__FMA_X4__) +#if defined(__aarch64__) + const vfloat<N> tNearX = madd(lower_x, ray.rdir.x, ray.neg_org_rdir.x); + const vfloat<N> tNearY = madd(lower_y, ray.rdir.y, ray.neg_org_rdir.y); + const vfloat<N> tNearZ = madd(lower_z, ray.rdir.z, ray.neg_org_rdir.z); + const vfloat<N> tFarX = madd(upper_x, ray.rdir.x, ray.neg_org_rdir.x); + const vfloat<N> tFarY = madd(upper_y, ray.rdir.y, ray.neg_org_rdir.y); + const vfloat<N> tFarZ = madd(upper_z, ray.rdir.z, ray.neg_org_rdir.z); +#else const vfloat<N> tNearX = msub(lower_x, ray.rdir.x, ray.org_rdir.x); const vfloat<N> tNearY = msub(lower_y, ray.rdir.y, ray.org_rdir.y); const vfloat<N> tNearZ = msub(lower_z, ray.rdir.z, ray.org_rdir.z); const vfloat<N> tFarX = msub(upper_x, ray.rdir.x, ray.org_rdir.x); const vfloat<N> tFarY = msub(upper_y, ray.rdir.y, ray.org_rdir.y); const vfloat<N> tFarZ = msub(upper_z, ray.rdir.z, ray.org_rdir.z); +#endif #else const vfloat<N> tNearX = (lower_x - ray.org.x) * ray.rdir.x; const vfloat<N> tNearY = (lower_y - ray.org.y) * ray.rdir.y; diff --git a/thirdparty/embree/kernels/bvh/node_intersector_frustum.h b/thirdparty/embree/kernels/bvh/node_intersector_frustum.h index 1f7215e5df..cad4e6de2d 100644 --- a/thirdparty/embree/kernels/bvh/node_intersector_frustum.h +++ b/thirdparty/embree/kernels/bvh/node_intersector_frustum.h @@ -75,9 +75,13 @@ namespace embree min_rdir = select(pos_rdir, reduced_min_rdir, reduced_max_rdir); max_rdir = select(pos_rdir, reduced_max_rdir, reduced_min_rdir); +#if defined (__aarch64__) + neg_min_org_rdir = -(min_rdir * select(pos_rdir, reduced_max_org, reduced_min_org)); + neg_max_org_rdir = -(max_rdir * select(pos_rdir, reduced_min_org, reduced_max_org)); +#else min_org_rdir = min_rdir * select(pos_rdir, reduced_max_org, reduced_min_org); max_org_rdir = max_rdir * select(pos_rdir, reduced_min_org, reduced_max_org); - +#endif min_dist = reduced_min_dist; max_dist = reduced_max_dist; @@ -95,9 +99,13 @@ namespace embree Vec3fa min_rdir; Vec3fa max_rdir; +#if defined (__aarch64__) + Vec3fa neg_min_org_rdir; + Vec3fa neg_max_org_rdir; +#else Vec3fa min_org_rdir; Vec3fa max_org_rdir; - +#endif float min_dist; float max_dist; }; @@ -191,13 +199,21 @@ namespace embree const vfloat<N> bmaxY = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.farY); const vfloat<N> bmaxZ = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.farZ); +#if defined (__aarch64__) + const vfloat<N> fminX = madd(bminX, vfloat<N>(frustum.min_rdir.x), vfloat<N>(frustum.neg_min_org_rdir.x)); + const vfloat<N> fminY = madd(bminY, vfloat<N>(frustum.min_rdir.y), vfloat<N>(frustum.neg_min_org_rdir.y)); + const vfloat<N> fminZ = madd(bminZ, vfloat<N>(frustum.min_rdir.z), vfloat<N>(frustum.neg_min_org_rdir.z)); + const vfloat<N> fmaxX = madd(bmaxX, vfloat<N>(frustum.max_rdir.x), vfloat<N>(frustum.neg_max_org_rdir.x)); + const vfloat<N> fmaxY = madd(bmaxY, vfloat<N>(frustum.max_rdir.y), vfloat<N>(frustum.neg_max_org_rdir.y)); + const vfloat<N> fmaxZ = madd(bmaxZ, vfloat<N>(frustum.max_rdir.z), vfloat<N>(frustum.neg_max_org_rdir.z)); +#else const vfloat<N> fminX = msub(bminX, vfloat<N>(frustum.min_rdir.x), vfloat<N>(frustum.min_org_rdir.x)); const vfloat<N> fminY = msub(bminY, vfloat<N>(frustum.min_rdir.y), vfloat<N>(frustum.min_org_rdir.y)); const vfloat<N> fminZ = msub(bminZ, vfloat<N>(frustum.min_rdir.z), vfloat<N>(frustum.min_org_rdir.z)); const vfloat<N> fmaxX = msub(bmaxX, vfloat<N>(frustum.max_rdir.x), vfloat<N>(frustum.max_org_rdir.x)); const vfloat<N> fmaxY = msub(bmaxY, vfloat<N>(frustum.max_rdir.y), vfloat<N>(frustum.max_org_rdir.y)); const vfloat<N> fmaxZ = msub(bmaxZ, vfloat<N>(frustum.max_rdir.z), vfloat<N>(frustum.max_org_rdir.z)); - +#endif const vfloat<N> fmin = maxi(fminX, fminY, fminZ, vfloat<N>(frustum.min_dist)); dist = fmin; const vfloat<N> fmax = mini(fmaxX, fmaxY, fmaxZ, vfloat<N>(frustum.max_dist)); diff --git a/thirdparty/embree/kernels/bvh/node_intersector_packet.h b/thirdparty/embree/kernels/bvh/node_intersector_packet.h index d5498fc5db..4deacd620d 100644 --- a/thirdparty/embree/kernels/bvh/node_intersector_packet.h +++ b/thirdparty/embree/kernels/bvh/node_intersector_packet.h @@ -39,7 +39,9 @@ namespace embree org = ray_org; dir = ray_dir; rdir = rcp_safe(ray_dir); -#if defined(__AVX2__) || defined(__ARM_NEON) +#if defined(__aarch64__) + neg_org_rdir = -(org * rdir); +#elif defined(__AVX2__) org_rdir = org * rdir; #endif @@ -55,7 +57,9 @@ namespace embree Vec3vf<K> org; Vec3vf<K> dir; Vec3vf<K> rdir; -#if defined(__AVX2__) || defined(__ARM_NEON) +#if defined(__aarch64__) + Vec3vf<K> neg_org_rdir; +#elif defined(__AVX2__) Vec3vf<K> org_rdir; #endif Vec3vi<K> nearXYZ; @@ -119,7 +123,14 @@ namespace embree const TravRayKFast<K>& ray, vfloat<K>& dist) { - #if defined(__AVX2__) || defined(__ARM_NEON) +#if defined(__aarch64__) + const vfloat<K> lclipMinX = madd(node->lower_x[i], ray.rdir.x, ray.neg_org_rdir.x); + const vfloat<K> lclipMinY = madd(node->lower_y[i], ray.rdir.y, ray.neg_org_rdir.y); + const vfloat<K> lclipMinZ = madd(node->lower_z[i], ray.rdir.z, ray.neg_org_rdir.z); + const vfloat<K> lclipMaxX = madd(node->upper_x[i], ray.rdir.x, ray.neg_org_rdir.x); + const vfloat<K> lclipMaxY = madd(node->upper_y[i], ray.rdir.y, ray.neg_org_rdir.y); + const vfloat<K> lclipMaxZ = madd(node->upper_z[i], ray.rdir.z, ray.neg_org_rdir.z); +#elif defined(__AVX2__) const vfloat<K> lclipMinX = msub(node->lower_x[i], ray.rdir.x, ray.org_rdir.x); const vfloat<K> lclipMinY = msub(node->lower_y[i], ray.rdir.y, ray.org_rdir.y); const vfloat<K> lclipMinZ = msub(node->lower_z[i], ray.rdir.z, ray.org_rdir.z); @@ -199,7 +210,14 @@ namespace embree const vfloat<K> vupper_y = madd(time, vfloat<K>(node->upper_dy[i]), vfloat<K>(node->upper_y[i])); const vfloat<K> vupper_z = madd(time, vfloat<K>(node->upper_dz[i]), vfloat<K>(node->upper_z[i])); -#if defined(__AVX2__) || defined(__ARM_NEON) +#if defined(__aarch64__) + const vfloat<K> lclipMinX = madd(vlower_x, ray.rdir.x, ray.neg_org_rdir.x); + const vfloat<K> lclipMinY = madd(vlower_y, ray.rdir.y, ray.neg_org_rdir.y); + const vfloat<K> lclipMinZ = madd(vlower_z, ray.rdir.z, ray.neg_org_rdir.z); + const vfloat<K> lclipMaxX = madd(vupper_x, ray.rdir.x, ray.neg_org_rdir.x); + const vfloat<K> lclipMaxY = madd(vupper_y, ray.rdir.y, ray.neg_org_rdir.y); + const vfloat<K> lclipMaxZ = madd(vupper_z, ray.rdir.z, ray.neg_org_rdir.z); +#elif defined(__AVX2__) const vfloat<K> lclipMinX = msub(vlower_x, ray.rdir.x, ray.org_rdir.x); const vfloat<K> lclipMinY = msub(vlower_y, ray.rdir.y, ray.org_rdir.y); const vfloat<K> lclipMinZ = msub(vlower_z, ray.rdir.z, ray.org_rdir.z); @@ -302,7 +320,14 @@ namespace embree const vfloat<K> vupper_y = madd(time, vfloat<K>(node->upper_dy[i]), vfloat<K>(node->upper_y[i])); const vfloat<K> vupper_z = madd(time, vfloat<K>(node->upper_dz[i]), vfloat<K>(node->upper_z[i])); -#if defined(__AVX2__) || defined(__ARM_NEON) +#if defined(__aarch64__) + const vfloat<K> lclipMinX = madd(vlower_x, ray.rdir.x, ray.neg_org_rdir.x); + const vfloat<K> lclipMinY = madd(vlower_y, ray.rdir.y, ray.neg_org_rdir.y); + const vfloat<K> lclipMinZ = madd(vlower_z, ray.rdir.z, ray.neg_org_rdir.z); + const vfloat<K> lclipMaxX = madd(vupper_x, ray.rdir.x, ray.neg_org_rdir.x); + const vfloat<K> lclipMaxY = madd(vupper_y, ray.rdir.y, ray.neg_org_rdir.y); + const vfloat<K> lclipMaxZ = madd(vupper_z, ray.rdir.z, ray.neg_org_rdir.z); +#elif defined(__AVX2__) const vfloat<K> lclipMinX = msub(vlower_x, ray.rdir.x, ray.org_rdir.x); const vfloat<K> lclipMinY = msub(vlower_y, ray.rdir.y, ray.org_rdir.y); const vfloat<K> lclipMinZ = msub(vlower_z, ray.rdir.z, ray.org_rdir.z); @@ -464,7 +489,14 @@ namespace embree const vfloat<N> lower_z = node->dequantizeLowerZ(); const vfloat<N> upper_z = node->dequantizeUpperZ(); - #if defined(__AVX2__) || defined(__ARM_NEON) + #if defined(__aarch64__) + const vfloat<K> lclipMinX = madd(lower_x[i], ray.rdir.x, ray.neg_org_rdir.x); + const vfloat<K> lclipMinY = madd(lower_y[i], ray.rdir.y, ray.neg_org_rdir.y); + const vfloat<K> lclipMinZ = madd(lower_z[i], ray.rdir.z, ray.neg_org_rdir.z); + const vfloat<K> lclipMaxX = madd(upper_x[i], ray.rdir.x, ray.neg_org_rdir.x); + const vfloat<K> lclipMaxY = madd(upper_y[i], ray.rdir.y, ray.neg_org_rdir.y); + const vfloat<K> lclipMaxZ = madd(upper_z[i], ray.rdir.z, ray.neg_org_rdir.z); + #elif defined(__AVX2__) const vfloat<K> lclipMinX = msub(lower_x[i], ray.rdir.x, ray.org_rdir.x); const vfloat<K> lclipMinY = msub(lower_y[i], ray.rdir.y, ray.org_rdir.y); const vfloat<K> lclipMinZ = msub(lower_z[i], ray.rdir.z, ray.org_rdir.z); @@ -549,7 +581,14 @@ namespace embree const vfloat<K> lower_z = node->template dequantizeLowerZ<K>(i,time); const vfloat<K> upper_z = node->template dequantizeUpperZ<K>(i,time); -#if defined(__AVX2__) || defined(__ARM_NEON) +#if defined(__aarch64__) + const vfloat<K> lclipMinX = madd(lower_x, ray.rdir.x, ray.neg_org_rdir.x); + const vfloat<K> lclipMinY = madd(lower_y, ray.rdir.y, ray.neg_org_rdir.y); + const vfloat<K> lclipMinZ = madd(lower_z, ray.rdir.z, ray.neg_org_rdir.z); + const vfloat<K> lclipMaxX = madd(upper_x, ray.rdir.x, ray.neg_org_rdir.x); + const vfloat<K> lclipMaxY = madd(upper_y, ray.rdir.y, ray.neg_org_rdir.y); + const vfloat<K> lclipMaxZ = madd(upper_z, ray.rdir.z, ray.neg_org_rdir.z); +#elif defined(__AVX2__) const vfloat<K> lclipMinX = msub(lower_x, ray.rdir.x, ray.org_rdir.x); const vfloat<K> lclipMinY = msub(lower_y, ray.rdir.y, ray.org_rdir.y); const vfloat<K> lclipMinZ = msub(lower_z, ray.rdir.z, ray.org_rdir.z); diff --git a/thirdparty/embree/kernels/bvh/node_intersector_packet_stream.h b/thirdparty/embree/kernels/bvh/node_intersector_packet_stream.h index 55b2c27231..943fd7043f 100644 --- a/thirdparty/embree/kernels/bvh/node_intersector_packet_stream.h +++ b/thirdparty/embree/kernels/bvh/node_intersector_packet_stream.h @@ -32,11 +32,19 @@ namespace embree __forceinline void init(const Vec3vf<K>& ray_org, const Vec3vf<K>& ray_dir) { rdir = rcp_safe(ray_dir); +#if defined(__aarch64__) + neg_org_rdir = -(ray_org * rdir); +#else org_rdir = ray_org * rdir; +#endif } Vec3vf<K> rdir; +#if defined(__aarch64__) + Vec3vf<K> neg_org_rdir; +#else Vec3vf<K> org_rdir; +#endif vfloat<K> tnear; vfloat<K> tfar; }; @@ -87,12 +95,21 @@ namespace embree const vfloat<N> bmaxY = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farY)); const vfloat<N> bmaxZ = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farZ)); +#if defined (__aarch64__) + const vfloat<N> rminX = madd(bminX, vfloat<N>(ray.rdir.x[k]), vfloat<N>(ray.neg_org_rdir.x[k])); + const vfloat<N> rminY = madd(bminY, vfloat<N>(ray.rdir.y[k]), vfloat<N>(ray.neg_org_rdir.y[k])); + const vfloat<N> rminZ = madd(bminZ, vfloat<N>(ray.rdir.z[k]), vfloat<N>(ray.neg_org_rdir.z[k])); + const vfloat<N> rmaxX = madd(bmaxX, vfloat<N>(ray.rdir.x[k]), vfloat<N>(ray.neg_org_rdir.x[k])); + const vfloat<N> rmaxY = madd(bmaxY, vfloat<N>(ray.rdir.y[k]), vfloat<N>(ray.neg_org_rdir.y[k])); + const vfloat<N> rmaxZ = madd(bmaxZ, vfloat<N>(ray.rdir.z[k]), vfloat<N>(ray.neg_org_rdir.z[k])); +#else const vfloat<N> rminX = msub(bminX, vfloat<N>(ray.rdir.x[k]), vfloat<N>(ray.org_rdir.x[k])); const vfloat<N> rminY = msub(bminY, vfloat<N>(ray.rdir.y[k]), vfloat<N>(ray.org_rdir.y[k])); const vfloat<N> rminZ = msub(bminZ, vfloat<N>(ray.rdir.z[k]), vfloat<N>(ray.org_rdir.z[k])); const vfloat<N> rmaxX = msub(bmaxX, vfloat<N>(ray.rdir.x[k]), vfloat<N>(ray.org_rdir.x[k])); const vfloat<N> rmaxY = msub(bmaxY, vfloat<N>(ray.rdir.y[k]), vfloat<N>(ray.org_rdir.y[k])); const vfloat<N> rmaxZ = msub(bmaxZ, vfloat<N>(ray.rdir.z[k]), vfloat<N>(ray.org_rdir.z[k])); +#endif const vfloat<N> rmin = maxi(rminX, rminY, rminZ, vfloat<N>(ray.tnear[k])); const vfloat<N> rmax = mini(rmaxX, rmaxY, rmaxZ, vfloat<N>(ray.tfar[k])); @@ -113,12 +130,21 @@ namespace embree const vfloat<K> bmaxY = *(const float*)(ptr + nf.farY); const vfloat<K> bmaxZ = *(const float*)(ptr + nf.farZ); +#if defined (__aarch64__) + const vfloat<K> rminX = madd(bminX, ray.rdir.x, ray.neg_org_rdir.x); + const vfloat<K> rminY = madd(bminY, ray.rdir.y, ray.neg_org_rdir.y); + const vfloat<K> rminZ = madd(bminZ, ray.rdir.z, ray.neg_org_rdir.z); + const vfloat<K> rmaxX = madd(bmaxX, ray.rdir.x, ray.neg_org_rdir.x); + const vfloat<K> rmaxY = madd(bmaxY, ray.rdir.y, ray.neg_org_rdir.y); + const vfloat<K> rmaxZ = madd(bmaxZ, ray.rdir.z, ray.neg_org_rdir.z); +#else const vfloat<K> rminX = msub(bminX, ray.rdir.x, ray.org_rdir.x); const vfloat<K> rminY = msub(bminY, ray.rdir.y, ray.org_rdir.y); const vfloat<K> rminZ = msub(bminZ, ray.rdir.z, ray.org_rdir.z); const vfloat<K> rmaxX = msub(bmaxX, ray.rdir.x, ray.org_rdir.x); const vfloat<K> rmaxY = msub(bmaxY, ray.rdir.y, ray.org_rdir.y); const vfloat<K> rmaxZ = msub(bmaxZ, ray.rdir.z, ray.org_rdir.z); +#endif const vfloat<K> rmin = maxi(rminX, rminY, rminZ, ray.tnear); const vfloat<K> rmax = mini(rmaxX, rmaxY, rmaxZ, ray.tfar); diff --git a/thirdparty/embree/kernels/common/accel.h b/thirdparty/embree/kernels/common/accel.h index cc4ea1805b..d24326ce92 100644 --- a/thirdparty/embree/kernels/common/accel.h +++ b/thirdparty/embree/kernels/common/accel.h @@ -332,7 +332,7 @@ namespace embree intersectorN.intersect(this,rayN,N,context); } -#if defined(__SSE__) +#if defined(__SSE__) || defined(__ARM_NEON) __forceinline void intersect(const vbool4& valid, RayHitK<4>& ray, IntersectContext* context) { const vint<4> mask = valid.mask32(); intersect4(&mask,(RTCRayHit4&)ray,context); @@ -388,7 +388,7 @@ namespace embree intersectorN.occluded(this,rayN,N,context); } -#if defined(__SSE__) +#if defined(__SSE__) || defined(__ARM_NEON) __forceinline void occluded(const vbool4& valid, RayK<4>& ray, IntersectContext* context) { const vint<4> mask = valid.mask32(); occluded4(&mask,(RTCRay4&)ray,context); diff --git a/thirdparty/embree/kernels/common/acceln.cpp b/thirdparty/embree/kernels/common/acceln.cpp index 32a27c560a..111c62083d 100644 --- a/thirdparty/embree/kernels/common/acceln.cpp +++ b/thirdparty/embree/kernels/common/acceln.cpp @@ -97,7 +97,7 @@ namespace embree for (size_t i=0; i<This->accels.size(); i++) { if (This->accels[i]->isEmpty()) continue; This->accels[i]->intersectors.occluded4(valid,ray,context); -#if defined(__SSE2__) +#if defined(__SSE2__) || defined(__ARM_NEON) vbool4 valid0 = asBool(((vint4*)valid)[0]); vbool4 hit0 = ((vfloat4*)ray.tfar)[0] >= vfloat4(zero); if (unlikely(none(valid0 & hit0))) break; @@ -111,7 +111,7 @@ namespace embree for (size_t i=0; i<This->accels.size(); i++) { if (This->accels[i]->isEmpty()) continue; This->accels[i]->intersectors.occluded8(valid,ray,context); -#if defined(__SSE2__) // FIXME: use higher ISA +#if defined(__SSE2__) || defined(__ARM_NEON) // FIXME: use higher ISA vbool4 valid0 = asBool(((vint4*)valid)[0]); vbool4 hit0 = ((vfloat4*)ray.tfar)[0] >= vfloat4(zero); vbool4 valid1 = asBool(((vint4*)valid)[1]); @@ -127,7 +127,7 @@ namespace embree for (size_t i=0; i<This->accels.size(); i++) { if (This->accels[i]->isEmpty()) continue; This->accels[i]->intersectors.occluded16(valid,ray,context); -#if defined(__SSE2__) // FIXME: use higher ISA +#if defined(__SSE2__) || defined(__ARM_NEON) // FIXME: use higher ISA vbool4 valid0 = asBool(((vint4*)valid)[0]); vbool4 hit0 = ((vfloat4*)ray.tfar)[0] >= vfloat4(zero); vbool4 valid1 = asBool(((vint4*)valid)[1]); diff --git a/thirdparty/embree/kernels/common/accelset.h b/thirdparty/embree/kernels/common/accelset.h index 90b184a07b..1b67120c97 100644 --- a/thirdparty/embree/kernels/common/accelset.h +++ b/thirdparty/embree/kernels/common/accelset.h @@ -14,21 +14,14 @@ namespace embree struct IntersectFunctionNArguments; struct OccludedFunctionNArguments; - typedef void (*ReportIntersectionFunc) (IntersectFunctionNArguments* args, const RTCFilterFunctionNArguments* filter_args); - typedef void (*ReportOcclusionFunc) (OccludedFunctionNArguments* args, const RTCFilterFunctionNArguments* filter_args); - struct IntersectFunctionNArguments : public RTCIntersectFunctionNArguments { - IntersectContext* internal_context; Geometry* geometry; - ReportIntersectionFunc report; }; struct OccludedFunctionNArguments : public RTCOccludedFunctionNArguments { - IntersectContext* internal_context; Geometry* geometry; - ReportOcclusionFunc report; }; /*! Base class for set of acceleration structures. */ @@ -145,7 +138,7 @@ namespace embree public: /*! Intersects a single ray with the scene. */ - __forceinline void intersect (RayHit& ray, unsigned int geomID, unsigned int primID, IntersectContext* context, ReportIntersectionFunc report) + __forceinline void intersect (RayHit& ray, unsigned int geomID, unsigned int primID, IntersectContext* context) { assert(primID < size()); assert(intersectorN.intersect); @@ -159,15 +152,13 @@ namespace embree args.N = 1; args.geomID = geomID; args.primID = primID; - args.internal_context = context; args.geometry = this; - args.report = report; intersectorN.intersect(&args); } /*! Tests if single ray is occluded by the scene. */ - __forceinline void occluded (Ray& ray, unsigned int geomID, unsigned int primID, IntersectContext* context, ReportOcclusionFunc report) + __forceinline void occluded (Ray& ray, unsigned int geomID, unsigned int primID, IntersectContext* context) { assert(primID < size()); assert(intersectorN.occluded); @@ -181,16 +172,14 @@ namespace embree args.N = 1; args.geomID = geomID; args.primID = primID; - args.internal_context = context; args.geometry = this; - args.report = report; intersectorN.occluded(&args); } /*! Intersects a packet of K rays with the scene. */ template<int K> - __forceinline void intersect (const vbool<K>& valid, RayHitK<K>& ray, unsigned int geomID, unsigned int primID, IntersectContext* context, ReportIntersectionFunc report) + __forceinline void intersect (const vbool<K>& valid, RayHitK<K>& ray, unsigned int geomID, unsigned int primID, IntersectContext* context) { assert(primID < size()); assert(intersectorN.intersect); @@ -204,16 +193,14 @@ namespace embree args.N = K; args.geomID = geomID; args.primID = primID; - args.internal_context = context; args.geometry = this; - args.report = report; intersectorN.intersect(&args); } /*! Tests if a packet of K rays is occluded by the scene. */ template<int K> - __forceinline void occluded (const vbool<K>& valid, RayK<K>& ray, unsigned int geomID, unsigned int primID, IntersectContext* context, ReportOcclusionFunc report) + __forceinline void occluded (const vbool<K>& valid, RayK<K>& ray, unsigned int geomID, unsigned int primID, IntersectContext* context) { assert(primID < size()); assert(intersectorN.occluded); @@ -227,9 +214,7 @@ namespace embree args.N = K; args.geomID = geomID; args.primID = primID; - args.internal_context = context; args.geometry = this; - args.report = report; intersectorN.occluded(&args); } diff --git a/thirdparty/embree/kernels/common/alloc.cpp b/thirdparty/embree/kernels/common/alloc.cpp index 1a0e1aeed3..38a76225f4 100644 --- a/thirdparty/embree/kernels/common/alloc.cpp +++ b/thirdparty/embree/kernels/common/alloc.cpp @@ -3,6 +3,9 @@ #include "alloc.h" #include "../../common/sys/thread.h" +#if defined(APPLE) && defined(__aarch64__) +#include "../../common/sys/barrier.h" +#endif namespace embree { diff --git a/thirdparty/embree/kernels/common/alloc.h b/thirdparty/embree/kernels/common/alloc.h index 4458e35c24..12769df2c8 100644 --- a/thirdparty/embree/kernels/common/alloc.h +++ b/thirdparty/embree/kernels/common/alloc.h @@ -8,6 +8,10 @@ #include "scene.h" #include "primref.h" +#if defined(APPLE) && defined(__aarch64__) +#include <mutex> +#endif + namespace embree { class FastAllocator @@ -26,7 +30,7 @@ namespace embree public: struct ThreadLocal2; - enum AllocationType { ALIGNED_MALLOC, OS_MALLOC, SHARED, ANY_TYPE }; + enum AllocationType { ALIGNED_MALLOC, EMBREE_OS_MALLOC, SHARED, ANY_TYPE }; /*! Per thread structure holding the current memory block. */ struct __aligned(64) ThreadLocal @@ -132,7 +136,11 @@ namespace embree { assert(alloc_i); if (alloc.load() == alloc_i) return; +#if defined(APPLE) && defined(__aarch64__) + std::scoped_lock lock(mutex); +#else Lock<SpinLock> lock(mutex); +#endif //if (alloc.load() == alloc_i) return; // not required as only one thread calls bind if (alloc.load()) { alloc.load()->bytesUsed += alloc0.getUsedBytes() + alloc1.getUsedBytes(); @@ -150,7 +158,11 @@ namespace embree { assert(alloc_i); if (alloc.load() != alloc_i) return; +#if defined(APPLE) && defined(__aarch64__) + std::scoped_lock lock(mutex); +#else Lock<SpinLock> lock(mutex); +#endif if (alloc.load() != alloc_i) return; // required as a different thread calls unbind alloc.load()->bytesUsed += alloc0.getUsedBytes() + alloc1.getUsedBytes(); alloc.load()->bytesFree += alloc0.getFreeBytes() + alloc1.getFreeBytes(); @@ -161,7 +173,11 @@ namespace embree } public: +#if defined(APPLE) && defined(__aarch64__) + std::mutex mutex; +#else SpinLock mutex; //!< required as unbind is called from other threads +#endif std::atomic<FastAllocator*> alloc; //!< parent allocator ThreadLocal alloc0; ThreadLocal alloc1; @@ -169,7 +185,7 @@ namespace embree FastAllocator (Device* device, bool osAllocation) : device(device), slotMask(0), usedBlocks(nullptr), freeBlocks(nullptr), use_single_mode(false), defaultBlockSize(PAGE_SIZE), estimatedSize(0), - growSize(PAGE_SIZE), maxGrowSize(maxAllocationSize), log2_grow_size_scale(0), bytesUsed(0), bytesFree(0), bytesWasted(0), atype(osAllocation ? OS_MALLOC : ALIGNED_MALLOC), + growSize(PAGE_SIZE), maxGrowSize(maxAllocationSize), log2_grow_size_scale(0), bytesUsed(0), bytesFree(0), bytesWasted(0), atype(osAllocation ? EMBREE_OS_MALLOC : ALIGNED_MALLOC), primrefarray(device,0) { for (size_t i=0; i<MAX_THREAD_USED_BLOCK_SLOTS; i++) @@ -206,7 +222,7 @@ namespace embree void setOSallocation(bool flag) { - atype = flag ? OS_MALLOC : ALIGNED_MALLOC; + atype = flag ? EMBREE_OS_MALLOC : ALIGNED_MALLOC; } private: @@ -217,7 +233,11 @@ namespace embree ThreadLocal2* alloc = thread_local_allocator2; if (alloc == nullptr) { thread_local_allocator2 = alloc = new ThreadLocal2; +#if defined(APPLE) && defined(__aarch64__) + std::scoped_lock lock(s_thread_local_allocators_lock); +#else Lock<SpinLock> lock(s_thread_local_allocators_lock); +#endif s_thread_local_allocators.push_back(make_unique(alloc)); } return alloc; @@ -227,7 +247,11 @@ namespace embree __forceinline void join(ThreadLocal2* alloc) { +#if defined(APPLE) && defined(__aarch64__) + std::scoped_lock lock(s_thread_local_allocators_lock); +#else Lock<SpinLock> lock(thread_local_allocators_lock); +#endif thread_local_allocators.push_back(alloc); } @@ -492,7 +516,11 @@ namespace embree /* parallel block creation in case of no freeBlocks, avoids single global mutex */ if (likely(freeBlocks.load() == nullptr)) { +#if defined(APPLE) && defined(__aarch64__) + std::scoped_lock lock(slotMutex[slot]); +#else Lock<SpinLock> lock(slotMutex[slot]); +#endif if (myUsedBlocks == threadUsedBlocks[slot]) { const size_t alignedBytes = (bytes+(align-1)) & ~(align-1); const size_t allocSize = max(min(growSize,maxGrowSize),alignedBytes); @@ -505,7 +533,11 @@ namespace embree /* if this fails allocate new block */ { - Lock<SpinLock> lock(mutex); +#if defined(APPLE) && defined(__aarch64__) + std::scoped_lock lock(mutex); +#else + Lock<SpinLock> lock(mutex); +#endif if (myUsedBlocks == threadUsedBlocks[slot]) { if (freeBlocks.load() != nullptr) { @@ -527,7 +559,11 @@ namespace embree /*! add new block */ void addBlock(void* ptr, ssize_t bytes) { +#if defined(APPLE) && defined(__aarch64__) + std::scoped_lock lock(mutex); +#else Lock<SpinLock> lock(mutex); +#endif const size_t sizeof_Header = offsetof(Block,data[0]); void* aptr = (void*) ((((size_t)ptr)+maxAlignment-1) & ~(maxAlignment-1)); size_t ofs = (size_t) aptr - (size_t) ptr; @@ -613,8 +649,8 @@ namespace embree bytesWasted(alloc->bytesWasted), stat_all(alloc,ANY_TYPE), stat_malloc(alloc,ALIGNED_MALLOC), - stat_4K(alloc,OS_MALLOC,false), - stat_2M(alloc,OS_MALLOC,true), + stat_4K(alloc,EMBREE_OS_MALLOC,false), + stat_2M(alloc,EMBREE_OS_MALLOC,true), stat_shared(alloc,SHARED) {} AllStatistics (size_t bytesUsed, @@ -707,7 +743,7 @@ namespace embree /* We avoid using os_malloc for small blocks as this could * cause a risk of fragmenting the virtual address space and * reach the limit of vm.max_map_count = 65k under Linux. */ - if (atype == OS_MALLOC && bytesAllocate < maxAllocationSize) + if (atype == EMBREE_OS_MALLOC && bytesAllocate < maxAllocationSize) atype = ALIGNED_MALLOC; /* we need to additionally allocate some header */ @@ -716,7 +752,7 @@ namespace embree bytesReserve = sizeof_Header+bytesReserve; /* consume full 4k pages with using os_malloc */ - if (atype == OS_MALLOC) { + if (atype == EMBREE_OS_MALLOC) { bytesAllocate = ((bytesAllocate+PAGE_SIZE-1) & ~(PAGE_SIZE-1)); bytesReserve = ((bytesReserve +PAGE_SIZE-1) & ~(PAGE_SIZE-1)); } @@ -748,11 +784,11 @@ namespace embree return new (ptr) Block(ALIGNED_MALLOC,bytesAllocate-sizeof_Header,bytesAllocate-sizeof_Header,next,alignment); } } - else if (atype == OS_MALLOC) + else if (atype == EMBREE_OS_MALLOC) { if (device) device->memoryMonitor(bytesAllocate,false); bool huge_pages; ptr = os_malloc(bytesReserve,huge_pages); - return new (ptr) Block(OS_MALLOC,bytesAllocate-sizeof_Header,bytesReserve-sizeof_Header,next,0,huge_pages); + return new (ptr) Block(EMBREE_OS_MALLOC,bytesAllocate-sizeof_Header,bytesReserve-sizeof_Header,next,0,huge_pages); } else assert(false); @@ -796,7 +832,7 @@ namespace embree if (device) device->memoryMonitor(-sizeof_Alloced,true); } - else if (atype == OS_MALLOC) { + else if (atype == EMBREE_OS_MALLOC) { size_t sizeof_This = sizeof_Header+reserveEnd; os_free(this,sizeof_This,huge_pages); if (device) device->memoryMonitor(-sizeof_Alloced,true); @@ -857,7 +893,7 @@ namespace embree bool hasType(AllocationType atype_i, bool huge_pages_i) const { if (atype_i == ANY_TYPE ) return true; - else if (atype == OS_MALLOC) return atype_i == atype && huge_pages_i == huge_pages; + else if (atype == EMBREE_OS_MALLOC) return atype_i == atype && huge_pages_i == huge_pages; else return atype_i == atype; } @@ -906,7 +942,7 @@ namespace embree void print_block() const { if (atype == ALIGNED_MALLOC) std::cout << "A"; - else if (atype == OS_MALLOC) std::cout << "O"; + else if (atype == EMBREE_OS_MALLOC) std::cout << "O"; else if (atype == SHARED) std::cout << "S"; if (huge_pages) std::cout << "H"; size_t bytesUsed = getBlockUsedBytes(); @@ -936,7 +972,11 @@ namespace embree std::atomic<Block*> freeBlocks; std::atomic<Block*> threadBlocks[MAX_THREAD_USED_BLOCK_SLOTS]; - SpinLock slotMutex[MAX_THREAD_USED_BLOCK_SLOTS]; +#if defined(APPLE) && defined(__aarch64__) + std::mutex slotMutex[MAX_THREAD_USED_BLOCK_SLOTS]; +#else + PaddedSpinLock slotMutex[MAX_THREAD_USED_BLOCK_SLOTS]; +#endif bool use_single_mode; size_t defaultBlockSize; @@ -950,7 +990,11 @@ namespace embree static __thread ThreadLocal2* thread_local_allocator2; static SpinLock s_thread_local_allocators_lock; static std::vector<std::unique_ptr<ThreadLocal2>> s_thread_local_allocators; +#if defined(APPLE) && defined(__aarch64__) + std::mutex thread_local_allocators_lock; +#else SpinLock thread_local_allocators_lock; +#endif std::vector<ThreadLocal2*> thread_local_allocators; AllocationType atype; mvector<PrimRef> primrefarray; //!< primrefarray used to allocate nodes diff --git a/thirdparty/embree/kernels/common/device.cpp b/thirdparty/embree/kernels/common/device.cpp index 068e0c2983..833ec65139 100644 --- a/thirdparty/embree/kernels/common/device.cpp +++ b/thirdparty/embree/kernels/common/device.cpp @@ -66,7 +66,11 @@ namespace embree case CPU::CORE1: frequency_level = FREQUENCY_SIMD128; break; case CPU::XEON_PHI_KNIGHTS_MILL : frequency_level = FREQUENCY_SIMD512; break; case CPU::XEON_PHI_KNIGHTS_LANDING: frequency_level = FREQUENCY_SIMD512; break; +#if defined(__APPLE__) + case CPU::ARM: frequency_level = FREQUENCY_SIMD256; break; // Apple M1 supports high throughput for SIMD4 +#else case CPU::ARM: frequency_level = FREQUENCY_SIMD128; break; +#endif } /* initialize global state */ diff --git a/thirdparty/embree/kernels/common/geometry.h b/thirdparty/embree/kernels/common/geometry.h index 2f9f2e7c94..593990f5b1 100644 --- a/thirdparty/embree/kernels/common/geometry.h +++ b/thirdparty/embree/kernels/common/geometry.h @@ -91,7 +91,7 @@ namespace embree size_t numFilterFunctions; //!< number of geometries with filter functions enabled size_t numTriangles; //!< number of enabled triangles - size_t numMBTriangles; //!< number of enabled motion blured triangles + size_t numMBTriangles; //!< number of enabled motion blurred triangles size_t numQuads; //!< number of enabled quads size_t numMBQuads; //!< number of enabled motion blurred quads size_t numBezierCurves; //!< number of enabled curves @@ -99,7 +99,7 @@ namespace embree size_t numLineSegments; //!< number of enabled line segments size_t numMBLineSegments; //!< number of enabled line motion blurred segments size_t numSubdivPatches; //!< number of enabled subdivision patches - size_t numMBSubdivPatches; //!< number of enabled motion blured subdivision patches + size_t numMBSubdivPatches; //!< number of enabled motion blurred subdivision patches size_t numUserGeometries; //!< number of enabled user geometries size_t numMBUserGeometries; //!< number of enabled motion blurred user geometries size_t numInstancesCheap; //!< number of enabled cheap instances diff --git a/thirdparty/embree/kernels/common/isa.h b/thirdparty/embree/kernels/common/isa.h index ae6556336c..9e1132e1a0 100644 --- a/thirdparty/embree/kernels/common/isa.h +++ b/thirdparty/embree/kernels/common/isa.h @@ -44,7 +44,7 @@ namespace embree #define SELECT_SYMBOL_DEFAULT(features,intersector) \ intersector = isa::intersector; -#if defined(__SSE__) +#if defined(__SSE__) || defined(__ARM_NEON) #if !defined(EMBREE_TARGET_SIMD4) #define EMBREE_TARGET_SIMD4 #endif diff --git a/thirdparty/embree/kernels/common/ray.h b/thirdparty/embree/kernels/common/ray.h index 7b951cc1e8..3c8ee3989c 100644 --- a/thirdparty/embree/kernels/common/ray.h +++ b/thirdparty/embree/kernels/common/ray.h @@ -6,7 +6,7 @@ #include "default.h" #include "instance_stack.h" -// FIXME: if ray gets seperated into ray* and hit, uload4 needs to be adjusted +// FIXME: if ray gets separated into ray* and hit, uload4 needs to be adjusted namespace embree { diff --git a/thirdparty/embree/kernels/common/rtcore.cpp b/thirdparty/embree/kernels/common/rtcore.cpp index 94b3819e42..a6ea55bfc4 100644 --- a/thirdparty/embree/kernels/common/rtcore.cpp +++ b/thirdparty/embree/kernels/common/rtcore.cpp @@ -7,6 +7,7 @@ #include "device.h" #include "scene.h" #include "context.h" +#include "../geometry/filter.h" #include "../../include/embree3/rtcore_ray.h" using namespace embree; @@ -482,7 +483,7 @@ RTC_NAMESPACE_BEGIN; IntersectContext context(scene,user_context); #if !defined(EMBREE_RAY_PACKETS) - Ray4* ray4 = (Ray4*) rayhit; + RayHit4* ray4 = (RayHit4*) rayhit; for (size_t i=0; i<4; i++) { if (!valid[i]) continue; RayHit ray1; ray4->get(i,ray1); @@ -513,7 +514,7 @@ RTC_NAMESPACE_BEGIN; IntersectContext context(scene,user_context); #if !defined(EMBREE_RAY_PACKETS) - Ray8* ray8 = (Ray8*) rayhit; + RayHit8* ray8 = (RayHit8*) rayhit; for (size_t i=0; i<8; i++) { if (!valid[i]) continue; RayHit ray1; ray8->get(i,ray1); @@ -546,7 +547,7 @@ RTC_NAMESPACE_BEGIN; IntersectContext context(scene,user_context); #if !defined(EMBREE_RAY_PACKETS) - Ray16* ray16 = (Ray16*) rayhit; + RayHit16* ray16 = (RayHit16*) rayhit; for (size_t i=0; i<16; i++) { if (!valid[i]) continue; RayHit ray1; ray16->get(i,ray1); @@ -1097,13 +1098,13 @@ RTC_NAMESPACE_BEGIN; RTC_API void rtcFilterIntersection(const struct RTCIntersectFunctionNArguments* const args_i, const struct RTCFilterFunctionNArguments* filter_args) { IntersectFunctionNArguments* args = (IntersectFunctionNArguments*) args_i; - args->report(args,filter_args); + isa::reportIntersection1(args, filter_args); } RTC_API void rtcFilterOcclusion(const struct RTCOccludedFunctionNArguments* const args_i, const struct RTCFilterFunctionNArguments* filter_args) { OccludedFunctionNArguments* args = (OccludedFunctionNArguments*) args_i; - args->report(args,filter_args); + isa::reportOcclusion1(args,filter_args); } RTC_API RTCGeometry rtcNewGeometry (RTCDevice hdevice, RTCGeometryType type) @@ -1763,4 +1764,19 @@ RTC_NAMESPACE_BEGIN; return nullptr; } + RTC_API RTCGeometry rtcGetGeometryThreadSafe (RTCScene hscene, unsigned int geomID) + { + Scene* scene = (Scene*) hscene; + RTC_CATCH_BEGIN; + RTC_TRACE(rtcGetGeometryThreadSafe); +#if defined(DEBUG) + RTC_VERIFY_HANDLE(hscene); + RTC_VERIFY_GEOMID(geomID); +#endif + Ref<Geometry> geom = scene->get_locked(geomID); + return (RTCGeometry) geom.ptr; + RTC_CATCH_END2(scene); + return nullptr; + } + RTC_NAMESPACE_END diff --git a/thirdparty/embree/kernels/common/rtcore.h b/thirdparty/embree/kernels/common/rtcore.h index f8aad7c7cb..ac58a84d6f 100644 --- a/thirdparty/embree/kernels/common/rtcore.h +++ b/thirdparty/embree/kernels/common/rtcore.h @@ -26,56 +26,59 @@ namespace embree /*! Macros used in the rtcore API implementation */ // -- GODOT start -- -// #define RTC_CATCH_BEGIN try { #define RTC_CATCH_BEGIN - -// #define RTC_CATCH_END(device) \ -// } catch (std::bad_alloc&) { \ -// Device::process_error(device,RTC_ERROR_OUT_OF_MEMORY,"out of memory"); \ -// } catch (rtcore_error& e) { \ -// Device::process_error(device,e.error,e.what()); \ -// } catch (std::exception& e) { \ -// Device::process_error(device,RTC_ERROR_UNKNOWN,e.what()); \ -// } catch (...) { \ -// Device::process_error(device,RTC_ERROR_UNKNOWN,"unknown exception caught"); \ -// } #define RTC_CATCH_END(device) - -// #define RTC_CATCH_END2(scene) \ -// } catch (std::bad_alloc&) { \ -// Device* device = scene ? scene->device : nullptr; \ -// Device::process_error(device,RTC_ERROR_OUT_OF_MEMORY,"out of memory"); \ -// } catch (rtcore_error& e) { \ -// Device* device = scene ? scene->device : nullptr; \ -// Device::process_error(device,e.error,e.what()); \ -// } catch (std::exception& e) { \ -// Device* device = scene ? scene->device : nullptr; \ -// Device::process_error(device,RTC_ERROR_UNKNOWN,e.what()); \ -// } catch (...) { \ -// Device* device = scene ? scene->device : nullptr; \ -// Device::process_error(device,RTC_ERROR_UNKNOWN,"unknown exception caught"); \ -// } #define RTC_CATCH_END2(scene) - -// #define RTC_CATCH_END2_FALSE(scene) \ -// } catch (std::bad_alloc&) { \ -// Device* device = scene ? scene->device : nullptr; \ -// Device::process_error(device,RTC_ERROR_OUT_OF_MEMORY,"out of memory"); \ -// return false; \ -// } catch (rtcore_error& e) { \ -// Device* device = scene ? scene->device : nullptr; \ -// Device::process_error(device,e.error,e.what()); \ -// return false; \ -// } catch (std::exception& e) { \ -// Device* device = scene ? scene->device : nullptr; \ -// Device::process_error(device,RTC_ERROR_UNKNOWN,e.what()); \ -// return false; \ -// } catch (...) { \ -// Device* device = scene ? scene->device : nullptr; \ -// Device::process_error(device,RTC_ERROR_UNKNOWN,"unknown exception caught"); \ -// return false; \ -// } #define RTC_CATCH_END2_FALSE(scene) return false; + +#if 0 +#define RTC_CATCH_BEGIN try { + +#define RTC_CATCH_END(device) \ + } catch (std::bad_alloc&) { \ + Device::process_error(device,RTC_ERROR_OUT_OF_MEMORY,"out of memory"); \ + } catch (rtcore_error& e) { \ + Device::process_error(device,e.error,e.what()); \ + } catch (std::exception& e) { \ + Device::process_error(device,RTC_ERROR_UNKNOWN,e.what()); \ + } catch (...) { \ + Device::process_error(device,RTC_ERROR_UNKNOWN,"unknown exception caught"); \ + } + +#define RTC_CATCH_END2(scene) \ + } catch (std::bad_alloc&) { \ + Device* device = scene ? scene->device : nullptr; \ + Device::process_error(device,RTC_ERROR_OUT_OF_MEMORY,"out of memory"); \ + } catch (rtcore_error& e) { \ + Device* device = scene ? scene->device : nullptr; \ + Device::process_error(device,e.error,e.what()); \ + } catch (std::exception& e) { \ + Device* device = scene ? scene->device : nullptr; \ + Device::process_error(device,RTC_ERROR_UNKNOWN,e.what()); \ + } catch (...) { \ + Device* device = scene ? scene->device : nullptr; \ + Device::process_error(device,RTC_ERROR_UNKNOWN,"unknown exception caught"); \ + } + +#define RTC_CATCH_END2_FALSE(scene) \ + } catch (std::bad_alloc&) { \ + Device* device = scene ? scene->device : nullptr; \ + Device::process_error(device,RTC_ERROR_OUT_OF_MEMORY,"out of memory"); \ + return false; \ + } catch (rtcore_error& e) { \ + Device* device = scene ? scene->device : nullptr; \ + Device::process_error(device,e.error,e.what()); \ + return false; \ + } catch (std::exception& e) { \ + Device* device = scene ? scene->device : nullptr; \ + Device::process_error(device,RTC_ERROR_UNKNOWN,e.what()); \ + return false; \ + } catch (...) { \ + Device* device = scene ? scene->device : nullptr; \ + Device::process_error(device,RTC_ERROR_UNKNOWN,"unknown exception caught"); \ + return false; \ + } +#endif // -- GODOT end -- #define RTC_VERIFY_HANDLE(handle) \ @@ -103,39 +106,35 @@ namespace embree #define RTC_TRACE(x) #endif -// -- GODOT begin -- -// /*! used to throw embree API errors */ -// struct rtcore_error : public std::exception -// { -// __forceinline rtcore_error(RTCError error, const std::string& str) -// : error(error), str(str) {} -// -// ~rtcore_error() throw() {} -// -// const char* what () const throw () { -// return str.c_str(); -// } -// -// RTCError error; -// std::string str; -// }; -// -- GODOT end -- +// -- GODOT start -- +#if 0 + /*! used to throw embree API errors */ + struct rtcore_error : public std::exception + { + __forceinline rtcore_error(RTCError error, const std::string& str) + : error(error), str(str) {} + + ~rtcore_error() throw() {} + + const char* what () const throw () { + return str.c_str(); + } + + RTCError error; + std::string str; + }; +#endif #if defined(DEBUG) // only report file and line in debug mode - // -- GODOT begin -- - // #define throw_RTCError(error,str) \ - // throw rtcore_error(error,std::string(__FILE__) + " (" + toString(__LINE__) + "): " + std::string(str)); #define throw_RTCError(error,str) \ printf("%s (%d): %s", __FILE__, __LINE__, std::string(str).c_str()), abort(); - // -- GODOT end -- + // throw rtcore_error(error,std::string(__FILE__) + " (" + toString(__LINE__) + "): " + std::string(str)); #else - // -- GODOT begin -- - // #define throw_RTCError(error,str) \ - // throw rtcore_error(error,str); #define throw_RTCError(error,str) \ abort(); - // -- GODOT end -- + // throw rtcore_error(error,str); #endif +// -- GODOT end -- #define RTC_BUILD_ARGUMENTS_HAS(settings,member) \ (settings.byteSize > (offsetof(RTCBuildArguments,member)+sizeof(settings.member))) diff --git a/thirdparty/embree/kernels/common/rtcore_builder.cpp b/thirdparty/embree/kernels/common/rtcore_builder.cpp index 1f1b6f6ddf..29e3bdca20 100644 --- a/thirdparty/embree/kernels/common/rtcore_builder.cpp +++ b/thirdparty/embree/kernels/common/rtcore_builder.cpp @@ -371,7 +371,7 @@ RTC_NAMESPACE_BEGIN bvh->allocator.init_estimate(arguments->primitiveCount*sizeof(BBox3fa)); bvh->allocator.reset(); - /* switch between differnet builders based on quality level */ + /* switch between different builders based on quality level */ if (arguments->buildQuality == RTC_BUILD_QUALITY_LOW) return rtcBuildBVHMorton(arguments); else if (arguments->buildQuality == RTC_BUILD_QUALITY_MEDIUM) diff --git a/thirdparty/embree/kernels/common/scene.cpp b/thirdparty/embree/kernels/common/scene.cpp index 408d7eae6f..65d31d0f81 100644 --- a/thirdparty/embree/kernels/common/scene.cpp +++ b/thirdparty/embree/kernels/common/scene.cpp @@ -629,9 +629,7 @@ namespace embree if (geometry == null) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"invalid geometry"); - if (geometry->isEnabled()) { - setModified (); - } + setModified (); accels_deleteGeometry(unsigned(geomID)); id_pool.deallocate((unsigned)geomID); geometries[geomID] = null; diff --git a/thirdparty/embree/kernels/common/scene_curves.h b/thirdparty/embree/kernels/common/scene_curves.h index a5a39e42d4..a1ea45d3c7 100644 --- a/thirdparty/embree/kernels/common/scene_curves.h +++ b/thirdparty/embree/kernels/common/scene_curves.h @@ -452,6 +452,10 @@ namespace embree const Vec3fa n1 = normal(index+1,itime); if (!isvalid(n0) || !isvalid(n1)) return false; + + const BBox3fa b = getOrientedCurveScaledRadius(i,itime).accurateBounds(); + if (!isvalid(b)) + return false; } } @@ -612,6 +616,10 @@ namespace embree const Vec3fa dn1 = dnormal(index+1,itime); if (!isvalid(dn0) || !isvalid(dn1)) return false; + + const BBox3fa b = getOrientedCurveScaledRadius(i,itime).accurateBounds(); + if (!isvalid(b)) + return false; } } diff --git a/thirdparty/embree/kernels/common/state.cpp b/thirdparty/embree/kernels/common/state.cpp index 01c862da0c..db6b803041 100644 --- a/thirdparty/embree/kernels/common/state.cpp +++ b/thirdparty/embree/kernels/common/state.cpp @@ -144,7 +144,20 @@ namespace embree } bool State::checkISASupport() { +#if defined(__ARM_NEON) + /* + * NEON CPU type is a mixture of NEON and SSE2 + */ + + bool hasSSE2 = (getCPUFeatures() & enabled_cpu_features) & CPU_FEATURE_SSE2; + + /* this will be true when explicitly initialize Device with `isa=neon` config */ + bool hasNEON = (getCPUFeatures() & enabled_cpu_features) & CPU_FEATURE_NEON; + + return hasSSE2 || hasNEON; +#else return (getCPUFeatures() & enabled_cpu_features) == enabled_cpu_features; +#endif } void State::verify() @@ -157,8 +170,10 @@ namespace embree * functions */ #if defined(DEBUG) #if defined(EMBREE_TARGET_SSE2) +#if !defined(__ARM_NEON) assert(sse2::getISA() <= SSE2); #endif +#endif #if defined(EMBREE_TARGET_SSE42) assert(sse42::getISA() <= SSE42); #endif diff --git a/thirdparty/embree/kernels/config.h b/thirdparty/embree/kernels/config.h index 2bf7e93587..84ac27d103 100644 --- a/thirdparty/embree/kernels/config.h +++ b/thirdparty/embree/kernels/config.h @@ -1,5 +1,4 @@ - -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 /* #undef EMBREE_RAY_MASK */ @@ -20,6 +19,7 @@ /* #undef EMBREE_COMPACT_POLYS */ #define EMBREE_CURVE_SELF_INTERSECTION_AVOIDANCE_FACTOR 2.0 +#define EMBREE_DISC_POINT_SELF_INTERSECTION_AVOIDANCE #if defined(EMBREE_GEOMETRY_TRIANGLE) #define IF_ENABLED_TRIS(x) x diff --git a/thirdparty/embree/kernels/geometry/curve_intersector_oriented.h b/thirdparty/embree/kernels/geometry/curve_intersector_oriented.h index 3d8900c2aa..75532f5ae0 100644 --- a/thirdparty/embree/kernels/geometry/curve_intersector_oriented.h +++ b/thirdparty/embree/kernels/geometry/curve_intersector_oriented.h @@ -225,7 +225,7 @@ namespace embree /* exit if convergence cannot get proven, but terminate if we are very small */ if (unlikely(!subset(K,x) && !very_small)) return false; - /* solve using newton raphson iteration of convergence is guarenteed */ + /* solve using newton raphson iteration of convergence is guaranteed */ solve_newton_raphson_loop(cu,cv,c1,dfdu,dfdv,rcp_J); return true; } diff --git a/thirdparty/embree/kernels/geometry/curve_intersector_sweep.h b/thirdparty/embree/kernels/geometry/curve_intersector_sweep.h index 2d4abd73ac..ed827d583f 100644 --- a/thirdparty/embree/kernels/geometry/curve_intersector_sweep.h +++ b/thirdparty/embree/kernels/geometry/curve_intersector_sweep.h @@ -60,7 +60,7 @@ namespace embree const Vec3fa dir = ray.dir; const float length_ray_dir = length(dir); - /* error of curve evaluations is propertional to largest coordinate */ + /* error of curve evaluations is proportional to largest coordinate */ const BBox3ff box = curve.bounds(); const float P_err = 16.0f*float(ulp)*reduce_max(max(abs(box.lower),abs(box.upper))); diff --git a/thirdparty/embree/kernels/geometry/disc_intersector.h b/thirdparty/embree/kernels/geometry/disc_intersector.h index 816c066899..ec6fa9c4f3 100644 --- a/thirdparty/embree/kernels/geometry/disc_intersector.h +++ b/thirdparty/embree/kernels/geometry/disc_intersector.h @@ -68,15 +68,15 @@ namespace embree const Vec3vf<M> center = v0.xyz(); const vfloat<M> radius = v0.w; + /* compute ray distance projC0 to hit point with ray oriented plane */ const Vec3vf<M> c0 = center - ray_org; const vfloat<M> projC0 = dot(c0, ray_dir) * rd2; valid &= (vfloat<M>(ray.tnear()) <= projC0) & (projC0 <= vfloat<M>(ray.tfar)); - if (EMBREE_CURVE_SELF_INTERSECTION_AVOIDANCE_FACTOR != 0.0f) - valid &= projC0 > float(EMBREE_CURVE_SELF_INTERSECTION_AVOIDANCE_FACTOR) * radius * pre.depth_scale; // ignore self intersections if (unlikely(none(valid))) return false; - + + /* check if hit point lies inside disc */ const Vec3vf<M> perp = c0 - projC0 * ray_dir; const vfloat<M> l2 = dot(perp, perp); const vfloat<M> r2 = radius * radius; @@ -84,6 +84,15 @@ namespace embree if (unlikely(none(valid))) return false; + /* We reject hits where the ray origin lies inside the ray + * oriented disc to avoid self intersections. */ +#if defined(EMBREE_DISC_POINT_SELF_INTERSECTION_AVOIDANCE) + const vfloat<M> m2 = dot(c0, c0); + valid &= (m2 > r2); + if (unlikely(none(valid))) + return false; +#endif + DiscIntersectorHitM<M> hit(zero, zero, projC0, -ray_dir); return epilog(valid, hit); } @@ -152,15 +161,15 @@ namespace embree const Vec3vf<M> center = v0.xyz(); const vfloat<M> radius = v0.w; + /* compute ray distance projC0 to hit point with ray oriented plane */ const Vec3vf<M> c0 = center - ray_org; const vfloat<M> projC0 = dot(c0, ray_dir) * rd2; valid &= (vfloat<M>(ray.tnear()[k]) <= projC0) & (projC0 <= vfloat<M>(ray.tfar[k])); - if (EMBREE_CURVE_SELF_INTERSECTION_AVOIDANCE_FACTOR != 0.0f) - valid &= projC0 > float(EMBREE_CURVE_SELF_INTERSECTION_AVOIDANCE_FACTOR) * radius * pre.depth_scale[k]; // ignore self intersections if (unlikely(none(valid))) return false; + /* check if hit point lies inside disc */ const Vec3vf<M> perp = c0 - projC0 * ray_dir; const vfloat<M> l2 = dot(perp, perp); const vfloat<M> r2 = radius * radius; @@ -168,6 +177,15 @@ namespace embree if (unlikely(none(valid))) return false; + /* We reject hits where the ray origin lies inside the ray + * oriented disc to avoid self intersections. */ +#if defined(EMBREE_DISC_POINT_SELF_INTERSECTION_AVOIDANCE) + const vfloat<M> m2 = dot(c0, c0); + valid &= (m2 > r2); + if (unlikely(none(valid))) + return false; +#endif + DiscIntersectorHitM<M> hit(zero, zero, projC0, -ray_dir); return epilog(valid, hit); } diff --git a/thirdparty/embree/kernels/geometry/filter.h b/thirdparty/embree/kernels/geometry/filter.h index 3b4d924ea7..d64320bf78 100644 --- a/thirdparty/embree/kernels/geometry/filter.h +++ b/thirdparty/embree/kernels/geometry/filter.h @@ -51,20 +51,11 @@ namespace embree __forceinline void reportIntersection1(IntersectFunctionNArguments* args, const RTCFilterFunctionNArguments* filter_args) { #if defined(EMBREE_FILTER_FUNCTION) - IntersectContext* MAYBE_UNUSED context = args->internal_context; - const Geometry* const geometry = args->geometry; - if (geometry->intersectionFilterN) { - assert(context->scene->hasGeometryFilterFunction()); - geometry->intersectionFilterN(filter_args); - } + if (args->geometry->intersectionFilterN) + args->geometry->intersectionFilterN(filter_args); - //if (args->valid[0] == 0) - // return; - - if (context->user->filter) { - assert(context->scene->hasContextFilterFunction()); - context->user->filter(filter_args); - } + if (args->context->filter) + args->context->filter(filter_args); #endif } @@ -105,20 +96,11 @@ namespace embree __forceinline void reportOcclusion1(OccludedFunctionNArguments* args, const RTCFilterFunctionNArguments* filter_args) { #if defined(EMBREE_FILTER_FUNCTION) - IntersectContext* MAYBE_UNUSED context = args->internal_context; - const Geometry* const geometry = args->geometry; - if (geometry->occlusionFilterN) { - assert(context->scene->hasGeometryFilterFunction()); - geometry->occlusionFilterN(filter_args); - } - - //if (args->valid[0] == 0) - // return false; + if (args->geometry->occlusionFilterN) + args->geometry->occlusionFilterN(filter_args); - if (context->user->filter) { - assert(context->scene->hasContextFilterFunction()); - context->user->filter(filter_args); - } + if (args->context->filter) + args->context->filter(filter_args); #endif } diff --git a/thirdparty/embree/kernels/geometry/object_intersector.h b/thirdparty/embree/kernels/geometry/object_intersector.h index 11ceb2f7fe..e4ad01852f 100644 --- a/thirdparty/embree/kernels/geometry/object_intersector.h +++ b/thirdparty/embree/kernels/geometry/object_intersector.h @@ -32,7 +32,7 @@ namespace embree return; #endif - accel->intersect(ray,prim.geomID(),prim.primID(),context,reportIntersection1); + accel->intersect(ray,prim.geomID(),prim.primID(),context); } static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& prim) @@ -44,7 +44,7 @@ namespace embree return false; #endif - accel->occluded(ray,prim.geomID(),prim.primID(),context,&reportOcclusion1); + accel->occluded(ray,prim.geomID(),prim.primID(),context); return ray.tfar < 0.0f; } @@ -89,7 +89,7 @@ namespace embree valid &= (ray.mask & accel->mask) != 0; if (none(valid)) return; #endif - accel->intersect(valid,ray,prim.geomID(),prim.primID(),context,&reportIntersection1); + accel->intersect(valid,ray,prim.geomID(),prim.primID(),context); } static __forceinline vbool<K> occluded(const vbool<K>& valid_i, const Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive& prim) @@ -102,7 +102,7 @@ namespace embree valid &= (ray.mask & accel->mask) != 0; if (none(valid)) return false; #endif - accel->occluded(valid,ray,prim.geomID(),prim.primID(),context,&reportOcclusion1); + accel->occluded(valid,ray,prim.geomID(),prim.primID(),context); return ray.tfar < 0.0f; } diff --git a/thirdparty/embree/kernels/geometry/quadv.h b/thirdparty/embree/kernels/geometry/quadv.h index 2137356ff2..514e519b0c 100644 --- a/thirdparty/embree/kernels/geometry/quadv.h +++ b/thirdparty/embree/kernels/geometry/quadv.h @@ -152,7 +152,7 @@ namespace embree Vec3vf<M> v0; // 1st vertex of the quads Vec3vf<M> v1; // 2nd vertex of the quads Vec3vf<M> v2; // 3rd vertex of the quads - Vec3vf<M> v3; // 4rd vertex of the quads + Vec3vf<M> v3; // 4th vertex of the quads private: vuint<M> geomIDs; // geometry ID vuint<M> primIDs; // primitive ID diff --git a/thirdparty/embree/kernels/geometry/roundline_intersector.h b/thirdparty/embree/kernels/geometry/roundline_intersector.h index 0e9393442b..764ff93fec 100644 --- a/thirdparty/embree/kernels/geometry/roundline_intersector.h +++ b/thirdparty/embree/kernels/geometry/roundline_intersector.h @@ -19,7 +19,7 @@ For multiple connected round linear curve segments this construction yield a proper shape when viewed from the outside. Using the - following CSG we can also handle the interiour in most common cases: + following CSG we can also handle the interior in most common cases: round_linear_curve(pl,rl,p0,r0,p1,r1,pr,rr) = cone_sphere(p0,r0,p1,r1) - cone(pl,rl,p0,r0) - cone(p1,r1,pr,rr) @@ -431,7 +431,7 @@ namespace embree Ng' = (h-u*dP) - (w0+u*dw)*dw/dP^2*dP Inserting the definition of w0 and dw and refactoring - yield a furhter scaled Ng'': + yield a further scaled Ng'': Ng'' = (dP^2 - dr^2) (h-q) - (r0+u*dr)*dr*dP diff --git a/thirdparty/embree/kernels/geometry/subgrid_intersector.h b/thirdparty/embree/kernels/geometry/subgrid_intersector.h index ad5fee2e4e..e241073812 100644 --- a/thirdparty/embree/kernels/geometry/subgrid_intersector.h +++ b/thirdparty/embree/kernels/geometry/subgrid_intersector.h @@ -264,8 +264,8 @@ namespace embree const Vec3vf<K> p2 = vtx[i*4+2]; const Vec3vf<K> p3 = vtx[i*4+3]; STAT3(shadow.trav_prims,1,popcnt(valid0),K); - if (pre.intersectK(valid0,ray,p0,p1,p2,p3,g,subgrid,i,OccludedKEpilogM<4,K,filter>(valid0,ray,context,subgrid.geomID(),subgrid.primID(),i))) - break; + pre.intersectK(valid0,ray,p0,p1,p2,p3,g,subgrid,i,OccludedKEpilogM<4,K,filter>(valid0,ray,context,subgrid.geomID(),subgrid.primID(),i)); + if (none(valid0)) break; } return !valid0; } @@ -408,10 +408,8 @@ namespace embree const Vec3vf<K> p2 = vtx[i*4+2]; const Vec3vf<K> p3 = vtx[i*4+3]; STAT3(shadow.trav_prims,1,popcnt(valid0),K); - //if (pre.intersectK(valid0,ray,p0,p1,p2,p3,g,subgrid,i,OccludedKEpilogM<4,K,filter>(valid0,ray,context,subgrid.geomID(),subgrid.primID(),i))) - if (pre.occludedK(valid0,ray,p0,p1,p2,p3,g,subgrid,i,OccludedKEpilogM<4,K,filter>(valid0,ray,context,subgrid.geomID(),subgrid.primID(),i))) - - break; + pre.occludedK(valid0,ray,p0,p1,p2,p3,g,subgrid,i,OccludedKEpilogM<4,K,filter>(valid0,ray,context,subgrid.geomID(),subgrid.primID(),i)); + if (none(valid0)) break; } return !valid0; } diff --git a/thirdparty/embree/kernels/hash.h b/thirdparty/embree/kernels/hash.h index 470e15f03e..39d50e2354 100644 --- a/thirdparty/embree/kernels/hash.h +++ b/thirdparty/embree/kernels/hash.h @@ -1,5 +1,4 @@ - -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#define RTC_HASH "12b99393438a4cc9e478e33459eed78bec6233fd" +#define RTC_HASH "698442324ccddd11725fb8875275dc1384f7fb40" diff --git a/thirdparty/embree/kernels/subdiv/bezier_patch.h b/thirdparty/embree/kernels/subdiv/bezier_patch.h index 2ff03902a7..0a2aef321f 100644 --- a/thirdparty/embree/kernels/subdiv/bezier_patch.h +++ b/thirdparty/embree/kernels/subdiv/bezier_patch.h @@ -94,7 +94,7 @@ namespace embree matrix[0][1] = computeRightEdgeBezierControlPoint(source.v,1,1); matrix[0][2] = computeLeftEdgeBezierControlPoint(source.v,1,2); - /* compute buttom edge control points */ + /* compute bottom edge control points */ matrix[3][1] = computeRightEdgeBezierControlPoint(source.v,2,1); matrix[3][2] = computeLeftEdgeBezierControlPoint(source.v,2,2); diff --git a/thirdparty/embree/kernels/subdiv/catmullclark_ring.h b/thirdparty/embree/kernels/subdiv/catmullclark_ring.h index e5ad5dadfe..eab91d9ee6 100644 --- a/thirdparty/embree/kernels/subdiv/catmullclark_ring.h +++ b/thirdparty/embree/kernels/subdiv/catmullclark_ring.h @@ -388,7 +388,7 @@ namespace embree return (Vertex_t)(n*n*vtx+4.0f*E+F) / ((n+5.0f)*n); } - /* gets limit tangent in the direction of egde vtx -> ring[0] */ + /* gets limit tangent in the direction of edge vtx -> ring[0] */ __forceinline Vertex getLimitTangent() const { if (unlikely(std::isinf(vertex_crease_weight))) @@ -429,7 +429,7 @@ namespace embree return sigma * (alpha + beta); } - /* gets limit tangent in the direction of egde vtx -> ring[edge_valence-2] */ + /* gets limit tangent in the direction of edge vtx -> ring[edge_valence-2] */ __forceinline Vertex getSecondLimitTangent() const { if (unlikely(std::isinf(vertex_crease_weight))) @@ -763,7 +763,7 @@ namespace embree } - /* gets limit tangent in the direction of egde vtx -> ring[0] */ + /* gets limit tangent in the direction of edge vtx -> ring[0] */ __forceinline Vertex getLimitTangent() const { CatmullClark1Ring cc_vtx; @@ -779,7 +779,7 @@ namespace embree return 2.0f * cc_vtx.getLimitTangent(); } - /* gets limit tangent in the direction of egde vtx -> ring[edge_valence-2] */ + /* gets limit tangent in the direction of edge vtx -> ring[edge_valence-2] */ __forceinline Vertex getSecondLimitTangent() const { CatmullClark1Ring cc_vtx; diff --git a/thirdparty/embree/kernels/subdiv/catmullrom_curve.h b/thirdparty/embree/kernels/subdiv/catmullrom_curve.h index 74fc4c1230..9532287d98 100644 --- a/thirdparty/embree/kernels/subdiv/catmullrom_curve.h +++ b/thirdparty/embree/kernels/subdiv/catmullrom_curve.h @@ -8,7 +8,7 @@ /* - Implements Catmul Rom curves with control points p0, p1, p2, p3. At + Implements Catmull-Rom curves with control points p0, p1, p2, p3. At t=0 the curve goes through p1, with tangent (p2-p0)/3, and for t=1 the curve goes through p2 with tangent (p3-p2)/2. @@ -91,11 +91,11 @@ namespace embree : v0(v0), v1(v1), v2(v2), v3(v3) {} __forceinline Vertex begin() const { - return madd(1.0f/6.0f,v0,madd(2.0f/3.0f,v1,1.0f/6.0f*v2)); + return v1; } __forceinline Vertex end() const { - return madd(1.0f/6.0f,v1,madd(2.0f/3.0f,v2,1.0f/6.0f*v3)); + return v2; } __forceinline Vertex center() const { diff --git a/thirdparty/embree/kernels/subdiv/linear_bezier_patch.h b/thirdparty/embree/kernels/subdiv/linear_bezier_patch.h index f8e8a25f35..dcdb101d7c 100644 --- a/thirdparty/embree/kernels/subdiv/linear_bezier_patch.h +++ b/thirdparty/embree/kernels/subdiv/linear_bezier_patch.h @@ -81,29 +81,29 @@ namespace embree { SourceCurve<Vec3ff> vcurve = center; SourceCurve<Vec3fa> ncurve = normal; - + /* here we construct a patch which follows the curve l(t) = * p(t) +/- r(t)*normalize(cross(n(t),dp(t))) */ const Vec3ff p0 = vcurve.eval(0.0f); const Vec3ff dp0 = vcurve.eval_du(0.0f); - const Vec3ff ddp0 = vcurve.eval_dudu(0.0f); + //const Vec3ff ddp0 = vcurve.eval_dudu(0.0f); // ddp0 is assumed to be 0 const Vec3fa n0 = ncurve.eval(0.0f); const Vec3fa dn0 = ncurve.eval_du(0.0f); const Vec3ff p1 = vcurve.eval(1.0f); const Vec3ff dp1 = vcurve.eval_du(1.0f); - const Vec3ff ddp1 = vcurve.eval_dudu(1.0f); + //const Vec3ff ddp1 = vcurve.eval_dudu(1.0f); // ddp1 is assumed to be 0 const Vec3fa n1 = ncurve.eval(1.0f); const Vec3fa dn1 = ncurve.eval_du(1.0f); const Vec3fa bt0 = cross(n0,dp0); - const Vec3fa dbt0 = cross(dn0,dp0) + cross(n0,ddp0); + const Vec3fa dbt0 = cross(dn0,dp0);// + cross(n0,ddp0); const Vec3fa bt1 = cross(n1,dp1); - const Vec3fa dbt1 = cross(dn1,dp1) + cross(n1,ddp1); + const Vec3fa dbt1 = cross(dn1,dp1);// + cross(n1,ddp1); const Vec3fa k0 = normalize(bt0); const Vec3fa dk0 = dnormalize(bt0,dbt0); diff --git a/thirdparty/embree/patches/emscripten-nthreads.patch b/thirdparty/embree/patches/emscripten-nthreads.patch new file mode 100644 index 0000000000..e42f203475 --- /dev/null +++ b/thirdparty/embree/patches/emscripten-nthreads.patch @@ -0,0 +1,42 @@ +diff --git a/thirdparty/embree/common/sys/sysinfo.cpp b/thirdparty/embree/common/sys/sysinfo.cpp +index c98f61fa53..7f7a009a1e 100644 +--- a/thirdparty/embree/common/sys/sysinfo.cpp ++++ b/thirdparty/embree/common/sys/sysinfo.cpp +@@ -640,6 +640,12 @@ namespace embree + + #if defined(__EMSCRIPTEN__) + #include <emscripten.h> ++ ++// -- GODOT start -- ++extern "C" { ++extern int godot_js_os_hw_concurrency_get(); ++} ++// -- GODOT end -- + #endif + + namespace embree +@@ -653,21 +659,9 @@ namespace embree + nThreads = sysconf(_SC_NPROCESSORS_ONLN); // does not work in Linux LXC container + assert(nThreads); + #elif defined(__EMSCRIPTEN__) +- // WebAssembly supports pthreads, but not pthread_getaffinity_np. Get the number of logical +- // threads from the browser or Node.js using JavaScript. +- nThreads = MAIN_THREAD_EM_ASM_INT({ +- const isBrowser = typeof window !== 'undefined'; +- const isNode = typeof process !== 'undefined' && process.versions != null && +- process.versions.node != null; +- if (isBrowser) { +- // Return 1 if the browser does not expose hardwareConcurrency. +- return window.navigator.hardwareConcurrency || 1; +- } else if (isNode) { +- return require('os').cpus().length; +- } else { +- return 1; +- } +- }); ++ // -- GODOT start -- ++ nThreads = godot_js_os_hw_concurrency_get(); ++ // -- GODOT end -- + #else + cpu_set_t set; + if (pthread_getaffinity_np(pthread_self(), sizeof(set), &set) == 0) diff --git a/thirdparty/embree/patches/godot-changes-android.patch b/thirdparty/embree/patches/godot-changes-android.patch deleted file mode 100644 index a27f924bde..0000000000 --- a/thirdparty/embree/patches/godot-changes-android.patch +++ /dev/null @@ -1,103 +0,0 @@ -diff --git a/thirdparty/embree/common/sys/sysinfo.cpp b/thirdparty/embree/common/sys/sysinfo.cpp -index ba97dc227b..1679599608 100644 ---- a/thirdparty/embree/common/sys/sysinfo.cpp -+++ b/thirdparty/embree/common/sys/sysinfo.cpp -@@ -618,7 +618,10 @@ namespace embree - static int nThreads = -1; - if (nThreads != -1) return nThreads; - --#if defined(__MACOSX__) -+// -- GODOT start -- -+// #if defined(__MACOSX__) -+#if defined(__MACOSX__) || defined(__ANDROID__) -+// -- GODOT end -- - nThreads = sysconf(_SC_NPROCESSORS_ONLN); // does not work in Linux LXC container - assert(nThreads); - #else -diff --git a/thirdparty/embree/common/sys/thread.cpp b/thirdparty/embree/common/sys/thread.cpp -index a7827e18f7..f4014be89b 100644 ---- a/thirdparty/embree/common/sys/thread.cpp -+++ b/thirdparty/embree/common/sys/thread.cpp -@@ -158,7 +158,9 @@ namespace embree - /// Linux Platform - //////////////////////////////////////////////////////////////////////////////// - --#if defined(__LINUX__) -+// -- GODOT start -- -+#if defined(__LINUX__) && !defined(__ANDROID__) -+// -- GODOT end -- - - #include <fstream> - #include <sstream> -@@ -247,6 +249,28 @@ namespace embree - } - #endif - -+// -- GODOT start -- -+//////////////////////////////////////////////////////////////////////////////// -+/// Android Platform -+//////////////////////////////////////////////////////////////////////////////// -+ -+#if defined(__ANDROID__) -+ -+namespace embree -+{ -+ /*! set affinity of the calling thread */ -+ void setAffinity(ssize_t affinity) -+ { -+ cpu_set_t cset; -+ CPU_ZERO(&cset); -+ CPU_SET(affinity, &cset); -+ -+ sched_setaffinity(0, sizeof(cset), &cset); -+ } -+} -+#endif -+// -- GODOT end -- -+ - //////////////////////////////////////////////////////////////////////////////// - /// FreeBSD Platform - //////////////////////////////////////////////////////////////////////////////// -@@ -355,7 +379,9 @@ namespace embree - pthread_attr_destroy(&attr); - - /* set affinity */ --#if defined(__LINUX__) -+// -- GODOT start -- -+#if defined(__LINUX__) && !defined(__ANDROID__) -+// -- GODOT end -- - if (threadID >= 0) { - cpu_set_t cset; - CPU_ZERO(&cset); -@@ -370,7 +396,16 @@ namespace embree - CPU_SET(threadID, &cset); - pthread_setaffinity_np(*tid, sizeof(cset), &cset); - } -+// -- GODOT start -- -+#elif defined(__ANDROID__) -+ if (threadID >= 0) { -+ cpu_set_t cset; -+ CPU_ZERO(&cset); -+ CPU_SET(threadID, &cset); -+ sched_setaffinity(pthread_gettid_np(*tid), sizeof(cset), &cset); -+ } - #endif -+// -- GODOT end -- - - return thread_t(tid); - } -@@ -389,8 +424,14 @@ namespace embree - - /*! destroy a hardware thread by its handle */ - void destroyThread(thread_t tid) { -+// -- GODOT start -- -+#if defined(__ANDROID__) -+ FATAL("Can't destroy threads on Android."); -+#else - pthread_cancel(*(pthread_t*)tid); - delete (pthread_t*)tid; -+#endif -+// -- GODOT end -- - } - - /*! creates thread local storage */ diff --git a/thirdparty/embree/patches/godot-changes-misc.patch b/thirdparty/embree/patches/godot-changes-misc.patch deleted file mode 100644 index 8bf0d9fa97..0000000000 --- a/thirdparty/embree/patches/godot-changes-misc.patch +++ /dev/null @@ -1,105 +0,0 @@ -diff --git a/thirdparty/embree/common/sys/intrinsics.h b/thirdparty/embree/common/sys/intrinsics.h -index 79729c87ab..ed8dd7d40a 100644 ---- a/thirdparty/embree/common/sys/intrinsics.h -+++ b/thirdparty/embree/common/sys/intrinsics.h -@@ -34,8 +34,14 @@ - #endif - - #if defined(__WIN32__) --# define NOMINMAX --# include <windows.h> -+// -- GODOT start -- -+#if !defined(NOMINMAX) -+// -- GODOT end -- -+#define NOMINMAX -+// -- GODOT start -- -+#endif -+#include "windows.h" -+// -- GODOT end -- - #endif - - /* normally defined in pmmintrin.h, but we always need this */ -diff --git a/thirdparty/embree/common/sys/platform.h b/thirdparty/embree/common/sys/platform.h -index 3fc5e99b8d..697e07bb86 100644 ---- a/thirdparty/embree/common/sys/platform.h -+++ b/thirdparty/embree/common/sys/platform.h -@@ -99,7 +99,9 @@ - #define dll_import - #endif - --#ifdef __WIN32__ -+// -- GODOT start -- -+#if defined(__WIN32__) && !defined(__MINGW32__) -+// -- GODOT end -- - #if !defined(__noinline) - #define __noinline __declspec(noinline) - #endif -@@ -149,6 +151,9 @@ - #define DELETED = delete - #endif - -+// -- GODOT start -- -+#if !defined(likely) -+// -- GODOT end -- - #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) - #define likely(expr) (expr) - #define unlikely(expr) (expr) -@@ -156,6 +161,9 @@ - #define likely(expr) __builtin_expect((bool)(expr),true ) - #define unlikely(expr) __builtin_expect((bool)(expr),false) - #endif -+// -- GODOT start -- -+#endif -+// -- GODOT end -- - - //////////////////////////////////////////////////////////////////////////////// - /// Error handling and debugging -diff --git a/thirdparty/embree/common/sys/sysinfo.cpp b/thirdparty/embree/common/sys/sysinfo.cpp -index ba97dc227b..f1a59e511e 100644 ---- a/thirdparty/embree/common/sys/sysinfo.cpp -+++ b/thirdparty/embree/common/sys/sysinfo.cpp -@@ -248,7 +248,9 @@ namespace embree - #if defined(__X86_ASM__) - __noinline int64_t get_xcr0() - { --#if defined (__WIN32__) -+// -- GODOT start -- -+#if defined (__WIN32__) && !defined (__MINGW32__) -+// -- GODOT end -- - int64_t xcr0 = 0; // int64_t is workaround for compiler bug under VS2013, Win32 - xcr0 = _xgetbv(0); - return xcr0; -diff --git a/thirdparty/embree/include/embree3/rtcore_common.h b/thirdparty/embree/include/embree3/rtcore_common.h -index 9c14b28745..4857e1e05e 100644 ---- a/thirdparty/embree/include/embree3/rtcore_common.h -+++ b/thirdparty/embree/include/embree3/rtcore_common.h -@@ -19,7 +19,9 @@ typedef int ssize_t; - #endif - #endif - --#ifdef _WIN32 -+// -- GODOT start -- -+#if defined(_WIN32) && defined(_MSC_VER) -+// -- GODOT end -- - # define RTC_ALIGN(...) __declspec(align(__VA_ARGS__)) - #else - # define RTC_ALIGN(...) __attribute__((aligned(__VA_ARGS__))) -diff --git a/thirdparty/embree/common/tasking/taskschedulertbb.h b/thirdparty/embree/common/tasking/taskschedulertbb.h -index 3fd15816e9..35bd49849f 100644 ---- a/thirdparty/embree/common/tasking/taskschedulertbb.h -+++ b/thirdparty/embree/common/tasking/taskschedulertbb.h -@@ -12,7 +12,13 @@ - #include "../sys/ref.h" - - #if defined(__WIN32__) -+// -- GODOT start -- -+#if !defined(NOMINMAX) -+// -- GODOT end -- - # define NOMINMAX -+// -- GODOT start -- -+#endif -+// -- GODOT end -- - #endif - - // We need to define these to avoid implicit linkage against -
\ No newline at end of file diff --git a/thirdparty/embree/patches/godot-changes-noexcept.patch b/thirdparty/embree/patches/godot-changes-noexcept.patch index 598a7f2ddc..84169c36e4 100644 --- a/thirdparty/embree/patches/godot-changes-noexcept.patch +++ b/thirdparty/embree/patches/godot-changes-noexcept.patch @@ -1,5 +1,5 @@ diff --git a/thirdparty/embree/common/algorithms/parallel_for.h b/thirdparty/embree/common/algorithms/parallel_for.h -index f052d8b468..645681ac63 100644 +index f2969a88f1..6d411e4852 100644 --- a/thirdparty/embree/common/algorithms/parallel_for.h +++ b/thirdparty/embree/common/algorithms/parallel_for.h @@ -21,7 +21,10 @@ namespace embree @@ -12,9 +12,9 @@ index f052d8b468..645681ac63 100644 + abort(); + // -- GODOT end -- } - #elif defined(TASKING_TBB) -@@ -31,13 +34,19 @@ namespace embree + #if TBB_INTERFACE_VERSION >= 12002 +@@ -30,13 +33,19 @@ namespace embree func(i); },context); if (context.is_group_execution_cancelled()) @@ -36,7 +36,7 @@ index f052d8b468..645681ac63 100644 #endif #elif defined(TASKING_PPL) -@@ -57,7 +66,10 @@ namespace embree +@@ -56,7 +65,10 @@ namespace embree #if defined(TASKING_INTERNAL) TaskScheduler::spawn(first,last,minStepSize,func); if (!TaskScheduler::wait()) @@ -48,7 +48,7 @@ index f052d8b468..645681ac63 100644 #elif defined(TASKING_TBB) #if TBB_INTERFACE_VERSION >= 12002 -@@ -66,13 +78,19 @@ namespace embree +@@ -65,13 +77,19 @@ namespace embree func(range<Index>(r.begin(),r.end())); },context); if (context.is_group_execution_cancelled()) @@ -70,7 +70,7 @@ index f052d8b468..645681ac63 100644 #endif #elif defined(TASKING_PPL) -@@ -104,13 +122,19 @@ namespace embree +@@ -103,13 +121,19 @@ namespace embree func(i); },tbb::simple_partitioner(),context); if (context.is_group_execution_cancelled()) @@ -92,7 +92,7 @@ index f052d8b468..645681ac63 100644 #endif } -@@ -125,13 +149,19 @@ namespace embree +@@ -124,13 +148,19 @@ namespace embree func(i); },ap,context); if (context.is_group_execution_cancelled()) @@ -115,7 +115,7 @@ index f052d8b468..645681ac63 100644 } diff --git a/thirdparty/embree/common/algorithms/parallel_reduce.h b/thirdparty/embree/common/algorithms/parallel_reduce.h -index f42ae2ec50..8271372ea4 100644 +index 1a94aad8c4..cd0078f2e6 100644 --- a/thirdparty/embree/common/algorithms/parallel_reduce.h +++ b/thirdparty/embree/common/algorithms/parallel_reduce.h @@ -58,15 +58,19 @@ namespace embree @@ -247,10 +247,10 @@ index 1bc30fe9a5..abdd269069 100644 /* hint for transparent huge pages (THP) */ diff --git a/thirdparty/embree/common/sys/platform.h b/thirdparty/embree/common/sys/platform.h -index 8a6d9fa0a9..697e07bb86 100644 +index be3ec36436..728bf6ed7d 100644 --- a/thirdparty/embree/common/sys/platform.h +++ b/thirdparty/embree/common/sys/platform.h -@@ -179,11 +179,19 @@ +@@ -178,11 +178,19 @@ #define PRINT4(x,y,z,w) embree_cout << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << ", " << STRING(w) << " = " << (w) << embree_endl #if defined(DEBUG) // only report file and line in debug mode @@ -351,7 +351,7 @@ index dca835a716..ad438588a3 100644 bool TaskScheduler::steal_from_other_threads(Thread& thread) diff --git a/thirdparty/embree/common/tasking/taskschedulerinternal.h b/thirdparty/embree/common/tasking/taskschedulerinternal.h -index c766a0bb6a..8fa6bb12fa 100644 +index 61a0e57c5b..6cc2495195 100644 --- a/thirdparty/embree/common/tasking/taskschedulerinternal.h +++ b/thirdparty/embree/common/tasking/taskschedulerinternal.h @@ -123,7 +123,10 @@ namespace embree @@ -391,7 +391,7 @@ index c766a0bb6a..8fa6bb12fa 100644 /*! steals a task from a different thread */ bool steal_from_other_threads(Thread& thread); diff --git a/thirdparty/embree/kernels/bvh/bvh_statistics.cpp b/thirdparty/embree/kernels/bvh/bvh_statistics.cpp -index d8da78eed7..d857ff7d95 100644 +index 40f9043736..57f75bfd7e 100644 --- a/thirdparty/embree/kernels/bvh/bvh_statistics.cpp +++ b/thirdparty/embree/kernels/bvh/bvh_statistics.cpp @@ -150,7 +150,10 @@ namespace embree @@ -407,10 +407,10 @@ index d8da78eed7..d857ff7d95 100644 return s; } diff --git a/thirdparty/embree/kernels/common/rtcore.cpp b/thirdparty/embree/kernels/common/rtcore.cpp -index 74e9fb335c..94b3819e42 100644 +index 95a94319ec..a6ea55bfc4 100644 --- a/thirdparty/embree/kernels/common/rtcore.cpp +++ b/thirdparty/embree/kernels/common/rtcore.cpp -@@ -197,7 +197,10 @@ RTC_NAMESPACE_BEGIN; +@@ -198,7 +198,10 @@ RTC_NAMESPACE_BEGIN; if (quality != RTC_BUILD_QUALITY_LOW && quality != RTC_BUILD_QUALITY_MEDIUM && quality != RTC_BUILD_QUALITY_HIGH) @@ -422,7 +422,7 @@ index 74e9fb335c..94b3819e42 100644 scene->setBuildQuality(quality); RTC_CATCH_END2(scene); } -@@ -1350,7 +1353,10 @@ RTC_NAMESPACE_BEGIN; +@@ -1351,7 +1354,10 @@ RTC_NAMESPACE_BEGIN; quality != RTC_BUILD_QUALITY_MEDIUM && quality != RTC_BUILD_QUALITY_HIGH && quality != RTC_BUILD_QUALITY_REFIT) @@ -435,172 +435,67 @@ index 74e9fb335c..94b3819e42 100644 RTC_CATCH_END2(geometry); } diff --git a/thirdparty/embree/kernels/common/rtcore.h b/thirdparty/embree/kernels/common/rtcore.h -index 4e4b24e9c2..373e49a689 100644 +index 4e4b24e9c2..ac58a84d6f 100644 --- a/thirdparty/embree/kernels/common/rtcore.h +++ b/thirdparty/embree/kernels/common/rtcore.h -@@ -25,52 +25,58 @@ namespace embree +@@ -25,6 +25,13 @@ namespace embree #endif /*! Macros used in the rtcore API implementation */ --#define RTC_CATCH_BEGIN try { +// -- GODOT start -- -+// #define RTC_CATCH_BEGIN try { +#define RTC_CATCH_BEGIN - --#define RTC_CATCH_END(device) \ -- } catch (std::bad_alloc&) { \ -- Device::process_error(device,RTC_ERROR_OUT_OF_MEMORY,"out of memory"); \ -- } catch (rtcore_error& e) { \ -- Device::process_error(device,e.error,e.what()); \ -- } catch (std::exception& e) { \ -- Device::process_error(device,RTC_ERROR_UNKNOWN,e.what()); \ -- } catch (...) { \ -- Device::process_error(device,RTC_ERROR_UNKNOWN,"unknown exception caught"); \ -- } -+// #define RTC_CATCH_END(device) \ -+// } catch (std::bad_alloc&) { \ -+// Device::process_error(device,RTC_ERROR_OUT_OF_MEMORY,"out of memory"); \ -+// } catch (rtcore_error& e) { \ -+// Device::process_error(device,e.error,e.what()); \ -+// } catch (std::exception& e) { \ -+// Device::process_error(device,RTC_ERROR_UNKNOWN,e.what()); \ -+// } catch (...) { \ -+// Device::process_error(device,RTC_ERROR_UNKNOWN,"unknown exception caught"); \ -+// } +#define RTC_CATCH_END(device) - --#define RTC_CATCH_END2(scene) \ -- } catch (std::bad_alloc&) { \ -- Device* device = scene ? scene->device : nullptr; \ -- Device::process_error(device,RTC_ERROR_OUT_OF_MEMORY,"out of memory"); \ -- } catch (rtcore_error& e) { \ -- Device* device = scene ? scene->device : nullptr; \ -- Device::process_error(device,e.error,e.what()); \ -- } catch (std::exception& e) { \ -- Device* device = scene ? scene->device : nullptr; \ -- Device::process_error(device,RTC_ERROR_UNKNOWN,e.what()); \ -- } catch (...) { \ -- Device* device = scene ? scene->device : nullptr; \ -- Device::process_error(device,RTC_ERROR_UNKNOWN,"unknown exception caught"); \ -- } -+// #define RTC_CATCH_END2(scene) \ -+// } catch (std::bad_alloc&) { \ -+// Device* device = scene ? scene->device : nullptr; \ -+// Device::process_error(device,RTC_ERROR_OUT_OF_MEMORY,"out of memory"); \ -+// } catch (rtcore_error& e) { \ -+// Device* device = scene ? scene->device : nullptr; \ -+// Device::process_error(device,e.error,e.what()); \ -+// } catch (std::exception& e) { \ -+// Device* device = scene ? scene->device : nullptr; \ -+// Device::process_error(device,RTC_ERROR_UNKNOWN,e.what()); \ -+// } catch (...) { \ -+// Device* device = scene ? scene->device : nullptr; \ -+// Device::process_error(device,RTC_ERROR_UNKNOWN,"unknown exception caught"); \ -+// } +#define RTC_CATCH_END2(scene) - --#define RTC_CATCH_END2_FALSE(scene) \ -- } catch (std::bad_alloc&) { \ -- Device* device = scene ? scene->device : nullptr; \ -- Device::process_error(device,RTC_ERROR_OUT_OF_MEMORY,"out of memory"); \ -- return false; \ -- } catch (rtcore_error& e) { \ -- Device* device = scene ? scene->device : nullptr; \ -- Device::process_error(device,e.error,e.what()); \ -- return false; \ -- } catch (std::exception& e) { \ -- Device* device = scene ? scene->device : nullptr; \ -- Device::process_error(device,RTC_ERROR_UNKNOWN,e.what()); \ -- return false; \ -- } catch (...) { \ -- Device* device = scene ? scene->device : nullptr; \ -- Device::process_error(device,RTC_ERROR_UNKNOWN,"unknown exception caught"); \ -- return false; \ -- } -+// #define RTC_CATCH_END2_FALSE(scene) \ -+// } catch (std::bad_alloc&) { \ -+// Device* device = scene ? scene->device : nullptr; \ -+// Device::process_error(device,RTC_ERROR_OUT_OF_MEMORY,"out of memory"); \ -+// return false; \ -+// } catch (rtcore_error& e) { \ -+// Device* device = scene ? scene->device : nullptr; \ -+// Device::process_error(device,e.error,e.what()); \ -+// return false; \ -+// } catch (std::exception& e) { \ -+// Device* device = scene ? scene->device : nullptr; \ -+// Device::process_error(device,RTC_ERROR_UNKNOWN,e.what()); \ -+// return false; \ -+// } catch (...) { \ -+// Device* device = scene ? scene->device : nullptr; \ -+// Device::process_error(device,RTC_ERROR_UNKNOWN,"unknown exception caught"); \ -+// return false; \ -+// } +#define RTC_CATCH_END2_FALSE(scene) return false; ++ ++#if 0 + #define RTC_CATCH_BEGIN try { + + #define RTC_CATCH_END(device) \ +@@ -71,6 +78,8 @@ namespace embree + Device::process_error(device,RTC_ERROR_UNKNOWN,"unknown exception caught"); \ + return false; \ + } ++#endif +// -- GODOT end -- #define RTC_VERIFY_HANDLE(handle) \ if (handle == nullptr) { \ -@@ -97,28 +103,38 @@ namespace embree +@@ -97,6 +106,8 @@ namespace embree #define RTC_TRACE(x) #endif -- /*! used to throw embree API errors */ -- struct rtcore_error : public std::exception -- { -- __forceinline rtcore_error(RTCError error, const std::string& str) -- : error(error), str(str) {} -- -- ~rtcore_error() throw() {} -- -- const char* what () const throw () { -- return str.c_str(); -- } -- -- RTCError error; -- std::string str; -- }; -+// -- GODOT begin -- -+// /*! used to throw embree API errors */ -+// struct rtcore_error : public std::exception -+// { -+// __forceinline rtcore_error(RTCError error, const std::string& str) -+// : error(error), str(str) {} -+// -+// ~rtcore_error() throw() {} -+// -+// const char* what () const throw () { -+// return str.c_str(); -+// } -+// -+// RTCError error; -+// std::string str; -+// }; -+// -- GODOT end -- ++// -- GODOT start -- ++#if 0 + /*! used to throw embree API errors */ + struct rtcore_error : public std::exception + { +@@ -112,14 +123,18 @@ namespace embree + RTCError error; + std::string str; + }; ++#endif #if defined(DEBUG) // only report file and line in debug mode -+ // -- GODOT begin -- -+ // #define throw_RTCError(error,str) \ -+ // throw rtcore_error(error,std::string(__FILE__) + " (" + toString(__LINE__) + "): " + std::string(str)); #define throw_RTCError(error,str) \ - throw rtcore_error(error,std::string(__FILE__) + " (" + toString(__LINE__) + "): " + std::string(str)); + printf("%s (%d): %s", __FILE__, __LINE__, std::string(str).c_str()), abort(); -+ // -- GODOT end -- ++ // throw rtcore_error(error,std::string(__FILE__) + " (" + toString(__LINE__) + "): " + std::string(str)); #else -+ // -- GODOT begin -- -+ // #define throw_RTCError(error,str) \ -+ // throw rtcore_error(error,str); #define throw_RTCError(error,str) \ - throw rtcore_error(error,str); + abort(); -+ // -- GODOT end -- ++ // throw rtcore_error(error,str); #endif ++// -- GODOT end -- #define RTC_BUILD_ARGUMENTS_HAS(settings,member) \ + (settings.byteSize > (offsetof(RTCBuildArguments,member)+sizeof(settings.member))) diff --git a/thirdparty/embree/kernels/common/scene.cpp b/thirdparty/embree/kernels/common/scene.cpp -index 0149055f2c..408d7eae6f 100644 +index ad1916c54e..65d31d0f81 100644 --- a/thirdparty/embree/kernels/common/scene.cpp +++ b/thirdparty/embree/kernels/common/scene.cpp -@@ -792,16 +792,18 @@ namespace embree +@@ -790,16 +790,18 @@ namespace embree } /* initiate build */ diff --git a/thirdparty/embree/patches/godot-changes-ubsan.patch b/thirdparty/embree/patches/godot-changes-ubsan.patch deleted file mode 100644 index 1336246f0d..0000000000 --- a/thirdparty/embree/patches/godot-changes-ubsan.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --git a/thirdparty/embree/kernels/builders/primrefgen.cpp b/thirdparty/embree/kernels/builders/primrefgen.cpp -index bb4fc81dfe..d279dc4993 100644 ---- a/thirdparty/embree/kernels/builders/primrefgen.cpp -+++ b/thirdparty/embree/kernels/builders/primrefgen.cpp -@@ -184,6 +184,9 @@ namespace embree - - // special variants for grid meshes - -+// -- GODOT start -- -+#if defined(EMBREE_GEOMETRY_GRID) -+// -- GODOT end -- - PrimInfo createPrimRefArrayGrids(Scene* scene, mvector<PrimRef>& prims, mvector<SubGridBuildData>& sgrids) - { - PrimInfo pinfo(empty); -@@ -293,6 +296,9 @@ namespace embree - - return pinfo; - } -+// -- GODOT start -- -+#endif -+// -- GODOT end -- - - // ==================================================================================================== - // ==================================================================================================== diff --git a/thirdparty/enet/enet/godot.h b/thirdparty/enet/enet/godot.h index faca1f21a0..1c60fdbb1f 100644 --- a/thirdparty/enet/enet/godot.h +++ b/thirdparty/enet/enet/godot.h @@ -1,32 +1,33 @@ -/*************************************************************************/ -/* godot.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 godot.h @brief ENet Godot header diff --git a/thirdparty/enet/enet/godot_ext.h b/thirdparty/enet/enet/godot_ext.h index 648f3d2f24..06a621b790 100644 --- a/thirdparty/enet/enet/godot_ext.h +++ b/thirdparty/enet/enet/godot_ext.h @@ -11,8 +11,8 @@ */ ENET_API void enet_address_set_ip(ENetAddress * address, const uint8_t * ip, size_t size); -ENET_API int enet_host_dtls_server_setup (ENetHost *, void *, void *); -ENET_API int enet_host_dtls_client_setup (ENetHost *, void *, uint8_t, const char *); +ENET_API int enet_host_dtls_server_setup (ENetHost *, void *); +ENET_API int enet_host_dtls_client_setup (ENetHost *, const char *, void *); ENET_API void enet_host_refuse_new_connections (ENetHost *, int); #endif // __ENET_GODOT_EXT_H__ diff --git a/thirdparty/enet/godot.cpp b/thirdparty/enet/godot.cpp index d2fcc4642e..ea7f4957a2 100644 --- a/thirdparty/enet/godot.cpp +++ b/thirdparty/enet/godot.cpp @@ -1,32 +1,33 @@ -/*************************************************************************/ -/* godot.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 godot.cpp @brief ENet Godot specific functions @@ -163,16 +164,14 @@ class ENetDTLSClient : public ENetGodotSocket { bool connected = false; Ref<PacketPeerUDP> udp; Ref<PacketPeerDTLS> dtls; - bool verify = false; + Ref<TLSOptions> tls_options; String for_hostname; - Ref<X509Certificate> cert; IPAddress local_address; public: - ENetDTLSClient(ENetUDP *p_base, Ref<X509Certificate> p_cert, bool p_verify, String p_for_hostname) { - verify = p_verify; + ENetDTLSClient(ENetUDP *p_base, String p_for_hostname, Ref<TLSOptions> p_options) { for_hostname = p_for_hostname; - cert = p_cert; + tls_options = p_options; udp.instantiate(); dtls = Ref<PacketPeerDTLS>(PacketPeerDTLS::create()); if (p_base->bound) { @@ -204,7 +203,7 @@ public: Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IPAddress p_ip, uint16_t p_port) { if (!connected) { udp->connect_to_host(p_ip, p_port); - if (dtls->connect_to_peer(udp, verify, for_hostname, cert)) { + if (dtls->connect_to_peer(udp, for_hostname, tls_options)) { return FAILED; } connected = true; @@ -264,7 +263,7 @@ class ENetDTLSServer : public ENetGodotSocket { IPAddress local_address; public: - ENetDTLSServer(ENetUDP *p_base, Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert) { + ENetDTLSServer(ENetUDP *p_base, Ref<TLSOptions> p_options) { udp_server.instantiate(); if (p_base->bound) { uint16_t port; @@ -273,7 +272,7 @@ public: bind(local_address, port); } server = Ref<DTLSServer>(DTLSServer::create()); - server->setup(p_key, p_cert); + server->setup(p_options); } ~ENetDTLSServer() { @@ -436,22 +435,22 @@ ENetSocket enet_socket_create(ENetSocketType type) { return socket; } -int enet_host_dtls_server_setup(ENetHost *host, void *p_key, void *p_cert) { +int enet_host_dtls_server_setup(ENetHost *host, void *p_options) { ENetGodotSocket *sock = (ENetGodotSocket *)host->socket; if (!sock->can_upgrade()) { return -1; } - host->socket = memnew(ENetDTLSServer((ENetUDP *)sock, Ref<CryptoKey>((CryptoKey *)p_key), Ref<X509Certificate>((X509Certificate *)p_cert))); + host->socket = memnew(ENetDTLSServer(static_cast<ENetUDP *>(sock), Ref<TLSOptions>(static_cast<TLSOptions *>(p_options)))); memdelete(sock); return 0; } -int enet_host_dtls_client_setup(ENetHost *host, void *p_cert, uint8_t p_verify, const char *p_for_hostname) { +int enet_host_dtls_client_setup(ENetHost *host, const char *p_for_hostname, void *p_options) { ENetGodotSocket *sock = (ENetGodotSocket *)host->socket; if (!sock->can_upgrade()) { return -1; } - host->socket = memnew(ENetDTLSClient((ENetUDP *)sock, Ref<X509Certificate>((X509Certificate *)p_cert), p_verify, String::utf8(p_for_hostname))); + host->socket = memnew(ENetDTLSClient(static_cast<ENetUDP *>(sock), String::utf8(p_for_hostname), Ref<TLSOptions>(static_cast<TLSOptions *>(p_options)))); memdelete(sock); return 0; } diff --git a/thirdparty/freetype/src/gzip/adler32.c b/thirdparty/freetype/src/gzip/adler32.c deleted file mode 100644 index aa032e1ddf..0000000000 --- a/thirdparty/freetype/src/gzip/adler32.c +++ /dev/null @@ -1,192 +0,0 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2011, 2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -#ifndef Z_FREETYPE -local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); -#endif - -#define BASE 65521U /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* use NO_DIVIDE if your processor does not do division in hardware -- - try it both ways to see which is faster */ -#ifdef NO_DIVIDE -/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 - (thank you to John Reiser for pointing this out) */ -# define CHOP(a) \ - do { \ - unsigned long tmp = a >> 16; \ - a &= 0xffffUL; \ - a += (tmp << 4) - tmp; \ - } while (0) -# define MOD28(a) \ - do { \ - CHOP(a); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD(a) \ - do { \ - CHOP(a); \ - MOD28(a); \ - } while (0) -# define MOD63(a) \ - do { /* this assumes a is not negative */ \ - z_off64_t tmp = a >> 32; \ - a &= 0xffffffffL; \ - a += (tmp << 8) - (tmp << 5) + tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -# define MOD28(a) a %= BASE -# define MOD63(a) a %= BASE -#endif - -/* ========================================================================= */ -uLong ZEXPORT adler32_z( - uLong adler, - const Bytef *buf, - z_size_t len) -{ - unsigned long sum2; - unsigned n; - - /* split Adler-32 into component sums */ - sum2 = (adler >> 16) & 0xffff; - adler &= 0xffff; - - /* in case user likes doing a byte at a time, keep it fast */ - if (len == 1) { - adler += buf[0]; - if (adler >= BASE) - adler -= BASE; - sum2 += adler; - if (sum2 >= BASE) - sum2 -= BASE; - return adler | (sum2 << 16); - } - - /* initial Adler-32 value (deferred check for len == 1 speed) */ - if (buf == Z_NULL) - return 1L; - - /* in case short lengths are provided, keep it somewhat fast */ - if (len < 16) { - while (len--) { - adler += *buf++; - sum2 += adler; - } - if (adler >= BASE) - adler -= BASE; - MOD28(sum2); /* only added so many BASE's */ - return adler | (sum2 << 16); - } - - /* do length NMAX blocks -- requires just one modulo operation */ - while (len >= NMAX) { - len -= NMAX; - n = NMAX / 16; /* NMAX is divisible by 16 */ - do { - DO16(buf); /* 16 sums unrolled */ - buf += 16; - } while (--n); - MOD(adler); - MOD(sum2); - } - - /* do remaining bytes (less than NMAX, still just one modulo) */ - if (len) { /* avoid modulos if none remaining */ - while (len >= 16) { - len -= 16; - DO16(buf); - buf += 16; - } - while (len--) { - adler += *buf++; - sum2 += adler; - } - MOD(adler); - MOD(sum2); - } - - /* return recombined sums */ - return adler | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32( - uLong adler, - const Bytef *buf, - uInt len) -{ - return adler32_z(adler, buf, len); -} - -#ifndef Z_FREETYPE - -/* ========================================================================= */ -local uLong adler32_combine_( - uLong adler1, - uLong adler2, - z_off64_t len2) -{ - unsigned long sum1; - unsigned long sum2; - unsigned rem; - - /* for negative len, return invalid adler32 as a clue for debugging */ - if (len2 < 0) - return 0xffffffffUL; - - /* the derivation of this formula is left as an exercise for the reader */ - MOD63(len2); /* assumes len2 >= 0 */ - rem = (unsigned)len2; - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 >= BASE) sum1 -= BASE; - if (sum1 >= BASE) sum1 -= BASE; - if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); - if (sum2 >= BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32_combine( - uLong adler1, - uLong adler2, - z_off_t len2) -{ - return adler32_combine_(adler1, adler2, len2); -} - -uLong ZEXPORT adler32_combine64( - uLong adler1, - uLong adler2, - z_off64_t len2) -{ - return adler32_combine_(adler1, adler2, len2); -} - -#endif /* !Z_FREETYPE */ diff --git a/thirdparty/freetype/src/gzip/crc32.c b/thirdparty/freetype/src/gzip/crc32.c deleted file mode 100644 index 2ddc32d1fb..0000000000 --- a/thirdparty/freetype/src/gzip/crc32.c +++ /dev/null @@ -1,1116 +0,0 @@ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2022 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - * - * This interleaved implementation of a CRC makes use of pipelined multiple - * arithmetic-logic units, commonly found in modern CPU cores. It is due to - * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution. - */ - -/* @(#) $Id$ */ - -/* - Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore - protection on the static variables used to control the first-use generation - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should - first call get_crc_table() to initialize the tables before allowing more than - one thread to use crc32(). - - MAKECRCH can be #defined to write out crc32.h. A main() routine is also - produced, so that this one source file can be compiled to an executable. - */ - -#ifdef MAKECRCH -# include <stdio.h> -# ifndef DYNAMIC_CRC_TABLE -# define DYNAMIC_CRC_TABLE -# endif /* !DYNAMIC_CRC_TABLE */ -#endif /* MAKECRCH */ - -#include "zutil.h" /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */ - - /* - A CRC of a message is computed on N braids of words in the message, where - each word consists of W bytes (4 or 8). If N is 3, for example, then three - running sparse CRCs are calculated respectively on each braid, at these - indices in the array of words: 0, 3, 6, ..., 1, 4, 7, ..., and 2, 5, 8, ... - This is done starting at a word boundary, and continues until as many blocks - of N * W bytes as are available have been processed. The results are combined - into a single CRC at the end. For this code, N must be in the range 1..6 and - W must be 4 or 8. The upper limit on N can be increased if desired by adding - more #if blocks, extending the patterns apparent in the code. In addition, - crc32.h would need to be regenerated, if the maximum N value is increased. - - N and W are chosen empirically by benchmarking the execution time on a given - processor. The choices for N and W below were based on testing on Intel Kaby - Lake i7, AMD Ryzen 7, ARM Cortex-A57, Sparc64-VII, PowerPC POWER9, and MIPS64 - Octeon II processors. The Intel, AMD, and ARM processors were all fastest - with N=5, W=8. The Sparc, PowerPC, and MIPS64 were all fastest at N=5, W=4. - They were all tested with either gcc or clang, all using the -O3 optimization - level. Your mileage may vary. - */ - -/* Define N */ -#ifdef Z_TESTN -# define N Z_TESTN -#else -# define N 5 -#endif -#if N < 1 || N > 6 -# error N must be in 1..6 -#endif - -/* - z_crc_t must be at least 32 bits. z_word_t must be at least as long as - z_crc_t. It is assumed here that z_word_t is either 32 bits or 64 bits, and - that bytes are eight bits. - */ - -/* - Define W and the associated z_word_t type. If W is not defined, then a - braided calculation is not used, and the associated tables and code are not - compiled. - */ -#ifdef Z_TESTW -# if Z_TESTW-1 != -1 -# define W Z_TESTW -# endif -#else -# ifdef MAKECRCH -# define W 8 /* required for MAKECRCH */ -# else -# if defined(__x86_64__) || defined(__aarch64__) -# define W 8 -# else -# define W 4 -# endif -# endif -#endif -#ifdef W -# if W == 8 && defined(Z_U8) - typedef Z_U8 z_word_t; -# elif defined(Z_U4) -# undef W -# define W 4 - typedef Z_U4 z_word_t; -# else -# undef W -# endif -#endif - -/* Local functions. */ -local z_crc_t multmodp OF((z_crc_t a, z_crc_t b)); -local z_crc_t x2nmodp OF((z_off64_t n, unsigned k)); - -/* If available, use the ARM processor CRC32 instruction. */ -#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8 -# define ARMCRC32 -#endif - -#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE)) -/* - Swap the bytes in a z_word_t to convert between little and big endian. Any - self-respecting compiler will optimize this to a single machine byte-swap - instruction, if one is available. This assumes that word_t is either 32 bits - or 64 bits. - */ -local z_word_t byte_swap( - z_word_t word) -{ -# if W == 8 - return - (word & 0xff00000000000000) >> 56 | - (word & 0xff000000000000) >> 40 | - (word & 0xff0000000000) >> 24 | - (word & 0xff00000000) >> 8 | - (word & 0xff000000) << 8 | - (word & 0xff0000) << 24 | - (word & 0xff00) << 40 | - (word & 0xff) << 56; -# else /* W == 4 */ - return - (word & 0xff000000) >> 24 | - (word & 0xff0000) >> 8 | - (word & 0xff00) << 8 | - (word & 0xff) << 24; -# endif -} -#endif - -/* CRC polynomial. */ -#define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */ - -#ifdef DYNAMIC_CRC_TABLE - -local z_crc_t FAR crc_table[256]; -local z_crc_t FAR x2n_table[32]; -local void make_crc_table OF((void)); -#ifdef W - local z_word_t FAR crc_big_table[256]; - local z_crc_t FAR crc_braid_table[W][256]; - local z_word_t FAR crc_braid_big_table[W][256]; - local void braid OF((z_crc_t [][256], z_word_t [][256], int, int)); -#endif -#ifdef MAKECRCH - local void write_table OF((FILE *, const z_crc_t FAR *, int)); - local void write_table32hi OF((FILE *, const z_word_t FAR *, int)); - local void write_table64 OF((FILE *, const z_word_t FAR *, int)); -#endif /* MAKECRCH */ - -/* - Define a once() function depending on the availability of atomics. If this is - compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in - multiple threads, and if atomics are not available, then get_crc_table() must - be called to initialize the tables and must return before any threads are - allowed to compute or combine CRCs. - */ - -/* Definition of once functionality. */ -typedef struct once_s once_t; -local void once OF((once_t *, void (*)(void))); - -/* Check for the availability of atomics. */ -#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ - !defined(__STDC_NO_ATOMICS__) - -#include <stdatomic.h> - -/* Structure for once(), which must be initialized with ONCE_INIT. */ -struct once_s { - atomic_flag begun; - atomic_int done; -}; -#define ONCE_INIT {ATOMIC_FLAG_INIT, 0} - -/* - Run the provided init() function exactly once, even if multiple threads - invoke once() at the same time. The state must be a once_t initialized with - ONCE_INIT. - */ -local void once(state, init) - once_t *state; - void (*init)(void); -{ - if (!atomic_load(&state->done)) { - if (atomic_flag_test_and_set(&state->begun)) - while (!atomic_load(&state->done)) - ; - else { - init(); - atomic_store(&state->done, 1); - } - } -} - -#else /* no atomics */ - -/* Structure for once(), which must be initialized with ONCE_INIT. */ -struct once_s { - volatile int begun; - volatile int done; -}; -#define ONCE_INIT {0, 0} - -/* Test and set. Alas, not atomic, but tries to minimize the period of - vulnerability. */ -local int test_and_set OF((int volatile *)); -local int test_and_set( - int volatile *flag) -{ - int was; - - was = *flag; - *flag = 1; - return was; -} - -/* Run the provided init() function once. This is not thread-safe. */ -local void once(state, init) - once_t *state; - void (*init)(void); -{ - if (!state->done) { - if (test_and_set(&state->begun)) - while (!state->done) - ; - else { - init(); - state->done = 1; - } - } -} - -#endif - -/* State for once(). */ -local once_t made = ONCE_INIT; - -/* - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x - (which is shifting right by one and adding x^32 mod p if the bit shifted out - is a one). We start with the highest power (least significant bit) of q and - repeat for all eight bits of q. - - The table is simply the CRC of all possible eight bit values. This is all the - information needed to generate CRCs on data a byte at a time for all - combinations of CRC register values and incoming bytes. - */ - -local void make_crc_table() -{ - unsigned i, j, n; - z_crc_t p; - - /* initialize the CRC of bytes tables */ - for (i = 0; i < 256; i++) { - p = i; - for (j = 0; j < 8; j++) - p = p & 1 ? (p >> 1) ^ POLY : p >> 1; - crc_table[i] = p; -#ifdef W - crc_big_table[i] = byte_swap(p); -#endif - } - - /* initialize the x^2^n mod p(x) table */ - p = (z_crc_t)1 << 30; /* x^1 */ - x2n_table[0] = p; - for (n = 1; n < 32; n++) - x2n_table[n] = p = multmodp(p, p); - -#ifdef W - /* initialize the braiding tables -- needs x2n_table[] */ - braid(crc_braid_table, crc_braid_big_table, N, W); -#endif - -#ifdef MAKECRCH - { - /* - The crc32.h header file contains tables for both 32-bit and 64-bit - z_word_t's, and so requires a 64-bit type be available. In that case, - z_word_t must be defined to be 64-bits. This code then also generates - and writes out the tables for the case that z_word_t is 32 bits. - */ -#if !defined(W) || W != 8 -# error Need a 64-bit integer type in order to generate crc32.h. -#endif - FILE *out; - int k, n; - z_crc_t ltl[8][256]; - z_word_t big[8][256]; - - out = fopen("crc32.h", "w"); - if (out == NULL) return; - - /* write out little-endian CRC table to crc32.h */ - fprintf(out, - "/* crc32.h -- tables for rapid CRC calculation\n" - " * Generated automatically by crc32.c\n */\n" - "\n" - "local const z_crc_t FAR crc_table[] = {\n" - " "); - write_table(out, crc_table, 256); - fprintf(out, - "};\n"); - - /* write out big-endian CRC table for 64-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#ifdef W\n" - "\n" - "#if W == 8\n" - "\n" - "local const z_word_t FAR crc_big_table[] = {\n" - " "); - write_table64(out, crc_big_table, 256); - fprintf(out, - "};\n"); - - /* write out big-endian CRC table for 32-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#else /* W == 4 */\n" - "\n" - "local const z_word_t FAR crc_big_table[] = {\n" - " "); - write_table32hi(out, crc_big_table, 256); - fprintf(out, - "};\n" - "\n" - "#endif\n"); - - /* write out braid tables for each value of N */ - for (n = 1; n <= 6; n++) { - fprintf(out, - "\n" - "#if N == %d\n", n); - - /* compute braid tables for this N and 64-bit word_t */ - braid(ltl, big, n, 8); - - /* write out braid tables for 64-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#if W == 8\n" - "\n" - "local const z_crc_t FAR crc_braid_table[][256] = {\n"); - for (k = 0; k < 8; k++) { - fprintf(out, " {"); - write_table(out, ltl[k], 256); - fprintf(out, "}%s", k < 7 ? ",\n" : ""); - } - fprintf(out, - "};\n" - "\n" - "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); - for (k = 0; k < 8; k++) { - fprintf(out, " {"); - write_table64(out, big[k], 256); - fprintf(out, "}%s", k < 7 ? ",\n" : ""); - } - fprintf(out, - "};\n"); - - /* compute braid tables for this N and 32-bit word_t */ - braid(ltl, big, n, 4); - - /* write out braid tables for 32-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#else /* W == 4 */\n" - "\n" - "local const z_crc_t FAR crc_braid_table[][256] = {\n"); - for (k = 0; k < 4; k++) { - fprintf(out, " {"); - write_table(out, ltl[k], 256); - fprintf(out, "}%s", k < 3 ? ",\n" : ""); - } - fprintf(out, - "};\n" - "\n" - "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); - for (k = 0; k < 4; k++) { - fprintf(out, " {"); - write_table32hi(out, big[k], 256); - fprintf(out, "}%s", k < 3 ? ",\n" : ""); - } - fprintf(out, - "};\n" - "\n" - "#endif\n" - "\n" - "#endif\n"); - } - fprintf(out, - "\n" - "#endif\n"); - - /* write out zeros operator table to crc32.h */ - fprintf(out, - "\n" - "local const z_crc_t FAR x2n_table[] = {\n" - " "); - write_table(out, x2n_table, 32); - fprintf(out, - "};\n"); - fclose(out); - } -#endif /* MAKECRCH */ -} - -#ifdef MAKECRCH - -/* - Write the 32-bit values in table[0..k-1] to out, five per line in - hexadecimal separated by commas. - */ -local void write_table( - FILE *out, - const z_crc_t FAR *table, - int k) -{ - int n; - - for (n = 0; n < k; n++) - fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", - (unsigned long)(table[n]), - n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); -} - -/* - Write the high 32-bits of each value in table[0..k-1] to out, five per line - in hexadecimal separated by commas. - */ -local void write_table32hi( - FILE *out, - const z_word_t FAR *table, - int k) -{ - int n; - - for (n = 0; n < k; n++) - fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", - (unsigned long)(table[n] >> 32), - n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); -} - -/* - Write the 64-bit values in table[0..k-1] to out, three per line in - hexadecimal separated by commas. This assumes that if there is a 64-bit - type, then there is also a long long integer type, and it is at least 64 - bits. If not, then the type cast and format string can be adjusted - accordingly. - */ -local void write_table64( - FILE *out, - const z_word_t FAR *table, - int k) -{ - int n; - - for (n = 0; n < k; n++) - fprintf(out, "%s0x%016llx%s", n == 0 || n % 3 ? "" : " ", - (unsigned long long)(table[n]), - n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", ")); -} - -/* Actually do the deed. */ -int main() -{ - make_crc_table(); - return 0; -} - -#endif /* MAKECRCH */ - -#ifdef W -/* - Generate the little and big-endian braid tables for the given n and z_word_t - size w. Each array must have room for w blocks of 256 elements. - */ -local void braid(ltl, big, n, w) - z_crc_t ltl[][256]; - z_word_t big[][256]; - int n; - int w; -{ - int k; - z_crc_t i, p, q; - for (k = 0; k < w; k++) { - p = x2nmodp((n * w + 3 - k) << 3, 0); - ltl[k][0] = 0; - big[w - 1 - k][0] = 0; - for (i = 1; i < 256; i++) { - ltl[k][i] = q = multmodp(i << 24, p); - big[w - 1 - k][i] = byte_swap(q); - } - } -} -#endif - -#else /* !DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Tables for byte-wise and braided CRC-32 calculations, and a table of powers - * of x for combining CRC-32s, all made by make_crc_table(). - */ -#include "crc32.h" -#endif /* DYNAMIC_CRC_TABLE */ - -/* ======================================================================== - * Routines used for CRC calculation. Some are also required for the table - * generation above. - */ - -/* - Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, - reflected. For speed, this requires that a not be zero. - */ -local z_crc_t multmodp( - z_crc_t a, - z_crc_t b) -{ - z_crc_t m, p; - - m = (z_crc_t)1 << 31; - p = 0; - for (;;) { - if (a & m) { - p ^= b; - if ((a & (m - 1)) == 0) - break; - } - m >>= 1; - b = b & 1 ? (b >> 1) ^ POLY : b >> 1; - } - return p; -} - -/* - Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been - initialized. - */ -local z_crc_t x2nmodp( - z_off64_t n, - unsigned k) -{ - z_crc_t p; - - p = (z_crc_t)1 << 31; /* x^0 == 1 */ - while (n) { - if (n & 1) - p = multmodp(x2n_table[k & 31], p); - n >>= 1; - k++; - } - return p; -} - -/* ========================================================================= - * This function can be used by asm versions of crc32(), and to force the - * generation of the CRC tables in a threaded application. - */ -const z_crc_t FAR * ZEXPORT get_crc_table() -{ -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - return (const z_crc_t FAR *)crc_table; -} - -/* ========================================================================= - * Use ARM machine instructions if available. This will compute the CRC about - * ten times faster than the braided calculation. This code does not check for - * the presence of the CRC instruction at run time. __ARM_FEATURE_CRC32 will - * only be defined if the compilation specifies an ARM processor architecture - * that has the instructions. For example, compiling with -march=armv8.1-a or - * -march=armv8-a+crc, or -march=native if the compile machine has the crc32 - * instructions. - */ -#ifdef ARMCRC32 - -/* - Constants empirically determined to maximize speed. These values are from - measurements on a Cortex-A57. Your mileage may vary. - */ -#define Z_BATCH 3990 /* number of words in a batch */ -#define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */ -#define Z_BATCH_MIN 800 /* fewest words in a final batch */ - -unsigned long ZEXPORT crc32_z( - unsigned long crc, - const unsigned char FAR *buf, - z_size_t len) -{ - z_crc_t val; - z_word_t crc1, crc2; - const z_word_t *word; - z_word_t val0, val1, val2; - z_size_t last, last2, i; - z_size_t num; - - /* Return initial CRC, if requested. */ - if (buf == Z_NULL) return 0; - -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - - /* Pre-condition the CRC */ - crc ^= 0xffffffff; - - /* Compute the CRC up to a word boundary. */ - while (len && ((z_size_t)buf & 7) != 0) { - len--; - val = *buf++; - __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); - } - - /* Prepare to compute the CRC on full 64-bit words word[0..num-1]. */ - word = (z_word_t const *)buf; - num = len >> 3; - len &= 7; - - /* Do three interleaved CRCs to realize the throughput of one crc32x - instruction per cycle. Each CRC is calcuated on Z_BATCH words. The three - CRCs are combined into a single CRC after each set of batches. */ - while (num >= 3 * Z_BATCH) { - crc1 = 0; - crc2 = 0; - for (i = 0; i < Z_BATCH; i++) { - val0 = word[i]; - val1 = word[i + Z_BATCH]; - val2 = word[i + 2 * Z_BATCH]; - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); - } - word += 3 * Z_BATCH; - num -= 3 * Z_BATCH; - crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc1; - crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc2; - } - - /* Do one last smaller batch with the remaining words, if there are enough - to pay for the combination of CRCs. */ - last = num / 3; - if (last >= Z_BATCH_MIN) { - last2 = last << 1; - crc1 = 0; - crc2 = 0; - for (i = 0; i < last; i++) { - val0 = word[i]; - val1 = word[i + last]; - val2 = word[i + last2]; - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); - } - word += 3 * last; - num -= 3 * last; - val = x2nmodp(last, 6); - crc = multmodp(val, crc) ^ crc1; - crc = multmodp(val, crc) ^ crc2; - } - - /* Compute the CRC on any remaining words. */ - for (i = 0; i < num; i++) { - val0 = word[i]; - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); - } - word += num; - - /* Complete the CRC on any remaining bytes. */ - buf = (const unsigned char FAR *)word; - while (len) { - len--; - val = *buf++; - __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); - } - - /* Return the CRC, post-conditioned. */ - return crc ^ 0xffffffff; -} - -#else - -#ifdef W - -/* - Return the CRC of the W bytes in the word_t data, taking the - least-significant byte of the word as the first byte of data, without any pre - or post conditioning. This is used to combine the CRCs of each braid. - */ -local z_crc_t crc_word( - z_word_t data) -{ - int k; - for (k = 0; k < W; k++) - data = (data >> 8) ^ crc_table[data & 0xff]; - return (z_crc_t)data; -} - -local z_word_t crc_word_big( - z_word_t data) -{ - int k; - for (k = 0; k < W; k++) - data = (data << 8) ^ - crc_big_table[(data >> ((W - 1) << 3)) & 0xff]; - return data; -} - -#endif - -/* ========================================================================= */ -unsigned long ZEXPORT crc32_z( - unsigned long crc, - const unsigned char FAR *buf, - z_size_t len) -{ - /* Return initial CRC, if requested. */ - if (buf == Z_NULL) return 0; - -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - - /* Pre-condition the CRC */ - crc ^= 0xffffffff; - -#ifdef W - - /* If provided enough bytes, do a braided CRC calculation. */ - if (len >= N * W + W - 1) { - z_size_t blks; - z_word_t const *words; - unsigned endian; - int k; - - /* Compute the CRC up to a z_word_t boundary. */ - while (len && ((z_size_t)buf & (W - 1)) != 0) { - len--; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - } - - /* Compute the CRC on as many N z_word_t blocks as are available. */ - blks = len / (N * W); - len -= blks * N * W; - words = (z_word_t const *)buf; - - /* Do endian check at execution time instead of compile time, since ARM - processors can change the endianess at execution time. If the - compiler knows what the endianess will be, it can optimize out the - check and the unused branch. */ - endian = 1; - if (*(unsigned char *)&endian) { - /* Little endian. */ - - z_crc_t crc0; - z_word_t word0; -#if N > 1 - z_crc_t crc1; - z_word_t word1; -#if N > 2 - z_crc_t crc2; - z_word_t word2; -#if N > 3 - z_crc_t crc3; - z_word_t word3; -#if N > 4 - z_crc_t crc4; - z_word_t word4; -#if N > 5 - z_crc_t crc5; - z_word_t word5; -#endif -#endif -#endif -#endif -#endif - - /* Initialize the CRC for each braid. */ - crc0 = crc; -#if N > 1 - crc1 = 0; -#if N > 2 - crc2 = 0; -#if N > 3 - crc3 = 0; -#if N > 4 - crc4 = 0; -#if N > 5 - crc5 = 0; -#endif -#endif -#endif -#endif -#endif - - /* - Process the first blks-1 blocks, computing the CRCs on each braid - independently. - */ - while (--blks) { - /* Load the word for each braid into registers. */ - word0 = crc0 ^ words[0]; -#if N > 1 - word1 = crc1 ^ words[1]; -#if N > 2 - word2 = crc2 ^ words[2]; -#if N > 3 - word3 = crc3 ^ words[3]; -#if N > 4 - word4 = crc4 ^ words[4]; -#if N > 5 - word5 = crc5 ^ words[5]; -#endif -#endif -#endif -#endif -#endif - words += N; - - /* Compute and update the CRC for each word. The loop should - get unrolled. */ - crc0 = crc_braid_table[0][word0 & 0xff]; -#if N > 1 - crc1 = crc_braid_table[0][word1 & 0xff]; -#if N > 2 - crc2 = crc_braid_table[0][word2 & 0xff]; -#if N > 3 - crc3 = crc_braid_table[0][word3 & 0xff]; -#if N > 4 - crc4 = crc_braid_table[0][word4 & 0xff]; -#if N > 5 - crc5 = crc_braid_table[0][word5 & 0xff]; -#endif -#endif -#endif -#endif -#endif - for (k = 1; k < W; k++) { - crc0 ^= crc_braid_table[k][(word0 >> (k << 3)) & 0xff]; -#if N > 1 - crc1 ^= crc_braid_table[k][(word1 >> (k << 3)) & 0xff]; -#if N > 2 - crc2 ^= crc_braid_table[k][(word2 >> (k << 3)) & 0xff]; -#if N > 3 - crc3 ^= crc_braid_table[k][(word3 >> (k << 3)) & 0xff]; -#if N > 4 - crc4 ^= crc_braid_table[k][(word4 >> (k << 3)) & 0xff]; -#if N > 5 - crc5 ^= crc_braid_table[k][(word5 >> (k << 3)) & 0xff]; -#endif -#endif -#endif -#endif -#endif - } - } - - /* - Process the last block, combining the CRCs of the N braids at the - same time. - */ - crc = crc_word(crc0 ^ words[0]); -#if N > 1 - crc = crc_word(crc1 ^ words[1] ^ crc); -#if N > 2 - crc = crc_word(crc2 ^ words[2] ^ crc); -#if N > 3 - crc = crc_word(crc3 ^ words[3] ^ crc); -#if N > 4 - crc = crc_word(crc4 ^ words[4] ^ crc); -#if N > 5 - crc = crc_word(crc5 ^ words[5] ^ crc); -#endif -#endif -#endif -#endif -#endif - words += N; - } - else { - /* Big endian. */ - - z_word_t crc0, word0, comb; -#if N > 1 - z_word_t crc1, word1; -#if N > 2 - z_word_t crc2, word2; -#if N > 3 - z_word_t crc3, word3; -#if N > 4 - z_word_t crc4, word4; -#if N > 5 - z_word_t crc5, word5; -#endif -#endif -#endif -#endif -#endif - - /* Initialize the CRC for each braid. */ - crc0 = byte_swap(crc); -#if N > 1 - crc1 = 0; -#if N > 2 - crc2 = 0; -#if N > 3 - crc3 = 0; -#if N > 4 - crc4 = 0; -#if N > 5 - crc5 = 0; -#endif -#endif -#endif -#endif -#endif - - /* - Process the first blks-1 blocks, computing the CRCs on each braid - independently. - */ - while (--blks) { - /* Load the word for each braid into registers. */ - word0 = crc0 ^ words[0]; -#if N > 1 - word1 = crc1 ^ words[1]; -#if N > 2 - word2 = crc2 ^ words[2]; -#if N > 3 - word3 = crc3 ^ words[3]; -#if N > 4 - word4 = crc4 ^ words[4]; -#if N > 5 - word5 = crc5 ^ words[5]; -#endif -#endif -#endif -#endif -#endif - words += N; - - /* Compute and update the CRC for each word. The loop should - get unrolled. */ - crc0 = crc_braid_big_table[0][word0 & 0xff]; -#if N > 1 - crc1 = crc_braid_big_table[0][word1 & 0xff]; -#if N > 2 - crc2 = crc_braid_big_table[0][word2 & 0xff]; -#if N > 3 - crc3 = crc_braid_big_table[0][word3 & 0xff]; -#if N > 4 - crc4 = crc_braid_big_table[0][word4 & 0xff]; -#if N > 5 - crc5 = crc_braid_big_table[0][word5 & 0xff]; -#endif -#endif -#endif -#endif -#endif - for (k = 1; k < W; k++) { - crc0 ^= crc_braid_big_table[k][(word0 >> (k << 3)) & 0xff]; -#if N > 1 - crc1 ^= crc_braid_big_table[k][(word1 >> (k << 3)) & 0xff]; -#if N > 2 - crc2 ^= crc_braid_big_table[k][(word2 >> (k << 3)) & 0xff]; -#if N > 3 - crc3 ^= crc_braid_big_table[k][(word3 >> (k << 3)) & 0xff]; -#if N > 4 - crc4 ^= crc_braid_big_table[k][(word4 >> (k << 3)) & 0xff]; -#if N > 5 - crc5 ^= crc_braid_big_table[k][(word5 >> (k << 3)) & 0xff]; -#endif -#endif -#endif -#endif -#endif - } - } - - /* - Process the last block, combining the CRCs of the N braids at the - same time. - */ - comb = crc_word_big(crc0 ^ words[0]); -#if N > 1 - comb = crc_word_big(crc1 ^ words[1] ^ comb); -#if N > 2 - comb = crc_word_big(crc2 ^ words[2] ^ comb); -#if N > 3 - comb = crc_word_big(crc3 ^ words[3] ^ comb); -#if N > 4 - comb = crc_word_big(crc4 ^ words[4] ^ comb); -#if N > 5 - comb = crc_word_big(crc5 ^ words[5] ^ comb); -#endif -#endif -#endif -#endif -#endif - words += N; - crc = byte_swap(comb); - } - - /* - Update the pointer to the remaining bytes to process. - */ - buf = (unsigned char const *)words; - } - -#endif /* W */ - - /* Complete the computation of the CRC on any remaining bytes. */ - while (len >= 8) { - len -= 8; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - } - while (len) { - len--; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - } - - /* Return the CRC, post-conditioned. */ - return crc ^ 0xffffffff; -} - -#endif - -/* ========================================================================= */ -unsigned long ZEXPORT crc32( - unsigned long crc, - const unsigned char FAR *buf, - uInt len) -{ - return crc32_z(crc, buf, len); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine64( - uLong crc1, - uLong crc2, - z_off64_t len2) -{ -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - return multmodp(x2nmodp(len2, 3), crc1) ^ crc2; -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine( - uLong crc1, - uLong crc2, - z_off_t len2) -{ - return crc32_combine64(crc1, crc2, len2); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine_gen64( - z_off64_t len2) -{ -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - return x2nmodp(len2, 3); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine_gen( - z_off_t len2) -{ - return crc32_combine_gen64(len2); -} - -/* ========================================================================= */ -uLong crc32_combine_op( - uLong crc1, - uLong crc2, - uLong op) -{ - return multmodp(op, crc1) ^ crc2; -} diff --git a/thirdparty/freetype/src/gzip/crc32.h b/thirdparty/freetype/src/gzip/crc32.h deleted file mode 100644 index 137df68d61..0000000000 --- a/thirdparty/freetype/src/gzip/crc32.h +++ /dev/null @@ -1,9446 +0,0 @@ -/* crc32.h -- tables for rapid CRC calculation - * Generated automatically by crc32.c - */ - -local const z_crc_t FAR crc_table[] = { - 0x00000000, 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, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 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}; - -#ifdef W - -#if W == 8 - -local const z_word_t FAR crc_big_table[] = { - 0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, - 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, - 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, - 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, - 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, - 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, - 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, - 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, - 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, - 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, - 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, - 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, - 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, - 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, - 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, - 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, - 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, - 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, - 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, - 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, - 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, - 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, - 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, - 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, - 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, - 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, - 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, - 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, - 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, - 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, - 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, - 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, - 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, - 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, - 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, - 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, - 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, - 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, - 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, - 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, - 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, - 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, - 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, - 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, - 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, - 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, - 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, - 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, - 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, - 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, - 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, - 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, - 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, - 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, - 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, - 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, - 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, - 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, - 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, - 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, - 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, - 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, - 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, - 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, - 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, - 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, - 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, - 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, - 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, - 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, - 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, - 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, - 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, - 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, - 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, - 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, - 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, - 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, - 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, - 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, - 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, - 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, - 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, - 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, - 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, - 0x8def022d00000000}; - -#else /* W == 4 */ - -local const z_word_t FAR crc_big_table[] = { - 0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, - 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, - 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, - 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, - 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, - 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, - 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, - 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, - 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, - 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, - 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, - 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, - 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, - 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, - 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, - 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, - 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, - 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, - 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, - 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, - 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, - 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, - 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, - 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, - 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, - 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, - 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, - 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, - 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, - 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, - 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, - 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, - 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, - 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, - 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, - 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, - 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, - 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, - 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, - 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, - 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, - 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, - 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, - 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, - 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, - 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, - 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, - 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, - 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, - 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, - 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, - 0x8def022d}; - -#endif - -#if N == 1 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, - 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, - 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, - 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, - 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, - 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, - 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, - 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, - 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, - 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, - 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, - 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, - 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, - 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, - 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, - 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, - 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, - 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, - 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, - 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, - 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, - 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, - 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, - 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, - 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, - 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, - 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, - 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, - 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, - 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, - 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, - 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, - 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, - 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, - 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, - 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, - 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, - 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, - 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, - 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, - 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, - 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, - 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, - 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, - 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, - 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, - 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, - 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, - 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, - 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, - 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, - 0x264b06e6}, - {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, - 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, - 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, - 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, - 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, - 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, - 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, - 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, - 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, - 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, - 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, - 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, - 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, - 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, - 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, - 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, - 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, - 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, - 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, - 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, - 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, - 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, - 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, - 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, - 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, - 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, - 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, - 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, - 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, - 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, - 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, - 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, - 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, - 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, - 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, - 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, - 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, - 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, - 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, - 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, - 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, - 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, - 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, - 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, - 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, - 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, - 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, - 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, - 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, - 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, - 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, - 0x92364a30}, - {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, - 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, - 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, - 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, - 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, - 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, - 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, - 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, - 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, - 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, - 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, - 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, - 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, - 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, - 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, - 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, - 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, - 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, - 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, - 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, - 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, - 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, - 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, - 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, - 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, - 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, - 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, - 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, - 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, - 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, - 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, - 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, - 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, - 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, - 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, - 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, - 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, - 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, - 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, - 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, - 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, - 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, - 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, - 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, - 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, - 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, - 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, - 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, - 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, - 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, - 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, - 0xe4c4abcc}, - {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, - 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, - 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, - 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, - 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, - 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, - 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, - 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, - 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, - 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, - 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, - 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, - 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, - 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, - 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, - 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, - 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, - 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, - 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, - 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, - 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, - 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, - 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, - 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, - 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, - 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, - 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, - 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, - 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, - 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, - 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, - 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, - 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, - 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, - 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, - 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, - 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, - 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, - 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, - 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, - 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, - 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, - 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, - 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, - 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, - 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, - 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, - 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, - 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, - 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, - 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, - 0xca64c78c}, - {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, - 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, - 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, - 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, - 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, - 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, - 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, - 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, - 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, - 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, - 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, - 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, - 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, - 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, - 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, - 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, - 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, - 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, - 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, - 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, - 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, - 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, - 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, - 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, - 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, - 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, - 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, - 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, - 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, - 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, - 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, - 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, - 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, - 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, - 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, - 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, - 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, - 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, - 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, - 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, - 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, - 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, - 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, - 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, - 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, - 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, - 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, - 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, - 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, - 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, - 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, - 0xde0506f1}, - {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, - 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, - 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, - 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, - 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, - 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, - 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, - 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, - 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, - 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, - 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, - 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, - 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, - 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, - 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, - 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, - 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, - 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, - 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, - 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, - 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, - 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, - 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, - 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, - 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, - 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, - 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, - 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, - 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, - 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, - 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, - 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, - 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, - 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, - 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, - 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, - 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, - 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, - 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, - 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, - 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, - 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, - 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, - 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, - 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, - 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, - 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, - 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, - 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, - 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, - 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, - 0xbe9834ed}, - {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, - 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, - 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, - 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, - 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, - 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, - 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, - 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, - 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, - 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, - 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, - 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, - 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, - 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, - 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, - 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, - 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, - 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, - 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, - 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, - 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, - 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, - 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, - 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, - 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, - 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, - 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, - 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, - 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, - 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, - 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, - 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, - 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, - 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, - 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, - 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, - 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, - 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, - 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, - 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, - 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, - 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, - 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, - 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, - 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, - 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, - 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, - 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, - 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, - 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, - 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, - 0x9324fd72}, - {0x00000000, 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, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 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}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, - 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, - 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, - 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, - 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, - 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, - 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, - 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, - 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, - 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, - 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, - 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, - 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, - 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, - 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, - 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, - 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, - 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, - 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, - 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, - 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, - 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, - 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, - 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, - 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, - 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, - 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, - 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, - 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, - 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, - 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, - 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, - 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, - 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, - 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, - 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, - 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, - 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, - 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, - 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, - 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, - 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, - 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, - 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, - 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, - 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, - 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, - 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, - 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, - 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, - 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, - 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, - 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, - 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, - 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, - 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, - 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, - 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, - 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, - 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, - 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, - 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, - 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, - 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, - 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, - 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, - 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, - 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, - 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, - 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, - 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, - 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, - 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, - 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, - 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, - 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, - 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, - 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, - 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, - 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, - 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, - 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, - 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, - 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, - 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, - 0x8def022d00000000}, - {0x0000000000000000, 0x41311b1900000000, 0x8262363200000000, - 0xc3532d2b00000000, 0x04c56c6400000000, 0x45f4777d00000000, - 0x86a75a5600000000, 0xc796414f00000000, 0x088ad9c800000000, - 0x49bbc2d100000000, 0x8ae8effa00000000, 0xcbd9f4e300000000, - 0x0c4fb5ac00000000, 0x4d7eaeb500000000, 0x8e2d839e00000000, - 0xcf1c988700000000, 0x5112c24a00000000, 0x1023d95300000000, - 0xd370f47800000000, 0x9241ef6100000000, 0x55d7ae2e00000000, - 0x14e6b53700000000, 0xd7b5981c00000000, 0x9684830500000000, - 0x59981b8200000000, 0x18a9009b00000000, 0xdbfa2db000000000, - 0x9acb36a900000000, 0x5d5d77e600000000, 0x1c6c6cff00000000, - 0xdf3f41d400000000, 0x9e0e5acd00000000, 0xa224849500000000, - 0xe3159f8c00000000, 0x2046b2a700000000, 0x6177a9be00000000, - 0xa6e1e8f100000000, 0xe7d0f3e800000000, 0x2483dec300000000, - 0x65b2c5da00000000, 0xaaae5d5d00000000, 0xeb9f464400000000, - 0x28cc6b6f00000000, 0x69fd707600000000, 0xae6b313900000000, - 0xef5a2a2000000000, 0x2c09070b00000000, 0x6d381c1200000000, - 0xf33646df00000000, 0xb2075dc600000000, 0x715470ed00000000, - 0x30656bf400000000, 0xf7f32abb00000000, 0xb6c231a200000000, - 0x75911c8900000000, 0x34a0079000000000, 0xfbbc9f1700000000, - 0xba8d840e00000000, 0x79dea92500000000, 0x38efb23c00000000, - 0xff79f37300000000, 0xbe48e86a00000000, 0x7d1bc54100000000, - 0x3c2ade5800000000, 0x054f79f000000000, 0x447e62e900000000, - 0x872d4fc200000000, 0xc61c54db00000000, 0x018a159400000000, - 0x40bb0e8d00000000, 0x83e823a600000000, 0xc2d938bf00000000, - 0x0dc5a03800000000, 0x4cf4bb2100000000, 0x8fa7960a00000000, - 0xce968d1300000000, 0x0900cc5c00000000, 0x4831d74500000000, - 0x8b62fa6e00000000, 0xca53e17700000000, 0x545dbbba00000000, - 0x156ca0a300000000, 0xd63f8d8800000000, 0x970e969100000000, - 0x5098d7de00000000, 0x11a9ccc700000000, 0xd2fae1ec00000000, - 0x93cbfaf500000000, 0x5cd7627200000000, 0x1de6796b00000000, - 0xdeb5544000000000, 0x9f844f5900000000, 0x58120e1600000000, - 0x1923150f00000000, 0xda70382400000000, 0x9b41233d00000000, - 0xa76bfd6500000000, 0xe65ae67c00000000, 0x2509cb5700000000, - 0x6438d04e00000000, 0xa3ae910100000000, 0xe29f8a1800000000, - 0x21cca73300000000, 0x60fdbc2a00000000, 0xafe124ad00000000, - 0xeed03fb400000000, 0x2d83129f00000000, 0x6cb2098600000000, - 0xab2448c900000000, 0xea1553d000000000, 0x29467efb00000000, - 0x687765e200000000, 0xf6793f2f00000000, 0xb748243600000000, - 0x741b091d00000000, 0x352a120400000000, 0xf2bc534b00000000, - 0xb38d485200000000, 0x70de657900000000, 0x31ef7e6000000000, - 0xfef3e6e700000000, 0xbfc2fdfe00000000, 0x7c91d0d500000000, - 0x3da0cbcc00000000, 0xfa368a8300000000, 0xbb07919a00000000, - 0x7854bcb100000000, 0x3965a7a800000000, 0x4b98833b00000000, - 0x0aa9982200000000, 0xc9fab50900000000, 0x88cbae1000000000, - 0x4f5def5f00000000, 0x0e6cf44600000000, 0xcd3fd96d00000000, - 0x8c0ec27400000000, 0x43125af300000000, 0x022341ea00000000, - 0xc1706cc100000000, 0x804177d800000000, 0x47d7369700000000, - 0x06e62d8e00000000, 0xc5b500a500000000, 0x84841bbc00000000, - 0x1a8a417100000000, 0x5bbb5a6800000000, 0x98e8774300000000, - 0xd9d96c5a00000000, 0x1e4f2d1500000000, 0x5f7e360c00000000, - 0x9c2d1b2700000000, 0xdd1c003e00000000, 0x120098b900000000, - 0x533183a000000000, 0x9062ae8b00000000, 0xd153b59200000000, - 0x16c5f4dd00000000, 0x57f4efc400000000, 0x94a7c2ef00000000, - 0xd596d9f600000000, 0xe9bc07ae00000000, 0xa88d1cb700000000, - 0x6bde319c00000000, 0x2aef2a8500000000, 0xed796bca00000000, - 0xac4870d300000000, 0x6f1b5df800000000, 0x2e2a46e100000000, - 0xe136de6600000000, 0xa007c57f00000000, 0x6354e85400000000, - 0x2265f34d00000000, 0xe5f3b20200000000, 0xa4c2a91b00000000, - 0x6791843000000000, 0x26a09f2900000000, 0xb8aec5e400000000, - 0xf99fdefd00000000, 0x3accf3d600000000, 0x7bfde8cf00000000, - 0xbc6ba98000000000, 0xfd5ab29900000000, 0x3e099fb200000000, - 0x7f3884ab00000000, 0xb0241c2c00000000, 0xf115073500000000, - 0x32462a1e00000000, 0x7377310700000000, 0xb4e1704800000000, - 0xf5d06b5100000000, 0x3683467a00000000, 0x77b25d6300000000, - 0x4ed7facb00000000, 0x0fe6e1d200000000, 0xccb5ccf900000000, - 0x8d84d7e000000000, 0x4a1296af00000000, 0x0b238db600000000, - 0xc870a09d00000000, 0x8941bb8400000000, 0x465d230300000000, - 0x076c381a00000000, 0xc43f153100000000, 0x850e0e2800000000, - 0x42984f6700000000, 0x03a9547e00000000, 0xc0fa795500000000, - 0x81cb624c00000000, 0x1fc5388100000000, 0x5ef4239800000000, - 0x9da70eb300000000, 0xdc9615aa00000000, 0x1b0054e500000000, - 0x5a314ffc00000000, 0x996262d700000000, 0xd85379ce00000000, - 0x174fe14900000000, 0x567efa5000000000, 0x952dd77b00000000, - 0xd41ccc6200000000, 0x138a8d2d00000000, 0x52bb963400000000, - 0x91e8bb1f00000000, 0xd0d9a00600000000, 0xecf37e5e00000000, - 0xadc2654700000000, 0x6e91486c00000000, 0x2fa0537500000000, - 0xe836123a00000000, 0xa907092300000000, 0x6a54240800000000, - 0x2b653f1100000000, 0xe479a79600000000, 0xa548bc8f00000000, - 0x661b91a400000000, 0x272a8abd00000000, 0xe0bccbf200000000, - 0xa18dd0eb00000000, 0x62defdc000000000, 0x23efe6d900000000, - 0xbde1bc1400000000, 0xfcd0a70d00000000, 0x3f838a2600000000, - 0x7eb2913f00000000, 0xb924d07000000000, 0xf815cb6900000000, - 0x3b46e64200000000, 0x7a77fd5b00000000, 0xb56b65dc00000000, - 0xf45a7ec500000000, 0x370953ee00000000, 0x763848f700000000, - 0xb1ae09b800000000, 0xf09f12a100000000, 0x33cc3f8a00000000, - 0x72fd249300000000}, - {0x0000000000000000, 0x376ac20100000000, 0x6ed4840300000000, - 0x59be460200000000, 0xdca8090700000000, 0xebc2cb0600000000, - 0xb27c8d0400000000, 0x85164f0500000000, 0xb851130e00000000, - 0x8f3bd10f00000000, 0xd685970d00000000, 0xe1ef550c00000000, - 0x64f91a0900000000, 0x5393d80800000000, 0x0a2d9e0a00000000, - 0x3d475c0b00000000, 0x70a3261c00000000, 0x47c9e41d00000000, - 0x1e77a21f00000000, 0x291d601e00000000, 0xac0b2f1b00000000, - 0x9b61ed1a00000000, 0xc2dfab1800000000, 0xf5b5691900000000, - 0xc8f2351200000000, 0xff98f71300000000, 0xa626b11100000000, - 0x914c731000000000, 0x145a3c1500000000, 0x2330fe1400000000, - 0x7a8eb81600000000, 0x4de47a1700000000, 0xe0464d3800000000, - 0xd72c8f3900000000, 0x8e92c93b00000000, 0xb9f80b3a00000000, - 0x3cee443f00000000, 0x0b84863e00000000, 0x523ac03c00000000, - 0x6550023d00000000, 0x58175e3600000000, 0x6f7d9c3700000000, - 0x36c3da3500000000, 0x01a9183400000000, 0x84bf573100000000, - 0xb3d5953000000000, 0xea6bd33200000000, 0xdd01113300000000, - 0x90e56b2400000000, 0xa78fa92500000000, 0xfe31ef2700000000, - 0xc95b2d2600000000, 0x4c4d622300000000, 0x7b27a02200000000, - 0x2299e62000000000, 0x15f3242100000000, 0x28b4782a00000000, - 0x1fdeba2b00000000, 0x4660fc2900000000, 0x710a3e2800000000, - 0xf41c712d00000000, 0xc376b32c00000000, 0x9ac8f52e00000000, - 0xada2372f00000000, 0xc08d9a7000000000, 0xf7e7587100000000, - 0xae591e7300000000, 0x9933dc7200000000, 0x1c25937700000000, - 0x2b4f517600000000, 0x72f1177400000000, 0x459bd57500000000, - 0x78dc897e00000000, 0x4fb64b7f00000000, 0x16080d7d00000000, - 0x2162cf7c00000000, 0xa474807900000000, 0x931e427800000000, - 0xcaa0047a00000000, 0xfdcac67b00000000, 0xb02ebc6c00000000, - 0x87447e6d00000000, 0xdefa386f00000000, 0xe990fa6e00000000, - 0x6c86b56b00000000, 0x5bec776a00000000, 0x0252316800000000, - 0x3538f36900000000, 0x087faf6200000000, 0x3f156d6300000000, - 0x66ab2b6100000000, 0x51c1e96000000000, 0xd4d7a66500000000, - 0xe3bd646400000000, 0xba03226600000000, 0x8d69e06700000000, - 0x20cbd74800000000, 0x17a1154900000000, 0x4e1f534b00000000, - 0x7975914a00000000, 0xfc63de4f00000000, 0xcb091c4e00000000, - 0x92b75a4c00000000, 0xa5dd984d00000000, 0x989ac44600000000, - 0xaff0064700000000, 0xf64e404500000000, 0xc124824400000000, - 0x4432cd4100000000, 0x73580f4000000000, 0x2ae6494200000000, - 0x1d8c8b4300000000, 0x5068f15400000000, 0x6702335500000000, - 0x3ebc755700000000, 0x09d6b75600000000, 0x8cc0f85300000000, - 0xbbaa3a5200000000, 0xe2147c5000000000, 0xd57ebe5100000000, - 0xe839e25a00000000, 0xdf53205b00000000, 0x86ed665900000000, - 0xb187a45800000000, 0x3491eb5d00000000, 0x03fb295c00000000, - 0x5a456f5e00000000, 0x6d2fad5f00000000, 0x801b35e100000000, - 0xb771f7e000000000, 0xeecfb1e200000000, 0xd9a573e300000000, - 0x5cb33ce600000000, 0x6bd9fee700000000, 0x3267b8e500000000, - 0x050d7ae400000000, 0x384a26ef00000000, 0x0f20e4ee00000000, - 0x569ea2ec00000000, 0x61f460ed00000000, 0xe4e22fe800000000, - 0xd388ede900000000, 0x8a36abeb00000000, 0xbd5c69ea00000000, - 0xf0b813fd00000000, 0xc7d2d1fc00000000, 0x9e6c97fe00000000, - 0xa90655ff00000000, 0x2c101afa00000000, 0x1b7ad8fb00000000, - 0x42c49ef900000000, 0x75ae5cf800000000, 0x48e900f300000000, - 0x7f83c2f200000000, 0x263d84f000000000, 0x115746f100000000, - 0x944109f400000000, 0xa32bcbf500000000, 0xfa958df700000000, - 0xcdff4ff600000000, 0x605d78d900000000, 0x5737bad800000000, - 0x0e89fcda00000000, 0x39e33edb00000000, 0xbcf571de00000000, - 0x8b9fb3df00000000, 0xd221f5dd00000000, 0xe54b37dc00000000, - 0xd80c6bd700000000, 0xef66a9d600000000, 0xb6d8efd400000000, - 0x81b22dd500000000, 0x04a462d000000000, 0x33cea0d100000000, - 0x6a70e6d300000000, 0x5d1a24d200000000, 0x10fe5ec500000000, - 0x27949cc400000000, 0x7e2adac600000000, 0x494018c700000000, - 0xcc5657c200000000, 0xfb3c95c300000000, 0xa282d3c100000000, - 0x95e811c000000000, 0xa8af4dcb00000000, 0x9fc58fca00000000, - 0xc67bc9c800000000, 0xf1110bc900000000, 0x740744cc00000000, - 0x436d86cd00000000, 0x1ad3c0cf00000000, 0x2db902ce00000000, - 0x4096af9100000000, 0x77fc6d9000000000, 0x2e422b9200000000, - 0x1928e99300000000, 0x9c3ea69600000000, 0xab54649700000000, - 0xf2ea229500000000, 0xc580e09400000000, 0xf8c7bc9f00000000, - 0xcfad7e9e00000000, 0x9613389c00000000, 0xa179fa9d00000000, - 0x246fb59800000000, 0x1305779900000000, 0x4abb319b00000000, - 0x7dd1f39a00000000, 0x3035898d00000000, 0x075f4b8c00000000, - 0x5ee10d8e00000000, 0x698bcf8f00000000, 0xec9d808a00000000, - 0xdbf7428b00000000, 0x8249048900000000, 0xb523c68800000000, - 0x88649a8300000000, 0xbf0e588200000000, 0xe6b01e8000000000, - 0xd1dadc8100000000, 0x54cc938400000000, 0x63a6518500000000, - 0x3a18178700000000, 0x0d72d58600000000, 0xa0d0e2a900000000, - 0x97ba20a800000000, 0xce0466aa00000000, 0xf96ea4ab00000000, - 0x7c78ebae00000000, 0x4b1229af00000000, 0x12ac6fad00000000, - 0x25c6adac00000000, 0x1881f1a700000000, 0x2feb33a600000000, - 0x765575a400000000, 0x413fb7a500000000, 0xc429f8a000000000, - 0xf3433aa100000000, 0xaafd7ca300000000, 0x9d97bea200000000, - 0xd073c4b500000000, 0xe71906b400000000, 0xbea740b600000000, - 0x89cd82b700000000, 0x0cdbcdb200000000, 0x3bb10fb300000000, - 0x620f49b100000000, 0x55658bb000000000, 0x6822d7bb00000000, - 0x5f4815ba00000000, 0x06f653b800000000, 0x319c91b900000000, - 0xb48adebc00000000, 0x83e01cbd00000000, 0xda5e5abf00000000, - 0xed3498be00000000}, - {0x0000000000000000, 0x6567bcb800000000, 0x8bc809aa00000000, - 0xeeafb51200000000, 0x5797628f00000000, 0x32f0de3700000000, - 0xdc5f6b2500000000, 0xb938d79d00000000, 0xef28b4c500000000, - 0x8a4f087d00000000, 0x64e0bd6f00000000, 0x018701d700000000, - 0xb8bfd64a00000000, 0xddd86af200000000, 0x3377dfe000000000, - 0x5610635800000000, 0x9f57195000000000, 0xfa30a5e800000000, - 0x149f10fa00000000, 0x71f8ac4200000000, 0xc8c07bdf00000000, - 0xada7c76700000000, 0x4308727500000000, 0x266fcecd00000000, - 0x707fad9500000000, 0x1518112d00000000, 0xfbb7a43f00000000, - 0x9ed0188700000000, 0x27e8cf1a00000000, 0x428f73a200000000, - 0xac20c6b000000000, 0xc9477a0800000000, 0x3eaf32a000000000, - 0x5bc88e1800000000, 0xb5673b0a00000000, 0xd00087b200000000, - 0x6938502f00000000, 0x0c5fec9700000000, 0xe2f0598500000000, - 0x8797e53d00000000, 0xd187866500000000, 0xb4e03add00000000, - 0x5a4f8fcf00000000, 0x3f28337700000000, 0x8610e4ea00000000, - 0xe377585200000000, 0x0dd8ed4000000000, 0x68bf51f800000000, - 0xa1f82bf000000000, 0xc49f974800000000, 0x2a30225a00000000, - 0x4f579ee200000000, 0xf66f497f00000000, 0x9308f5c700000000, - 0x7da740d500000000, 0x18c0fc6d00000000, 0x4ed09f3500000000, - 0x2bb7238d00000000, 0xc518969f00000000, 0xa07f2a2700000000, - 0x1947fdba00000000, 0x7c20410200000000, 0x928ff41000000000, - 0xf7e848a800000000, 0x3d58149b00000000, 0x583fa82300000000, - 0xb6901d3100000000, 0xd3f7a18900000000, 0x6acf761400000000, - 0x0fa8caac00000000, 0xe1077fbe00000000, 0x8460c30600000000, - 0xd270a05e00000000, 0xb7171ce600000000, 0x59b8a9f400000000, - 0x3cdf154c00000000, 0x85e7c2d100000000, 0xe0807e6900000000, - 0x0e2fcb7b00000000, 0x6b4877c300000000, 0xa20f0dcb00000000, - 0xc768b17300000000, 0x29c7046100000000, 0x4ca0b8d900000000, - 0xf5986f4400000000, 0x90ffd3fc00000000, 0x7e5066ee00000000, - 0x1b37da5600000000, 0x4d27b90e00000000, 0x284005b600000000, - 0xc6efb0a400000000, 0xa3880c1c00000000, 0x1ab0db8100000000, - 0x7fd7673900000000, 0x9178d22b00000000, 0xf41f6e9300000000, - 0x03f7263b00000000, 0x66909a8300000000, 0x883f2f9100000000, - 0xed58932900000000, 0x546044b400000000, 0x3107f80c00000000, - 0xdfa84d1e00000000, 0xbacff1a600000000, 0xecdf92fe00000000, - 0x89b82e4600000000, 0x67179b5400000000, 0x027027ec00000000, - 0xbb48f07100000000, 0xde2f4cc900000000, 0x3080f9db00000000, - 0x55e7456300000000, 0x9ca03f6b00000000, 0xf9c783d300000000, - 0x176836c100000000, 0x720f8a7900000000, 0xcb375de400000000, - 0xae50e15c00000000, 0x40ff544e00000000, 0x2598e8f600000000, - 0x73888bae00000000, 0x16ef371600000000, 0xf840820400000000, - 0x9d273ebc00000000, 0x241fe92100000000, 0x4178559900000000, - 0xafd7e08b00000000, 0xcab05c3300000000, 0x3bb659ed00000000, - 0x5ed1e55500000000, 0xb07e504700000000, 0xd519ecff00000000, - 0x6c213b6200000000, 0x094687da00000000, 0xe7e932c800000000, - 0x828e8e7000000000, 0xd49eed2800000000, 0xb1f9519000000000, - 0x5f56e48200000000, 0x3a31583a00000000, 0x83098fa700000000, - 0xe66e331f00000000, 0x08c1860d00000000, 0x6da63ab500000000, - 0xa4e140bd00000000, 0xc186fc0500000000, 0x2f29491700000000, - 0x4a4ef5af00000000, 0xf376223200000000, 0x96119e8a00000000, - 0x78be2b9800000000, 0x1dd9972000000000, 0x4bc9f47800000000, - 0x2eae48c000000000, 0xc001fdd200000000, 0xa566416a00000000, - 0x1c5e96f700000000, 0x79392a4f00000000, 0x97969f5d00000000, - 0xf2f123e500000000, 0x05196b4d00000000, 0x607ed7f500000000, - 0x8ed162e700000000, 0xebb6de5f00000000, 0x528e09c200000000, - 0x37e9b57a00000000, 0xd946006800000000, 0xbc21bcd000000000, - 0xea31df8800000000, 0x8f56633000000000, 0x61f9d62200000000, - 0x049e6a9a00000000, 0xbda6bd0700000000, 0xd8c101bf00000000, - 0x366eb4ad00000000, 0x5309081500000000, 0x9a4e721d00000000, - 0xff29cea500000000, 0x11867bb700000000, 0x74e1c70f00000000, - 0xcdd9109200000000, 0xa8beac2a00000000, 0x4611193800000000, - 0x2376a58000000000, 0x7566c6d800000000, 0x10017a6000000000, - 0xfeaecf7200000000, 0x9bc973ca00000000, 0x22f1a45700000000, - 0x479618ef00000000, 0xa939adfd00000000, 0xcc5e114500000000, - 0x06ee4d7600000000, 0x6389f1ce00000000, 0x8d2644dc00000000, - 0xe841f86400000000, 0x51792ff900000000, 0x341e934100000000, - 0xdab1265300000000, 0xbfd69aeb00000000, 0xe9c6f9b300000000, - 0x8ca1450b00000000, 0x620ef01900000000, 0x07694ca100000000, - 0xbe519b3c00000000, 0xdb36278400000000, 0x3599929600000000, - 0x50fe2e2e00000000, 0x99b9542600000000, 0xfcdee89e00000000, - 0x12715d8c00000000, 0x7716e13400000000, 0xce2e36a900000000, - 0xab498a1100000000, 0x45e63f0300000000, 0x208183bb00000000, - 0x7691e0e300000000, 0x13f65c5b00000000, 0xfd59e94900000000, - 0x983e55f100000000, 0x2106826c00000000, 0x44613ed400000000, - 0xaace8bc600000000, 0xcfa9377e00000000, 0x38417fd600000000, - 0x5d26c36e00000000, 0xb389767c00000000, 0xd6eecac400000000, - 0x6fd61d5900000000, 0x0ab1a1e100000000, 0xe41e14f300000000, - 0x8179a84b00000000, 0xd769cb1300000000, 0xb20e77ab00000000, - 0x5ca1c2b900000000, 0x39c67e0100000000, 0x80fea99c00000000, - 0xe599152400000000, 0x0b36a03600000000, 0x6e511c8e00000000, - 0xa716668600000000, 0xc271da3e00000000, 0x2cde6f2c00000000, - 0x49b9d39400000000, 0xf081040900000000, 0x95e6b8b100000000, - 0x7b490da300000000, 0x1e2eb11b00000000, 0x483ed24300000000, - 0x2d596efb00000000, 0xc3f6dbe900000000, 0xa691675100000000, - 0x1fa9b0cc00000000, 0x7ace0c7400000000, 0x9461b96600000000, - 0xf10605de00000000}, - {0x0000000000000000, 0xb029603d00000000, 0x6053c07a00000000, - 0xd07aa04700000000, 0xc0a680f500000000, 0x708fe0c800000000, - 0xa0f5408f00000000, 0x10dc20b200000000, 0xc14b703000000000, - 0x7162100d00000000, 0xa118b04a00000000, 0x1131d07700000000, - 0x01edf0c500000000, 0xb1c490f800000000, 0x61be30bf00000000, - 0xd197508200000000, 0x8297e06000000000, 0x32be805d00000000, - 0xe2c4201a00000000, 0x52ed402700000000, 0x4231609500000000, - 0xf21800a800000000, 0x2262a0ef00000000, 0x924bc0d200000000, - 0x43dc905000000000, 0xf3f5f06d00000000, 0x238f502a00000000, - 0x93a6301700000000, 0x837a10a500000000, 0x3353709800000000, - 0xe329d0df00000000, 0x5300b0e200000000, 0x042fc1c100000000, - 0xb406a1fc00000000, 0x647c01bb00000000, 0xd455618600000000, - 0xc489413400000000, 0x74a0210900000000, 0xa4da814e00000000, - 0x14f3e17300000000, 0xc564b1f100000000, 0x754dd1cc00000000, - 0xa537718b00000000, 0x151e11b600000000, 0x05c2310400000000, - 0xb5eb513900000000, 0x6591f17e00000000, 0xd5b8914300000000, - 0x86b821a100000000, 0x3691419c00000000, 0xe6ebe1db00000000, - 0x56c281e600000000, 0x461ea15400000000, 0xf637c16900000000, - 0x264d612e00000000, 0x9664011300000000, 0x47f3519100000000, - 0xf7da31ac00000000, 0x27a091eb00000000, 0x9789f1d600000000, - 0x8755d16400000000, 0x377cb15900000000, 0xe706111e00000000, - 0x572f712300000000, 0x4958f35800000000, 0xf971936500000000, - 0x290b332200000000, 0x9922531f00000000, 0x89fe73ad00000000, - 0x39d7139000000000, 0xe9adb3d700000000, 0x5984d3ea00000000, - 0x8813836800000000, 0x383ae35500000000, 0xe840431200000000, - 0x5869232f00000000, 0x48b5039d00000000, 0xf89c63a000000000, - 0x28e6c3e700000000, 0x98cfa3da00000000, 0xcbcf133800000000, - 0x7be6730500000000, 0xab9cd34200000000, 0x1bb5b37f00000000, - 0x0b6993cd00000000, 0xbb40f3f000000000, 0x6b3a53b700000000, - 0xdb13338a00000000, 0x0a84630800000000, 0xbaad033500000000, - 0x6ad7a37200000000, 0xdafec34f00000000, 0xca22e3fd00000000, - 0x7a0b83c000000000, 0xaa71238700000000, 0x1a5843ba00000000, - 0x4d77329900000000, 0xfd5e52a400000000, 0x2d24f2e300000000, - 0x9d0d92de00000000, 0x8dd1b26c00000000, 0x3df8d25100000000, - 0xed82721600000000, 0x5dab122b00000000, 0x8c3c42a900000000, - 0x3c15229400000000, 0xec6f82d300000000, 0x5c46e2ee00000000, - 0x4c9ac25c00000000, 0xfcb3a26100000000, 0x2cc9022600000000, - 0x9ce0621b00000000, 0xcfe0d2f900000000, 0x7fc9b2c400000000, - 0xafb3128300000000, 0x1f9a72be00000000, 0x0f46520c00000000, - 0xbf6f323100000000, 0x6f15927600000000, 0xdf3cf24b00000000, - 0x0eaba2c900000000, 0xbe82c2f400000000, 0x6ef862b300000000, - 0xded1028e00000000, 0xce0d223c00000000, 0x7e24420100000000, - 0xae5ee24600000000, 0x1e77827b00000000, 0x92b0e6b100000000, - 0x2299868c00000000, 0xf2e326cb00000000, 0x42ca46f600000000, - 0x5216664400000000, 0xe23f067900000000, 0x3245a63e00000000, - 0x826cc60300000000, 0x53fb968100000000, 0xe3d2f6bc00000000, - 0x33a856fb00000000, 0x838136c600000000, 0x935d167400000000, - 0x2374764900000000, 0xf30ed60e00000000, 0x4327b63300000000, - 0x102706d100000000, 0xa00e66ec00000000, 0x7074c6ab00000000, - 0xc05da69600000000, 0xd081862400000000, 0x60a8e61900000000, - 0xb0d2465e00000000, 0x00fb266300000000, 0xd16c76e100000000, - 0x614516dc00000000, 0xb13fb69b00000000, 0x0116d6a600000000, - 0x11caf61400000000, 0xa1e3962900000000, 0x7199366e00000000, - 0xc1b0565300000000, 0x969f277000000000, 0x26b6474d00000000, - 0xf6cce70a00000000, 0x46e5873700000000, 0x5639a78500000000, - 0xe610c7b800000000, 0x366a67ff00000000, 0x864307c200000000, - 0x57d4574000000000, 0xe7fd377d00000000, 0x3787973a00000000, - 0x87aef70700000000, 0x9772d7b500000000, 0x275bb78800000000, - 0xf72117cf00000000, 0x470877f200000000, 0x1408c71000000000, - 0xa421a72d00000000, 0x745b076a00000000, 0xc472675700000000, - 0xd4ae47e500000000, 0x648727d800000000, 0xb4fd879f00000000, - 0x04d4e7a200000000, 0xd543b72000000000, 0x656ad71d00000000, - 0xb510775a00000000, 0x0539176700000000, 0x15e537d500000000, - 0xa5cc57e800000000, 0x75b6f7af00000000, 0xc59f979200000000, - 0xdbe815e900000000, 0x6bc175d400000000, 0xbbbbd59300000000, - 0x0b92b5ae00000000, 0x1b4e951c00000000, 0xab67f52100000000, - 0x7b1d556600000000, 0xcb34355b00000000, 0x1aa365d900000000, - 0xaa8a05e400000000, 0x7af0a5a300000000, 0xcad9c59e00000000, - 0xda05e52c00000000, 0x6a2c851100000000, 0xba56255600000000, - 0x0a7f456b00000000, 0x597ff58900000000, 0xe95695b400000000, - 0x392c35f300000000, 0x890555ce00000000, 0x99d9757c00000000, - 0x29f0154100000000, 0xf98ab50600000000, 0x49a3d53b00000000, - 0x983485b900000000, 0x281de58400000000, 0xf86745c300000000, - 0x484e25fe00000000, 0x5892054c00000000, 0xe8bb657100000000, - 0x38c1c53600000000, 0x88e8a50b00000000, 0xdfc7d42800000000, - 0x6feeb41500000000, 0xbf94145200000000, 0x0fbd746f00000000, - 0x1f6154dd00000000, 0xaf4834e000000000, 0x7f3294a700000000, - 0xcf1bf49a00000000, 0x1e8ca41800000000, 0xaea5c42500000000, - 0x7edf646200000000, 0xcef6045f00000000, 0xde2a24ed00000000, - 0x6e0344d000000000, 0xbe79e49700000000, 0x0e5084aa00000000, - 0x5d50344800000000, 0xed79547500000000, 0x3d03f43200000000, - 0x8d2a940f00000000, 0x9df6b4bd00000000, 0x2ddfd48000000000, - 0xfda574c700000000, 0x4d8c14fa00000000, 0x9c1b447800000000, - 0x2c32244500000000, 0xfc48840200000000, 0x4c61e43f00000000, - 0x5cbdc48d00000000, 0xec94a4b000000000, 0x3cee04f700000000, - 0x8cc764ca00000000}, - {0x0000000000000000, 0xa5d35ccb00000000, 0x0ba1c84d00000000, - 0xae72948600000000, 0x1642919b00000000, 0xb391cd5000000000, - 0x1de359d600000000, 0xb830051d00000000, 0x6d8253ec00000000, - 0xc8510f2700000000, 0x66239ba100000000, 0xc3f0c76a00000000, - 0x7bc0c27700000000, 0xde139ebc00000000, 0x70610a3a00000000, - 0xd5b256f100000000, 0x9b02d60300000000, 0x3ed18ac800000000, - 0x90a31e4e00000000, 0x3570428500000000, 0x8d40479800000000, - 0x28931b5300000000, 0x86e18fd500000000, 0x2332d31e00000000, - 0xf68085ef00000000, 0x5353d92400000000, 0xfd214da200000000, - 0x58f2116900000000, 0xe0c2147400000000, 0x451148bf00000000, - 0xeb63dc3900000000, 0x4eb080f200000000, 0x3605ac0700000000, - 0x93d6f0cc00000000, 0x3da4644a00000000, 0x9877388100000000, - 0x20473d9c00000000, 0x8594615700000000, 0x2be6f5d100000000, - 0x8e35a91a00000000, 0x5b87ffeb00000000, 0xfe54a32000000000, - 0x502637a600000000, 0xf5f56b6d00000000, 0x4dc56e7000000000, - 0xe81632bb00000000, 0x4664a63d00000000, 0xe3b7faf600000000, - 0xad077a0400000000, 0x08d426cf00000000, 0xa6a6b24900000000, - 0x0375ee8200000000, 0xbb45eb9f00000000, 0x1e96b75400000000, - 0xb0e423d200000000, 0x15377f1900000000, 0xc08529e800000000, - 0x6556752300000000, 0xcb24e1a500000000, 0x6ef7bd6e00000000, - 0xd6c7b87300000000, 0x7314e4b800000000, 0xdd66703e00000000, - 0x78b52cf500000000, 0x6c0a580f00000000, 0xc9d904c400000000, - 0x67ab904200000000, 0xc278cc8900000000, 0x7a48c99400000000, - 0xdf9b955f00000000, 0x71e901d900000000, 0xd43a5d1200000000, - 0x01880be300000000, 0xa45b572800000000, 0x0a29c3ae00000000, - 0xaffa9f6500000000, 0x17ca9a7800000000, 0xb219c6b300000000, - 0x1c6b523500000000, 0xb9b80efe00000000, 0xf7088e0c00000000, - 0x52dbd2c700000000, 0xfca9464100000000, 0x597a1a8a00000000, - 0xe14a1f9700000000, 0x4499435c00000000, 0xeaebd7da00000000, - 0x4f388b1100000000, 0x9a8adde000000000, 0x3f59812b00000000, - 0x912b15ad00000000, 0x34f8496600000000, 0x8cc84c7b00000000, - 0x291b10b000000000, 0x8769843600000000, 0x22bad8fd00000000, - 0x5a0ff40800000000, 0xffdca8c300000000, 0x51ae3c4500000000, - 0xf47d608e00000000, 0x4c4d659300000000, 0xe99e395800000000, - 0x47ecadde00000000, 0xe23ff11500000000, 0x378da7e400000000, - 0x925efb2f00000000, 0x3c2c6fa900000000, 0x99ff336200000000, - 0x21cf367f00000000, 0x841c6ab400000000, 0x2a6efe3200000000, - 0x8fbda2f900000000, 0xc10d220b00000000, 0x64de7ec000000000, - 0xcaacea4600000000, 0x6f7fb68d00000000, 0xd74fb39000000000, - 0x729cef5b00000000, 0xdcee7bdd00000000, 0x793d271600000000, - 0xac8f71e700000000, 0x095c2d2c00000000, 0xa72eb9aa00000000, - 0x02fde56100000000, 0xbacde07c00000000, 0x1f1ebcb700000000, - 0xb16c283100000000, 0x14bf74fa00000000, 0xd814b01e00000000, - 0x7dc7ecd500000000, 0xd3b5785300000000, 0x7666249800000000, - 0xce56218500000000, 0x6b857d4e00000000, 0xc5f7e9c800000000, - 0x6024b50300000000, 0xb596e3f200000000, 0x1045bf3900000000, - 0xbe372bbf00000000, 0x1be4777400000000, 0xa3d4726900000000, - 0x06072ea200000000, 0xa875ba2400000000, 0x0da6e6ef00000000, - 0x4316661d00000000, 0xe6c53ad600000000, 0x48b7ae5000000000, - 0xed64f29b00000000, 0x5554f78600000000, 0xf087ab4d00000000, - 0x5ef53fcb00000000, 0xfb26630000000000, 0x2e9435f100000000, - 0x8b47693a00000000, 0x2535fdbc00000000, 0x80e6a17700000000, - 0x38d6a46a00000000, 0x9d05f8a100000000, 0x33776c2700000000, - 0x96a430ec00000000, 0xee111c1900000000, 0x4bc240d200000000, - 0xe5b0d45400000000, 0x4063889f00000000, 0xf8538d8200000000, - 0x5d80d14900000000, 0xf3f245cf00000000, 0x5621190400000000, - 0x83934ff500000000, 0x2640133e00000000, 0x883287b800000000, - 0x2de1db7300000000, 0x95d1de6e00000000, 0x300282a500000000, - 0x9e70162300000000, 0x3ba34ae800000000, 0x7513ca1a00000000, - 0xd0c096d100000000, 0x7eb2025700000000, 0xdb615e9c00000000, - 0x63515b8100000000, 0xc682074a00000000, 0x68f093cc00000000, - 0xcd23cf0700000000, 0x189199f600000000, 0xbd42c53d00000000, - 0x133051bb00000000, 0xb6e30d7000000000, 0x0ed3086d00000000, - 0xab0054a600000000, 0x0572c02000000000, 0xa0a19ceb00000000, - 0xb41ee81100000000, 0x11cdb4da00000000, 0xbfbf205c00000000, - 0x1a6c7c9700000000, 0xa25c798a00000000, 0x078f254100000000, - 0xa9fdb1c700000000, 0x0c2eed0c00000000, 0xd99cbbfd00000000, - 0x7c4fe73600000000, 0xd23d73b000000000, 0x77ee2f7b00000000, - 0xcfde2a6600000000, 0x6a0d76ad00000000, 0xc47fe22b00000000, - 0x61acbee000000000, 0x2f1c3e1200000000, 0x8acf62d900000000, - 0x24bdf65f00000000, 0x816eaa9400000000, 0x395eaf8900000000, - 0x9c8df34200000000, 0x32ff67c400000000, 0x972c3b0f00000000, - 0x429e6dfe00000000, 0xe74d313500000000, 0x493fa5b300000000, - 0xececf97800000000, 0x54dcfc6500000000, 0xf10fa0ae00000000, - 0x5f7d342800000000, 0xfaae68e300000000, 0x821b441600000000, - 0x27c818dd00000000, 0x89ba8c5b00000000, 0x2c69d09000000000, - 0x9459d58d00000000, 0x318a894600000000, 0x9ff81dc000000000, - 0x3a2b410b00000000, 0xef9917fa00000000, 0x4a4a4b3100000000, - 0xe438dfb700000000, 0x41eb837c00000000, 0xf9db866100000000, - 0x5c08daaa00000000, 0xf27a4e2c00000000, 0x57a912e700000000, - 0x1919921500000000, 0xbccacede00000000, 0x12b85a5800000000, - 0xb76b069300000000, 0x0f5b038e00000000, 0xaa885f4500000000, - 0x04facbc300000000, 0xa129970800000000, 0x749bc1f900000000, - 0xd1489d3200000000, 0x7f3a09b400000000, 0xdae9557f00000000, - 0x62d9506200000000, 0xc70a0ca900000000, 0x6978982f00000000, - 0xccabc4e400000000}, - {0x0000000000000000, 0xb40b77a600000000, 0x29119f9700000000, - 0x9d1ae83100000000, 0x13244ff400000000, 0xa72f385200000000, - 0x3a35d06300000000, 0x8e3ea7c500000000, 0x674eef3300000000, - 0xd345989500000000, 0x4e5f70a400000000, 0xfa54070200000000, - 0x746aa0c700000000, 0xc061d76100000000, 0x5d7b3f5000000000, - 0xe97048f600000000, 0xce9cde6700000000, 0x7a97a9c100000000, - 0xe78d41f000000000, 0x5386365600000000, 0xddb8919300000000, - 0x69b3e63500000000, 0xf4a90e0400000000, 0x40a279a200000000, - 0xa9d2315400000000, 0x1dd946f200000000, 0x80c3aec300000000, - 0x34c8d96500000000, 0xbaf67ea000000000, 0x0efd090600000000, - 0x93e7e13700000000, 0x27ec969100000000, 0x9c39bdcf00000000, - 0x2832ca6900000000, 0xb528225800000000, 0x012355fe00000000, - 0x8f1df23b00000000, 0x3b16859d00000000, 0xa60c6dac00000000, - 0x12071a0a00000000, 0xfb7752fc00000000, 0x4f7c255a00000000, - 0xd266cd6b00000000, 0x666dbacd00000000, 0xe8531d0800000000, - 0x5c586aae00000000, 0xc142829f00000000, 0x7549f53900000000, - 0x52a563a800000000, 0xe6ae140e00000000, 0x7bb4fc3f00000000, - 0xcfbf8b9900000000, 0x41812c5c00000000, 0xf58a5bfa00000000, - 0x6890b3cb00000000, 0xdc9bc46d00000000, 0x35eb8c9b00000000, - 0x81e0fb3d00000000, 0x1cfa130c00000000, 0xa8f164aa00000000, - 0x26cfc36f00000000, 0x92c4b4c900000000, 0x0fde5cf800000000, - 0xbbd52b5e00000000, 0x79750b4400000000, 0xcd7e7ce200000000, - 0x506494d300000000, 0xe46fe37500000000, 0x6a5144b000000000, - 0xde5a331600000000, 0x4340db2700000000, 0xf74bac8100000000, - 0x1e3be47700000000, 0xaa3093d100000000, 0x372a7be000000000, - 0x83210c4600000000, 0x0d1fab8300000000, 0xb914dc2500000000, - 0x240e341400000000, 0x900543b200000000, 0xb7e9d52300000000, - 0x03e2a28500000000, 0x9ef84ab400000000, 0x2af33d1200000000, - 0xa4cd9ad700000000, 0x10c6ed7100000000, 0x8ddc054000000000, - 0x39d772e600000000, 0xd0a73a1000000000, 0x64ac4db600000000, - 0xf9b6a58700000000, 0x4dbdd22100000000, 0xc38375e400000000, - 0x7788024200000000, 0xea92ea7300000000, 0x5e999dd500000000, - 0xe54cb68b00000000, 0x5147c12d00000000, 0xcc5d291c00000000, - 0x78565eba00000000, 0xf668f97f00000000, 0x42638ed900000000, - 0xdf7966e800000000, 0x6b72114e00000000, 0x820259b800000000, - 0x36092e1e00000000, 0xab13c62f00000000, 0x1f18b18900000000, - 0x9126164c00000000, 0x252d61ea00000000, 0xb83789db00000000, - 0x0c3cfe7d00000000, 0x2bd068ec00000000, 0x9fdb1f4a00000000, - 0x02c1f77b00000000, 0xb6ca80dd00000000, 0x38f4271800000000, - 0x8cff50be00000000, 0x11e5b88f00000000, 0xa5eecf2900000000, - 0x4c9e87df00000000, 0xf895f07900000000, 0x658f184800000000, - 0xd1846fee00000000, 0x5fbac82b00000000, 0xebb1bf8d00000000, - 0x76ab57bc00000000, 0xc2a0201a00000000, 0xf2ea168800000000, - 0x46e1612e00000000, 0xdbfb891f00000000, 0x6ff0feb900000000, - 0xe1ce597c00000000, 0x55c52eda00000000, 0xc8dfc6eb00000000, - 0x7cd4b14d00000000, 0x95a4f9bb00000000, 0x21af8e1d00000000, - 0xbcb5662c00000000, 0x08be118a00000000, 0x8680b64f00000000, - 0x328bc1e900000000, 0xaf9129d800000000, 0x1b9a5e7e00000000, - 0x3c76c8ef00000000, 0x887dbf4900000000, 0x1567577800000000, - 0xa16c20de00000000, 0x2f52871b00000000, 0x9b59f0bd00000000, - 0x0643188c00000000, 0xb2486f2a00000000, 0x5b3827dc00000000, - 0xef33507a00000000, 0x7229b84b00000000, 0xc622cfed00000000, - 0x481c682800000000, 0xfc171f8e00000000, 0x610df7bf00000000, - 0xd506801900000000, 0x6ed3ab4700000000, 0xdad8dce100000000, - 0x47c234d000000000, 0xf3c9437600000000, 0x7df7e4b300000000, - 0xc9fc931500000000, 0x54e67b2400000000, 0xe0ed0c8200000000, - 0x099d447400000000, 0xbd9633d200000000, 0x208cdbe300000000, - 0x9487ac4500000000, 0x1ab90b8000000000, 0xaeb27c2600000000, - 0x33a8941700000000, 0x87a3e3b100000000, 0xa04f752000000000, - 0x1444028600000000, 0x895eeab700000000, 0x3d559d1100000000, - 0xb36b3ad400000000, 0x07604d7200000000, 0x9a7aa54300000000, - 0x2e71d2e500000000, 0xc7019a1300000000, 0x730aedb500000000, - 0xee10058400000000, 0x5a1b722200000000, 0xd425d5e700000000, - 0x602ea24100000000, 0xfd344a7000000000, 0x493f3dd600000000, - 0x8b9f1dcc00000000, 0x3f946a6a00000000, 0xa28e825b00000000, - 0x1685f5fd00000000, 0x98bb523800000000, 0x2cb0259e00000000, - 0xb1aacdaf00000000, 0x05a1ba0900000000, 0xecd1f2ff00000000, - 0x58da855900000000, 0xc5c06d6800000000, 0x71cb1ace00000000, - 0xfff5bd0b00000000, 0x4bfecaad00000000, 0xd6e4229c00000000, - 0x62ef553a00000000, 0x4503c3ab00000000, 0xf108b40d00000000, - 0x6c125c3c00000000, 0xd8192b9a00000000, 0x56278c5f00000000, - 0xe22cfbf900000000, 0x7f3613c800000000, 0xcb3d646e00000000, - 0x224d2c9800000000, 0x96465b3e00000000, 0x0b5cb30f00000000, - 0xbf57c4a900000000, 0x3169636c00000000, 0x856214ca00000000, - 0x1878fcfb00000000, 0xac738b5d00000000, 0x17a6a00300000000, - 0xa3add7a500000000, 0x3eb73f9400000000, 0x8abc483200000000, - 0x0482eff700000000, 0xb089985100000000, 0x2d93706000000000, - 0x999807c600000000, 0x70e84f3000000000, 0xc4e3389600000000, - 0x59f9d0a700000000, 0xedf2a70100000000, 0x63cc00c400000000, - 0xd7c7776200000000, 0x4add9f5300000000, 0xfed6e8f500000000, - 0xd93a7e6400000000, 0x6d3109c200000000, 0xf02be1f300000000, - 0x4420965500000000, 0xca1e319000000000, 0x7e15463600000000, - 0xe30fae0700000000, 0x5704d9a100000000, 0xbe74915700000000, - 0x0a7fe6f100000000, 0x97650ec000000000, 0x236e796600000000, - 0xad50dea300000000, 0x195ba90500000000, 0x8441413400000000, - 0x304a369200000000}, - {0x0000000000000000, 0x9e00aacc00000000, 0x7d07254200000000, - 0xe3078f8e00000000, 0xfa0e4a8400000000, 0x640ee04800000000, - 0x87096fc600000000, 0x1909c50a00000000, 0xb51be5d300000000, - 0x2b1b4f1f00000000, 0xc81cc09100000000, 0x561c6a5d00000000, - 0x4f15af5700000000, 0xd115059b00000000, 0x32128a1500000000, - 0xac1220d900000000, 0x2b31bb7c00000000, 0xb53111b000000000, - 0x56369e3e00000000, 0xc83634f200000000, 0xd13ff1f800000000, - 0x4f3f5b3400000000, 0xac38d4ba00000000, 0x32387e7600000000, - 0x9e2a5eaf00000000, 0x002af46300000000, 0xe32d7bed00000000, - 0x7d2dd12100000000, 0x6424142b00000000, 0xfa24bee700000000, - 0x1923316900000000, 0x87239ba500000000, 0x566276f900000000, - 0xc862dc3500000000, 0x2b6553bb00000000, 0xb565f97700000000, - 0xac6c3c7d00000000, 0x326c96b100000000, 0xd16b193f00000000, - 0x4f6bb3f300000000, 0xe379932a00000000, 0x7d7939e600000000, - 0x9e7eb66800000000, 0x007e1ca400000000, 0x1977d9ae00000000, - 0x8777736200000000, 0x6470fcec00000000, 0xfa70562000000000, - 0x7d53cd8500000000, 0xe353674900000000, 0x0054e8c700000000, - 0x9e54420b00000000, 0x875d870100000000, 0x195d2dcd00000000, - 0xfa5aa24300000000, 0x645a088f00000000, 0xc848285600000000, - 0x5648829a00000000, 0xb54f0d1400000000, 0x2b4fa7d800000000, - 0x324662d200000000, 0xac46c81e00000000, 0x4f41479000000000, - 0xd141ed5c00000000, 0xedc29d2900000000, 0x73c237e500000000, - 0x90c5b86b00000000, 0x0ec512a700000000, 0x17ccd7ad00000000, - 0x89cc7d6100000000, 0x6acbf2ef00000000, 0xf4cb582300000000, - 0x58d978fa00000000, 0xc6d9d23600000000, 0x25de5db800000000, - 0xbbdef77400000000, 0xa2d7327e00000000, 0x3cd798b200000000, - 0xdfd0173c00000000, 0x41d0bdf000000000, 0xc6f3265500000000, - 0x58f38c9900000000, 0xbbf4031700000000, 0x25f4a9db00000000, - 0x3cfd6cd100000000, 0xa2fdc61d00000000, 0x41fa499300000000, - 0xdffae35f00000000, 0x73e8c38600000000, 0xede8694a00000000, - 0x0eefe6c400000000, 0x90ef4c0800000000, 0x89e6890200000000, - 0x17e623ce00000000, 0xf4e1ac4000000000, 0x6ae1068c00000000, - 0xbba0ebd000000000, 0x25a0411c00000000, 0xc6a7ce9200000000, - 0x58a7645e00000000, 0x41aea15400000000, 0xdfae0b9800000000, - 0x3ca9841600000000, 0xa2a92eda00000000, 0x0ebb0e0300000000, - 0x90bba4cf00000000, 0x73bc2b4100000000, 0xedbc818d00000000, - 0xf4b5448700000000, 0x6ab5ee4b00000000, 0x89b261c500000000, - 0x17b2cb0900000000, 0x909150ac00000000, 0x0e91fa6000000000, - 0xed9675ee00000000, 0x7396df2200000000, 0x6a9f1a2800000000, - 0xf49fb0e400000000, 0x17983f6a00000000, 0x899895a600000000, - 0x258ab57f00000000, 0xbb8a1fb300000000, 0x588d903d00000000, - 0xc68d3af100000000, 0xdf84fffb00000000, 0x4184553700000000, - 0xa283dab900000000, 0x3c83707500000000, 0xda853b5300000000, - 0x4485919f00000000, 0xa7821e1100000000, 0x3982b4dd00000000, - 0x208b71d700000000, 0xbe8bdb1b00000000, 0x5d8c549500000000, - 0xc38cfe5900000000, 0x6f9ede8000000000, 0xf19e744c00000000, - 0x1299fbc200000000, 0x8c99510e00000000, 0x9590940400000000, - 0x0b903ec800000000, 0xe897b14600000000, 0x76971b8a00000000, - 0xf1b4802f00000000, 0x6fb42ae300000000, 0x8cb3a56d00000000, - 0x12b30fa100000000, 0x0bbacaab00000000, 0x95ba606700000000, - 0x76bdefe900000000, 0xe8bd452500000000, 0x44af65fc00000000, - 0xdaafcf3000000000, 0x39a840be00000000, 0xa7a8ea7200000000, - 0xbea12f7800000000, 0x20a185b400000000, 0xc3a60a3a00000000, - 0x5da6a0f600000000, 0x8ce74daa00000000, 0x12e7e76600000000, - 0xf1e068e800000000, 0x6fe0c22400000000, 0x76e9072e00000000, - 0xe8e9ade200000000, 0x0bee226c00000000, 0x95ee88a000000000, - 0x39fca87900000000, 0xa7fc02b500000000, 0x44fb8d3b00000000, - 0xdafb27f700000000, 0xc3f2e2fd00000000, 0x5df2483100000000, - 0xbef5c7bf00000000, 0x20f56d7300000000, 0xa7d6f6d600000000, - 0x39d65c1a00000000, 0xdad1d39400000000, 0x44d1795800000000, - 0x5dd8bc5200000000, 0xc3d8169e00000000, 0x20df991000000000, - 0xbedf33dc00000000, 0x12cd130500000000, 0x8ccdb9c900000000, - 0x6fca364700000000, 0xf1ca9c8b00000000, 0xe8c3598100000000, - 0x76c3f34d00000000, 0x95c47cc300000000, 0x0bc4d60f00000000, - 0x3747a67a00000000, 0xa9470cb600000000, 0x4a40833800000000, - 0xd44029f400000000, 0xcd49ecfe00000000, 0x5349463200000000, - 0xb04ec9bc00000000, 0x2e4e637000000000, 0x825c43a900000000, - 0x1c5ce96500000000, 0xff5b66eb00000000, 0x615bcc2700000000, - 0x7852092d00000000, 0xe652a3e100000000, 0x05552c6f00000000, - 0x9b5586a300000000, 0x1c761d0600000000, 0x8276b7ca00000000, - 0x6171384400000000, 0xff71928800000000, 0xe678578200000000, - 0x7878fd4e00000000, 0x9b7f72c000000000, 0x057fd80c00000000, - 0xa96df8d500000000, 0x376d521900000000, 0xd46add9700000000, - 0x4a6a775b00000000, 0x5363b25100000000, 0xcd63189d00000000, - 0x2e64971300000000, 0xb0643ddf00000000, 0x6125d08300000000, - 0xff257a4f00000000, 0x1c22f5c100000000, 0x82225f0d00000000, - 0x9b2b9a0700000000, 0x052b30cb00000000, 0xe62cbf4500000000, - 0x782c158900000000, 0xd43e355000000000, 0x4a3e9f9c00000000, - 0xa939101200000000, 0x3739bade00000000, 0x2e307fd400000000, - 0xb030d51800000000, 0x53375a9600000000, 0xcd37f05a00000000, - 0x4a146bff00000000, 0xd414c13300000000, 0x37134ebd00000000, - 0xa913e47100000000, 0xb01a217b00000000, 0x2e1a8bb700000000, - 0xcd1d043900000000, 0x531daef500000000, 0xff0f8e2c00000000, - 0x610f24e000000000, 0x8208ab6e00000000, 0x1c0801a200000000, - 0x0501c4a800000000, 0x9b016e6400000000, 0x7806e1ea00000000, - 0xe6064b2600000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, - 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, - 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, - 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, - 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, - 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, - 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, - 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, - 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, - 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, - 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, - 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, - 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, - 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, - 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, - 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, - 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, - 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, - 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, - 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, - 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, - 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, - 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, - 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, - 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, - 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, - 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, - 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, - 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, - 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, - 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, - 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, - 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, - 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, - 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, - 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, - 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, - 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, - 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, - 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, - 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, - 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, - 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, - 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, - 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, - 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, - 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, - 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, - 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, - 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, - 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, - 0xde0506f1}, - {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, - 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, - 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, - 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, - 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, - 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, - 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, - 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, - 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, - 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, - 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, - 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, - 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, - 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, - 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, - 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, - 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, - 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, - 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, - 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, - 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, - 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, - 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, - 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, - 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, - 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, - 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, - 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, - 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, - 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, - 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, - 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, - 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, - 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, - 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, - 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, - 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, - 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, - 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, - 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, - 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, - 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, - 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, - 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, - 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, - 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, - 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, - 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, - 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, - 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, - 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, - 0xbe9834ed}, - {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, - 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, - 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, - 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, - 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, - 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, - 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, - 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, - 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, - 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, - 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, - 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, - 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, - 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, - 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, - 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, - 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, - 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, - 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, - 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, - 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, - 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, - 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, - 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, - 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, - 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, - 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, - 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, - 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, - 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, - 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, - 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, - 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, - 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, - 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, - 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, - 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, - 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, - 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, - 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, - 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, - 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, - 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, - 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, - 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, - 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, - 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, - 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, - 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, - 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, - 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, - 0x9324fd72}, - {0x00000000, 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, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 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}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, - 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, - 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, - 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, - 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, - 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, - 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, - 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, - 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, - 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, - 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, - 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, - 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, - 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, - 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, - 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, - 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, - 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, - 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, - 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, - 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, - 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, - 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, - 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, - 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, - 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, - 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, - 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, - 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, - 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, - 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, - 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, - 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, - 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, - 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, - 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, - 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, - 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, - 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, - 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, - 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, - 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, - 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, - 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, - 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, - 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, - 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, - 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, - 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, - 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, - 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, - 0x8def022d}, - {0x00000000, 0x41311b19, 0x82623632, 0xc3532d2b, 0x04c56c64, - 0x45f4777d, 0x86a75a56, 0xc796414f, 0x088ad9c8, 0x49bbc2d1, - 0x8ae8effa, 0xcbd9f4e3, 0x0c4fb5ac, 0x4d7eaeb5, 0x8e2d839e, - 0xcf1c9887, 0x5112c24a, 0x1023d953, 0xd370f478, 0x9241ef61, - 0x55d7ae2e, 0x14e6b537, 0xd7b5981c, 0x96848305, 0x59981b82, - 0x18a9009b, 0xdbfa2db0, 0x9acb36a9, 0x5d5d77e6, 0x1c6c6cff, - 0xdf3f41d4, 0x9e0e5acd, 0xa2248495, 0xe3159f8c, 0x2046b2a7, - 0x6177a9be, 0xa6e1e8f1, 0xe7d0f3e8, 0x2483dec3, 0x65b2c5da, - 0xaaae5d5d, 0xeb9f4644, 0x28cc6b6f, 0x69fd7076, 0xae6b3139, - 0xef5a2a20, 0x2c09070b, 0x6d381c12, 0xf33646df, 0xb2075dc6, - 0x715470ed, 0x30656bf4, 0xf7f32abb, 0xb6c231a2, 0x75911c89, - 0x34a00790, 0xfbbc9f17, 0xba8d840e, 0x79dea925, 0x38efb23c, - 0xff79f373, 0xbe48e86a, 0x7d1bc541, 0x3c2ade58, 0x054f79f0, - 0x447e62e9, 0x872d4fc2, 0xc61c54db, 0x018a1594, 0x40bb0e8d, - 0x83e823a6, 0xc2d938bf, 0x0dc5a038, 0x4cf4bb21, 0x8fa7960a, - 0xce968d13, 0x0900cc5c, 0x4831d745, 0x8b62fa6e, 0xca53e177, - 0x545dbbba, 0x156ca0a3, 0xd63f8d88, 0x970e9691, 0x5098d7de, - 0x11a9ccc7, 0xd2fae1ec, 0x93cbfaf5, 0x5cd76272, 0x1de6796b, - 0xdeb55440, 0x9f844f59, 0x58120e16, 0x1923150f, 0xda703824, - 0x9b41233d, 0xa76bfd65, 0xe65ae67c, 0x2509cb57, 0x6438d04e, - 0xa3ae9101, 0xe29f8a18, 0x21cca733, 0x60fdbc2a, 0xafe124ad, - 0xeed03fb4, 0x2d83129f, 0x6cb20986, 0xab2448c9, 0xea1553d0, - 0x29467efb, 0x687765e2, 0xf6793f2f, 0xb7482436, 0x741b091d, - 0x352a1204, 0xf2bc534b, 0xb38d4852, 0x70de6579, 0x31ef7e60, - 0xfef3e6e7, 0xbfc2fdfe, 0x7c91d0d5, 0x3da0cbcc, 0xfa368a83, - 0xbb07919a, 0x7854bcb1, 0x3965a7a8, 0x4b98833b, 0x0aa99822, - 0xc9fab509, 0x88cbae10, 0x4f5def5f, 0x0e6cf446, 0xcd3fd96d, - 0x8c0ec274, 0x43125af3, 0x022341ea, 0xc1706cc1, 0x804177d8, - 0x47d73697, 0x06e62d8e, 0xc5b500a5, 0x84841bbc, 0x1a8a4171, - 0x5bbb5a68, 0x98e87743, 0xd9d96c5a, 0x1e4f2d15, 0x5f7e360c, - 0x9c2d1b27, 0xdd1c003e, 0x120098b9, 0x533183a0, 0x9062ae8b, - 0xd153b592, 0x16c5f4dd, 0x57f4efc4, 0x94a7c2ef, 0xd596d9f6, - 0xe9bc07ae, 0xa88d1cb7, 0x6bde319c, 0x2aef2a85, 0xed796bca, - 0xac4870d3, 0x6f1b5df8, 0x2e2a46e1, 0xe136de66, 0xa007c57f, - 0x6354e854, 0x2265f34d, 0xe5f3b202, 0xa4c2a91b, 0x67918430, - 0x26a09f29, 0xb8aec5e4, 0xf99fdefd, 0x3accf3d6, 0x7bfde8cf, - 0xbc6ba980, 0xfd5ab299, 0x3e099fb2, 0x7f3884ab, 0xb0241c2c, - 0xf1150735, 0x32462a1e, 0x73773107, 0xb4e17048, 0xf5d06b51, - 0x3683467a, 0x77b25d63, 0x4ed7facb, 0x0fe6e1d2, 0xccb5ccf9, - 0x8d84d7e0, 0x4a1296af, 0x0b238db6, 0xc870a09d, 0x8941bb84, - 0x465d2303, 0x076c381a, 0xc43f1531, 0x850e0e28, 0x42984f67, - 0x03a9547e, 0xc0fa7955, 0x81cb624c, 0x1fc53881, 0x5ef42398, - 0x9da70eb3, 0xdc9615aa, 0x1b0054e5, 0x5a314ffc, 0x996262d7, - 0xd85379ce, 0x174fe149, 0x567efa50, 0x952dd77b, 0xd41ccc62, - 0x138a8d2d, 0x52bb9634, 0x91e8bb1f, 0xd0d9a006, 0xecf37e5e, - 0xadc26547, 0x6e91486c, 0x2fa05375, 0xe836123a, 0xa9070923, - 0x6a542408, 0x2b653f11, 0xe479a796, 0xa548bc8f, 0x661b91a4, - 0x272a8abd, 0xe0bccbf2, 0xa18dd0eb, 0x62defdc0, 0x23efe6d9, - 0xbde1bc14, 0xfcd0a70d, 0x3f838a26, 0x7eb2913f, 0xb924d070, - 0xf815cb69, 0x3b46e642, 0x7a77fd5b, 0xb56b65dc, 0xf45a7ec5, - 0x370953ee, 0x763848f7, 0xb1ae09b8, 0xf09f12a1, 0x33cc3f8a, - 0x72fd2493}, - {0x00000000, 0x376ac201, 0x6ed48403, 0x59be4602, 0xdca80907, - 0xebc2cb06, 0xb27c8d04, 0x85164f05, 0xb851130e, 0x8f3bd10f, - 0xd685970d, 0xe1ef550c, 0x64f91a09, 0x5393d808, 0x0a2d9e0a, - 0x3d475c0b, 0x70a3261c, 0x47c9e41d, 0x1e77a21f, 0x291d601e, - 0xac0b2f1b, 0x9b61ed1a, 0xc2dfab18, 0xf5b56919, 0xc8f23512, - 0xff98f713, 0xa626b111, 0x914c7310, 0x145a3c15, 0x2330fe14, - 0x7a8eb816, 0x4de47a17, 0xe0464d38, 0xd72c8f39, 0x8e92c93b, - 0xb9f80b3a, 0x3cee443f, 0x0b84863e, 0x523ac03c, 0x6550023d, - 0x58175e36, 0x6f7d9c37, 0x36c3da35, 0x01a91834, 0x84bf5731, - 0xb3d59530, 0xea6bd332, 0xdd011133, 0x90e56b24, 0xa78fa925, - 0xfe31ef27, 0xc95b2d26, 0x4c4d6223, 0x7b27a022, 0x2299e620, - 0x15f32421, 0x28b4782a, 0x1fdeba2b, 0x4660fc29, 0x710a3e28, - 0xf41c712d, 0xc376b32c, 0x9ac8f52e, 0xada2372f, 0xc08d9a70, - 0xf7e75871, 0xae591e73, 0x9933dc72, 0x1c259377, 0x2b4f5176, - 0x72f11774, 0x459bd575, 0x78dc897e, 0x4fb64b7f, 0x16080d7d, - 0x2162cf7c, 0xa4748079, 0x931e4278, 0xcaa0047a, 0xfdcac67b, - 0xb02ebc6c, 0x87447e6d, 0xdefa386f, 0xe990fa6e, 0x6c86b56b, - 0x5bec776a, 0x02523168, 0x3538f369, 0x087faf62, 0x3f156d63, - 0x66ab2b61, 0x51c1e960, 0xd4d7a665, 0xe3bd6464, 0xba032266, - 0x8d69e067, 0x20cbd748, 0x17a11549, 0x4e1f534b, 0x7975914a, - 0xfc63de4f, 0xcb091c4e, 0x92b75a4c, 0xa5dd984d, 0x989ac446, - 0xaff00647, 0xf64e4045, 0xc1248244, 0x4432cd41, 0x73580f40, - 0x2ae64942, 0x1d8c8b43, 0x5068f154, 0x67023355, 0x3ebc7557, - 0x09d6b756, 0x8cc0f853, 0xbbaa3a52, 0xe2147c50, 0xd57ebe51, - 0xe839e25a, 0xdf53205b, 0x86ed6659, 0xb187a458, 0x3491eb5d, - 0x03fb295c, 0x5a456f5e, 0x6d2fad5f, 0x801b35e1, 0xb771f7e0, - 0xeecfb1e2, 0xd9a573e3, 0x5cb33ce6, 0x6bd9fee7, 0x3267b8e5, - 0x050d7ae4, 0x384a26ef, 0x0f20e4ee, 0x569ea2ec, 0x61f460ed, - 0xe4e22fe8, 0xd388ede9, 0x8a36abeb, 0xbd5c69ea, 0xf0b813fd, - 0xc7d2d1fc, 0x9e6c97fe, 0xa90655ff, 0x2c101afa, 0x1b7ad8fb, - 0x42c49ef9, 0x75ae5cf8, 0x48e900f3, 0x7f83c2f2, 0x263d84f0, - 0x115746f1, 0x944109f4, 0xa32bcbf5, 0xfa958df7, 0xcdff4ff6, - 0x605d78d9, 0x5737bad8, 0x0e89fcda, 0x39e33edb, 0xbcf571de, - 0x8b9fb3df, 0xd221f5dd, 0xe54b37dc, 0xd80c6bd7, 0xef66a9d6, - 0xb6d8efd4, 0x81b22dd5, 0x04a462d0, 0x33cea0d1, 0x6a70e6d3, - 0x5d1a24d2, 0x10fe5ec5, 0x27949cc4, 0x7e2adac6, 0x494018c7, - 0xcc5657c2, 0xfb3c95c3, 0xa282d3c1, 0x95e811c0, 0xa8af4dcb, - 0x9fc58fca, 0xc67bc9c8, 0xf1110bc9, 0x740744cc, 0x436d86cd, - 0x1ad3c0cf, 0x2db902ce, 0x4096af91, 0x77fc6d90, 0x2e422b92, - 0x1928e993, 0x9c3ea696, 0xab546497, 0xf2ea2295, 0xc580e094, - 0xf8c7bc9f, 0xcfad7e9e, 0x9613389c, 0xa179fa9d, 0x246fb598, - 0x13057799, 0x4abb319b, 0x7dd1f39a, 0x3035898d, 0x075f4b8c, - 0x5ee10d8e, 0x698bcf8f, 0xec9d808a, 0xdbf7428b, 0x82490489, - 0xb523c688, 0x88649a83, 0xbf0e5882, 0xe6b01e80, 0xd1dadc81, - 0x54cc9384, 0x63a65185, 0x3a181787, 0x0d72d586, 0xa0d0e2a9, - 0x97ba20a8, 0xce0466aa, 0xf96ea4ab, 0x7c78ebae, 0x4b1229af, - 0x12ac6fad, 0x25c6adac, 0x1881f1a7, 0x2feb33a6, 0x765575a4, - 0x413fb7a5, 0xc429f8a0, 0xf3433aa1, 0xaafd7ca3, 0x9d97bea2, - 0xd073c4b5, 0xe71906b4, 0xbea740b6, 0x89cd82b7, 0x0cdbcdb2, - 0x3bb10fb3, 0x620f49b1, 0x55658bb0, 0x6822d7bb, 0x5f4815ba, - 0x06f653b8, 0x319c91b9, 0xb48adebc, 0x83e01cbd, 0xda5e5abf, - 0xed3498be}, - {0x00000000, 0x6567bcb8, 0x8bc809aa, 0xeeafb512, 0x5797628f, - 0x32f0de37, 0xdc5f6b25, 0xb938d79d, 0xef28b4c5, 0x8a4f087d, - 0x64e0bd6f, 0x018701d7, 0xb8bfd64a, 0xddd86af2, 0x3377dfe0, - 0x56106358, 0x9f571950, 0xfa30a5e8, 0x149f10fa, 0x71f8ac42, - 0xc8c07bdf, 0xada7c767, 0x43087275, 0x266fcecd, 0x707fad95, - 0x1518112d, 0xfbb7a43f, 0x9ed01887, 0x27e8cf1a, 0x428f73a2, - 0xac20c6b0, 0xc9477a08, 0x3eaf32a0, 0x5bc88e18, 0xb5673b0a, - 0xd00087b2, 0x6938502f, 0x0c5fec97, 0xe2f05985, 0x8797e53d, - 0xd1878665, 0xb4e03add, 0x5a4f8fcf, 0x3f283377, 0x8610e4ea, - 0xe3775852, 0x0dd8ed40, 0x68bf51f8, 0xa1f82bf0, 0xc49f9748, - 0x2a30225a, 0x4f579ee2, 0xf66f497f, 0x9308f5c7, 0x7da740d5, - 0x18c0fc6d, 0x4ed09f35, 0x2bb7238d, 0xc518969f, 0xa07f2a27, - 0x1947fdba, 0x7c204102, 0x928ff410, 0xf7e848a8, 0x3d58149b, - 0x583fa823, 0xb6901d31, 0xd3f7a189, 0x6acf7614, 0x0fa8caac, - 0xe1077fbe, 0x8460c306, 0xd270a05e, 0xb7171ce6, 0x59b8a9f4, - 0x3cdf154c, 0x85e7c2d1, 0xe0807e69, 0x0e2fcb7b, 0x6b4877c3, - 0xa20f0dcb, 0xc768b173, 0x29c70461, 0x4ca0b8d9, 0xf5986f44, - 0x90ffd3fc, 0x7e5066ee, 0x1b37da56, 0x4d27b90e, 0x284005b6, - 0xc6efb0a4, 0xa3880c1c, 0x1ab0db81, 0x7fd76739, 0x9178d22b, - 0xf41f6e93, 0x03f7263b, 0x66909a83, 0x883f2f91, 0xed589329, - 0x546044b4, 0x3107f80c, 0xdfa84d1e, 0xbacff1a6, 0xecdf92fe, - 0x89b82e46, 0x67179b54, 0x027027ec, 0xbb48f071, 0xde2f4cc9, - 0x3080f9db, 0x55e74563, 0x9ca03f6b, 0xf9c783d3, 0x176836c1, - 0x720f8a79, 0xcb375de4, 0xae50e15c, 0x40ff544e, 0x2598e8f6, - 0x73888bae, 0x16ef3716, 0xf8408204, 0x9d273ebc, 0x241fe921, - 0x41785599, 0xafd7e08b, 0xcab05c33, 0x3bb659ed, 0x5ed1e555, - 0xb07e5047, 0xd519ecff, 0x6c213b62, 0x094687da, 0xe7e932c8, - 0x828e8e70, 0xd49eed28, 0xb1f95190, 0x5f56e482, 0x3a31583a, - 0x83098fa7, 0xe66e331f, 0x08c1860d, 0x6da63ab5, 0xa4e140bd, - 0xc186fc05, 0x2f294917, 0x4a4ef5af, 0xf3762232, 0x96119e8a, - 0x78be2b98, 0x1dd99720, 0x4bc9f478, 0x2eae48c0, 0xc001fdd2, - 0xa566416a, 0x1c5e96f7, 0x79392a4f, 0x97969f5d, 0xf2f123e5, - 0x05196b4d, 0x607ed7f5, 0x8ed162e7, 0xebb6de5f, 0x528e09c2, - 0x37e9b57a, 0xd9460068, 0xbc21bcd0, 0xea31df88, 0x8f566330, - 0x61f9d622, 0x049e6a9a, 0xbda6bd07, 0xd8c101bf, 0x366eb4ad, - 0x53090815, 0x9a4e721d, 0xff29cea5, 0x11867bb7, 0x74e1c70f, - 0xcdd91092, 0xa8beac2a, 0x46111938, 0x2376a580, 0x7566c6d8, - 0x10017a60, 0xfeaecf72, 0x9bc973ca, 0x22f1a457, 0x479618ef, - 0xa939adfd, 0xcc5e1145, 0x06ee4d76, 0x6389f1ce, 0x8d2644dc, - 0xe841f864, 0x51792ff9, 0x341e9341, 0xdab12653, 0xbfd69aeb, - 0xe9c6f9b3, 0x8ca1450b, 0x620ef019, 0x07694ca1, 0xbe519b3c, - 0xdb362784, 0x35999296, 0x50fe2e2e, 0x99b95426, 0xfcdee89e, - 0x12715d8c, 0x7716e134, 0xce2e36a9, 0xab498a11, 0x45e63f03, - 0x208183bb, 0x7691e0e3, 0x13f65c5b, 0xfd59e949, 0x983e55f1, - 0x2106826c, 0x44613ed4, 0xaace8bc6, 0xcfa9377e, 0x38417fd6, - 0x5d26c36e, 0xb389767c, 0xd6eecac4, 0x6fd61d59, 0x0ab1a1e1, - 0xe41e14f3, 0x8179a84b, 0xd769cb13, 0xb20e77ab, 0x5ca1c2b9, - 0x39c67e01, 0x80fea99c, 0xe5991524, 0x0b36a036, 0x6e511c8e, - 0xa7166686, 0xc271da3e, 0x2cde6f2c, 0x49b9d394, 0xf0810409, - 0x95e6b8b1, 0x7b490da3, 0x1e2eb11b, 0x483ed243, 0x2d596efb, - 0xc3f6dbe9, 0xa6916751, 0x1fa9b0cc, 0x7ace0c74, 0x9461b966, - 0xf10605de}}; - -#endif - -#endif - -#if N == 2 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, - 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, - 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, - 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, - 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, - 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, - 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, - 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, - 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, - 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, - 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, - 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, - 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, - 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, - 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, - 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, - 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, - 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, - 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, - 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, - 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, - 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, - 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, - 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, - 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, - 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, - 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, - 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, - 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, - 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, - 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, - 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, - 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, - 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, - 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, - 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, - 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, - 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, - 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, - 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, - 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, - 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, - 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, - 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, - 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, - 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, - 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, - 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, - 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, - 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, - 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, - 0x0d7139d7}, - {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, - 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, - 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, - 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, - 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, - 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, - 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, - 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, - 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, - 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, - 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, - 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, - 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, - 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, - 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, - 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, - 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, - 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, - 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, - 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, - 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, - 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, - 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, - 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, - 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, - 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, - 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, - 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, - 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, - 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, - 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, - 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, - 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, - 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, - 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, - 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, - 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, - 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, - 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, - 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, - 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, - 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, - 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, - 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, - 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, - 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, - 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, - 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, - 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, - 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, - 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, - 0x1c53e98a}, - {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, - 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, - 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, - 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, - 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, - 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, - 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, - 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, - 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, - 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, - 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, - 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, - 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, - 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, - 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, - 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, - 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, - 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, - 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, - 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, - 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, - 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, - 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, - 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, - 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, - 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, - 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, - 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, - 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, - 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, - 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, - 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, - 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, - 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, - 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, - 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, - 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, - 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, - 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, - 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, - 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, - 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, - 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, - 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, - 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, - 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, - 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, - 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, - 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, - 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, - 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, - 0x3f88e851}, - {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, - 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, - 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, - 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, - 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, - 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, - 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, - 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, - 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, - 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, - 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, - 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, - 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, - 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, - 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, - 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, - 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, - 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, - 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, - 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, - 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, - 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, - 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, - 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, - 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, - 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, - 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, - 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, - 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, - 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, - 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, - 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, - 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, - 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, - 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, - 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, - 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, - 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, - 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, - 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, - 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, - 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, - 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, - 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, - 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, - 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, - 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, - 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, - 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, - 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, - 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, - 0x3dee8ca6}, - {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, - 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, - 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, - 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, - 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, - 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, - 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, - 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, - 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, - 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, - 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, - 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, - 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, - 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, - 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, - 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, - 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, - 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, - 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, - 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, - 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, - 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, - 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, - 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, - 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, - 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, - 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, - 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, - 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, - 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, - 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, - 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, - 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, - 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, - 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, - 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, - 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, - 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, - 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, - 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, - 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, - 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, - 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, - 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, - 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, - 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, - 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, - 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, - 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, - 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, - 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, - 0x36197165}, - {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, - 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, - 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, - 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, - 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, - 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, - 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, - 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, - 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, - 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, - 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, - 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, - 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, - 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, - 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, - 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, - 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, - 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, - 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, - 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, - 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, - 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, - 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, - 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, - 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, - 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, - 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, - 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, - 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, - 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, - 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, - 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, - 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, - 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, - 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, - 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, - 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, - 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, - 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, - 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, - 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, - 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, - 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, - 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, - 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, - 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, - 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, - 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, - 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, - 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, - 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, - 0x1a3b93aa}, - {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, - 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, - 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, - 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, - 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, - 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, - 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, - 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, - 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, - 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, - 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, - 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, - 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, - 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, - 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, - 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, - 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, - 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, - 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, - 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, - 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, - 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, - 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, - 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, - 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, - 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, - 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, - 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, - 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, - 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, - 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, - 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, - 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, - 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, - 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, - 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, - 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, - 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, - 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, - 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, - 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, - 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, - 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, - 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, - 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, - 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, - 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, - 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, - 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, - 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, - 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, - 0xe147d714}, - {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, - 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, - 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, - 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, - 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, - 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, - 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, - 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, - 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, - 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, - 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, - 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, - 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, - 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, - 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, - 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, - 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, - 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, - 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, - 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, - 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, - 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, - 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, - 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, - 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, - 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, - 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, - 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, - 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, - 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, - 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, - 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, - 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, - 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, - 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, - 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, - 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, - 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, - 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, - 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, - 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, - 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, - 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, - 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, - 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, - 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, - 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, - 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, - 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, - 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, - 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, - 0x494f0c4b}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x43147b1700000000, 0x8628f62e00000000, - 0xc53c8d3900000000, 0x0c51ec5d00000000, 0x4f45974a00000000, - 0x8a791a7300000000, 0xc96d616400000000, 0x18a2d8bb00000000, - 0x5bb6a3ac00000000, 0x9e8a2e9500000000, 0xdd9e558200000000, - 0x14f334e600000000, 0x57e74ff100000000, 0x92dbc2c800000000, - 0xd1cfb9df00000000, 0x7142c0ac00000000, 0x3256bbbb00000000, - 0xf76a368200000000, 0xb47e4d9500000000, 0x7d132cf100000000, - 0x3e0757e600000000, 0xfb3bdadf00000000, 0xb82fa1c800000000, - 0x69e0181700000000, 0x2af4630000000000, 0xefc8ee3900000000, - 0xacdc952e00000000, 0x65b1f44a00000000, 0x26a58f5d00000000, - 0xe399026400000000, 0xa08d797300000000, 0xa382f18200000000, - 0xe0968a9500000000, 0x25aa07ac00000000, 0x66be7cbb00000000, - 0xafd31ddf00000000, 0xecc766c800000000, 0x29fbebf100000000, - 0x6aef90e600000000, 0xbb20293900000000, 0xf834522e00000000, - 0x3d08df1700000000, 0x7e1ca40000000000, 0xb771c56400000000, - 0xf465be7300000000, 0x3159334a00000000, 0x724d485d00000000, - 0xd2c0312e00000000, 0x91d44a3900000000, 0x54e8c70000000000, - 0x17fcbc1700000000, 0xde91dd7300000000, 0x9d85a66400000000, - 0x58b92b5d00000000, 0x1bad504a00000000, 0xca62e99500000000, - 0x8976928200000000, 0x4c4a1fbb00000000, 0x0f5e64ac00000000, - 0xc63305c800000000, 0x85277edf00000000, 0x401bf3e600000000, - 0x030f88f100000000, 0x070392de00000000, 0x4417e9c900000000, - 0x812b64f000000000, 0xc23f1fe700000000, 0x0b527e8300000000, - 0x4846059400000000, 0x8d7a88ad00000000, 0xce6ef3ba00000000, - 0x1fa14a6500000000, 0x5cb5317200000000, 0x9989bc4b00000000, - 0xda9dc75c00000000, 0x13f0a63800000000, 0x50e4dd2f00000000, - 0x95d8501600000000, 0xd6cc2b0100000000, 0x7641527200000000, - 0x3555296500000000, 0xf069a45c00000000, 0xb37ddf4b00000000, - 0x7a10be2f00000000, 0x3904c53800000000, 0xfc38480100000000, - 0xbf2c331600000000, 0x6ee38ac900000000, 0x2df7f1de00000000, - 0xe8cb7ce700000000, 0xabdf07f000000000, 0x62b2669400000000, - 0x21a61d8300000000, 0xe49a90ba00000000, 0xa78eebad00000000, - 0xa481635c00000000, 0xe795184b00000000, 0x22a9957200000000, - 0x61bdee6500000000, 0xa8d08f0100000000, 0xebc4f41600000000, - 0x2ef8792f00000000, 0x6dec023800000000, 0xbc23bbe700000000, - 0xff37c0f000000000, 0x3a0b4dc900000000, 0x791f36de00000000, - 0xb07257ba00000000, 0xf3662cad00000000, 0x365aa19400000000, - 0x754eda8300000000, 0xd5c3a3f000000000, 0x96d7d8e700000000, - 0x53eb55de00000000, 0x10ff2ec900000000, 0xd9924fad00000000, - 0x9a8634ba00000000, 0x5fbab98300000000, 0x1caec29400000000, - 0xcd617b4b00000000, 0x8e75005c00000000, 0x4b498d6500000000, - 0x085df67200000000, 0xc130971600000000, 0x8224ec0100000000, - 0x4718613800000000, 0x040c1a2f00000000, 0x4f00556600000000, - 0x0c142e7100000000, 0xc928a34800000000, 0x8a3cd85f00000000, - 0x4351b93b00000000, 0x0045c22c00000000, 0xc5794f1500000000, - 0x866d340200000000, 0x57a28ddd00000000, 0x14b6f6ca00000000, - 0xd18a7bf300000000, 0x929e00e400000000, 0x5bf3618000000000, - 0x18e71a9700000000, 0xdddb97ae00000000, 0x9ecfecb900000000, - 0x3e4295ca00000000, 0x7d56eedd00000000, 0xb86a63e400000000, - 0xfb7e18f300000000, 0x3213799700000000, 0x7107028000000000, - 0xb43b8fb900000000, 0xf72ff4ae00000000, 0x26e04d7100000000, - 0x65f4366600000000, 0xa0c8bb5f00000000, 0xe3dcc04800000000, - 0x2ab1a12c00000000, 0x69a5da3b00000000, 0xac99570200000000, - 0xef8d2c1500000000, 0xec82a4e400000000, 0xaf96dff300000000, - 0x6aaa52ca00000000, 0x29be29dd00000000, 0xe0d348b900000000, - 0xa3c733ae00000000, 0x66fbbe9700000000, 0x25efc58000000000, - 0xf4207c5f00000000, 0xb734074800000000, 0x72088a7100000000, - 0x311cf16600000000, 0xf871900200000000, 0xbb65eb1500000000, - 0x7e59662c00000000, 0x3d4d1d3b00000000, 0x9dc0644800000000, - 0xded41f5f00000000, 0x1be8926600000000, 0x58fce97100000000, - 0x9191881500000000, 0xd285f30200000000, 0x17b97e3b00000000, - 0x54ad052c00000000, 0x8562bcf300000000, 0xc676c7e400000000, - 0x034a4add00000000, 0x405e31ca00000000, 0x893350ae00000000, - 0xca272bb900000000, 0x0f1ba68000000000, 0x4c0fdd9700000000, - 0x4803c7b800000000, 0x0b17bcaf00000000, 0xce2b319600000000, - 0x8d3f4a8100000000, 0x44522be500000000, 0x074650f200000000, - 0xc27addcb00000000, 0x816ea6dc00000000, 0x50a11f0300000000, - 0x13b5641400000000, 0xd689e92d00000000, 0x959d923a00000000, - 0x5cf0f35e00000000, 0x1fe4884900000000, 0xdad8057000000000, - 0x99cc7e6700000000, 0x3941071400000000, 0x7a557c0300000000, - 0xbf69f13a00000000, 0xfc7d8a2d00000000, 0x3510eb4900000000, - 0x7604905e00000000, 0xb3381d6700000000, 0xf02c667000000000, - 0x21e3dfaf00000000, 0x62f7a4b800000000, 0xa7cb298100000000, - 0xe4df529600000000, 0x2db233f200000000, 0x6ea648e500000000, - 0xab9ac5dc00000000, 0xe88ebecb00000000, 0xeb81363a00000000, - 0xa8954d2d00000000, 0x6da9c01400000000, 0x2ebdbb0300000000, - 0xe7d0da6700000000, 0xa4c4a17000000000, 0x61f82c4900000000, - 0x22ec575e00000000, 0xf323ee8100000000, 0xb037959600000000, - 0x750b18af00000000, 0x361f63b800000000, 0xff7202dc00000000, - 0xbc6679cb00000000, 0x795af4f200000000, 0x3a4e8fe500000000, - 0x9ac3f69600000000, 0xd9d78d8100000000, 0x1ceb00b800000000, - 0x5fff7baf00000000, 0x96921acb00000000, 0xd58661dc00000000, - 0x10baece500000000, 0x53ae97f200000000, 0x82612e2d00000000, - 0xc175553a00000000, 0x0449d80300000000, 0x475da31400000000, - 0x8e30c27000000000, 0xcd24b96700000000, 0x0818345e00000000, - 0x4b0c4f4900000000}, - {0x0000000000000000, 0x3e6bc2ef00000000, 0x3dd0f50400000000, - 0x03bb37eb00000000, 0x7aa0eb0900000000, 0x44cb29e600000000, - 0x47701e0d00000000, 0x791bdce200000000, 0xf440d71300000000, - 0xca2b15fc00000000, 0xc990221700000000, 0xf7fbe0f800000000, - 0x8ee03c1a00000000, 0xb08bfef500000000, 0xb330c91e00000000, - 0x8d5b0bf100000000, 0xe881ae2700000000, 0xd6ea6cc800000000, - 0xd5515b2300000000, 0xeb3a99cc00000000, 0x9221452e00000000, - 0xac4a87c100000000, 0xaff1b02a00000000, 0x919a72c500000000, - 0x1cc1793400000000, 0x22aabbdb00000000, 0x21118c3000000000, - 0x1f7a4edf00000000, 0x6661923d00000000, 0x580a50d200000000, - 0x5bb1673900000000, 0x65daa5d600000000, 0xd0035d4f00000000, - 0xee689fa000000000, 0xedd3a84b00000000, 0xd3b86aa400000000, - 0xaaa3b64600000000, 0x94c874a900000000, 0x9773434200000000, - 0xa91881ad00000000, 0x24438a5c00000000, 0x1a2848b300000000, - 0x19937f5800000000, 0x27f8bdb700000000, 0x5ee3615500000000, - 0x6088a3ba00000000, 0x6333945100000000, 0x5d5856be00000000, - 0x3882f36800000000, 0x06e9318700000000, 0x0552066c00000000, - 0x3b39c48300000000, 0x4222186100000000, 0x7c49da8e00000000, - 0x7ff2ed6500000000, 0x41992f8a00000000, 0xccc2247b00000000, - 0xf2a9e69400000000, 0xf112d17f00000000, 0xcf79139000000000, - 0xb662cf7200000000, 0x88090d9d00000000, 0x8bb23a7600000000, - 0xb5d9f89900000000, 0xa007ba9e00000000, 0x9e6c787100000000, - 0x9dd74f9a00000000, 0xa3bc8d7500000000, 0xdaa7519700000000, - 0xe4cc937800000000, 0xe777a49300000000, 0xd91c667c00000000, - 0x54476d8d00000000, 0x6a2caf6200000000, 0x6997988900000000, - 0x57fc5a6600000000, 0x2ee7868400000000, 0x108c446b00000000, - 0x1337738000000000, 0x2d5cb16f00000000, 0x488614b900000000, - 0x76edd65600000000, 0x7556e1bd00000000, 0x4b3d235200000000, - 0x3226ffb000000000, 0x0c4d3d5f00000000, 0x0ff60ab400000000, - 0x319dc85b00000000, 0xbcc6c3aa00000000, 0x82ad014500000000, - 0x811636ae00000000, 0xbf7df44100000000, 0xc66628a300000000, - 0xf80dea4c00000000, 0xfbb6dda700000000, 0xc5dd1f4800000000, - 0x7004e7d100000000, 0x4e6f253e00000000, 0x4dd412d500000000, - 0x73bfd03a00000000, 0x0aa40cd800000000, 0x34cfce3700000000, - 0x3774f9dc00000000, 0x091f3b3300000000, 0x844430c200000000, - 0xba2ff22d00000000, 0xb994c5c600000000, 0x87ff072900000000, - 0xfee4dbcb00000000, 0xc08f192400000000, 0xc3342ecf00000000, - 0xfd5fec2000000000, 0x988549f600000000, 0xa6ee8b1900000000, - 0xa555bcf200000000, 0x9b3e7e1d00000000, 0xe225a2ff00000000, - 0xdc4e601000000000, 0xdff557fb00000000, 0xe19e951400000000, - 0x6cc59ee500000000, 0x52ae5c0a00000000, 0x51156be100000000, - 0x6f7ea90e00000000, 0x166575ec00000000, 0x280eb70300000000, - 0x2bb580e800000000, 0x15de420700000000, 0x010905e600000000, - 0x3f62c70900000000, 0x3cd9f0e200000000, 0x02b2320d00000000, - 0x7ba9eeef00000000, 0x45c22c0000000000, 0x46791beb00000000, - 0x7812d90400000000, 0xf549d2f500000000, 0xcb22101a00000000, - 0xc89927f100000000, 0xf6f2e51e00000000, 0x8fe939fc00000000, - 0xb182fb1300000000, 0xb239ccf800000000, 0x8c520e1700000000, - 0xe988abc100000000, 0xd7e3692e00000000, 0xd4585ec500000000, - 0xea339c2a00000000, 0x932840c800000000, 0xad43822700000000, - 0xaef8b5cc00000000, 0x9093772300000000, 0x1dc87cd200000000, - 0x23a3be3d00000000, 0x201889d600000000, 0x1e734b3900000000, - 0x676897db00000000, 0x5903553400000000, 0x5ab862df00000000, - 0x64d3a03000000000, 0xd10a58a900000000, 0xef619a4600000000, - 0xecdaadad00000000, 0xd2b16f4200000000, 0xabaab3a000000000, - 0x95c1714f00000000, 0x967a46a400000000, 0xa811844b00000000, - 0x254a8fba00000000, 0x1b214d5500000000, 0x189a7abe00000000, - 0x26f1b85100000000, 0x5fea64b300000000, 0x6181a65c00000000, - 0x623a91b700000000, 0x5c51535800000000, 0x398bf68e00000000, - 0x07e0346100000000, 0x045b038a00000000, 0x3a30c16500000000, - 0x432b1d8700000000, 0x7d40df6800000000, 0x7efbe88300000000, - 0x40902a6c00000000, 0xcdcb219d00000000, 0xf3a0e37200000000, - 0xf01bd49900000000, 0xce70167600000000, 0xb76bca9400000000, - 0x8900087b00000000, 0x8abb3f9000000000, 0xb4d0fd7f00000000, - 0xa10ebf7800000000, 0x9f657d9700000000, 0x9cde4a7c00000000, - 0xa2b5889300000000, 0xdbae547100000000, 0xe5c5969e00000000, - 0xe67ea17500000000, 0xd815639a00000000, 0x554e686b00000000, - 0x6b25aa8400000000, 0x689e9d6f00000000, 0x56f55f8000000000, - 0x2fee836200000000, 0x1185418d00000000, 0x123e766600000000, - 0x2c55b48900000000, 0x498f115f00000000, 0x77e4d3b000000000, - 0x745fe45b00000000, 0x4a3426b400000000, 0x332ffa5600000000, - 0x0d4438b900000000, 0x0eff0f5200000000, 0x3094cdbd00000000, - 0xbdcfc64c00000000, 0x83a404a300000000, 0x801f334800000000, - 0xbe74f1a700000000, 0xc76f2d4500000000, 0xf904efaa00000000, - 0xfabfd84100000000, 0xc4d41aae00000000, 0x710de23700000000, - 0x4f6620d800000000, 0x4cdd173300000000, 0x72b6d5dc00000000, - 0x0bad093e00000000, 0x35c6cbd100000000, 0x367dfc3a00000000, - 0x08163ed500000000, 0x854d352400000000, 0xbb26f7cb00000000, - 0xb89dc02000000000, 0x86f602cf00000000, 0xffedde2d00000000, - 0xc1861cc200000000, 0xc23d2b2900000000, 0xfc56e9c600000000, - 0x998c4c1000000000, 0xa7e78eff00000000, 0xa45cb91400000000, - 0x9a377bfb00000000, 0xe32ca71900000000, 0xdd4765f600000000, - 0xdefc521d00000000, 0xe09790f200000000, 0x6dcc9b0300000000, - 0x53a759ec00000000, 0x501c6e0700000000, 0x6e77ace800000000, - 0x176c700a00000000, 0x2907b2e500000000, 0x2abc850e00000000, - 0x14d747e100000000}, - {0x0000000000000000, 0xc0df8ec100000000, 0xc1b96c5800000000, - 0x0166e29900000000, 0x8273d9b000000000, 0x42ac577100000000, - 0x43cab5e800000000, 0x83153b2900000000, 0x45e1c3ba00000000, - 0x853e4d7b00000000, 0x8458afe200000000, 0x4487212300000000, - 0xc7921a0a00000000, 0x074d94cb00000000, 0x062b765200000000, - 0xc6f4f89300000000, 0xcbc4f6ae00000000, 0x0b1b786f00000000, - 0x0a7d9af600000000, 0xcaa2143700000000, 0x49b72f1e00000000, - 0x8968a1df00000000, 0x880e434600000000, 0x48d1cd8700000000, - 0x8e25351400000000, 0x4efabbd500000000, 0x4f9c594c00000000, - 0x8f43d78d00000000, 0x0c56eca400000000, 0xcc89626500000000, - 0xcdef80fc00000000, 0x0d300e3d00000000, 0xd78f9c8600000000, - 0x1750124700000000, 0x1636f0de00000000, 0xd6e97e1f00000000, - 0x55fc453600000000, 0x9523cbf700000000, 0x9445296e00000000, - 0x549aa7af00000000, 0x926e5f3c00000000, 0x52b1d1fd00000000, - 0x53d7336400000000, 0x9308bda500000000, 0x101d868c00000000, - 0xd0c2084d00000000, 0xd1a4ead400000000, 0x117b641500000000, - 0x1c4b6a2800000000, 0xdc94e4e900000000, 0xddf2067000000000, - 0x1d2d88b100000000, 0x9e38b39800000000, 0x5ee73d5900000000, - 0x5f81dfc000000000, 0x9f5e510100000000, 0x59aaa99200000000, - 0x9975275300000000, 0x9813c5ca00000000, 0x58cc4b0b00000000, - 0xdbd9702200000000, 0x1b06fee300000000, 0x1a601c7a00000000, - 0xdabf92bb00000000, 0xef1948d600000000, 0x2fc6c61700000000, - 0x2ea0248e00000000, 0xee7faa4f00000000, 0x6d6a916600000000, - 0xadb51fa700000000, 0xacd3fd3e00000000, 0x6c0c73ff00000000, - 0xaaf88b6c00000000, 0x6a2705ad00000000, 0x6b41e73400000000, - 0xab9e69f500000000, 0x288b52dc00000000, 0xe854dc1d00000000, - 0xe9323e8400000000, 0x29edb04500000000, 0x24ddbe7800000000, - 0xe40230b900000000, 0xe564d22000000000, 0x25bb5ce100000000, - 0xa6ae67c800000000, 0x6671e90900000000, 0x67170b9000000000, - 0xa7c8855100000000, 0x613c7dc200000000, 0xa1e3f30300000000, - 0xa085119a00000000, 0x605a9f5b00000000, 0xe34fa47200000000, - 0x23902ab300000000, 0x22f6c82a00000000, 0xe22946eb00000000, - 0x3896d45000000000, 0xf8495a9100000000, 0xf92fb80800000000, - 0x39f036c900000000, 0xbae50de000000000, 0x7a3a832100000000, - 0x7b5c61b800000000, 0xbb83ef7900000000, 0x7d7717ea00000000, - 0xbda8992b00000000, 0xbcce7bb200000000, 0x7c11f57300000000, - 0xff04ce5a00000000, 0x3fdb409b00000000, 0x3ebda20200000000, - 0xfe622cc300000000, 0xf35222fe00000000, 0x338dac3f00000000, - 0x32eb4ea600000000, 0xf234c06700000000, 0x7121fb4e00000000, - 0xb1fe758f00000000, 0xb098971600000000, 0x704719d700000000, - 0xb6b3e14400000000, 0x766c6f8500000000, 0x770a8d1c00000000, - 0xb7d503dd00000000, 0x34c038f400000000, 0xf41fb63500000000, - 0xf57954ac00000000, 0x35a6da6d00000000, 0x9f35e17700000000, - 0x5fea6fb600000000, 0x5e8c8d2f00000000, 0x9e5303ee00000000, - 0x1d4638c700000000, 0xdd99b60600000000, 0xdcff549f00000000, - 0x1c20da5e00000000, 0xdad422cd00000000, 0x1a0bac0c00000000, - 0x1b6d4e9500000000, 0xdbb2c05400000000, 0x58a7fb7d00000000, - 0x987875bc00000000, 0x991e972500000000, 0x59c119e400000000, - 0x54f117d900000000, 0x942e991800000000, 0x95487b8100000000, - 0x5597f54000000000, 0xd682ce6900000000, 0x165d40a800000000, - 0x173ba23100000000, 0xd7e42cf000000000, 0x1110d46300000000, - 0xd1cf5aa200000000, 0xd0a9b83b00000000, 0x107636fa00000000, - 0x93630dd300000000, 0x53bc831200000000, 0x52da618b00000000, - 0x9205ef4a00000000, 0x48ba7df100000000, 0x8865f33000000000, - 0x890311a900000000, 0x49dc9f6800000000, 0xcac9a44100000000, - 0x0a162a8000000000, 0x0b70c81900000000, 0xcbaf46d800000000, - 0x0d5bbe4b00000000, 0xcd84308a00000000, 0xcce2d21300000000, - 0x0c3d5cd200000000, 0x8f2867fb00000000, 0x4ff7e93a00000000, - 0x4e910ba300000000, 0x8e4e856200000000, 0x837e8b5f00000000, - 0x43a1059e00000000, 0x42c7e70700000000, 0x821869c600000000, - 0x010d52ef00000000, 0xc1d2dc2e00000000, 0xc0b43eb700000000, - 0x006bb07600000000, 0xc69f48e500000000, 0x0640c62400000000, - 0x072624bd00000000, 0xc7f9aa7c00000000, 0x44ec915500000000, - 0x84331f9400000000, 0x8555fd0d00000000, 0x458a73cc00000000, - 0x702ca9a100000000, 0xb0f3276000000000, 0xb195c5f900000000, - 0x714a4b3800000000, 0xf25f701100000000, 0x3280fed000000000, - 0x33e61c4900000000, 0xf339928800000000, 0x35cd6a1b00000000, - 0xf512e4da00000000, 0xf474064300000000, 0x34ab888200000000, - 0xb7beb3ab00000000, 0x77613d6a00000000, 0x7607dff300000000, - 0xb6d8513200000000, 0xbbe85f0f00000000, 0x7b37d1ce00000000, - 0x7a51335700000000, 0xba8ebd9600000000, 0x399b86bf00000000, - 0xf944087e00000000, 0xf822eae700000000, 0x38fd642600000000, - 0xfe099cb500000000, 0x3ed6127400000000, 0x3fb0f0ed00000000, - 0xff6f7e2c00000000, 0x7c7a450500000000, 0xbca5cbc400000000, - 0xbdc3295d00000000, 0x7d1ca79c00000000, 0xa7a3352700000000, - 0x677cbbe600000000, 0x661a597f00000000, 0xa6c5d7be00000000, - 0x25d0ec9700000000, 0xe50f625600000000, 0xe46980cf00000000, - 0x24b60e0e00000000, 0xe242f69d00000000, 0x229d785c00000000, - 0x23fb9ac500000000, 0xe324140400000000, 0x60312f2d00000000, - 0xa0eea1ec00000000, 0xa188437500000000, 0x6157cdb400000000, - 0x6c67c38900000000, 0xacb84d4800000000, 0xaddeafd100000000, - 0x6d01211000000000, 0xee141a3900000000, 0x2ecb94f800000000, - 0x2fad766100000000, 0xef72f8a000000000, 0x2986003300000000, - 0xe9598ef200000000, 0xe83f6c6b00000000, 0x28e0e2aa00000000, - 0xabf5d98300000000, 0x6b2a574200000000, 0x6a4cb5db00000000, - 0xaa933b1a00000000}, - {0x0000000000000000, 0x6f4ca59b00000000, 0x9f9e3bec00000000, - 0xf0d29e7700000000, 0x7f3b060300000000, 0x1077a39800000000, - 0xe0a53def00000000, 0x8fe9987400000000, 0xfe760c0600000000, - 0x913aa99d00000000, 0x61e837ea00000000, 0x0ea4927100000000, - 0x814d0a0500000000, 0xee01af9e00000000, 0x1ed331e900000000, - 0x719f947200000000, 0xfced180c00000000, 0x93a1bd9700000000, - 0x637323e000000000, 0x0c3f867b00000000, 0x83d61e0f00000000, - 0xec9abb9400000000, 0x1c4825e300000000, 0x7304807800000000, - 0x029b140a00000000, 0x6dd7b19100000000, 0x9d052fe600000000, - 0xf2498a7d00000000, 0x7da0120900000000, 0x12ecb79200000000, - 0xe23e29e500000000, 0x8d728c7e00000000, 0xf8db311800000000, - 0x9797948300000000, 0x67450af400000000, 0x0809af6f00000000, - 0x87e0371b00000000, 0xe8ac928000000000, 0x187e0cf700000000, - 0x7732a96c00000000, 0x06ad3d1e00000000, 0x69e1988500000000, - 0x993306f200000000, 0xf67fa36900000000, 0x79963b1d00000000, - 0x16da9e8600000000, 0xe60800f100000000, 0x8944a56a00000000, - 0x0436291400000000, 0x6b7a8c8f00000000, 0x9ba812f800000000, - 0xf4e4b76300000000, 0x7b0d2f1700000000, 0x14418a8c00000000, - 0xe49314fb00000000, 0x8bdfb16000000000, 0xfa40251200000000, - 0x950c808900000000, 0x65de1efe00000000, 0x0a92bb6500000000, - 0x857b231100000000, 0xea37868a00000000, 0x1ae518fd00000000, - 0x75a9bd6600000000, 0xf0b7633000000000, 0x9ffbc6ab00000000, - 0x6f2958dc00000000, 0x0065fd4700000000, 0x8f8c653300000000, - 0xe0c0c0a800000000, 0x10125edf00000000, 0x7f5efb4400000000, - 0x0ec16f3600000000, 0x618dcaad00000000, 0x915f54da00000000, - 0xfe13f14100000000, 0x71fa693500000000, 0x1eb6ccae00000000, - 0xee6452d900000000, 0x8128f74200000000, 0x0c5a7b3c00000000, - 0x6316dea700000000, 0x93c440d000000000, 0xfc88e54b00000000, - 0x73617d3f00000000, 0x1c2dd8a400000000, 0xecff46d300000000, - 0x83b3e34800000000, 0xf22c773a00000000, 0x9d60d2a100000000, - 0x6db24cd600000000, 0x02fee94d00000000, 0x8d17713900000000, - 0xe25bd4a200000000, 0x12894ad500000000, 0x7dc5ef4e00000000, - 0x086c522800000000, 0x6720f7b300000000, 0x97f269c400000000, - 0xf8becc5f00000000, 0x7757542b00000000, 0x181bf1b000000000, - 0xe8c96fc700000000, 0x8785ca5c00000000, 0xf61a5e2e00000000, - 0x9956fbb500000000, 0x698465c200000000, 0x06c8c05900000000, - 0x8921582d00000000, 0xe66dfdb600000000, 0x16bf63c100000000, - 0x79f3c65a00000000, 0xf4814a2400000000, 0x9bcdefbf00000000, - 0x6b1f71c800000000, 0x0453d45300000000, 0x8bba4c2700000000, - 0xe4f6e9bc00000000, 0x142477cb00000000, 0x7b68d25000000000, - 0x0af7462200000000, 0x65bbe3b900000000, 0x95697dce00000000, - 0xfa25d85500000000, 0x75cc402100000000, 0x1a80e5ba00000000, - 0xea527bcd00000000, 0x851ede5600000000, 0xe06fc76000000000, - 0x8f2362fb00000000, 0x7ff1fc8c00000000, 0x10bd591700000000, - 0x9f54c16300000000, 0xf01864f800000000, 0x00cafa8f00000000, - 0x6f865f1400000000, 0x1e19cb6600000000, 0x71556efd00000000, - 0x8187f08a00000000, 0xeecb551100000000, 0x6122cd6500000000, - 0x0e6e68fe00000000, 0xfebcf68900000000, 0x91f0531200000000, - 0x1c82df6c00000000, 0x73ce7af700000000, 0x831ce48000000000, - 0xec50411b00000000, 0x63b9d96f00000000, 0x0cf57cf400000000, - 0xfc27e28300000000, 0x936b471800000000, 0xe2f4d36a00000000, - 0x8db876f100000000, 0x7d6ae88600000000, 0x12264d1d00000000, - 0x9dcfd56900000000, 0xf28370f200000000, 0x0251ee8500000000, - 0x6d1d4b1e00000000, 0x18b4f67800000000, 0x77f853e300000000, - 0x872acd9400000000, 0xe866680f00000000, 0x678ff07b00000000, - 0x08c355e000000000, 0xf811cb9700000000, 0x975d6e0c00000000, - 0xe6c2fa7e00000000, 0x898e5fe500000000, 0x795cc19200000000, - 0x1610640900000000, 0x99f9fc7d00000000, 0xf6b559e600000000, - 0x0667c79100000000, 0x692b620a00000000, 0xe459ee7400000000, - 0x8b154bef00000000, 0x7bc7d59800000000, 0x148b700300000000, - 0x9b62e87700000000, 0xf42e4dec00000000, 0x04fcd39b00000000, - 0x6bb0760000000000, 0x1a2fe27200000000, 0x756347e900000000, - 0x85b1d99e00000000, 0xeafd7c0500000000, 0x6514e47100000000, - 0x0a5841ea00000000, 0xfa8adf9d00000000, 0x95c67a0600000000, - 0x10d8a45000000000, 0x7f9401cb00000000, 0x8f469fbc00000000, - 0xe00a3a2700000000, 0x6fe3a25300000000, 0x00af07c800000000, - 0xf07d99bf00000000, 0x9f313c2400000000, 0xeeaea85600000000, - 0x81e20dcd00000000, 0x713093ba00000000, 0x1e7c362100000000, - 0x9195ae5500000000, 0xfed90bce00000000, 0x0e0b95b900000000, - 0x6147302200000000, 0xec35bc5c00000000, 0x837919c700000000, - 0x73ab87b000000000, 0x1ce7222b00000000, 0x930eba5f00000000, - 0xfc421fc400000000, 0x0c9081b300000000, 0x63dc242800000000, - 0x1243b05a00000000, 0x7d0f15c100000000, 0x8ddd8bb600000000, - 0xe2912e2d00000000, 0x6d78b65900000000, 0x023413c200000000, - 0xf2e68db500000000, 0x9daa282e00000000, 0xe803954800000000, - 0x874f30d300000000, 0x779daea400000000, 0x18d10b3f00000000, - 0x9738934b00000000, 0xf87436d000000000, 0x08a6a8a700000000, - 0x67ea0d3c00000000, 0x1675994e00000000, 0x79393cd500000000, - 0x89eba2a200000000, 0xe6a7073900000000, 0x694e9f4d00000000, - 0x06023ad600000000, 0xf6d0a4a100000000, 0x999c013a00000000, - 0x14ee8d4400000000, 0x7ba228df00000000, 0x8b70b6a800000000, - 0xe43c133300000000, 0x6bd58b4700000000, 0x04992edc00000000, - 0xf44bb0ab00000000, 0x9b07153000000000, 0xea98814200000000, - 0x85d424d900000000, 0x7506baae00000000, 0x1a4a1f3500000000, - 0x95a3874100000000, 0xfaef22da00000000, 0x0a3dbcad00000000, - 0x6571193600000000}, - {0x0000000000000000, 0x85d996dd00000000, 0x4bb55c6000000000, - 0xce6ccabd00000000, 0x966ab9c000000000, 0x13b32f1d00000000, - 0xdddfe5a000000000, 0x5806737d00000000, 0x6dd3035a00000000, - 0xe80a958700000000, 0x26665f3a00000000, 0xa3bfc9e700000000, - 0xfbb9ba9a00000000, 0x7e602c4700000000, 0xb00ce6fa00000000, - 0x35d5702700000000, 0xdaa607b400000000, 0x5f7f916900000000, - 0x91135bd400000000, 0x14cacd0900000000, 0x4cccbe7400000000, - 0xc91528a900000000, 0x0779e21400000000, 0x82a074c900000000, - 0xb77504ee00000000, 0x32ac923300000000, 0xfcc0588e00000000, - 0x7919ce5300000000, 0x211fbd2e00000000, 0xa4c62bf300000000, - 0x6aaae14e00000000, 0xef73779300000000, 0xf54b7eb300000000, - 0x7092e86e00000000, 0xbefe22d300000000, 0x3b27b40e00000000, - 0x6321c77300000000, 0xe6f851ae00000000, 0x28949b1300000000, - 0xad4d0dce00000000, 0x98987de900000000, 0x1d41eb3400000000, - 0xd32d218900000000, 0x56f4b75400000000, 0x0ef2c42900000000, - 0x8b2b52f400000000, 0x4547984900000000, 0xc09e0e9400000000, - 0x2fed790700000000, 0xaa34efda00000000, 0x6458256700000000, - 0xe181b3ba00000000, 0xb987c0c700000000, 0x3c5e561a00000000, - 0xf2329ca700000000, 0x77eb0a7a00000000, 0x423e7a5d00000000, - 0xc7e7ec8000000000, 0x098b263d00000000, 0x8c52b0e000000000, - 0xd454c39d00000000, 0x518d554000000000, 0x9fe19ffd00000000, - 0x1a38092000000000, 0xab918dbd00000000, 0x2e481b6000000000, - 0xe024d1dd00000000, 0x65fd470000000000, 0x3dfb347d00000000, - 0xb822a2a000000000, 0x764e681d00000000, 0xf397fec000000000, - 0xc6428ee700000000, 0x439b183a00000000, 0x8df7d28700000000, - 0x082e445a00000000, 0x5028372700000000, 0xd5f1a1fa00000000, - 0x1b9d6b4700000000, 0x9e44fd9a00000000, 0x71378a0900000000, - 0xf4ee1cd400000000, 0x3a82d66900000000, 0xbf5b40b400000000, - 0xe75d33c900000000, 0x6284a51400000000, 0xace86fa900000000, - 0x2931f97400000000, 0x1ce4895300000000, 0x993d1f8e00000000, - 0x5751d53300000000, 0xd28843ee00000000, 0x8a8e309300000000, - 0x0f57a64e00000000, 0xc13b6cf300000000, 0x44e2fa2e00000000, - 0x5edaf30e00000000, 0xdb0365d300000000, 0x156faf6e00000000, - 0x90b639b300000000, 0xc8b04ace00000000, 0x4d69dc1300000000, - 0x830516ae00000000, 0x06dc807300000000, 0x3309f05400000000, - 0xb6d0668900000000, 0x78bcac3400000000, 0xfd653ae900000000, - 0xa563499400000000, 0x20badf4900000000, 0xeed615f400000000, - 0x6b0f832900000000, 0x847cf4ba00000000, 0x01a5626700000000, - 0xcfc9a8da00000000, 0x4a103e0700000000, 0x12164d7a00000000, - 0x97cfdba700000000, 0x59a3111a00000000, 0xdc7a87c700000000, - 0xe9aff7e000000000, 0x6c76613d00000000, 0xa21aab8000000000, - 0x27c33d5d00000000, 0x7fc54e2000000000, 0xfa1cd8fd00000000, - 0x3470124000000000, 0xb1a9849d00000000, 0x17256aa000000000, - 0x92fcfc7d00000000, 0x5c9036c000000000, 0xd949a01d00000000, - 0x814fd36000000000, 0x049645bd00000000, 0xcafa8f0000000000, - 0x4f2319dd00000000, 0x7af669fa00000000, 0xff2fff2700000000, - 0x3143359a00000000, 0xb49aa34700000000, 0xec9cd03a00000000, - 0x694546e700000000, 0xa7298c5a00000000, 0x22f01a8700000000, - 0xcd836d1400000000, 0x485afbc900000000, 0x8636317400000000, - 0x03efa7a900000000, 0x5be9d4d400000000, 0xde30420900000000, - 0x105c88b400000000, 0x95851e6900000000, 0xa0506e4e00000000, - 0x2589f89300000000, 0xebe5322e00000000, 0x6e3ca4f300000000, - 0x363ad78e00000000, 0xb3e3415300000000, 0x7d8f8bee00000000, - 0xf8561d3300000000, 0xe26e141300000000, 0x67b782ce00000000, - 0xa9db487300000000, 0x2c02deae00000000, 0x7404add300000000, - 0xf1dd3b0e00000000, 0x3fb1f1b300000000, 0xba68676e00000000, - 0x8fbd174900000000, 0x0a64819400000000, 0xc4084b2900000000, - 0x41d1ddf400000000, 0x19d7ae8900000000, 0x9c0e385400000000, - 0x5262f2e900000000, 0xd7bb643400000000, 0x38c813a700000000, - 0xbd11857a00000000, 0x737d4fc700000000, 0xf6a4d91a00000000, - 0xaea2aa6700000000, 0x2b7b3cba00000000, 0xe517f60700000000, - 0x60ce60da00000000, 0x551b10fd00000000, 0xd0c2862000000000, - 0x1eae4c9d00000000, 0x9b77da4000000000, 0xc371a93d00000000, - 0x46a83fe000000000, 0x88c4f55d00000000, 0x0d1d638000000000, - 0xbcb4e71d00000000, 0x396d71c000000000, 0xf701bb7d00000000, - 0x72d82da000000000, 0x2ade5edd00000000, 0xaf07c80000000000, - 0x616b02bd00000000, 0xe4b2946000000000, 0xd167e44700000000, - 0x54be729a00000000, 0x9ad2b82700000000, 0x1f0b2efa00000000, - 0x470d5d8700000000, 0xc2d4cb5a00000000, 0x0cb801e700000000, - 0x8961973a00000000, 0x6612e0a900000000, 0xe3cb767400000000, - 0x2da7bcc900000000, 0xa87e2a1400000000, 0xf078596900000000, - 0x75a1cfb400000000, 0xbbcd050900000000, 0x3e1493d400000000, - 0x0bc1e3f300000000, 0x8e18752e00000000, 0x4074bf9300000000, - 0xc5ad294e00000000, 0x9dab5a3300000000, 0x1872ccee00000000, - 0xd61e065300000000, 0x53c7908e00000000, 0x49ff99ae00000000, - 0xcc260f7300000000, 0x024ac5ce00000000, 0x8793531300000000, - 0xdf95206e00000000, 0x5a4cb6b300000000, 0x94207c0e00000000, - 0x11f9ead300000000, 0x242c9af400000000, 0xa1f50c2900000000, - 0x6f99c69400000000, 0xea40504900000000, 0xb246233400000000, - 0x379fb5e900000000, 0xf9f37f5400000000, 0x7c2ae98900000000, - 0x93599e1a00000000, 0x168008c700000000, 0xd8ecc27a00000000, - 0x5d3554a700000000, 0x053327da00000000, 0x80eab10700000000, - 0x4e867bba00000000, 0xcb5fed6700000000, 0xfe8a9d4000000000, - 0x7b530b9d00000000, 0xb53fc12000000000, 0x30e657fd00000000, - 0x68e0248000000000, 0xed39b25d00000000, 0x235578e000000000, - 0xa68cee3d00000000}, - {0x0000000000000000, 0x76e10f9d00000000, 0xadc46ee100000000, - 0xdb25617c00000000, 0x1b8fac1900000000, 0x6d6ea38400000000, - 0xb64bc2f800000000, 0xc0aacd6500000000, 0x361e593300000000, - 0x40ff56ae00000000, 0x9bda37d200000000, 0xed3b384f00000000, - 0x2d91f52a00000000, 0x5b70fab700000000, 0x80559bcb00000000, - 0xf6b4945600000000, 0x6c3cb26600000000, 0x1addbdfb00000000, - 0xc1f8dc8700000000, 0xb719d31a00000000, 0x77b31e7f00000000, - 0x015211e200000000, 0xda77709e00000000, 0xac967f0300000000, - 0x5a22eb5500000000, 0x2cc3e4c800000000, 0xf7e685b400000000, - 0x81078a2900000000, 0x41ad474c00000000, 0x374c48d100000000, - 0xec6929ad00000000, 0x9a88263000000000, 0xd87864cd00000000, - 0xae996b5000000000, 0x75bc0a2c00000000, 0x035d05b100000000, - 0xc3f7c8d400000000, 0xb516c74900000000, 0x6e33a63500000000, - 0x18d2a9a800000000, 0xee663dfe00000000, 0x9887326300000000, - 0x43a2531f00000000, 0x35435c8200000000, 0xf5e991e700000000, - 0x83089e7a00000000, 0x582dff0600000000, 0x2eccf09b00000000, - 0xb444d6ab00000000, 0xc2a5d93600000000, 0x1980b84a00000000, - 0x6f61b7d700000000, 0xafcb7ab200000000, 0xd92a752f00000000, - 0x020f145300000000, 0x74ee1bce00000000, 0x825a8f9800000000, - 0xf4bb800500000000, 0x2f9ee17900000000, 0x597feee400000000, - 0x99d5238100000000, 0xef342c1c00000000, 0x34114d6000000000, - 0x42f042fd00000000, 0xf1f7b94100000000, 0x8716b6dc00000000, - 0x5c33d7a000000000, 0x2ad2d83d00000000, 0xea78155800000000, - 0x9c991ac500000000, 0x47bc7bb900000000, 0x315d742400000000, - 0xc7e9e07200000000, 0xb108efef00000000, 0x6a2d8e9300000000, - 0x1ccc810e00000000, 0xdc664c6b00000000, 0xaa8743f600000000, - 0x71a2228a00000000, 0x07432d1700000000, 0x9dcb0b2700000000, - 0xeb2a04ba00000000, 0x300f65c600000000, 0x46ee6a5b00000000, - 0x8644a73e00000000, 0xf0a5a8a300000000, 0x2b80c9df00000000, - 0x5d61c64200000000, 0xabd5521400000000, 0xdd345d8900000000, - 0x06113cf500000000, 0x70f0336800000000, 0xb05afe0d00000000, - 0xc6bbf19000000000, 0x1d9e90ec00000000, 0x6b7f9f7100000000, - 0x298fdd8c00000000, 0x5f6ed21100000000, 0x844bb36d00000000, - 0xf2aabcf000000000, 0x3200719500000000, 0x44e17e0800000000, - 0x9fc41f7400000000, 0xe92510e900000000, 0x1f9184bf00000000, - 0x69708b2200000000, 0xb255ea5e00000000, 0xc4b4e5c300000000, - 0x041e28a600000000, 0x72ff273b00000000, 0xa9da464700000000, - 0xdf3b49da00000000, 0x45b36fea00000000, 0x3352607700000000, - 0xe877010b00000000, 0x9e960e9600000000, 0x5e3cc3f300000000, - 0x28ddcc6e00000000, 0xf3f8ad1200000000, 0x8519a28f00000000, - 0x73ad36d900000000, 0x054c394400000000, 0xde69583800000000, - 0xa88857a500000000, 0x68229ac000000000, 0x1ec3955d00000000, - 0xc5e6f42100000000, 0xb307fbbc00000000, 0xe2ef738300000000, - 0x940e7c1e00000000, 0x4f2b1d6200000000, 0x39ca12ff00000000, - 0xf960df9a00000000, 0x8f81d00700000000, 0x54a4b17b00000000, - 0x2245bee600000000, 0xd4f12ab000000000, 0xa210252d00000000, - 0x7935445100000000, 0x0fd44bcc00000000, 0xcf7e86a900000000, - 0xb99f893400000000, 0x62bae84800000000, 0x145be7d500000000, - 0x8ed3c1e500000000, 0xf832ce7800000000, 0x2317af0400000000, - 0x55f6a09900000000, 0x955c6dfc00000000, 0xe3bd626100000000, - 0x3898031d00000000, 0x4e790c8000000000, 0xb8cd98d600000000, - 0xce2c974b00000000, 0x1509f63700000000, 0x63e8f9aa00000000, - 0xa34234cf00000000, 0xd5a33b5200000000, 0x0e865a2e00000000, - 0x786755b300000000, 0x3a97174e00000000, 0x4c7618d300000000, - 0x975379af00000000, 0xe1b2763200000000, 0x2118bb5700000000, - 0x57f9b4ca00000000, 0x8cdcd5b600000000, 0xfa3dda2b00000000, - 0x0c894e7d00000000, 0x7a6841e000000000, 0xa14d209c00000000, - 0xd7ac2f0100000000, 0x1706e26400000000, 0x61e7edf900000000, - 0xbac28c8500000000, 0xcc23831800000000, 0x56aba52800000000, - 0x204aaab500000000, 0xfb6fcbc900000000, 0x8d8ec45400000000, - 0x4d24093100000000, 0x3bc506ac00000000, 0xe0e067d000000000, - 0x9601684d00000000, 0x60b5fc1b00000000, 0x1654f38600000000, - 0xcd7192fa00000000, 0xbb909d6700000000, 0x7b3a500200000000, - 0x0ddb5f9f00000000, 0xd6fe3ee300000000, 0xa01f317e00000000, - 0x1318cac200000000, 0x65f9c55f00000000, 0xbedca42300000000, - 0xc83dabbe00000000, 0x089766db00000000, 0x7e76694600000000, - 0xa553083a00000000, 0xd3b207a700000000, 0x250693f100000000, - 0x53e79c6c00000000, 0x88c2fd1000000000, 0xfe23f28d00000000, - 0x3e893fe800000000, 0x4868307500000000, 0x934d510900000000, - 0xe5ac5e9400000000, 0x7f2478a400000000, 0x09c5773900000000, - 0xd2e0164500000000, 0xa40119d800000000, 0x64abd4bd00000000, - 0x124adb2000000000, 0xc96fba5c00000000, 0xbf8eb5c100000000, - 0x493a219700000000, 0x3fdb2e0a00000000, 0xe4fe4f7600000000, - 0x921f40eb00000000, 0x52b58d8e00000000, 0x2454821300000000, - 0xff71e36f00000000, 0x8990ecf200000000, 0xcb60ae0f00000000, - 0xbd81a19200000000, 0x66a4c0ee00000000, 0x1045cf7300000000, - 0xd0ef021600000000, 0xa60e0d8b00000000, 0x7d2b6cf700000000, - 0x0bca636a00000000, 0xfd7ef73c00000000, 0x8b9ff8a100000000, - 0x50ba99dd00000000, 0x265b964000000000, 0xe6f15b2500000000, - 0x901054b800000000, 0x4b3535c400000000, 0x3dd43a5900000000, - 0xa75c1c6900000000, 0xd1bd13f400000000, 0x0a98728800000000, - 0x7c797d1500000000, 0xbcd3b07000000000, 0xca32bfed00000000, - 0x1117de9100000000, 0x67f6d10c00000000, 0x9142455a00000000, - 0xe7a34ac700000000, 0x3c862bbb00000000, 0x4a67242600000000, - 0x8acde94300000000, 0xfc2ce6de00000000, 0x270987a200000000, - 0x51e8883f00000000}, - {0x0000000000000000, 0xe8dbfbb900000000, 0x91b186a800000000, - 0x796a7d1100000000, 0x63657c8a00000000, 0x8bbe873300000000, - 0xf2d4fa2200000000, 0x1a0f019b00000000, 0x87cc89cf00000000, - 0x6f17727600000000, 0x167d0f6700000000, 0xfea6f4de00000000, - 0xe4a9f54500000000, 0x0c720efc00000000, 0x751873ed00000000, - 0x9dc3885400000000, 0x4f9f624400000000, 0xa74499fd00000000, - 0xde2ee4ec00000000, 0x36f51f5500000000, 0x2cfa1ece00000000, - 0xc421e57700000000, 0xbd4b986600000000, 0x559063df00000000, - 0xc853eb8b00000000, 0x2088103200000000, 0x59e26d2300000000, - 0xb139969a00000000, 0xab36970100000000, 0x43ed6cb800000000, - 0x3a8711a900000000, 0xd25cea1000000000, 0x9e3ec58800000000, - 0x76e53e3100000000, 0x0f8f432000000000, 0xe754b89900000000, - 0xfd5bb90200000000, 0x158042bb00000000, 0x6cea3faa00000000, - 0x8431c41300000000, 0x19f24c4700000000, 0xf129b7fe00000000, - 0x8843caef00000000, 0x6098315600000000, 0x7a9730cd00000000, - 0x924ccb7400000000, 0xeb26b66500000000, 0x03fd4ddc00000000, - 0xd1a1a7cc00000000, 0x397a5c7500000000, 0x4010216400000000, - 0xa8cbdadd00000000, 0xb2c4db4600000000, 0x5a1f20ff00000000, - 0x23755dee00000000, 0xcbaea65700000000, 0x566d2e0300000000, - 0xbeb6d5ba00000000, 0xc7dca8ab00000000, 0x2f07531200000000, - 0x3508528900000000, 0xddd3a93000000000, 0xa4b9d42100000000, - 0x4c622f9800000000, 0x7d7bfbca00000000, 0x95a0007300000000, - 0xecca7d6200000000, 0x041186db00000000, 0x1e1e874000000000, - 0xf6c57cf900000000, 0x8faf01e800000000, 0x6774fa5100000000, - 0xfab7720500000000, 0x126c89bc00000000, 0x6b06f4ad00000000, - 0x83dd0f1400000000, 0x99d20e8f00000000, 0x7109f53600000000, - 0x0863882700000000, 0xe0b8739e00000000, 0x32e4998e00000000, - 0xda3f623700000000, 0xa3551f2600000000, 0x4b8ee49f00000000, - 0x5181e50400000000, 0xb95a1ebd00000000, 0xc03063ac00000000, - 0x28eb981500000000, 0xb528104100000000, 0x5df3ebf800000000, - 0x249996e900000000, 0xcc426d5000000000, 0xd64d6ccb00000000, - 0x3e96977200000000, 0x47fcea6300000000, 0xaf2711da00000000, - 0xe3453e4200000000, 0x0b9ec5fb00000000, 0x72f4b8ea00000000, - 0x9a2f435300000000, 0x802042c800000000, 0x68fbb97100000000, - 0x1191c46000000000, 0xf94a3fd900000000, 0x6489b78d00000000, - 0x8c524c3400000000, 0xf538312500000000, 0x1de3ca9c00000000, - 0x07eccb0700000000, 0xef3730be00000000, 0x965d4daf00000000, - 0x7e86b61600000000, 0xacda5c0600000000, 0x4401a7bf00000000, - 0x3d6bdaae00000000, 0xd5b0211700000000, 0xcfbf208c00000000, - 0x2764db3500000000, 0x5e0ea62400000000, 0xb6d55d9d00000000, - 0x2b16d5c900000000, 0xc3cd2e7000000000, 0xbaa7536100000000, - 0x527ca8d800000000, 0x4873a94300000000, 0xa0a852fa00000000, - 0xd9c22feb00000000, 0x3119d45200000000, 0xbbf0874e00000000, - 0x532b7cf700000000, 0x2a4101e600000000, 0xc29afa5f00000000, - 0xd895fbc400000000, 0x304e007d00000000, 0x49247d6c00000000, - 0xa1ff86d500000000, 0x3c3c0e8100000000, 0xd4e7f53800000000, - 0xad8d882900000000, 0x4556739000000000, 0x5f59720b00000000, - 0xb78289b200000000, 0xcee8f4a300000000, 0x26330f1a00000000, - 0xf46fe50a00000000, 0x1cb41eb300000000, 0x65de63a200000000, - 0x8d05981b00000000, 0x970a998000000000, 0x7fd1623900000000, - 0x06bb1f2800000000, 0xee60e49100000000, 0x73a36cc500000000, - 0x9b78977c00000000, 0xe212ea6d00000000, 0x0ac911d400000000, - 0x10c6104f00000000, 0xf81debf600000000, 0x817796e700000000, - 0x69ac6d5e00000000, 0x25ce42c600000000, 0xcd15b97f00000000, - 0xb47fc46e00000000, 0x5ca43fd700000000, 0x46ab3e4c00000000, - 0xae70c5f500000000, 0xd71ab8e400000000, 0x3fc1435d00000000, - 0xa202cb0900000000, 0x4ad930b000000000, 0x33b34da100000000, - 0xdb68b61800000000, 0xc167b78300000000, 0x29bc4c3a00000000, - 0x50d6312b00000000, 0xb80dca9200000000, 0x6a51208200000000, - 0x828adb3b00000000, 0xfbe0a62a00000000, 0x133b5d9300000000, - 0x09345c0800000000, 0xe1efa7b100000000, 0x9885daa000000000, - 0x705e211900000000, 0xed9da94d00000000, 0x054652f400000000, - 0x7c2c2fe500000000, 0x94f7d45c00000000, 0x8ef8d5c700000000, - 0x66232e7e00000000, 0x1f49536f00000000, 0xf792a8d600000000, - 0xc68b7c8400000000, 0x2e50873d00000000, 0x573afa2c00000000, - 0xbfe1019500000000, 0xa5ee000e00000000, 0x4d35fbb700000000, - 0x345f86a600000000, 0xdc847d1f00000000, 0x4147f54b00000000, - 0xa99c0ef200000000, 0xd0f673e300000000, 0x382d885a00000000, - 0x222289c100000000, 0xcaf9727800000000, 0xb3930f6900000000, - 0x5b48f4d000000000, 0x89141ec000000000, 0x61cfe57900000000, - 0x18a5986800000000, 0xf07e63d100000000, 0xea71624a00000000, - 0x02aa99f300000000, 0x7bc0e4e200000000, 0x931b1f5b00000000, - 0x0ed8970f00000000, 0xe6036cb600000000, 0x9f6911a700000000, - 0x77b2ea1e00000000, 0x6dbdeb8500000000, 0x8566103c00000000, - 0xfc0c6d2d00000000, 0x14d7969400000000, 0x58b5b90c00000000, - 0xb06e42b500000000, 0xc9043fa400000000, 0x21dfc41d00000000, - 0x3bd0c58600000000, 0xd30b3e3f00000000, 0xaa61432e00000000, - 0x42bab89700000000, 0xdf7930c300000000, 0x37a2cb7a00000000, - 0x4ec8b66b00000000, 0xa6134dd200000000, 0xbc1c4c4900000000, - 0x54c7b7f000000000, 0x2dadcae100000000, 0xc576315800000000, - 0x172adb4800000000, 0xfff120f100000000, 0x869b5de000000000, - 0x6e40a65900000000, 0x744fa7c200000000, 0x9c945c7b00000000, - 0xe5fe216a00000000, 0x0d25dad300000000, 0x90e6528700000000, - 0x783da93e00000000, 0x0157d42f00000000, 0xe98c2f9600000000, - 0xf3832e0d00000000, 0x1b58d5b400000000, 0x6232a8a500000000, - 0x8ae9531c00000000}, - {0x0000000000000000, 0x919168ae00000000, 0x6325a08700000000, - 0xf2b4c82900000000, 0x874c31d400000000, 0x16dd597a00000000, - 0xe469915300000000, 0x75f8f9fd00000000, 0x4f9f137300000000, - 0xde0e7bdd00000000, 0x2cbab3f400000000, 0xbd2bdb5a00000000, - 0xc8d322a700000000, 0x59424a0900000000, 0xabf6822000000000, - 0x3a67ea8e00000000, 0x9e3e27e600000000, 0x0faf4f4800000000, - 0xfd1b876100000000, 0x6c8aefcf00000000, 0x1972163200000000, - 0x88e37e9c00000000, 0x7a57b6b500000000, 0xebc6de1b00000000, - 0xd1a1349500000000, 0x40305c3b00000000, 0xb284941200000000, - 0x2315fcbc00000000, 0x56ed054100000000, 0xc77c6def00000000, - 0x35c8a5c600000000, 0xa459cd6800000000, 0x7d7b3f1700000000, - 0xecea57b900000000, 0x1e5e9f9000000000, 0x8fcff73e00000000, - 0xfa370ec300000000, 0x6ba6666d00000000, 0x9912ae4400000000, - 0x0883c6ea00000000, 0x32e42c6400000000, 0xa37544ca00000000, - 0x51c18ce300000000, 0xc050e44d00000000, 0xb5a81db000000000, - 0x2439751e00000000, 0xd68dbd3700000000, 0x471cd59900000000, - 0xe34518f100000000, 0x72d4705f00000000, 0x8060b87600000000, - 0x11f1d0d800000000, 0x6409292500000000, 0xf598418b00000000, - 0x072c89a200000000, 0x96bde10c00000000, 0xacda0b8200000000, - 0x3d4b632c00000000, 0xcfffab0500000000, 0x5e6ec3ab00000000, - 0x2b963a5600000000, 0xba0752f800000000, 0x48b39ad100000000, - 0xd922f27f00000000, 0xfaf67e2e00000000, 0x6b67168000000000, - 0x99d3dea900000000, 0x0842b60700000000, 0x7dba4ffa00000000, - 0xec2b275400000000, 0x1e9fef7d00000000, 0x8f0e87d300000000, - 0xb5696d5d00000000, 0x24f805f300000000, 0xd64ccdda00000000, - 0x47dda57400000000, 0x32255c8900000000, 0xa3b4342700000000, - 0x5100fc0e00000000, 0xc09194a000000000, 0x64c859c800000000, - 0xf559316600000000, 0x07edf94f00000000, 0x967c91e100000000, - 0xe384681c00000000, 0x721500b200000000, 0x80a1c89b00000000, - 0x1130a03500000000, 0x2b574abb00000000, 0xbac6221500000000, - 0x4872ea3c00000000, 0xd9e3829200000000, 0xac1b7b6f00000000, - 0x3d8a13c100000000, 0xcf3edbe800000000, 0x5eafb34600000000, - 0x878d413900000000, 0x161c299700000000, 0xe4a8e1be00000000, - 0x7539891000000000, 0x00c170ed00000000, 0x9150184300000000, - 0x63e4d06a00000000, 0xf275b8c400000000, 0xc812524a00000000, - 0x59833ae400000000, 0xab37f2cd00000000, 0x3aa69a6300000000, - 0x4f5e639e00000000, 0xdecf0b3000000000, 0x2c7bc31900000000, - 0xbdeaabb700000000, 0x19b366df00000000, 0x88220e7100000000, - 0x7a96c65800000000, 0xeb07aef600000000, 0x9eff570b00000000, - 0x0f6e3fa500000000, 0xfddaf78c00000000, 0x6c4b9f2200000000, - 0x562c75ac00000000, 0xc7bd1d0200000000, 0x3509d52b00000000, - 0xa498bd8500000000, 0xd160447800000000, 0x40f12cd600000000, - 0xb245e4ff00000000, 0x23d48c5100000000, 0xf4edfd5c00000000, - 0x657c95f200000000, 0x97c85ddb00000000, 0x0659357500000000, - 0x73a1cc8800000000, 0xe230a42600000000, 0x10846c0f00000000, - 0x811504a100000000, 0xbb72ee2f00000000, 0x2ae3868100000000, - 0xd8574ea800000000, 0x49c6260600000000, 0x3c3edffb00000000, - 0xadafb75500000000, 0x5f1b7f7c00000000, 0xce8a17d200000000, - 0x6ad3daba00000000, 0xfb42b21400000000, 0x09f67a3d00000000, - 0x9867129300000000, 0xed9feb6e00000000, 0x7c0e83c000000000, - 0x8eba4be900000000, 0x1f2b234700000000, 0x254cc9c900000000, - 0xb4dda16700000000, 0x4669694e00000000, 0xd7f801e000000000, - 0xa200f81d00000000, 0x339190b300000000, 0xc125589a00000000, - 0x50b4303400000000, 0x8996c24b00000000, 0x1807aae500000000, - 0xeab362cc00000000, 0x7b220a6200000000, 0x0edaf39f00000000, - 0x9f4b9b3100000000, 0x6dff531800000000, 0xfc6e3bb600000000, - 0xc609d13800000000, 0x5798b99600000000, 0xa52c71bf00000000, - 0x34bd191100000000, 0x4145e0ec00000000, 0xd0d4884200000000, - 0x2260406b00000000, 0xb3f128c500000000, 0x17a8e5ad00000000, - 0x86398d0300000000, 0x748d452a00000000, 0xe51c2d8400000000, - 0x90e4d47900000000, 0x0175bcd700000000, 0xf3c174fe00000000, - 0x62501c5000000000, 0x5837f6de00000000, 0xc9a69e7000000000, - 0x3b12565900000000, 0xaa833ef700000000, 0xdf7bc70a00000000, - 0x4eeaafa400000000, 0xbc5e678d00000000, 0x2dcf0f2300000000, - 0x0e1b837200000000, 0x9f8aebdc00000000, 0x6d3e23f500000000, - 0xfcaf4b5b00000000, 0x8957b2a600000000, 0x18c6da0800000000, - 0xea72122100000000, 0x7be37a8f00000000, 0x4184900100000000, - 0xd015f8af00000000, 0x22a1308600000000, 0xb330582800000000, - 0xc6c8a1d500000000, 0x5759c97b00000000, 0xa5ed015200000000, - 0x347c69fc00000000, 0x9025a49400000000, 0x01b4cc3a00000000, - 0xf300041300000000, 0x62916cbd00000000, 0x1769954000000000, - 0x86f8fdee00000000, 0x744c35c700000000, 0xe5dd5d6900000000, - 0xdfbab7e700000000, 0x4e2bdf4900000000, 0xbc9f176000000000, - 0x2d0e7fce00000000, 0x58f6863300000000, 0xc967ee9d00000000, - 0x3bd326b400000000, 0xaa424e1a00000000, 0x7360bc6500000000, - 0xe2f1d4cb00000000, 0x10451ce200000000, 0x81d4744c00000000, - 0xf42c8db100000000, 0x65bde51f00000000, 0x97092d3600000000, - 0x0698459800000000, 0x3cffaf1600000000, 0xad6ec7b800000000, - 0x5fda0f9100000000, 0xce4b673f00000000, 0xbbb39ec200000000, - 0x2a22f66c00000000, 0xd8963e4500000000, 0x490756eb00000000, - 0xed5e9b8300000000, 0x7ccff32d00000000, 0x8e7b3b0400000000, - 0x1fea53aa00000000, 0x6a12aa5700000000, 0xfb83c2f900000000, - 0x09370ad000000000, 0x98a6627e00000000, 0xa2c188f000000000, - 0x3350e05e00000000, 0xc1e4287700000000, 0x507540d900000000, - 0x258db92400000000, 0xb41cd18a00000000, 0x46a819a300000000, - 0xd739710d00000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, - 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, - 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, - 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, - 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, - 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, - 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, - 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, - 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, - 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, - 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, - 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, - 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, - 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, - 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, - 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, - 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, - 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, - 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, - 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, - 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, - 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, - 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, - 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, - 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, - 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, - 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, - 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, - 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, - 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, - 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, - 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, - 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, - 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, - 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, - 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, - 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, - 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, - 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, - 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, - 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, - 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, - 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, - 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, - 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, - 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, - 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, - 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, - 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, - 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, - 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, - 0x264b06e6}, - {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, - 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, - 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, - 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, - 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, - 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, - 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, - 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, - 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, - 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, - 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, - 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, - 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, - 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, - 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, - 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, - 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, - 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, - 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, - 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, - 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, - 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, - 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, - 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, - 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, - 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, - 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, - 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, - 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, - 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, - 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, - 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, - 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, - 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, - 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, - 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, - 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, - 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, - 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, - 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, - 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, - 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, - 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, - 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, - 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, - 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, - 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, - 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, - 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, - 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, - 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, - 0x92364a30}, - {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, - 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, - 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, - 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, - 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, - 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, - 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, - 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, - 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, - 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, - 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, - 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, - 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, - 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, - 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, - 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, - 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, - 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, - 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, - 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, - 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, - 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, - 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, - 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, - 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, - 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, - 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, - 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, - 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, - 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, - 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, - 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, - 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, - 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, - 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, - 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, - 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, - 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, - 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, - 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, - 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, - 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, - 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, - 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, - 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, - 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, - 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, - 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, - 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, - 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, - 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, - 0xe4c4abcc}, - {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, - 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, - 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, - 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, - 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, - 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, - 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, - 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, - 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, - 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, - 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, - 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, - 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, - 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, - 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, - 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, - 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, - 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, - 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, - 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, - 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, - 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, - 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, - 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, - 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, - 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, - 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, - 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, - 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, - 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, - 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, - 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, - 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, - 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, - 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, - 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, - 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, - 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, - 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, - 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, - 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, - 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, - 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, - 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, - 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, - 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, - 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, - 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, - 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, - 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, - 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, - 0xca64c78c}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0xb029603d, 0x6053c07a, 0xd07aa047, 0xc0a680f5, - 0x708fe0c8, 0xa0f5408f, 0x10dc20b2, 0xc14b7030, 0x7162100d, - 0xa118b04a, 0x1131d077, 0x01edf0c5, 0xb1c490f8, 0x61be30bf, - 0xd1975082, 0x8297e060, 0x32be805d, 0xe2c4201a, 0x52ed4027, - 0x42316095, 0xf21800a8, 0x2262a0ef, 0x924bc0d2, 0x43dc9050, - 0xf3f5f06d, 0x238f502a, 0x93a63017, 0x837a10a5, 0x33537098, - 0xe329d0df, 0x5300b0e2, 0x042fc1c1, 0xb406a1fc, 0x647c01bb, - 0xd4556186, 0xc4894134, 0x74a02109, 0xa4da814e, 0x14f3e173, - 0xc564b1f1, 0x754dd1cc, 0xa537718b, 0x151e11b6, 0x05c23104, - 0xb5eb5139, 0x6591f17e, 0xd5b89143, 0x86b821a1, 0x3691419c, - 0xe6ebe1db, 0x56c281e6, 0x461ea154, 0xf637c169, 0x264d612e, - 0x96640113, 0x47f35191, 0xf7da31ac, 0x27a091eb, 0x9789f1d6, - 0x8755d164, 0x377cb159, 0xe706111e, 0x572f7123, 0x4958f358, - 0xf9719365, 0x290b3322, 0x9922531f, 0x89fe73ad, 0x39d71390, - 0xe9adb3d7, 0x5984d3ea, 0x88138368, 0x383ae355, 0xe8404312, - 0x5869232f, 0x48b5039d, 0xf89c63a0, 0x28e6c3e7, 0x98cfa3da, - 0xcbcf1338, 0x7be67305, 0xab9cd342, 0x1bb5b37f, 0x0b6993cd, - 0xbb40f3f0, 0x6b3a53b7, 0xdb13338a, 0x0a846308, 0xbaad0335, - 0x6ad7a372, 0xdafec34f, 0xca22e3fd, 0x7a0b83c0, 0xaa712387, - 0x1a5843ba, 0x4d773299, 0xfd5e52a4, 0x2d24f2e3, 0x9d0d92de, - 0x8dd1b26c, 0x3df8d251, 0xed827216, 0x5dab122b, 0x8c3c42a9, - 0x3c152294, 0xec6f82d3, 0x5c46e2ee, 0x4c9ac25c, 0xfcb3a261, - 0x2cc90226, 0x9ce0621b, 0xcfe0d2f9, 0x7fc9b2c4, 0xafb31283, - 0x1f9a72be, 0x0f46520c, 0xbf6f3231, 0x6f159276, 0xdf3cf24b, - 0x0eaba2c9, 0xbe82c2f4, 0x6ef862b3, 0xded1028e, 0xce0d223c, - 0x7e244201, 0xae5ee246, 0x1e77827b, 0x92b0e6b1, 0x2299868c, - 0xf2e326cb, 0x42ca46f6, 0x52166644, 0xe23f0679, 0x3245a63e, - 0x826cc603, 0x53fb9681, 0xe3d2f6bc, 0x33a856fb, 0x838136c6, - 0x935d1674, 0x23747649, 0xf30ed60e, 0x4327b633, 0x102706d1, - 0xa00e66ec, 0x7074c6ab, 0xc05da696, 0xd0818624, 0x60a8e619, - 0xb0d2465e, 0x00fb2663, 0xd16c76e1, 0x614516dc, 0xb13fb69b, - 0x0116d6a6, 0x11caf614, 0xa1e39629, 0x7199366e, 0xc1b05653, - 0x969f2770, 0x26b6474d, 0xf6cce70a, 0x46e58737, 0x5639a785, - 0xe610c7b8, 0x366a67ff, 0x864307c2, 0x57d45740, 0xe7fd377d, - 0x3787973a, 0x87aef707, 0x9772d7b5, 0x275bb788, 0xf72117cf, - 0x470877f2, 0x1408c710, 0xa421a72d, 0x745b076a, 0xc4726757, - 0xd4ae47e5, 0x648727d8, 0xb4fd879f, 0x04d4e7a2, 0xd543b720, - 0x656ad71d, 0xb510775a, 0x05391767, 0x15e537d5, 0xa5cc57e8, - 0x75b6f7af, 0xc59f9792, 0xdbe815e9, 0x6bc175d4, 0xbbbbd593, - 0x0b92b5ae, 0x1b4e951c, 0xab67f521, 0x7b1d5566, 0xcb34355b, - 0x1aa365d9, 0xaa8a05e4, 0x7af0a5a3, 0xcad9c59e, 0xda05e52c, - 0x6a2c8511, 0xba562556, 0x0a7f456b, 0x597ff589, 0xe95695b4, - 0x392c35f3, 0x890555ce, 0x99d9757c, 0x29f01541, 0xf98ab506, - 0x49a3d53b, 0x983485b9, 0x281de584, 0xf86745c3, 0x484e25fe, - 0x5892054c, 0xe8bb6571, 0x38c1c536, 0x88e8a50b, 0xdfc7d428, - 0x6feeb415, 0xbf941452, 0x0fbd746f, 0x1f6154dd, 0xaf4834e0, - 0x7f3294a7, 0xcf1bf49a, 0x1e8ca418, 0xaea5c425, 0x7edf6462, - 0xcef6045f, 0xde2a24ed, 0x6e0344d0, 0xbe79e497, 0x0e5084aa, - 0x5d503448, 0xed795475, 0x3d03f432, 0x8d2a940f, 0x9df6b4bd, - 0x2ddfd480, 0xfda574c7, 0x4d8c14fa, 0x9c1b4478, 0x2c322445, - 0xfc488402, 0x4c61e43f, 0x5cbdc48d, 0xec94a4b0, 0x3cee04f7, - 0x8cc764ca}, - {0x00000000, 0xa5d35ccb, 0x0ba1c84d, 0xae729486, 0x1642919b, - 0xb391cd50, 0x1de359d6, 0xb830051d, 0x6d8253ec, 0xc8510f27, - 0x66239ba1, 0xc3f0c76a, 0x7bc0c277, 0xde139ebc, 0x70610a3a, - 0xd5b256f1, 0x9b02d603, 0x3ed18ac8, 0x90a31e4e, 0x35704285, - 0x8d404798, 0x28931b53, 0x86e18fd5, 0x2332d31e, 0xf68085ef, - 0x5353d924, 0xfd214da2, 0x58f21169, 0xe0c21474, 0x451148bf, - 0xeb63dc39, 0x4eb080f2, 0x3605ac07, 0x93d6f0cc, 0x3da4644a, - 0x98773881, 0x20473d9c, 0x85946157, 0x2be6f5d1, 0x8e35a91a, - 0x5b87ffeb, 0xfe54a320, 0x502637a6, 0xf5f56b6d, 0x4dc56e70, - 0xe81632bb, 0x4664a63d, 0xe3b7faf6, 0xad077a04, 0x08d426cf, - 0xa6a6b249, 0x0375ee82, 0xbb45eb9f, 0x1e96b754, 0xb0e423d2, - 0x15377f19, 0xc08529e8, 0x65567523, 0xcb24e1a5, 0x6ef7bd6e, - 0xd6c7b873, 0x7314e4b8, 0xdd66703e, 0x78b52cf5, 0x6c0a580f, - 0xc9d904c4, 0x67ab9042, 0xc278cc89, 0x7a48c994, 0xdf9b955f, - 0x71e901d9, 0xd43a5d12, 0x01880be3, 0xa45b5728, 0x0a29c3ae, - 0xaffa9f65, 0x17ca9a78, 0xb219c6b3, 0x1c6b5235, 0xb9b80efe, - 0xf7088e0c, 0x52dbd2c7, 0xfca94641, 0x597a1a8a, 0xe14a1f97, - 0x4499435c, 0xeaebd7da, 0x4f388b11, 0x9a8adde0, 0x3f59812b, - 0x912b15ad, 0x34f84966, 0x8cc84c7b, 0x291b10b0, 0x87698436, - 0x22bad8fd, 0x5a0ff408, 0xffdca8c3, 0x51ae3c45, 0xf47d608e, - 0x4c4d6593, 0xe99e3958, 0x47ecadde, 0xe23ff115, 0x378da7e4, - 0x925efb2f, 0x3c2c6fa9, 0x99ff3362, 0x21cf367f, 0x841c6ab4, - 0x2a6efe32, 0x8fbda2f9, 0xc10d220b, 0x64de7ec0, 0xcaacea46, - 0x6f7fb68d, 0xd74fb390, 0x729cef5b, 0xdcee7bdd, 0x793d2716, - 0xac8f71e7, 0x095c2d2c, 0xa72eb9aa, 0x02fde561, 0xbacde07c, - 0x1f1ebcb7, 0xb16c2831, 0x14bf74fa, 0xd814b01e, 0x7dc7ecd5, - 0xd3b57853, 0x76662498, 0xce562185, 0x6b857d4e, 0xc5f7e9c8, - 0x6024b503, 0xb596e3f2, 0x1045bf39, 0xbe372bbf, 0x1be47774, - 0xa3d47269, 0x06072ea2, 0xa875ba24, 0x0da6e6ef, 0x4316661d, - 0xe6c53ad6, 0x48b7ae50, 0xed64f29b, 0x5554f786, 0xf087ab4d, - 0x5ef53fcb, 0xfb266300, 0x2e9435f1, 0x8b47693a, 0x2535fdbc, - 0x80e6a177, 0x38d6a46a, 0x9d05f8a1, 0x33776c27, 0x96a430ec, - 0xee111c19, 0x4bc240d2, 0xe5b0d454, 0x4063889f, 0xf8538d82, - 0x5d80d149, 0xf3f245cf, 0x56211904, 0x83934ff5, 0x2640133e, - 0x883287b8, 0x2de1db73, 0x95d1de6e, 0x300282a5, 0x9e701623, - 0x3ba34ae8, 0x7513ca1a, 0xd0c096d1, 0x7eb20257, 0xdb615e9c, - 0x63515b81, 0xc682074a, 0x68f093cc, 0xcd23cf07, 0x189199f6, - 0xbd42c53d, 0x133051bb, 0xb6e30d70, 0x0ed3086d, 0xab0054a6, - 0x0572c020, 0xa0a19ceb, 0xb41ee811, 0x11cdb4da, 0xbfbf205c, - 0x1a6c7c97, 0xa25c798a, 0x078f2541, 0xa9fdb1c7, 0x0c2eed0c, - 0xd99cbbfd, 0x7c4fe736, 0xd23d73b0, 0x77ee2f7b, 0xcfde2a66, - 0x6a0d76ad, 0xc47fe22b, 0x61acbee0, 0x2f1c3e12, 0x8acf62d9, - 0x24bdf65f, 0x816eaa94, 0x395eaf89, 0x9c8df342, 0x32ff67c4, - 0x972c3b0f, 0x429e6dfe, 0xe74d3135, 0x493fa5b3, 0xececf978, - 0x54dcfc65, 0xf10fa0ae, 0x5f7d3428, 0xfaae68e3, 0x821b4416, - 0x27c818dd, 0x89ba8c5b, 0x2c69d090, 0x9459d58d, 0x318a8946, - 0x9ff81dc0, 0x3a2b410b, 0xef9917fa, 0x4a4a4b31, 0xe438dfb7, - 0x41eb837c, 0xf9db8661, 0x5c08daaa, 0xf27a4e2c, 0x57a912e7, - 0x19199215, 0xbccacede, 0x12b85a58, 0xb76b0693, 0x0f5b038e, - 0xaa885f45, 0x04facbc3, 0xa1299708, 0x749bc1f9, 0xd1489d32, - 0x7f3a09b4, 0xdae9557f, 0x62d95062, 0xc70a0ca9, 0x6978982f, - 0xccabc4e4}, - {0x00000000, 0xb40b77a6, 0x29119f97, 0x9d1ae831, 0x13244ff4, - 0xa72f3852, 0x3a35d063, 0x8e3ea7c5, 0x674eef33, 0xd3459895, - 0x4e5f70a4, 0xfa540702, 0x746aa0c7, 0xc061d761, 0x5d7b3f50, - 0xe97048f6, 0xce9cde67, 0x7a97a9c1, 0xe78d41f0, 0x53863656, - 0xddb89193, 0x69b3e635, 0xf4a90e04, 0x40a279a2, 0xa9d23154, - 0x1dd946f2, 0x80c3aec3, 0x34c8d965, 0xbaf67ea0, 0x0efd0906, - 0x93e7e137, 0x27ec9691, 0x9c39bdcf, 0x2832ca69, 0xb5282258, - 0x012355fe, 0x8f1df23b, 0x3b16859d, 0xa60c6dac, 0x12071a0a, - 0xfb7752fc, 0x4f7c255a, 0xd266cd6b, 0x666dbacd, 0xe8531d08, - 0x5c586aae, 0xc142829f, 0x7549f539, 0x52a563a8, 0xe6ae140e, - 0x7bb4fc3f, 0xcfbf8b99, 0x41812c5c, 0xf58a5bfa, 0x6890b3cb, - 0xdc9bc46d, 0x35eb8c9b, 0x81e0fb3d, 0x1cfa130c, 0xa8f164aa, - 0x26cfc36f, 0x92c4b4c9, 0x0fde5cf8, 0xbbd52b5e, 0x79750b44, - 0xcd7e7ce2, 0x506494d3, 0xe46fe375, 0x6a5144b0, 0xde5a3316, - 0x4340db27, 0xf74bac81, 0x1e3be477, 0xaa3093d1, 0x372a7be0, - 0x83210c46, 0x0d1fab83, 0xb914dc25, 0x240e3414, 0x900543b2, - 0xb7e9d523, 0x03e2a285, 0x9ef84ab4, 0x2af33d12, 0xa4cd9ad7, - 0x10c6ed71, 0x8ddc0540, 0x39d772e6, 0xd0a73a10, 0x64ac4db6, - 0xf9b6a587, 0x4dbdd221, 0xc38375e4, 0x77880242, 0xea92ea73, - 0x5e999dd5, 0xe54cb68b, 0x5147c12d, 0xcc5d291c, 0x78565eba, - 0xf668f97f, 0x42638ed9, 0xdf7966e8, 0x6b72114e, 0x820259b8, - 0x36092e1e, 0xab13c62f, 0x1f18b189, 0x9126164c, 0x252d61ea, - 0xb83789db, 0x0c3cfe7d, 0x2bd068ec, 0x9fdb1f4a, 0x02c1f77b, - 0xb6ca80dd, 0x38f42718, 0x8cff50be, 0x11e5b88f, 0xa5eecf29, - 0x4c9e87df, 0xf895f079, 0x658f1848, 0xd1846fee, 0x5fbac82b, - 0xebb1bf8d, 0x76ab57bc, 0xc2a0201a, 0xf2ea1688, 0x46e1612e, - 0xdbfb891f, 0x6ff0feb9, 0xe1ce597c, 0x55c52eda, 0xc8dfc6eb, - 0x7cd4b14d, 0x95a4f9bb, 0x21af8e1d, 0xbcb5662c, 0x08be118a, - 0x8680b64f, 0x328bc1e9, 0xaf9129d8, 0x1b9a5e7e, 0x3c76c8ef, - 0x887dbf49, 0x15675778, 0xa16c20de, 0x2f52871b, 0x9b59f0bd, - 0x0643188c, 0xb2486f2a, 0x5b3827dc, 0xef33507a, 0x7229b84b, - 0xc622cfed, 0x481c6828, 0xfc171f8e, 0x610df7bf, 0xd5068019, - 0x6ed3ab47, 0xdad8dce1, 0x47c234d0, 0xf3c94376, 0x7df7e4b3, - 0xc9fc9315, 0x54e67b24, 0xe0ed0c82, 0x099d4474, 0xbd9633d2, - 0x208cdbe3, 0x9487ac45, 0x1ab90b80, 0xaeb27c26, 0x33a89417, - 0x87a3e3b1, 0xa04f7520, 0x14440286, 0x895eeab7, 0x3d559d11, - 0xb36b3ad4, 0x07604d72, 0x9a7aa543, 0x2e71d2e5, 0xc7019a13, - 0x730aedb5, 0xee100584, 0x5a1b7222, 0xd425d5e7, 0x602ea241, - 0xfd344a70, 0x493f3dd6, 0x8b9f1dcc, 0x3f946a6a, 0xa28e825b, - 0x1685f5fd, 0x98bb5238, 0x2cb0259e, 0xb1aacdaf, 0x05a1ba09, - 0xecd1f2ff, 0x58da8559, 0xc5c06d68, 0x71cb1ace, 0xfff5bd0b, - 0x4bfecaad, 0xd6e4229c, 0x62ef553a, 0x4503c3ab, 0xf108b40d, - 0x6c125c3c, 0xd8192b9a, 0x56278c5f, 0xe22cfbf9, 0x7f3613c8, - 0xcb3d646e, 0x224d2c98, 0x96465b3e, 0x0b5cb30f, 0xbf57c4a9, - 0x3169636c, 0x856214ca, 0x1878fcfb, 0xac738b5d, 0x17a6a003, - 0xa3add7a5, 0x3eb73f94, 0x8abc4832, 0x0482eff7, 0xb0899851, - 0x2d937060, 0x999807c6, 0x70e84f30, 0xc4e33896, 0x59f9d0a7, - 0xedf2a701, 0x63cc00c4, 0xd7c77762, 0x4add9f53, 0xfed6e8f5, - 0xd93a7e64, 0x6d3109c2, 0xf02be1f3, 0x44209655, 0xca1e3190, - 0x7e154636, 0xe30fae07, 0x5704d9a1, 0xbe749157, 0x0a7fe6f1, - 0x97650ec0, 0x236e7966, 0xad50dea3, 0x195ba905, 0x84414134, - 0x304a3692}, - {0x00000000, 0x9e00aacc, 0x7d072542, 0xe3078f8e, 0xfa0e4a84, - 0x640ee048, 0x87096fc6, 0x1909c50a, 0xb51be5d3, 0x2b1b4f1f, - 0xc81cc091, 0x561c6a5d, 0x4f15af57, 0xd115059b, 0x32128a15, - 0xac1220d9, 0x2b31bb7c, 0xb53111b0, 0x56369e3e, 0xc83634f2, - 0xd13ff1f8, 0x4f3f5b34, 0xac38d4ba, 0x32387e76, 0x9e2a5eaf, - 0x002af463, 0xe32d7bed, 0x7d2dd121, 0x6424142b, 0xfa24bee7, - 0x19233169, 0x87239ba5, 0x566276f9, 0xc862dc35, 0x2b6553bb, - 0xb565f977, 0xac6c3c7d, 0x326c96b1, 0xd16b193f, 0x4f6bb3f3, - 0xe379932a, 0x7d7939e6, 0x9e7eb668, 0x007e1ca4, 0x1977d9ae, - 0x87777362, 0x6470fcec, 0xfa705620, 0x7d53cd85, 0xe3536749, - 0x0054e8c7, 0x9e54420b, 0x875d8701, 0x195d2dcd, 0xfa5aa243, - 0x645a088f, 0xc8482856, 0x5648829a, 0xb54f0d14, 0x2b4fa7d8, - 0x324662d2, 0xac46c81e, 0x4f414790, 0xd141ed5c, 0xedc29d29, - 0x73c237e5, 0x90c5b86b, 0x0ec512a7, 0x17ccd7ad, 0x89cc7d61, - 0x6acbf2ef, 0xf4cb5823, 0x58d978fa, 0xc6d9d236, 0x25de5db8, - 0xbbdef774, 0xa2d7327e, 0x3cd798b2, 0xdfd0173c, 0x41d0bdf0, - 0xc6f32655, 0x58f38c99, 0xbbf40317, 0x25f4a9db, 0x3cfd6cd1, - 0xa2fdc61d, 0x41fa4993, 0xdffae35f, 0x73e8c386, 0xede8694a, - 0x0eefe6c4, 0x90ef4c08, 0x89e68902, 0x17e623ce, 0xf4e1ac40, - 0x6ae1068c, 0xbba0ebd0, 0x25a0411c, 0xc6a7ce92, 0x58a7645e, - 0x41aea154, 0xdfae0b98, 0x3ca98416, 0xa2a92eda, 0x0ebb0e03, - 0x90bba4cf, 0x73bc2b41, 0xedbc818d, 0xf4b54487, 0x6ab5ee4b, - 0x89b261c5, 0x17b2cb09, 0x909150ac, 0x0e91fa60, 0xed9675ee, - 0x7396df22, 0x6a9f1a28, 0xf49fb0e4, 0x17983f6a, 0x899895a6, - 0x258ab57f, 0xbb8a1fb3, 0x588d903d, 0xc68d3af1, 0xdf84fffb, - 0x41845537, 0xa283dab9, 0x3c837075, 0xda853b53, 0x4485919f, - 0xa7821e11, 0x3982b4dd, 0x208b71d7, 0xbe8bdb1b, 0x5d8c5495, - 0xc38cfe59, 0x6f9ede80, 0xf19e744c, 0x1299fbc2, 0x8c99510e, - 0x95909404, 0x0b903ec8, 0xe897b146, 0x76971b8a, 0xf1b4802f, - 0x6fb42ae3, 0x8cb3a56d, 0x12b30fa1, 0x0bbacaab, 0x95ba6067, - 0x76bdefe9, 0xe8bd4525, 0x44af65fc, 0xdaafcf30, 0x39a840be, - 0xa7a8ea72, 0xbea12f78, 0x20a185b4, 0xc3a60a3a, 0x5da6a0f6, - 0x8ce74daa, 0x12e7e766, 0xf1e068e8, 0x6fe0c224, 0x76e9072e, - 0xe8e9ade2, 0x0bee226c, 0x95ee88a0, 0x39fca879, 0xa7fc02b5, - 0x44fb8d3b, 0xdafb27f7, 0xc3f2e2fd, 0x5df24831, 0xbef5c7bf, - 0x20f56d73, 0xa7d6f6d6, 0x39d65c1a, 0xdad1d394, 0x44d17958, - 0x5dd8bc52, 0xc3d8169e, 0x20df9910, 0xbedf33dc, 0x12cd1305, - 0x8ccdb9c9, 0x6fca3647, 0xf1ca9c8b, 0xe8c35981, 0x76c3f34d, - 0x95c47cc3, 0x0bc4d60f, 0x3747a67a, 0xa9470cb6, 0x4a408338, - 0xd44029f4, 0xcd49ecfe, 0x53494632, 0xb04ec9bc, 0x2e4e6370, - 0x825c43a9, 0x1c5ce965, 0xff5b66eb, 0x615bcc27, 0x7852092d, - 0xe652a3e1, 0x05552c6f, 0x9b5586a3, 0x1c761d06, 0x8276b7ca, - 0x61713844, 0xff719288, 0xe6785782, 0x7878fd4e, 0x9b7f72c0, - 0x057fd80c, 0xa96df8d5, 0x376d5219, 0xd46add97, 0x4a6a775b, - 0x5363b251, 0xcd63189d, 0x2e649713, 0xb0643ddf, 0x6125d083, - 0xff257a4f, 0x1c22f5c1, 0x82225f0d, 0x9b2b9a07, 0x052b30cb, - 0xe62cbf45, 0x782c1589, 0xd43e3550, 0x4a3e9f9c, 0xa9391012, - 0x3739bade, 0x2e307fd4, 0xb030d518, 0x53375a96, 0xcd37f05a, - 0x4a146bff, 0xd414c133, 0x37134ebd, 0xa913e471, 0xb01a217b, - 0x2e1a8bb7, 0xcd1d0439, 0x531daef5, 0xff0f8e2c, 0x610f24e0, - 0x8208ab6e, 0x1c0801a2, 0x0501c4a8, 0x9b016e64, 0x7806e1ea, - 0xe6064b26}}; - -#endif - -#endif - -#if N == 3 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, - 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, - 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, - 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, - 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, - 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, - 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, - 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, - 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, - 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, - 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, - 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, - 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, - 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, - 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, - 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, - 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, - 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, - 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, - 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, - 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, - 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, - 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, - 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, - 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, - 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, - 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, - 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, - 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, - 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, - 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, - 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, - 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, - 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, - 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, - 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, - 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, - 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, - 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, - 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, - 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, - 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, - 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, - 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, - 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, - 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, - 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, - 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, - 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, - 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, - 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, - 0x09cd8551}, - {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, - 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, - 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, - 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, - 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, - 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, - 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, - 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, - 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, - 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, - 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, - 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, - 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, - 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, - 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, - 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, - 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, - 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, - 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, - 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, - 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, - 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, - 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, - 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, - 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, - 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, - 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, - 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, - 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, - 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, - 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, - 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, - 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, - 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, - 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, - 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, - 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, - 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, - 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, - 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, - 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, - 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, - 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, - 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, - 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, - 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, - 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, - 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, - 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, - 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, - 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, - 0x7bc97a0c}, - {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, - 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, - 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, - 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, - 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, - 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, - 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, - 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, - 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, - 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, - 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, - 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, - 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, - 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, - 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, - 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, - 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, - 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, - 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, - 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, - 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, - 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, - 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, - 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, - 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, - 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, - 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, - 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, - 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, - 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, - 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, - 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, - 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, - 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, - 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, - 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, - 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, - 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, - 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, - 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, - 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, - 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, - 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, - 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, - 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, - 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, - 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, - 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, - 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, - 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, - 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, - 0x7851a2ca}, - {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, - 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, - 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, - 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, - 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, - 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, - 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, - 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, - 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, - 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, - 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, - 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, - 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, - 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, - 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, - 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, - 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, - 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, - 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, - 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, - 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, - 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, - 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, - 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, - 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, - 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, - 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, - 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, - 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, - 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, - 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, - 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, - 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, - 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, - 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, - 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, - 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, - 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, - 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, - 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, - 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, - 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, - 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, - 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, - 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, - 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, - 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, - 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, - 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, - 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, - 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, - 0x566b6848}, - {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, - 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, - 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, - 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, - 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, - 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, - 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, - 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, - 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, - 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, - 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, - 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, - 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, - 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, - 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, - 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, - 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, - 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, - 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, - 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, - 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, - 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, - 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, - 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, - 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, - 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, - 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, - 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, - 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, - 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, - 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, - 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, - 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, - 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, - 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, - 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, - 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, - 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, - 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, - 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, - 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, - 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, - 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, - 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, - 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, - 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, - 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, - 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, - 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, - 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, - 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, - 0xd8ac6b35}, - {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, - 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, - 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, - 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, - 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, - 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, - 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, - 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, - 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, - 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, - 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, - 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, - 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, - 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, - 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, - 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, - 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, - 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, - 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, - 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, - 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, - 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, - 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, - 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, - 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, - 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, - 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, - 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, - 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, - 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, - 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, - 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, - 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, - 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, - 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, - 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, - 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, - 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, - 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, - 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, - 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, - 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, - 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, - 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, - 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, - 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, - 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, - 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, - 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, - 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, - 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, - 0xa140efa8}, - {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, - 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, - 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, - 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, - 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, - 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, - 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, - 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, - 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, - 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, - 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, - 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, - 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, - 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, - 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, - 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, - 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, - 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, - 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, - 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, - 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, - 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, - 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, - 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, - 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, - 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, - 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, - 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, - 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, - 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, - 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, - 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, - 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, - 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, - 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, - 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, - 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, - 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, - 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, - 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, - 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, - 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, - 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, - 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, - 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, - 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, - 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, - 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, - 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, - 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, - 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, - 0x917cd6a1}, - {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, - 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, - 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, - 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, - 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, - 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, - 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, - 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, - 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, - 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, - 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, - 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, - 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, - 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, - 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, - 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, - 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, - 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, - 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, - 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, - 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, - 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, - 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, - 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, - 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, - 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, - 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, - 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, - 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, - 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, - 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, - 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, - 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, - 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, - 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, - 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, - 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, - 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, - 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, - 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, - 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, - 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, - 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, - 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, - 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, - 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, - 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, - 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, - 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, - 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, - 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, - 0x18ba364e}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x43cba68700000000, 0xc7903cd400000000, - 0x845b9a5300000000, 0xcf27087300000000, 0x8cecaef400000000, - 0x08b734a700000000, 0x4b7c922000000000, 0x9e4f10e600000000, - 0xdd84b66100000000, 0x59df2c3200000000, 0x1a148ab500000000, - 0x5168189500000000, 0x12a3be1200000000, 0x96f8244100000000, - 0xd53382c600000000, 0x7d99511700000000, 0x3e52f79000000000, - 0xba096dc300000000, 0xf9c2cb4400000000, 0xb2be596400000000, - 0xf175ffe300000000, 0x752e65b000000000, 0x36e5c33700000000, - 0xe3d641f100000000, 0xa01de77600000000, 0x24467d2500000000, - 0x678ddba200000000, 0x2cf1498200000000, 0x6f3aef0500000000, - 0xeb61755600000000, 0xa8aad3d100000000, 0xfa32a32e00000000, - 0xb9f905a900000000, 0x3da29ffa00000000, 0x7e69397d00000000, - 0x3515ab5d00000000, 0x76de0dda00000000, 0xf285978900000000, - 0xb14e310e00000000, 0x647db3c800000000, 0x27b6154f00000000, - 0xa3ed8f1c00000000, 0xe026299b00000000, 0xab5abbbb00000000, - 0xe8911d3c00000000, 0x6cca876f00000000, 0x2f0121e800000000, - 0x87abf23900000000, 0xc46054be00000000, 0x403bceed00000000, - 0x03f0686a00000000, 0x488cfa4a00000000, 0x0b475ccd00000000, - 0x8f1cc69e00000000, 0xccd7601900000000, 0x19e4e2df00000000, - 0x5a2f445800000000, 0xde74de0b00000000, 0x9dbf788c00000000, - 0xd6c3eaac00000000, 0x95084c2b00000000, 0x1153d67800000000, - 0x529870ff00000000, 0xf465465d00000000, 0xb7aee0da00000000, - 0x33f57a8900000000, 0x703edc0e00000000, 0x3b424e2e00000000, - 0x7889e8a900000000, 0xfcd272fa00000000, 0xbf19d47d00000000, - 0x6a2a56bb00000000, 0x29e1f03c00000000, 0xadba6a6f00000000, - 0xee71cce800000000, 0xa50d5ec800000000, 0xe6c6f84f00000000, - 0x629d621c00000000, 0x2156c49b00000000, 0x89fc174a00000000, - 0xca37b1cd00000000, 0x4e6c2b9e00000000, 0x0da78d1900000000, - 0x46db1f3900000000, 0x0510b9be00000000, 0x814b23ed00000000, - 0xc280856a00000000, 0x17b307ac00000000, 0x5478a12b00000000, - 0xd0233b7800000000, 0x93e89dff00000000, 0xd8940fdf00000000, - 0x9b5fa95800000000, 0x1f04330b00000000, 0x5ccf958c00000000, - 0x0e57e57300000000, 0x4d9c43f400000000, 0xc9c7d9a700000000, - 0x8a0c7f2000000000, 0xc170ed0000000000, 0x82bb4b8700000000, - 0x06e0d1d400000000, 0x452b775300000000, 0x9018f59500000000, - 0xd3d3531200000000, 0x5788c94100000000, 0x14436fc600000000, - 0x5f3ffde600000000, 0x1cf45b6100000000, 0x98afc13200000000, - 0xdb6467b500000000, 0x73ceb46400000000, 0x300512e300000000, - 0xb45e88b000000000, 0xf7952e3700000000, 0xbce9bc1700000000, - 0xff221a9000000000, 0x7b7980c300000000, 0x38b2264400000000, - 0xed81a48200000000, 0xae4a020500000000, 0x2a11985600000000, - 0x69da3ed100000000, 0x22a6acf100000000, 0x616d0a7600000000, - 0xe536902500000000, 0xa6fd36a200000000, 0xe8cb8cba00000000, - 0xab002a3d00000000, 0x2f5bb06e00000000, 0x6c9016e900000000, - 0x27ec84c900000000, 0x6427224e00000000, 0xe07cb81d00000000, - 0xa3b71e9a00000000, 0x76849c5c00000000, 0x354f3adb00000000, - 0xb114a08800000000, 0xf2df060f00000000, 0xb9a3942f00000000, - 0xfa6832a800000000, 0x7e33a8fb00000000, 0x3df80e7c00000000, - 0x9552ddad00000000, 0xd6997b2a00000000, 0x52c2e17900000000, - 0x110947fe00000000, 0x5a75d5de00000000, 0x19be735900000000, - 0x9de5e90a00000000, 0xde2e4f8d00000000, 0x0b1dcd4b00000000, - 0x48d66bcc00000000, 0xcc8df19f00000000, 0x8f46571800000000, - 0xc43ac53800000000, 0x87f163bf00000000, 0x03aaf9ec00000000, - 0x40615f6b00000000, 0x12f92f9400000000, 0x5132891300000000, - 0xd569134000000000, 0x96a2b5c700000000, 0xddde27e700000000, - 0x9e15816000000000, 0x1a4e1b3300000000, 0x5985bdb400000000, - 0x8cb63f7200000000, 0xcf7d99f500000000, 0x4b2603a600000000, - 0x08eda52100000000, 0x4391370100000000, 0x005a918600000000, - 0x84010bd500000000, 0xc7caad5200000000, 0x6f607e8300000000, - 0x2cabd80400000000, 0xa8f0425700000000, 0xeb3be4d000000000, - 0xa04776f000000000, 0xe38cd07700000000, 0x67d74a2400000000, - 0x241ceca300000000, 0xf12f6e6500000000, 0xb2e4c8e200000000, - 0x36bf52b100000000, 0x7574f43600000000, 0x3e08661600000000, - 0x7dc3c09100000000, 0xf9985ac200000000, 0xba53fc4500000000, - 0x1caecae700000000, 0x5f656c6000000000, 0xdb3ef63300000000, - 0x98f550b400000000, 0xd389c29400000000, 0x9042641300000000, - 0x1419fe4000000000, 0x57d258c700000000, 0x82e1da0100000000, - 0xc12a7c8600000000, 0x4571e6d500000000, 0x06ba405200000000, - 0x4dc6d27200000000, 0x0e0d74f500000000, 0x8a56eea600000000, - 0xc99d482100000000, 0x61379bf000000000, 0x22fc3d7700000000, - 0xa6a7a72400000000, 0xe56c01a300000000, 0xae10938300000000, - 0xeddb350400000000, 0x6980af5700000000, 0x2a4b09d000000000, - 0xff788b1600000000, 0xbcb32d9100000000, 0x38e8b7c200000000, - 0x7b23114500000000, 0x305f836500000000, 0x739425e200000000, - 0xf7cfbfb100000000, 0xb404193600000000, 0xe69c69c900000000, - 0xa557cf4e00000000, 0x210c551d00000000, 0x62c7f39a00000000, - 0x29bb61ba00000000, 0x6a70c73d00000000, 0xee2b5d6e00000000, - 0xade0fbe900000000, 0x78d3792f00000000, 0x3b18dfa800000000, - 0xbf4345fb00000000, 0xfc88e37c00000000, 0xb7f4715c00000000, - 0xf43fd7db00000000, 0x70644d8800000000, 0x33afeb0f00000000, - 0x9b0538de00000000, 0xd8ce9e5900000000, 0x5c95040a00000000, - 0x1f5ea28d00000000, 0x542230ad00000000, 0x17e9962a00000000, - 0x93b20c7900000000, 0xd079aafe00000000, 0x054a283800000000, - 0x46818ebf00000000, 0xc2da14ec00000000, 0x8111b26b00000000, - 0xca6d204b00000000, 0x89a686cc00000000, 0x0dfd1c9f00000000, - 0x4e36ba1800000000}, - {0x0000000000000000, 0xe1b652ef00000000, 0x836bd40500000000, - 0x62dd86ea00000000, 0x06d7a80b00000000, 0xe761fae400000000, - 0x85bc7c0e00000000, 0x640a2ee100000000, 0x0cae511700000000, - 0xed1803f800000000, 0x8fc5851200000000, 0x6e73d7fd00000000, - 0x0a79f91c00000000, 0xebcfabf300000000, 0x89122d1900000000, - 0x68a47ff600000000, 0x185ca32e00000000, 0xf9eaf1c100000000, - 0x9b37772b00000000, 0x7a8125c400000000, 0x1e8b0b2500000000, - 0xff3d59ca00000000, 0x9de0df2000000000, 0x7c568dcf00000000, - 0x14f2f23900000000, 0xf544a0d600000000, 0x9799263c00000000, - 0x762f74d300000000, 0x12255a3200000000, 0xf39308dd00000000, - 0x914e8e3700000000, 0x70f8dcd800000000, 0x30b8465d00000000, - 0xd10e14b200000000, 0xb3d3925800000000, 0x5265c0b700000000, - 0x366fee5600000000, 0xd7d9bcb900000000, 0xb5043a5300000000, - 0x54b268bc00000000, 0x3c16174a00000000, 0xdda045a500000000, - 0xbf7dc34f00000000, 0x5ecb91a000000000, 0x3ac1bf4100000000, - 0xdb77edae00000000, 0xb9aa6b4400000000, 0x581c39ab00000000, - 0x28e4e57300000000, 0xc952b79c00000000, 0xab8f317600000000, - 0x4a39639900000000, 0x2e334d7800000000, 0xcf851f9700000000, - 0xad58997d00000000, 0x4ceecb9200000000, 0x244ab46400000000, - 0xc5fce68b00000000, 0xa721606100000000, 0x4697328e00000000, - 0x229d1c6f00000000, 0xc32b4e8000000000, 0xa1f6c86a00000000, - 0x40409a8500000000, 0x60708dba00000000, 0x81c6df5500000000, - 0xe31b59bf00000000, 0x02ad0b5000000000, 0x66a725b100000000, - 0x8711775e00000000, 0xe5ccf1b400000000, 0x047aa35b00000000, - 0x6cdedcad00000000, 0x8d688e4200000000, 0xefb508a800000000, - 0x0e035a4700000000, 0x6a0974a600000000, 0x8bbf264900000000, - 0xe962a0a300000000, 0x08d4f24c00000000, 0x782c2e9400000000, - 0x999a7c7b00000000, 0xfb47fa9100000000, 0x1af1a87e00000000, - 0x7efb869f00000000, 0x9f4dd47000000000, 0xfd90529a00000000, - 0x1c26007500000000, 0x74827f8300000000, 0x95342d6c00000000, - 0xf7e9ab8600000000, 0x165ff96900000000, 0x7255d78800000000, - 0x93e3856700000000, 0xf13e038d00000000, 0x1088516200000000, - 0x50c8cbe700000000, 0xb17e990800000000, 0xd3a31fe200000000, - 0x32154d0d00000000, 0x561f63ec00000000, 0xb7a9310300000000, - 0xd574b7e900000000, 0x34c2e50600000000, 0x5c669af000000000, - 0xbdd0c81f00000000, 0xdf0d4ef500000000, 0x3ebb1c1a00000000, - 0x5ab132fb00000000, 0xbb07601400000000, 0xd9dae6fe00000000, - 0x386cb41100000000, 0x489468c900000000, 0xa9223a2600000000, - 0xcbffbccc00000000, 0x2a49ee2300000000, 0x4e43c0c200000000, - 0xaff5922d00000000, 0xcd2814c700000000, 0x2c9e462800000000, - 0x443a39de00000000, 0xa58c6b3100000000, 0xc751eddb00000000, - 0x26e7bf3400000000, 0x42ed91d500000000, 0xa35bc33a00000000, - 0xc18645d000000000, 0x2030173f00000000, 0x81e66bae00000000, - 0x6050394100000000, 0x028dbfab00000000, 0xe33bed4400000000, - 0x8731c3a500000000, 0x6687914a00000000, 0x045a17a000000000, - 0xe5ec454f00000000, 0x8d483ab900000000, 0x6cfe685600000000, - 0x0e23eebc00000000, 0xef95bc5300000000, 0x8b9f92b200000000, - 0x6a29c05d00000000, 0x08f446b700000000, 0xe942145800000000, - 0x99bac88000000000, 0x780c9a6f00000000, 0x1ad11c8500000000, - 0xfb674e6a00000000, 0x9f6d608b00000000, 0x7edb326400000000, - 0x1c06b48e00000000, 0xfdb0e66100000000, 0x9514999700000000, - 0x74a2cb7800000000, 0x167f4d9200000000, 0xf7c91f7d00000000, - 0x93c3319c00000000, 0x7275637300000000, 0x10a8e59900000000, - 0xf11eb77600000000, 0xb15e2df300000000, 0x50e87f1c00000000, - 0x3235f9f600000000, 0xd383ab1900000000, 0xb78985f800000000, - 0x563fd71700000000, 0x34e251fd00000000, 0xd554031200000000, - 0xbdf07ce400000000, 0x5c462e0b00000000, 0x3e9ba8e100000000, - 0xdf2dfa0e00000000, 0xbb27d4ef00000000, 0x5a91860000000000, - 0x384c00ea00000000, 0xd9fa520500000000, 0xa9028edd00000000, - 0x48b4dc3200000000, 0x2a695ad800000000, 0xcbdf083700000000, - 0xafd526d600000000, 0x4e63743900000000, 0x2cbef2d300000000, - 0xcd08a03c00000000, 0xa5acdfca00000000, 0x441a8d2500000000, - 0x26c70bcf00000000, 0xc771592000000000, 0xa37b77c100000000, - 0x42cd252e00000000, 0x2010a3c400000000, 0xc1a6f12b00000000, - 0xe196e61400000000, 0x0020b4fb00000000, 0x62fd321100000000, - 0x834b60fe00000000, 0xe7414e1f00000000, 0x06f71cf000000000, - 0x642a9a1a00000000, 0x859cc8f500000000, 0xed38b70300000000, - 0x0c8ee5ec00000000, 0x6e53630600000000, 0x8fe531e900000000, - 0xebef1f0800000000, 0x0a594de700000000, 0x6884cb0d00000000, - 0x893299e200000000, 0xf9ca453a00000000, 0x187c17d500000000, - 0x7aa1913f00000000, 0x9b17c3d000000000, 0xff1ded3100000000, - 0x1eabbfde00000000, 0x7c76393400000000, 0x9dc06bdb00000000, - 0xf564142d00000000, 0x14d246c200000000, 0x760fc02800000000, - 0x97b992c700000000, 0xf3b3bc2600000000, 0x1205eec900000000, - 0x70d8682300000000, 0x916e3acc00000000, 0xd12ea04900000000, - 0x3098f2a600000000, 0x5245744c00000000, 0xb3f326a300000000, - 0xd7f9084200000000, 0x364f5aad00000000, 0x5492dc4700000000, - 0xb5248ea800000000, 0xdd80f15e00000000, 0x3c36a3b100000000, - 0x5eeb255b00000000, 0xbf5d77b400000000, 0xdb57595500000000, - 0x3ae10bba00000000, 0x583c8d5000000000, 0xb98adfbf00000000, - 0xc972036700000000, 0x28c4518800000000, 0x4a19d76200000000, - 0xabaf858d00000000, 0xcfa5ab6c00000000, 0x2e13f98300000000, - 0x4cce7f6900000000, 0xad782d8600000000, 0xc5dc527000000000, - 0x246a009f00000000, 0x46b7867500000000, 0xa701d49a00000000, - 0xc30bfa7b00000000, 0x22bda89400000000, 0x40602e7e00000000, - 0xa1d67c9100000000}, - {0x0000000000000000, 0x5880e2d700000000, 0xf106b47400000000, - 0xa98656a300000000, 0xe20d68e900000000, 0xba8d8a3e00000000, - 0x130bdc9d00000000, 0x4b8b3e4a00000000, 0x851da10900000000, - 0xdd9d43de00000000, 0x741b157d00000000, 0x2c9bf7aa00000000, - 0x6710c9e000000000, 0x3f902b3700000000, 0x96167d9400000000, - 0xce969f4300000000, 0x0a3b421300000000, 0x52bba0c400000000, - 0xfb3df66700000000, 0xa3bd14b000000000, 0xe8362afa00000000, - 0xb0b6c82d00000000, 0x19309e8e00000000, 0x41b07c5900000000, - 0x8f26e31a00000000, 0xd7a601cd00000000, 0x7e20576e00000000, - 0x26a0b5b900000000, 0x6d2b8bf300000000, 0x35ab692400000000, - 0x9c2d3f8700000000, 0xc4addd5000000000, 0x1476842600000000, - 0x4cf666f100000000, 0xe570305200000000, 0xbdf0d28500000000, - 0xf67beccf00000000, 0xaefb0e1800000000, 0x077d58bb00000000, - 0x5ffdba6c00000000, 0x916b252f00000000, 0xc9ebc7f800000000, - 0x606d915b00000000, 0x38ed738c00000000, 0x73664dc600000000, - 0x2be6af1100000000, 0x8260f9b200000000, 0xdae01b6500000000, - 0x1e4dc63500000000, 0x46cd24e200000000, 0xef4b724100000000, - 0xb7cb909600000000, 0xfc40aedc00000000, 0xa4c04c0b00000000, - 0x0d461aa800000000, 0x55c6f87f00000000, 0x9b50673c00000000, - 0xc3d085eb00000000, 0x6a56d34800000000, 0x32d6319f00000000, - 0x795d0fd500000000, 0x21dded0200000000, 0x885bbba100000000, - 0xd0db597600000000, 0x28ec084d00000000, 0x706cea9a00000000, - 0xd9eabc3900000000, 0x816a5eee00000000, 0xcae160a400000000, - 0x9261827300000000, 0x3be7d4d000000000, 0x6367360700000000, - 0xadf1a94400000000, 0xf5714b9300000000, 0x5cf71d3000000000, - 0x0477ffe700000000, 0x4ffcc1ad00000000, 0x177c237a00000000, - 0xbefa75d900000000, 0xe67a970e00000000, 0x22d74a5e00000000, - 0x7a57a88900000000, 0xd3d1fe2a00000000, 0x8b511cfd00000000, - 0xc0da22b700000000, 0x985ac06000000000, 0x31dc96c300000000, - 0x695c741400000000, 0xa7caeb5700000000, 0xff4a098000000000, - 0x56cc5f2300000000, 0x0e4cbdf400000000, 0x45c783be00000000, - 0x1d47616900000000, 0xb4c137ca00000000, 0xec41d51d00000000, - 0x3c9a8c6b00000000, 0x641a6ebc00000000, 0xcd9c381f00000000, - 0x951cdac800000000, 0xde97e48200000000, 0x8617065500000000, - 0x2f9150f600000000, 0x7711b22100000000, 0xb9872d6200000000, - 0xe107cfb500000000, 0x4881991600000000, 0x10017bc100000000, - 0x5b8a458b00000000, 0x030aa75c00000000, 0xaa8cf1ff00000000, - 0xf20c132800000000, 0x36a1ce7800000000, 0x6e212caf00000000, - 0xc7a77a0c00000000, 0x9f2798db00000000, 0xd4aca69100000000, - 0x8c2c444600000000, 0x25aa12e500000000, 0x7d2af03200000000, - 0xb3bc6f7100000000, 0xeb3c8da600000000, 0x42badb0500000000, - 0x1a3a39d200000000, 0x51b1079800000000, 0x0931e54f00000000, - 0xa0b7b3ec00000000, 0xf837513b00000000, 0x50d8119a00000000, - 0x0858f34d00000000, 0xa1dea5ee00000000, 0xf95e473900000000, - 0xb2d5797300000000, 0xea559ba400000000, 0x43d3cd0700000000, - 0x1b532fd000000000, 0xd5c5b09300000000, 0x8d45524400000000, - 0x24c304e700000000, 0x7c43e63000000000, 0x37c8d87a00000000, - 0x6f483aad00000000, 0xc6ce6c0e00000000, 0x9e4e8ed900000000, - 0x5ae3538900000000, 0x0263b15e00000000, 0xabe5e7fd00000000, - 0xf365052a00000000, 0xb8ee3b6000000000, 0xe06ed9b700000000, - 0x49e88f1400000000, 0x11686dc300000000, 0xdffef28000000000, - 0x877e105700000000, 0x2ef846f400000000, 0x7678a42300000000, - 0x3df39a6900000000, 0x657378be00000000, 0xccf52e1d00000000, - 0x9475ccca00000000, 0x44ae95bc00000000, 0x1c2e776b00000000, - 0xb5a821c800000000, 0xed28c31f00000000, 0xa6a3fd5500000000, - 0xfe231f8200000000, 0x57a5492100000000, 0x0f25abf600000000, - 0xc1b334b500000000, 0x9933d66200000000, 0x30b580c100000000, - 0x6835621600000000, 0x23be5c5c00000000, 0x7b3ebe8b00000000, - 0xd2b8e82800000000, 0x8a380aff00000000, 0x4e95d7af00000000, - 0x1615357800000000, 0xbf9363db00000000, 0xe713810c00000000, - 0xac98bf4600000000, 0xf4185d9100000000, 0x5d9e0b3200000000, - 0x051ee9e500000000, 0xcb8876a600000000, 0x9308947100000000, - 0x3a8ec2d200000000, 0x620e200500000000, 0x29851e4f00000000, - 0x7105fc9800000000, 0xd883aa3b00000000, 0x800348ec00000000, - 0x783419d700000000, 0x20b4fb0000000000, 0x8932ada300000000, - 0xd1b24f7400000000, 0x9a39713e00000000, 0xc2b993e900000000, - 0x6b3fc54a00000000, 0x33bf279d00000000, 0xfd29b8de00000000, - 0xa5a95a0900000000, 0x0c2f0caa00000000, 0x54afee7d00000000, - 0x1f24d03700000000, 0x47a432e000000000, 0xee22644300000000, - 0xb6a2869400000000, 0x720f5bc400000000, 0x2a8fb91300000000, - 0x8309efb000000000, 0xdb890d6700000000, 0x9002332d00000000, - 0xc882d1fa00000000, 0x6104875900000000, 0x3984658e00000000, - 0xf712facd00000000, 0xaf92181a00000000, 0x06144eb900000000, - 0x5e94ac6e00000000, 0x151f922400000000, 0x4d9f70f300000000, - 0xe419265000000000, 0xbc99c48700000000, 0x6c429df100000000, - 0x34c27f2600000000, 0x9d44298500000000, 0xc5c4cb5200000000, - 0x8e4ff51800000000, 0xd6cf17cf00000000, 0x7f49416c00000000, - 0x27c9a3bb00000000, 0xe95f3cf800000000, 0xb1dfde2f00000000, - 0x1859888c00000000, 0x40d96a5b00000000, 0x0b52541100000000, - 0x53d2b6c600000000, 0xfa54e06500000000, 0xa2d402b200000000, - 0x6679dfe200000000, 0x3ef93d3500000000, 0x977f6b9600000000, - 0xcfff894100000000, 0x8474b70b00000000, 0xdcf455dc00000000, - 0x7572037f00000000, 0x2df2e1a800000000, 0xe3647eeb00000000, - 0xbbe49c3c00000000, 0x1262ca9f00000000, 0x4ae2284800000000, - 0x0169160200000000, 0x59e9f4d500000000, 0xf06fa27600000000, - 0xa8ef40a100000000}, - {0x0000000000000000, 0x463b676500000000, 0x8c76ceca00000000, - 0xca4da9af00000000, 0x59ebed4e00000000, 0x1fd08a2b00000000, - 0xd59d238400000000, 0x93a644e100000000, 0xb2d6db9d00000000, - 0xf4edbcf800000000, 0x3ea0155700000000, 0x789b723200000000, - 0xeb3d36d300000000, 0xad0651b600000000, 0x674bf81900000000, - 0x21709f7c00000000, 0x25abc6e000000000, 0x6390a18500000000, - 0xa9dd082a00000000, 0xefe66f4f00000000, 0x7c402bae00000000, - 0x3a7b4ccb00000000, 0xf036e56400000000, 0xb60d820100000000, - 0x977d1d7d00000000, 0xd1467a1800000000, 0x1b0bd3b700000000, - 0x5d30b4d200000000, 0xce96f03300000000, 0x88ad975600000000, - 0x42e03ef900000000, 0x04db599c00000000, 0x0b50fc1a00000000, - 0x4d6b9b7f00000000, 0x872632d000000000, 0xc11d55b500000000, - 0x52bb115400000000, 0x1480763100000000, 0xdecddf9e00000000, - 0x98f6b8fb00000000, 0xb986278700000000, 0xffbd40e200000000, - 0x35f0e94d00000000, 0x73cb8e2800000000, 0xe06dcac900000000, - 0xa656adac00000000, 0x6c1b040300000000, 0x2a20636600000000, - 0x2efb3afa00000000, 0x68c05d9f00000000, 0xa28df43000000000, - 0xe4b6935500000000, 0x7710d7b400000000, 0x312bb0d100000000, - 0xfb66197e00000000, 0xbd5d7e1b00000000, 0x9c2de16700000000, - 0xda16860200000000, 0x105b2fad00000000, 0x566048c800000000, - 0xc5c60c2900000000, 0x83fd6b4c00000000, 0x49b0c2e300000000, - 0x0f8ba58600000000, 0x16a0f83500000000, 0x509b9f5000000000, - 0x9ad636ff00000000, 0xdced519a00000000, 0x4f4b157b00000000, - 0x0970721e00000000, 0xc33ddbb100000000, 0x8506bcd400000000, - 0xa47623a800000000, 0xe24d44cd00000000, 0x2800ed6200000000, - 0x6e3b8a0700000000, 0xfd9dcee600000000, 0xbba6a98300000000, - 0x71eb002c00000000, 0x37d0674900000000, 0x330b3ed500000000, - 0x753059b000000000, 0xbf7df01f00000000, 0xf946977a00000000, - 0x6ae0d39b00000000, 0x2cdbb4fe00000000, 0xe6961d5100000000, - 0xa0ad7a3400000000, 0x81dde54800000000, 0xc7e6822d00000000, - 0x0dab2b8200000000, 0x4b904ce700000000, 0xd836080600000000, - 0x9e0d6f6300000000, 0x5440c6cc00000000, 0x127ba1a900000000, - 0x1df0042f00000000, 0x5bcb634a00000000, 0x9186cae500000000, - 0xd7bdad8000000000, 0x441be96100000000, 0x02208e0400000000, - 0xc86d27ab00000000, 0x8e5640ce00000000, 0xaf26dfb200000000, - 0xe91db8d700000000, 0x2350117800000000, 0x656b761d00000000, - 0xf6cd32fc00000000, 0xb0f6559900000000, 0x7abbfc3600000000, - 0x3c809b5300000000, 0x385bc2cf00000000, 0x7e60a5aa00000000, - 0xb42d0c0500000000, 0xf2166b6000000000, 0x61b02f8100000000, - 0x278b48e400000000, 0xedc6e14b00000000, 0xabfd862e00000000, - 0x8a8d195200000000, 0xccb67e3700000000, 0x06fbd79800000000, - 0x40c0b0fd00000000, 0xd366f41c00000000, 0x955d937900000000, - 0x5f103ad600000000, 0x192b5db300000000, 0x2c40f16b00000000, - 0x6a7b960e00000000, 0xa0363fa100000000, 0xe60d58c400000000, - 0x75ab1c2500000000, 0x33907b4000000000, 0xf9ddd2ef00000000, - 0xbfe6b58a00000000, 0x9e962af600000000, 0xd8ad4d9300000000, - 0x12e0e43c00000000, 0x54db835900000000, 0xc77dc7b800000000, - 0x8146a0dd00000000, 0x4b0b097200000000, 0x0d306e1700000000, - 0x09eb378b00000000, 0x4fd050ee00000000, 0x859df94100000000, - 0xc3a69e2400000000, 0x5000dac500000000, 0x163bbda000000000, - 0xdc76140f00000000, 0x9a4d736a00000000, 0xbb3dec1600000000, - 0xfd068b7300000000, 0x374b22dc00000000, 0x717045b900000000, - 0xe2d6015800000000, 0xa4ed663d00000000, 0x6ea0cf9200000000, - 0x289ba8f700000000, 0x27100d7100000000, 0x612b6a1400000000, - 0xab66c3bb00000000, 0xed5da4de00000000, 0x7efbe03f00000000, - 0x38c0875a00000000, 0xf28d2ef500000000, 0xb4b6499000000000, - 0x95c6d6ec00000000, 0xd3fdb18900000000, 0x19b0182600000000, - 0x5f8b7f4300000000, 0xcc2d3ba200000000, 0x8a165cc700000000, - 0x405bf56800000000, 0x0660920d00000000, 0x02bbcb9100000000, - 0x4480acf400000000, 0x8ecd055b00000000, 0xc8f6623e00000000, - 0x5b5026df00000000, 0x1d6b41ba00000000, 0xd726e81500000000, - 0x911d8f7000000000, 0xb06d100c00000000, 0xf656776900000000, - 0x3c1bdec600000000, 0x7a20b9a300000000, 0xe986fd4200000000, - 0xafbd9a2700000000, 0x65f0338800000000, 0x23cb54ed00000000, - 0x3ae0095e00000000, 0x7cdb6e3b00000000, 0xb696c79400000000, - 0xf0ada0f100000000, 0x630be41000000000, 0x2530837500000000, - 0xef7d2ada00000000, 0xa9464dbf00000000, 0x8836d2c300000000, - 0xce0db5a600000000, 0x04401c0900000000, 0x427b7b6c00000000, - 0xd1dd3f8d00000000, 0x97e658e800000000, 0x5dabf14700000000, - 0x1b90962200000000, 0x1f4bcfbe00000000, 0x5970a8db00000000, - 0x933d017400000000, 0xd506661100000000, 0x46a022f000000000, - 0x009b459500000000, 0xcad6ec3a00000000, 0x8ced8b5f00000000, - 0xad9d142300000000, 0xeba6734600000000, 0x21ebdae900000000, - 0x67d0bd8c00000000, 0xf476f96d00000000, 0xb24d9e0800000000, - 0x780037a700000000, 0x3e3b50c200000000, 0x31b0f54400000000, - 0x778b922100000000, 0xbdc63b8e00000000, 0xfbfd5ceb00000000, - 0x685b180a00000000, 0x2e607f6f00000000, 0xe42dd6c000000000, - 0xa216b1a500000000, 0x83662ed900000000, 0xc55d49bc00000000, - 0x0f10e01300000000, 0x492b877600000000, 0xda8dc39700000000, - 0x9cb6a4f200000000, 0x56fb0d5d00000000, 0x10c06a3800000000, - 0x141b33a400000000, 0x522054c100000000, 0x986dfd6e00000000, - 0xde569a0b00000000, 0x4df0deea00000000, 0x0bcbb98f00000000, - 0xc186102000000000, 0x87bd774500000000, 0xa6cde83900000000, - 0xe0f68f5c00000000, 0x2abb26f300000000, 0x6c80419600000000, - 0xff26057700000000, 0xb91d621200000000, 0x7350cbbd00000000, - 0x356bacd800000000}, - {0x0000000000000000, 0x9e83da9f00000000, 0x7d01c4e400000000, - 0xe3821e7b00000000, 0xbb04f91200000000, 0x2587238d00000000, - 0xc6053df600000000, 0x5886e76900000000, 0x7609f22500000000, - 0xe88a28ba00000000, 0x0b0836c100000000, 0x958bec5e00000000, - 0xcd0d0b3700000000, 0x538ed1a800000000, 0xb00ccfd300000000, - 0x2e8f154c00000000, 0xec12e44b00000000, 0x72913ed400000000, - 0x911320af00000000, 0x0f90fa3000000000, 0x57161d5900000000, - 0xc995c7c600000000, 0x2a17d9bd00000000, 0xb494032200000000, - 0x9a1b166e00000000, 0x0498ccf100000000, 0xe71ad28a00000000, - 0x7999081500000000, 0x211fef7c00000000, 0xbf9c35e300000000, - 0x5c1e2b9800000000, 0xc29df10700000000, 0xd825c89700000000, - 0x46a6120800000000, 0xa5240c7300000000, 0x3ba7d6ec00000000, - 0x6321318500000000, 0xfda2eb1a00000000, 0x1e20f56100000000, - 0x80a32ffe00000000, 0xae2c3ab200000000, 0x30afe02d00000000, - 0xd32dfe5600000000, 0x4dae24c900000000, 0x1528c3a000000000, - 0x8bab193f00000000, 0x6829074400000000, 0xf6aadddb00000000, - 0x34372cdc00000000, 0xaab4f64300000000, 0x4936e83800000000, - 0xd7b532a700000000, 0x8f33d5ce00000000, 0x11b00f5100000000, - 0xf232112a00000000, 0x6cb1cbb500000000, 0x423edef900000000, - 0xdcbd046600000000, 0x3f3f1a1d00000000, 0xa1bcc08200000000, - 0xf93a27eb00000000, 0x67b9fd7400000000, 0x843be30f00000000, - 0x1ab8399000000000, 0xf14de1f400000000, 0x6fce3b6b00000000, - 0x8c4c251000000000, 0x12cfff8f00000000, 0x4a4918e600000000, - 0xd4cac27900000000, 0x3748dc0200000000, 0xa9cb069d00000000, - 0x874413d100000000, 0x19c7c94e00000000, 0xfa45d73500000000, - 0x64c60daa00000000, 0x3c40eac300000000, 0xa2c3305c00000000, - 0x41412e2700000000, 0xdfc2f4b800000000, 0x1d5f05bf00000000, - 0x83dcdf2000000000, 0x605ec15b00000000, 0xfedd1bc400000000, - 0xa65bfcad00000000, 0x38d8263200000000, 0xdb5a384900000000, - 0x45d9e2d600000000, 0x6b56f79a00000000, 0xf5d52d0500000000, - 0x1657337e00000000, 0x88d4e9e100000000, 0xd0520e8800000000, - 0x4ed1d41700000000, 0xad53ca6c00000000, 0x33d010f300000000, - 0x2968296300000000, 0xb7ebf3fc00000000, 0x5469ed8700000000, - 0xcaea371800000000, 0x926cd07100000000, 0x0cef0aee00000000, - 0xef6d149500000000, 0x71eece0a00000000, 0x5f61db4600000000, - 0xc1e201d900000000, 0x22601fa200000000, 0xbce3c53d00000000, - 0xe465225400000000, 0x7ae6f8cb00000000, 0x9964e6b000000000, - 0x07e73c2f00000000, 0xc57acd2800000000, 0x5bf917b700000000, - 0xb87b09cc00000000, 0x26f8d35300000000, 0x7e7e343a00000000, - 0xe0fdeea500000000, 0x037ff0de00000000, 0x9dfc2a4100000000, - 0xb3733f0d00000000, 0x2df0e59200000000, 0xce72fbe900000000, - 0x50f1217600000000, 0x0877c61f00000000, 0x96f41c8000000000, - 0x757602fb00000000, 0xebf5d86400000000, 0xa39db33200000000, - 0x3d1e69ad00000000, 0xde9c77d600000000, 0x401fad4900000000, - 0x18994a2000000000, 0x861a90bf00000000, 0x65988ec400000000, - 0xfb1b545b00000000, 0xd594411700000000, 0x4b179b8800000000, - 0xa89585f300000000, 0x36165f6c00000000, 0x6e90b80500000000, - 0xf013629a00000000, 0x13917ce100000000, 0x8d12a67e00000000, - 0x4f8f577900000000, 0xd10c8de600000000, 0x328e939d00000000, - 0xac0d490200000000, 0xf48bae6b00000000, 0x6a0874f400000000, - 0x898a6a8f00000000, 0x1709b01000000000, 0x3986a55c00000000, - 0xa7057fc300000000, 0x448761b800000000, 0xda04bb2700000000, - 0x82825c4e00000000, 0x1c0186d100000000, 0xff8398aa00000000, - 0x6100423500000000, 0x7bb87ba500000000, 0xe53ba13a00000000, - 0x06b9bf4100000000, 0x983a65de00000000, 0xc0bc82b700000000, - 0x5e3f582800000000, 0xbdbd465300000000, 0x233e9ccc00000000, - 0x0db1898000000000, 0x9332531f00000000, 0x70b04d6400000000, - 0xee3397fb00000000, 0xb6b5709200000000, 0x2836aa0d00000000, - 0xcbb4b47600000000, 0x55376ee900000000, 0x97aa9fee00000000, - 0x0929457100000000, 0xeaab5b0a00000000, 0x7428819500000000, - 0x2cae66fc00000000, 0xb22dbc6300000000, 0x51afa21800000000, - 0xcf2c788700000000, 0xe1a36dcb00000000, 0x7f20b75400000000, - 0x9ca2a92f00000000, 0x022173b000000000, 0x5aa794d900000000, - 0xc4244e4600000000, 0x27a6503d00000000, 0xb9258aa200000000, - 0x52d052c600000000, 0xcc53885900000000, 0x2fd1962200000000, - 0xb1524cbd00000000, 0xe9d4abd400000000, 0x7757714b00000000, - 0x94d56f3000000000, 0x0a56b5af00000000, 0x24d9a0e300000000, - 0xba5a7a7c00000000, 0x59d8640700000000, 0xc75bbe9800000000, - 0x9fdd59f100000000, 0x015e836e00000000, 0xe2dc9d1500000000, - 0x7c5f478a00000000, 0xbec2b68d00000000, 0x20416c1200000000, - 0xc3c3726900000000, 0x5d40a8f600000000, 0x05c64f9f00000000, - 0x9b45950000000000, 0x78c78b7b00000000, 0xe64451e400000000, - 0xc8cb44a800000000, 0x56489e3700000000, 0xb5ca804c00000000, - 0x2b495ad300000000, 0x73cfbdba00000000, 0xed4c672500000000, - 0x0ece795e00000000, 0x904da3c100000000, 0x8af59a5100000000, - 0x147640ce00000000, 0xf7f45eb500000000, 0x6977842a00000000, - 0x31f1634300000000, 0xaf72b9dc00000000, 0x4cf0a7a700000000, - 0xd2737d3800000000, 0xfcfc687400000000, 0x627fb2eb00000000, - 0x81fdac9000000000, 0x1f7e760f00000000, 0x47f8916600000000, - 0xd97b4bf900000000, 0x3af9558200000000, 0xa47a8f1d00000000, - 0x66e77e1a00000000, 0xf864a48500000000, 0x1be6bafe00000000, - 0x8565606100000000, 0xdde3870800000000, 0x43605d9700000000, - 0xa0e243ec00000000, 0x3e61997300000000, 0x10ee8c3f00000000, - 0x8e6d56a000000000, 0x6def48db00000000, 0xf36c924400000000, - 0xabea752d00000000, 0x3569afb200000000, 0xd6ebb1c900000000, - 0x48686b5600000000}, - {0x0000000000000000, 0xc064281700000000, 0x80c9502e00000000, - 0x40ad783900000000, 0x0093a15c00000000, 0xc0f7894b00000000, - 0x805af17200000000, 0x403ed96500000000, 0x002643b900000000, - 0xc0426bae00000000, 0x80ef139700000000, 0x408b3b8000000000, - 0x00b5e2e500000000, 0xc0d1caf200000000, 0x807cb2cb00000000, - 0x40189adc00000000, 0x414af7a900000000, 0x812edfbe00000000, - 0xc183a78700000000, 0x01e78f9000000000, 0x41d956f500000000, - 0x81bd7ee200000000, 0xc11006db00000000, 0x01742ecc00000000, - 0x416cb41000000000, 0x81089c0700000000, 0xc1a5e43e00000000, - 0x01c1cc2900000000, 0x41ff154c00000000, 0x819b3d5b00000000, - 0xc136456200000000, 0x01526d7500000000, 0xc3929f8800000000, - 0x03f6b79f00000000, 0x435bcfa600000000, 0x833fe7b100000000, - 0xc3013ed400000000, 0x036516c300000000, 0x43c86efa00000000, - 0x83ac46ed00000000, 0xc3b4dc3100000000, 0x03d0f42600000000, - 0x437d8c1f00000000, 0x8319a40800000000, 0xc3277d6d00000000, - 0x0343557a00000000, 0x43ee2d4300000000, 0x838a055400000000, - 0x82d8682100000000, 0x42bc403600000000, 0x0211380f00000000, - 0xc275101800000000, 0x824bc97d00000000, 0x422fe16a00000000, - 0x0282995300000000, 0xc2e6b14400000000, 0x82fe2b9800000000, - 0x429a038f00000000, 0x02377bb600000000, 0xc25353a100000000, - 0x826d8ac400000000, 0x4209a2d300000000, 0x02a4daea00000000, - 0xc2c0f2fd00000000, 0xc7234eca00000000, 0x074766dd00000000, - 0x47ea1ee400000000, 0x878e36f300000000, 0xc7b0ef9600000000, - 0x07d4c78100000000, 0x4779bfb800000000, 0x871d97af00000000, - 0xc7050d7300000000, 0x0761256400000000, 0x47cc5d5d00000000, - 0x87a8754a00000000, 0xc796ac2f00000000, 0x07f2843800000000, - 0x475ffc0100000000, 0x873bd41600000000, 0x8669b96300000000, - 0x460d917400000000, 0x06a0e94d00000000, 0xc6c4c15a00000000, - 0x86fa183f00000000, 0x469e302800000000, 0x0633481100000000, - 0xc657600600000000, 0x864ffada00000000, 0x462bd2cd00000000, - 0x0686aaf400000000, 0xc6e282e300000000, 0x86dc5b8600000000, - 0x46b8739100000000, 0x06150ba800000000, 0xc67123bf00000000, - 0x04b1d14200000000, 0xc4d5f95500000000, 0x8478816c00000000, - 0x441ca97b00000000, 0x0422701e00000000, 0xc446580900000000, - 0x84eb203000000000, 0x448f082700000000, 0x049792fb00000000, - 0xc4f3baec00000000, 0x845ec2d500000000, 0x443aeac200000000, - 0x040433a700000000, 0xc4601bb000000000, 0x84cd638900000000, - 0x44a94b9e00000000, 0x45fb26eb00000000, 0x859f0efc00000000, - 0xc53276c500000000, 0x05565ed200000000, 0x456887b700000000, - 0x850cafa000000000, 0xc5a1d79900000000, 0x05c5ff8e00000000, - 0x45dd655200000000, 0x85b94d4500000000, 0xc514357c00000000, - 0x05701d6b00000000, 0x454ec40e00000000, 0x852aec1900000000, - 0xc587942000000000, 0x05e3bc3700000000, 0xcf41ed4f00000000, - 0x0f25c55800000000, 0x4f88bd6100000000, 0x8fec957600000000, - 0xcfd24c1300000000, 0x0fb6640400000000, 0x4f1b1c3d00000000, - 0x8f7f342a00000000, 0xcf67aef600000000, 0x0f0386e100000000, - 0x4faefed800000000, 0x8fcad6cf00000000, 0xcff40faa00000000, - 0x0f9027bd00000000, 0x4f3d5f8400000000, 0x8f59779300000000, - 0x8e0b1ae600000000, 0x4e6f32f100000000, 0x0ec24ac800000000, - 0xcea662df00000000, 0x8e98bbba00000000, 0x4efc93ad00000000, - 0x0e51eb9400000000, 0xce35c38300000000, 0x8e2d595f00000000, - 0x4e49714800000000, 0x0ee4097100000000, 0xce80216600000000, - 0x8ebef80300000000, 0x4edad01400000000, 0x0e77a82d00000000, - 0xce13803a00000000, 0x0cd372c700000000, 0xccb75ad000000000, - 0x8c1a22e900000000, 0x4c7e0afe00000000, 0x0c40d39b00000000, - 0xcc24fb8c00000000, 0x8c8983b500000000, 0x4cedaba200000000, - 0x0cf5317e00000000, 0xcc91196900000000, 0x8c3c615000000000, - 0x4c58494700000000, 0x0c66902200000000, 0xcc02b83500000000, - 0x8cafc00c00000000, 0x4ccbe81b00000000, 0x4d99856e00000000, - 0x8dfdad7900000000, 0xcd50d54000000000, 0x0d34fd5700000000, - 0x4d0a243200000000, 0x8d6e0c2500000000, 0xcdc3741c00000000, - 0x0da75c0b00000000, 0x4dbfc6d700000000, 0x8ddbeec000000000, - 0xcd7696f900000000, 0x0d12beee00000000, 0x4d2c678b00000000, - 0x8d484f9c00000000, 0xcde537a500000000, 0x0d811fb200000000, - 0x0862a38500000000, 0xc8068b9200000000, 0x88abf3ab00000000, - 0x48cfdbbc00000000, 0x08f102d900000000, 0xc8952ace00000000, - 0x883852f700000000, 0x485c7ae000000000, 0x0844e03c00000000, - 0xc820c82b00000000, 0x888db01200000000, 0x48e9980500000000, - 0x08d7416000000000, 0xc8b3697700000000, 0x881e114e00000000, - 0x487a395900000000, 0x4928542c00000000, 0x894c7c3b00000000, - 0xc9e1040200000000, 0x09852c1500000000, 0x49bbf57000000000, - 0x89dfdd6700000000, 0xc972a55e00000000, 0x09168d4900000000, - 0x490e179500000000, 0x896a3f8200000000, 0xc9c747bb00000000, - 0x09a36fac00000000, 0x499db6c900000000, 0x89f99ede00000000, - 0xc954e6e700000000, 0x0930cef000000000, 0xcbf03c0d00000000, - 0x0b94141a00000000, 0x4b396c2300000000, 0x8b5d443400000000, - 0xcb639d5100000000, 0x0b07b54600000000, 0x4baacd7f00000000, - 0x8bcee56800000000, 0xcbd67fb400000000, 0x0bb257a300000000, - 0x4b1f2f9a00000000, 0x8b7b078d00000000, 0xcb45dee800000000, - 0x0b21f6ff00000000, 0x4b8c8ec600000000, 0x8be8a6d100000000, - 0x8abacba400000000, 0x4adee3b300000000, 0x0a739b8a00000000, - 0xca17b39d00000000, 0x8a296af800000000, 0x4a4d42ef00000000, - 0x0ae03ad600000000, 0xca8412c100000000, 0x8a9c881d00000000, - 0x4af8a00a00000000, 0x0a55d83300000000, 0xca31f02400000000, - 0x8a0f294100000000, 0x4a6b015600000000, 0x0ac6796f00000000, - 0xcaa2517800000000}, - {0x0000000000000000, 0xd4ea739b00000000, 0xe9d396ed00000000, - 0x3d39e57600000000, 0x93a15c0000000000, 0x474b2f9b00000000, - 0x7a72caed00000000, 0xae98b97600000000, 0x2643b90000000000, - 0xf2a9ca9b00000000, 0xcf902fed00000000, 0x1b7a5c7600000000, - 0xb5e2e50000000000, 0x6108969b00000000, 0x5c3173ed00000000, - 0x88db007600000000, 0x4c86720100000000, 0x986c019a00000000, - 0xa555e4ec00000000, 0x71bf977700000000, 0xdf272e0100000000, - 0x0bcd5d9a00000000, 0x36f4b8ec00000000, 0xe21ecb7700000000, - 0x6ac5cb0100000000, 0xbe2fb89a00000000, 0x83165dec00000000, - 0x57fc2e7700000000, 0xf964970100000000, 0x2d8ee49a00000000, - 0x10b701ec00000000, 0xc45d727700000000, 0x980ce50200000000, - 0x4ce6969900000000, 0x71df73ef00000000, 0xa535007400000000, - 0x0badb90200000000, 0xdf47ca9900000000, 0xe27e2fef00000000, - 0x36945c7400000000, 0xbe4f5c0200000000, 0x6aa52f9900000000, - 0x579ccaef00000000, 0x8376b97400000000, 0x2dee000200000000, - 0xf904739900000000, 0xc43d96ef00000000, 0x10d7e57400000000, - 0xd48a970300000000, 0x0060e49800000000, 0x3d5901ee00000000, - 0xe9b3727500000000, 0x472bcb0300000000, 0x93c1b89800000000, - 0xaef85dee00000000, 0x7a122e7500000000, 0xf2c92e0300000000, - 0x26235d9800000000, 0x1b1ab8ee00000000, 0xcff0cb7500000000, - 0x6168720300000000, 0xb582019800000000, 0x88bbe4ee00000000, - 0x5c51977500000000, 0x3019ca0500000000, 0xe4f3b99e00000000, - 0xd9ca5ce800000000, 0x0d202f7300000000, 0xa3b8960500000000, - 0x7752e59e00000000, 0x4a6b00e800000000, 0x9e81737300000000, - 0x165a730500000000, 0xc2b0009e00000000, 0xff89e5e800000000, - 0x2b63967300000000, 0x85fb2f0500000000, 0x51115c9e00000000, - 0x6c28b9e800000000, 0xb8c2ca7300000000, 0x7c9fb80400000000, - 0xa875cb9f00000000, 0x954c2ee900000000, 0x41a65d7200000000, - 0xef3ee40400000000, 0x3bd4979f00000000, 0x06ed72e900000000, - 0xd207017200000000, 0x5adc010400000000, 0x8e36729f00000000, - 0xb30f97e900000000, 0x67e5e47200000000, 0xc97d5d0400000000, - 0x1d972e9f00000000, 0x20aecbe900000000, 0xf444b87200000000, - 0xa8152f0700000000, 0x7cff5c9c00000000, 0x41c6b9ea00000000, - 0x952cca7100000000, 0x3bb4730700000000, 0xef5e009c00000000, - 0xd267e5ea00000000, 0x068d967100000000, 0x8e56960700000000, - 0x5abce59c00000000, 0x678500ea00000000, 0xb36f737100000000, - 0x1df7ca0700000000, 0xc91db99c00000000, 0xf4245cea00000000, - 0x20ce2f7100000000, 0xe4935d0600000000, 0x30792e9d00000000, - 0x0d40cbeb00000000, 0xd9aab87000000000, 0x7732010600000000, - 0xa3d8729d00000000, 0x9ee197eb00000000, 0x4a0be47000000000, - 0xc2d0e40600000000, 0x163a979d00000000, 0x2b0372eb00000000, - 0xffe9017000000000, 0x5171b80600000000, 0x859bcb9d00000000, - 0xb8a22eeb00000000, 0x6c485d7000000000, 0x6032940b00000000, - 0xb4d8e79000000000, 0x89e102e600000000, 0x5d0b717d00000000, - 0xf393c80b00000000, 0x2779bb9000000000, 0x1a405ee600000000, - 0xceaa2d7d00000000, 0x46712d0b00000000, 0x929b5e9000000000, - 0xafa2bbe600000000, 0x7b48c87d00000000, 0xd5d0710b00000000, - 0x013a029000000000, 0x3c03e7e600000000, 0xe8e9947d00000000, - 0x2cb4e60a00000000, 0xf85e959100000000, 0xc56770e700000000, - 0x118d037c00000000, 0xbf15ba0a00000000, 0x6bffc99100000000, - 0x56c62ce700000000, 0x822c5f7c00000000, 0x0af75f0a00000000, - 0xde1d2c9100000000, 0xe324c9e700000000, 0x37ceba7c00000000, - 0x9956030a00000000, 0x4dbc709100000000, 0x708595e700000000, - 0xa46fe67c00000000, 0xf83e710900000000, 0x2cd4029200000000, - 0x11ede7e400000000, 0xc507947f00000000, 0x6b9f2d0900000000, - 0xbf755e9200000000, 0x824cbbe400000000, 0x56a6c87f00000000, - 0xde7dc80900000000, 0x0a97bb9200000000, 0x37ae5ee400000000, - 0xe3442d7f00000000, 0x4ddc940900000000, 0x9936e79200000000, - 0xa40f02e400000000, 0x70e5717f00000000, 0xb4b8030800000000, - 0x6052709300000000, 0x5d6b95e500000000, 0x8981e67e00000000, - 0x27195f0800000000, 0xf3f32c9300000000, 0xcecac9e500000000, - 0x1a20ba7e00000000, 0x92fbba0800000000, 0x4611c99300000000, - 0x7b282ce500000000, 0xafc25f7e00000000, 0x015ae60800000000, - 0xd5b0959300000000, 0xe88970e500000000, 0x3c63037e00000000, - 0x502b5e0e00000000, 0x84c12d9500000000, 0xb9f8c8e300000000, - 0x6d12bb7800000000, 0xc38a020e00000000, 0x1760719500000000, - 0x2a5994e300000000, 0xfeb3e77800000000, 0x7668e70e00000000, - 0xa282949500000000, 0x9fbb71e300000000, 0x4b51027800000000, - 0xe5c9bb0e00000000, 0x3123c89500000000, 0x0c1a2de300000000, - 0xd8f05e7800000000, 0x1cad2c0f00000000, 0xc8475f9400000000, - 0xf57ebae200000000, 0x2194c97900000000, 0x8f0c700f00000000, - 0x5be6039400000000, 0x66dfe6e200000000, 0xb235957900000000, - 0x3aee950f00000000, 0xee04e69400000000, 0xd33d03e200000000, - 0x07d7707900000000, 0xa94fc90f00000000, 0x7da5ba9400000000, - 0x409c5fe200000000, 0x94762c7900000000, 0xc827bb0c00000000, - 0x1ccdc89700000000, 0x21f42de100000000, 0xf51e5e7a00000000, - 0x5b86e70c00000000, 0x8f6c949700000000, 0xb25571e100000000, - 0x66bf027a00000000, 0xee64020c00000000, 0x3a8e719700000000, - 0x07b794e100000000, 0xd35de77a00000000, 0x7dc55e0c00000000, - 0xa92f2d9700000000, 0x9416c8e100000000, 0x40fcbb7a00000000, - 0x84a1c90d00000000, 0x504bba9600000000, 0x6d725fe000000000, - 0xb9982c7b00000000, 0x1700950d00000000, 0xc3eae69600000000, - 0xfed303e000000000, 0x2a39707b00000000, 0xa2e2700d00000000, - 0x7608039600000000, 0x4b31e6e000000000, 0x9fdb957b00000000, - 0x31432c0d00000000, 0xe5a95f9600000000, 0xd890bae000000000, - 0x0c7ac97b00000000}, - {0x0000000000000000, 0x2765258100000000, 0x0fcc3bd900000000, - 0x28a91e5800000000, 0x5f9e066900000000, 0x78fb23e800000000, - 0x50523db000000000, 0x7737183100000000, 0xbe3c0dd200000000, - 0x9959285300000000, 0xb1f0360b00000000, 0x9695138a00000000, - 0xe1a20bbb00000000, 0xc6c72e3a00000000, 0xee6e306200000000, - 0xc90b15e300000000, 0x3d7f6b7f00000000, 0x1a1a4efe00000000, - 0x32b350a600000000, 0x15d6752700000000, 0x62e16d1600000000, - 0x4584489700000000, 0x6d2d56cf00000000, 0x4a48734e00000000, - 0x834366ad00000000, 0xa426432c00000000, 0x8c8f5d7400000000, - 0xabea78f500000000, 0xdcdd60c400000000, 0xfbb8454500000000, - 0xd3115b1d00000000, 0xf4747e9c00000000, 0x7afed6fe00000000, - 0x5d9bf37f00000000, 0x7532ed2700000000, 0x5257c8a600000000, - 0x2560d09700000000, 0x0205f51600000000, 0x2aaceb4e00000000, - 0x0dc9cecf00000000, 0xc4c2db2c00000000, 0xe3a7fead00000000, - 0xcb0ee0f500000000, 0xec6bc57400000000, 0x9b5cdd4500000000, - 0xbc39f8c400000000, 0x9490e69c00000000, 0xb3f5c31d00000000, - 0x4781bd8100000000, 0x60e4980000000000, 0x484d865800000000, - 0x6f28a3d900000000, 0x181fbbe800000000, 0x3f7a9e6900000000, - 0x17d3803100000000, 0x30b6a5b000000000, 0xf9bdb05300000000, - 0xded895d200000000, 0xf6718b8a00000000, 0xd114ae0b00000000, - 0xa623b63a00000000, 0x814693bb00000000, 0xa9ef8de300000000, - 0x8e8aa86200000000, 0xb5fadc2600000000, 0x929ff9a700000000, - 0xba36e7ff00000000, 0x9d53c27e00000000, 0xea64da4f00000000, - 0xcd01ffce00000000, 0xe5a8e19600000000, 0xc2cdc41700000000, - 0x0bc6d1f400000000, 0x2ca3f47500000000, 0x040aea2d00000000, - 0x236fcfac00000000, 0x5458d79d00000000, 0x733df21c00000000, - 0x5b94ec4400000000, 0x7cf1c9c500000000, 0x8885b75900000000, - 0xafe092d800000000, 0x87498c8000000000, 0xa02ca90100000000, - 0xd71bb13000000000, 0xf07e94b100000000, 0xd8d78ae900000000, - 0xffb2af6800000000, 0x36b9ba8b00000000, 0x11dc9f0a00000000, - 0x3975815200000000, 0x1e10a4d300000000, 0x6927bce200000000, - 0x4e42996300000000, 0x66eb873b00000000, 0x418ea2ba00000000, - 0xcf040ad800000000, 0xe8612f5900000000, 0xc0c8310100000000, - 0xe7ad148000000000, 0x909a0cb100000000, 0xb7ff293000000000, - 0x9f56376800000000, 0xb83312e900000000, 0x7138070a00000000, - 0x565d228b00000000, 0x7ef43cd300000000, 0x5991195200000000, - 0x2ea6016300000000, 0x09c324e200000000, 0x216a3aba00000000, - 0x060f1f3b00000000, 0xf27b61a700000000, 0xd51e442600000000, - 0xfdb75a7e00000000, 0xdad27fff00000000, 0xade567ce00000000, - 0x8a80424f00000000, 0xa2295c1700000000, 0x854c799600000000, - 0x4c476c7500000000, 0x6b2249f400000000, 0x438b57ac00000000, - 0x64ee722d00000000, 0x13d96a1c00000000, 0x34bc4f9d00000000, - 0x1c1551c500000000, 0x3b70744400000000, 0x6af5b94d00000000, - 0x4d909ccc00000000, 0x6539829400000000, 0x425ca71500000000, - 0x356bbf2400000000, 0x120e9aa500000000, 0x3aa784fd00000000, - 0x1dc2a17c00000000, 0xd4c9b49f00000000, 0xf3ac911e00000000, - 0xdb058f4600000000, 0xfc60aac700000000, 0x8b57b2f600000000, - 0xac32977700000000, 0x849b892f00000000, 0xa3feacae00000000, - 0x578ad23200000000, 0x70eff7b300000000, 0x5846e9eb00000000, - 0x7f23cc6a00000000, 0x0814d45b00000000, 0x2f71f1da00000000, - 0x07d8ef8200000000, 0x20bdca0300000000, 0xe9b6dfe000000000, - 0xced3fa6100000000, 0xe67ae43900000000, 0xc11fc1b800000000, - 0xb628d98900000000, 0x914dfc0800000000, 0xb9e4e25000000000, - 0x9e81c7d100000000, 0x100b6fb300000000, 0x376e4a3200000000, - 0x1fc7546a00000000, 0x38a271eb00000000, 0x4f9569da00000000, - 0x68f04c5b00000000, 0x4059520300000000, 0x673c778200000000, - 0xae37626100000000, 0x895247e000000000, 0xa1fb59b800000000, - 0x869e7c3900000000, 0xf1a9640800000000, 0xd6cc418900000000, - 0xfe655fd100000000, 0xd9007a5000000000, 0x2d7404cc00000000, - 0x0a11214d00000000, 0x22b83f1500000000, 0x05dd1a9400000000, - 0x72ea02a500000000, 0x558f272400000000, 0x7d26397c00000000, - 0x5a431cfd00000000, 0x9348091e00000000, 0xb42d2c9f00000000, - 0x9c8432c700000000, 0xbbe1174600000000, 0xccd60f7700000000, - 0xebb32af600000000, 0xc31a34ae00000000, 0xe47f112f00000000, - 0xdf0f656b00000000, 0xf86a40ea00000000, 0xd0c35eb200000000, - 0xf7a67b3300000000, 0x8091630200000000, 0xa7f4468300000000, - 0x8f5d58db00000000, 0xa8387d5a00000000, 0x613368b900000000, - 0x46564d3800000000, 0x6eff536000000000, 0x499a76e100000000, - 0x3ead6ed000000000, 0x19c84b5100000000, 0x3161550900000000, - 0x1604708800000000, 0xe2700e1400000000, 0xc5152b9500000000, - 0xedbc35cd00000000, 0xcad9104c00000000, 0xbdee087d00000000, - 0x9a8b2dfc00000000, 0xb22233a400000000, 0x9547162500000000, - 0x5c4c03c600000000, 0x7b29264700000000, 0x5380381f00000000, - 0x74e51d9e00000000, 0x03d205af00000000, 0x24b7202e00000000, - 0x0c1e3e7600000000, 0x2b7b1bf700000000, 0xa5f1b39500000000, - 0x8294961400000000, 0xaa3d884c00000000, 0x8d58adcd00000000, - 0xfa6fb5fc00000000, 0xdd0a907d00000000, 0xf5a38e2500000000, - 0xd2c6aba400000000, 0x1bcdbe4700000000, 0x3ca89bc600000000, - 0x1401859e00000000, 0x3364a01f00000000, 0x4453b82e00000000, - 0x63369daf00000000, 0x4b9f83f700000000, 0x6cfaa67600000000, - 0x988ed8ea00000000, 0xbfebfd6b00000000, 0x9742e33300000000, - 0xb027c6b200000000, 0xc710de8300000000, 0xe075fb0200000000, - 0xc8dce55a00000000, 0xefb9c0db00000000, 0x26b2d53800000000, - 0x01d7f0b900000000, 0x297eeee100000000, 0x0e1bcb6000000000, - 0x792cd35100000000, 0x5e49f6d000000000, 0x76e0e88800000000, - 0x5185cd0900000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, - 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, - 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, - 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, - 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, - 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, - 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, - 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, - 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, - 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, - 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, - 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, - 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, - 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, - 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, - 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, - 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, - 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, - 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, - 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, - 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, - 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, - 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, - 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, - 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, - 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, - 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, - 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, - 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, - 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, - 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, - 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, - 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, - 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, - 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, - 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, - 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, - 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, - 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, - 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, - 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, - 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, - 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, - 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, - 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, - 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, - 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, - 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, - 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, - 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, - 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, - 0x36197165}, - {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, - 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, - 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, - 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, - 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, - 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, - 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, - 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, - 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, - 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, - 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, - 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, - 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, - 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, - 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, - 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, - 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, - 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, - 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, - 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, - 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, - 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, - 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, - 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, - 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, - 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, - 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, - 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, - 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, - 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, - 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, - 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, - 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, - 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, - 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, - 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, - 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, - 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, - 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, - 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, - 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, - 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, - 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, - 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, - 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, - 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, - 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, - 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, - 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, - 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, - 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, - 0x1a3b93aa}, - {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, - 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, - 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, - 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, - 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, - 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, - 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, - 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, - 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, - 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, - 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, - 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, - 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, - 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, - 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, - 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, - 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, - 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, - 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, - 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, - 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, - 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, - 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, - 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, - 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, - 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, - 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, - 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, - 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, - 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, - 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, - 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, - 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, - 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, - 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, - 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, - 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, - 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, - 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, - 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, - 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, - 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, - 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, - 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, - 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, - 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, - 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, - 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, - 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, - 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, - 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, - 0xe147d714}, - {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, - 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, - 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, - 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, - 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, - 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, - 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, - 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, - 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, - 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, - 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, - 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, - 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, - 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, - 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, - 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, - 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, - 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, - 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, - 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, - 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, - 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, - 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, - 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, - 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, - 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, - 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, - 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, - 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, - 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, - 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, - 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, - 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, - 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, - 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, - 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, - 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, - 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, - 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, - 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, - 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, - 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, - 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, - 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, - 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, - 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, - 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, - 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, - 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, - 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, - 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, - 0x494f0c4b}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x43147b17, 0x8628f62e, 0xc53c8d39, 0x0c51ec5d, - 0x4f45974a, 0x8a791a73, 0xc96d6164, 0x18a2d8bb, 0x5bb6a3ac, - 0x9e8a2e95, 0xdd9e5582, 0x14f334e6, 0x57e74ff1, 0x92dbc2c8, - 0xd1cfb9df, 0x7142c0ac, 0x3256bbbb, 0xf76a3682, 0xb47e4d95, - 0x7d132cf1, 0x3e0757e6, 0xfb3bdadf, 0xb82fa1c8, 0x69e01817, - 0x2af46300, 0xefc8ee39, 0xacdc952e, 0x65b1f44a, 0x26a58f5d, - 0xe3990264, 0xa08d7973, 0xa382f182, 0xe0968a95, 0x25aa07ac, - 0x66be7cbb, 0xafd31ddf, 0xecc766c8, 0x29fbebf1, 0x6aef90e6, - 0xbb202939, 0xf834522e, 0x3d08df17, 0x7e1ca400, 0xb771c564, - 0xf465be73, 0x3159334a, 0x724d485d, 0xd2c0312e, 0x91d44a39, - 0x54e8c700, 0x17fcbc17, 0xde91dd73, 0x9d85a664, 0x58b92b5d, - 0x1bad504a, 0xca62e995, 0x89769282, 0x4c4a1fbb, 0x0f5e64ac, - 0xc63305c8, 0x85277edf, 0x401bf3e6, 0x030f88f1, 0x070392de, - 0x4417e9c9, 0x812b64f0, 0xc23f1fe7, 0x0b527e83, 0x48460594, - 0x8d7a88ad, 0xce6ef3ba, 0x1fa14a65, 0x5cb53172, 0x9989bc4b, - 0xda9dc75c, 0x13f0a638, 0x50e4dd2f, 0x95d85016, 0xd6cc2b01, - 0x76415272, 0x35552965, 0xf069a45c, 0xb37ddf4b, 0x7a10be2f, - 0x3904c538, 0xfc384801, 0xbf2c3316, 0x6ee38ac9, 0x2df7f1de, - 0xe8cb7ce7, 0xabdf07f0, 0x62b26694, 0x21a61d83, 0xe49a90ba, - 0xa78eebad, 0xa481635c, 0xe795184b, 0x22a99572, 0x61bdee65, - 0xa8d08f01, 0xebc4f416, 0x2ef8792f, 0x6dec0238, 0xbc23bbe7, - 0xff37c0f0, 0x3a0b4dc9, 0x791f36de, 0xb07257ba, 0xf3662cad, - 0x365aa194, 0x754eda83, 0xd5c3a3f0, 0x96d7d8e7, 0x53eb55de, - 0x10ff2ec9, 0xd9924fad, 0x9a8634ba, 0x5fbab983, 0x1caec294, - 0xcd617b4b, 0x8e75005c, 0x4b498d65, 0x085df672, 0xc1309716, - 0x8224ec01, 0x47186138, 0x040c1a2f, 0x4f005566, 0x0c142e71, - 0xc928a348, 0x8a3cd85f, 0x4351b93b, 0x0045c22c, 0xc5794f15, - 0x866d3402, 0x57a28ddd, 0x14b6f6ca, 0xd18a7bf3, 0x929e00e4, - 0x5bf36180, 0x18e71a97, 0xdddb97ae, 0x9ecfecb9, 0x3e4295ca, - 0x7d56eedd, 0xb86a63e4, 0xfb7e18f3, 0x32137997, 0x71070280, - 0xb43b8fb9, 0xf72ff4ae, 0x26e04d71, 0x65f43666, 0xa0c8bb5f, - 0xe3dcc048, 0x2ab1a12c, 0x69a5da3b, 0xac995702, 0xef8d2c15, - 0xec82a4e4, 0xaf96dff3, 0x6aaa52ca, 0x29be29dd, 0xe0d348b9, - 0xa3c733ae, 0x66fbbe97, 0x25efc580, 0xf4207c5f, 0xb7340748, - 0x72088a71, 0x311cf166, 0xf8719002, 0xbb65eb15, 0x7e59662c, - 0x3d4d1d3b, 0x9dc06448, 0xded41f5f, 0x1be89266, 0x58fce971, - 0x91918815, 0xd285f302, 0x17b97e3b, 0x54ad052c, 0x8562bcf3, - 0xc676c7e4, 0x034a4add, 0x405e31ca, 0x893350ae, 0xca272bb9, - 0x0f1ba680, 0x4c0fdd97, 0x4803c7b8, 0x0b17bcaf, 0xce2b3196, - 0x8d3f4a81, 0x44522be5, 0x074650f2, 0xc27addcb, 0x816ea6dc, - 0x50a11f03, 0x13b56414, 0xd689e92d, 0x959d923a, 0x5cf0f35e, - 0x1fe48849, 0xdad80570, 0x99cc7e67, 0x39410714, 0x7a557c03, - 0xbf69f13a, 0xfc7d8a2d, 0x3510eb49, 0x7604905e, 0xb3381d67, - 0xf02c6670, 0x21e3dfaf, 0x62f7a4b8, 0xa7cb2981, 0xe4df5296, - 0x2db233f2, 0x6ea648e5, 0xab9ac5dc, 0xe88ebecb, 0xeb81363a, - 0xa8954d2d, 0x6da9c014, 0x2ebdbb03, 0xe7d0da67, 0xa4c4a170, - 0x61f82c49, 0x22ec575e, 0xf323ee81, 0xb0379596, 0x750b18af, - 0x361f63b8, 0xff7202dc, 0xbc6679cb, 0x795af4f2, 0x3a4e8fe5, - 0x9ac3f696, 0xd9d78d81, 0x1ceb00b8, 0x5fff7baf, 0x96921acb, - 0xd58661dc, 0x10baece5, 0x53ae97f2, 0x82612e2d, 0xc175553a, - 0x0449d803, 0x475da314, 0x8e30c270, 0xcd24b967, 0x0818345e, - 0x4b0c4f49}, - {0x00000000, 0x3e6bc2ef, 0x3dd0f504, 0x03bb37eb, 0x7aa0eb09, - 0x44cb29e6, 0x47701e0d, 0x791bdce2, 0xf440d713, 0xca2b15fc, - 0xc9902217, 0xf7fbe0f8, 0x8ee03c1a, 0xb08bfef5, 0xb330c91e, - 0x8d5b0bf1, 0xe881ae27, 0xd6ea6cc8, 0xd5515b23, 0xeb3a99cc, - 0x9221452e, 0xac4a87c1, 0xaff1b02a, 0x919a72c5, 0x1cc17934, - 0x22aabbdb, 0x21118c30, 0x1f7a4edf, 0x6661923d, 0x580a50d2, - 0x5bb16739, 0x65daa5d6, 0xd0035d4f, 0xee689fa0, 0xedd3a84b, - 0xd3b86aa4, 0xaaa3b646, 0x94c874a9, 0x97734342, 0xa91881ad, - 0x24438a5c, 0x1a2848b3, 0x19937f58, 0x27f8bdb7, 0x5ee36155, - 0x6088a3ba, 0x63339451, 0x5d5856be, 0x3882f368, 0x06e93187, - 0x0552066c, 0x3b39c483, 0x42221861, 0x7c49da8e, 0x7ff2ed65, - 0x41992f8a, 0xccc2247b, 0xf2a9e694, 0xf112d17f, 0xcf791390, - 0xb662cf72, 0x88090d9d, 0x8bb23a76, 0xb5d9f899, 0xa007ba9e, - 0x9e6c7871, 0x9dd74f9a, 0xa3bc8d75, 0xdaa75197, 0xe4cc9378, - 0xe777a493, 0xd91c667c, 0x54476d8d, 0x6a2caf62, 0x69979889, - 0x57fc5a66, 0x2ee78684, 0x108c446b, 0x13377380, 0x2d5cb16f, - 0x488614b9, 0x76edd656, 0x7556e1bd, 0x4b3d2352, 0x3226ffb0, - 0x0c4d3d5f, 0x0ff60ab4, 0x319dc85b, 0xbcc6c3aa, 0x82ad0145, - 0x811636ae, 0xbf7df441, 0xc66628a3, 0xf80dea4c, 0xfbb6dda7, - 0xc5dd1f48, 0x7004e7d1, 0x4e6f253e, 0x4dd412d5, 0x73bfd03a, - 0x0aa40cd8, 0x34cfce37, 0x3774f9dc, 0x091f3b33, 0x844430c2, - 0xba2ff22d, 0xb994c5c6, 0x87ff0729, 0xfee4dbcb, 0xc08f1924, - 0xc3342ecf, 0xfd5fec20, 0x988549f6, 0xa6ee8b19, 0xa555bcf2, - 0x9b3e7e1d, 0xe225a2ff, 0xdc4e6010, 0xdff557fb, 0xe19e9514, - 0x6cc59ee5, 0x52ae5c0a, 0x51156be1, 0x6f7ea90e, 0x166575ec, - 0x280eb703, 0x2bb580e8, 0x15de4207, 0x010905e6, 0x3f62c709, - 0x3cd9f0e2, 0x02b2320d, 0x7ba9eeef, 0x45c22c00, 0x46791beb, - 0x7812d904, 0xf549d2f5, 0xcb22101a, 0xc89927f1, 0xf6f2e51e, - 0x8fe939fc, 0xb182fb13, 0xb239ccf8, 0x8c520e17, 0xe988abc1, - 0xd7e3692e, 0xd4585ec5, 0xea339c2a, 0x932840c8, 0xad438227, - 0xaef8b5cc, 0x90937723, 0x1dc87cd2, 0x23a3be3d, 0x201889d6, - 0x1e734b39, 0x676897db, 0x59035534, 0x5ab862df, 0x64d3a030, - 0xd10a58a9, 0xef619a46, 0xecdaadad, 0xd2b16f42, 0xabaab3a0, - 0x95c1714f, 0x967a46a4, 0xa811844b, 0x254a8fba, 0x1b214d55, - 0x189a7abe, 0x26f1b851, 0x5fea64b3, 0x6181a65c, 0x623a91b7, - 0x5c515358, 0x398bf68e, 0x07e03461, 0x045b038a, 0x3a30c165, - 0x432b1d87, 0x7d40df68, 0x7efbe883, 0x40902a6c, 0xcdcb219d, - 0xf3a0e372, 0xf01bd499, 0xce701676, 0xb76bca94, 0x8900087b, - 0x8abb3f90, 0xb4d0fd7f, 0xa10ebf78, 0x9f657d97, 0x9cde4a7c, - 0xa2b58893, 0xdbae5471, 0xe5c5969e, 0xe67ea175, 0xd815639a, - 0x554e686b, 0x6b25aa84, 0x689e9d6f, 0x56f55f80, 0x2fee8362, - 0x1185418d, 0x123e7666, 0x2c55b489, 0x498f115f, 0x77e4d3b0, - 0x745fe45b, 0x4a3426b4, 0x332ffa56, 0x0d4438b9, 0x0eff0f52, - 0x3094cdbd, 0xbdcfc64c, 0x83a404a3, 0x801f3348, 0xbe74f1a7, - 0xc76f2d45, 0xf904efaa, 0xfabfd841, 0xc4d41aae, 0x710de237, - 0x4f6620d8, 0x4cdd1733, 0x72b6d5dc, 0x0bad093e, 0x35c6cbd1, - 0x367dfc3a, 0x08163ed5, 0x854d3524, 0xbb26f7cb, 0xb89dc020, - 0x86f602cf, 0xffedde2d, 0xc1861cc2, 0xc23d2b29, 0xfc56e9c6, - 0x998c4c10, 0xa7e78eff, 0xa45cb914, 0x9a377bfb, 0xe32ca719, - 0xdd4765f6, 0xdefc521d, 0xe09790f2, 0x6dcc9b03, 0x53a759ec, - 0x501c6e07, 0x6e77ace8, 0x176c700a, 0x2907b2e5, 0x2abc850e, - 0x14d747e1}, - {0x00000000, 0xc0df8ec1, 0xc1b96c58, 0x0166e299, 0x8273d9b0, - 0x42ac5771, 0x43cab5e8, 0x83153b29, 0x45e1c3ba, 0x853e4d7b, - 0x8458afe2, 0x44872123, 0xc7921a0a, 0x074d94cb, 0x062b7652, - 0xc6f4f893, 0xcbc4f6ae, 0x0b1b786f, 0x0a7d9af6, 0xcaa21437, - 0x49b72f1e, 0x8968a1df, 0x880e4346, 0x48d1cd87, 0x8e253514, - 0x4efabbd5, 0x4f9c594c, 0x8f43d78d, 0x0c56eca4, 0xcc896265, - 0xcdef80fc, 0x0d300e3d, 0xd78f9c86, 0x17501247, 0x1636f0de, - 0xd6e97e1f, 0x55fc4536, 0x9523cbf7, 0x9445296e, 0x549aa7af, - 0x926e5f3c, 0x52b1d1fd, 0x53d73364, 0x9308bda5, 0x101d868c, - 0xd0c2084d, 0xd1a4ead4, 0x117b6415, 0x1c4b6a28, 0xdc94e4e9, - 0xddf20670, 0x1d2d88b1, 0x9e38b398, 0x5ee73d59, 0x5f81dfc0, - 0x9f5e5101, 0x59aaa992, 0x99752753, 0x9813c5ca, 0x58cc4b0b, - 0xdbd97022, 0x1b06fee3, 0x1a601c7a, 0xdabf92bb, 0xef1948d6, - 0x2fc6c617, 0x2ea0248e, 0xee7faa4f, 0x6d6a9166, 0xadb51fa7, - 0xacd3fd3e, 0x6c0c73ff, 0xaaf88b6c, 0x6a2705ad, 0x6b41e734, - 0xab9e69f5, 0x288b52dc, 0xe854dc1d, 0xe9323e84, 0x29edb045, - 0x24ddbe78, 0xe40230b9, 0xe564d220, 0x25bb5ce1, 0xa6ae67c8, - 0x6671e909, 0x67170b90, 0xa7c88551, 0x613c7dc2, 0xa1e3f303, - 0xa085119a, 0x605a9f5b, 0xe34fa472, 0x23902ab3, 0x22f6c82a, - 0xe22946eb, 0x3896d450, 0xf8495a91, 0xf92fb808, 0x39f036c9, - 0xbae50de0, 0x7a3a8321, 0x7b5c61b8, 0xbb83ef79, 0x7d7717ea, - 0xbda8992b, 0xbcce7bb2, 0x7c11f573, 0xff04ce5a, 0x3fdb409b, - 0x3ebda202, 0xfe622cc3, 0xf35222fe, 0x338dac3f, 0x32eb4ea6, - 0xf234c067, 0x7121fb4e, 0xb1fe758f, 0xb0989716, 0x704719d7, - 0xb6b3e144, 0x766c6f85, 0x770a8d1c, 0xb7d503dd, 0x34c038f4, - 0xf41fb635, 0xf57954ac, 0x35a6da6d, 0x9f35e177, 0x5fea6fb6, - 0x5e8c8d2f, 0x9e5303ee, 0x1d4638c7, 0xdd99b606, 0xdcff549f, - 0x1c20da5e, 0xdad422cd, 0x1a0bac0c, 0x1b6d4e95, 0xdbb2c054, - 0x58a7fb7d, 0x987875bc, 0x991e9725, 0x59c119e4, 0x54f117d9, - 0x942e9918, 0x95487b81, 0x5597f540, 0xd682ce69, 0x165d40a8, - 0x173ba231, 0xd7e42cf0, 0x1110d463, 0xd1cf5aa2, 0xd0a9b83b, - 0x107636fa, 0x93630dd3, 0x53bc8312, 0x52da618b, 0x9205ef4a, - 0x48ba7df1, 0x8865f330, 0x890311a9, 0x49dc9f68, 0xcac9a441, - 0x0a162a80, 0x0b70c819, 0xcbaf46d8, 0x0d5bbe4b, 0xcd84308a, - 0xcce2d213, 0x0c3d5cd2, 0x8f2867fb, 0x4ff7e93a, 0x4e910ba3, - 0x8e4e8562, 0x837e8b5f, 0x43a1059e, 0x42c7e707, 0x821869c6, - 0x010d52ef, 0xc1d2dc2e, 0xc0b43eb7, 0x006bb076, 0xc69f48e5, - 0x0640c624, 0x072624bd, 0xc7f9aa7c, 0x44ec9155, 0x84331f94, - 0x8555fd0d, 0x458a73cc, 0x702ca9a1, 0xb0f32760, 0xb195c5f9, - 0x714a4b38, 0xf25f7011, 0x3280fed0, 0x33e61c49, 0xf3399288, - 0x35cd6a1b, 0xf512e4da, 0xf4740643, 0x34ab8882, 0xb7beb3ab, - 0x77613d6a, 0x7607dff3, 0xb6d85132, 0xbbe85f0f, 0x7b37d1ce, - 0x7a513357, 0xba8ebd96, 0x399b86bf, 0xf944087e, 0xf822eae7, - 0x38fd6426, 0xfe099cb5, 0x3ed61274, 0x3fb0f0ed, 0xff6f7e2c, - 0x7c7a4505, 0xbca5cbc4, 0xbdc3295d, 0x7d1ca79c, 0xa7a33527, - 0x677cbbe6, 0x661a597f, 0xa6c5d7be, 0x25d0ec97, 0xe50f6256, - 0xe46980cf, 0x24b60e0e, 0xe242f69d, 0x229d785c, 0x23fb9ac5, - 0xe3241404, 0x60312f2d, 0xa0eea1ec, 0xa1884375, 0x6157cdb4, - 0x6c67c389, 0xacb84d48, 0xaddeafd1, 0x6d012110, 0xee141a39, - 0x2ecb94f8, 0x2fad7661, 0xef72f8a0, 0x29860033, 0xe9598ef2, - 0xe83f6c6b, 0x28e0e2aa, 0xabf5d983, 0x6b2a5742, 0x6a4cb5db, - 0xaa933b1a}, - {0x00000000, 0x6f4ca59b, 0x9f9e3bec, 0xf0d29e77, 0x7f3b0603, - 0x1077a398, 0xe0a53def, 0x8fe99874, 0xfe760c06, 0x913aa99d, - 0x61e837ea, 0x0ea49271, 0x814d0a05, 0xee01af9e, 0x1ed331e9, - 0x719f9472, 0xfced180c, 0x93a1bd97, 0x637323e0, 0x0c3f867b, - 0x83d61e0f, 0xec9abb94, 0x1c4825e3, 0x73048078, 0x029b140a, - 0x6dd7b191, 0x9d052fe6, 0xf2498a7d, 0x7da01209, 0x12ecb792, - 0xe23e29e5, 0x8d728c7e, 0xf8db3118, 0x97979483, 0x67450af4, - 0x0809af6f, 0x87e0371b, 0xe8ac9280, 0x187e0cf7, 0x7732a96c, - 0x06ad3d1e, 0x69e19885, 0x993306f2, 0xf67fa369, 0x79963b1d, - 0x16da9e86, 0xe60800f1, 0x8944a56a, 0x04362914, 0x6b7a8c8f, - 0x9ba812f8, 0xf4e4b763, 0x7b0d2f17, 0x14418a8c, 0xe49314fb, - 0x8bdfb160, 0xfa402512, 0x950c8089, 0x65de1efe, 0x0a92bb65, - 0x857b2311, 0xea37868a, 0x1ae518fd, 0x75a9bd66, 0xf0b76330, - 0x9ffbc6ab, 0x6f2958dc, 0x0065fd47, 0x8f8c6533, 0xe0c0c0a8, - 0x10125edf, 0x7f5efb44, 0x0ec16f36, 0x618dcaad, 0x915f54da, - 0xfe13f141, 0x71fa6935, 0x1eb6ccae, 0xee6452d9, 0x8128f742, - 0x0c5a7b3c, 0x6316dea7, 0x93c440d0, 0xfc88e54b, 0x73617d3f, - 0x1c2dd8a4, 0xecff46d3, 0x83b3e348, 0xf22c773a, 0x9d60d2a1, - 0x6db24cd6, 0x02fee94d, 0x8d177139, 0xe25bd4a2, 0x12894ad5, - 0x7dc5ef4e, 0x086c5228, 0x6720f7b3, 0x97f269c4, 0xf8becc5f, - 0x7757542b, 0x181bf1b0, 0xe8c96fc7, 0x8785ca5c, 0xf61a5e2e, - 0x9956fbb5, 0x698465c2, 0x06c8c059, 0x8921582d, 0xe66dfdb6, - 0x16bf63c1, 0x79f3c65a, 0xf4814a24, 0x9bcdefbf, 0x6b1f71c8, - 0x0453d453, 0x8bba4c27, 0xe4f6e9bc, 0x142477cb, 0x7b68d250, - 0x0af74622, 0x65bbe3b9, 0x95697dce, 0xfa25d855, 0x75cc4021, - 0x1a80e5ba, 0xea527bcd, 0x851ede56, 0xe06fc760, 0x8f2362fb, - 0x7ff1fc8c, 0x10bd5917, 0x9f54c163, 0xf01864f8, 0x00cafa8f, - 0x6f865f14, 0x1e19cb66, 0x71556efd, 0x8187f08a, 0xeecb5511, - 0x6122cd65, 0x0e6e68fe, 0xfebcf689, 0x91f05312, 0x1c82df6c, - 0x73ce7af7, 0x831ce480, 0xec50411b, 0x63b9d96f, 0x0cf57cf4, - 0xfc27e283, 0x936b4718, 0xe2f4d36a, 0x8db876f1, 0x7d6ae886, - 0x12264d1d, 0x9dcfd569, 0xf28370f2, 0x0251ee85, 0x6d1d4b1e, - 0x18b4f678, 0x77f853e3, 0x872acd94, 0xe866680f, 0x678ff07b, - 0x08c355e0, 0xf811cb97, 0x975d6e0c, 0xe6c2fa7e, 0x898e5fe5, - 0x795cc192, 0x16106409, 0x99f9fc7d, 0xf6b559e6, 0x0667c791, - 0x692b620a, 0xe459ee74, 0x8b154bef, 0x7bc7d598, 0x148b7003, - 0x9b62e877, 0xf42e4dec, 0x04fcd39b, 0x6bb07600, 0x1a2fe272, - 0x756347e9, 0x85b1d99e, 0xeafd7c05, 0x6514e471, 0x0a5841ea, - 0xfa8adf9d, 0x95c67a06, 0x10d8a450, 0x7f9401cb, 0x8f469fbc, - 0xe00a3a27, 0x6fe3a253, 0x00af07c8, 0xf07d99bf, 0x9f313c24, - 0xeeaea856, 0x81e20dcd, 0x713093ba, 0x1e7c3621, 0x9195ae55, - 0xfed90bce, 0x0e0b95b9, 0x61473022, 0xec35bc5c, 0x837919c7, - 0x73ab87b0, 0x1ce7222b, 0x930eba5f, 0xfc421fc4, 0x0c9081b3, - 0x63dc2428, 0x1243b05a, 0x7d0f15c1, 0x8ddd8bb6, 0xe2912e2d, - 0x6d78b659, 0x023413c2, 0xf2e68db5, 0x9daa282e, 0xe8039548, - 0x874f30d3, 0x779daea4, 0x18d10b3f, 0x9738934b, 0xf87436d0, - 0x08a6a8a7, 0x67ea0d3c, 0x1675994e, 0x79393cd5, 0x89eba2a2, - 0xe6a70739, 0x694e9f4d, 0x06023ad6, 0xf6d0a4a1, 0x999c013a, - 0x14ee8d44, 0x7ba228df, 0x8b70b6a8, 0xe43c1333, 0x6bd58b47, - 0x04992edc, 0xf44bb0ab, 0x9b071530, 0xea988142, 0x85d424d9, - 0x7506baae, 0x1a4a1f35, 0x95a38741, 0xfaef22da, 0x0a3dbcad, - 0x65711936}}; - -#endif - -#endif - -#if N == 4 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xf1da05aa, 0x38c50d15, 0xc91f08bf, 0x718a1a2a, - 0x80501f80, 0x494f173f, 0xb8951295, 0xe3143454, 0x12ce31fe, - 0xdbd13941, 0x2a0b3ceb, 0x929e2e7e, 0x63442bd4, 0xaa5b236b, - 0x5b8126c1, 0x1d596ee9, 0xec836b43, 0x259c63fc, 0xd4466656, - 0x6cd374c3, 0x9d097169, 0x541679d6, 0xa5cc7c7c, 0xfe4d5abd, - 0x0f975f17, 0xc68857a8, 0x37525202, 0x8fc74097, 0x7e1d453d, - 0xb7024d82, 0x46d84828, 0x3ab2ddd2, 0xcb68d878, 0x0277d0c7, - 0xf3add56d, 0x4b38c7f8, 0xbae2c252, 0x73fdcaed, 0x8227cf47, - 0xd9a6e986, 0x287cec2c, 0xe163e493, 0x10b9e139, 0xa82cf3ac, - 0x59f6f606, 0x90e9feb9, 0x6133fb13, 0x27ebb33b, 0xd631b691, - 0x1f2ebe2e, 0xeef4bb84, 0x5661a911, 0xa7bbacbb, 0x6ea4a404, - 0x9f7ea1ae, 0xc4ff876f, 0x352582c5, 0xfc3a8a7a, 0x0de08fd0, - 0xb5759d45, 0x44af98ef, 0x8db09050, 0x7c6a95fa, 0x7565bba4, - 0x84bfbe0e, 0x4da0b6b1, 0xbc7ab31b, 0x04efa18e, 0xf535a424, - 0x3c2aac9b, 0xcdf0a931, 0x96718ff0, 0x67ab8a5a, 0xaeb482e5, - 0x5f6e874f, 0xe7fb95da, 0x16219070, 0xdf3e98cf, 0x2ee49d65, - 0x683cd54d, 0x99e6d0e7, 0x50f9d858, 0xa123ddf2, 0x19b6cf67, - 0xe86ccacd, 0x2173c272, 0xd0a9c7d8, 0x8b28e119, 0x7af2e4b3, - 0xb3edec0c, 0x4237e9a6, 0xfaa2fb33, 0x0b78fe99, 0xc267f626, - 0x33bdf38c, 0x4fd76676, 0xbe0d63dc, 0x77126b63, 0x86c86ec9, - 0x3e5d7c5c, 0xcf8779f6, 0x06987149, 0xf74274e3, 0xacc35222, - 0x5d195788, 0x94065f37, 0x65dc5a9d, 0xdd494808, 0x2c934da2, - 0xe58c451d, 0x145640b7, 0x528e089f, 0xa3540d35, 0x6a4b058a, - 0x9b910020, 0x230412b5, 0xd2de171f, 0x1bc11fa0, 0xea1b1a0a, - 0xb19a3ccb, 0x40403961, 0x895f31de, 0x78853474, 0xc01026e1, - 0x31ca234b, 0xf8d52bf4, 0x090f2e5e, 0xeacb7748, 0x1b1172e2, - 0xd20e7a5d, 0x23d47ff7, 0x9b416d62, 0x6a9b68c8, 0xa3846077, - 0x525e65dd, 0x09df431c, 0xf80546b6, 0x311a4e09, 0xc0c04ba3, - 0x78555936, 0x898f5c9c, 0x40905423, 0xb14a5189, 0xf79219a1, - 0x06481c0b, 0xcf5714b4, 0x3e8d111e, 0x8618038b, 0x77c20621, - 0xbedd0e9e, 0x4f070b34, 0x14862df5, 0xe55c285f, 0x2c4320e0, - 0xdd99254a, 0x650c37df, 0x94d63275, 0x5dc93aca, 0xac133f60, - 0xd079aa9a, 0x21a3af30, 0xe8bca78f, 0x1966a225, 0xa1f3b0b0, - 0x5029b51a, 0x9936bda5, 0x68ecb80f, 0x336d9ece, 0xc2b79b64, - 0x0ba893db, 0xfa729671, 0x42e784e4, 0xb33d814e, 0x7a2289f1, - 0x8bf88c5b, 0xcd20c473, 0x3cfac1d9, 0xf5e5c966, 0x043fcccc, - 0xbcaade59, 0x4d70dbf3, 0x846fd34c, 0x75b5d6e6, 0x2e34f027, - 0xdfeef58d, 0x16f1fd32, 0xe72bf898, 0x5fbeea0d, 0xae64efa7, - 0x677be718, 0x96a1e2b2, 0x9faeccec, 0x6e74c946, 0xa76bc1f9, - 0x56b1c453, 0xee24d6c6, 0x1ffed36c, 0xd6e1dbd3, 0x273bde79, - 0x7cbaf8b8, 0x8d60fd12, 0x447ff5ad, 0xb5a5f007, 0x0d30e292, - 0xfceae738, 0x35f5ef87, 0xc42fea2d, 0x82f7a205, 0x732da7af, - 0xba32af10, 0x4be8aaba, 0xf37db82f, 0x02a7bd85, 0xcbb8b53a, - 0x3a62b090, 0x61e39651, 0x903993fb, 0x59269b44, 0xa8fc9eee, - 0x10698c7b, 0xe1b389d1, 0x28ac816e, 0xd97684c4, 0xa51c113e, - 0x54c61494, 0x9dd91c2b, 0x6c031981, 0xd4960b14, 0x254c0ebe, - 0xec530601, 0x1d8903ab, 0x4608256a, 0xb7d220c0, 0x7ecd287f, - 0x8f172dd5, 0x37823f40, 0xc6583aea, 0x0f473255, 0xfe9d37ff, - 0xb8457fd7, 0x499f7a7d, 0x808072c2, 0x715a7768, 0xc9cf65fd, - 0x38156057, 0xf10a68e8, 0x00d06d42, 0x5b514b83, 0xaa8b4e29, - 0x63944696, 0x924e433c, 0x2adb51a9, 0xdb015403, 0x121e5cbc, - 0xe3c45916}, - {0x00000000, 0x0ee7e8d1, 0x1dcfd1a2, 0x13283973, 0x3b9fa344, - 0x35784b95, 0x265072e6, 0x28b79a37, 0x773f4688, 0x79d8ae59, - 0x6af0972a, 0x64177ffb, 0x4ca0e5cc, 0x42470d1d, 0x516f346e, - 0x5f88dcbf, 0xee7e8d10, 0xe09965c1, 0xf3b15cb2, 0xfd56b463, - 0xd5e12e54, 0xdb06c685, 0xc82efff6, 0xc6c91727, 0x9941cb98, - 0x97a62349, 0x848e1a3a, 0x8a69f2eb, 0xa2de68dc, 0xac39800d, - 0xbf11b97e, 0xb1f651af, 0x078c1c61, 0x096bf4b0, 0x1a43cdc3, - 0x14a42512, 0x3c13bf25, 0x32f457f4, 0x21dc6e87, 0x2f3b8656, - 0x70b35ae9, 0x7e54b238, 0x6d7c8b4b, 0x639b639a, 0x4b2cf9ad, - 0x45cb117c, 0x56e3280f, 0x5804c0de, 0xe9f29171, 0xe71579a0, - 0xf43d40d3, 0xfadaa802, 0xd26d3235, 0xdc8adae4, 0xcfa2e397, - 0xc1450b46, 0x9ecdd7f9, 0x902a3f28, 0x8302065b, 0x8de5ee8a, - 0xa55274bd, 0xabb59c6c, 0xb89da51f, 0xb67a4dce, 0x0f1838c2, - 0x01ffd013, 0x12d7e960, 0x1c3001b1, 0x34879b86, 0x3a607357, - 0x29484a24, 0x27afa2f5, 0x78277e4a, 0x76c0969b, 0x65e8afe8, - 0x6b0f4739, 0x43b8dd0e, 0x4d5f35df, 0x5e770cac, 0x5090e47d, - 0xe166b5d2, 0xef815d03, 0xfca96470, 0xf24e8ca1, 0xdaf91696, - 0xd41efe47, 0xc736c734, 0xc9d12fe5, 0x9659f35a, 0x98be1b8b, - 0x8b9622f8, 0x8571ca29, 0xadc6501e, 0xa321b8cf, 0xb00981bc, - 0xbeee696d, 0x089424a3, 0x0673cc72, 0x155bf501, 0x1bbc1dd0, - 0x330b87e7, 0x3dec6f36, 0x2ec45645, 0x2023be94, 0x7fab622b, - 0x714c8afa, 0x6264b389, 0x6c835b58, 0x4434c16f, 0x4ad329be, - 0x59fb10cd, 0x571cf81c, 0xe6eaa9b3, 0xe80d4162, 0xfb257811, - 0xf5c290c0, 0xdd750af7, 0xd392e226, 0xc0badb55, 0xce5d3384, - 0x91d5ef3b, 0x9f3207ea, 0x8c1a3e99, 0x82fdd648, 0xaa4a4c7f, - 0xa4ada4ae, 0xb7859ddd, 0xb962750c, 0x1e307184, 0x10d79955, - 0x03ffa026, 0x0d1848f7, 0x25afd2c0, 0x2b483a11, 0x38600362, - 0x3687ebb3, 0x690f370c, 0x67e8dfdd, 0x74c0e6ae, 0x7a270e7f, - 0x52909448, 0x5c777c99, 0x4f5f45ea, 0x41b8ad3b, 0xf04efc94, - 0xfea91445, 0xed812d36, 0xe366c5e7, 0xcbd15fd0, 0xc536b701, - 0xd61e8e72, 0xd8f966a3, 0x8771ba1c, 0x899652cd, 0x9abe6bbe, - 0x9459836f, 0xbcee1958, 0xb209f189, 0xa121c8fa, 0xafc6202b, - 0x19bc6de5, 0x175b8534, 0x0473bc47, 0x0a945496, 0x2223cea1, - 0x2cc42670, 0x3fec1f03, 0x310bf7d2, 0x6e832b6d, 0x6064c3bc, - 0x734cfacf, 0x7dab121e, 0x551c8829, 0x5bfb60f8, 0x48d3598b, - 0x4634b15a, 0xf7c2e0f5, 0xf9250824, 0xea0d3157, 0xe4ead986, - 0xcc5d43b1, 0xc2baab60, 0xd1929213, 0xdf757ac2, 0x80fda67d, - 0x8e1a4eac, 0x9d3277df, 0x93d59f0e, 0xbb620539, 0xb585ede8, - 0xa6add49b, 0xa84a3c4a, 0x11284946, 0x1fcfa197, 0x0ce798e4, - 0x02007035, 0x2ab7ea02, 0x245002d3, 0x37783ba0, 0x399fd371, - 0x66170fce, 0x68f0e71f, 0x7bd8de6c, 0x753f36bd, 0x5d88ac8a, - 0x536f445b, 0x40477d28, 0x4ea095f9, 0xff56c456, 0xf1b12c87, - 0xe29915f4, 0xec7efd25, 0xc4c96712, 0xca2e8fc3, 0xd906b6b0, - 0xd7e15e61, 0x886982de, 0x868e6a0f, 0x95a6537c, 0x9b41bbad, - 0xb3f6219a, 0xbd11c94b, 0xae39f038, 0xa0de18e9, 0x16a45527, - 0x1843bdf6, 0x0b6b8485, 0x058c6c54, 0x2d3bf663, 0x23dc1eb2, - 0x30f427c1, 0x3e13cf10, 0x619b13af, 0x6f7cfb7e, 0x7c54c20d, - 0x72b32adc, 0x5a04b0eb, 0x54e3583a, 0x47cb6149, 0x492c8998, - 0xf8dad837, 0xf63d30e6, 0xe5150995, 0xebf2e144, 0xc3457b73, - 0xcda293a2, 0xde8aaad1, 0xd06d4200, 0x8fe59ebf, 0x8102766e, - 0x922a4f1d, 0x9ccda7cc, 0xb47a3dfb, 0xba9dd52a, 0xa9b5ec59, - 0xa7520488}, - {0x00000000, 0x3c60e308, 0x78c1c610, 0x44a12518, 0xf1838c20, - 0xcde36f28, 0x89424a30, 0xb522a938, 0x38761e01, 0x0416fd09, - 0x40b7d811, 0x7cd73b19, 0xc9f59221, 0xf5957129, 0xb1345431, - 0x8d54b739, 0x70ec3c02, 0x4c8cdf0a, 0x082dfa12, 0x344d191a, - 0x816fb022, 0xbd0f532a, 0xf9ae7632, 0xc5ce953a, 0x489a2203, - 0x74fac10b, 0x305be413, 0x0c3b071b, 0xb919ae23, 0x85794d2b, - 0xc1d86833, 0xfdb88b3b, 0xe1d87804, 0xddb89b0c, 0x9919be14, - 0xa5795d1c, 0x105bf424, 0x2c3b172c, 0x689a3234, 0x54fad13c, - 0xd9ae6605, 0xe5ce850d, 0xa16fa015, 0x9d0f431d, 0x282dea25, - 0x144d092d, 0x50ec2c35, 0x6c8ccf3d, 0x91344406, 0xad54a70e, - 0xe9f58216, 0xd595611e, 0x60b7c826, 0x5cd72b2e, 0x18760e36, - 0x2416ed3e, 0xa9425a07, 0x9522b90f, 0xd1839c17, 0xede37f1f, - 0x58c1d627, 0x64a1352f, 0x20001037, 0x1c60f33f, 0x18c1f649, - 0x24a11541, 0x60003059, 0x5c60d351, 0xe9427a69, 0xd5229961, - 0x9183bc79, 0xade35f71, 0x20b7e848, 0x1cd70b40, 0x58762e58, - 0x6416cd50, 0xd1346468, 0xed548760, 0xa9f5a278, 0x95954170, - 0x682dca4b, 0x544d2943, 0x10ec0c5b, 0x2c8cef53, 0x99ae466b, - 0xa5cea563, 0xe16f807b, 0xdd0f6373, 0x505bd44a, 0x6c3b3742, - 0x289a125a, 0x14faf152, 0xa1d8586a, 0x9db8bb62, 0xd9199e7a, - 0xe5797d72, 0xf9198e4d, 0xc5796d45, 0x81d8485d, 0xbdb8ab55, - 0x089a026d, 0x34fae165, 0x705bc47d, 0x4c3b2775, 0xc16f904c, - 0xfd0f7344, 0xb9ae565c, 0x85ceb554, 0x30ec1c6c, 0x0c8cff64, - 0x482dda7c, 0x744d3974, 0x89f5b24f, 0xb5955147, 0xf134745f, - 0xcd549757, 0x78763e6f, 0x4416dd67, 0x00b7f87f, 0x3cd71b77, - 0xb183ac4e, 0x8de34f46, 0xc9426a5e, 0xf5228956, 0x4000206e, - 0x7c60c366, 0x38c1e67e, 0x04a10576, 0x3183ec92, 0x0de30f9a, - 0x49422a82, 0x7522c98a, 0xc00060b2, 0xfc6083ba, 0xb8c1a6a2, - 0x84a145aa, 0x09f5f293, 0x3595119b, 0x71343483, 0x4d54d78b, - 0xf8767eb3, 0xc4169dbb, 0x80b7b8a3, 0xbcd75bab, 0x416fd090, - 0x7d0f3398, 0x39ae1680, 0x05cef588, 0xb0ec5cb0, 0x8c8cbfb8, - 0xc82d9aa0, 0xf44d79a8, 0x7919ce91, 0x45792d99, 0x01d80881, - 0x3db8eb89, 0x889a42b1, 0xb4faa1b9, 0xf05b84a1, 0xcc3b67a9, - 0xd05b9496, 0xec3b779e, 0xa89a5286, 0x94fab18e, 0x21d818b6, - 0x1db8fbbe, 0x5919dea6, 0x65793dae, 0xe82d8a97, 0xd44d699f, - 0x90ec4c87, 0xac8caf8f, 0x19ae06b7, 0x25cee5bf, 0x616fc0a7, - 0x5d0f23af, 0xa0b7a894, 0x9cd74b9c, 0xd8766e84, 0xe4168d8c, - 0x513424b4, 0x6d54c7bc, 0x29f5e2a4, 0x159501ac, 0x98c1b695, - 0xa4a1559d, 0xe0007085, 0xdc60938d, 0x69423ab5, 0x5522d9bd, - 0x1183fca5, 0x2de31fad, 0x29421adb, 0x1522f9d3, 0x5183dccb, - 0x6de33fc3, 0xd8c196fb, 0xe4a175f3, 0xa00050eb, 0x9c60b3e3, - 0x113404da, 0x2d54e7d2, 0x69f5c2ca, 0x559521c2, 0xe0b788fa, - 0xdcd76bf2, 0x98764eea, 0xa416ade2, 0x59ae26d9, 0x65cec5d1, - 0x216fe0c9, 0x1d0f03c1, 0xa82daaf9, 0x944d49f1, 0xd0ec6ce9, - 0xec8c8fe1, 0x61d838d8, 0x5db8dbd0, 0x1919fec8, 0x25791dc0, - 0x905bb4f8, 0xac3b57f0, 0xe89a72e8, 0xd4fa91e0, 0xc89a62df, - 0xf4fa81d7, 0xb05ba4cf, 0x8c3b47c7, 0x3919eeff, 0x05790df7, - 0x41d828ef, 0x7db8cbe7, 0xf0ec7cde, 0xcc8c9fd6, 0x882dbace, - 0xb44d59c6, 0x016ff0fe, 0x3d0f13f6, 0x79ae36ee, 0x45ced5e6, - 0xb8765edd, 0x8416bdd5, 0xc0b798cd, 0xfcd77bc5, 0x49f5d2fd, - 0x759531f5, 0x313414ed, 0x0d54f7e5, 0x800040dc, 0xbc60a3d4, - 0xf8c186cc, 0xc4a165c4, 0x7183ccfc, 0x4de32ff4, 0x09420aec, - 0x3522e9e4}, - {0x00000000, 0x6307d924, 0xc60fb248, 0xa5086b6c, 0x576e62d1, - 0x3469bbf5, 0x9161d099, 0xf26609bd, 0xaedcc5a2, 0xcddb1c86, - 0x68d377ea, 0x0bd4aece, 0xf9b2a773, 0x9ab57e57, 0x3fbd153b, - 0x5cbacc1f, 0x86c88d05, 0xe5cf5421, 0x40c73f4d, 0x23c0e669, - 0xd1a6efd4, 0xb2a136f0, 0x17a95d9c, 0x74ae84b8, 0x281448a7, - 0x4b139183, 0xee1bfaef, 0x8d1c23cb, 0x7f7a2a76, 0x1c7df352, - 0xb975983e, 0xda72411a, 0xd6e01c4b, 0xb5e7c56f, 0x10efae03, - 0x73e87727, 0x818e7e9a, 0xe289a7be, 0x4781ccd2, 0x248615f6, - 0x783cd9e9, 0x1b3b00cd, 0xbe336ba1, 0xdd34b285, 0x2f52bb38, - 0x4c55621c, 0xe95d0970, 0x8a5ad054, 0x5028914e, 0x332f486a, - 0x96272306, 0xf520fa22, 0x0746f39f, 0x64412abb, 0xc14941d7, - 0xa24e98f3, 0xfef454ec, 0x9df38dc8, 0x38fbe6a4, 0x5bfc3f80, - 0xa99a363d, 0xca9def19, 0x6f958475, 0x0c925d51, 0x76b13ed7, - 0x15b6e7f3, 0xb0be8c9f, 0xd3b955bb, 0x21df5c06, 0x42d88522, - 0xe7d0ee4e, 0x84d7376a, 0xd86dfb75, 0xbb6a2251, 0x1e62493d, - 0x7d659019, 0x8f0399a4, 0xec044080, 0x490c2bec, 0x2a0bf2c8, - 0xf079b3d2, 0x937e6af6, 0x3676019a, 0x5571d8be, 0xa717d103, - 0xc4100827, 0x6118634b, 0x021fba6f, 0x5ea57670, 0x3da2af54, - 0x98aac438, 0xfbad1d1c, 0x09cb14a1, 0x6acccd85, 0xcfc4a6e9, - 0xacc37fcd, 0xa051229c, 0xc356fbb8, 0x665e90d4, 0x055949f0, - 0xf73f404d, 0x94389969, 0x3130f205, 0x52372b21, 0x0e8de73e, - 0x6d8a3e1a, 0xc8825576, 0xab858c52, 0x59e385ef, 0x3ae45ccb, - 0x9fec37a7, 0xfcebee83, 0x2699af99, 0x459e76bd, 0xe0961dd1, - 0x8391c4f5, 0x71f7cd48, 0x12f0146c, 0xb7f87f00, 0xd4ffa624, - 0x88456a3b, 0xeb42b31f, 0x4e4ad873, 0x2d4d0157, 0xdf2b08ea, - 0xbc2cd1ce, 0x1924baa2, 0x7a236386, 0xed627dae, 0x8e65a48a, - 0x2b6dcfe6, 0x486a16c2, 0xba0c1f7f, 0xd90bc65b, 0x7c03ad37, - 0x1f047413, 0x43beb80c, 0x20b96128, 0x85b10a44, 0xe6b6d360, - 0x14d0dadd, 0x77d703f9, 0xd2df6895, 0xb1d8b1b1, 0x6baaf0ab, - 0x08ad298f, 0xada542e3, 0xcea29bc7, 0x3cc4927a, 0x5fc34b5e, - 0xfacb2032, 0x99ccf916, 0xc5763509, 0xa671ec2d, 0x03798741, - 0x607e5e65, 0x921857d8, 0xf11f8efc, 0x5417e590, 0x37103cb4, - 0x3b8261e5, 0x5885b8c1, 0xfd8dd3ad, 0x9e8a0a89, 0x6cec0334, - 0x0febda10, 0xaae3b17c, 0xc9e46858, 0x955ea447, 0xf6597d63, - 0x5351160f, 0x3056cf2b, 0xc230c696, 0xa1371fb2, 0x043f74de, - 0x6738adfa, 0xbd4aece0, 0xde4d35c4, 0x7b455ea8, 0x1842878c, - 0xea248e31, 0x89235715, 0x2c2b3c79, 0x4f2ce55d, 0x13962942, - 0x7091f066, 0xd5999b0a, 0xb69e422e, 0x44f84b93, 0x27ff92b7, - 0x82f7f9db, 0xe1f020ff, 0x9bd34379, 0xf8d49a5d, 0x5ddcf131, - 0x3edb2815, 0xccbd21a8, 0xafbaf88c, 0x0ab293e0, 0x69b54ac4, - 0x350f86db, 0x56085fff, 0xf3003493, 0x9007edb7, 0x6261e40a, - 0x01663d2e, 0xa46e5642, 0xc7698f66, 0x1d1bce7c, 0x7e1c1758, - 0xdb147c34, 0xb813a510, 0x4a75acad, 0x29727589, 0x8c7a1ee5, - 0xef7dc7c1, 0xb3c70bde, 0xd0c0d2fa, 0x75c8b996, 0x16cf60b2, - 0xe4a9690f, 0x87aeb02b, 0x22a6db47, 0x41a10263, 0x4d335f32, - 0x2e348616, 0x8b3ced7a, 0xe83b345e, 0x1a5d3de3, 0x795ae4c7, - 0xdc528fab, 0xbf55568f, 0xe3ef9a90, 0x80e843b4, 0x25e028d8, - 0x46e7f1fc, 0xb481f841, 0xd7862165, 0x728e4a09, 0x1189932d, - 0xcbfbd237, 0xa8fc0b13, 0x0df4607f, 0x6ef3b95b, 0x9c95b0e6, - 0xff9269c2, 0x5a9a02ae, 0x399ddb8a, 0x65271795, 0x0620ceb1, - 0xa328a5dd, 0xc02f7cf9, 0x32497544, 0x514eac60, 0xf446c70c, - 0x97411e28}, - {0x00000000, 0x01b5fd1d, 0x036bfa3a, 0x02de0727, 0x06d7f474, - 0x07620969, 0x05bc0e4e, 0x0409f353, 0x0dafe8e8, 0x0c1a15f5, - 0x0ec412d2, 0x0f71efcf, 0x0b781c9c, 0x0acde181, 0x0813e6a6, - 0x09a61bbb, 0x1b5fd1d0, 0x1aea2ccd, 0x18342bea, 0x1981d6f7, - 0x1d8825a4, 0x1c3dd8b9, 0x1ee3df9e, 0x1f562283, 0x16f03938, - 0x1745c425, 0x159bc302, 0x142e3e1f, 0x1027cd4c, 0x11923051, - 0x134c3776, 0x12f9ca6b, 0x36bfa3a0, 0x370a5ebd, 0x35d4599a, - 0x3461a487, 0x306857d4, 0x31ddaac9, 0x3303adee, 0x32b650f3, - 0x3b104b48, 0x3aa5b655, 0x387bb172, 0x39ce4c6f, 0x3dc7bf3c, - 0x3c724221, 0x3eac4506, 0x3f19b81b, 0x2de07270, 0x2c558f6d, - 0x2e8b884a, 0x2f3e7557, 0x2b378604, 0x2a827b19, 0x285c7c3e, - 0x29e98123, 0x204f9a98, 0x21fa6785, 0x232460a2, 0x22919dbf, - 0x26986eec, 0x272d93f1, 0x25f394d6, 0x244669cb, 0x6d7f4740, - 0x6ccaba5d, 0x6e14bd7a, 0x6fa14067, 0x6ba8b334, 0x6a1d4e29, - 0x68c3490e, 0x6976b413, 0x60d0afa8, 0x616552b5, 0x63bb5592, - 0x620ea88f, 0x66075bdc, 0x67b2a6c1, 0x656ca1e6, 0x64d95cfb, - 0x76209690, 0x77956b8d, 0x754b6caa, 0x74fe91b7, 0x70f762e4, - 0x71429ff9, 0x739c98de, 0x722965c3, 0x7b8f7e78, 0x7a3a8365, - 0x78e48442, 0x7951795f, 0x7d588a0c, 0x7ced7711, 0x7e337036, - 0x7f868d2b, 0x5bc0e4e0, 0x5a7519fd, 0x58ab1eda, 0x591ee3c7, - 0x5d171094, 0x5ca2ed89, 0x5e7ceaae, 0x5fc917b3, 0x566f0c08, - 0x57daf115, 0x5504f632, 0x54b10b2f, 0x50b8f87c, 0x510d0561, - 0x53d30246, 0x5266ff5b, 0x409f3530, 0x412ac82d, 0x43f4cf0a, - 0x42413217, 0x4648c144, 0x47fd3c59, 0x45233b7e, 0x4496c663, - 0x4d30ddd8, 0x4c8520c5, 0x4e5b27e2, 0x4feedaff, 0x4be729ac, - 0x4a52d4b1, 0x488cd396, 0x49392e8b, 0xdafe8e80, 0xdb4b739d, - 0xd99574ba, 0xd82089a7, 0xdc297af4, 0xdd9c87e9, 0xdf4280ce, - 0xdef77dd3, 0xd7516668, 0xd6e49b75, 0xd43a9c52, 0xd58f614f, - 0xd186921c, 0xd0336f01, 0xd2ed6826, 0xd358953b, 0xc1a15f50, - 0xc014a24d, 0xc2caa56a, 0xc37f5877, 0xc776ab24, 0xc6c35639, - 0xc41d511e, 0xc5a8ac03, 0xcc0eb7b8, 0xcdbb4aa5, 0xcf654d82, - 0xced0b09f, 0xcad943cc, 0xcb6cbed1, 0xc9b2b9f6, 0xc80744eb, - 0xec412d20, 0xedf4d03d, 0xef2ad71a, 0xee9f2a07, 0xea96d954, - 0xeb232449, 0xe9fd236e, 0xe848de73, 0xe1eec5c8, 0xe05b38d5, - 0xe2853ff2, 0xe330c2ef, 0xe73931bc, 0xe68ccca1, 0xe452cb86, - 0xe5e7369b, 0xf71efcf0, 0xf6ab01ed, 0xf47506ca, 0xf5c0fbd7, - 0xf1c90884, 0xf07cf599, 0xf2a2f2be, 0xf3170fa3, 0xfab11418, - 0xfb04e905, 0xf9daee22, 0xf86f133f, 0xfc66e06c, 0xfdd31d71, - 0xff0d1a56, 0xfeb8e74b, 0xb781c9c0, 0xb63434dd, 0xb4ea33fa, - 0xb55fcee7, 0xb1563db4, 0xb0e3c0a9, 0xb23dc78e, 0xb3883a93, - 0xba2e2128, 0xbb9bdc35, 0xb945db12, 0xb8f0260f, 0xbcf9d55c, - 0xbd4c2841, 0xbf922f66, 0xbe27d27b, 0xacde1810, 0xad6be50d, - 0xafb5e22a, 0xae001f37, 0xaa09ec64, 0xabbc1179, 0xa962165e, - 0xa8d7eb43, 0xa171f0f8, 0xa0c40de5, 0xa21a0ac2, 0xa3aff7df, - 0xa7a6048c, 0xa613f991, 0xa4cdfeb6, 0xa57803ab, 0x813e6a60, - 0x808b977d, 0x8255905a, 0x83e06d47, 0x87e99e14, 0x865c6309, - 0x8482642e, 0x85379933, 0x8c918288, 0x8d247f95, 0x8ffa78b2, - 0x8e4f85af, 0x8a4676fc, 0x8bf38be1, 0x892d8cc6, 0x889871db, - 0x9a61bbb0, 0x9bd446ad, 0x990a418a, 0x98bfbc97, 0x9cb64fc4, - 0x9d03b2d9, 0x9fddb5fe, 0x9e6848e3, 0x97ce5358, 0x967bae45, - 0x94a5a962, 0x9510547f, 0x9119a72c, 0x90ac5a31, 0x92725d16, - 0x93c7a00b}, - {0x00000000, 0x6e8c1b41, 0xdd183682, 0xb3942dc3, 0x61416b45, - 0x0fcd7004, 0xbc595dc7, 0xd2d54686, 0xc282d68a, 0xac0ecdcb, - 0x1f9ae008, 0x7116fb49, 0xa3c3bdcf, 0xcd4fa68e, 0x7edb8b4d, - 0x1057900c, 0x5e74ab55, 0x30f8b014, 0x836c9dd7, 0xede08696, - 0x3f35c010, 0x51b9db51, 0xe22df692, 0x8ca1edd3, 0x9cf67ddf, - 0xf27a669e, 0x41ee4b5d, 0x2f62501c, 0xfdb7169a, 0x933b0ddb, - 0x20af2018, 0x4e233b59, 0xbce956aa, 0xd2654deb, 0x61f16028, - 0x0f7d7b69, 0xdda83def, 0xb32426ae, 0x00b00b6d, 0x6e3c102c, - 0x7e6b8020, 0x10e79b61, 0xa373b6a2, 0xcdffade3, 0x1f2aeb65, - 0x71a6f024, 0xc232dde7, 0xacbec6a6, 0xe29dfdff, 0x8c11e6be, - 0x3f85cb7d, 0x5109d03c, 0x83dc96ba, 0xed508dfb, 0x5ec4a038, - 0x3048bb79, 0x201f2b75, 0x4e933034, 0xfd071df7, 0x938b06b6, - 0x415e4030, 0x2fd25b71, 0x9c4676b2, 0xf2ca6df3, 0xa2a3ab15, - 0xcc2fb054, 0x7fbb9d97, 0x113786d6, 0xc3e2c050, 0xad6edb11, - 0x1efaf6d2, 0x7076ed93, 0x60217d9f, 0x0ead66de, 0xbd394b1d, - 0xd3b5505c, 0x016016da, 0x6fec0d9b, 0xdc782058, 0xb2f43b19, - 0xfcd70040, 0x925b1b01, 0x21cf36c2, 0x4f432d83, 0x9d966b05, - 0xf31a7044, 0x408e5d87, 0x2e0246c6, 0x3e55d6ca, 0x50d9cd8b, - 0xe34de048, 0x8dc1fb09, 0x5f14bd8f, 0x3198a6ce, 0x820c8b0d, - 0xec80904c, 0x1e4afdbf, 0x70c6e6fe, 0xc352cb3d, 0xadded07c, - 0x7f0b96fa, 0x11878dbb, 0xa213a078, 0xcc9fbb39, 0xdcc82b35, - 0xb2443074, 0x01d01db7, 0x6f5c06f6, 0xbd894070, 0xd3055b31, - 0x609176f2, 0x0e1d6db3, 0x403e56ea, 0x2eb24dab, 0x9d266068, - 0xf3aa7b29, 0x217f3daf, 0x4ff326ee, 0xfc670b2d, 0x92eb106c, - 0x82bc8060, 0xec309b21, 0x5fa4b6e2, 0x3128ada3, 0xe3fdeb25, - 0x8d71f064, 0x3ee5dda7, 0x5069c6e6, 0x9e36506b, 0xf0ba4b2a, - 0x432e66e9, 0x2da27da8, 0xff773b2e, 0x91fb206f, 0x226f0dac, - 0x4ce316ed, 0x5cb486e1, 0x32389da0, 0x81acb063, 0xef20ab22, - 0x3df5eda4, 0x5379f6e5, 0xe0eddb26, 0x8e61c067, 0xc042fb3e, - 0xaecee07f, 0x1d5acdbc, 0x73d6d6fd, 0xa103907b, 0xcf8f8b3a, - 0x7c1ba6f9, 0x1297bdb8, 0x02c02db4, 0x6c4c36f5, 0xdfd81b36, - 0xb1540077, 0x638146f1, 0x0d0d5db0, 0xbe997073, 0xd0156b32, - 0x22df06c1, 0x4c531d80, 0xffc73043, 0x914b2b02, 0x439e6d84, - 0x2d1276c5, 0x9e865b06, 0xf00a4047, 0xe05dd04b, 0x8ed1cb0a, - 0x3d45e6c9, 0x53c9fd88, 0x811cbb0e, 0xef90a04f, 0x5c048d8c, - 0x328896cd, 0x7cabad94, 0x1227b6d5, 0xa1b39b16, 0xcf3f8057, - 0x1deac6d1, 0x7366dd90, 0xc0f2f053, 0xae7eeb12, 0xbe297b1e, - 0xd0a5605f, 0x63314d9c, 0x0dbd56dd, 0xdf68105b, 0xb1e40b1a, - 0x027026d9, 0x6cfc3d98, 0x3c95fb7e, 0x5219e03f, 0xe18dcdfc, - 0x8f01d6bd, 0x5dd4903b, 0x33588b7a, 0x80cca6b9, 0xee40bdf8, - 0xfe172df4, 0x909b36b5, 0x230f1b76, 0x4d830037, 0x9f5646b1, - 0xf1da5df0, 0x424e7033, 0x2cc26b72, 0x62e1502b, 0x0c6d4b6a, - 0xbff966a9, 0xd1757de8, 0x03a03b6e, 0x6d2c202f, 0xdeb80dec, - 0xb03416ad, 0xa06386a1, 0xceef9de0, 0x7d7bb023, 0x13f7ab62, - 0xc122ede4, 0xafaef6a5, 0x1c3adb66, 0x72b6c027, 0x807cadd4, - 0xeef0b695, 0x5d649b56, 0x33e88017, 0xe13dc691, 0x8fb1ddd0, - 0x3c25f013, 0x52a9eb52, 0x42fe7b5e, 0x2c72601f, 0x9fe64ddc, - 0xf16a569d, 0x23bf101b, 0x4d330b5a, 0xfea72699, 0x902b3dd8, - 0xde080681, 0xb0841dc0, 0x03103003, 0x6d9c2b42, 0xbf496dc4, - 0xd1c57685, 0x62515b46, 0x0cdd4007, 0x1c8ad00b, 0x7206cb4a, - 0xc192e689, 0xaf1efdc8, 0x7dcbbb4e, 0x1347a00f, 0xa0d38dcc, - 0xce5f968d}, - {0x00000000, 0xe71da697, 0x154a4b6f, 0xf257edf8, 0x2a9496de, - 0xcd893049, 0x3fdeddb1, 0xd8c37b26, 0x55292dbc, 0xb2348b2b, - 0x406366d3, 0xa77ec044, 0x7fbdbb62, 0x98a01df5, 0x6af7f00d, - 0x8dea569a, 0xaa525b78, 0x4d4ffdef, 0xbf181017, 0x5805b680, - 0x80c6cda6, 0x67db6b31, 0x958c86c9, 0x7291205e, 0xff7b76c4, - 0x1866d053, 0xea313dab, 0x0d2c9b3c, 0xd5efe01a, 0x32f2468d, - 0xc0a5ab75, 0x27b80de2, 0x8fd5b0b1, 0x68c81626, 0x9a9ffbde, - 0x7d825d49, 0xa541266f, 0x425c80f8, 0xb00b6d00, 0x5716cb97, - 0xdafc9d0d, 0x3de13b9a, 0xcfb6d662, 0x28ab70f5, 0xf0680bd3, - 0x1775ad44, 0xe52240bc, 0x023fe62b, 0x2587ebc9, 0xc29a4d5e, - 0x30cda0a6, 0xd7d00631, 0x0f137d17, 0xe80edb80, 0x1a593678, - 0xfd4490ef, 0x70aec675, 0x97b360e2, 0x65e48d1a, 0x82f92b8d, - 0x5a3a50ab, 0xbd27f63c, 0x4f701bc4, 0xa86dbd53, 0xc4da6723, - 0x23c7c1b4, 0xd1902c4c, 0x368d8adb, 0xee4ef1fd, 0x0953576a, - 0xfb04ba92, 0x1c191c05, 0x91f34a9f, 0x76eeec08, 0x84b901f0, - 0x63a4a767, 0xbb67dc41, 0x5c7a7ad6, 0xae2d972e, 0x493031b9, - 0x6e883c5b, 0x89959acc, 0x7bc27734, 0x9cdfd1a3, 0x441caa85, - 0xa3010c12, 0x5156e1ea, 0xb64b477d, 0x3ba111e7, 0xdcbcb770, - 0x2eeb5a88, 0xc9f6fc1f, 0x11358739, 0xf62821ae, 0x047fcc56, - 0xe3626ac1, 0x4b0fd792, 0xac127105, 0x5e459cfd, 0xb9583a6a, - 0x619b414c, 0x8686e7db, 0x74d10a23, 0x93ccacb4, 0x1e26fa2e, - 0xf93b5cb9, 0x0b6cb141, 0xec7117d6, 0x34b26cf0, 0xd3afca67, - 0x21f8279f, 0xc6e58108, 0xe15d8cea, 0x06402a7d, 0xf417c785, - 0x130a6112, 0xcbc91a34, 0x2cd4bca3, 0xde83515b, 0x399ef7cc, - 0xb474a156, 0x536907c1, 0xa13eea39, 0x46234cae, 0x9ee03788, - 0x79fd911f, 0x8baa7ce7, 0x6cb7da70, 0x52c5c807, 0xb5d86e90, - 0x478f8368, 0xa09225ff, 0x78515ed9, 0x9f4cf84e, 0x6d1b15b6, - 0x8a06b321, 0x07ece5bb, 0xe0f1432c, 0x12a6aed4, 0xf5bb0843, - 0x2d787365, 0xca65d5f2, 0x3832380a, 0xdf2f9e9d, 0xf897937f, - 0x1f8a35e8, 0xedddd810, 0x0ac07e87, 0xd20305a1, 0x351ea336, - 0xc7494ece, 0x2054e859, 0xadbebec3, 0x4aa31854, 0xb8f4f5ac, - 0x5fe9533b, 0x872a281d, 0x60378e8a, 0x92606372, 0x757dc5e5, - 0xdd1078b6, 0x3a0dde21, 0xc85a33d9, 0x2f47954e, 0xf784ee68, - 0x109948ff, 0xe2cea507, 0x05d30390, 0x8839550a, 0x6f24f39d, - 0x9d731e65, 0x7a6eb8f2, 0xa2adc3d4, 0x45b06543, 0xb7e788bb, - 0x50fa2e2c, 0x774223ce, 0x905f8559, 0x620868a1, 0x8515ce36, - 0x5dd6b510, 0xbacb1387, 0x489cfe7f, 0xaf8158e8, 0x226b0e72, - 0xc576a8e5, 0x3721451d, 0xd03ce38a, 0x08ff98ac, 0xefe23e3b, - 0x1db5d3c3, 0xfaa87554, 0x961faf24, 0x710209b3, 0x8355e44b, - 0x644842dc, 0xbc8b39fa, 0x5b969f6d, 0xa9c17295, 0x4edcd402, - 0xc3368298, 0x242b240f, 0xd67cc9f7, 0x31616f60, 0xe9a21446, - 0x0ebfb2d1, 0xfce85f29, 0x1bf5f9be, 0x3c4df45c, 0xdb5052cb, - 0x2907bf33, 0xce1a19a4, 0x16d96282, 0xf1c4c415, 0x039329ed, - 0xe48e8f7a, 0x6964d9e0, 0x8e797f77, 0x7c2e928f, 0x9b333418, - 0x43f04f3e, 0xa4ede9a9, 0x56ba0451, 0xb1a7a2c6, 0x19ca1f95, - 0xfed7b902, 0x0c8054fa, 0xeb9df26d, 0x335e894b, 0xd4432fdc, - 0x2614c224, 0xc10964b3, 0x4ce33229, 0xabfe94be, 0x59a97946, - 0xbeb4dfd1, 0x6677a4f7, 0x816a0260, 0x733def98, 0x9420490f, - 0xb39844ed, 0x5485e27a, 0xa6d20f82, 0x41cfa915, 0x990cd233, - 0x7e1174a4, 0x8c46995c, 0x6b5b3fcb, 0xe6b16951, 0x01accfc6, - 0xf3fb223e, 0x14e684a9, 0xcc25ff8f, 0x2b385918, 0xd96fb4e0, - 0x3e721277}, - {0x00000000, 0xa58b900e, 0x9066265d, 0x35edb653, 0xfbbd4afb, - 0x5e36daf5, 0x6bdb6ca6, 0xce50fca8, 0x2c0b93b7, 0x898003b9, - 0xbc6db5ea, 0x19e625e4, 0xd7b6d94c, 0x723d4942, 0x47d0ff11, - 0xe25b6f1f, 0x5817276e, 0xfd9cb760, 0xc8710133, 0x6dfa913d, - 0xa3aa6d95, 0x0621fd9b, 0x33cc4bc8, 0x9647dbc6, 0x741cb4d9, - 0xd19724d7, 0xe47a9284, 0x41f1028a, 0x8fa1fe22, 0x2a2a6e2c, - 0x1fc7d87f, 0xba4c4871, 0xb02e4edc, 0x15a5ded2, 0x20486881, - 0x85c3f88f, 0x4b930427, 0xee189429, 0xdbf5227a, 0x7e7eb274, - 0x9c25dd6b, 0x39ae4d65, 0x0c43fb36, 0xa9c86b38, 0x67989790, - 0xc213079e, 0xf7feb1cd, 0x527521c3, 0xe83969b2, 0x4db2f9bc, - 0x785f4fef, 0xddd4dfe1, 0x13842349, 0xb60fb347, 0x83e20514, - 0x2669951a, 0xc432fa05, 0x61b96a0b, 0x5454dc58, 0xf1df4c56, - 0x3f8fb0fe, 0x9a0420f0, 0xafe996a3, 0x0a6206ad, 0xbb2d9bf9, - 0x1ea60bf7, 0x2b4bbda4, 0x8ec02daa, 0x4090d102, 0xe51b410c, - 0xd0f6f75f, 0x757d6751, 0x9726084e, 0x32ad9840, 0x07402e13, - 0xa2cbbe1d, 0x6c9b42b5, 0xc910d2bb, 0xfcfd64e8, 0x5976f4e6, - 0xe33abc97, 0x46b12c99, 0x735c9aca, 0xd6d70ac4, 0x1887f66c, - 0xbd0c6662, 0x88e1d031, 0x2d6a403f, 0xcf312f20, 0x6ababf2e, - 0x5f57097d, 0xfadc9973, 0x348c65db, 0x9107f5d5, 0xa4ea4386, - 0x0161d388, 0x0b03d525, 0xae88452b, 0x9b65f378, 0x3eee6376, - 0xf0be9fde, 0x55350fd0, 0x60d8b983, 0xc553298d, 0x27084692, - 0x8283d69c, 0xb76e60cf, 0x12e5f0c1, 0xdcb50c69, 0x793e9c67, - 0x4cd32a34, 0xe958ba3a, 0x5314f24b, 0xf69f6245, 0xc372d416, - 0x66f94418, 0xa8a9b8b0, 0x0d2228be, 0x38cf9eed, 0x9d440ee3, - 0x7f1f61fc, 0xda94f1f2, 0xef7947a1, 0x4af2d7af, 0x84a22b07, - 0x2129bb09, 0x14c40d5a, 0xb14f9d54, 0xad2a31b3, 0x08a1a1bd, - 0x3d4c17ee, 0x98c787e0, 0x56977b48, 0xf31ceb46, 0xc6f15d15, - 0x637acd1b, 0x8121a204, 0x24aa320a, 0x11478459, 0xb4cc1457, - 0x7a9ce8ff, 0xdf1778f1, 0xeafacea2, 0x4f715eac, 0xf53d16dd, - 0x50b686d3, 0x655b3080, 0xc0d0a08e, 0x0e805c26, 0xab0bcc28, - 0x9ee67a7b, 0x3b6dea75, 0xd936856a, 0x7cbd1564, 0x4950a337, - 0xecdb3339, 0x228bcf91, 0x87005f9f, 0xb2ede9cc, 0x176679c2, - 0x1d047f6f, 0xb88fef61, 0x8d625932, 0x28e9c93c, 0xe6b93594, - 0x4332a59a, 0x76df13c9, 0xd35483c7, 0x310fecd8, 0x94847cd6, - 0xa169ca85, 0x04e25a8b, 0xcab2a623, 0x6f39362d, 0x5ad4807e, - 0xff5f1070, 0x45135801, 0xe098c80f, 0xd5757e5c, 0x70feee52, - 0xbeae12fa, 0x1b2582f4, 0x2ec834a7, 0x8b43a4a9, 0x6918cbb6, - 0xcc935bb8, 0xf97eedeb, 0x5cf57de5, 0x92a5814d, 0x372e1143, - 0x02c3a710, 0xa748371e, 0x1607aa4a, 0xb38c3a44, 0x86618c17, - 0x23ea1c19, 0xedbae0b1, 0x483170bf, 0x7ddcc6ec, 0xd85756e2, - 0x3a0c39fd, 0x9f87a9f3, 0xaa6a1fa0, 0x0fe18fae, 0xc1b17306, - 0x643ae308, 0x51d7555b, 0xf45cc555, 0x4e108d24, 0xeb9b1d2a, - 0xde76ab79, 0x7bfd3b77, 0xb5adc7df, 0x102657d1, 0x25cbe182, - 0x8040718c, 0x621b1e93, 0xc7908e9d, 0xf27d38ce, 0x57f6a8c0, - 0x99a65468, 0x3c2dc466, 0x09c07235, 0xac4be23b, 0xa629e496, - 0x03a27498, 0x364fc2cb, 0x93c452c5, 0x5d94ae6d, 0xf81f3e63, - 0xcdf28830, 0x6879183e, 0x8a227721, 0x2fa9e72f, 0x1a44517c, - 0xbfcfc172, 0x719f3dda, 0xd414add4, 0xe1f91b87, 0x44728b89, - 0xfe3ec3f8, 0x5bb553f6, 0x6e58e5a5, 0xcbd375ab, 0x05838903, - 0xa008190d, 0x95e5af5e, 0x306e3f50, 0xd235504f, 0x77bec041, - 0x42537612, 0xe7d8e61c, 0x29881ab4, 0x8c038aba, 0xb9ee3ce9, - 0x1c65ace7}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x0e908ba500000000, 0x5d26669000000000, - 0x53b6ed3500000000, 0xfb4abdfb00000000, 0xf5da365e00000000, - 0xa66cdb6b00000000, 0xa8fc50ce00000000, 0xb7930b2c00000000, - 0xb903808900000000, 0xeab56dbc00000000, 0xe425e61900000000, - 0x4cd9b6d700000000, 0x42493d7200000000, 0x11ffd04700000000, - 0x1f6f5be200000000, 0x6e27175800000000, 0x60b79cfd00000000, - 0x330171c800000000, 0x3d91fa6d00000000, 0x956daaa300000000, - 0x9bfd210600000000, 0xc84bcc3300000000, 0xc6db479600000000, - 0xd9b41c7400000000, 0xd72497d100000000, 0x84927ae400000000, - 0x8a02f14100000000, 0x22fea18f00000000, 0x2c6e2a2a00000000, - 0x7fd8c71f00000000, 0x71484cba00000000, 0xdc4e2eb000000000, - 0xd2dea51500000000, 0x8168482000000000, 0x8ff8c38500000000, - 0x2704934b00000000, 0x299418ee00000000, 0x7a22f5db00000000, - 0x74b27e7e00000000, 0x6bdd259c00000000, 0x654dae3900000000, - 0x36fb430c00000000, 0x386bc8a900000000, 0x9097986700000000, - 0x9e0713c200000000, 0xcdb1fef700000000, 0xc321755200000000, - 0xb26939e800000000, 0xbcf9b24d00000000, 0xef4f5f7800000000, - 0xe1dfd4dd00000000, 0x4923841300000000, 0x47b30fb600000000, - 0x1405e28300000000, 0x1a95692600000000, 0x05fa32c400000000, - 0x0b6ab96100000000, 0x58dc545400000000, 0x564cdff100000000, - 0xfeb08f3f00000000, 0xf020049a00000000, 0xa396e9af00000000, - 0xad06620a00000000, 0xf99b2dbb00000000, 0xf70ba61e00000000, - 0xa4bd4b2b00000000, 0xaa2dc08e00000000, 0x02d1904000000000, - 0x0c411be500000000, 0x5ff7f6d000000000, 0x51677d7500000000, - 0x4e08269700000000, 0x4098ad3200000000, 0x132e400700000000, - 0x1dbecba200000000, 0xb5429b6c00000000, 0xbbd210c900000000, - 0xe864fdfc00000000, 0xe6f4765900000000, 0x97bc3ae300000000, - 0x992cb14600000000, 0xca9a5c7300000000, 0xc40ad7d600000000, - 0x6cf6871800000000, 0x62660cbd00000000, 0x31d0e18800000000, - 0x3f406a2d00000000, 0x202f31cf00000000, 0x2ebfba6a00000000, - 0x7d09575f00000000, 0x7399dcfa00000000, 0xdb658c3400000000, - 0xd5f5079100000000, 0x8643eaa400000000, 0x88d3610100000000, - 0x25d5030b00000000, 0x2b4588ae00000000, 0x78f3659b00000000, - 0x7663ee3e00000000, 0xde9fbef000000000, 0xd00f355500000000, - 0x83b9d86000000000, 0x8d2953c500000000, 0x9246082700000000, - 0x9cd6838200000000, 0xcf606eb700000000, 0xc1f0e51200000000, - 0x690cb5dc00000000, 0x679c3e7900000000, 0x342ad34c00000000, - 0x3aba58e900000000, 0x4bf2145300000000, 0x45629ff600000000, - 0x16d472c300000000, 0x1844f96600000000, 0xb0b8a9a800000000, - 0xbe28220d00000000, 0xed9ecf3800000000, 0xe30e449d00000000, - 0xfc611f7f00000000, 0xf2f194da00000000, 0xa14779ef00000000, - 0xafd7f24a00000000, 0x072ba28400000000, 0x09bb292100000000, - 0x5a0dc41400000000, 0x549d4fb100000000, 0xb3312aad00000000, - 0xbda1a10800000000, 0xee174c3d00000000, 0xe087c79800000000, - 0x487b975600000000, 0x46eb1cf300000000, 0x155df1c600000000, - 0x1bcd7a6300000000, 0x04a2218100000000, 0x0a32aa2400000000, - 0x5984471100000000, 0x5714ccb400000000, 0xffe89c7a00000000, - 0xf17817df00000000, 0xa2cefaea00000000, 0xac5e714f00000000, - 0xdd163df500000000, 0xd386b65000000000, 0x80305b6500000000, - 0x8ea0d0c000000000, 0x265c800e00000000, 0x28cc0bab00000000, - 0x7b7ae69e00000000, 0x75ea6d3b00000000, 0x6a8536d900000000, - 0x6415bd7c00000000, 0x37a3504900000000, 0x3933dbec00000000, - 0x91cf8b2200000000, 0x9f5f008700000000, 0xcce9edb200000000, - 0xc279661700000000, 0x6f7f041d00000000, 0x61ef8fb800000000, - 0x3259628d00000000, 0x3cc9e92800000000, 0x9435b9e600000000, - 0x9aa5324300000000, 0xc913df7600000000, 0xc78354d300000000, - 0xd8ec0f3100000000, 0xd67c849400000000, 0x85ca69a100000000, - 0x8b5ae20400000000, 0x23a6b2ca00000000, 0x2d36396f00000000, - 0x7e80d45a00000000, 0x70105fff00000000, 0x0158134500000000, - 0x0fc898e000000000, 0x5c7e75d500000000, 0x52eefe7000000000, - 0xfa12aebe00000000, 0xf482251b00000000, 0xa734c82e00000000, - 0xa9a4438b00000000, 0xb6cb186900000000, 0xb85b93cc00000000, - 0xebed7ef900000000, 0xe57df55c00000000, 0x4d81a59200000000, - 0x43112e3700000000, 0x10a7c30200000000, 0x1e3748a700000000, - 0x4aaa071600000000, 0x443a8cb300000000, 0x178c618600000000, - 0x191cea2300000000, 0xb1e0baed00000000, 0xbf70314800000000, - 0xecc6dc7d00000000, 0xe25657d800000000, 0xfd390c3a00000000, - 0xf3a9879f00000000, 0xa01f6aaa00000000, 0xae8fe10f00000000, - 0x0673b1c100000000, 0x08e33a6400000000, 0x5b55d75100000000, - 0x55c55cf400000000, 0x248d104e00000000, 0x2a1d9beb00000000, - 0x79ab76de00000000, 0x773bfd7b00000000, 0xdfc7adb500000000, - 0xd157261000000000, 0x82e1cb2500000000, 0x8c71408000000000, - 0x931e1b6200000000, 0x9d8e90c700000000, 0xce387df200000000, - 0xc0a8f65700000000, 0x6854a69900000000, 0x66c42d3c00000000, - 0x3572c00900000000, 0x3be24bac00000000, 0x96e429a600000000, - 0x9874a20300000000, 0xcbc24f3600000000, 0xc552c49300000000, - 0x6dae945d00000000, 0x633e1ff800000000, 0x3088f2cd00000000, - 0x3e18796800000000, 0x2177228a00000000, 0x2fe7a92f00000000, - 0x7c51441a00000000, 0x72c1cfbf00000000, 0xda3d9f7100000000, - 0xd4ad14d400000000, 0x871bf9e100000000, 0x898b724400000000, - 0xf8c33efe00000000, 0xf653b55b00000000, 0xa5e5586e00000000, - 0xab75d3cb00000000, 0x0389830500000000, 0x0d1908a000000000, - 0x5eafe59500000000, 0x503f6e3000000000, 0x4f5035d200000000, - 0x41c0be7700000000, 0x1276534200000000, 0x1ce6d8e700000000, - 0xb41a882900000000, 0xba8a038c00000000, 0xe93ceeb900000000, - 0xe7ac651c00000000}, - {0x0000000000000000, 0x97a61de700000000, 0x6f4b4a1500000000, - 0xf8ed57f200000000, 0xde96942a00000000, 0x493089cd00000000, - 0xb1ddde3f00000000, 0x267bc3d800000000, 0xbc2d295500000000, - 0x2b8b34b200000000, 0xd366634000000000, 0x44c07ea700000000, - 0x62bbbd7f00000000, 0xf51da09800000000, 0x0df0f76a00000000, - 0x9a56ea8d00000000, 0x785b52aa00000000, 0xeffd4f4d00000000, - 0x171018bf00000000, 0x80b6055800000000, 0xa6cdc68000000000, - 0x316bdb6700000000, 0xc9868c9500000000, 0x5e20917200000000, - 0xc4767bff00000000, 0x53d0661800000000, 0xab3d31ea00000000, - 0x3c9b2c0d00000000, 0x1ae0efd500000000, 0x8d46f23200000000, - 0x75aba5c000000000, 0xe20db82700000000, 0xb1b0d58f00000000, - 0x2616c86800000000, 0xdefb9f9a00000000, 0x495d827d00000000, - 0x6f2641a500000000, 0xf8805c4200000000, 0x006d0bb000000000, - 0x97cb165700000000, 0x0d9dfcda00000000, 0x9a3be13d00000000, - 0x62d6b6cf00000000, 0xf570ab2800000000, 0xd30b68f000000000, - 0x44ad751700000000, 0xbc4022e500000000, 0x2be63f0200000000, - 0xc9eb872500000000, 0x5e4d9ac200000000, 0xa6a0cd3000000000, - 0x3106d0d700000000, 0x177d130f00000000, 0x80db0ee800000000, - 0x7836591a00000000, 0xef9044fd00000000, 0x75c6ae7000000000, - 0xe260b39700000000, 0x1a8de46500000000, 0x8d2bf98200000000, - 0xab503a5a00000000, 0x3cf627bd00000000, 0xc41b704f00000000, - 0x53bd6da800000000, 0x2367dac400000000, 0xb4c1c72300000000, - 0x4c2c90d100000000, 0xdb8a8d3600000000, 0xfdf14eee00000000, - 0x6a57530900000000, 0x92ba04fb00000000, 0x051c191c00000000, - 0x9f4af39100000000, 0x08ecee7600000000, 0xf001b98400000000, - 0x67a7a46300000000, 0x41dc67bb00000000, 0xd67a7a5c00000000, - 0x2e972dae00000000, 0xb931304900000000, 0x5b3c886e00000000, - 0xcc9a958900000000, 0x3477c27b00000000, 0xa3d1df9c00000000, - 0x85aa1c4400000000, 0x120c01a300000000, 0xeae1565100000000, - 0x7d474bb600000000, 0xe711a13b00000000, 0x70b7bcdc00000000, - 0x885aeb2e00000000, 0x1ffcf6c900000000, 0x3987351100000000, - 0xae2128f600000000, 0x56cc7f0400000000, 0xc16a62e300000000, - 0x92d70f4b00000000, 0x057112ac00000000, 0xfd9c455e00000000, - 0x6a3a58b900000000, 0x4c419b6100000000, 0xdbe7868600000000, - 0x230ad17400000000, 0xb4accc9300000000, 0x2efa261e00000000, - 0xb95c3bf900000000, 0x41b16c0b00000000, 0xd61771ec00000000, - 0xf06cb23400000000, 0x67caafd300000000, 0x9f27f82100000000, - 0x0881e5c600000000, 0xea8c5de100000000, 0x7d2a400600000000, - 0x85c717f400000000, 0x12610a1300000000, 0x341ac9cb00000000, - 0xa3bcd42c00000000, 0x5b5183de00000000, 0xccf79e3900000000, - 0x56a174b400000000, 0xc107695300000000, 0x39ea3ea100000000, - 0xae4c234600000000, 0x8837e09e00000000, 0x1f91fd7900000000, - 0xe77caa8b00000000, 0x70dab76c00000000, 0x07c8c55200000000, - 0x906ed8b500000000, 0x68838f4700000000, 0xff2592a000000000, - 0xd95e517800000000, 0x4ef84c9f00000000, 0xb6151b6d00000000, - 0x21b3068a00000000, 0xbbe5ec0700000000, 0x2c43f1e000000000, - 0xd4aea61200000000, 0x4308bbf500000000, 0x6573782d00000000, - 0xf2d565ca00000000, 0x0a38323800000000, 0x9d9e2fdf00000000, - 0x7f9397f800000000, 0xe8358a1f00000000, 0x10d8dded00000000, - 0x877ec00a00000000, 0xa10503d200000000, 0x36a31e3500000000, - 0xce4e49c700000000, 0x59e8542000000000, 0xc3bebead00000000, - 0x5418a34a00000000, 0xacf5f4b800000000, 0x3b53e95f00000000, - 0x1d282a8700000000, 0x8a8e376000000000, 0x7263609200000000, - 0xe5c57d7500000000, 0xb67810dd00000000, 0x21de0d3a00000000, - 0xd9335ac800000000, 0x4e95472f00000000, 0x68ee84f700000000, - 0xff48991000000000, 0x07a5cee200000000, 0x9003d30500000000, - 0x0a55398800000000, 0x9df3246f00000000, 0x651e739d00000000, - 0xf2b86e7a00000000, 0xd4c3ada200000000, 0x4365b04500000000, - 0xbb88e7b700000000, 0x2c2efa5000000000, 0xce23427700000000, - 0x59855f9000000000, 0xa168086200000000, 0x36ce158500000000, - 0x10b5d65d00000000, 0x8713cbba00000000, 0x7ffe9c4800000000, - 0xe85881af00000000, 0x720e6b2200000000, 0xe5a876c500000000, - 0x1d45213700000000, 0x8ae33cd000000000, 0xac98ff0800000000, - 0x3b3ee2ef00000000, 0xc3d3b51d00000000, 0x5475a8fa00000000, - 0x24af1f9600000000, 0xb309027100000000, 0x4be4558300000000, - 0xdc42486400000000, 0xfa398bbc00000000, 0x6d9f965b00000000, - 0x9572c1a900000000, 0x02d4dc4e00000000, 0x988236c300000000, - 0x0f242b2400000000, 0xf7c97cd600000000, 0x606f613100000000, - 0x4614a2e900000000, 0xd1b2bf0e00000000, 0x295fe8fc00000000, - 0xbef9f51b00000000, 0x5cf44d3c00000000, 0xcb5250db00000000, - 0x33bf072900000000, 0xa4191ace00000000, 0x8262d91600000000, - 0x15c4c4f100000000, 0xed29930300000000, 0x7a8f8ee400000000, - 0xe0d9646900000000, 0x777f798e00000000, 0x8f922e7c00000000, - 0x1834339b00000000, 0x3e4ff04300000000, 0xa9e9eda400000000, - 0x5104ba5600000000, 0xc6a2a7b100000000, 0x951fca1900000000, - 0x02b9d7fe00000000, 0xfa54800c00000000, 0x6df29deb00000000, - 0x4b895e3300000000, 0xdc2f43d400000000, 0x24c2142600000000, - 0xb36409c100000000, 0x2932e34c00000000, 0xbe94feab00000000, - 0x4679a95900000000, 0xd1dfb4be00000000, 0xf7a4776600000000, - 0x60026a8100000000, 0x98ef3d7300000000, 0x0f49209400000000, - 0xed4498b300000000, 0x7ae2855400000000, 0x820fd2a600000000, - 0x15a9cf4100000000, 0x33d20c9900000000, 0xa474117e00000000, - 0x5c99468c00000000, 0xcb3f5b6b00000000, 0x5169b1e600000000, - 0xc6cfac0100000000, 0x3e22fbf300000000, 0xa984e61400000000, - 0x8fff25cc00000000, 0x1859382b00000000, 0xe0b46fd900000000, - 0x7712723e00000000}, - {0x0000000000000000, 0x411b8c6e00000000, 0x823618dd00000000, - 0xc32d94b300000000, 0x456b416100000000, 0x0470cd0f00000000, - 0xc75d59bc00000000, 0x8646d5d200000000, 0x8ad682c200000000, - 0xcbcd0eac00000000, 0x08e09a1f00000000, 0x49fb167100000000, - 0xcfbdc3a300000000, 0x8ea64fcd00000000, 0x4d8bdb7e00000000, - 0x0c90571000000000, 0x55ab745e00000000, 0x14b0f83000000000, - 0xd79d6c8300000000, 0x9686e0ed00000000, 0x10c0353f00000000, - 0x51dbb95100000000, 0x92f62de200000000, 0xd3eda18c00000000, - 0xdf7df69c00000000, 0x9e667af200000000, 0x5d4bee4100000000, - 0x1c50622f00000000, 0x9a16b7fd00000000, 0xdb0d3b9300000000, - 0x1820af2000000000, 0x593b234e00000000, 0xaa56e9bc00000000, - 0xeb4d65d200000000, 0x2860f16100000000, 0x697b7d0f00000000, - 0xef3da8dd00000000, 0xae2624b300000000, 0x6d0bb00000000000, - 0x2c103c6e00000000, 0x20806b7e00000000, 0x619be71000000000, - 0xa2b673a300000000, 0xe3adffcd00000000, 0x65eb2a1f00000000, - 0x24f0a67100000000, 0xe7dd32c200000000, 0xa6c6beac00000000, - 0xfffd9de200000000, 0xbee6118c00000000, 0x7dcb853f00000000, - 0x3cd0095100000000, 0xba96dc8300000000, 0xfb8d50ed00000000, - 0x38a0c45e00000000, 0x79bb483000000000, 0x752b1f2000000000, - 0x3430934e00000000, 0xf71d07fd00000000, 0xb6068b9300000000, - 0x30405e4100000000, 0x715bd22f00000000, 0xb276469c00000000, - 0xf36dcaf200000000, 0x15aba3a200000000, 0x54b02fcc00000000, - 0x979dbb7f00000000, 0xd686371100000000, 0x50c0e2c300000000, - 0x11db6ead00000000, 0xd2f6fa1e00000000, 0x93ed767000000000, - 0x9f7d216000000000, 0xde66ad0e00000000, 0x1d4b39bd00000000, - 0x5c50b5d300000000, 0xda16600100000000, 0x9b0dec6f00000000, - 0x582078dc00000000, 0x193bf4b200000000, 0x4000d7fc00000000, - 0x011b5b9200000000, 0xc236cf2100000000, 0x832d434f00000000, - 0x056b969d00000000, 0x44701af300000000, 0x875d8e4000000000, - 0xc646022e00000000, 0xcad6553e00000000, 0x8bcdd95000000000, - 0x48e04de300000000, 0x09fbc18d00000000, 0x8fbd145f00000000, - 0xcea6983100000000, 0x0d8b0c8200000000, 0x4c9080ec00000000, - 0xbffd4a1e00000000, 0xfee6c67000000000, 0x3dcb52c300000000, - 0x7cd0dead00000000, 0xfa960b7f00000000, 0xbb8d871100000000, - 0x78a013a200000000, 0x39bb9fcc00000000, 0x352bc8dc00000000, - 0x743044b200000000, 0xb71dd00100000000, 0xf6065c6f00000000, - 0x704089bd00000000, 0x315b05d300000000, 0xf276916000000000, - 0xb36d1d0e00000000, 0xea563e4000000000, 0xab4db22e00000000, - 0x6860269d00000000, 0x297baaf300000000, 0xaf3d7f2100000000, - 0xee26f34f00000000, 0x2d0b67fc00000000, 0x6c10eb9200000000, - 0x6080bc8200000000, 0x219b30ec00000000, 0xe2b6a45f00000000, - 0xa3ad283100000000, 0x25ebfde300000000, 0x64f0718d00000000, - 0xa7dde53e00000000, 0xe6c6695000000000, 0x6b50369e00000000, - 0x2a4bbaf000000000, 0xe9662e4300000000, 0xa87da22d00000000, - 0x2e3b77ff00000000, 0x6f20fb9100000000, 0xac0d6f2200000000, - 0xed16e34c00000000, 0xe186b45c00000000, 0xa09d383200000000, - 0x63b0ac8100000000, 0x22ab20ef00000000, 0xa4edf53d00000000, - 0xe5f6795300000000, 0x26dbede000000000, 0x67c0618e00000000, - 0x3efb42c000000000, 0x7fe0ceae00000000, 0xbccd5a1d00000000, - 0xfdd6d67300000000, 0x7b9003a100000000, 0x3a8b8fcf00000000, - 0xf9a61b7c00000000, 0xb8bd971200000000, 0xb42dc00200000000, - 0xf5364c6c00000000, 0x361bd8df00000000, 0x770054b100000000, - 0xf146816300000000, 0xb05d0d0d00000000, 0x737099be00000000, - 0x326b15d000000000, 0xc106df2200000000, 0x801d534c00000000, - 0x4330c7ff00000000, 0x022b4b9100000000, 0x846d9e4300000000, - 0xc576122d00000000, 0x065b869e00000000, 0x47400af000000000, - 0x4bd05de000000000, 0x0acbd18e00000000, 0xc9e6453d00000000, - 0x88fdc95300000000, 0x0ebb1c8100000000, 0x4fa090ef00000000, - 0x8c8d045c00000000, 0xcd96883200000000, 0x94adab7c00000000, - 0xd5b6271200000000, 0x169bb3a100000000, 0x57803fcf00000000, - 0xd1c6ea1d00000000, 0x90dd667300000000, 0x53f0f2c000000000, - 0x12eb7eae00000000, 0x1e7b29be00000000, 0x5f60a5d000000000, - 0x9c4d316300000000, 0xdd56bd0d00000000, 0x5b1068df00000000, - 0x1a0be4b100000000, 0xd926700200000000, 0x983dfc6c00000000, - 0x7efb953c00000000, 0x3fe0195200000000, 0xfccd8de100000000, - 0xbdd6018f00000000, 0x3b90d45d00000000, 0x7a8b583300000000, - 0xb9a6cc8000000000, 0xf8bd40ee00000000, 0xf42d17fe00000000, - 0xb5369b9000000000, 0x761b0f2300000000, 0x3700834d00000000, - 0xb146569f00000000, 0xf05ddaf100000000, 0x33704e4200000000, - 0x726bc22c00000000, 0x2b50e16200000000, 0x6a4b6d0c00000000, - 0xa966f9bf00000000, 0xe87d75d100000000, 0x6e3ba00300000000, - 0x2f202c6d00000000, 0xec0db8de00000000, 0xad1634b000000000, - 0xa18663a000000000, 0xe09defce00000000, 0x23b07b7d00000000, - 0x62abf71300000000, 0xe4ed22c100000000, 0xa5f6aeaf00000000, - 0x66db3a1c00000000, 0x27c0b67200000000, 0xd4ad7c8000000000, - 0x95b6f0ee00000000, 0x569b645d00000000, 0x1780e83300000000, - 0x91c63de100000000, 0xd0ddb18f00000000, 0x13f0253c00000000, - 0x52eba95200000000, 0x5e7bfe4200000000, 0x1f60722c00000000, - 0xdc4de69f00000000, 0x9d566af100000000, 0x1b10bf2300000000, - 0x5a0b334d00000000, 0x9926a7fe00000000, 0xd83d2b9000000000, - 0x810608de00000000, 0xc01d84b000000000, 0x0330100300000000, - 0x422b9c6d00000000, 0xc46d49bf00000000, 0x8576c5d100000000, - 0x465b516200000000, 0x0740dd0c00000000, 0x0bd08a1c00000000, - 0x4acb067200000000, 0x89e692c100000000, 0xc8fd1eaf00000000, - 0x4ebbcb7d00000000, 0x0fa0471300000000, 0xcc8dd3a000000000, - 0x8d965fce00000000}, - {0x0000000000000000, 0x1dfdb50100000000, 0x3afa6b0300000000, - 0x2707de0200000000, 0x74f4d70600000000, 0x6909620700000000, - 0x4e0ebc0500000000, 0x53f3090400000000, 0xe8e8af0d00000000, - 0xf5151a0c00000000, 0xd212c40e00000000, 0xcfef710f00000000, - 0x9c1c780b00000000, 0x81e1cd0a00000000, 0xa6e6130800000000, - 0xbb1ba60900000000, 0xd0d15f1b00000000, 0xcd2cea1a00000000, - 0xea2b341800000000, 0xf7d6811900000000, 0xa425881d00000000, - 0xb9d83d1c00000000, 0x9edfe31e00000000, 0x8322561f00000000, - 0x3839f01600000000, 0x25c4451700000000, 0x02c39b1500000000, - 0x1f3e2e1400000000, 0x4ccd271000000000, 0x5130921100000000, - 0x76374c1300000000, 0x6bcaf91200000000, 0xa0a3bf3600000000, - 0xbd5e0a3700000000, 0x9a59d43500000000, 0x87a4613400000000, - 0xd457683000000000, 0xc9aadd3100000000, 0xeead033300000000, - 0xf350b63200000000, 0x484b103b00000000, 0x55b6a53a00000000, - 0x72b17b3800000000, 0x6f4cce3900000000, 0x3cbfc73d00000000, - 0x2142723c00000000, 0x0645ac3e00000000, 0x1bb8193f00000000, - 0x7072e02d00000000, 0x6d8f552c00000000, 0x4a888b2e00000000, - 0x57753e2f00000000, 0x0486372b00000000, 0x197b822a00000000, - 0x3e7c5c2800000000, 0x2381e92900000000, 0x989a4f2000000000, - 0x8567fa2100000000, 0xa260242300000000, 0xbf9d912200000000, - 0xec6e982600000000, 0xf1932d2700000000, 0xd694f32500000000, - 0xcb69462400000000, 0x40477f6d00000000, 0x5dbaca6c00000000, - 0x7abd146e00000000, 0x6740a16f00000000, 0x34b3a86b00000000, - 0x294e1d6a00000000, 0x0e49c36800000000, 0x13b4766900000000, - 0xa8afd06000000000, 0xb552656100000000, 0x9255bb6300000000, - 0x8fa80e6200000000, 0xdc5b076600000000, 0xc1a6b26700000000, - 0xe6a16c6500000000, 0xfb5cd96400000000, 0x9096207600000000, - 0x8d6b957700000000, 0xaa6c4b7500000000, 0xb791fe7400000000, - 0xe462f77000000000, 0xf99f427100000000, 0xde989c7300000000, - 0xc365297200000000, 0x787e8f7b00000000, 0x65833a7a00000000, - 0x4284e47800000000, 0x5f79517900000000, 0x0c8a587d00000000, - 0x1177ed7c00000000, 0x3670337e00000000, 0x2b8d867f00000000, - 0xe0e4c05b00000000, 0xfd19755a00000000, 0xda1eab5800000000, - 0xc7e31e5900000000, 0x9410175d00000000, 0x89eda25c00000000, - 0xaeea7c5e00000000, 0xb317c95f00000000, 0x080c6f5600000000, - 0x15f1da5700000000, 0x32f6045500000000, 0x2f0bb15400000000, - 0x7cf8b85000000000, 0x61050d5100000000, 0x4602d35300000000, - 0x5bff665200000000, 0x30359f4000000000, 0x2dc82a4100000000, - 0x0acff44300000000, 0x1732414200000000, 0x44c1484600000000, - 0x593cfd4700000000, 0x7e3b234500000000, 0x63c6964400000000, - 0xd8dd304d00000000, 0xc520854c00000000, 0xe2275b4e00000000, - 0xffdaee4f00000000, 0xac29e74b00000000, 0xb1d4524a00000000, - 0x96d38c4800000000, 0x8b2e394900000000, 0x808efeda00000000, - 0x9d734bdb00000000, 0xba7495d900000000, 0xa78920d800000000, - 0xf47a29dc00000000, 0xe9879cdd00000000, 0xce8042df00000000, - 0xd37df7de00000000, 0x686651d700000000, 0x759be4d600000000, - 0x529c3ad400000000, 0x4f618fd500000000, 0x1c9286d100000000, - 0x016f33d000000000, 0x2668edd200000000, 0x3b9558d300000000, - 0x505fa1c100000000, 0x4da214c000000000, 0x6aa5cac200000000, - 0x77587fc300000000, 0x24ab76c700000000, 0x3956c3c600000000, - 0x1e511dc400000000, 0x03aca8c500000000, 0xb8b70ecc00000000, - 0xa54abbcd00000000, 0x824d65cf00000000, 0x9fb0d0ce00000000, - 0xcc43d9ca00000000, 0xd1be6ccb00000000, 0xf6b9b2c900000000, - 0xeb4407c800000000, 0x202d41ec00000000, 0x3dd0f4ed00000000, - 0x1ad72aef00000000, 0x072a9fee00000000, 0x54d996ea00000000, - 0x492423eb00000000, 0x6e23fde900000000, 0x73de48e800000000, - 0xc8c5eee100000000, 0xd5385be000000000, 0xf23f85e200000000, - 0xefc230e300000000, 0xbc3139e700000000, 0xa1cc8ce600000000, - 0x86cb52e400000000, 0x9b36e7e500000000, 0xf0fc1ef700000000, - 0xed01abf600000000, 0xca0675f400000000, 0xd7fbc0f500000000, - 0x8408c9f100000000, 0x99f57cf000000000, 0xbef2a2f200000000, - 0xa30f17f300000000, 0x1814b1fa00000000, 0x05e904fb00000000, - 0x22eedaf900000000, 0x3f136ff800000000, 0x6ce066fc00000000, - 0x711dd3fd00000000, 0x561a0dff00000000, 0x4be7b8fe00000000, - 0xc0c981b700000000, 0xdd3434b600000000, 0xfa33eab400000000, - 0xe7ce5fb500000000, 0xb43d56b100000000, 0xa9c0e3b000000000, - 0x8ec73db200000000, 0x933a88b300000000, 0x28212eba00000000, - 0x35dc9bbb00000000, 0x12db45b900000000, 0x0f26f0b800000000, - 0x5cd5f9bc00000000, 0x41284cbd00000000, 0x662f92bf00000000, - 0x7bd227be00000000, 0x1018deac00000000, 0x0de56bad00000000, - 0x2ae2b5af00000000, 0x371f00ae00000000, 0x64ec09aa00000000, - 0x7911bcab00000000, 0x5e1662a900000000, 0x43ebd7a800000000, - 0xf8f071a100000000, 0xe50dc4a000000000, 0xc20a1aa200000000, - 0xdff7afa300000000, 0x8c04a6a700000000, 0x91f913a600000000, - 0xb6fecda400000000, 0xab0378a500000000, 0x606a3e8100000000, - 0x7d978b8000000000, 0x5a90558200000000, 0x476de08300000000, - 0x149ee98700000000, 0x09635c8600000000, 0x2e64828400000000, - 0x3399378500000000, 0x8882918c00000000, 0x957f248d00000000, - 0xb278fa8f00000000, 0xaf854f8e00000000, 0xfc76468a00000000, - 0xe18bf38b00000000, 0xc68c2d8900000000, 0xdb71988800000000, - 0xb0bb619a00000000, 0xad46d49b00000000, 0x8a410a9900000000, - 0x97bcbf9800000000, 0xc44fb69c00000000, 0xd9b2039d00000000, - 0xfeb5dd9f00000000, 0xe348689e00000000, 0x5853ce9700000000, - 0x45ae7b9600000000, 0x62a9a59400000000, 0x7f54109500000000, - 0x2ca7199100000000, 0x315aac9000000000, 0x165d729200000000, - 0x0ba0c79300000000}, - {0x0000000000000000, 0x24d9076300000000, 0x48b20fc600000000, - 0x6c6b08a500000000, 0xd1626e5700000000, 0xf5bb693400000000, - 0x99d0619100000000, 0xbd0966f200000000, 0xa2c5dcae00000000, - 0x861cdbcd00000000, 0xea77d36800000000, 0xceaed40b00000000, - 0x73a7b2f900000000, 0x577eb59a00000000, 0x3b15bd3f00000000, - 0x1fccba5c00000000, 0x058dc88600000000, 0x2154cfe500000000, - 0x4d3fc74000000000, 0x69e6c02300000000, 0xd4efa6d100000000, - 0xf036a1b200000000, 0x9c5da91700000000, 0xb884ae7400000000, - 0xa748142800000000, 0x8391134b00000000, 0xeffa1bee00000000, - 0xcb231c8d00000000, 0x762a7a7f00000000, 0x52f37d1c00000000, - 0x3e9875b900000000, 0x1a4172da00000000, 0x4b1ce0d600000000, - 0x6fc5e7b500000000, 0x03aeef1000000000, 0x2777e87300000000, - 0x9a7e8e8100000000, 0xbea789e200000000, 0xd2cc814700000000, - 0xf615862400000000, 0xe9d93c7800000000, 0xcd003b1b00000000, - 0xa16b33be00000000, 0x85b234dd00000000, 0x38bb522f00000000, - 0x1c62554c00000000, 0x70095de900000000, 0x54d05a8a00000000, - 0x4e91285000000000, 0x6a482f3300000000, 0x0623279600000000, - 0x22fa20f500000000, 0x9ff3460700000000, 0xbb2a416400000000, - 0xd74149c100000000, 0xf3984ea200000000, 0xec54f4fe00000000, - 0xc88df39d00000000, 0xa4e6fb3800000000, 0x803ffc5b00000000, - 0x3d369aa900000000, 0x19ef9dca00000000, 0x7584956f00000000, - 0x515d920c00000000, 0xd73eb17600000000, 0xf3e7b61500000000, - 0x9f8cbeb000000000, 0xbb55b9d300000000, 0x065cdf2100000000, - 0x2285d84200000000, 0x4eeed0e700000000, 0x6a37d78400000000, - 0x75fb6dd800000000, 0x51226abb00000000, 0x3d49621e00000000, - 0x1990657d00000000, 0xa499038f00000000, 0x804004ec00000000, - 0xec2b0c4900000000, 0xc8f20b2a00000000, 0xd2b379f000000000, - 0xf66a7e9300000000, 0x9a01763600000000, 0xbed8715500000000, - 0x03d117a700000000, 0x270810c400000000, 0x4b63186100000000, - 0x6fba1f0200000000, 0x7076a55e00000000, 0x54afa23d00000000, - 0x38c4aa9800000000, 0x1c1dadfb00000000, 0xa114cb0900000000, - 0x85cdcc6a00000000, 0xe9a6c4cf00000000, 0xcd7fc3ac00000000, - 0x9c2251a000000000, 0xb8fb56c300000000, 0xd4905e6600000000, - 0xf049590500000000, 0x4d403ff700000000, 0x6999389400000000, - 0x05f2303100000000, 0x212b375200000000, 0x3ee78d0e00000000, - 0x1a3e8a6d00000000, 0x765582c800000000, 0x528c85ab00000000, - 0xef85e35900000000, 0xcb5ce43a00000000, 0xa737ec9f00000000, - 0x83eeebfc00000000, 0x99af992600000000, 0xbd769e4500000000, - 0xd11d96e000000000, 0xf5c4918300000000, 0x48cdf77100000000, - 0x6c14f01200000000, 0x007ff8b700000000, 0x24a6ffd400000000, - 0x3b6a458800000000, 0x1fb342eb00000000, 0x73d84a4e00000000, - 0x57014d2d00000000, 0xea082bdf00000000, 0xced12cbc00000000, - 0xa2ba241900000000, 0x8663237a00000000, 0xae7d62ed00000000, - 0x8aa4658e00000000, 0xe6cf6d2b00000000, 0xc2166a4800000000, - 0x7f1f0cba00000000, 0x5bc60bd900000000, 0x37ad037c00000000, - 0x1374041f00000000, 0x0cb8be4300000000, 0x2861b92000000000, - 0x440ab18500000000, 0x60d3b6e600000000, 0xdddad01400000000, - 0xf903d77700000000, 0x9568dfd200000000, 0xb1b1d8b100000000, - 0xabf0aa6b00000000, 0x8f29ad0800000000, 0xe342a5ad00000000, - 0xc79ba2ce00000000, 0x7a92c43c00000000, 0x5e4bc35f00000000, - 0x3220cbfa00000000, 0x16f9cc9900000000, 0x093576c500000000, - 0x2dec71a600000000, 0x4187790300000000, 0x655e7e6000000000, - 0xd857189200000000, 0xfc8e1ff100000000, 0x90e5175400000000, - 0xb43c103700000000, 0xe561823b00000000, 0xc1b8855800000000, - 0xadd38dfd00000000, 0x890a8a9e00000000, 0x3403ec6c00000000, - 0x10daeb0f00000000, 0x7cb1e3aa00000000, 0x5868e4c900000000, - 0x47a45e9500000000, 0x637d59f600000000, 0x0f16515300000000, - 0x2bcf563000000000, 0x96c630c200000000, 0xb21f37a100000000, - 0xde743f0400000000, 0xfaad386700000000, 0xe0ec4abd00000000, - 0xc4354dde00000000, 0xa85e457b00000000, 0x8c87421800000000, - 0x318e24ea00000000, 0x1557238900000000, 0x793c2b2c00000000, - 0x5de52c4f00000000, 0x4229961300000000, 0x66f0917000000000, - 0x0a9b99d500000000, 0x2e429eb600000000, 0x934bf84400000000, - 0xb792ff2700000000, 0xdbf9f78200000000, 0xff20f0e100000000, - 0x7943d39b00000000, 0x5d9ad4f800000000, 0x31f1dc5d00000000, - 0x1528db3e00000000, 0xa821bdcc00000000, 0x8cf8baaf00000000, - 0xe093b20a00000000, 0xc44ab56900000000, 0xdb860f3500000000, - 0xff5f085600000000, 0x933400f300000000, 0xb7ed079000000000, - 0x0ae4616200000000, 0x2e3d660100000000, 0x42566ea400000000, - 0x668f69c700000000, 0x7cce1b1d00000000, 0x58171c7e00000000, - 0x347c14db00000000, 0x10a513b800000000, 0xadac754a00000000, - 0x8975722900000000, 0xe51e7a8c00000000, 0xc1c77def00000000, - 0xde0bc7b300000000, 0xfad2c0d000000000, 0x96b9c87500000000, - 0xb260cf1600000000, 0x0f69a9e400000000, 0x2bb0ae8700000000, - 0x47dba62200000000, 0x6302a14100000000, 0x325f334d00000000, - 0x1686342e00000000, 0x7aed3c8b00000000, 0x5e343be800000000, - 0xe33d5d1a00000000, 0xc7e45a7900000000, 0xab8f52dc00000000, - 0x8f5655bf00000000, 0x909aefe300000000, 0xb443e88000000000, - 0xd828e02500000000, 0xfcf1e74600000000, 0x41f881b400000000, - 0x652186d700000000, 0x094a8e7200000000, 0x2d93891100000000, - 0x37d2fbcb00000000, 0x130bfca800000000, 0x7f60f40d00000000, - 0x5bb9f36e00000000, 0xe6b0959c00000000, 0xc26992ff00000000, - 0xae029a5a00000000, 0x8adb9d3900000000, 0x9517276500000000, - 0xb1ce200600000000, 0xdda528a300000000, 0xf97c2fc000000000, - 0x4475493200000000, 0x60ac4e5100000000, 0x0cc746f400000000, - 0x281e419700000000}, - {0x0000000000000000, 0x08e3603c00000000, 0x10c6c17800000000, - 0x1825a14400000000, 0x208c83f100000000, 0x286fe3cd00000000, - 0x304a428900000000, 0x38a922b500000000, 0x011e763800000000, - 0x09fd160400000000, 0x11d8b74000000000, 0x193bd77c00000000, - 0x2192f5c900000000, 0x297195f500000000, 0x315434b100000000, - 0x39b7548d00000000, 0x023cec7000000000, 0x0adf8c4c00000000, - 0x12fa2d0800000000, 0x1a194d3400000000, 0x22b06f8100000000, - 0x2a530fbd00000000, 0x3276aef900000000, 0x3a95cec500000000, - 0x03229a4800000000, 0x0bc1fa7400000000, 0x13e45b3000000000, - 0x1b073b0c00000000, 0x23ae19b900000000, 0x2b4d798500000000, - 0x3368d8c100000000, 0x3b8bb8fd00000000, 0x0478d8e100000000, - 0x0c9bb8dd00000000, 0x14be199900000000, 0x1c5d79a500000000, - 0x24f45b1000000000, 0x2c173b2c00000000, 0x34329a6800000000, - 0x3cd1fa5400000000, 0x0566aed900000000, 0x0d85cee500000000, - 0x15a06fa100000000, 0x1d430f9d00000000, 0x25ea2d2800000000, - 0x2d094d1400000000, 0x352cec5000000000, 0x3dcf8c6c00000000, - 0x0644349100000000, 0x0ea754ad00000000, 0x1682f5e900000000, - 0x1e6195d500000000, 0x26c8b76000000000, 0x2e2bd75c00000000, - 0x360e761800000000, 0x3eed162400000000, 0x075a42a900000000, - 0x0fb9229500000000, 0x179c83d100000000, 0x1f7fe3ed00000000, - 0x27d6c15800000000, 0x2f35a16400000000, 0x3710002000000000, - 0x3ff3601c00000000, 0x49f6c11800000000, 0x4115a12400000000, - 0x5930006000000000, 0x51d3605c00000000, 0x697a42e900000000, - 0x619922d500000000, 0x79bc839100000000, 0x715fe3ad00000000, - 0x48e8b72000000000, 0x400bd71c00000000, 0x582e765800000000, - 0x50cd166400000000, 0x686434d100000000, 0x608754ed00000000, - 0x78a2f5a900000000, 0x7041959500000000, 0x4bca2d6800000000, - 0x43294d5400000000, 0x5b0cec1000000000, 0x53ef8c2c00000000, - 0x6b46ae9900000000, 0x63a5cea500000000, 0x7b806fe100000000, - 0x73630fdd00000000, 0x4ad45b5000000000, 0x42373b6c00000000, - 0x5a129a2800000000, 0x52f1fa1400000000, 0x6a58d8a100000000, - 0x62bbb89d00000000, 0x7a9e19d900000000, 0x727d79e500000000, - 0x4d8e19f900000000, 0x456d79c500000000, 0x5d48d88100000000, - 0x55abb8bd00000000, 0x6d029a0800000000, 0x65e1fa3400000000, - 0x7dc45b7000000000, 0x75273b4c00000000, 0x4c906fc100000000, - 0x44730ffd00000000, 0x5c56aeb900000000, 0x54b5ce8500000000, - 0x6c1cec3000000000, 0x64ff8c0c00000000, 0x7cda2d4800000000, - 0x74394d7400000000, 0x4fb2f58900000000, 0x475195b500000000, - 0x5f7434f100000000, 0x579754cd00000000, 0x6f3e767800000000, - 0x67dd164400000000, 0x7ff8b70000000000, 0x771bd73c00000000, - 0x4eac83b100000000, 0x464fe38d00000000, 0x5e6a42c900000000, - 0x568922f500000000, 0x6e20004000000000, 0x66c3607c00000000, - 0x7ee6c13800000000, 0x7605a10400000000, 0x92ec833100000000, - 0x9a0fe30d00000000, 0x822a424900000000, 0x8ac9227500000000, - 0xb26000c000000000, 0xba8360fc00000000, 0xa2a6c1b800000000, - 0xaa45a18400000000, 0x93f2f50900000000, 0x9b11953500000000, - 0x8334347100000000, 0x8bd7544d00000000, 0xb37e76f800000000, - 0xbb9d16c400000000, 0xa3b8b78000000000, 0xab5bd7bc00000000, - 0x90d06f4100000000, 0x98330f7d00000000, 0x8016ae3900000000, - 0x88f5ce0500000000, 0xb05cecb000000000, 0xb8bf8c8c00000000, - 0xa09a2dc800000000, 0xa8794df400000000, 0x91ce197900000000, - 0x992d794500000000, 0x8108d80100000000, 0x89ebb83d00000000, - 0xb1429a8800000000, 0xb9a1fab400000000, 0xa1845bf000000000, - 0xa9673bcc00000000, 0x96945bd000000000, 0x9e773bec00000000, - 0x86529aa800000000, 0x8eb1fa9400000000, 0xb618d82100000000, - 0xbefbb81d00000000, 0xa6de195900000000, 0xae3d796500000000, - 0x978a2de800000000, 0x9f694dd400000000, 0x874cec9000000000, - 0x8faf8cac00000000, 0xb706ae1900000000, 0xbfe5ce2500000000, - 0xa7c06f6100000000, 0xaf230f5d00000000, 0x94a8b7a000000000, - 0x9c4bd79c00000000, 0x846e76d800000000, 0x8c8d16e400000000, - 0xb424345100000000, 0xbcc7546d00000000, 0xa4e2f52900000000, - 0xac01951500000000, 0x95b6c19800000000, 0x9d55a1a400000000, - 0x857000e000000000, 0x8d9360dc00000000, 0xb53a426900000000, - 0xbdd9225500000000, 0xa5fc831100000000, 0xad1fe32d00000000, - 0xdb1a422900000000, 0xd3f9221500000000, 0xcbdc835100000000, - 0xc33fe36d00000000, 0xfb96c1d800000000, 0xf375a1e400000000, - 0xeb5000a000000000, 0xe3b3609c00000000, 0xda04341100000000, - 0xd2e7542d00000000, 0xcac2f56900000000, 0xc221955500000000, - 0xfa88b7e000000000, 0xf26bd7dc00000000, 0xea4e769800000000, - 0xe2ad16a400000000, 0xd926ae5900000000, 0xd1c5ce6500000000, - 0xc9e06f2100000000, 0xc1030f1d00000000, 0xf9aa2da800000000, - 0xf1494d9400000000, 0xe96cecd000000000, 0xe18f8cec00000000, - 0xd838d86100000000, 0xd0dbb85d00000000, 0xc8fe191900000000, - 0xc01d792500000000, 0xf8b45b9000000000, 0xf0573bac00000000, - 0xe8729ae800000000, 0xe091fad400000000, 0xdf629ac800000000, - 0xd781faf400000000, 0xcfa45bb000000000, 0xc7473b8c00000000, - 0xffee193900000000, 0xf70d790500000000, 0xef28d84100000000, - 0xe7cbb87d00000000, 0xde7cecf000000000, 0xd69f8ccc00000000, - 0xceba2d8800000000, 0xc6594db400000000, 0xfef06f0100000000, - 0xf6130f3d00000000, 0xee36ae7900000000, 0xe6d5ce4500000000, - 0xdd5e76b800000000, 0xd5bd168400000000, 0xcd98b7c000000000, - 0xc57bd7fc00000000, 0xfdd2f54900000000, 0xf531957500000000, - 0xed14343100000000, 0xe5f7540d00000000, 0xdc40008000000000, - 0xd4a360bc00000000, 0xcc86c1f800000000, 0xc465a1c400000000, - 0xfccc837100000000, 0xf42fe34d00000000, 0xec0a420900000000, - 0xe4e9223500000000}, - {0x0000000000000000, 0xd1e8e70e00000000, 0xa2d1cf1d00000000, - 0x7339281300000000, 0x44a39f3b00000000, 0x954b783500000000, - 0xe672502600000000, 0x379ab72800000000, 0x88463f7700000000, - 0x59aed87900000000, 0x2a97f06a00000000, 0xfb7f176400000000, - 0xcce5a04c00000000, 0x1d0d474200000000, 0x6e346f5100000000, - 0xbfdc885f00000000, 0x108d7eee00000000, 0xc16599e000000000, - 0xb25cb1f300000000, 0x63b456fd00000000, 0x542ee1d500000000, - 0x85c606db00000000, 0xf6ff2ec800000000, 0x2717c9c600000000, - 0x98cb419900000000, 0x4923a69700000000, 0x3a1a8e8400000000, - 0xebf2698a00000000, 0xdc68dea200000000, 0x0d8039ac00000000, - 0x7eb911bf00000000, 0xaf51f6b100000000, 0x611c8c0700000000, - 0xb0f46b0900000000, 0xc3cd431a00000000, 0x1225a41400000000, - 0x25bf133c00000000, 0xf457f43200000000, 0x876edc2100000000, - 0x56863b2f00000000, 0xe95ab37000000000, 0x38b2547e00000000, - 0x4b8b7c6d00000000, 0x9a639b6300000000, 0xadf92c4b00000000, - 0x7c11cb4500000000, 0x0f28e35600000000, 0xdec0045800000000, - 0x7191f2e900000000, 0xa07915e700000000, 0xd3403df400000000, - 0x02a8dafa00000000, 0x35326dd200000000, 0xe4da8adc00000000, - 0x97e3a2cf00000000, 0x460b45c100000000, 0xf9d7cd9e00000000, - 0x283f2a9000000000, 0x5b06028300000000, 0x8aeee58d00000000, - 0xbd7452a500000000, 0x6c9cb5ab00000000, 0x1fa59db800000000, - 0xce4d7ab600000000, 0xc238180f00000000, 0x13d0ff0100000000, - 0x60e9d71200000000, 0xb101301c00000000, 0x869b873400000000, - 0x5773603a00000000, 0x244a482900000000, 0xf5a2af2700000000, - 0x4a7e277800000000, 0x9b96c07600000000, 0xe8afe86500000000, - 0x39470f6b00000000, 0x0eddb84300000000, 0xdf355f4d00000000, - 0xac0c775e00000000, 0x7de4905000000000, 0xd2b566e100000000, - 0x035d81ef00000000, 0x7064a9fc00000000, 0xa18c4ef200000000, - 0x9616f9da00000000, 0x47fe1ed400000000, 0x34c736c700000000, - 0xe52fd1c900000000, 0x5af3599600000000, 0x8b1bbe9800000000, - 0xf822968b00000000, 0x29ca718500000000, 0x1e50c6ad00000000, - 0xcfb821a300000000, 0xbc8109b000000000, 0x6d69eebe00000000, - 0xa324940800000000, 0x72cc730600000000, 0x01f55b1500000000, - 0xd01dbc1b00000000, 0xe7870b3300000000, 0x366fec3d00000000, - 0x4556c42e00000000, 0x94be232000000000, 0x2b62ab7f00000000, - 0xfa8a4c7100000000, 0x89b3646200000000, 0x585b836c00000000, - 0x6fc1344400000000, 0xbe29d34a00000000, 0xcd10fb5900000000, - 0x1cf81c5700000000, 0xb3a9eae600000000, 0x62410de800000000, - 0x117825fb00000000, 0xc090c2f500000000, 0xf70a75dd00000000, - 0x26e292d300000000, 0x55dbbac000000000, 0x84335dce00000000, - 0x3befd59100000000, 0xea07329f00000000, 0x993e1a8c00000000, - 0x48d6fd8200000000, 0x7f4c4aaa00000000, 0xaea4ada400000000, - 0xdd9d85b700000000, 0x0c7562b900000000, 0x8471301e00000000, - 0x5599d71000000000, 0x26a0ff0300000000, 0xf748180d00000000, - 0xc0d2af2500000000, 0x113a482b00000000, 0x6203603800000000, - 0xb3eb873600000000, 0x0c370f6900000000, 0xdddfe86700000000, - 0xaee6c07400000000, 0x7f0e277a00000000, 0x4894905200000000, - 0x997c775c00000000, 0xea455f4f00000000, 0x3badb84100000000, - 0x94fc4ef000000000, 0x4514a9fe00000000, 0x362d81ed00000000, - 0xe7c566e300000000, 0xd05fd1cb00000000, 0x01b736c500000000, - 0x728e1ed600000000, 0xa366f9d800000000, 0x1cba718700000000, - 0xcd52968900000000, 0xbe6bbe9a00000000, 0x6f83599400000000, - 0x5819eebc00000000, 0x89f109b200000000, 0xfac821a100000000, - 0x2b20c6af00000000, 0xe56dbc1900000000, 0x34855b1700000000, - 0x47bc730400000000, 0x9654940a00000000, 0xa1ce232200000000, - 0x7026c42c00000000, 0x031fec3f00000000, 0xd2f70b3100000000, - 0x6d2b836e00000000, 0xbcc3646000000000, 0xcffa4c7300000000, - 0x1e12ab7d00000000, 0x29881c5500000000, 0xf860fb5b00000000, - 0x8b59d34800000000, 0x5ab1344600000000, 0xf5e0c2f700000000, - 0x240825f900000000, 0x57310dea00000000, 0x86d9eae400000000, - 0xb1435dcc00000000, 0x60abbac200000000, 0x139292d100000000, - 0xc27a75df00000000, 0x7da6fd8000000000, 0xac4e1a8e00000000, - 0xdf77329d00000000, 0x0e9fd59300000000, 0x390562bb00000000, - 0xe8ed85b500000000, 0x9bd4ada600000000, 0x4a3c4aa800000000, - 0x4649281100000000, 0x97a1cf1f00000000, 0xe498e70c00000000, - 0x3570000200000000, 0x02eab72a00000000, 0xd302502400000000, - 0xa03b783700000000, 0x71d39f3900000000, 0xce0f176600000000, - 0x1fe7f06800000000, 0x6cded87b00000000, 0xbd363f7500000000, - 0x8aac885d00000000, 0x5b446f5300000000, 0x287d474000000000, - 0xf995a04e00000000, 0x56c456ff00000000, 0x872cb1f100000000, - 0xf41599e200000000, 0x25fd7eec00000000, 0x1267c9c400000000, - 0xc38f2eca00000000, 0xb0b606d900000000, 0x615ee1d700000000, - 0xde82698800000000, 0x0f6a8e8600000000, 0x7c53a69500000000, - 0xadbb419b00000000, 0x9a21f6b300000000, 0x4bc911bd00000000, - 0x38f039ae00000000, 0xe918dea000000000, 0x2755a41600000000, - 0xf6bd431800000000, 0x85846b0b00000000, 0x546c8c0500000000, - 0x63f63b2d00000000, 0xb21edc2300000000, 0xc127f43000000000, - 0x10cf133e00000000, 0xaf139b6100000000, 0x7efb7c6f00000000, - 0x0dc2547c00000000, 0xdc2ab37200000000, 0xebb0045a00000000, - 0x3a58e35400000000, 0x4961cb4700000000, 0x98892c4900000000, - 0x37d8daf800000000, 0xe6303df600000000, 0x950915e500000000, - 0x44e1f2eb00000000, 0x737b45c300000000, 0xa293a2cd00000000, - 0xd1aa8ade00000000, 0x00426dd000000000, 0xbf9ee58f00000000, - 0x6e76028100000000, 0x1d4f2a9200000000, 0xcca7cd9c00000000, - 0xfb3d7ab400000000, 0x2ad59dba00000000, 0x59ecb5a900000000, - 0x880452a700000000}, - {0x0000000000000000, 0xaa05daf100000000, 0x150dc53800000000, - 0xbf081fc900000000, 0x2a1a8a7100000000, 0x801f508000000000, - 0x3f174f4900000000, 0x951295b800000000, 0x543414e300000000, - 0xfe31ce1200000000, 0x4139d1db00000000, 0xeb3c0b2a00000000, - 0x7e2e9e9200000000, 0xd42b446300000000, 0x6b235baa00000000, - 0xc126815b00000000, 0xe96e591d00000000, 0x436b83ec00000000, - 0xfc639c2500000000, 0x566646d400000000, 0xc374d36c00000000, - 0x6971099d00000000, 0xd679165400000000, 0x7c7ccca500000000, - 0xbd5a4dfe00000000, 0x175f970f00000000, 0xa85788c600000000, - 0x0252523700000000, 0x9740c78f00000000, 0x3d451d7e00000000, - 0x824d02b700000000, 0x2848d84600000000, 0xd2ddb23a00000000, - 0x78d868cb00000000, 0xc7d0770200000000, 0x6dd5adf300000000, - 0xf8c7384b00000000, 0x52c2e2ba00000000, 0xedcafd7300000000, - 0x47cf278200000000, 0x86e9a6d900000000, 0x2cec7c2800000000, - 0x93e463e100000000, 0x39e1b91000000000, 0xacf32ca800000000, - 0x06f6f65900000000, 0xb9fee99000000000, 0x13fb336100000000, - 0x3bb3eb2700000000, 0x91b631d600000000, 0x2ebe2e1f00000000, - 0x84bbf4ee00000000, 0x11a9615600000000, 0xbbacbba700000000, - 0x04a4a46e00000000, 0xaea17e9f00000000, 0x6f87ffc400000000, - 0xc582253500000000, 0x7a8a3afc00000000, 0xd08fe00d00000000, - 0x459d75b500000000, 0xef98af4400000000, 0x5090b08d00000000, - 0xfa956a7c00000000, 0xa4bb657500000000, 0x0ebebf8400000000, - 0xb1b6a04d00000000, 0x1bb37abc00000000, 0x8ea1ef0400000000, - 0x24a435f500000000, 0x9bac2a3c00000000, 0x31a9f0cd00000000, - 0xf08f719600000000, 0x5a8aab6700000000, 0xe582b4ae00000000, - 0x4f876e5f00000000, 0xda95fbe700000000, 0x7090211600000000, - 0xcf983edf00000000, 0x659de42e00000000, 0x4dd53c6800000000, - 0xe7d0e69900000000, 0x58d8f95000000000, 0xf2dd23a100000000, - 0x67cfb61900000000, 0xcdca6ce800000000, 0x72c2732100000000, - 0xd8c7a9d000000000, 0x19e1288b00000000, 0xb3e4f27a00000000, - 0x0cecedb300000000, 0xa6e9374200000000, 0x33fba2fa00000000, - 0x99fe780b00000000, 0x26f667c200000000, 0x8cf3bd3300000000, - 0x7666d74f00000000, 0xdc630dbe00000000, 0x636b127700000000, - 0xc96ec88600000000, 0x5c7c5d3e00000000, 0xf67987cf00000000, - 0x4971980600000000, 0xe37442f700000000, 0x2252c3ac00000000, - 0x8857195d00000000, 0x375f069400000000, 0x9d5adc6500000000, - 0x084849dd00000000, 0xa24d932c00000000, 0x1d458ce500000000, - 0xb740561400000000, 0x9f088e5200000000, 0x350d54a300000000, - 0x8a054b6a00000000, 0x2000919b00000000, 0xb512042300000000, - 0x1f17ded200000000, 0xa01fc11b00000000, 0x0a1a1bea00000000, - 0xcb3c9ab100000000, 0x6139404000000000, 0xde315f8900000000, - 0x7434857800000000, 0xe12610c000000000, 0x4b23ca3100000000, - 0xf42bd5f800000000, 0x5e2e0f0900000000, 0x4877cbea00000000, - 0xe272111b00000000, 0x5d7a0ed200000000, 0xf77fd42300000000, - 0x626d419b00000000, 0xc8689b6a00000000, 0x776084a300000000, - 0xdd655e5200000000, 0x1c43df0900000000, 0xb64605f800000000, - 0x094e1a3100000000, 0xa34bc0c000000000, 0x3659557800000000, - 0x9c5c8f8900000000, 0x2354904000000000, 0x89514ab100000000, - 0xa11992f700000000, 0x0b1c480600000000, 0xb41457cf00000000, - 0x1e118d3e00000000, 0x8b03188600000000, 0x2106c27700000000, - 0x9e0eddbe00000000, 0x340b074f00000000, 0xf52d861400000000, - 0x5f285ce500000000, 0xe020432c00000000, 0x4a2599dd00000000, - 0xdf370c6500000000, 0x7532d69400000000, 0xca3ac95d00000000, - 0x603f13ac00000000, 0x9aaa79d000000000, 0x30afa32100000000, - 0x8fa7bce800000000, 0x25a2661900000000, 0xb0b0f3a100000000, - 0x1ab5295000000000, 0xa5bd369900000000, 0x0fb8ec6800000000, - 0xce9e6d3300000000, 0x649bb7c200000000, 0xdb93a80b00000000, - 0x719672fa00000000, 0xe484e74200000000, 0x4e813db300000000, - 0xf189227a00000000, 0x5b8cf88b00000000, 0x73c420cd00000000, - 0xd9c1fa3c00000000, 0x66c9e5f500000000, 0xcccc3f0400000000, - 0x59deaabc00000000, 0xf3db704d00000000, 0x4cd36f8400000000, - 0xe6d6b57500000000, 0x27f0342e00000000, 0x8df5eedf00000000, - 0x32fdf11600000000, 0x98f82be700000000, 0x0deabe5f00000000, - 0xa7ef64ae00000000, 0x18e77b6700000000, 0xb2e2a19600000000, - 0xecccae9f00000000, 0x46c9746e00000000, 0xf9c16ba700000000, - 0x53c4b15600000000, 0xc6d624ee00000000, 0x6cd3fe1f00000000, - 0xd3dbe1d600000000, 0x79de3b2700000000, 0xb8f8ba7c00000000, - 0x12fd608d00000000, 0xadf57f4400000000, 0x07f0a5b500000000, - 0x92e2300d00000000, 0x38e7eafc00000000, 0x87eff53500000000, - 0x2dea2fc400000000, 0x05a2f78200000000, 0xafa72d7300000000, - 0x10af32ba00000000, 0xbaaae84b00000000, 0x2fb87df300000000, - 0x85bda70200000000, 0x3ab5b8cb00000000, 0x90b0623a00000000, - 0x5196e36100000000, 0xfb93399000000000, 0x449b265900000000, - 0xee9efca800000000, 0x7b8c691000000000, 0xd189b3e100000000, - 0x6e81ac2800000000, 0xc48476d900000000, 0x3e111ca500000000, - 0x9414c65400000000, 0x2b1cd99d00000000, 0x8119036c00000000, - 0x140b96d400000000, 0xbe0e4c2500000000, 0x010653ec00000000, - 0xab03891d00000000, 0x6a25084600000000, 0xc020d2b700000000, - 0x7f28cd7e00000000, 0xd52d178f00000000, 0x403f823700000000, - 0xea3a58c600000000, 0x5532470f00000000, 0xff379dfe00000000, - 0xd77f45b800000000, 0x7d7a9f4900000000, 0xc272808000000000, - 0x68775a7100000000, 0xfd65cfc900000000, 0x5760153800000000, - 0xe8680af100000000, 0x426dd00000000000, 0x834b515b00000000, - 0x294e8baa00000000, 0x9646946300000000, 0x3c434e9200000000, - 0xa951db2a00000000, 0x035401db00000000, 0xbc5c1e1200000000, - 0x1659c4e300000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, - 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, - 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, - 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, - 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, - 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, - 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, - 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, - 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, - 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, - 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, - 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, - 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, - 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, - 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, - 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, - 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, - 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, - 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, - 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, - 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, - 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, - 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, - 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, - 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, - 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, - 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, - 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, - 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, - 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, - 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, - 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, - 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, - 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, - 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, - 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, - 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, - 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, - 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, - 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, - 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, - 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, - 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, - 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, - 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, - 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, - 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, - 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, - 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, - 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, - 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, - 0x0d7139d7}, - {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, - 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, - 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, - 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, - 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, - 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, - 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, - 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, - 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, - 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, - 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, - 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, - 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, - 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, - 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, - 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, - 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, - 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, - 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, - 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, - 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, - 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, - 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, - 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, - 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, - 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, - 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, - 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, - 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, - 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, - 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, - 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, - 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, - 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, - 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, - 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, - 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, - 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, - 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, - 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, - 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, - 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, - 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, - 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, - 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, - 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, - 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, - 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, - 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, - 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, - 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, - 0x1c53e98a}, - {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, - 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, - 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, - 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, - 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, - 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, - 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, - 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, - 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, - 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, - 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, - 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, - 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, - 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, - 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, - 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, - 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, - 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, - 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, - 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, - 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, - 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, - 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, - 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, - 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, - 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, - 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, - 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, - 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, - 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, - 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, - 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, - 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, - 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, - 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, - 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, - 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, - 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, - 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, - 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, - 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, - 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, - 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, - 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, - 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, - 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, - 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, - 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, - 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, - 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, - 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, - 0x3f88e851}, - {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, - 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, - 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, - 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, - 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, - 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, - 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, - 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, - 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, - 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, - 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, - 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, - 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, - 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, - 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, - 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, - 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, - 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, - 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, - 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, - 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, - 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, - 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, - 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, - 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, - 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, - 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, - 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, - 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, - 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, - 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, - 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, - 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, - 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, - 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, - 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, - 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, - 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, - 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, - 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, - 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, - 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, - 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, - 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, - 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, - 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, - 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, - 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, - 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, - 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, - 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, - 0x3dee8ca6}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x85d996dd, 0x4bb55c60, 0xce6ccabd, 0x966ab9c0, - 0x13b32f1d, 0xdddfe5a0, 0x5806737d, 0x6dd3035a, 0xe80a9587, - 0x26665f3a, 0xa3bfc9e7, 0xfbb9ba9a, 0x7e602c47, 0xb00ce6fa, - 0x35d57027, 0xdaa607b4, 0x5f7f9169, 0x91135bd4, 0x14cacd09, - 0x4cccbe74, 0xc91528a9, 0x0779e214, 0x82a074c9, 0xb77504ee, - 0x32ac9233, 0xfcc0588e, 0x7919ce53, 0x211fbd2e, 0xa4c62bf3, - 0x6aaae14e, 0xef737793, 0xf54b7eb3, 0x7092e86e, 0xbefe22d3, - 0x3b27b40e, 0x6321c773, 0xe6f851ae, 0x28949b13, 0xad4d0dce, - 0x98987de9, 0x1d41eb34, 0xd32d2189, 0x56f4b754, 0x0ef2c429, - 0x8b2b52f4, 0x45479849, 0xc09e0e94, 0x2fed7907, 0xaa34efda, - 0x64582567, 0xe181b3ba, 0xb987c0c7, 0x3c5e561a, 0xf2329ca7, - 0x77eb0a7a, 0x423e7a5d, 0xc7e7ec80, 0x098b263d, 0x8c52b0e0, - 0xd454c39d, 0x518d5540, 0x9fe19ffd, 0x1a380920, 0xab918dbd, - 0x2e481b60, 0xe024d1dd, 0x65fd4700, 0x3dfb347d, 0xb822a2a0, - 0x764e681d, 0xf397fec0, 0xc6428ee7, 0x439b183a, 0x8df7d287, - 0x082e445a, 0x50283727, 0xd5f1a1fa, 0x1b9d6b47, 0x9e44fd9a, - 0x71378a09, 0xf4ee1cd4, 0x3a82d669, 0xbf5b40b4, 0xe75d33c9, - 0x6284a514, 0xace86fa9, 0x2931f974, 0x1ce48953, 0x993d1f8e, - 0x5751d533, 0xd28843ee, 0x8a8e3093, 0x0f57a64e, 0xc13b6cf3, - 0x44e2fa2e, 0x5edaf30e, 0xdb0365d3, 0x156faf6e, 0x90b639b3, - 0xc8b04ace, 0x4d69dc13, 0x830516ae, 0x06dc8073, 0x3309f054, - 0xb6d06689, 0x78bcac34, 0xfd653ae9, 0xa5634994, 0x20badf49, - 0xeed615f4, 0x6b0f8329, 0x847cf4ba, 0x01a56267, 0xcfc9a8da, - 0x4a103e07, 0x12164d7a, 0x97cfdba7, 0x59a3111a, 0xdc7a87c7, - 0xe9aff7e0, 0x6c76613d, 0xa21aab80, 0x27c33d5d, 0x7fc54e20, - 0xfa1cd8fd, 0x34701240, 0xb1a9849d, 0x17256aa0, 0x92fcfc7d, - 0x5c9036c0, 0xd949a01d, 0x814fd360, 0x049645bd, 0xcafa8f00, - 0x4f2319dd, 0x7af669fa, 0xff2fff27, 0x3143359a, 0xb49aa347, - 0xec9cd03a, 0x694546e7, 0xa7298c5a, 0x22f01a87, 0xcd836d14, - 0x485afbc9, 0x86363174, 0x03efa7a9, 0x5be9d4d4, 0xde304209, - 0x105c88b4, 0x95851e69, 0xa0506e4e, 0x2589f893, 0xebe5322e, - 0x6e3ca4f3, 0x363ad78e, 0xb3e34153, 0x7d8f8bee, 0xf8561d33, - 0xe26e1413, 0x67b782ce, 0xa9db4873, 0x2c02deae, 0x7404add3, - 0xf1dd3b0e, 0x3fb1f1b3, 0xba68676e, 0x8fbd1749, 0x0a648194, - 0xc4084b29, 0x41d1ddf4, 0x19d7ae89, 0x9c0e3854, 0x5262f2e9, - 0xd7bb6434, 0x38c813a7, 0xbd11857a, 0x737d4fc7, 0xf6a4d91a, - 0xaea2aa67, 0x2b7b3cba, 0xe517f607, 0x60ce60da, 0x551b10fd, - 0xd0c28620, 0x1eae4c9d, 0x9b77da40, 0xc371a93d, 0x46a83fe0, - 0x88c4f55d, 0x0d1d6380, 0xbcb4e71d, 0x396d71c0, 0xf701bb7d, - 0x72d82da0, 0x2ade5edd, 0xaf07c800, 0x616b02bd, 0xe4b29460, - 0xd167e447, 0x54be729a, 0x9ad2b827, 0x1f0b2efa, 0x470d5d87, - 0xc2d4cb5a, 0x0cb801e7, 0x8961973a, 0x6612e0a9, 0xe3cb7674, - 0x2da7bcc9, 0xa87e2a14, 0xf0785969, 0x75a1cfb4, 0xbbcd0509, - 0x3e1493d4, 0x0bc1e3f3, 0x8e18752e, 0x4074bf93, 0xc5ad294e, - 0x9dab5a33, 0x1872ccee, 0xd61e0653, 0x53c7908e, 0x49ff99ae, - 0xcc260f73, 0x024ac5ce, 0x87935313, 0xdf95206e, 0x5a4cb6b3, - 0x94207c0e, 0x11f9ead3, 0x242c9af4, 0xa1f50c29, 0x6f99c694, - 0xea405049, 0xb2462334, 0x379fb5e9, 0xf9f37f54, 0x7c2ae989, - 0x93599e1a, 0x168008c7, 0xd8ecc27a, 0x5d3554a7, 0x053327da, - 0x80eab107, 0x4e867bba, 0xcb5fed67, 0xfe8a9d40, 0x7b530b9d, - 0xb53fc120, 0x30e657fd, 0x68e02480, 0xed39b25d, 0x235578e0, - 0xa68cee3d}, - {0x00000000, 0x76e10f9d, 0xadc46ee1, 0xdb25617c, 0x1b8fac19, - 0x6d6ea384, 0xb64bc2f8, 0xc0aacd65, 0x361e5933, 0x40ff56ae, - 0x9bda37d2, 0xed3b384f, 0x2d91f52a, 0x5b70fab7, 0x80559bcb, - 0xf6b49456, 0x6c3cb266, 0x1addbdfb, 0xc1f8dc87, 0xb719d31a, - 0x77b31e7f, 0x015211e2, 0xda77709e, 0xac967f03, 0x5a22eb55, - 0x2cc3e4c8, 0xf7e685b4, 0x81078a29, 0x41ad474c, 0x374c48d1, - 0xec6929ad, 0x9a882630, 0xd87864cd, 0xae996b50, 0x75bc0a2c, - 0x035d05b1, 0xc3f7c8d4, 0xb516c749, 0x6e33a635, 0x18d2a9a8, - 0xee663dfe, 0x98873263, 0x43a2531f, 0x35435c82, 0xf5e991e7, - 0x83089e7a, 0x582dff06, 0x2eccf09b, 0xb444d6ab, 0xc2a5d936, - 0x1980b84a, 0x6f61b7d7, 0xafcb7ab2, 0xd92a752f, 0x020f1453, - 0x74ee1bce, 0x825a8f98, 0xf4bb8005, 0x2f9ee179, 0x597feee4, - 0x99d52381, 0xef342c1c, 0x34114d60, 0x42f042fd, 0xf1f7b941, - 0x8716b6dc, 0x5c33d7a0, 0x2ad2d83d, 0xea781558, 0x9c991ac5, - 0x47bc7bb9, 0x315d7424, 0xc7e9e072, 0xb108efef, 0x6a2d8e93, - 0x1ccc810e, 0xdc664c6b, 0xaa8743f6, 0x71a2228a, 0x07432d17, - 0x9dcb0b27, 0xeb2a04ba, 0x300f65c6, 0x46ee6a5b, 0x8644a73e, - 0xf0a5a8a3, 0x2b80c9df, 0x5d61c642, 0xabd55214, 0xdd345d89, - 0x06113cf5, 0x70f03368, 0xb05afe0d, 0xc6bbf190, 0x1d9e90ec, - 0x6b7f9f71, 0x298fdd8c, 0x5f6ed211, 0x844bb36d, 0xf2aabcf0, - 0x32007195, 0x44e17e08, 0x9fc41f74, 0xe92510e9, 0x1f9184bf, - 0x69708b22, 0xb255ea5e, 0xc4b4e5c3, 0x041e28a6, 0x72ff273b, - 0xa9da4647, 0xdf3b49da, 0x45b36fea, 0x33526077, 0xe877010b, - 0x9e960e96, 0x5e3cc3f3, 0x28ddcc6e, 0xf3f8ad12, 0x8519a28f, - 0x73ad36d9, 0x054c3944, 0xde695838, 0xa88857a5, 0x68229ac0, - 0x1ec3955d, 0xc5e6f421, 0xb307fbbc, 0xe2ef7383, 0x940e7c1e, - 0x4f2b1d62, 0x39ca12ff, 0xf960df9a, 0x8f81d007, 0x54a4b17b, - 0x2245bee6, 0xd4f12ab0, 0xa210252d, 0x79354451, 0x0fd44bcc, - 0xcf7e86a9, 0xb99f8934, 0x62bae848, 0x145be7d5, 0x8ed3c1e5, - 0xf832ce78, 0x2317af04, 0x55f6a099, 0x955c6dfc, 0xe3bd6261, - 0x3898031d, 0x4e790c80, 0xb8cd98d6, 0xce2c974b, 0x1509f637, - 0x63e8f9aa, 0xa34234cf, 0xd5a33b52, 0x0e865a2e, 0x786755b3, - 0x3a97174e, 0x4c7618d3, 0x975379af, 0xe1b27632, 0x2118bb57, - 0x57f9b4ca, 0x8cdcd5b6, 0xfa3dda2b, 0x0c894e7d, 0x7a6841e0, - 0xa14d209c, 0xd7ac2f01, 0x1706e264, 0x61e7edf9, 0xbac28c85, - 0xcc238318, 0x56aba528, 0x204aaab5, 0xfb6fcbc9, 0x8d8ec454, - 0x4d240931, 0x3bc506ac, 0xe0e067d0, 0x9601684d, 0x60b5fc1b, - 0x1654f386, 0xcd7192fa, 0xbb909d67, 0x7b3a5002, 0x0ddb5f9f, - 0xd6fe3ee3, 0xa01f317e, 0x1318cac2, 0x65f9c55f, 0xbedca423, - 0xc83dabbe, 0x089766db, 0x7e766946, 0xa553083a, 0xd3b207a7, - 0x250693f1, 0x53e79c6c, 0x88c2fd10, 0xfe23f28d, 0x3e893fe8, - 0x48683075, 0x934d5109, 0xe5ac5e94, 0x7f2478a4, 0x09c57739, - 0xd2e01645, 0xa40119d8, 0x64abd4bd, 0x124adb20, 0xc96fba5c, - 0xbf8eb5c1, 0x493a2197, 0x3fdb2e0a, 0xe4fe4f76, 0x921f40eb, - 0x52b58d8e, 0x24548213, 0xff71e36f, 0x8990ecf2, 0xcb60ae0f, - 0xbd81a192, 0x66a4c0ee, 0x1045cf73, 0xd0ef0216, 0xa60e0d8b, - 0x7d2b6cf7, 0x0bca636a, 0xfd7ef73c, 0x8b9ff8a1, 0x50ba99dd, - 0x265b9640, 0xe6f15b25, 0x901054b8, 0x4b3535c4, 0x3dd43a59, - 0xa75c1c69, 0xd1bd13f4, 0x0a987288, 0x7c797d15, 0xbcd3b070, - 0xca32bfed, 0x1117de91, 0x67f6d10c, 0x9142455a, 0xe7a34ac7, - 0x3c862bbb, 0x4a672426, 0x8acde943, 0xfc2ce6de, 0x270987a2, - 0x51e8883f}, - {0x00000000, 0xe8dbfbb9, 0x91b186a8, 0x796a7d11, 0x63657c8a, - 0x8bbe8733, 0xf2d4fa22, 0x1a0f019b, 0x87cc89cf, 0x6f177276, - 0x167d0f67, 0xfea6f4de, 0xe4a9f545, 0x0c720efc, 0x751873ed, - 0x9dc38854, 0x4f9f6244, 0xa74499fd, 0xde2ee4ec, 0x36f51f55, - 0x2cfa1ece, 0xc421e577, 0xbd4b9866, 0x559063df, 0xc853eb8b, - 0x20881032, 0x59e26d23, 0xb139969a, 0xab369701, 0x43ed6cb8, - 0x3a8711a9, 0xd25cea10, 0x9e3ec588, 0x76e53e31, 0x0f8f4320, - 0xe754b899, 0xfd5bb902, 0x158042bb, 0x6cea3faa, 0x8431c413, - 0x19f24c47, 0xf129b7fe, 0x8843caef, 0x60983156, 0x7a9730cd, - 0x924ccb74, 0xeb26b665, 0x03fd4ddc, 0xd1a1a7cc, 0x397a5c75, - 0x40102164, 0xa8cbdadd, 0xb2c4db46, 0x5a1f20ff, 0x23755dee, - 0xcbaea657, 0x566d2e03, 0xbeb6d5ba, 0xc7dca8ab, 0x2f075312, - 0x35085289, 0xddd3a930, 0xa4b9d421, 0x4c622f98, 0x7d7bfbca, - 0x95a00073, 0xecca7d62, 0x041186db, 0x1e1e8740, 0xf6c57cf9, - 0x8faf01e8, 0x6774fa51, 0xfab77205, 0x126c89bc, 0x6b06f4ad, - 0x83dd0f14, 0x99d20e8f, 0x7109f536, 0x08638827, 0xe0b8739e, - 0x32e4998e, 0xda3f6237, 0xa3551f26, 0x4b8ee49f, 0x5181e504, - 0xb95a1ebd, 0xc03063ac, 0x28eb9815, 0xb5281041, 0x5df3ebf8, - 0x249996e9, 0xcc426d50, 0xd64d6ccb, 0x3e969772, 0x47fcea63, - 0xaf2711da, 0xe3453e42, 0x0b9ec5fb, 0x72f4b8ea, 0x9a2f4353, - 0x802042c8, 0x68fbb971, 0x1191c460, 0xf94a3fd9, 0x6489b78d, - 0x8c524c34, 0xf5383125, 0x1de3ca9c, 0x07eccb07, 0xef3730be, - 0x965d4daf, 0x7e86b616, 0xacda5c06, 0x4401a7bf, 0x3d6bdaae, - 0xd5b02117, 0xcfbf208c, 0x2764db35, 0x5e0ea624, 0xb6d55d9d, - 0x2b16d5c9, 0xc3cd2e70, 0xbaa75361, 0x527ca8d8, 0x4873a943, - 0xa0a852fa, 0xd9c22feb, 0x3119d452, 0xbbf0874e, 0x532b7cf7, - 0x2a4101e6, 0xc29afa5f, 0xd895fbc4, 0x304e007d, 0x49247d6c, - 0xa1ff86d5, 0x3c3c0e81, 0xd4e7f538, 0xad8d8829, 0x45567390, - 0x5f59720b, 0xb78289b2, 0xcee8f4a3, 0x26330f1a, 0xf46fe50a, - 0x1cb41eb3, 0x65de63a2, 0x8d05981b, 0x970a9980, 0x7fd16239, - 0x06bb1f28, 0xee60e491, 0x73a36cc5, 0x9b78977c, 0xe212ea6d, - 0x0ac911d4, 0x10c6104f, 0xf81debf6, 0x817796e7, 0x69ac6d5e, - 0x25ce42c6, 0xcd15b97f, 0xb47fc46e, 0x5ca43fd7, 0x46ab3e4c, - 0xae70c5f5, 0xd71ab8e4, 0x3fc1435d, 0xa202cb09, 0x4ad930b0, - 0x33b34da1, 0xdb68b618, 0xc167b783, 0x29bc4c3a, 0x50d6312b, - 0xb80dca92, 0x6a512082, 0x828adb3b, 0xfbe0a62a, 0x133b5d93, - 0x09345c08, 0xe1efa7b1, 0x9885daa0, 0x705e2119, 0xed9da94d, - 0x054652f4, 0x7c2c2fe5, 0x94f7d45c, 0x8ef8d5c7, 0x66232e7e, - 0x1f49536f, 0xf792a8d6, 0xc68b7c84, 0x2e50873d, 0x573afa2c, - 0xbfe10195, 0xa5ee000e, 0x4d35fbb7, 0x345f86a6, 0xdc847d1f, - 0x4147f54b, 0xa99c0ef2, 0xd0f673e3, 0x382d885a, 0x222289c1, - 0xcaf97278, 0xb3930f69, 0x5b48f4d0, 0x89141ec0, 0x61cfe579, - 0x18a59868, 0xf07e63d1, 0xea71624a, 0x02aa99f3, 0x7bc0e4e2, - 0x931b1f5b, 0x0ed8970f, 0xe6036cb6, 0x9f6911a7, 0x77b2ea1e, - 0x6dbdeb85, 0x8566103c, 0xfc0c6d2d, 0x14d79694, 0x58b5b90c, - 0xb06e42b5, 0xc9043fa4, 0x21dfc41d, 0x3bd0c586, 0xd30b3e3f, - 0xaa61432e, 0x42bab897, 0xdf7930c3, 0x37a2cb7a, 0x4ec8b66b, - 0xa6134dd2, 0xbc1c4c49, 0x54c7b7f0, 0x2dadcae1, 0xc5763158, - 0x172adb48, 0xfff120f1, 0x869b5de0, 0x6e40a659, 0x744fa7c2, - 0x9c945c7b, 0xe5fe216a, 0x0d25dad3, 0x90e65287, 0x783da93e, - 0x0157d42f, 0xe98c2f96, 0xf3832e0d, 0x1b58d5b4, 0x6232a8a5, - 0x8ae9531c}, - {0x00000000, 0x919168ae, 0x6325a087, 0xf2b4c829, 0x874c31d4, - 0x16dd597a, 0xe4699153, 0x75f8f9fd, 0x4f9f1373, 0xde0e7bdd, - 0x2cbab3f4, 0xbd2bdb5a, 0xc8d322a7, 0x59424a09, 0xabf68220, - 0x3a67ea8e, 0x9e3e27e6, 0x0faf4f48, 0xfd1b8761, 0x6c8aefcf, - 0x19721632, 0x88e37e9c, 0x7a57b6b5, 0xebc6de1b, 0xd1a13495, - 0x40305c3b, 0xb2849412, 0x2315fcbc, 0x56ed0541, 0xc77c6def, - 0x35c8a5c6, 0xa459cd68, 0x7d7b3f17, 0xecea57b9, 0x1e5e9f90, - 0x8fcff73e, 0xfa370ec3, 0x6ba6666d, 0x9912ae44, 0x0883c6ea, - 0x32e42c64, 0xa37544ca, 0x51c18ce3, 0xc050e44d, 0xb5a81db0, - 0x2439751e, 0xd68dbd37, 0x471cd599, 0xe34518f1, 0x72d4705f, - 0x8060b876, 0x11f1d0d8, 0x64092925, 0xf598418b, 0x072c89a2, - 0x96bde10c, 0xacda0b82, 0x3d4b632c, 0xcfffab05, 0x5e6ec3ab, - 0x2b963a56, 0xba0752f8, 0x48b39ad1, 0xd922f27f, 0xfaf67e2e, - 0x6b671680, 0x99d3dea9, 0x0842b607, 0x7dba4ffa, 0xec2b2754, - 0x1e9fef7d, 0x8f0e87d3, 0xb5696d5d, 0x24f805f3, 0xd64ccdda, - 0x47dda574, 0x32255c89, 0xa3b43427, 0x5100fc0e, 0xc09194a0, - 0x64c859c8, 0xf5593166, 0x07edf94f, 0x967c91e1, 0xe384681c, - 0x721500b2, 0x80a1c89b, 0x1130a035, 0x2b574abb, 0xbac62215, - 0x4872ea3c, 0xd9e38292, 0xac1b7b6f, 0x3d8a13c1, 0xcf3edbe8, - 0x5eafb346, 0x878d4139, 0x161c2997, 0xe4a8e1be, 0x75398910, - 0x00c170ed, 0x91501843, 0x63e4d06a, 0xf275b8c4, 0xc812524a, - 0x59833ae4, 0xab37f2cd, 0x3aa69a63, 0x4f5e639e, 0xdecf0b30, - 0x2c7bc319, 0xbdeaabb7, 0x19b366df, 0x88220e71, 0x7a96c658, - 0xeb07aef6, 0x9eff570b, 0x0f6e3fa5, 0xfddaf78c, 0x6c4b9f22, - 0x562c75ac, 0xc7bd1d02, 0x3509d52b, 0xa498bd85, 0xd1604478, - 0x40f12cd6, 0xb245e4ff, 0x23d48c51, 0xf4edfd5c, 0x657c95f2, - 0x97c85ddb, 0x06593575, 0x73a1cc88, 0xe230a426, 0x10846c0f, - 0x811504a1, 0xbb72ee2f, 0x2ae38681, 0xd8574ea8, 0x49c62606, - 0x3c3edffb, 0xadafb755, 0x5f1b7f7c, 0xce8a17d2, 0x6ad3daba, - 0xfb42b214, 0x09f67a3d, 0x98671293, 0xed9feb6e, 0x7c0e83c0, - 0x8eba4be9, 0x1f2b2347, 0x254cc9c9, 0xb4dda167, 0x4669694e, - 0xd7f801e0, 0xa200f81d, 0x339190b3, 0xc125589a, 0x50b43034, - 0x8996c24b, 0x1807aae5, 0xeab362cc, 0x7b220a62, 0x0edaf39f, - 0x9f4b9b31, 0x6dff5318, 0xfc6e3bb6, 0xc609d138, 0x5798b996, - 0xa52c71bf, 0x34bd1911, 0x4145e0ec, 0xd0d48842, 0x2260406b, - 0xb3f128c5, 0x17a8e5ad, 0x86398d03, 0x748d452a, 0xe51c2d84, - 0x90e4d479, 0x0175bcd7, 0xf3c174fe, 0x62501c50, 0x5837f6de, - 0xc9a69e70, 0x3b125659, 0xaa833ef7, 0xdf7bc70a, 0x4eeaafa4, - 0xbc5e678d, 0x2dcf0f23, 0x0e1b8372, 0x9f8aebdc, 0x6d3e23f5, - 0xfcaf4b5b, 0x8957b2a6, 0x18c6da08, 0xea721221, 0x7be37a8f, - 0x41849001, 0xd015f8af, 0x22a13086, 0xb3305828, 0xc6c8a1d5, - 0x5759c97b, 0xa5ed0152, 0x347c69fc, 0x9025a494, 0x01b4cc3a, - 0xf3000413, 0x62916cbd, 0x17699540, 0x86f8fdee, 0x744c35c7, - 0xe5dd5d69, 0xdfbab7e7, 0x4e2bdf49, 0xbc9f1760, 0x2d0e7fce, - 0x58f68633, 0xc967ee9d, 0x3bd326b4, 0xaa424e1a, 0x7360bc65, - 0xe2f1d4cb, 0x10451ce2, 0x81d4744c, 0xf42c8db1, 0x65bde51f, - 0x97092d36, 0x06984598, 0x3cffaf16, 0xad6ec7b8, 0x5fda0f91, - 0xce4b673f, 0xbbb39ec2, 0x2a22f66c, 0xd8963e45, 0x490756eb, - 0xed5e9b83, 0x7ccff32d, 0x8e7b3b04, 0x1fea53aa, 0x6a12aa57, - 0xfb83c2f9, 0x09370ad0, 0x98a6627e, 0xa2c188f0, 0x3350e05e, - 0xc1e42877, 0x507540d9, 0x258db924, 0xb41cd18a, 0x46a819a3, - 0xd739710d}}; - -#endif - -#endif - -#if N == 5 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xaf449247, 0x85f822cf, 0x2abcb088, 0xd08143df, - 0x7fc5d198, 0x55796110, 0xfa3df357, 0x7a7381ff, 0xd53713b8, - 0xff8ba330, 0x50cf3177, 0xaaf2c220, 0x05b65067, 0x2f0ae0ef, - 0x804e72a8, 0xf4e703fe, 0x5ba391b9, 0x711f2131, 0xde5bb376, - 0x24664021, 0x8b22d266, 0xa19e62ee, 0x0edaf0a9, 0x8e948201, - 0x21d01046, 0x0b6ca0ce, 0xa4283289, 0x5e15c1de, 0xf1515399, - 0xdbede311, 0x74a97156, 0x32bf01bd, 0x9dfb93fa, 0xb7472372, - 0x1803b135, 0xe23e4262, 0x4d7ad025, 0x67c660ad, 0xc882f2ea, - 0x48cc8042, 0xe7881205, 0xcd34a28d, 0x627030ca, 0x984dc39d, - 0x370951da, 0x1db5e152, 0xb2f17315, 0xc6580243, 0x691c9004, - 0x43a0208c, 0xece4b2cb, 0x16d9419c, 0xb99dd3db, 0x93216353, - 0x3c65f114, 0xbc2b83bc, 0x136f11fb, 0x39d3a173, 0x96973334, - 0x6caac063, 0xc3ee5224, 0xe952e2ac, 0x461670eb, 0x657e037a, - 0xca3a913d, 0xe08621b5, 0x4fc2b3f2, 0xb5ff40a5, 0x1abbd2e2, - 0x3007626a, 0x9f43f02d, 0x1f0d8285, 0xb04910c2, 0x9af5a04a, - 0x35b1320d, 0xcf8cc15a, 0x60c8531d, 0x4a74e395, 0xe53071d2, - 0x91990084, 0x3edd92c3, 0x1461224b, 0xbb25b00c, 0x4118435b, - 0xee5cd11c, 0xc4e06194, 0x6ba4f3d3, 0xebea817b, 0x44ae133c, - 0x6e12a3b4, 0xc15631f3, 0x3b6bc2a4, 0x942f50e3, 0xbe93e06b, - 0x11d7722c, 0x57c102c7, 0xf8859080, 0xd2392008, 0x7d7db24f, - 0x87404118, 0x2804d35f, 0x02b863d7, 0xadfcf190, 0x2db28338, - 0x82f6117f, 0xa84aa1f7, 0x070e33b0, 0xfd33c0e7, 0x527752a0, - 0x78cbe228, 0xd78f706f, 0xa3260139, 0x0c62937e, 0x26de23f6, - 0x899ab1b1, 0x73a742e6, 0xdce3d0a1, 0xf65f6029, 0x591bf26e, - 0xd95580c6, 0x76111281, 0x5cada209, 0xf3e9304e, 0x09d4c319, - 0xa690515e, 0x8c2ce1d6, 0x23687391, 0xcafc06f4, 0x65b894b3, - 0x4f04243b, 0xe040b67c, 0x1a7d452b, 0xb539d76c, 0x9f8567e4, - 0x30c1f5a3, 0xb08f870b, 0x1fcb154c, 0x3577a5c4, 0x9a333783, - 0x600ec4d4, 0xcf4a5693, 0xe5f6e61b, 0x4ab2745c, 0x3e1b050a, - 0x915f974d, 0xbbe327c5, 0x14a7b582, 0xee9a46d5, 0x41ded492, - 0x6b62641a, 0xc426f65d, 0x446884f5, 0xeb2c16b2, 0xc190a63a, - 0x6ed4347d, 0x94e9c72a, 0x3bad556d, 0x1111e5e5, 0xbe5577a2, - 0xf8430749, 0x5707950e, 0x7dbb2586, 0xd2ffb7c1, 0x28c24496, - 0x8786d6d1, 0xad3a6659, 0x027ef41e, 0x823086b6, 0x2d7414f1, - 0x07c8a479, 0xa88c363e, 0x52b1c569, 0xfdf5572e, 0xd749e7a6, - 0x780d75e1, 0x0ca404b7, 0xa3e096f0, 0x895c2678, 0x2618b43f, - 0xdc254768, 0x7361d52f, 0x59dd65a7, 0xf699f7e0, 0x76d78548, - 0xd993170f, 0xf32fa787, 0x5c6b35c0, 0xa656c697, 0x091254d0, - 0x23aee458, 0x8cea761f, 0xaf82058e, 0x00c697c9, 0x2a7a2741, - 0x853eb506, 0x7f034651, 0xd047d416, 0xfafb649e, 0x55bff6d9, - 0xd5f18471, 0x7ab51636, 0x5009a6be, 0xff4d34f9, 0x0570c7ae, - 0xaa3455e9, 0x8088e561, 0x2fcc7726, 0x5b650670, 0xf4219437, - 0xde9d24bf, 0x71d9b6f8, 0x8be445af, 0x24a0d7e8, 0x0e1c6760, - 0xa158f527, 0x2116878f, 0x8e5215c8, 0xa4eea540, 0x0baa3707, - 0xf197c450, 0x5ed35617, 0x746fe69f, 0xdb2b74d8, 0x9d3d0433, - 0x32799674, 0x18c526fc, 0xb781b4bb, 0x4dbc47ec, 0xe2f8d5ab, - 0xc8446523, 0x6700f764, 0xe74e85cc, 0x480a178b, 0x62b6a703, - 0xcdf23544, 0x37cfc613, 0x988b5454, 0xb237e4dc, 0x1d73769b, - 0x69da07cd, 0xc69e958a, 0xec222502, 0x4366b745, 0xb95b4412, - 0x161fd655, 0x3ca366dd, 0x93e7f49a, 0x13a98632, 0xbced1475, - 0x9651a4fd, 0x391536ba, 0xc328c5ed, 0x6c6c57aa, 0x46d0e722, - 0xe9947565}, - {0x00000000, 0x4e890ba9, 0x9d121752, 0xd39b1cfb, 0xe15528e5, - 0xafdc234c, 0x7c473fb7, 0x32ce341e, 0x19db578b, 0x57525c22, - 0x84c940d9, 0xca404b70, 0xf88e7f6e, 0xb60774c7, 0x659c683c, - 0x2b156395, 0x33b6af16, 0x7d3fa4bf, 0xaea4b844, 0xe02db3ed, - 0xd2e387f3, 0x9c6a8c5a, 0x4ff190a1, 0x01789b08, 0x2a6df89d, - 0x64e4f334, 0xb77fefcf, 0xf9f6e466, 0xcb38d078, 0x85b1dbd1, - 0x562ac72a, 0x18a3cc83, 0x676d5e2c, 0x29e45585, 0xfa7f497e, - 0xb4f642d7, 0x863876c9, 0xc8b17d60, 0x1b2a619b, 0x55a36a32, - 0x7eb609a7, 0x303f020e, 0xe3a41ef5, 0xad2d155c, 0x9fe32142, - 0xd16a2aeb, 0x02f13610, 0x4c783db9, 0x54dbf13a, 0x1a52fa93, - 0xc9c9e668, 0x8740edc1, 0xb58ed9df, 0xfb07d276, 0x289cce8d, - 0x6615c524, 0x4d00a6b1, 0x0389ad18, 0xd012b1e3, 0x9e9bba4a, - 0xac558e54, 0xe2dc85fd, 0x31479906, 0x7fce92af, 0xcedabc58, - 0x8053b7f1, 0x53c8ab0a, 0x1d41a0a3, 0x2f8f94bd, 0x61069f14, - 0xb29d83ef, 0xfc148846, 0xd701ebd3, 0x9988e07a, 0x4a13fc81, - 0x049af728, 0x3654c336, 0x78ddc89f, 0xab46d464, 0xe5cfdfcd, - 0xfd6c134e, 0xb3e518e7, 0x607e041c, 0x2ef70fb5, 0x1c393bab, - 0x52b03002, 0x812b2cf9, 0xcfa22750, 0xe4b744c5, 0xaa3e4f6c, - 0x79a55397, 0x372c583e, 0x05e26c20, 0x4b6b6789, 0x98f07b72, - 0xd67970db, 0xa9b7e274, 0xe73ee9dd, 0x34a5f526, 0x7a2cfe8f, - 0x48e2ca91, 0x066bc138, 0xd5f0ddc3, 0x9b79d66a, 0xb06cb5ff, - 0xfee5be56, 0x2d7ea2ad, 0x63f7a904, 0x51399d1a, 0x1fb096b3, - 0xcc2b8a48, 0x82a281e1, 0x9a014d62, 0xd48846cb, 0x07135a30, - 0x499a5199, 0x7b546587, 0x35dd6e2e, 0xe64672d5, 0xa8cf797c, - 0x83da1ae9, 0xcd531140, 0x1ec80dbb, 0x50410612, 0x628f320c, - 0x2c0639a5, 0xff9d255e, 0xb1142ef7, 0x46c47ef1, 0x084d7558, - 0xdbd669a3, 0x955f620a, 0xa7915614, 0xe9185dbd, 0x3a834146, - 0x740a4aef, 0x5f1f297a, 0x119622d3, 0xc20d3e28, 0x8c843581, - 0xbe4a019f, 0xf0c30a36, 0x235816cd, 0x6dd11d64, 0x7572d1e7, - 0x3bfbda4e, 0xe860c6b5, 0xa6e9cd1c, 0x9427f902, 0xdaaef2ab, - 0x0935ee50, 0x47bce5f9, 0x6ca9866c, 0x22208dc5, 0xf1bb913e, - 0xbf329a97, 0x8dfcae89, 0xc375a520, 0x10eeb9db, 0x5e67b272, - 0x21a920dd, 0x6f202b74, 0xbcbb378f, 0xf2323c26, 0xc0fc0838, - 0x8e750391, 0x5dee1f6a, 0x136714c3, 0x38727756, 0x76fb7cff, - 0xa5606004, 0xebe96bad, 0xd9275fb3, 0x97ae541a, 0x443548e1, - 0x0abc4348, 0x121f8fcb, 0x5c968462, 0x8f0d9899, 0xc1849330, - 0xf34aa72e, 0xbdc3ac87, 0x6e58b07c, 0x20d1bbd5, 0x0bc4d840, - 0x454dd3e9, 0x96d6cf12, 0xd85fc4bb, 0xea91f0a5, 0xa418fb0c, - 0x7783e7f7, 0x390aec5e, 0x881ec2a9, 0xc697c900, 0x150cd5fb, - 0x5b85de52, 0x694bea4c, 0x27c2e1e5, 0xf459fd1e, 0xbad0f6b7, - 0x91c59522, 0xdf4c9e8b, 0x0cd78270, 0x425e89d9, 0x7090bdc7, - 0x3e19b66e, 0xed82aa95, 0xa30ba13c, 0xbba86dbf, 0xf5216616, - 0x26ba7aed, 0x68337144, 0x5afd455a, 0x14744ef3, 0xc7ef5208, - 0x896659a1, 0xa2733a34, 0xecfa319d, 0x3f612d66, 0x71e826cf, - 0x432612d1, 0x0daf1978, 0xde340583, 0x90bd0e2a, 0xef739c85, - 0xa1fa972c, 0x72618bd7, 0x3ce8807e, 0x0e26b460, 0x40afbfc9, - 0x9334a332, 0xddbda89b, 0xf6a8cb0e, 0xb821c0a7, 0x6bbadc5c, - 0x2533d7f5, 0x17fde3eb, 0x5974e842, 0x8aeff4b9, 0xc466ff10, - 0xdcc53393, 0x924c383a, 0x41d724c1, 0x0f5e2f68, 0x3d901b76, - 0x731910df, 0xa0820c24, 0xee0b078d, 0xc51e6418, 0x8b976fb1, - 0x580c734a, 0x168578e3, 0x244b4cfd, 0x6ac24754, 0xb9595baf, - 0xf7d05006}, - {0x00000000, 0x8d88fde2, 0xc060fd85, 0x4de80067, 0x5bb0fd4b, - 0xd63800a9, 0x9bd000ce, 0x1658fd2c, 0xb761fa96, 0x3ae90774, - 0x77010713, 0xfa89faf1, 0xecd107dd, 0x6159fa3f, 0x2cb1fa58, - 0xa13907ba, 0xb5b2f36d, 0x383a0e8f, 0x75d20ee8, 0xf85af30a, - 0xee020e26, 0x638af3c4, 0x2e62f3a3, 0xa3ea0e41, 0x02d309fb, - 0x8f5bf419, 0xc2b3f47e, 0x4f3b099c, 0x5963f4b0, 0xd4eb0952, - 0x99030935, 0x148bf4d7, 0xb014e09b, 0x3d9c1d79, 0x70741d1e, - 0xfdfce0fc, 0xeba41dd0, 0x662ce032, 0x2bc4e055, 0xa64c1db7, - 0x07751a0d, 0x8afde7ef, 0xc715e788, 0x4a9d1a6a, 0x5cc5e746, - 0xd14d1aa4, 0x9ca51ac3, 0x112de721, 0x05a613f6, 0x882eee14, - 0xc5c6ee73, 0x484e1391, 0x5e16eebd, 0xd39e135f, 0x9e761338, - 0x13feeeda, 0xb2c7e960, 0x3f4f1482, 0x72a714e5, 0xff2fe907, - 0xe977142b, 0x64ffe9c9, 0x2917e9ae, 0xa49f144c, 0xbb58c777, - 0x36d03a95, 0x7b383af2, 0xf6b0c710, 0xe0e83a3c, 0x6d60c7de, - 0x2088c7b9, 0xad003a5b, 0x0c393de1, 0x81b1c003, 0xcc59c064, - 0x41d13d86, 0x5789c0aa, 0xda013d48, 0x97e93d2f, 0x1a61c0cd, - 0x0eea341a, 0x8362c9f8, 0xce8ac99f, 0x4302347d, 0x555ac951, - 0xd8d234b3, 0x953a34d4, 0x18b2c936, 0xb98bce8c, 0x3403336e, - 0x79eb3309, 0xf463ceeb, 0xe23b33c7, 0x6fb3ce25, 0x225bce42, - 0xafd333a0, 0x0b4c27ec, 0x86c4da0e, 0xcb2cda69, 0x46a4278b, - 0x50fcdaa7, 0xdd742745, 0x909c2722, 0x1d14dac0, 0xbc2ddd7a, - 0x31a52098, 0x7c4d20ff, 0xf1c5dd1d, 0xe79d2031, 0x6a15ddd3, - 0x27fdddb4, 0xaa752056, 0xbefed481, 0x33762963, 0x7e9e2904, - 0xf316d4e6, 0xe54e29ca, 0x68c6d428, 0x252ed44f, 0xa8a629ad, - 0x099f2e17, 0x8417d3f5, 0xc9ffd392, 0x44772e70, 0x522fd35c, - 0xdfa72ebe, 0x924f2ed9, 0x1fc7d33b, 0xadc088af, 0x2048754d, - 0x6da0752a, 0xe02888c8, 0xf67075e4, 0x7bf88806, 0x36108861, - 0xbb987583, 0x1aa17239, 0x97298fdb, 0xdac18fbc, 0x5749725e, - 0x41118f72, 0xcc997290, 0x817172f7, 0x0cf98f15, 0x18727bc2, - 0x95fa8620, 0xd8128647, 0x559a7ba5, 0x43c28689, 0xce4a7b6b, - 0x83a27b0c, 0x0e2a86ee, 0xaf138154, 0x229b7cb6, 0x6f737cd1, - 0xe2fb8133, 0xf4a37c1f, 0x792b81fd, 0x34c3819a, 0xb94b7c78, - 0x1dd46834, 0x905c95d6, 0xddb495b1, 0x503c6853, 0x4664957f, - 0xcbec689d, 0x860468fa, 0x0b8c9518, 0xaab592a2, 0x273d6f40, - 0x6ad56f27, 0xe75d92c5, 0xf1056fe9, 0x7c8d920b, 0x3165926c, - 0xbced6f8e, 0xa8669b59, 0x25ee66bb, 0x680666dc, 0xe58e9b3e, - 0xf3d66612, 0x7e5e9bf0, 0x33b69b97, 0xbe3e6675, 0x1f0761cf, - 0x928f9c2d, 0xdf679c4a, 0x52ef61a8, 0x44b79c84, 0xc93f6166, - 0x84d76101, 0x095f9ce3, 0x16984fd8, 0x9b10b23a, 0xd6f8b25d, - 0x5b704fbf, 0x4d28b293, 0xc0a04f71, 0x8d484f16, 0x00c0b2f4, - 0xa1f9b54e, 0x2c7148ac, 0x619948cb, 0xec11b529, 0xfa494805, - 0x77c1b5e7, 0x3a29b580, 0xb7a14862, 0xa32abcb5, 0x2ea24157, - 0x634a4130, 0xeec2bcd2, 0xf89a41fe, 0x7512bc1c, 0x38fabc7b, - 0xb5724199, 0x144b4623, 0x99c3bbc1, 0xd42bbba6, 0x59a34644, - 0x4ffbbb68, 0xc273468a, 0x8f9b46ed, 0x0213bb0f, 0xa68caf43, - 0x2b0452a1, 0x66ec52c6, 0xeb64af24, 0xfd3c5208, 0x70b4afea, - 0x3d5caf8d, 0xb0d4526f, 0x11ed55d5, 0x9c65a837, 0xd18da850, - 0x5c0555b2, 0x4a5da89e, 0xc7d5557c, 0x8a3d551b, 0x07b5a8f9, - 0x133e5c2e, 0x9eb6a1cc, 0xd35ea1ab, 0x5ed65c49, 0x488ea165, - 0xc5065c87, 0x88ee5ce0, 0x0566a102, 0xa45fa6b8, 0x29d75b5a, - 0x643f5b3d, 0xe9b7a6df, 0xffef5bf3, 0x7267a611, 0x3f8fa676, - 0xb2075b94}, - {0x00000000, 0x80f0171f, 0xda91287f, 0x5a613f60, 0x6e5356bf, - 0xeea341a0, 0xb4c27ec0, 0x343269df, 0xdca6ad7e, 0x5c56ba61, - 0x06378501, 0x86c7921e, 0xb2f5fbc1, 0x3205ecde, 0x6864d3be, - 0xe894c4a1, 0x623c5cbd, 0xe2cc4ba2, 0xb8ad74c2, 0x385d63dd, - 0x0c6f0a02, 0x8c9f1d1d, 0xd6fe227d, 0x560e3562, 0xbe9af1c3, - 0x3e6ae6dc, 0x640bd9bc, 0xe4fbcea3, 0xd0c9a77c, 0x5039b063, - 0x0a588f03, 0x8aa8981c, 0xc478b97a, 0x4488ae65, 0x1ee99105, - 0x9e19861a, 0xaa2befc5, 0x2adbf8da, 0x70bac7ba, 0xf04ad0a5, - 0x18de1404, 0x982e031b, 0xc24f3c7b, 0x42bf2b64, 0x768d42bb, - 0xf67d55a4, 0xac1c6ac4, 0x2cec7ddb, 0xa644e5c7, 0x26b4f2d8, - 0x7cd5cdb8, 0xfc25daa7, 0xc817b378, 0x48e7a467, 0x12869b07, - 0x92768c18, 0x7ae248b9, 0xfa125fa6, 0xa07360c6, 0x208377d9, - 0x14b11e06, 0x94410919, 0xce203679, 0x4ed02166, 0x538074b5, - 0xd37063aa, 0x89115cca, 0x09e14bd5, 0x3dd3220a, 0xbd233515, - 0xe7420a75, 0x67b21d6a, 0x8f26d9cb, 0x0fd6ced4, 0x55b7f1b4, - 0xd547e6ab, 0xe1758f74, 0x6185986b, 0x3be4a70b, 0xbb14b014, - 0x31bc2808, 0xb14c3f17, 0xeb2d0077, 0x6bdd1768, 0x5fef7eb7, - 0xdf1f69a8, 0x857e56c8, 0x058e41d7, 0xed1a8576, 0x6dea9269, - 0x378bad09, 0xb77bba16, 0x8349d3c9, 0x03b9c4d6, 0x59d8fbb6, - 0xd928eca9, 0x97f8cdcf, 0x1708dad0, 0x4d69e5b0, 0xcd99f2af, - 0xf9ab9b70, 0x795b8c6f, 0x233ab30f, 0xa3caa410, 0x4b5e60b1, - 0xcbae77ae, 0x91cf48ce, 0x113f5fd1, 0x250d360e, 0xa5fd2111, - 0xff9c1e71, 0x7f6c096e, 0xf5c49172, 0x7534866d, 0x2f55b90d, - 0xafa5ae12, 0x9b97c7cd, 0x1b67d0d2, 0x4106efb2, 0xc1f6f8ad, - 0x29623c0c, 0xa9922b13, 0xf3f31473, 0x7303036c, 0x47316ab3, - 0xc7c17dac, 0x9da042cc, 0x1d5055d3, 0xa700e96a, 0x27f0fe75, - 0x7d91c115, 0xfd61d60a, 0xc953bfd5, 0x49a3a8ca, 0x13c297aa, - 0x933280b5, 0x7ba64414, 0xfb56530b, 0xa1376c6b, 0x21c77b74, - 0x15f512ab, 0x950505b4, 0xcf643ad4, 0x4f942dcb, 0xc53cb5d7, - 0x45cca2c8, 0x1fad9da8, 0x9f5d8ab7, 0xab6fe368, 0x2b9ff477, - 0x71fecb17, 0xf10edc08, 0x199a18a9, 0x996a0fb6, 0xc30b30d6, - 0x43fb27c9, 0x77c94e16, 0xf7395909, 0xad586669, 0x2da87176, - 0x63785010, 0xe388470f, 0xb9e9786f, 0x39196f70, 0x0d2b06af, - 0x8ddb11b0, 0xd7ba2ed0, 0x574a39cf, 0xbfdefd6e, 0x3f2eea71, - 0x654fd511, 0xe5bfc20e, 0xd18dabd1, 0x517dbcce, 0x0b1c83ae, - 0x8bec94b1, 0x01440cad, 0x81b41bb2, 0xdbd524d2, 0x5b2533cd, - 0x6f175a12, 0xefe74d0d, 0xb586726d, 0x35766572, 0xdde2a1d3, - 0x5d12b6cc, 0x077389ac, 0x87839eb3, 0xb3b1f76c, 0x3341e073, - 0x6920df13, 0xe9d0c80c, 0xf4809ddf, 0x74708ac0, 0x2e11b5a0, - 0xaee1a2bf, 0x9ad3cb60, 0x1a23dc7f, 0x4042e31f, 0xc0b2f400, - 0x282630a1, 0xa8d627be, 0xf2b718de, 0x72470fc1, 0x4675661e, - 0xc6857101, 0x9ce44e61, 0x1c14597e, 0x96bcc162, 0x164cd67d, - 0x4c2de91d, 0xccddfe02, 0xf8ef97dd, 0x781f80c2, 0x227ebfa2, - 0xa28ea8bd, 0x4a1a6c1c, 0xcaea7b03, 0x908b4463, 0x107b537c, - 0x24493aa3, 0xa4b92dbc, 0xfed812dc, 0x7e2805c3, 0x30f824a5, - 0xb00833ba, 0xea690cda, 0x6a991bc5, 0x5eab721a, 0xde5b6505, - 0x843a5a65, 0x04ca4d7a, 0xec5e89db, 0x6cae9ec4, 0x36cfa1a4, - 0xb63fb6bb, 0x820ddf64, 0x02fdc87b, 0x589cf71b, 0xd86ce004, - 0x52c47818, 0xd2346f07, 0x88555067, 0x08a54778, 0x3c972ea7, - 0xbc6739b8, 0xe60606d8, 0x66f611c7, 0x8e62d566, 0x0e92c279, - 0x54f3fd19, 0xd403ea06, 0xe03183d9, 0x60c194c6, 0x3aa0aba6, - 0xba50bcb9}, - {0x00000000, 0x9570d495, 0xf190af6b, 0x64e07bfe, 0x38505897, - 0xad208c02, 0xc9c0f7fc, 0x5cb02369, 0x70a0b12e, 0xe5d065bb, - 0x81301e45, 0x1440cad0, 0x48f0e9b9, 0xdd803d2c, 0xb96046d2, - 0x2c109247, 0xe141625c, 0x7431b6c9, 0x10d1cd37, 0x85a119a2, - 0xd9113acb, 0x4c61ee5e, 0x288195a0, 0xbdf14135, 0x91e1d372, - 0x049107e7, 0x60717c19, 0xf501a88c, 0xa9b18be5, 0x3cc15f70, - 0x5821248e, 0xcd51f01b, 0x19f3c2f9, 0x8c83166c, 0xe8636d92, - 0x7d13b907, 0x21a39a6e, 0xb4d34efb, 0xd0333505, 0x4543e190, - 0x695373d7, 0xfc23a742, 0x98c3dcbc, 0x0db30829, 0x51032b40, - 0xc473ffd5, 0xa093842b, 0x35e350be, 0xf8b2a0a5, 0x6dc27430, - 0x09220fce, 0x9c52db5b, 0xc0e2f832, 0x55922ca7, 0x31725759, - 0xa40283cc, 0x8812118b, 0x1d62c51e, 0x7982bee0, 0xecf26a75, - 0xb042491c, 0x25329d89, 0x41d2e677, 0xd4a232e2, 0x33e785f2, - 0xa6975167, 0xc2772a99, 0x5707fe0c, 0x0bb7dd65, 0x9ec709f0, - 0xfa27720e, 0x6f57a69b, 0x434734dc, 0xd637e049, 0xb2d79bb7, - 0x27a74f22, 0x7b176c4b, 0xee67b8de, 0x8a87c320, 0x1ff717b5, - 0xd2a6e7ae, 0x47d6333b, 0x233648c5, 0xb6469c50, 0xeaf6bf39, - 0x7f866bac, 0x1b661052, 0x8e16c4c7, 0xa2065680, 0x37768215, - 0x5396f9eb, 0xc6e62d7e, 0x9a560e17, 0x0f26da82, 0x6bc6a17c, - 0xfeb675e9, 0x2a14470b, 0xbf64939e, 0xdb84e860, 0x4ef43cf5, - 0x12441f9c, 0x8734cb09, 0xe3d4b0f7, 0x76a46462, 0x5ab4f625, - 0xcfc422b0, 0xab24594e, 0x3e548ddb, 0x62e4aeb2, 0xf7947a27, - 0x937401d9, 0x0604d54c, 0xcb552557, 0x5e25f1c2, 0x3ac58a3c, - 0xafb55ea9, 0xf3057dc0, 0x6675a955, 0x0295d2ab, 0x97e5063e, - 0xbbf59479, 0x2e8540ec, 0x4a653b12, 0xdf15ef87, 0x83a5ccee, - 0x16d5187b, 0x72356385, 0xe745b710, 0x67cf0be4, 0xf2bfdf71, - 0x965fa48f, 0x032f701a, 0x5f9f5373, 0xcaef87e6, 0xae0ffc18, - 0x3b7f288d, 0x176fbaca, 0x821f6e5f, 0xe6ff15a1, 0x738fc134, - 0x2f3fe25d, 0xba4f36c8, 0xdeaf4d36, 0x4bdf99a3, 0x868e69b8, - 0x13febd2d, 0x771ec6d3, 0xe26e1246, 0xbede312f, 0x2baee5ba, - 0x4f4e9e44, 0xda3e4ad1, 0xf62ed896, 0x635e0c03, 0x07be77fd, - 0x92cea368, 0xce7e8001, 0x5b0e5494, 0x3fee2f6a, 0xaa9efbff, - 0x7e3cc91d, 0xeb4c1d88, 0x8fac6676, 0x1adcb2e3, 0x466c918a, - 0xd31c451f, 0xb7fc3ee1, 0x228cea74, 0x0e9c7833, 0x9becaca6, - 0xff0cd758, 0x6a7c03cd, 0x36cc20a4, 0xa3bcf431, 0xc75c8fcf, - 0x522c5b5a, 0x9f7dab41, 0x0a0d7fd4, 0x6eed042a, 0xfb9dd0bf, - 0xa72df3d6, 0x325d2743, 0x56bd5cbd, 0xc3cd8828, 0xefdd1a6f, - 0x7aadcefa, 0x1e4db504, 0x8b3d6191, 0xd78d42f8, 0x42fd966d, - 0x261ded93, 0xb36d3906, 0x54288e16, 0xc1585a83, 0xa5b8217d, - 0x30c8f5e8, 0x6c78d681, 0xf9080214, 0x9de879ea, 0x0898ad7f, - 0x24883f38, 0xb1f8ebad, 0xd5189053, 0x406844c6, 0x1cd867af, - 0x89a8b33a, 0xed48c8c4, 0x78381c51, 0xb569ec4a, 0x201938df, - 0x44f94321, 0xd18997b4, 0x8d39b4dd, 0x18496048, 0x7ca91bb6, - 0xe9d9cf23, 0xc5c95d64, 0x50b989f1, 0x3459f20f, 0xa129269a, - 0xfd9905f3, 0x68e9d166, 0x0c09aa98, 0x99797e0d, 0x4ddb4cef, - 0xd8ab987a, 0xbc4be384, 0x293b3711, 0x758b1478, 0xe0fbc0ed, - 0x841bbb13, 0x116b6f86, 0x3d7bfdc1, 0xa80b2954, 0xcceb52aa, - 0x599b863f, 0x052ba556, 0x905b71c3, 0xf4bb0a3d, 0x61cbdea8, - 0xac9a2eb3, 0x39eafa26, 0x5d0a81d8, 0xc87a554d, 0x94ca7624, - 0x01baa2b1, 0x655ad94f, 0xf02a0dda, 0xdc3a9f9d, 0x494a4b08, - 0x2daa30f6, 0xb8dae463, 0xe46ac70a, 0x711a139f, 0x15fa6861, - 0x808abcf4}, - {0x00000000, 0xcf9e17c8, 0x444d29d1, 0x8bd33e19, 0x889a53a2, - 0x4704446a, 0xccd77a73, 0x03496dbb, 0xca45a105, 0x05dbb6cd, - 0x8e0888d4, 0x41969f1c, 0x42dff2a7, 0x8d41e56f, 0x0692db76, - 0xc90cccbe, 0x4ffa444b, 0x80645383, 0x0bb76d9a, 0xc4297a52, - 0xc76017e9, 0x08fe0021, 0x832d3e38, 0x4cb329f0, 0x85bfe54e, - 0x4a21f286, 0xc1f2cc9f, 0x0e6cdb57, 0x0d25b6ec, 0xc2bba124, - 0x49689f3d, 0x86f688f5, 0x9ff48896, 0x506a9f5e, 0xdbb9a147, - 0x1427b68f, 0x176edb34, 0xd8f0ccfc, 0x5323f2e5, 0x9cbde52d, - 0x55b12993, 0x9a2f3e5b, 0x11fc0042, 0xde62178a, 0xdd2b7a31, - 0x12b56df9, 0x996653e0, 0x56f84428, 0xd00eccdd, 0x1f90db15, - 0x9443e50c, 0x5bddf2c4, 0x58949f7f, 0x970a88b7, 0x1cd9b6ae, - 0xd347a166, 0x1a4b6dd8, 0xd5d57a10, 0x5e064409, 0x919853c1, - 0x92d13e7a, 0x5d4f29b2, 0xd69c17ab, 0x19020063, 0xe498176d, - 0x2b0600a5, 0xa0d53ebc, 0x6f4b2974, 0x6c0244cf, 0xa39c5307, - 0x284f6d1e, 0xe7d17ad6, 0x2eddb668, 0xe143a1a0, 0x6a909fb9, - 0xa50e8871, 0xa647e5ca, 0x69d9f202, 0xe20acc1b, 0x2d94dbd3, - 0xab625326, 0x64fc44ee, 0xef2f7af7, 0x20b16d3f, 0x23f80084, - 0xec66174c, 0x67b52955, 0xa82b3e9d, 0x6127f223, 0xaeb9e5eb, - 0x256adbf2, 0xeaf4cc3a, 0xe9bda181, 0x2623b649, 0xadf08850, - 0x626e9f98, 0x7b6c9ffb, 0xb4f28833, 0x3f21b62a, 0xf0bfa1e2, - 0xf3f6cc59, 0x3c68db91, 0xb7bbe588, 0x7825f240, 0xb1293efe, - 0x7eb72936, 0xf564172f, 0x3afa00e7, 0x39b36d5c, 0xf62d7a94, - 0x7dfe448d, 0xb2605345, 0x3496dbb0, 0xfb08cc78, 0x70dbf261, - 0xbf45e5a9, 0xbc0c8812, 0x73929fda, 0xf841a1c3, 0x37dfb60b, - 0xfed37ab5, 0x314d6d7d, 0xba9e5364, 0x750044ac, 0x76492917, - 0xb9d73edf, 0x320400c6, 0xfd9a170e, 0x1241289b, 0xdddf3f53, - 0x560c014a, 0x99921682, 0x9adb7b39, 0x55456cf1, 0xde9652e8, - 0x11084520, 0xd804899e, 0x179a9e56, 0x9c49a04f, 0x53d7b787, - 0x509eda3c, 0x9f00cdf4, 0x14d3f3ed, 0xdb4de425, 0x5dbb6cd0, - 0x92257b18, 0x19f64501, 0xd66852c9, 0xd5213f72, 0x1abf28ba, - 0x916c16a3, 0x5ef2016b, 0x97fecdd5, 0x5860da1d, 0xd3b3e404, - 0x1c2df3cc, 0x1f649e77, 0xd0fa89bf, 0x5b29b7a6, 0x94b7a06e, - 0x8db5a00d, 0x422bb7c5, 0xc9f889dc, 0x06669e14, 0x052ff3af, - 0xcab1e467, 0x4162da7e, 0x8efccdb6, 0x47f00108, 0x886e16c0, - 0x03bd28d9, 0xcc233f11, 0xcf6a52aa, 0x00f44562, 0x8b277b7b, - 0x44b96cb3, 0xc24fe446, 0x0dd1f38e, 0x8602cd97, 0x499cda5f, - 0x4ad5b7e4, 0x854ba02c, 0x0e989e35, 0xc10689fd, 0x080a4543, - 0xc794528b, 0x4c476c92, 0x83d97b5a, 0x809016e1, 0x4f0e0129, - 0xc4dd3f30, 0x0b4328f8, 0xf6d93ff6, 0x3947283e, 0xb2941627, - 0x7d0a01ef, 0x7e436c54, 0xb1dd7b9c, 0x3a0e4585, 0xf590524d, - 0x3c9c9ef3, 0xf302893b, 0x78d1b722, 0xb74fa0ea, 0xb406cd51, - 0x7b98da99, 0xf04be480, 0x3fd5f348, 0xb9237bbd, 0x76bd6c75, - 0xfd6e526c, 0x32f045a4, 0x31b9281f, 0xfe273fd7, 0x75f401ce, - 0xba6a1606, 0x7366dab8, 0xbcf8cd70, 0x372bf369, 0xf8b5e4a1, - 0xfbfc891a, 0x34629ed2, 0xbfb1a0cb, 0x702fb703, 0x692db760, - 0xa6b3a0a8, 0x2d609eb1, 0xe2fe8979, 0xe1b7e4c2, 0x2e29f30a, - 0xa5facd13, 0x6a64dadb, 0xa3681665, 0x6cf601ad, 0xe7253fb4, - 0x28bb287c, 0x2bf245c7, 0xe46c520f, 0x6fbf6c16, 0xa0217bde, - 0x26d7f32b, 0xe949e4e3, 0x629adafa, 0xad04cd32, 0xae4da089, - 0x61d3b741, 0xea008958, 0x259e9e90, 0xec92522e, 0x230c45e6, - 0xa8df7bff, 0x67416c37, 0x6408018c, 0xab961644, 0x2045285d, - 0xefdb3f95}, - {0x00000000, 0x24825136, 0x4904a26c, 0x6d86f35a, 0x920944d8, - 0xb68b15ee, 0xdb0de6b4, 0xff8fb782, 0xff638ff1, 0xdbe1dec7, - 0xb6672d9d, 0x92e57cab, 0x6d6acb29, 0x49e89a1f, 0x246e6945, - 0x00ec3873, 0x25b619a3, 0x01344895, 0x6cb2bbcf, 0x4830eaf9, - 0xb7bf5d7b, 0x933d0c4d, 0xfebbff17, 0xda39ae21, 0xdad59652, - 0xfe57c764, 0x93d1343e, 0xb7536508, 0x48dcd28a, 0x6c5e83bc, - 0x01d870e6, 0x255a21d0, 0x4b6c3346, 0x6fee6270, 0x0268912a, - 0x26eac01c, 0xd965779e, 0xfde726a8, 0x9061d5f2, 0xb4e384c4, - 0xb40fbcb7, 0x908ded81, 0xfd0b1edb, 0xd9894fed, 0x2606f86f, - 0x0284a959, 0x6f025a03, 0x4b800b35, 0x6eda2ae5, 0x4a587bd3, - 0x27de8889, 0x035cd9bf, 0xfcd36e3d, 0xd8513f0b, 0xb5d7cc51, - 0x91559d67, 0x91b9a514, 0xb53bf422, 0xd8bd0778, 0xfc3f564e, - 0x03b0e1cc, 0x2732b0fa, 0x4ab443a0, 0x6e361296, 0x96d8668c, - 0xb25a37ba, 0xdfdcc4e0, 0xfb5e95d6, 0x04d12254, 0x20537362, - 0x4dd58038, 0x6957d10e, 0x69bbe97d, 0x4d39b84b, 0x20bf4b11, - 0x043d1a27, 0xfbb2ada5, 0xdf30fc93, 0xb2b60fc9, 0x96345eff, - 0xb36e7f2f, 0x97ec2e19, 0xfa6add43, 0xdee88c75, 0x21673bf7, - 0x05e56ac1, 0x6863999b, 0x4ce1c8ad, 0x4c0df0de, 0x688fa1e8, - 0x050952b2, 0x218b0384, 0xde04b406, 0xfa86e530, 0x9700166a, - 0xb382475c, 0xddb455ca, 0xf93604fc, 0x94b0f7a6, 0xb032a690, - 0x4fbd1112, 0x6b3f4024, 0x06b9b37e, 0x223be248, 0x22d7da3b, - 0x06558b0d, 0x6bd37857, 0x4f512961, 0xb0de9ee3, 0x945ccfd5, - 0xf9da3c8f, 0xdd586db9, 0xf8024c69, 0xdc801d5f, 0xb106ee05, - 0x9584bf33, 0x6a0b08b1, 0x4e895987, 0x230faadd, 0x078dfbeb, - 0x0761c398, 0x23e392ae, 0x4e6561f4, 0x6ae730c2, 0x95688740, - 0xb1ead676, 0xdc6c252c, 0xf8ee741a, 0xf6c1cb59, 0xd2439a6f, - 0xbfc56935, 0x9b473803, 0x64c88f81, 0x404adeb7, 0x2dcc2ded, - 0x094e7cdb, 0x09a244a8, 0x2d20159e, 0x40a6e6c4, 0x6424b7f2, - 0x9bab0070, 0xbf295146, 0xd2afa21c, 0xf62df32a, 0xd377d2fa, - 0xf7f583cc, 0x9a737096, 0xbef121a0, 0x417e9622, 0x65fcc714, - 0x087a344e, 0x2cf86578, 0x2c145d0b, 0x08960c3d, 0x6510ff67, - 0x4192ae51, 0xbe1d19d3, 0x9a9f48e5, 0xf719bbbf, 0xd39bea89, - 0xbdadf81f, 0x992fa929, 0xf4a95a73, 0xd02b0b45, 0x2fa4bcc7, - 0x0b26edf1, 0x66a01eab, 0x42224f9d, 0x42ce77ee, 0x664c26d8, - 0x0bcad582, 0x2f4884b4, 0xd0c73336, 0xf4456200, 0x99c3915a, - 0xbd41c06c, 0x981be1bc, 0xbc99b08a, 0xd11f43d0, 0xf59d12e6, - 0x0a12a564, 0x2e90f452, 0x43160708, 0x6794563e, 0x67786e4d, - 0x43fa3f7b, 0x2e7ccc21, 0x0afe9d17, 0xf5712a95, 0xd1f37ba3, - 0xbc7588f9, 0x98f7d9cf, 0x6019add5, 0x449bfce3, 0x291d0fb9, - 0x0d9f5e8f, 0xf210e90d, 0xd692b83b, 0xbb144b61, 0x9f961a57, - 0x9f7a2224, 0xbbf87312, 0xd67e8048, 0xf2fcd17e, 0x0d7366fc, - 0x29f137ca, 0x4477c490, 0x60f595a6, 0x45afb476, 0x612de540, - 0x0cab161a, 0x2829472c, 0xd7a6f0ae, 0xf324a198, 0x9ea252c2, - 0xba2003f4, 0xbacc3b87, 0x9e4e6ab1, 0xf3c899eb, 0xd74ac8dd, - 0x28c57f5f, 0x0c472e69, 0x61c1dd33, 0x45438c05, 0x2b759e93, - 0x0ff7cfa5, 0x62713cff, 0x46f36dc9, 0xb97cda4b, 0x9dfe8b7d, - 0xf0787827, 0xd4fa2911, 0xd4161162, 0xf0944054, 0x9d12b30e, - 0xb990e238, 0x461f55ba, 0x629d048c, 0x0f1bf7d6, 0x2b99a6e0, - 0x0ec38730, 0x2a41d606, 0x47c7255c, 0x6345746a, 0x9ccac3e8, - 0xb84892de, 0xd5ce6184, 0xf14c30b2, 0xf1a008c1, 0xd52259f7, - 0xb8a4aaad, 0x9c26fb9b, 0x63a94c19, 0x472b1d2f, 0x2aadee75, - 0x0e2fbf43}, - {0x00000000, 0x36f290f3, 0x6de521e6, 0x5b17b115, 0xdbca43cc, - 0xed38d33f, 0xb62f622a, 0x80ddf2d9, 0x6ce581d9, 0x5a17112a, - 0x0100a03f, 0x37f230cc, 0xb72fc215, 0x81dd52e6, 0xdacae3f3, - 0xec387300, 0xd9cb03b2, 0xef399341, 0xb42e2254, 0x82dcb2a7, - 0x0201407e, 0x34f3d08d, 0x6fe46198, 0x5916f16b, 0xb52e826b, - 0x83dc1298, 0xd8cba38d, 0xee39337e, 0x6ee4c1a7, 0x58165154, - 0x0301e041, 0x35f370b2, 0x68e70125, 0x5e1591d6, 0x050220c3, - 0x33f0b030, 0xb32d42e9, 0x85dfd21a, 0xdec8630f, 0xe83af3fc, - 0x040280fc, 0x32f0100f, 0x69e7a11a, 0x5f1531e9, 0xdfc8c330, - 0xe93a53c3, 0xb22de2d6, 0x84df7225, 0xb12c0297, 0x87de9264, - 0xdcc92371, 0xea3bb382, 0x6ae6415b, 0x5c14d1a8, 0x070360bd, - 0x31f1f04e, 0xddc9834e, 0xeb3b13bd, 0xb02ca2a8, 0x86de325b, - 0x0603c082, 0x30f15071, 0x6be6e164, 0x5d147197, 0xd1ce024a, - 0xe73c92b9, 0xbc2b23ac, 0x8ad9b35f, 0x0a044186, 0x3cf6d175, - 0x67e16060, 0x5113f093, 0xbd2b8393, 0x8bd91360, 0xd0cea275, - 0xe63c3286, 0x66e1c05f, 0x501350ac, 0x0b04e1b9, 0x3df6714a, - 0x080501f8, 0x3ef7910b, 0x65e0201e, 0x5312b0ed, 0xd3cf4234, - 0xe53dd2c7, 0xbe2a63d2, 0x88d8f321, 0x64e08021, 0x521210d2, - 0x0905a1c7, 0x3ff73134, 0xbf2ac3ed, 0x89d8531e, 0xd2cfe20b, - 0xe43d72f8, 0xb929036f, 0x8fdb939c, 0xd4cc2289, 0xe23eb27a, - 0x62e340a3, 0x5411d050, 0x0f066145, 0x39f4f1b6, 0xd5cc82b6, - 0xe33e1245, 0xb829a350, 0x8edb33a3, 0x0e06c17a, 0x38f45189, - 0x63e3e09c, 0x5511706f, 0x60e200dd, 0x5610902e, 0x0d07213b, - 0x3bf5b1c8, 0xbb284311, 0x8ddad3e2, 0xd6cd62f7, 0xe03ff204, - 0x0c078104, 0x3af511f7, 0x61e2a0e2, 0x57103011, 0xd7cdc2c8, - 0xe13f523b, 0xba28e32e, 0x8cda73dd, 0x78ed02d5, 0x4e1f9226, - 0x15082333, 0x23fab3c0, 0xa3274119, 0x95d5d1ea, 0xcec260ff, - 0xf830f00c, 0x1408830c, 0x22fa13ff, 0x79eda2ea, 0x4f1f3219, - 0xcfc2c0c0, 0xf9305033, 0xa227e126, 0x94d571d5, 0xa1260167, - 0x97d49194, 0xccc32081, 0xfa31b072, 0x7aec42ab, 0x4c1ed258, - 0x1709634d, 0x21fbf3be, 0xcdc380be, 0xfb31104d, 0xa026a158, - 0x96d431ab, 0x1609c372, 0x20fb5381, 0x7bece294, 0x4d1e7267, - 0x100a03f0, 0x26f89303, 0x7def2216, 0x4b1db2e5, 0xcbc0403c, - 0xfd32d0cf, 0xa62561da, 0x90d7f129, 0x7cef8229, 0x4a1d12da, - 0x110aa3cf, 0x27f8333c, 0xa725c1e5, 0x91d75116, 0xcac0e003, - 0xfc3270f0, 0xc9c10042, 0xff3390b1, 0xa42421a4, 0x92d6b157, - 0x120b438e, 0x24f9d37d, 0x7fee6268, 0x491cf29b, 0xa524819b, - 0x93d61168, 0xc8c1a07d, 0xfe33308e, 0x7eeec257, 0x481c52a4, - 0x130be3b1, 0x25f97342, 0xa923009f, 0x9fd1906c, 0xc4c62179, - 0xf234b18a, 0x72e94353, 0x441bd3a0, 0x1f0c62b5, 0x29fef246, - 0xc5c68146, 0xf33411b5, 0xa823a0a0, 0x9ed13053, 0x1e0cc28a, - 0x28fe5279, 0x73e9e36c, 0x451b739f, 0x70e8032d, 0x461a93de, - 0x1d0d22cb, 0x2bffb238, 0xab2240e1, 0x9dd0d012, 0xc6c76107, - 0xf035f1f4, 0x1c0d82f4, 0x2aff1207, 0x71e8a312, 0x471a33e1, - 0xc7c7c138, 0xf13551cb, 0xaa22e0de, 0x9cd0702d, 0xc1c401ba, - 0xf7369149, 0xac21205c, 0x9ad3b0af, 0x1a0e4276, 0x2cfcd285, - 0x77eb6390, 0x4119f363, 0xad218063, 0x9bd31090, 0xc0c4a185, - 0xf6363176, 0x76ebc3af, 0x4019535c, 0x1b0ee249, 0x2dfc72ba, - 0x180f0208, 0x2efd92fb, 0x75ea23ee, 0x4318b31d, 0xc3c541c4, - 0xf537d137, 0xae206022, 0x98d2f0d1, 0x74ea83d1, 0x42181322, - 0x190fa237, 0x2ffd32c4, 0xaf20c01d, 0x99d250ee, 0xc2c5e1fb, - 0xf4377108}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0xf390f23600000000, 0xe621e56d00000000, - 0x15b1175b00000000, 0xcc43cadb00000000, 0x3fd338ed00000000, - 0x2a622fb600000000, 0xd9f2dd8000000000, 0xd981e56c00000000, - 0x2a11175a00000000, 0x3fa0000100000000, 0xcc30f23700000000, - 0x15c22fb700000000, 0xe652dd8100000000, 0xf3e3cada00000000, - 0x007338ec00000000, 0xb203cbd900000000, 0x419339ef00000000, - 0x54222eb400000000, 0xa7b2dc8200000000, 0x7e40010200000000, - 0x8dd0f33400000000, 0x9861e46f00000000, 0x6bf1165900000000, - 0x6b822eb500000000, 0x9812dc8300000000, 0x8da3cbd800000000, - 0x7e3339ee00000000, 0xa7c1e46e00000000, 0x5451165800000000, - 0x41e0010300000000, 0xb270f33500000000, 0x2501e76800000000, - 0xd691155e00000000, 0xc320020500000000, 0x30b0f03300000000, - 0xe9422db300000000, 0x1ad2df8500000000, 0x0f63c8de00000000, - 0xfcf33ae800000000, 0xfc80020400000000, 0x0f10f03200000000, - 0x1aa1e76900000000, 0xe931155f00000000, 0x30c3c8df00000000, - 0xc3533ae900000000, 0xd6e22db200000000, 0x2572df8400000000, - 0x97022cb100000000, 0x6492de8700000000, 0x7123c9dc00000000, - 0x82b33bea00000000, 0x5b41e66a00000000, 0xa8d1145c00000000, - 0xbd60030700000000, 0x4ef0f13100000000, 0x4e83c9dd00000000, - 0xbd133beb00000000, 0xa8a22cb000000000, 0x5b32de8600000000, - 0x82c0030600000000, 0x7150f13000000000, 0x64e1e66b00000000, - 0x9771145d00000000, 0x4a02ced100000000, 0xb9923ce700000000, - 0xac232bbc00000000, 0x5fb3d98a00000000, 0x8641040a00000000, - 0x75d1f63c00000000, 0x6060e16700000000, 0x93f0135100000000, - 0x93832bbd00000000, 0x6013d98b00000000, 0x75a2ced000000000, - 0x86323ce600000000, 0x5fc0e16600000000, 0xac50135000000000, - 0xb9e1040b00000000, 0x4a71f63d00000000, 0xf801050800000000, - 0x0b91f73e00000000, 0x1e20e06500000000, 0xedb0125300000000, - 0x3442cfd300000000, 0xc7d23de500000000, 0xd2632abe00000000, - 0x21f3d88800000000, 0x2180e06400000000, 0xd210125200000000, - 0xc7a1050900000000, 0x3431f73f00000000, 0xedc32abf00000000, - 0x1e53d88900000000, 0x0be2cfd200000000, 0xf8723de400000000, - 0x6f0329b900000000, 0x9c93db8f00000000, 0x8922ccd400000000, - 0x7ab23ee200000000, 0xa340e36200000000, 0x50d0115400000000, - 0x4561060f00000000, 0xb6f1f43900000000, 0xb682ccd500000000, - 0x45123ee300000000, 0x50a329b800000000, 0xa333db8e00000000, - 0x7ac1060e00000000, 0x8951f43800000000, 0x9ce0e36300000000, - 0x6f70115500000000, 0xdd00e26000000000, 0x2e90105600000000, - 0x3b21070d00000000, 0xc8b1f53b00000000, 0x114328bb00000000, - 0xe2d3da8d00000000, 0xf762cdd600000000, 0x04f23fe000000000, - 0x0481070c00000000, 0xf711f53a00000000, 0xe2a0e26100000000, - 0x1130105700000000, 0xc8c2cdd700000000, 0x3b523fe100000000, - 0x2ee328ba00000000, 0xdd73da8c00000000, 0xd502ed7800000000, - 0x26921f4e00000000, 0x3323081500000000, 0xc0b3fa2300000000, - 0x194127a300000000, 0xead1d59500000000, 0xff60c2ce00000000, - 0x0cf030f800000000, 0x0c83081400000000, 0xff13fa2200000000, - 0xeaa2ed7900000000, 0x19321f4f00000000, 0xc0c0c2cf00000000, - 0x335030f900000000, 0x26e127a200000000, 0xd571d59400000000, - 0x670126a100000000, 0x9491d49700000000, 0x8120c3cc00000000, - 0x72b031fa00000000, 0xab42ec7a00000000, 0x58d21e4c00000000, - 0x4d63091700000000, 0xbef3fb2100000000, 0xbe80c3cd00000000, - 0x4d1031fb00000000, 0x58a126a000000000, 0xab31d49600000000, - 0x72c3091600000000, 0x8153fb2000000000, 0x94e2ec7b00000000, - 0x67721e4d00000000, 0xf0030a1000000000, 0x0393f82600000000, - 0x1622ef7d00000000, 0xe5b21d4b00000000, 0x3c40c0cb00000000, - 0xcfd032fd00000000, 0xda6125a600000000, 0x29f1d79000000000, - 0x2982ef7c00000000, 0xda121d4a00000000, 0xcfa30a1100000000, - 0x3c33f82700000000, 0xe5c125a700000000, 0x1651d79100000000, - 0x03e0c0ca00000000, 0xf07032fc00000000, 0x4200c1c900000000, - 0xb19033ff00000000, 0xa42124a400000000, 0x57b1d69200000000, - 0x8e430b1200000000, 0x7dd3f92400000000, 0x6862ee7f00000000, - 0x9bf21c4900000000, 0x9b8124a500000000, 0x6811d69300000000, - 0x7da0c1c800000000, 0x8e3033fe00000000, 0x57c2ee7e00000000, - 0xa4521c4800000000, 0xb1e30b1300000000, 0x4273f92500000000, - 0x9f0023a900000000, 0x6c90d19f00000000, 0x7921c6c400000000, - 0x8ab134f200000000, 0x5343e97200000000, 0xa0d31b4400000000, - 0xb5620c1f00000000, 0x46f2fe2900000000, 0x4681c6c500000000, - 0xb51134f300000000, 0xa0a023a800000000, 0x5330d19e00000000, - 0x8ac20c1e00000000, 0x7952fe2800000000, 0x6ce3e97300000000, - 0x9f731b4500000000, 0x2d03e87000000000, 0xde931a4600000000, - 0xcb220d1d00000000, 0x38b2ff2b00000000, 0xe14022ab00000000, - 0x12d0d09d00000000, 0x0761c7c600000000, 0xf4f135f000000000, - 0xf4820d1c00000000, 0x0712ff2a00000000, 0x12a3e87100000000, - 0xe1331a4700000000, 0x38c1c7c700000000, 0xcb5135f100000000, - 0xdee022aa00000000, 0x2d70d09c00000000, 0xba01c4c100000000, - 0x499136f700000000, 0x5c2021ac00000000, 0xafb0d39a00000000, - 0x76420e1a00000000, 0x85d2fc2c00000000, 0x9063eb7700000000, - 0x63f3194100000000, 0x638021ad00000000, 0x9010d39b00000000, - 0x85a1c4c000000000, 0x763136f600000000, 0xafc3eb7600000000, - 0x5c53194000000000, 0x49e20e1b00000000, 0xba72fc2d00000000, - 0x08020f1800000000, 0xfb92fd2e00000000, 0xee23ea7500000000, - 0x1db3184300000000, 0xc441c5c300000000, 0x37d137f500000000, - 0x226020ae00000000, 0xd1f0d29800000000, 0xd183ea7400000000, - 0x2213184200000000, 0x37a20f1900000000, 0xc432fd2f00000000, - 0x1dc020af00000000, 0xee50d29900000000, 0xfbe1c5c200000000, - 0x087137f400000000}, - {0x0000000000000000, 0x3651822400000000, 0x6ca2044900000000, - 0x5af3866d00000000, 0xd844099200000000, 0xee158bb600000000, - 0xb4e60ddb00000000, 0x82b78fff00000000, 0xf18f63ff00000000, - 0xc7dee1db00000000, 0x9d2d67b600000000, 0xab7ce59200000000, - 0x29cb6a6d00000000, 0x1f9ae84900000000, 0x45696e2400000000, - 0x7338ec0000000000, 0xa319b62500000000, 0x9548340100000000, - 0xcfbbb26c00000000, 0xf9ea304800000000, 0x7b5dbfb700000000, - 0x4d0c3d9300000000, 0x17ffbbfe00000000, 0x21ae39da00000000, - 0x5296d5da00000000, 0x64c757fe00000000, 0x3e34d19300000000, - 0x086553b700000000, 0x8ad2dc4800000000, 0xbc835e6c00000000, - 0xe670d80100000000, 0xd0215a2500000000, 0x46336c4b00000000, - 0x7062ee6f00000000, 0x2a91680200000000, 0x1cc0ea2600000000, - 0x9e7765d900000000, 0xa826e7fd00000000, 0xf2d5619000000000, - 0xc484e3b400000000, 0xb7bc0fb400000000, 0x81ed8d9000000000, - 0xdb1e0bfd00000000, 0xed4f89d900000000, 0x6ff8062600000000, - 0x59a9840200000000, 0x035a026f00000000, 0x350b804b00000000, - 0xe52ada6e00000000, 0xd37b584a00000000, 0x8988de2700000000, - 0xbfd95c0300000000, 0x3d6ed3fc00000000, 0x0b3f51d800000000, - 0x51ccd7b500000000, 0x679d559100000000, 0x14a5b99100000000, - 0x22f43bb500000000, 0x7807bdd800000000, 0x4e563ffc00000000, - 0xcce1b00300000000, 0xfab0322700000000, 0xa043b44a00000000, - 0x9612366e00000000, 0x8c66d89600000000, 0xba375ab200000000, - 0xe0c4dcdf00000000, 0xd6955efb00000000, 0x5422d10400000000, - 0x6273532000000000, 0x3880d54d00000000, 0x0ed1576900000000, - 0x7de9bb6900000000, 0x4bb8394d00000000, 0x114bbf2000000000, - 0x271a3d0400000000, 0xa5adb2fb00000000, 0x93fc30df00000000, - 0xc90fb6b200000000, 0xff5e349600000000, 0x2f7f6eb300000000, - 0x192eec9700000000, 0x43dd6afa00000000, 0x758ce8de00000000, - 0xf73b672100000000, 0xc16ae50500000000, 0x9b99636800000000, - 0xadc8e14c00000000, 0xdef00d4c00000000, 0xe8a18f6800000000, - 0xb252090500000000, 0x84038b2100000000, 0x06b404de00000000, - 0x30e586fa00000000, 0x6a16009700000000, 0x5c4782b300000000, - 0xca55b4dd00000000, 0xfc0436f900000000, 0xa6f7b09400000000, - 0x90a632b000000000, 0x1211bd4f00000000, 0x24403f6b00000000, - 0x7eb3b90600000000, 0x48e23b2200000000, 0x3bdad72200000000, - 0x0d8b550600000000, 0x5778d36b00000000, 0x6129514f00000000, - 0xe39edeb000000000, 0xd5cf5c9400000000, 0x8f3cdaf900000000, - 0xb96d58dd00000000, 0x694c02f800000000, 0x5f1d80dc00000000, - 0x05ee06b100000000, 0x33bf849500000000, 0xb1080b6a00000000, - 0x8759894e00000000, 0xddaa0f2300000000, 0xebfb8d0700000000, - 0x98c3610700000000, 0xae92e32300000000, 0xf461654e00000000, - 0xc230e76a00000000, 0x4087689500000000, 0x76d6eab100000000, - 0x2c256cdc00000000, 0x1a74eef800000000, 0x59cbc1f600000000, - 0x6f9a43d200000000, 0x3569c5bf00000000, 0x0338479b00000000, - 0x818fc86400000000, 0xb7de4a4000000000, 0xed2dcc2d00000000, - 0xdb7c4e0900000000, 0xa844a20900000000, 0x9e15202d00000000, - 0xc4e6a64000000000, 0xf2b7246400000000, 0x7000ab9b00000000, - 0x465129bf00000000, 0x1ca2afd200000000, 0x2af32df600000000, - 0xfad277d300000000, 0xcc83f5f700000000, 0x9670739a00000000, - 0xa021f1be00000000, 0x22967e4100000000, 0x14c7fc6500000000, - 0x4e347a0800000000, 0x7865f82c00000000, 0x0b5d142c00000000, - 0x3d0c960800000000, 0x67ff106500000000, 0x51ae924100000000, - 0xd3191dbe00000000, 0xe5489f9a00000000, 0xbfbb19f700000000, - 0x89ea9bd300000000, 0x1ff8adbd00000000, 0x29a92f9900000000, - 0x735aa9f400000000, 0x450b2bd000000000, 0xc7bca42f00000000, - 0xf1ed260b00000000, 0xab1ea06600000000, 0x9d4f224200000000, - 0xee77ce4200000000, 0xd8264c6600000000, 0x82d5ca0b00000000, - 0xb484482f00000000, 0x3633c7d000000000, 0x006245f400000000, - 0x5a91c39900000000, 0x6cc041bd00000000, 0xbce11b9800000000, - 0x8ab099bc00000000, 0xd0431fd100000000, 0xe6129df500000000, - 0x64a5120a00000000, 0x52f4902e00000000, 0x0807164300000000, - 0x3e56946700000000, 0x4d6e786700000000, 0x7b3ffa4300000000, - 0x21cc7c2e00000000, 0x179dfe0a00000000, 0x952a71f500000000, - 0xa37bf3d100000000, 0xf98875bc00000000, 0xcfd9f79800000000, - 0xd5ad196000000000, 0xe3fc9b4400000000, 0xb90f1d2900000000, - 0x8f5e9f0d00000000, 0x0de910f200000000, 0x3bb892d600000000, - 0x614b14bb00000000, 0x571a969f00000000, 0x24227a9f00000000, - 0x1273f8bb00000000, 0x48807ed600000000, 0x7ed1fcf200000000, - 0xfc66730d00000000, 0xca37f12900000000, 0x90c4774400000000, - 0xa695f56000000000, 0x76b4af4500000000, 0x40e52d6100000000, - 0x1a16ab0c00000000, 0x2c47292800000000, 0xaef0a6d700000000, - 0x98a124f300000000, 0xc252a29e00000000, 0xf40320ba00000000, - 0x873bccba00000000, 0xb16a4e9e00000000, 0xeb99c8f300000000, - 0xddc84ad700000000, 0x5f7fc52800000000, 0x692e470c00000000, - 0x33ddc16100000000, 0x058c434500000000, 0x939e752b00000000, - 0xa5cff70f00000000, 0xff3c716200000000, 0xc96df34600000000, - 0x4bda7cb900000000, 0x7d8bfe9d00000000, 0x277878f000000000, - 0x1129fad400000000, 0x621116d400000000, 0x544094f000000000, - 0x0eb3129d00000000, 0x38e290b900000000, 0xba551f4600000000, - 0x8c049d6200000000, 0xd6f71b0f00000000, 0xe0a6992b00000000, - 0x3087c30e00000000, 0x06d6412a00000000, 0x5c25c74700000000, - 0x6a74456300000000, 0xe8c3ca9c00000000, 0xde9248b800000000, - 0x8461ced500000000, 0xb2304cf100000000, 0xc108a0f100000000, - 0xf75922d500000000, 0xadaaa4b800000000, 0x9bfb269c00000000, - 0x194ca96300000000, 0x2f1d2b4700000000, 0x75eead2a00000000, - 0x43bf2f0e00000000}, - {0x0000000000000000, 0xc8179ecf00000000, 0xd1294d4400000000, - 0x193ed38b00000000, 0xa2539a8800000000, 0x6a44044700000000, - 0x737ad7cc00000000, 0xbb6d490300000000, 0x05a145ca00000000, - 0xcdb6db0500000000, 0xd488088e00000000, 0x1c9f964100000000, - 0xa7f2df4200000000, 0x6fe5418d00000000, 0x76db920600000000, - 0xbecc0cc900000000, 0x4b44fa4f00000000, 0x8353648000000000, - 0x9a6db70b00000000, 0x527a29c400000000, 0xe91760c700000000, - 0x2100fe0800000000, 0x383e2d8300000000, 0xf029b34c00000000, - 0x4ee5bf8500000000, 0x86f2214a00000000, 0x9fccf2c100000000, - 0x57db6c0e00000000, 0xecb6250d00000000, 0x24a1bbc200000000, - 0x3d9f684900000000, 0xf588f68600000000, 0x9688f49f00000000, - 0x5e9f6a5000000000, 0x47a1b9db00000000, 0x8fb6271400000000, - 0x34db6e1700000000, 0xfcccf0d800000000, 0xe5f2235300000000, - 0x2de5bd9c00000000, 0x9329b15500000000, 0x5b3e2f9a00000000, - 0x4200fc1100000000, 0x8a1762de00000000, 0x317a2bdd00000000, - 0xf96db51200000000, 0xe053669900000000, 0x2844f85600000000, - 0xddcc0ed000000000, 0x15db901f00000000, 0x0ce5439400000000, - 0xc4f2dd5b00000000, 0x7f9f945800000000, 0xb7880a9700000000, - 0xaeb6d91c00000000, 0x66a147d300000000, 0xd86d4b1a00000000, - 0x107ad5d500000000, 0x0944065e00000000, 0xc153989100000000, - 0x7a3ed19200000000, 0xb2294f5d00000000, 0xab179cd600000000, - 0x6300021900000000, 0x6d1798e400000000, 0xa500062b00000000, - 0xbc3ed5a000000000, 0x74294b6f00000000, 0xcf44026c00000000, - 0x07539ca300000000, 0x1e6d4f2800000000, 0xd67ad1e700000000, - 0x68b6dd2e00000000, 0xa0a143e100000000, 0xb99f906a00000000, - 0x71880ea500000000, 0xcae547a600000000, 0x02f2d96900000000, - 0x1bcc0ae200000000, 0xd3db942d00000000, 0x265362ab00000000, - 0xee44fc6400000000, 0xf77a2fef00000000, 0x3f6db12000000000, - 0x8400f82300000000, 0x4c1766ec00000000, 0x5529b56700000000, - 0x9d3e2ba800000000, 0x23f2276100000000, 0xebe5b9ae00000000, - 0xf2db6a2500000000, 0x3accf4ea00000000, 0x81a1bde900000000, - 0x49b6232600000000, 0x5088f0ad00000000, 0x989f6e6200000000, - 0xfb9f6c7b00000000, 0x3388f2b400000000, 0x2ab6213f00000000, - 0xe2a1bff000000000, 0x59ccf6f300000000, 0x91db683c00000000, - 0x88e5bbb700000000, 0x40f2257800000000, 0xfe3e29b100000000, - 0x3629b77e00000000, 0x2f1764f500000000, 0xe700fa3a00000000, - 0x5c6db33900000000, 0x947a2df600000000, 0x8d44fe7d00000000, - 0x455360b200000000, 0xb0db963400000000, 0x78cc08fb00000000, - 0x61f2db7000000000, 0xa9e545bf00000000, 0x12880cbc00000000, - 0xda9f927300000000, 0xc3a141f800000000, 0x0bb6df3700000000, - 0xb57ad3fe00000000, 0x7d6d4d3100000000, 0x64539eba00000000, - 0xac44007500000000, 0x1729497600000000, 0xdf3ed7b900000000, - 0xc600043200000000, 0x0e179afd00000000, 0x9b28411200000000, - 0x533fdfdd00000000, 0x4a010c5600000000, 0x8216929900000000, - 0x397bdb9a00000000, 0xf16c455500000000, 0xe85296de00000000, - 0x2045081100000000, 0x9e8904d800000000, 0x569e9a1700000000, - 0x4fa0499c00000000, 0x87b7d75300000000, 0x3cda9e5000000000, - 0xf4cd009f00000000, 0xedf3d31400000000, 0x25e44ddb00000000, - 0xd06cbb5d00000000, 0x187b259200000000, 0x0145f61900000000, - 0xc95268d600000000, 0x723f21d500000000, 0xba28bf1a00000000, - 0xa3166c9100000000, 0x6b01f25e00000000, 0xd5cdfe9700000000, - 0x1dda605800000000, 0x04e4b3d300000000, 0xccf32d1c00000000, - 0x779e641f00000000, 0xbf89fad000000000, 0xa6b7295b00000000, - 0x6ea0b79400000000, 0x0da0b58d00000000, 0xc5b72b4200000000, - 0xdc89f8c900000000, 0x149e660600000000, 0xaff32f0500000000, - 0x67e4b1ca00000000, 0x7eda624100000000, 0xb6cdfc8e00000000, - 0x0801f04700000000, 0xc0166e8800000000, 0xd928bd0300000000, - 0x113f23cc00000000, 0xaa526acf00000000, 0x6245f40000000000, - 0x7b7b278b00000000, 0xb36cb94400000000, 0x46e44fc200000000, - 0x8ef3d10d00000000, 0x97cd028600000000, 0x5fda9c4900000000, - 0xe4b7d54a00000000, 0x2ca04b8500000000, 0x359e980e00000000, - 0xfd8906c100000000, 0x43450a0800000000, 0x8b5294c700000000, - 0x926c474c00000000, 0x5a7bd98300000000, 0xe116908000000000, - 0x29010e4f00000000, 0x303fddc400000000, 0xf828430b00000000, - 0xf63fd9f600000000, 0x3e28473900000000, 0x271694b200000000, - 0xef010a7d00000000, 0x546c437e00000000, 0x9c7bddb100000000, - 0x85450e3a00000000, 0x4d5290f500000000, 0xf39e9c3c00000000, - 0x3b8902f300000000, 0x22b7d17800000000, 0xeaa04fb700000000, - 0x51cd06b400000000, 0x99da987b00000000, 0x80e44bf000000000, - 0x48f3d53f00000000, 0xbd7b23b900000000, 0x756cbd7600000000, - 0x6c526efd00000000, 0xa445f03200000000, 0x1f28b93100000000, - 0xd73f27fe00000000, 0xce01f47500000000, 0x06166aba00000000, - 0xb8da667300000000, 0x70cdf8bc00000000, 0x69f32b3700000000, - 0xa1e4b5f800000000, 0x1a89fcfb00000000, 0xd29e623400000000, - 0xcba0b1bf00000000, 0x03b72f7000000000, 0x60b72d6900000000, - 0xa8a0b3a600000000, 0xb19e602d00000000, 0x7989fee200000000, - 0xc2e4b7e100000000, 0x0af3292e00000000, 0x13cdfaa500000000, - 0xdbda646a00000000, 0x651668a300000000, 0xad01f66c00000000, - 0xb43f25e700000000, 0x7c28bb2800000000, 0xc745f22b00000000, - 0x0f526ce400000000, 0x166cbf6f00000000, 0xde7b21a000000000, - 0x2bf3d72600000000, 0xe3e449e900000000, 0xfada9a6200000000, - 0x32cd04ad00000000, 0x89a04dae00000000, 0x41b7d36100000000, - 0x588900ea00000000, 0x909e9e2500000000, 0x2e5292ec00000000, - 0xe6450c2300000000, 0xff7bdfa800000000, 0x376c416700000000, - 0x8c01086400000000, 0x441696ab00000000, 0x5d28452000000000, - 0x953fdbef00000000}, - {0x0000000000000000, 0x95d4709500000000, 0x6baf90f100000000, - 0xfe7be06400000000, 0x9758503800000000, 0x028c20ad00000000, - 0xfcf7c0c900000000, 0x6923b05c00000000, 0x2eb1a07000000000, - 0xbb65d0e500000000, 0x451e308100000000, 0xd0ca401400000000, - 0xb9e9f04800000000, 0x2c3d80dd00000000, 0xd24660b900000000, - 0x4792102c00000000, 0x5c6241e100000000, 0xc9b6317400000000, - 0x37cdd11000000000, 0xa219a18500000000, 0xcb3a11d900000000, - 0x5eee614c00000000, 0xa095812800000000, 0x3541f1bd00000000, - 0x72d3e19100000000, 0xe707910400000000, 0x197c716000000000, - 0x8ca801f500000000, 0xe58bb1a900000000, 0x705fc13c00000000, - 0x8e24215800000000, 0x1bf051cd00000000, 0xf9c2f31900000000, - 0x6c16838c00000000, 0x926d63e800000000, 0x07b9137d00000000, - 0x6e9aa32100000000, 0xfb4ed3b400000000, 0x053533d000000000, - 0x90e1434500000000, 0xd773536900000000, 0x42a723fc00000000, - 0xbcdcc39800000000, 0x2908b30d00000000, 0x402b035100000000, - 0xd5ff73c400000000, 0x2b8493a000000000, 0xbe50e33500000000, - 0xa5a0b2f800000000, 0x3074c26d00000000, 0xce0f220900000000, - 0x5bdb529c00000000, 0x32f8e2c000000000, 0xa72c925500000000, - 0x5957723100000000, 0xcc8302a400000000, 0x8b11128800000000, - 0x1ec5621d00000000, 0xe0be827900000000, 0x756af2ec00000000, - 0x1c4942b000000000, 0x899d322500000000, 0x77e6d24100000000, - 0xe232a2d400000000, 0xf285e73300000000, 0x675197a600000000, - 0x992a77c200000000, 0x0cfe075700000000, 0x65ddb70b00000000, - 0xf009c79e00000000, 0x0e7227fa00000000, 0x9ba6576f00000000, - 0xdc34474300000000, 0x49e037d600000000, 0xb79bd7b200000000, - 0x224fa72700000000, 0x4b6c177b00000000, 0xdeb867ee00000000, - 0x20c3878a00000000, 0xb517f71f00000000, 0xaee7a6d200000000, - 0x3b33d64700000000, 0xc548362300000000, 0x509c46b600000000, - 0x39bff6ea00000000, 0xac6b867f00000000, 0x5210661b00000000, - 0xc7c4168e00000000, 0x805606a200000000, 0x1582763700000000, - 0xebf9965300000000, 0x7e2de6c600000000, 0x170e569a00000000, - 0x82da260f00000000, 0x7ca1c66b00000000, 0xe975b6fe00000000, - 0x0b47142a00000000, 0x9e9364bf00000000, 0x60e884db00000000, - 0xf53cf44e00000000, 0x9c1f441200000000, 0x09cb348700000000, - 0xf7b0d4e300000000, 0x6264a47600000000, 0x25f6b45a00000000, - 0xb022c4cf00000000, 0x4e5924ab00000000, 0xdb8d543e00000000, - 0xb2aee46200000000, 0x277a94f700000000, 0xd901749300000000, - 0x4cd5040600000000, 0x572555cb00000000, 0xc2f1255e00000000, - 0x3c8ac53a00000000, 0xa95eb5af00000000, 0xc07d05f300000000, - 0x55a9756600000000, 0xabd2950200000000, 0x3e06e59700000000, - 0x7994f5bb00000000, 0xec40852e00000000, 0x123b654a00000000, - 0x87ef15df00000000, 0xeecca58300000000, 0x7b18d51600000000, - 0x8563357200000000, 0x10b745e700000000, 0xe40bcf6700000000, - 0x71dfbff200000000, 0x8fa45f9600000000, 0x1a702f0300000000, - 0x73539f5f00000000, 0xe687efca00000000, 0x18fc0fae00000000, - 0x8d287f3b00000000, 0xcaba6f1700000000, 0x5f6e1f8200000000, - 0xa115ffe600000000, 0x34c18f7300000000, 0x5de23f2f00000000, - 0xc8364fba00000000, 0x364dafde00000000, 0xa399df4b00000000, - 0xb8698e8600000000, 0x2dbdfe1300000000, 0xd3c61e7700000000, - 0x46126ee200000000, 0x2f31debe00000000, 0xbae5ae2b00000000, - 0x449e4e4f00000000, 0xd14a3eda00000000, 0x96d82ef600000000, - 0x030c5e6300000000, 0xfd77be0700000000, 0x68a3ce9200000000, - 0x01807ece00000000, 0x94540e5b00000000, 0x6a2fee3f00000000, - 0xfffb9eaa00000000, 0x1dc93c7e00000000, 0x881d4ceb00000000, - 0x7666ac8f00000000, 0xe3b2dc1a00000000, 0x8a916c4600000000, - 0x1f451cd300000000, 0xe13efcb700000000, 0x74ea8c2200000000, - 0x33789c0e00000000, 0xa6acec9b00000000, 0x58d70cff00000000, - 0xcd037c6a00000000, 0xa420cc3600000000, 0x31f4bca300000000, - 0xcf8f5cc700000000, 0x5a5b2c5200000000, 0x41ab7d9f00000000, - 0xd47f0d0a00000000, 0x2a04ed6e00000000, 0xbfd09dfb00000000, - 0xd6f32da700000000, 0x43275d3200000000, 0xbd5cbd5600000000, - 0x2888cdc300000000, 0x6f1addef00000000, 0xfacead7a00000000, - 0x04b54d1e00000000, 0x91613d8b00000000, 0xf8428dd700000000, - 0x6d96fd4200000000, 0x93ed1d2600000000, 0x06396db300000000, - 0x168e285400000000, 0x835a58c100000000, 0x7d21b8a500000000, - 0xe8f5c83000000000, 0x81d6786c00000000, 0x140208f900000000, - 0xea79e89d00000000, 0x7fad980800000000, 0x383f882400000000, - 0xadebf8b100000000, 0x539018d500000000, 0xc644684000000000, - 0xaf67d81c00000000, 0x3ab3a88900000000, 0xc4c848ed00000000, - 0x511c387800000000, 0x4aec69b500000000, 0xdf38192000000000, - 0x2143f94400000000, 0xb49789d100000000, 0xddb4398d00000000, - 0x4860491800000000, 0xb61ba97c00000000, 0x23cfd9e900000000, - 0x645dc9c500000000, 0xf189b95000000000, 0x0ff2593400000000, - 0x9a2629a100000000, 0xf30599fd00000000, 0x66d1e96800000000, - 0x98aa090c00000000, 0x0d7e799900000000, 0xef4cdb4d00000000, - 0x7a98abd800000000, 0x84e34bbc00000000, 0x11373b2900000000, - 0x78148b7500000000, 0xedc0fbe000000000, 0x13bb1b8400000000, - 0x866f6b1100000000, 0xc1fd7b3d00000000, 0x54290ba800000000, - 0xaa52ebcc00000000, 0x3f869b5900000000, 0x56a52b0500000000, - 0xc3715b9000000000, 0x3d0abbf400000000, 0xa8decb6100000000, - 0xb32e9aac00000000, 0x26faea3900000000, 0xd8810a5d00000000, - 0x4d557ac800000000, 0x2476ca9400000000, 0xb1a2ba0100000000, - 0x4fd95a6500000000, 0xda0d2af000000000, 0x9d9f3adc00000000, - 0x084b4a4900000000, 0xf630aa2d00000000, 0x63e4dab800000000, - 0x0ac76ae400000000, 0x9f131a7100000000, 0x6168fa1500000000, - 0xf4bc8a8000000000}, - {0x0000000000000000, 0x1f17f08000000000, 0x7f2891da00000000, - 0x603f615a00000000, 0xbf56536e00000000, 0xa041a3ee00000000, - 0xc07ec2b400000000, 0xdf69323400000000, 0x7eada6dc00000000, - 0x61ba565c00000000, 0x0185370600000000, 0x1e92c78600000000, - 0xc1fbf5b200000000, 0xdeec053200000000, 0xbed3646800000000, - 0xa1c494e800000000, 0xbd5c3c6200000000, 0xa24bcce200000000, - 0xc274adb800000000, 0xdd635d3800000000, 0x020a6f0c00000000, - 0x1d1d9f8c00000000, 0x7d22fed600000000, 0x62350e5600000000, - 0xc3f19abe00000000, 0xdce66a3e00000000, 0xbcd90b6400000000, - 0xa3cefbe400000000, 0x7ca7c9d000000000, 0x63b0395000000000, - 0x038f580a00000000, 0x1c98a88a00000000, 0x7ab978c400000000, - 0x65ae884400000000, 0x0591e91e00000000, 0x1a86199e00000000, - 0xc5ef2baa00000000, 0xdaf8db2a00000000, 0xbac7ba7000000000, - 0xa5d04af000000000, 0x0414de1800000000, 0x1b032e9800000000, - 0x7b3c4fc200000000, 0x642bbf4200000000, 0xbb428d7600000000, - 0xa4557df600000000, 0xc46a1cac00000000, 0xdb7dec2c00000000, - 0xc7e544a600000000, 0xd8f2b42600000000, 0xb8cdd57c00000000, - 0xa7da25fc00000000, 0x78b317c800000000, 0x67a4e74800000000, - 0x079b861200000000, 0x188c769200000000, 0xb948e27a00000000, - 0xa65f12fa00000000, 0xc66073a000000000, 0xd977832000000000, - 0x061eb11400000000, 0x1909419400000000, 0x793620ce00000000, - 0x6621d04e00000000, 0xb574805300000000, 0xaa6370d300000000, - 0xca5c118900000000, 0xd54be10900000000, 0x0a22d33d00000000, - 0x153523bd00000000, 0x750a42e700000000, 0x6a1db26700000000, - 0xcbd9268f00000000, 0xd4ced60f00000000, 0xb4f1b75500000000, - 0xabe647d500000000, 0x748f75e100000000, 0x6b98856100000000, - 0x0ba7e43b00000000, 0x14b014bb00000000, 0x0828bc3100000000, - 0x173f4cb100000000, 0x77002deb00000000, 0x6817dd6b00000000, - 0xb77eef5f00000000, 0xa8691fdf00000000, 0xc8567e8500000000, - 0xd7418e0500000000, 0x76851aed00000000, 0x6992ea6d00000000, - 0x09ad8b3700000000, 0x16ba7bb700000000, 0xc9d3498300000000, - 0xd6c4b90300000000, 0xb6fbd85900000000, 0xa9ec28d900000000, - 0xcfcdf89700000000, 0xd0da081700000000, 0xb0e5694d00000000, - 0xaff299cd00000000, 0x709babf900000000, 0x6f8c5b7900000000, - 0x0fb33a2300000000, 0x10a4caa300000000, 0xb1605e4b00000000, - 0xae77aecb00000000, 0xce48cf9100000000, 0xd15f3f1100000000, - 0x0e360d2500000000, 0x1121fda500000000, 0x711e9cff00000000, - 0x6e096c7f00000000, 0x7291c4f500000000, 0x6d86347500000000, - 0x0db9552f00000000, 0x12aea5af00000000, 0xcdc7979b00000000, - 0xd2d0671b00000000, 0xb2ef064100000000, 0xadf8f6c100000000, - 0x0c3c622900000000, 0x132b92a900000000, 0x7314f3f300000000, - 0x6c03037300000000, 0xb36a314700000000, 0xac7dc1c700000000, - 0xcc42a09d00000000, 0xd355501d00000000, 0x6ae900a700000000, - 0x75fef02700000000, 0x15c1917d00000000, 0x0ad661fd00000000, - 0xd5bf53c900000000, 0xcaa8a34900000000, 0xaa97c21300000000, - 0xb580329300000000, 0x1444a67b00000000, 0x0b5356fb00000000, - 0x6b6c37a100000000, 0x747bc72100000000, 0xab12f51500000000, - 0xb405059500000000, 0xd43a64cf00000000, 0xcb2d944f00000000, - 0xd7b53cc500000000, 0xc8a2cc4500000000, 0xa89dad1f00000000, - 0xb78a5d9f00000000, 0x68e36fab00000000, 0x77f49f2b00000000, - 0x17cbfe7100000000, 0x08dc0ef100000000, 0xa9189a1900000000, - 0xb60f6a9900000000, 0xd6300bc300000000, 0xc927fb4300000000, - 0x164ec97700000000, 0x095939f700000000, 0x696658ad00000000, - 0x7671a82d00000000, 0x1050786300000000, 0x0f4788e300000000, - 0x6f78e9b900000000, 0x706f193900000000, 0xaf062b0d00000000, - 0xb011db8d00000000, 0xd02ebad700000000, 0xcf394a5700000000, - 0x6efddebf00000000, 0x71ea2e3f00000000, 0x11d54f6500000000, - 0x0ec2bfe500000000, 0xd1ab8dd100000000, 0xcebc7d5100000000, - 0xae831c0b00000000, 0xb194ec8b00000000, 0xad0c440100000000, - 0xb21bb48100000000, 0xd224d5db00000000, 0xcd33255b00000000, - 0x125a176f00000000, 0x0d4de7ef00000000, 0x6d7286b500000000, - 0x7265763500000000, 0xd3a1e2dd00000000, 0xccb6125d00000000, - 0xac89730700000000, 0xb39e838700000000, 0x6cf7b1b300000000, - 0x73e0413300000000, 0x13df206900000000, 0x0cc8d0e900000000, - 0xdf9d80f400000000, 0xc08a707400000000, 0xa0b5112e00000000, - 0xbfa2e1ae00000000, 0x60cbd39a00000000, 0x7fdc231a00000000, - 0x1fe3424000000000, 0x00f4b2c000000000, 0xa130262800000000, - 0xbe27d6a800000000, 0xde18b7f200000000, 0xc10f477200000000, - 0x1e66754600000000, 0x017185c600000000, 0x614ee49c00000000, - 0x7e59141c00000000, 0x62c1bc9600000000, 0x7dd64c1600000000, - 0x1de92d4c00000000, 0x02feddcc00000000, 0xdd97eff800000000, - 0xc2801f7800000000, 0xa2bf7e2200000000, 0xbda88ea200000000, - 0x1c6c1a4a00000000, 0x037beaca00000000, 0x63448b9000000000, - 0x7c537b1000000000, 0xa33a492400000000, 0xbc2db9a400000000, - 0xdc12d8fe00000000, 0xc305287e00000000, 0xa524f83000000000, - 0xba3308b000000000, 0xda0c69ea00000000, 0xc51b996a00000000, - 0x1a72ab5e00000000, 0x05655bde00000000, 0x655a3a8400000000, - 0x7a4dca0400000000, 0xdb895eec00000000, 0xc49eae6c00000000, - 0xa4a1cf3600000000, 0xbbb63fb600000000, 0x64df0d8200000000, - 0x7bc8fd0200000000, 0x1bf79c5800000000, 0x04e06cd800000000, - 0x1878c45200000000, 0x076f34d200000000, 0x6750558800000000, - 0x7847a50800000000, 0xa72e973c00000000, 0xb83967bc00000000, - 0xd80606e600000000, 0xc711f66600000000, 0x66d5628e00000000, - 0x79c2920e00000000, 0x19fdf35400000000, 0x06ea03d400000000, - 0xd98331e000000000, 0xc694c16000000000, 0xa6aba03a00000000, - 0xb9bc50ba00000000}, - {0x0000000000000000, 0xe2fd888d00000000, 0x85fd60c000000000, - 0x6700e84d00000000, 0x4bfdb05b00000000, 0xa90038d600000000, - 0xce00d09b00000000, 0x2cfd581600000000, 0x96fa61b700000000, - 0x7407e93a00000000, 0x1307017700000000, 0xf1fa89fa00000000, - 0xdd07d1ec00000000, 0x3ffa596100000000, 0x58fab12c00000000, - 0xba0739a100000000, 0x6df3b2b500000000, 0x8f0e3a3800000000, - 0xe80ed27500000000, 0x0af35af800000000, 0x260e02ee00000000, - 0xc4f38a6300000000, 0xa3f3622e00000000, 0x410eeaa300000000, - 0xfb09d30200000000, 0x19f45b8f00000000, 0x7ef4b3c200000000, - 0x9c093b4f00000000, 0xb0f4635900000000, 0x5209ebd400000000, - 0x3509039900000000, 0xd7f48b1400000000, 0x9be014b000000000, - 0x791d9c3d00000000, 0x1e1d747000000000, 0xfce0fcfd00000000, - 0xd01da4eb00000000, 0x32e02c6600000000, 0x55e0c42b00000000, - 0xb71d4ca600000000, 0x0d1a750700000000, 0xefe7fd8a00000000, - 0x88e715c700000000, 0x6a1a9d4a00000000, 0x46e7c55c00000000, - 0xa41a4dd100000000, 0xc31aa59c00000000, 0x21e72d1100000000, - 0xf613a60500000000, 0x14ee2e8800000000, 0x73eec6c500000000, - 0x91134e4800000000, 0xbdee165e00000000, 0x5f139ed300000000, - 0x3813769e00000000, 0xdaeefe1300000000, 0x60e9c7b200000000, - 0x82144f3f00000000, 0xe514a77200000000, 0x07e92fff00000000, - 0x2b1477e900000000, 0xc9e9ff6400000000, 0xaee9172900000000, - 0x4c149fa400000000, 0x77c758bb00000000, 0x953ad03600000000, - 0xf23a387b00000000, 0x10c7b0f600000000, 0x3c3ae8e000000000, - 0xdec7606d00000000, 0xb9c7882000000000, 0x5b3a00ad00000000, - 0xe13d390c00000000, 0x03c0b18100000000, 0x64c059cc00000000, - 0x863dd14100000000, 0xaac0895700000000, 0x483d01da00000000, - 0x2f3de99700000000, 0xcdc0611a00000000, 0x1a34ea0e00000000, - 0xf8c9628300000000, 0x9fc98ace00000000, 0x7d34024300000000, - 0x51c95a5500000000, 0xb334d2d800000000, 0xd4343a9500000000, - 0x36c9b21800000000, 0x8cce8bb900000000, 0x6e33033400000000, - 0x0933eb7900000000, 0xebce63f400000000, 0xc7333be200000000, - 0x25ceb36f00000000, 0x42ce5b2200000000, 0xa033d3af00000000, - 0xec274c0b00000000, 0x0edac48600000000, 0x69da2ccb00000000, - 0x8b27a44600000000, 0xa7dafc5000000000, 0x452774dd00000000, - 0x22279c9000000000, 0xc0da141d00000000, 0x7add2dbc00000000, - 0x9820a53100000000, 0xff204d7c00000000, 0x1dddc5f100000000, - 0x31209de700000000, 0xd3dd156a00000000, 0xb4ddfd2700000000, - 0x562075aa00000000, 0x81d4febe00000000, 0x6329763300000000, - 0x04299e7e00000000, 0xe6d416f300000000, 0xca294ee500000000, - 0x28d4c66800000000, 0x4fd42e2500000000, 0xad29a6a800000000, - 0x172e9f0900000000, 0xf5d3178400000000, 0x92d3ffc900000000, - 0x702e774400000000, 0x5cd32f5200000000, 0xbe2ea7df00000000, - 0xd92e4f9200000000, 0x3bd3c71f00000000, 0xaf88c0ad00000000, - 0x4d75482000000000, 0x2a75a06d00000000, 0xc88828e000000000, - 0xe47570f600000000, 0x0688f87b00000000, 0x6188103600000000, - 0x837598bb00000000, 0x3972a11a00000000, 0xdb8f299700000000, - 0xbc8fc1da00000000, 0x5e72495700000000, 0x728f114100000000, - 0x907299cc00000000, 0xf772718100000000, 0x158ff90c00000000, - 0xc27b721800000000, 0x2086fa9500000000, 0x478612d800000000, - 0xa57b9a5500000000, 0x8986c24300000000, 0x6b7b4ace00000000, - 0x0c7ba28300000000, 0xee862a0e00000000, 0x548113af00000000, - 0xb67c9b2200000000, 0xd17c736f00000000, 0x3381fbe200000000, - 0x1f7ca3f400000000, 0xfd812b7900000000, 0x9a81c33400000000, - 0x787c4bb900000000, 0x3468d41d00000000, 0xd6955c9000000000, - 0xb195b4dd00000000, 0x53683c5000000000, 0x7f95644600000000, - 0x9d68eccb00000000, 0xfa68048600000000, 0x18958c0b00000000, - 0xa292b5aa00000000, 0x406f3d2700000000, 0x276fd56a00000000, - 0xc5925de700000000, 0xe96f05f100000000, 0x0b928d7c00000000, - 0x6c92653100000000, 0x8e6fedbc00000000, 0x599b66a800000000, - 0xbb66ee2500000000, 0xdc66066800000000, 0x3e9b8ee500000000, - 0x1266d6f300000000, 0xf09b5e7e00000000, 0x979bb63300000000, - 0x75663ebe00000000, 0xcf61071f00000000, 0x2d9c8f9200000000, - 0x4a9c67df00000000, 0xa861ef5200000000, 0x849cb74400000000, - 0x66613fc900000000, 0x0161d78400000000, 0xe39c5f0900000000, - 0xd84f981600000000, 0x3ab2109b00000000, 0x5db2f8d600000000, - 0xbf4f705b00000000, 0x93b2284d00000000, 0x714fa0c000000000, - 0x164f488d00000000, 0xf4b2c00000000000, 0x4eb5f9a100000000, - 0xac48712c00000000, 0xcb48996100000000, 0x29b511ec00000000, - 0x054849fa00000000, 0xe7b5c17700000000, 0x80b5293a00000000, - 0x6248a1b700000000, 0xb5bc2aa300000000, 0x5741a22e00000000, - 0x30414a6300000000, 0xd2bcc2ee00000000, 0xfe419af800000000, - 0x1cbc127500000000, 0x7bbcfa3800000000, 0x994172b500000000, - 0x23464b1400000000, 0xc1bbc39900000000, 0xa6bb2bd400000000, - 0x4446a35900000000, 0x68bbfb4f00000000, 0x8a4673c200000000, - 0xed469b8f00000000, 0x0fbb130200000000, 0x43af8ca600000000, - 0xa152042b00000000, 0xc652ec6600000000, 0x24af64eb00000000, - 0x08523cfd00000000, 0xeaafb47000000000, 0x8daf5c3d00000000, - 0x6f52d4b000000000, 0xd555ed1100000000, 0x37a8659c00000000, - 0x50a88dd100000000, 0xb255055c00000000, 0x9ea85d4a00000000, - 0x7c55d5c700000000, 0x1b553d8a00000000, 0xf9a8b50700000000, - 0x2e5c3e1300000000, 0xcca1b69e00000000, 0xaba15ed300000000, - 0x495cd65e00000000, 0x65a18e4800000000, 0x875c06c500000000, - 0xe05cee8800000000, 0x02a1660500000000, 0xb8a65fa400000000, - 0x5a5bd72900000000, 0x3d5b3f6400000000, 0xdfa6b7e900000000, - 0xf35befff00000000, 0x11a6677200000000, 0x76a68f3f00000000, - 0x945b07b200000000}, - {0x0000000000000000, 0xa90b894e00000000, 0x5217129d00000000, - 0xfb1c9bd300000000, 0xe52855e100000000, 0x4c23dcaf00000000, - 0xb73f477c00000000, 0x1e34ce3200000000, 0x8b57db1900000000, - 0x225c525700000000, 0xd940c98400000000, 0x704b40ca00000000, - 0x6e7f8ef800000000, 0xc77407b600000000, 0x3c689c6500000000, - 0x9563152b00000000, 0x16afb63300000000, 0xbfa43f7d00000000, - 0x44b8a4ae00000000, 0xedb32de000000000, 0xf387e3d200000000, - 0x5a8c6a9c00000000, 0xa190f14f00000000, 0x089b780100000000, - 0x9df86d2a00000000, 0x34f3e46400000000, 0xcfef7fb700000000, - 0x66e4f6f900000000, 0x78d038cb00000000, 0xd1dbb18500000000, - 0x2ac72a5600000000, 0x83cca31800000000, 0x2c5e6d6700000000, - 0x8555e42900000000, 0x7e497ffa00000000, 0xd742f6b400000000, - 0xc976388600000000, 0x607db1c800000000, 0x9b612a1b00000000, - 0x326aa35500000000, 0xa709b67e00000000, 0x0e023f3000000000, - 0xf51ea4e300000000, 0x5c152dad00000000, 0x4221e39f00000000, - 0xeb2a6ad100000000, 0x1036f10200000000, 0xb93d784c00000000, - 0x3af1db5400000000, 0x93fa521a00000000, 0x68e6c9c900000000, - 0xc1ed408700000000, 0xdfd98eb500000000, 0x76d207fb00000000, - 0x8dce9c2800000000, 0x24c5156600000000, 0xb1a6004d00000000, - 0x18ad890300000000, 0xe3b112d000000000, 0x4aba9b9e00000000, - 0x548e55ac00000000, 0xfd85dce200000000, 0x0699473100000000, - 0xaf92ce7f00000000, 0x58bcdace00000000, 0xf1b7538000000000, - 0x0aabc85300000000, 0xa3a0411d00000000, 0xbd948f2f00000000, - 0x149f066100000000, 0xef839db200000000, 0x468814fc00000000, - 0xd3eb01d700000000, 0x7ae0889900000000, 0x81fc134a00000000, - 0x28f79a0400000000, 0x36c3543600000000, 0x9fc8dd7800000000, - 0x64d446ab00000000, 0xcddfcfe500000000, 0x4e136cfd00000000, - 0xe718e5b300000000, 0x1c047e6000000000, 0xb50ff72e00000000, - 0xab3b391c00000000, 0x0230b05200000000, 0xf92c2b8100000000, - 0x5027a2cf00000000, 0xc544b7e400000000, 0x6c4f3eaa00000000, - 0x9753a57900000000, 0x3e582c3700000000, 0x206ce20500000000, - 0x89676b4b00000000, 0x727bf09800000000, 0xdb7079d600000000, - 0x74e2b7a900000000, 0xdde93ee700000000, 0x26f5a53400000000, - 0x8ffe2c7a00000000, 0x91cae24800000000, 0x38c16b0600000000, - 0xc3ddf0d500000000, 0x6ad6799b00000000, 0xffb56cb000000000, - 0x56bee5fe00000000, 0xada27e2d00000000, 0x04a9f76300000000, - 0x1a9d395100000000, 0xb396b01f00000000, 0x488a2bcc00000000, - 0xe181a28200000000, 0x624d019a00000000, 0xcb4688d400000000, - 0x305a130700000000, 0x99519a4900000000, 0x8765547b00000000, - 0x2e6edd3500000000, 0xd57246e600000000, 0x7c79cfa800000000, - 0xe91ada8300000000, 0x401153cd00000000, 0xbb0dc81e00000000, - 0x1206415000000000, 0x0c328f6200000000, 0xa539062c00000000, - 0x5e259dff00000000, 0xf72e14b100000000, 0xf17ec44600000000, - 0x58754d0800000000, 0xa369d6db00000000, 0x0a625f9500000000, - 0x145691a700000000, 0xbd5d18e900000000, 0x4641833a00000000, - 0xef4a0a7400000000, 0x7a291f5f00000000, 0xd322961100000000, - 0x283e0dc200000000, 0x8135848c00000000, 0x9f014abe00000000, - 0x360ac3f000000000, 0xcd16582300000000, 0x641dd16d00000000, - 0xe7d1727500000000, 0x4edafb3b00000000, 0xb5c660e800000000, - 0x1ccde9a600000000, 0x02f9279400000000, 0xabf2aeda00000000, - 0x50ee350900000000, 0xf9e5bc4700000000, 0x6c86a96c00000000, - 0xc58d202200000000, 0x3e91bbf100000000, 0x979a32bf00000000, - 0x89aefc8d00000000, 0x20a575c300000000, 0xdbb9ee1000000000, - 0x72b2675e00000000, 0xdd20a92100000000, 0x742b206f00000000, - 0x8f37bbbc00000000, 0x263c32f200000000, 0x3808fcc000000000, - 0x9103758e00000000, 0x6a1fee5d00000000, 0xc314671300000000, - 0x5677723800000000, 0xff7cfb7600000000, 0x046060a500000000, - 0xad6be9eb00000000, 0xb35f27d900000000, 0x1a54ae9700000000, - 0xe148354400000000, 0x4843bc0a00000000, 0xcb8f1f1200000000, - 0x6284965c00000000, 0x99980d8f00000000, 0x309384c100000000, - 0x2ea74af300000000, 0x87acc3bd00000000, 0x7cb0586e00000000, - 0xd5bbd12000000000, 0x40d8c40b00000000, 0xe9d34d4500000000, - 0x12cfd69600000000, 0xbbc45fd800000000, 0xa5f091ea00000000, - 0x0cfb18a400000000, 0xf7e7837700000000, 0x5eec0a3900000000, - 0xa9c21e8800000000, 0x00c997c600000000, 0xfbd50c1500000000, - 0x52de855b00000000, 0x4cea4b6900000000, 0xe5e1c22700000000, - 0x1efd59f400000000, 0xb7f6d0ba00000000, 0x2295c59100000000, - 0x8b9e4cdf00000000, 0x7082d70c00000000, 0xd9895e4200000000, - 0xc7bd907000000000, 0x6eb6193e00000000, 0x95aa82ed00000000, - 0x3ca10ba300000000, 0xbf6da8bb00000000, 0x166621f500000000, - 0xed7aba2600000000, 0x4471336800000000, 0x5a45fd5a00000000, - 0xf34e741400000000, 0x0852efc700000000, 0xa159668900000000, - 0x343a73a200000000, 0x9d31faec00000000, 0x662d613f00000000, - 0xcf26e87100000000, 0xd112264300000000, 0x7819af0d00000000, - 0x830534de00000000, 0x2a0ebd9000000000, 0x859c73ef00000000, - 0x2c97faa100000000, 0xd78b617200000000, 0x7e80e83c00000000, - 0x60b4260e00000000, 0xc9bfaf4000000000, 0x32a3349300000000, - 0x9ba8bddd00000000, 0x0ecba8f600000000, 0xa7c021b800000000, - 0x5cdcba6b00000000, 0xf5d7332500000000, 0xebe3fd1700000000, - 0x42e8745900000000, 0xb9f4ef8a00000000, 0x10ff66c400000000, - 0x9333c5dc00000000, 0x3a384c9200000000, 0xc124d74100000000, - 0x682f5e0f00000000, 0x761b903d00000000, 0xdf10197300000000, - 0x240c82a000000000, 0x8d070bee00000000, 0x18641ec500000000, - 0xb16f978b00000000, 0x4a730c5800000000, 0xe378851600000000, - 0xfd4c4b2400000000, 0x5447c26a00000000, 0xaf5b59b900000000, - 0x0650d0f700000000}, - {0x0000000000000000, 0x479244af00000000, 0xcf22f88500000000, - 0x88b0bc2a00000000, 0xdf4381d000000000, 0x98d1c57f00000000, - 0x1061795500000000, 0x57f33dfa00000000, 0xff81737a00000000, - 0xb81337d500000000, 0x30a38bff00000000, 0x7731cf5000000000, - 0x20c2f2aa00000000, 0x6750b60500000000, 0xefe00a2f00000000, - 0xa8724e8000000000, 0xfe03e7f400000000, 0xb991a35b00000000, - 0x31211f7100000000, 0x76b35bde00000000, 0x2140662400000000, - 0x66d2228b00000000, 0xee629ea100000000, 0xa9f0da0e00000000, - 0x0182948e00000000, 0x4610d02100000000, 0xcea06c0b00000000, - 0x893228a400000000, 0xdec1155e00000000, 0x995351f100000000, - 0x11e3eddb00000000, 0x5671a97400000000, 0xbd01bf3200000000, - 0xfa93fb9d00000000, 0x722347b700000000, 0x35b1031800000000, - 0x62423ee200000000, 0x25d07a4d00000000, 0xad60c66700000000, - 0xeaf282c800000000, 0x4280cc4800000000, 0x051288e700000000, - 0x8da234cd00000000, 0xca30706200000000, 0x9dc34d9800000000, - 0xda51093700000000, 0x52e1b51d00000000, 0x1573f1b200000000, - 0x430258c600000000, 0x04901c6900000000, 0x8c20a04300000000, - 0xcbb2e4ec00000000, 0x9c41d91600000000, 0xdbd39db900000000, - 0x5363219300000000, 0x14f1653c00000000, 0xbc832bbc00000000, - 0xfb116f1300000000, 0x73a1d33900000000, 0x3433979600000000, - 0x63c0aa6c00000000, 0x2452eec300000000, 0xace252e900000000, - 0xeb70164600000000, 0x7a037e6500000000, 0x3d913aca00000000, - 0xb52186e000000000, 0xf2b3c24f00000000, 0xa540ffb500000000, - 0xe2d2bb1a00000000, 0x6a62073000000000, 0x2df0439f00000000, - 0x85820d1f00000000, 0xc21049b000000000, 0x4aa0f59a00000000, - 0x0d32b13500000000, 0x5ac18ccf00000000, 0x1d53c86000000000, - 0x95e3744a00000000, 0xd27130e500000000, 0x8400999100000000, - 0xc392dd3e00000000, 0x4b22611400000000, 0x0cb025bb00000000, - 0x5b43184100000000, 0x1cd15cee00000000, 0x9461e0c400000000, - 0xd3f3a46b00000000, 0x7b81eaeb00000000, 0x3c13ae4400000000, - 0xb4a3126e00000000, 0xf33156c100000000, 0xa4c26b3b00000000, - 0xe3502f9400000000, 0x6be093be00000000, 0x2c72d71100000000, - 0xc702c15700000000, 0x809085f800000000, 0x082039d200000000, - 0x4fb27d7d00000000, 0x1841408700000000, 0x5fd3042800000000, - 0xd763b80200000000, 0x90f1fcad00000000, 0x3883b22d00000000, - 0x7f11f68200000000, 0xf7a14aa800000000, 0xb0330e0700000000, - 0xe7c033fd00000000, 0xa052775200000000, 0x28e2cb7800000000, - 0x6f708fd700000000, 0x390126a300000000, 0x7e93620c00000000, - 0xf623de2600000000, 0xb1b19a8900000000, 0xe642a77300000000, - 0xa1d0e3dc00000000, 0x29605ff600000000, 0x6ef21b5900000000, - 0xc68055d900000000, 0x8112117600000000, 0x09a2ad5c00000000, - 0x4e30e9f300000000, 0x19c3d40900000000, 0x5e5190a600000000, - 0xd6e12c8c00000000, 0x9173682300000000, 0xf406fcca00000000, - 0xb394b86500000000, 0x3b24044f00000000, 0x7cb640e000000000, - 0x2b457d1a00000000, 0x6cd739b500000000, 0xe467859f00000000, - 0xa3f5c13000000000, 0x0b878fb000000000, 0x4c15cb1f00000000, - 0xc4a5773500000000, 0x8337339a00000000, 0xd4c40e6000000000, - 0x93564acf00000000, 0x1be6f6e500000000, 0x5c74b24a00000000, - 0x0a051b3e00000000, 0x4d975f9100000000, 0xc527e3bb00000000, - 0x82b5a71400000000, 0xd5469aee00000000, 0x92d4de4100000000, - 0x1a64626b00000000, 0x5df626c400000000, 0xf584684400000000, - 0xb2162ceb00000000, 0x3aa690c100000000, 0x7d34d46e00000000, - 0x2ac7e99400000000, 0x6d55ad3b00000000, 0xe5e5111100000000, - 0xa27755be00000000, 0x490743f800000000, 0x0e95075700000000, - 0x8625bb7d00000000, 0xc1b7ffd200000000, 0x9644c22800000000, - 0xd1d6868700000000, 0x59663aad00000000, 0x1ef47e0200000000, - 0xb686308200000000, 0xf114742d00000000, 0x79a4c80700000000, - 0x3e368ca800000000, 0x69c5b15200000000, 0x2e57f5fd00000000, - 0xa6e749d700000000, 0xe1750d7800000000, 0xb704a40c00000000, - 0xf096e0a300000000, 0x78265c8900000000, 0x3fb4182600000000, - 0x684725dc00000000, 0x2fd5617300000000, 0xa765dd5900000000, - 0xe0f799f600000000, 0x4885d77600000000, 0x0f1793d900000000, - 0x87a72ff300000000, 0xc0356b5c00000000, 0x97c656a600000000, - 0xd054120900000000, 0x58e4ae2300000000, 0x1f76ea8c00000000, - 0x8e0582af00000000, 0xc997c60000000000, 0x41277a2a00000000, - 0x06b53e8500000000, 0x5146037f00000000, 0x16d447d000000000, - 0x9e64fbfa00000000, 0xd9f6bf5500000000, 0x7184f1d500000000, - 0x3616b57a00000000, 0xbea6095000000000, 0xf9344dff00000000, - 0xaec7700500000000, 0xe95534aa00000000, 0x61e5888000000000, - 0x2677cc2f00000000, 0x7006655b00000000, 0x379421f400000000, - 0xbf249dde00000000, 0xf8b6d97100000000, 0xaf45e48b00000000, - 0xe8d7a02400000000, 0x60671c0e00000000, 0x27f558a100000000, - 0x8f87162100000000, 0xc815528e00000000, 0x40a5eea400000000, - 0x0737aa0b00000000, 0x50c497f100000000, 0x1756d35e00000000, - 0x9fe66f7400000000, 0xd8742bdb00000000, 0x33043d9d00000000, - 0x7496793200000000, 0xfc26c51800000000, 0xbbb481b700000000, - 0xec47bc4d00000000, 0xabd5f8e200000000, 0x236544c800000000, - 0x64f7006700000000, 0xcc854ee700000000, 0x8b170a4800000000, - 0x03a7b66200000000, 0x4435f2cd00000000, 0x13c6cf3700000000, - 0x54548b9800000000, 0xdce437b200000000, 0x9b76731d00000000, - 0xcd07da6900000000, 0x8a959ec600000000, 0x022522ec00000000, - 0x45b7664300000000, 0x12445bb900000000, 0x55d61f1600000000, - 0xdd66a33c00000000, 0x9af4e79300000000, 0x3286a91300000000, - 0x7514edbc00000000, 0xfda4519600000000, 0xba36153900000000, - 0xedc528c300000000, 0xaa576c6c00000000, 0x22e7d04600000000, - 0x657594e900000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, - 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, - 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, - 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, - 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, - 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, - 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, - 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, - 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, - 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, - 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, - 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, - 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, - 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, - 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, - 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, - 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, - 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, - 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, - 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, - 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, - 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, - 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, - 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, - 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, - 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, - 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, - 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, - 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, - 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, - 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, - 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, - 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, - 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, - 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, - 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, - 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, - 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, - 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, - 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, - 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, - 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, - 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, - 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, - 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, - 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, - 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, - 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, - 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, - 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, - 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, - 0xd8ac6b35}, - {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, - 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, - 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, - 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, - 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, - 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, - 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, - 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, - 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, - 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, - 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, - 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, - 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, - 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, - 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, - 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, - 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, - 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, - 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, - 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, - 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, - 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, - 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, - 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, - 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, - 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, - 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, - 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, - 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, - 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, - 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, - 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, - 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, - 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, - 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, - 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, - 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, - 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, - 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, - 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, - 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, - 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, - 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, - 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, - 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, - 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, - 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, - 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, - 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, - 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, - 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, - 0xa140efa8}, - {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, - 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, - 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, - 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, - 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, - 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, - 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, - 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, - 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, - 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, - 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, - 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, - 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, - 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, - 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, - 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, - 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, - 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, - 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, - 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, - 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, - 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, - 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, - 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, - 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, - 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, - 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, - 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, - 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, - 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, - 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, - 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, - 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, - 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, - 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, - 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, - 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, - 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, - 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, - 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, - 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, - 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, - 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, - 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, - 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, - 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, - 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, - 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, - 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, - 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, - 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, - 0x917cd6a1}, - {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, - 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, - 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, - 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, - 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, - 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, - 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, - 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, - 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, - 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, - 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, - 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, - 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, - 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, - 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, - 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, - 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, - 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, - 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, - 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, - 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, - 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, - 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, - 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, - 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, - 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, - 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, - 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, - 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, - 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, - 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, - 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, - 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, - 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, - 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, - 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, - 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, - 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, - 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, - 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, - 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, - 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, - 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, - 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, - 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, - 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, - 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, - 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, - 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, - 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, - 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, - 0x18ba364e}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x43cba687, 0xc7903cd4, 0x845b9a53, 0xcf270873, - 0x8cecaef4, 0x08b734a7, 0x4b7c9220, 0x9e4f10e6, 0xdd84b661, - 0x59df2c32, 0x1a148ab5, 0x51681895, 0x12a3be12, 0x96f82441, - 0xd53382c6, 0x7d995117, 0x3e52f790, 0xba096dc3, 0xf9c2cb44, - 0xb2be5964, 0xf175ffe3, 0x752e65b0, 0x36e5c337, 0xe3d641f1, - 0xa01de776, 0x24467d25, 0x678ddba2, 0x2cf14982, 0x6f3aef05, - 0xeb617556, 0xa8aad3d1, 0xfa32a32e, 0xb9f905a9, 0x3da29ffa, - 0x7e69397d, 0x3515ab5d, 0x76de0dda, 0xf2859789, 0xb14e310e, - 0x647db3c8, 0x27b6154f, 0xa3ed8f1c, 0xe026299b, 0xab5abbbb, - 0xe8911d3c, 0x6cca876f, 0x2f0121e8, 0x87abf239, 0xc46054be, - 0x403bceed, 0x03f0686a, 0x488cfa4a, 0x0b475ccd, 0x8f1cc69e, - 0xccd76019, 0x19e4e2df, 0x5a2f4458, 0xde74de0b, 0x9dbf788c, - 0xd6c3eaac, 0x95084c2b, 0x1153d678, 0x529870ff, 0xf465465d, - 0xb7aee0da, 0x33f57a89, 0x703edc0e, 0x3b424e2e, 0x7889e8a9, - 0xfcd272fa, 0xbf19d47d, 0x6a2a56bb, 0x29e1f03c, 0xadba6a6f, - 0xee71cce8, 0xa50d5ec8, 0xe6c6f84f, 0x629d621c, 0x2156c49b, - 0x89fc174a, 0xca37b1cd, 0x4e6c2b9e, 0x0da78d19, 0x46db1f39, - 0x0510b9be, 0x814b23ed, 0xc280856a, 0x17b307ac, 0x5478a12b, - 0xd0233b78, 0x93e89dff, 0xd8940fdf, 0x9b5fa958, 0x1f04330b, - 0x5ccf958c, 0x0e57e573, 0x4d9c43f4, 0xc9c7d9a7, 0x8a0c7f20, - 0xc170ed00, 0x82bb4b87, 0x06e0d1d4, 0x452b7753, 0x9018f595, - 0xd3d35312, 0x5788c941, 0x14436fc6, 0x5f3ffde6, 0x1cf45b61, - 0x98afc132, 0xdb6467b5, 0x73ceb464, 0x300512e3, 0xb45e88b0, - 0xf7952e37, 0xbce9bc17, 0xff221a90, 0x7b7980c3, 0x38b22644, - 0xed81a482, 0xae4a0205, 0x2a119856, 0x69da3ed1, 0x22a6acf1, - 0x616d0a76, 0xe5369025, 0xa6fd36a2, 0xe8cb8cba, 0xab002a3d, - 0x2f5bb06e, 0x6c9016e9, 0x27ec84c9, 0x6427224e, 0xe07cb81d, - 0xa3b71e9a, 0x76849c5c, 0x354f3adb, 0xb114a088, 0xf2df060f, - 0xb9a3942f, 0xfa6832a8, 0x7e33a8fb, 0x3df80e7c, 0x9552ddad, - 0xd6997b2a, 0x52c2e179, 0x110947fe, 0x5a75d5de, 0x19be7359, - 0x9de5e90a, 0xde2e4f8d, 0x0b1dcd4b, 0x48d66bcc, 0xcc8df19f, - 0x8f465718, 0xc43ac538, 0x87f163bf, 0x03aaf9ec, 0x40615f6b, - 0x12f92f94, 0x51328913, 0xd5691340, 0x96a2b5c7, 0xddde27e7, - 0x9e158160, 0x1a4e1b33, 0x5985bdb4, 0x8cb63f72, 0xcf7d99f5, - 0x4b2603a6, 0x08eda521, 0x43913701, 0x005a9186, 0x84010bd5, - 0xc7caad52, 0x6f607e83, 0x2cabd804, 0xa8f04257, 0xeb3be4d0, - 0xa04776f0, 0xe38cd077, 0x67d74a24, 0x241ceca3, 0xf12f6e65, - 0xb2e4c8e2, 0x36bf52b1, 0x7574f436, 0x3e086616, 0x7dc3c091, - 0xf9985ac2, 0xba53fc45, 0x1caecae7, 0x5f656c60, 0xdb3ef633, - 0x98f550b4, 0xd389c294, 0x90426413, 0x1419fe40, 0x57d258c7, - 0x82e1da01, 0xc12a7c86, 0x4571e6d5, 0x06ba4052, 0x4dc6d272, - 0x0e0d74f5, 0x8a56eea6, 0xc99d4821, 0x61379bf0, 0x22fc3d77, - 0xa6a7a724, 0xe56c01a3, 0xae109383, 0xeddb3504, 0x6980af57, - 0x2a4b09d0, 0xff788b16, 0xbcb32d91, 0x38e8b7c2, 0x7b231145, - 0x305f8365, 0x739425e2, 0xf7cfbfb1, 0xb4041936, 0xe69c69c9, - 0xa557cf4e, 0x210c551d, 0x62c7f39a, 0x29bb61ba, 0x6a70c73d, - 0xee2b5d6e, 0xade0fbe9, 0x78d3792f, 0x3b18dfa8, 0xbf4345fb, - 0xfc88e37c, 0xb7f4715c, 0xf43fd7db, 0x70644d88, 0x33afeb0f, - 0x9b0538de, 0xd8ce9e59, 0x5c95040a, 0x1f5ea28d, 0x542230ad, - 0x17e9962a, 0x93b20c79, 0xd079aafe, 0x054a2838, 0x46818ebf, - 0xc2da14ec, 0x8111b26b, 0xca6d204b, 0x89a686cc, 0x0dfd1c9f, - 0x4e36ba18}, - {0x00000000, 0xe1b652ef, 0x836bd405, 0x62dd86ea, 0x06d7a80b, - 0xe761fae4, 0x85bc7c0e, 0x640a2ee1, 0x0cae5117, 0xed1803f8, - 0x8fc58512, 0x6e73d7fd, 0x0a79f91c, 0xebcfabf3, 0x89122d19, - 0x68a47ff6, 0x185ca32e, 0xf9eaf1c1, 0x9b37772b, 0x7a8125c4, - 0x1e8b0b25, 0xff3d59ca, 0x9de0df20, 0x7c568dcf, 0x14f2f239, - 0xf544a0d6, 0x9799263c, 0x762f74d3, 0x12255a32, 0xf39308dd, - 0x914e8e37, 0x70f8dcd8, 0x30b8465d, 0xd10e14b2, 0xb3d39258, - 0x5265c0b7, 0x366fee56, 0xd7d9bcb9, 0xb5043a53, 0x54b268bc, - 0x3c16174a, 0xdda045a5, 0xbf7dc34f, 0x5ecb91a0, 0x3ac1bf41, - 0xdb77edae, 0xb9aa6b44, 0x581c39ab, 0x28e4e573, 0xc952b79c, - 0xab8f3176, 0x4a396399, 0x2e334d78, 0xcf851f97, 0xad58997d, - 0x4ceecb92, 0x244ab464, 0xc5fce68b, 0xa7216061, 0x4697328e, - 0x229d1c6f, 0xc32b4e80, 0xa1f6c86a, 0x40409a85, 0x60708dba, - 0x81c6df55, 0xe31b59bf, 0x02ad0b50, 0x66a725b1, 0x8711775e, - 0xe5ccf1b4, 0x047aa35b, 0x6cdedcad, 0x8d688e42, 0xefb508a8, - 0x0e035a47, 0x6a0974a6, 0x8bbf2649, 0xe962a0a3, 0x08d4f24c, - 0x782c2e94, 0x999a7c7b, 0xfb47fa91, 0x1af1a87e, 0x7efb869f, - 0x9f4dd470, 0xfd90529a, 0x1c260075, 0x74827f83, 0x95342d6c, - 0xf7e9ab86, 0x165ff969, 0x7255d788, 0x93e38567, 0xf13e038d, - 0x10885162, 0x50c8cbe7, 0xb17e9908, 0xd3a31fe2, 0x32154d0d, - 0x561f63ec, 0xb7a93103, 0xd574b7e9, 0x34c2e506, 0x5c669af0, - 0xbdd0c81f, 0xdf0d4ef5, 0x3ebb1c1a, 0x5ab132fb, 0xbb076014, - 0xd9dae6fe, 0x386cb411, 0x489468c9, 0xa9223a26, 0xcbffbccc, - 0x2a49ee23, 0x4e43c0c2, 0xaff5922d, 0xcd2814c7, 0x2c9e4628, - 0x443a39de, 0xa58c6b31, 0xc751eddb, 0x26e7bf34, 0x42ed91d5, - 0xa35bc33a, 0xc18645d0, 0x2030173f, 0x81e66bae, 0x60503941, - 0x028dbfab, 0xe33bed44, 0x8731c3a5, 0x6687914a, 0x045a17a0, - 0xe5ec454f, 0x8d483ab9, 0x6cfe6856, 0x0e23eebc, 0xef95bc53, - 0x8b9f92b2, 0x6a29c05d, 0x08f446b7, 0xe9421458, 0x99bac880, - 0x780c9a6f, 0x1ad11c85, 0xfb674e6a, 0x9f6d608b, 0x7edb3264, - 0x1c06b48e, 0xfdb0e661, 0x95149997, 0x74a2cb78, 0x167f4d92, - 0xf7c91f7d, 0x93c3319c, 0x72756373, 0x10a8e599, 0xf11eb776, - 0xb15e2df3, 0x50e87f1c, 0x3235f9f6, 0xd383ab19, 0xb78985f8, - 0x563fd717, 0x34e251fd, 0xd5540312, 0xbdf07ce4, 0x5c462e0b, - 0x3e9ba8e1, 0xdf2dfa0e, 0xbb27d4ef, 0x5a918600, 0x384c00ea, - 0xd9fa5205, 0xa9028edd, 0x48b4dc32, 0x2a695ad8, 0xcbdf0837, - 0xafd526d6, 0x4e637439, 0x2cbef2d3, 0xcd08a03c, 0xa5acdfca, - 0x441a8d25, 0x26c70bcf, 0xc7715920, 0xa37b77c1, 0x42cd252e, - 0x2010a3c4, 0xc1a6f12b, 0xe196e614, 0x0020b4fb, 0x62fd3211, - 0x834b60fe, 0xe7414e1f, 0x06f71cf0, 0x642a9a1a, 0x859cc8f5, - 0xed38b703, 0x0c8ee5ec, 0x6e536306, 0x8fe531e9, 0xebef1f08, - 0x0a594de7, 0x6884cb0d, 0x893299e2, 0xf9ca453a, 0x187c17d5, - 0x7aa1913f, 0x9b17c3d0, 0xff1ded31, 0x1eabbfde, 0x7c763934, - 0x9dc06bdb, 0xf564142d, 0x14d246c2, 0x760fc028, 0x97b992c7, - 0xf3b3bc26, 0x1205eec9, 0x70d86823, 0x916e3acc, 0xd12ea049, - 0x3098f2a6, 0x5245744c, 0xb3f326a3, 0xd7f90842, 0x364f5aad, - 0x5492dc47, 0xb5248ea8, 0xdd80f15e, 0x3c36a3b1, 0x5eeb255b, - 0xbf5d77b4, 0xdb575955, 0x3ae10bba, 0x583c8d50, 0xb98adfbf, - 0xc9720367, 0x28c45188, 0x4a19d762, 0xabaf858d, 0xcfa5ab6c, - 0x2e13f983, 0x4cce7f69, 0xad782d86, 0xc5dc5270, 0x246a009f, - 0x46b78675, 0xa701d49a, 0xc30bfa7b, 0x22bda894, 0x40602e7e, - 0xa1d67c91}, - {0x00000000, 0x5880e2d7, 0xf106b474, 0xa98656a3, 0xe20d68e9, - 0xba8d8a3e, 0x130bdc9d, 0x4b8b3e4a, 0x851da109, 0xdd9d43de, - 0x741b157d, 0x2c9bf7aa, 0x6710c9e0, 0x3f902b37, 0x96167d94, - 0xce969f43, 0x0a3b4213, 0x52bba0c4, 0xfb3df667, 0xa3bd14b0, - 0xe8362afa, 0xb0b6c82d, 0x19309e8e, 0x41b07c59, 0x8f26e31a, - 0xd7a601cd, 0x7e20576e, 0x26a0b5b9, 0x6d2b8bf3, 0x35ab6924, - 0x9c2d3f87, 0xc4addd50, 0x14768426, 0x4cf666f1, 0xe5703052, - 0xbdf0d285, 0xf67beccf, 0xaefb0e18, 0x077d58bb, 0x5ffdba6c, - 0x916b252f, 0xc9ebc7f8, 0x606d915b, 0x38ed738c, 0x73664dc6, - 0x2be6af11, 0x8260f9b2, 0xdae01b65, 0x1e4dc635, 0x46cd24e2, - 0xef4b7241, 0xb7cb9096, 0xfc40aedc, 0xa4c04c0b, 0x0d461aa8, - 0x55c6f87f, 0x9b50673c, 0xc3d085eb, 0x6a56d348, 0x32d6319f, - 0x795d0fd5, 0x21dded02, 0x885bbba1, 0xd0db5976, 0x28ec084d, - 0x706cea9a, 0xd9eabc39, 0x816a5eee, 0xcae160a4, 0x92618273, - 0x3be7d4d0, 0x63673607, 0xadf1a944, 0xf5714b93, 0x5cf71d30, - 0x0477ffe7, 0x4ffcc1ad, 0x177c237a, 0xbefa75d9, 0xe67a970e, - 0x22d74a5e, 0x7a57a889, 0xd3d1fe2a, 0x8b511cfd, 0xc0da22b7, - 0x985ac060, 0x31dc96c3, 0x695c7414, 0xa7caeb57, 0xff4a0980, - 0x56cc5f23, 0x0e4cbdf4, 0x45c783be, 0x1d476169, 0xb4c137ca, - 0xec41d51d, 0x3c9a8c6b, 0x641a6ebc, 0xcd9c381f, 0x951cdac8, - 0xde97e482, 0x86170655, 0x2f9150f6, 0x7711b221, 0xb9872d62, - 0xe107cfb5, 0x48819916, 0x10017bc1, 0x5b8a458b, 0x030aa75c, - 0xaa8cf1ff, 0xf20c1328, 0x36a1ce78, 0x6e212caf, 0xc7a77a0c, - 0x9f2798db, 0xd4aca691, 0x8c2c4446, 0x25aa12e5, 0x7d2af032, - 0xb3bc6f71, 0xeb3c8da6, 0x42badb05, 0x1a3a39d2, 0x51b10798, - 0x0931e54f, 0xa0b7b3ec, 0xf837513b, 0x50d8119a, 0x0858f34d, - 0xa1dea5ee, 0xf95e4739, 0xb2d57973, 0xea559ba4, 0x43d3cd07, - 0x1b532fd0, 0xd5c5b093, 0x8d455244, 0x24c304e7, 0x7c43e630, - 0x37c8d87a, 0x6f483aad, 0xc6ce6c0e, 0x9e4e8ed9, 0x5ae35389, - 0x0263b15e, 0xabe5e7fd, 0xf365052a, 0xb8ee3b60, 0xe06ed9b7, - 0x49e88f14, 0x11686dc3, 0xdffef280, 0x877e1057, 0x2ef846f4, - 0x7678a423, 0x3df39a69, 0x657378be, 0xccf52e1d, 0x9475ccca, - 0x44ae95bc, 0x1c2e776b, 0xb5a821c8, 0xed28c31f, 0xa6a3fd55, - 0xfe231f82, 0x57a54921, 0x0f25abf6, 0xc1b334b5, 0x9933d662, - 0x30b580c1, 0x68356216, 0x23be5c5c, 0x7b3ebe8b, 0xd2b8e828, - 0x8a380aff, 0x4e95d7af, 0x16153578, 0xbf9363db, 0xe713810c, - 0xac98bf46, 0xf4185d91, 0x5d9e0b32, 0x051ee9e5, 0xcb8876a6, - 0x93089471, 0x3a8ec2d2, 0x620e2005, 0x29851e4f, 0x7105fc98, - 0xd883aa3b, 0x800348ec, 0x783419d7, 0x20b4fb00, 0x8932ada3, - 0xd1b24f74, 0x9a39713e, 0xc2b993e9, 0x6b3fc54a, 0x33bf279d, - 0xfd29b8de, 0xa5a95a09, 0x0c2f0caa, 0x54afee7d, 0x1f24d037, - 0x47a432e0, 0xee226443, 0xb6a28694, 0x720f5bc4, 0x2a8fb913, - 0x8309efb0, 0xdb890d67, 0x9002332d, 0xc882d1fa, 0x61048759, - 0x3984658e, 0xf712facd, 0xaf92181a, 0x06144eb9, 0x5e94ac6e, - 0x151f9224, 0x4d9f70f3, 0xe4192650, 0xbc99c487, 0x6c429df1, - 0x34c27f26, 0x9d442985, 0xc5c4cb52, 0x8e4ff518, 0xd6cf17cf, - 0x7f49416c, 0x27c9a3bb, 0xe95f3cf8, 0xb1dfde2f, 0x1859888c, - 0x40d96a5b, 0x0b525411, 0x53d2b6c6, 0xfa54e065, 0xa2d402b2, - 0x6679dfe2, 0x3ef93d35, 0x977f6b96, 0xcfff8941, 0x8474b70b, - 0xdcf455dc, 0x7572037f, 0x2df2e1a8, 0xe3647eeb, 0xbbe49c3c, - 0x1262ca9f, 0x4ae22848, 0x01691602, 0x59e9f4d5, 0xf06fa276, - 0xa8ef40a1}, - {0x00000000, 0x463b6765, 0x8c76ceca, 0xca4da9af, 0x59ebed4e, - 0x1fd08a2b, 0xd59d2384, 0x93a644e1, 0xb2d6db9d, 0xf4edbcf8, - 0x3ea01557, 0x789b7232, 0xeb3d36d3, 0xad0651b6, 0x674bf819, - 0x21709f7c, 0x25abc6e0, 0x6390a185, 0xa9dd082a, 0xefe66f4f, - 0x7c402bae, 0x3a7b4ccb, 0xf036e564, 0xb60d8201, 0x977d1d7d, - 0xd1467a18, 0x1b0bd3b7, 0x5d30b4d2, 0xce96f033, 0x88ad9756, - 0x42e03ef9, 0x04db599c, 0x0b50fc1a, 0x4d6b9b7f, 0x872632d0, - 0xc11d55b5, 0x52bb1154, 0x14807631, 0xdecddf9e, 0x98f6b8fb, - 0xb9862787, 0xffbd40e2, 0x35f0e94d, 0x73cb8e28, 0xe06dcac9, - 0xa656adac, 0x6c1b0403, 0x2a206366, 0x2efb3afa, 0x68c05d9f, - 0xa28df430, 0xe4b69355, 0x7710d7b4, 0x312bb0d1, 0xfb66197e, - 0xbd5d7e1b, 0x9c2de167, 0xda168602, 0x105b2fad, 0x566048c8, - 0xc5c60c29, 0x83fd6b4c, 0x49b0c2e3, 0x0f8ba586, 0x16a0f835, - 0x509b9f50, 0x9ad636ff, 0xdced519a, 0x4f4b157b, 0x0970721e, - 0xc33ddbb1, 0x8506bcd4, 0xa47623a8, 0xe24d44cd, 0x2800ed62, - 0x6e3b8a07, 0xfd9dcee6, 0xbba6a983, 0x71eb002c, 0x37d06749, - 0x330b3ed5, 0x753059b0, 0xbf7df01f, 0xf946977a, 0x6ae0d39b, - 0x2cdbb4fe, 0xe6961d51, 0xa0ad7a34, 0x81dde548, 0xc7e6822d, - 0x0dab2b82, 0x4b904ce7, 0xd8360806, 0x9e0d6f63, 0x5440c6cc, - 0x127ba1a9, 0x1df0042f, 0x5bcb634a, 0x9186cae5, 0xd7bdad80, - 0x441be961, 0x02208e04, 0xc86d27ab, 0x8e5640ce, 0xaf26dfb2, - 0xe91db8d7, 0x23501178, 0x656b761d, 0xf6cd32fc, 0xb0f65599, - 0x7abbfc36, 0x3c809b53, 0x385bc2cf, 0x7e60a5aa, 0xb42d0c05, - 0xf2166b60, 0x61b02f81, 0x278b48e4, 0xedc6e14b, 0xabfd862e, - 0x8a8d1952, 0xccb67e37, 0x06fbd798, 0x40c0b0fd, 0xd366f41c, - 0x955d9379, 0x5f103ad6, 0x192b5db3, 0x2c40f16b, 0x6a7b960e, - 0xa0363fa1, 0xe60d58c4, 0x75ab1c25, 0x33907b40, 0xf9ddd2ef, - 0xbfe6b58a, 0x9e962af6, 0xd8ad4d93, 0x12e0e43c, 0x54db8359, - 0xc77dc7b8, 0x8146a0dd, 0x4b0b0972, 0x0d306e17, 0x09eb378b, - 0x4fd050ee, 0x859df941, 0xc3a69e24, 0x5000dac5, 0x163bbda0, - 0xdc76140f, 0x9a4d736a, 0xbb3dec16, 0xfd068b73, 0x374b22dc, - 0x717045b9, 0xe2d60158, 0xa4ed663d, 0x6ea0cf92, 0x289ba8f7, - 0x27100d71, 0x612b6a14, 0xab66c3bb, 0xed5da4de, 0x7efbe03f, - 0x38c0875a, 0xf28d2ef5, 0xb4b64990, 0x95c6d6ec, 0xd3fdb189, - 0x19b01826, 0x5f8b7f43, 0xcc2d3ba2, 0x8a165cc7, 0x405bf568, - 0x0660920d, 0x02bbcb91, 0x4480acf4, 0x8ecd055b, 0xc8f6623e, - 0x5b5026df, 0x1d6b41ba, 0xd726e815, 0x911d8f70, 0xb06d100c, - 0xf6567769, 0x3c1bdec6, 0x7a20b9a3, 0xe986fd42, 0xafbd9a27, - 0x65f03388, 0x23cb54ed, 0x3ae0095e, 0x7cdb6e3b, 0xb696c794, - 0xf0ada0f1, 0x630be410, 0x25308375, 0xef7d2ada, 0xa9464dbf, - 0x8836d2c3, 0xce0db5a6, 0x04401c09, 0x427b7b6c, 0xd1dd3f8d, - 0x97e658e8, 0x5dabf147, 0x1b909622, 0x1f4bcfbe, 0x5970a8db, - 0x933d0174, 0xd5066611, 0x46a022f0, 0x009b4595, 0xcad6ec3a, - 0x8ced8b5f, 0xad9d1423, 0xeba67346, 0x21ebdae9, 0x67d0bd8c, - 0xf476f96d, 0xb24d9e08, 0x780037a7, 0x3e3b50c2, 0x31b0f544, - 0x778b9221, 0xbdc63b8e, 0xfbfd5ceb, 0x685b180a, 0x2e607f6f, - 0xe42dd6c0, 0xa216b1a5, 0x83662ed9, 0xc55d49bc, 0x0f10e013, - 0x492b8776, 0xda8dc397, 0x9cb6a4f2, 0x56fb0d5d, 0x10c06a38, - 0x141b33a4, 0x522054c1, 0x986dfd6e, 0xde569a0b, 0x4df0deea, - 0x0bcbb98f, 0xc1861020, 0x87bd7745, 0xa6cde839, 0xe0f68f5c, - 0x2abb26f3, 0x6c804196, 0xff260577, 0xb91d6212, 0x7350cbbd, - 0x356bacd8}}; - -#endif - -#endif - -#if N == 6 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x3db1ecdc, 0x7b63d9b8, 0x46d23564, 0xf6c7b370, - 0xcb765fac, 0x8da46ac8, 0xb0158614, 0x36fe60a1, 0x0b4f8c7d, - 0x4d9db919, 0x702c55c5, 0xc039d3d1, 0xfd883f0d, 0xbb5a0a69, - 0x86ebe6b5, 0x6dfcc142, 0x504d2d9e, 0x169f18fa, 0x2b2ef426, - 0x9b3b7232, 0xa68a9eee, 0xe058ab8a, 0xdde94756, 0x5b02a1e3, - 0x66b34d3f, 0x2061785b, 0x1dd09487, 0xadc51293, 0x9074fe4f, - 0xd6a6cb2b, 0xeb1727f7, 0xdbf98284, 0xe6486e58, 0xa09a5b3c, - 0x9d2bb7e0, 0x2d3e31f4, 0x108fdd28, 0x565de84c, 0x6bec0490, - 0xed07e225, 0xd0b60ef9, 0x96643b9d, 0xabd5d741, 0x1bc05155, - 0x2671bd89, 0x60a388ed, 0x5d126431, 0xb60543c6, 0x8bb4af1a, - 0xcd669a7e, 0xf0d776a2, 0x40c2f0b6, 0x7d731c6a, 0x3ba1290e, - 0x0610c5d2, 0x80fb2367, 0xbd4acfbb, 0xfb98fadf, 0xc6291603, - 0x763c9017, 0x4b8d7ccb, 0x0d5f49af, 0x30eea573, 0x6c820349, - 0x5133ef95, 0x17e1daf1, 0x2a50362d, 0x9a45b039, 0xa7f45ce5, - 0xe1266981, 0xdc97855d, 0x5a7c63e8, 0x67cd8f34, 0x211fba50, - 0x1cae568c, 0xacbbd098, 0x910a3c44, 0xd7d80920, 0xea69e5fc, - 0x017ec20b, 0x3ccf2ed7, 0x7a1d1bb3, 0x47acf76f, 0xf7b9717b, - 0xca089da7, 0x8cdaa8c3, 0xb16b441f, 0x3780a2aa, 0x0a314e76, - 0x4ce37b12, 0x715297ce, 0xc14711da, 0xfcf6fd06, 0xba24c862, - 0x879524be, 0xb77b81cd, 0x8aca6d11, 0xcc185875, 0xf1a9b4a9, - 0x41bc32bd, 0x7c0dde61, 0x3adfeb05, 0x076e07d9, 0x8185e16c, - 0xbc340db0, 0xfae638d4, 0xc757d408, 0x7742521c, 0x4af3bec0, - 0x0c218ba4, 0x31906778, 0xda87408f, 0xe736ac53, 0xa1e49937, - 0x9c5575eb, 0x2c40f3ff, 0x11f11f23, 0x57232a47, 0x6a92c69b, - 0xec79202e, 0xd1c8ccf2, 0x971af996, 0xaaab154a, 0x1abe935e, - 0x270f7f82, 0x61dd4ae6, 0x5c6ca63a, 0xd9040692, 0xe4b5ea4e, - 0xa267df2a, 0x9fd633f6, 0x2fc3b5e2, 0x1272593e, 0x54a06c5a, - 0x69118086, 0xeffa6633, 0xd24b8aef, 0x9499bf8b, 0xa9285357, - 0x193dd543, 0x248c399f, 0x625e0cfb, 0x5fefe027, 0xb4f8c7d0, - 0x89492b0c, 0xcf9b1e68, 0xf22af2b4, 0x423f74a0, 0x7f8e987c, - 0x395cad18, 0x04ed41c4, 0x8206a771, 0xbfb74bad, 0xf9657ec9, - 0xc4d49215, 0x74c11401, 0x4970f8dd, 0x0fa2cdb9, 0x32132165, - 0x02fd8416, 0x3f4c68ca, 0x799e5dae, 0x442fb172, 0xf43a3766, - 0xc98bdbba, 0x8f59eede, 0xb2e80202, 0x3403e4b7, 0x09b2086b, - 0x4f603d0f, 0x72d1d1d3, 0xc2c457c7, 0xff75bb1b, 0xb9a78e7f, - 0x841662a3, 0x6f014554, 0x52b0a988, 0x14629cec, 0x29d37030, - 0x99c6f624, 0xa4771af8, 0xe2a52f9c, 0xdf14c340, 0x59ff25f5, - 0x644ec929, 0x229cfc4d, 0x1f2d1091, 0xaf389685, 0x92897a59, - 0xd45b4f3d, 0xe9eaa3e1, 0xb58605db, 0x8837e907, 0xcee5dc63, - 0xf35430bf, 0x4341b6ab, 0x7ef05a77, 0x38226f13, 0x059383cf, - 0x8378657a, 0xbec989a6, 0xf81bbcc2, 0xc5aa501e, 0x75bfd60a, - 0x480e3ad6, 0x0edc0fb2, 0x336de36e, 0xd87ac499, 0xe5cb2845, - 0xa3191d21, 0x9ea8f1fd, 0x2ebd77e9, 0x130c9b35, 0x55deae51, - 0x686f428d, 0xee84a438, 0xd33548e4, 0x95e77d80, 0xa856915c, - 0x18431748, 0x25f2fb94, 0x6320cef0, 0x5e91222c, 0x6e7f875f, - 0x53ce6b83, 0x151c5ee7, 0x28adb23b, 0x98b8342f, 0xa509d8f3, - 0xe3dbed97, 0xde6a014b, 0x5881e7fe, 0x65300b22, 0x23e23e46, - 0x1e53d29a, 0xae46548e, 0x93f7b852, 0xd5258d36, 0xe89461ea, - 0x0383461d, 0x3e32aac1, 0x78e09fa5, 0x45517379, 0xf544f56d, - 0xc8f519b1, 0x8e272cd5, 0xb396c009, 0x357d26bc, 0x08ccca60, - 0x4e1eff04, 0x73af13d8, 0xc3ba95cc, 0xfe0b7910, 0xb8d94c74, - 0x8568a0a8}, - {0x00000000, 0x69790b65, 0xd2f216ca, 0xbb8b1daf, 0x7e952bd5, - 0x17ec20b0, 0xac673d1f, 0xc51e367a, 0xfd2a57aa, 0x94535ccf, - 0x2fd84160, 0x46a14a05, 0x83bf7c7f, 0xeac6771a, 0x514d6ab5, - 0x383461d0, 0x2125a915, 0x485ca270, 0xf3d7bfdf, 0x9aaeb4ba, - 0x5fb082c0, 0x36c989a5, 0x8d42940a, 0xe43b9f6f, 0xdc0ffebf, - 0xb576f5da, 0x0efde875, 0x6784e310, 0xa29ad56a, 0xcbe3de0f, - 0x7068c3a0, 0x1911c8c5, 0x424b522a, 0x2b32594f, 0x90b944e0, - 0xf9c04f85, 0x3cde79ff, 0x55a7729a, 0xee2c6f35, 0x87556450, - 0xbf610580, 0xd6180ee5, 0x6d93134a, 0x04ea182f, 0xc1f42e55, - 0xa88d2530, 0x1306389f, 0x7a7f33fa, 0x636efb3f, 0x0a17f05a, - 0xb19cedf5, 0xd8e5e690, 0x1dfbd0ea, 0x7482db8f, 0xcf09c620, - 0xa670cd45, 0x9e44ac95, 0xf73da7f0, 0x4cb6ba5f, 0x25cfb13a, - 0xe0d18740, 0x89a88c25, 0x3223918a, 0x5b5a9aef, 0x8496a454, - 0xedefaf31, 0x5664b29e, 0x3f1db9fb, 0xfa038f81, 0x937a84e4, - 0x28f1994b, 0x4188922e, 0x79bcf3fe, 0x10c5f89b, 0xab4ee534, - 0xc237ee51, 0x0729d82b, 0x6e50d34e, 0xd5dbcee1, 0xbca2c584, - 0xa5b30d41, 0xccca0624, 0x77411b8b, 0x1e3810ee, 0xdb262694, - 0xb25f2df1, 0x09d4305e, 0x60ad3b3b, 0x58995aeb, 0x31e0518e, - 0x8a6b4c21, 0xe3124744, 0x260c713e, 0x4f757a5b, 0xf4fe67f4, - 0x9d876c91, 0xc6ddf67e, 0xafa4fd1b, 0x142fe0b4, 0x7d56ebd1, - 0xb848ddab, 0xd131d6ce, 0x6abacb61, 0x03c3c004, 0x3bf7a1d4, - 0x528eaab1, 0xe905b71e, 0x807cbc7b, 0x45628a01, 0x2c1b8164, - 0x97909ccb, 0xfee997ae, 0xe7f85f6b, 0x8e81540e, 0x350a49a1, - 0x5c7342c4, 0x996d74be, 0xf0147fdb, 0x4b9f6274, 0x22e66911, - 0x1ad208c1, 0x73ab03a4, 0xc8201e0b, 0xa159156e, 0x64472314, - 0x0d3e2871, 0xb6b535de, 0xdfcc3ebb, 0xd25c4ee9, 0xbb25458c, - 0x00ae5823, 0x69d75346, 0xacc9653c, 0xc5b06e59, 0x7e3b73f6, - 0x17427893, 0x2f761943, 0x460f1226, 0xfd840f89, 0x94fd04ec, - 0x51e33296, 0x389a39f3, 0x8311245c, 0xea682f39, 0xf379e7fc, - 0x9a00ec99, 0x218bf136, 0x48f2fa53, 0x8deccc29, 0xe495c74c, - 0x5f1edae3, 0x3667d186, 0x0e53b056, 0x672abb33, 0xdca1a69c, - 0xb5d8adf9, 0x70c69b83, 0x19bf90e6, 0xa2348d49, 0xcb4d862c, - 0x90171cc3, 0xf96e17a6, 0x42e50a09, 0x2b9c016c, 0xee823716, - 0x87fb3c73, 0x3c7021dc, 0x55092ab9, 0x6d3d4b69, 0x0444400c, - 0xbfcf5da3, 0xd6b656c6, 0x13a860bc, 0x7ad16bd9, 0xc15a7676, - 0xa8237d13, 0xb132b5d6, 0xd84bbeb3, 0x63c0a31c, 0x0ab9a879, - 0xcfa79e03, 0xa6de9566, 0x1d5588c9, 0x742c83ac, 0x4c18e27c, - 0x2561e919, 0x9eeaf4b6, 0xf793ffd3, 0x328dc9a9, 0x5bf4c2cc, - 0xe07fdf63, 0x8906d406, 0x56caeabd, 0x3fb3e1d8, 0x8438fc77, - 0xed41f712, 0x285fc168, 0x4126ca0d, 0xfaadd7a2, 0x93d4dcc7, - 0xabe0bd17, 0xc299b672, 0x7912abdd, 0x106ba0b8, 0xd57596c2, - 0xbc0c9da7, 0x07878008, 0x6efe8b6d, 0x77ef43a8, 0x1e9648cd, - 0xa51d5562, 0xcc645e07, 0x097a687d, 0x60036318, 0xdb887eb7, - 0xb2f175d2, 0x8ac51402, 0xe3bc1f67, 0x583702c8, 0x314e09ad, - 0xf4503fd7, 0x9d2934b2, 0x26a2291d, 0x4fdb2278, 0x1481b897, - 0x7df8b3f2, 0xc673ae5d, 0xaf0aa538, 0x6a149342, 0x036d9827, - 0xb8e68588, 0xd19f8eed, 0xe9abef3d, 0x80d2e458, 0x3b59f9f7, - 0x5220f292, 0x973ec4e8, 0xfe47cf8d, 0x45ccd222, 0x2cb5d947, - 0x35a41182, 0x5cdd1ae7, 0xe7560748, 0x8e2f0c2d, 0x4b313a57, - 0x22483132, 0x99c32c9d, 0xf0ba27f8, 0xc88e4628, 0xa1f74d4d, - 0x1a7c50e2, 0x73055b87, 0xb61b6dfd, 0xdf626698, 0x64e97b37, - 0x0d907052}, - {0x00000000, 0x7fc99b93, 0xff933726, 0x805aacb5, 0x2457680d, - 0x5b9ef39e, 0xdbc45f2b, 0xa40dc4b8, 0x48aed01a, 0x37674b89, - 0xb73de73c, 0xc8f47caf, 0x6cf9b817, 0x13302384, 0x936a8f31, - 0xeca314a2, 0x915da034, 0xee943ba7, 0x6ece9712, 0x11070c81, - 0xb50ac839, 0xcac353aa, 0x4a99ff1f, 0x3550648c, 0xd9f3702e, - 0xa63aebbd, 0x26604708, 0x59a9dc9b, 0xfda41823, 0x826d83b0, - 0x02372f05, 0x7dfeb496, 0xf9ca4629, 0x8603ddba, 0x0659710f, - 0x7990ea9c, 0xdd9d2e24, 0xa254b5b7, 0x220e1902, 0x5dc78291, - 0xb1649633, 0xcead0da0, 0x4ef7a115, 0x313e3a86, 0x9533fe3e, - 0xeafa65ad, 0x6aa0c918, 0x1569528b, 0x6897e61d, 0x175e7d8e, - 0x9704d13b, 0xe8cd4aa8, 0x4cc08e10, 0x33091583, 0xb353b936, - 0xcc9a22a5, 0x20393607, 0x5ff0ad94, 0xdfaa0121, 0xa0639ab2, - 0x046e5e0a, 0x7ba7c599, 0xfbfd692c, 0x8434f2bf, 0x28e58a13, - 0x572c1180, 0xd776bd35, 0xa8bf26a6, 0x0cb2e21e, 0x737b798d, - 0xf321d538, 0x8ce84eab, 0x604b5a09, 0x1f82c19a, 0x9fd86d2f, - 0xe011f6bc, 0x441c3204, 0x3bd5a997, 0xbb8f0522, 0xc4469eb1, - 0xb9b82a27, 0xc671b1b4, 0x462b1d01, 0x39e28692, 0x9def422a, - 0xe226d9b9, 0x627c750c, 0x1db5ee9f, 0xf116fa3d, 0x8edf61ae, - 0x0e85cd1b, 0x714c5688, 0xd5419230, 0xaa8809a3, 0x2ad2a516, - 0x551b3e85, 0xd12fcc3a, 0xaee657a9, 0x2ebcfb1c, 0x5175608f, - 0xf578a437, 0x8ab13fa4, 0x0aeb9311, 0x75220882, 0x99811c20, - 0xe64887b3, 0x66122b06, 0x19dbb095, 0xbdd6742d, 0xc21fefbe, - 0x4245430b, 0x3d8cd898, 0x40726c0e, 0x3fbbf79d, 0xbfe15b28, - 0xc028c0bb, 0x64250403, 0x1bec9f90, 0x9bb63325, 0xe47fa8b6, - 0x08dcbc14, 0x77152787, 0xf74f8b32, 0x888610a1, 0x2c8bd419, - 0x53424f8a, 0xd318e33f, 0xacd178ac, 0x51cb1426, 0x2e028fb5, - 0xae582300, 0xd191b893, 0x759c7c2b, 0x0a55e7b8, 0x8a0f4b0d, - 0xf5c6d09e, 0x1965c43c, 0x66ac5faf, 0xe6f6f31a, 0x993f6889, - 0x3d32ac31, 0x42fb37a2, 0xc2a19b17, 0xbd680084, 0xc096b412, - 0xbf5f2f81, 0x3f058334, 0x40cc18a7, 0xe4c1dc1f, 0x9b08478c, - 0x1b52eb39, 0x649b70aa, 0x88386408, 0xf7f1ff9b, 0x77ab532e, - 0x0862c8bd, 0xac6f0c05, 0xd3a69796, 0x53fc3b23, 0x2c35a0b0, - 0xa801520f, 0xd7c8c99c, 0x57926529, 0x285bfeba, 0x8c563a02, - 0xf39fa191, 0x73c50d24, 0x0c0c96b7, 0xe0af8215, 0x9f661986, - 0x1f3cb533, 0x60f52ea0, 0xc4f8ea18, 0xbb31718b, 0x3b6bdd3e, - 0x44a246ad, 0x395cf23b, 0x469569a8, 0xc6cfc51d, 0xb9065e8e, - 0x1d0b9a36, 0x62c201a5, 0xe298ad10, 0x9d513683, 0x71f22221, - 0x0e3bb9b2, 0x8e611507, 0xf1a88e94, 0x55a54a2c, 0x2a6cd1bf, - 0xaa367d0a, 0xd5ffe699, 0x792e9e35, 0x06e705a6, 0x86bda913, - 0xf9743280, 0x5d79f638, 0x22b06dab, 0xa2eac11e, 0xdd235a8d, - 0x31804e2f, 0x4e49d5bc, 0xce137909, 0xb1dae29a, 0x15d72622, - 0x6a1ebdb1, 0xea441104, 0x958d8a97, 0xe8733e01, 0x97baa592, - 0x17e00927, 0x682992b4, 0xcc24560c, 0xb3edcd9f, 0x33b7612a, - 0x4c7efab9, 0xa0ddee1b, 0xdf147588, 0x5f4ed93d, 0x208742ae, - 0x848a8616, 0xfb431d85, 0x7b19b130, 0x04d02aa3, 0x80e4d81c, - 0xff2d438f, 0x7f77ef3a, 0x00be74a9, 0xa4b3b011, 0xdb7a2b82, - 0x5b208737, 0x24e91ca4, 0xc84a0806, 0xb7839395, 0x37d93f20, - 0x4810a4b3, 0xec1d600b, 0x93d4fb98, 0x138e572d, 0x6c47ccbe, - 0x11b97828, 0x6e70e3bb, 0xee2a4f0e, 0x91e3d49d, 0x35ee1025, - 0x4a278bb6, 0xca7d2703, 0xb5b4bc90, 0x5917a832, 0x26de33a1, - 0xa6849f14, 0xd94d0487, 0x7d40c03f, 0x02895bac, 0x82d3f719, - 0xfd1a6c8a}, - {0x00000000, 0xa396284c, 0x9c5d56d9, 0x3fcb7e95, 0xe3cbabf3, - 0x405d83bf, 0x7f96fd2a, 0xdc00d566, 0x1ce651a7, 0xbf7079eb, - 0x80bb077e, 0x232d2f32, 0xff2dfa54, 0x5cbbd218, 0x6370ac8d, - 0xc0e684c1, 0x39cca34e, 0x9a5a8b02, 0xa591f597, 0x0607dddb, - 0xda0708bd, 0x799120f1, 0x465a5e64, 0xe5cc7628, 0x252af2e9, - 0x86bcdaa5, 0xb977a430, 0x1ae18c7c, 0xc6e1591a, 0x65777156, - 0x5abc0fc3, 0xf92a278f, 0x7399469c, 0xd00f6ed0, 0xefc41045, - 0x4c523809, 0x9052ed6f, 0x33c4c523, 0x0c0fbbb6, 0xaf9993fa, - 0x6f7f173b, 0xcce93f77, 0xf32241e2, 0x50b469ae, 0x8cb4bcc8, - 0x2f229484, 0x10e9ea11, 0xb37fc25d, 0x4a55e5d2, 0xe9c3cd9e, - 0xd608b30b, 0x759e9b47, 0xa99e4e21, 0x0a08666d, 0x35c318f8, - 0x965530b4, 0x56b3b475, 0xf5259c39, 0xcaeee2ac, 0x6978cae0, - 0xb5781f86, 0x16ee37ca, 0x2925495f, 0x8ab36113, 0xe7328d38, - 0x44a4a574, 0x7b6fdbe1, 0xd8f9f3ad, 0x04f926cb, 0xa76f0e87, - 0x98a47012, 0x3b32585e, 0xfbd4dc9f, 0x5842f4d3, 0x67898a46, - 0xc41fa20a, 0x181f776c, 0xbb895f20, 0x844221b5, 0x27d409f9, - 0xdefe2e76, 0x7d68063a, 0x42a378af, 0xe13550e3, 0x3d358585, - 0x9ea3adc9, 0xa168d35c, 0x02fefb10, 0xc2187fd1, 0x618e579d, - 0x5e452908, 0xfdd30144, 0x21d3d422, 0x8245fc6e, 0xbd8e82fb, - 0x1e18aab7, 0x94abcba4, 0x373de3e8, 0x08f69d7d, 0xab60b531, - 0x77606057, 0xd4f6481b, 0xeb3d368e, 0x48ab1ec2, 0x884d9a03, - 0x2bdbb24f, 0x1410ccda, 0xb786e496, 0x6b8631f0, 0xc81019bc, - 0xf7db6729, 0x544d4f65, 0xad6768ea, 0x0ef140a6, 0x313a3e33, - 0x92ac167f, 0x4eacc319, 0xed3aeb55, 0xd2f195c0, 0x7167bd8c, - 0xb181394d, 0x12171101, 0x2ddc6f94, 0x8e4a47d8, 0x524a92be, - 0xf1dcbaf2, 0xce17c467, 0x6d81ec2b, 0x15141c31, 0xb682347d, - 0x89494ae8, 0x2adf62a4, 0xf6dfb7c2, 0x55499f8e, 0x6a82e11b, - 0xc914c957, 0x09f24d96, 0xaa6465da, 0x95af1b4f, 0x36393303, - 0xea39e665, 0x49afce29, 0x7664b0bc, 0xd5f298f0, 0x2cd8bf7f, - 0x8f4e9733, 0xb085e9a6, 0x1313c1ea, 0xcf13148c, 0x6c853cc0, - 0x534e4255, 0xf0d86a19, 0x303eeed8, 0x93a8c694, 0xac63b801, - 0x0ff5904d, 0xd3f5452b, 0x70636d67, 0x4fa813f2, 0xec3e3bbe, - 0x668d5aad, 0xc51b72e1, 0xfad00c74, 0x59462438, 0x8546f15e, - 0x26d0d912, 0x191ba787, 0xba8d8fcb, 0x7a6b0b0a, 0xd9fd2346, - 0xe6365dd3, 0x45a0759f, 0x99a0a0f9, 0x3a3688b5, 0x05fdf620, - 0xa66bde6c, 0x5f41f9e3, 0xfcd7d1af, 0xc31caf3a, 0x608a8776, - 0xbc8a5210, 0x1f1c7a5c, 0x20d704c9, 0x83412c85, 0x43a7a844, - 0xe0318008, 0xdffafe9d, 0x7c6cd6d1, 0xa06c03b7, 0x03fa2bfb, - 0x3c31556e, 0x9fa77d22, 0xf2269109, 0x51b0b945, 0x6e7bc7d0, - 0xcdedef9c, 0x11ed3afa, 0xb27b12b6, 0x8db06c23, 0x2e26446f, - 0xeec0c0ae, 0x4d56e8e2, 0x729d9677, 0xd10bbe3b, 0x0d0b6b5d, - 0xae9d4311, 0x91563d84, 0x32c015c8, 0xcbea3247, 0x687c1a0b, - 0x57b7649e, 0xf4214cd2, 0x282199b4, 0x8bb7b1f8, 0xb47ccf6d, - 0x17eae721, 0xd70c63e0, 0x749a4bac, 0x4b513539, 0xe8c71d75, - 0x34c7c813, 0x9751e05f, 0xa89a9eca, 0x0b0cb686, 0x81bfd795, - 0x2229ffd9, 0x1de2814c, 0xbe74a900, 0x62747c66, 0xc1e2542a, - 0xfe292abf, 0x5dbf02f3, 0x9d598632, 0x3ecfae7e, 0x0104d0eb, - 0xa292f8a7, 0x7e922dc1, 0xdd04058d, 0xe2cf7b18, 0x41595354, - 0xb87374db, 0x1be55c97, 0x242e2202, 0x87b80a4e, 0x5bb8df28, - 0xf82ef764, 0xc7e589f1, 0x6473a1bd, 0xa495257c, 0x07030d30, - 0x38c873a5, 0x9b5e5be9, 0x475e8e8f, 0xe4c8a6c3, 0xdb03d856, - 0x7895f01a}, - {0x00000000, 0x2a283862, 0x545070c4, 0x7e7848a6, 0xa8a0e188, - 0x8288d9ea, 0xfcf0914c, 0xd6d8a92e, 0x8a30c551, 0xa018fd33, - 0xde60b595, 0xf4488df7, 0x229024d9, 0x08b81cbb, 0x76c0541d, - 0x5ce86c7f, 0xcf108ce3, 0xe538b481, 0x9b40fc27, 0xb168c445, - 0x67b06d6b, 0x4d985509, 0x33e01daf, 0x19c825cd, 0x452049b2, - 0x6f0871d0, 0x11703976, 0x3b580114, 0xed80a83a, 0xc7a89058, - 0xb9d0d8fe, 0x93f8e09c, 0x45501f87, 0x6f7827e5, 0x11006f43, - 0x3b285721, 0xedf0fe0f, 0xc7d8c66d, 0xb9a08ecb, 0x9388b6a9, - 0xcf60dad6, 0xe548e2b4, 0x9b30aa12, 0xb1189270, 0x67c03b5e, - 0x4de8033c, 0x33904b9a, 0x19b873f8, 0x8a409364, 0xa068ab06, - 0xde10e3a0, 0xf438dbc2, 0x22e072ec, 0x08c84a8e, 0x76b00228, - 0x5c983a4a, 0x00705635, 0x2a586e57, 0x542026f1, 0x7e081e93, - 0xa8d0b7bd, 0x82f88fdf, 0xfc80c779, 0xd6a8ff1b, 0x8aa03f0e, - 0xa088076c, 0xdef04fca, 0xf4d877a8, 0x2200de86, 0x0828e6e4, - 0x7650ae42, 0x5c789620, 0x0090fa5f, 0x2ab8c23d, 0x54c08a9b, - 0x7ee8b2f9, 0xa8301bd7, 0x821823b5, 0xfc606b13, 0xd6485371, - 0x45b0b3ed, 0x6f988b8f, 0x11e0c329, 0x3bc8fb4b, 0xed105265, - 0xc7386a07, 0xb94022a1, 0x93681ac3, 0xcf8076bc, 0xe5a84ede, - 0x9bd00678, 0xb1f83e1a, 0x67209734, 0x4d08af56, 0x3370e7f0, - 0x1958df92, 0xcff02089, 0xe5d818eb, 0x9ba0504d, 0xb188682f, - 0x6750c101, 0x4d78f963, 0x3300b1c5, 0x192889a7, 0x45c0e5d8, - 0x6fe8ddba, 0x1190951c, 0x3bb8ad7e, 0xed600450, 0xc7483c32, - 0xb9307494, 0x93184cf6, 0x00e0ac6a, 0x2ac89408, 0x54b0dcae, - 0x7e98e4cc, 0xa8404de2, 0x82687580, 0xfc103d26, 0xd6380544, - 0x8ad0693b, 0xa0f85159, 0xde8019ff, 0xf4a8219d, 0x227088b3, - 0x0858b0d1, 0x7620f877, 0x5c08c015, 0xce31785d, 0xe419403f, - 0x9a610899, 0xb04930fb, 0x669199d5, 0x4cb9a1b7, 0x32c1e911, - 0x18e9d173, 0x4401bd0c, 0x6e29856e, 0x1051cdc8, 0x3a79f5aa, - 0xeca15c84, 0xc68964e6, 0xb8f12c40, 0x92d91422, 0x0121f4be, - 0x2b09ccdc, 0x5571847a, 0x7f59bc18, 0xa9811536, 0x83a92d54, - 0xfdd165f2, 0xd7f95d90, 0x8b1131ef, 0xa139098d, 0xdf41412b, - 0xf5697949, 0x23b1d067, 0x0999e805, 0x77e1a0a3, 0x5dc998c1, - 0x8b6167da, 0xa1495fb8, 0xdf31171e, 0xf5192f7c, 0x23c18652, - 0x09e9be30, 0x7791f696, 0x5db9cef4, 0x0151a28b, 0x2b799ae9, - 0x5501d24f, 0x7f29ea2d, 0xa9f14303, 0x83d97b61, 0xfda133c7, - 0xd7890ba5, 0x4471eb39, 0x6e59d35b, 0x10219bfd, 0x3a09a39f, - 0xecd10ab1, 0xc6f932d3, 0xb8817a75, 0x92a94217, 0xce412e68, - 0xe469160a, 0x9a115eac, 0xb03966ce, 0x66e1cfe0, 0x4cc9f782, - 0x32b1bf24, 0x18998746, 0x44914753, 0x6eb97f31, 0x10c13797, - 0x3ae90ff5, 0xec31a6db, 0xc6199eb9, 0xb861d61f, 0x9249ee7d, - 0xcea18202, 0xe489ba60, 0x9af1f2c6, 0xb0d9caa4, 0x6601638a, - 0x4c295be8, 0x3251134e, 0x18792b2c, 0x8b81cbb0, 0xa1a9f3d2, - 0xdfd1bb74, 0xf5f98316, 0x23212a38, 0x0909125a, 0x77715afc, - 0x5d59629e, 0x01b10ee1, 0x2b993683, 0x55e17e25, 0x7fc94647, - 0xa911ef69, 0x8339d70b, 0xfd419fad, 0xd769a7cf, 0x01c158d4, - 0x2be960b6, 0x55912810, 0x7fb91072, 0xa961b95c, 0x8349813e, - 0xfd31c998, 0xd719f1fa, 0x8bf19d85, 0xa1d9a5e7, 0xdfa1ed41, - 0xf589d523, 0x23517c0d, 0x0979446f, 0x77010cc9, 0x5d2934ab, - 0xced1d437, 0xe4f9ec55, 0x9a81a4f3, 0xb0a99c91, 0x667135bf, - 0x4c590ddd, 0x3221457b, 0x18097d19, 0x44e11166, 0x6ec92904, - 0x10b161a2, 0x3a9959c0, 0xec41f0ee, 0xc669c88c, 0xb811802a, - 0x9239b848}, - {0x00000000, 0x4713f6fb, 0x8e27edf6, 0xc9341b0d, 0xc73eddad, - 0x802d2b56, 0x4919305b, 0x0e0ac6a0, 0x550cbd1b, 0x121f4be0, - 0xdb2b50ed, 0x9c38a616, 0x923260b6, 0xd521964d, 0x1c158d40, - 0x5b067bbb, 0xaa197a36, 0xed0a8ccd, 0x243e97c0, 0x632d613b, - 0x6d27a79b, 0x2a345160, 0xe3004a6d, 0xa413bc96, 0xff15c72d, - 0xb80631d6, 0x71322adb, 0x3621dc20, 0x382b1a80, 0x7f38ec7b, - 0xb60cf776, 0xf11f018d, 0x8f43f22d, 0xc85004d6, 0x01641fdb, - 0x4677e920, 0x487d2f80, 0x0f6ed97b, 0xc65ac276, 0x8149348d, - 0xda4f4f36, 0x9d5cb9cd, 0x5468a2c0, 0x137b543b, 0x1d71929b, - 0x5a626460, 0x93567f6d, 0xd4458996, 0x255a881b, 0x62497ee0, - 0xab7d65ed, 0xec6e9316, 0xe26455b6, 0xa577a34d, 0x6c43b840, - 0x2b504ebb, 0x70563500, 0x3745c3fb, 0xfe71d8f6, 0xb9622e0d, - 0xb768e8ad, 0xf07b1e56, 0x394f055b, 0x7e5cf3a0, 0xc5f6e21b, - 0x82e514e0, 0x4bd10fed, 0x0cc2f916, 0x02c83fb6, 0x45dbc94d, - 0x8cefd240, 0xcbfc24bb, 0x90fa5f00, 0xd7e9a9fb, 0x1eddb2f6, - 0x59ce440d, 0x57c482ad, 0x10d77456, 0xd9e36f5b, 0x9ef099a0, - 0x6fef982d, 0x28fc6ed6, 0xe1c875db, 0xa6db8320, 0xa8d14580, - 0xefc2b37b, 0x26f6a876, 0x61e55e8d, 0x3ae32536, 0x7df0d3cd, - 0xb4c4c8c0, 0xf3d73e3b, 0xfdddf89b, 0xbace0e60, 0x73fa156d, - 0x34e9e396, 0x4ab51036, 0x0da6e6cd, 0xc492fdc0, 0x83810b3b, - 0x8d8bcd9b, 0xca983b60, 0x03ac206d, 0x44bfd696, 0x1fb9ad2d, - 0x58aa5bd6, 0x919e40db, 0xd68db620, 0xd8877080, 0x9f94867b, - 0x56a09d76, 0x11b36b8d, 0xe0ac6a00, 0xa7bf9cfb, 0x6e8b87f6, - 0x2998710d, 0x2792b7ad, 0x60814156, 0xa9b55a5b, 0xeea6aca0, - 0xb5a0d71b, 0xf2b321e0, 0x3b873aed, 0x7c94cc16, 0x729e0ab6, - 0x358dfc4d, 0xfcb9e740, 0xbbaa11bb, 0x509cc277, 0x178f348c, - 0xdebb2f81, 0x99a8d97a, 0x97a21fda, 0xd0b1e921, 0x1985f22c, - 0x5e9604d7, 0x05907f6c, 0x42838997, 0x8bb7929a, 0xcca46461, - 0xc2aea2c1, 0x85bd543a, 0x4c894f37, 0x0b9ab9cc, 0xfa85b841, - 0xbd964eba, 0x74a255b7, 0x33b1a34c, 0x3dbb65ec, 0x7aa89317, - 0xb39c881a, 0xf48f7ee1, 0xaf89055a, 0xe89af3a1, 0x21aee8ac, - 0x66bd1e57, 0x68b7d8f7, 0x2fa42e0c, 0xe6903501, 0xa183c3fa, - 0xdfdf305a, 0x98ccc6a1, 0x51f8ddac, 0x16eb2b57, 0x18e1edf7, - 0x5ff21b0c, 0x96c60001, 0xd1d5f6fa, 0x8ad38d41, 0xcdc07bba, - 0x04f460b7, 0x43e7964c, 0x4ded50ec, 0x0afea617, 0xc3cabd1a, - 0x84d94be1, 0x75c64a6c, 0x32d5bc97, 0xfbe1a79a, 0xbcf25161, - 0xb2f897c1, 0xf5eb613a, 0x3cdf7a37, 0x7bcc8ccc, 0x20caf777, - 0x67d9018c, 0xaeed1a81, 0xe9feec7a, 0xe7f42ada, 0xa0e7dc21, - 0x69d3c72c, 0x2ec031d7, 0x956a206c, 0xd279d697, 0x1b4dcd9a, - 0x5c5e3b61, 0x5254fdc1, 0x15470b3a, 0xdc731037, 0x9b60e6cc, - 0xc0669d77, 0x87756b8c, 0x4e417081, 0x0952867a, 0x075840da, - 0x404bb621, 0x897fad2c, 0xce6c5bd7, 0x3f735a5a, 0x7860aca1, - 0xb154b7ac, 0xf6474157, 0xf84d87f7, 0xbf5e710c, 0x766a6a01, - 0x31799cfa, 0x6a7fe741, 0x2d6c11ba, 0xe4580ab7, 0xa34bfc4c, - 0xad413aec, 0xea52cc17, 0x2366d71a, 0x647521e1, 0x1a29d241, - 0x5d3a24ba, 0x940e3fb7, 0xd31dc94c, 0xdd170fec, 0x9a04f917, - 0x5330e21a, 0x142314e1, 0x4f256f5a, 0x083699a1, 0xc10282ac, - 0x86117457, 0x881bb2f7, 0xcf08440c, 0x063c5f01, 0x412fa9fa, - 0xb030a877, 0xf7235e8c, 0x3e174581, 0x7904b37a, 0x770e75da, - 0x301d8321, 0xf929982c, 0xbe3a6ed7, 0xe53c156c, 0xa22fe397, - 0x6b1bf89a, 0x2c080e61, 0x2202c8c1, 0x65113e3a, 0xac252537, - 0xeb36d3cc}, - {0x00000000, 0xa13984ee, 0x99020f9d, 0x383b8b73, 0xe975197b, - 0x484c9d95, 0x707716e6, 0xd14e9208, 0x099b34b7, 0xa8a2b059, - 0x90993b2a, 0x31a0bfc4, 0xe0ee2dcc, 0x41d7a922, 0x79ec2251, - 0xd8d5a6bf, 0x1336696e, 0xb20fed80, 0x8a3466f3, 0x2b0de21d, - 0xfa437015, 0x5b7af4fb, 0x63417f88, 0xc278fb66, 0x1aad5dd9, - 0xbb94d937, 0x83af5244, 0x2296d6aa, 0xf3d844a2, 0x52e1c04c, - 0x6ada4b3f, 0xcbe3cfd1, 0x266cd2dc, 0x87555632, 0xbf6edd41, - 0x1e5759af, 0xcf19cba7, 0x6e204f49, 0x561bc43a, 0xf72240d4, - 0x2ff7e66b, 0x8ece6285, 0xb6f5e9f6, 0x17cc6d18, 0xc682ff10, - 0x67bb7bfe, 0x5f80f08d, 0xfeb97463, 0x355abbb2, 0x94633f5c, - 0xac58b42f, 0x0d6130c1, 0xdc2fa2c9, 0x7d162627, 0x452dad54, - 0xe41429ba, 0x3cc18f05, 0x9df80beb, 0xa5c38098, 0x04fa0476, - 0xd5b4967e, 0x748d1290, 0x4cb699e3, 0xed8f1d0d, 0x4cd9a5b8, - 0xede02156, 0xd5dbaa25, 0x74e22ecb, 0xa5acbcc3, 0x0495382d, - 0x3caeb35e, 0x9d9737b0, 0x4542910f, 0xe47b15e1, 0xdc409e92, - 0x7d791a7c, 0xac378874, 0x0d0e0c9a, 0x353587e9, 0x940c0307, - 0x5fefccd6, 0xfed64838, 0xc6edc34b, 0x67d447a5, 0xb69ad5ad, - 0x17a35143, 0x2f98da30, 0x8ea15ede, 0x5674f861, 0xf74d7c8f, - 0xcf76f7fc, 0x6e4f7312, 0xbf01e11a, 0x1e3865f4, 0x2603ee87, - 0x873a6a69, 0x6ab57764, 0xcb8cf38a, 0xf3b778f9, 0x528efc17, - 0x83c06e1f, 0x22f9eaf1, 0x1ac26182, 0xbbfbe56c, 0x632e43d3, - 0xc217c73d, 0xfa2c4c4e, 0x5b15c8a0, 0x8a5b5aa8, 0x2b62de46, - 0x13595535, 0xb260d1db, 0x79831e0a, 0xd8ba9ae4, 0xe0811197, - 0x41b89579, 0x90f60771, 0x31cf839f, 0x09f408ec, 0xa8cd8c02, - 0x70182abd, 0xd121ae53, 0xe91a2520, 0x4823a1ce, 0x996d33c6, - 0x3854b728, 0x006f3c5b, 0xa156b8b5, 0x99b34b70, 0x388acf9e, - 0x00b144ed, 0xa188c003, 0x70c6520b, 0xd1ffd6e5, 0xe9c45d96, - 0x48fdd978, 0x90287fc7, 0x3111fb29, 0x092a705a, 0xa813f4b4, - 0x795d66bc, 0xd864e252, 0xe05f6921, 0x4166edcf, 0x8a85221e, - 0x2bbca6f0, 0x13872d83, 0xb2bea96d, 0x63f03b65, 0xc2c9bf8b, - 0xfaf234f8, 0x5bcbb016, 0x831e16a9, 0x22279247, 0x1a1c1934, - 0xbb259dda, 0x6a6b0fd2, 0xcb528b3c, 0xf369004f, 0x525084a1, - 0xbfdf99ac, 0x1ee61d42, 0x26dd9631, 0x87e412df, 0x56aa80d7, - 0xf7930439, 0xcfa88f4a, 0x6e910ba4, 0xb644ad1b, 0x177d29f5, - 0x2f46a286, 0x8e7f2668, 0x5f31b460, 0xfe08308e, 0xc633bbfd, - 0x670a3f13, 0xace9f0c2, 0x0dd0742c, 0x35ebff5f, 0x94d27bb1, - 0x459ce9b9, 0xe4a56d57, 0xdc9ee624, 0x7da762ca, 0xa572c475, - 0x044b409b, 0x3c70cbe8, 0x9d494f06, 0x4c07dd0e, 0xed3e59e0, - 0xd505d293, 0x743c567d, 0xd56aeec8, 0x74536a26, 0x4c68e155, - 0xed5165bb, 0x3c1ff7b3, 0x9d26735d, 0xa51df82e, 0x04247cc0, - 0xdcf1da7f, 0x7dc85e91, 0x45f3d5e2, 0xe4ca510c, 0x3584c304, - 0x94bd47ea, 0xac86cc99, 0x0dbf4877, 0xc65c87a6, 0x67650348, - 0x5f5e883b, 0xfe670cd5, 0x2f299edd, 0x8e101a33, 0xb62b9140, - 0x171215ae, 0xcfc7b311, 0x6efe37ff, 0x56c5bc8c, 0xf7fc3862, - 0x26b2aa6a, 0x878b2e84, 0xbfb0a5f7, 0x1e892119, 0xf3063c14, - 0x523fb8fa, 0x6a043389, 0xcb3db767, 0x1a73256f, 0xbb4aa181, - 0x83712af2, 0x2248ae1c, 0xfa9d08a3, 0x5ba48c4d, 0x639f073e, - 0xc2a683d0, 0x13e811d8, 0xb2d19536, 0x8aea1e45, 0x2bd39aab, - 0xe030557a, 0x4109d194, 0x79325ae7, 0xd80bde09, 0x09454c01, - 0xa87cc8ef, 0x9047439c, 0x317ec772, 0xe9ab61cd, 0x4892e523, - 0x70a96e50, 0xd190eabe, 0x00de78b6, 0xa1e7fc58, 0x99dc772b, - 0x38e5f3c5}, - {0x00000000, 0xe81790a1, 0x0b5e2703, 0xe349b7a2, 0x16bc4e06, - 0xfeabdea7, 0x1de26905, 0xf5f5f9a4, 0x2d789c0c, 0xc56f0cad, - 0x2626bb0f, 0xce312bae, 0x3bc4d20a, 0xd3d342ab, 0x309af509, - 0xd88d65a8, 0x5af13818, 0xb2e6a8b9, 0x51af1f1b, 0xb9b88fba, - 0x4c4d761e, 0xa45ae6bf, 0x4713511d, 0xaf04c1bc, 0x7789a414, - 0x9f9e34b5, 0x7cd78317, 0x94c013b6, 0x6135ea12, 0x89227ab3, - 0x6a6bcd11, 0x827c5db0, 0xb5e27030, 0x5df5e091, 0xbebc5733, - 0x56abc792, 0xa35e3e36, 0x4b49ae97, 0xa8001935, 0x40178994, - 0x989aec3c, 0x708d7c9d, 0x93c4cb3f, 0x7bd35b9e, 0x8e26a23a, - 0x6631329b, 0x85788539, 0x6d6f1598, 0xef134828, 0x0704d889, - 0xe44d6f2b, 0x0c5aff8a, 0xf9af062e, 0x11b8968f, 0xf2f1212d, - 0x1ae6b18c, 0xc26bd424, 0x2a7c4485, 0xc935f327, 0x21226386, - 0xd4d79a22, 0x3cc00a83, 0xdf89bd21, 0x379e2d80, 0xb0b5e621, - 0x58a27680, 0xbbebc122, 0x53fc5183, 0xa609a827, 0x4e1e3886, - 0xad578f24, 0x45401f85, 0x9dcd7a2d, 0x75daea8c, 0x96935d2e, - 0x7e84cd8f, 0x8b71342b, 0x6366a48a, 0x802f1328, 0x68388389, - 0xea44de39, 0x02534e98, 0xe11af93a, 0x090d699b, 0xfcf8903f, - 0x14ef009e, 0xf7a6b73c, 0x1fb1279d, 0xc73c4235, 0x2f2bd294, - 0xcc626536, 0x2475f597, 0xd1800c33, 0x39979c92, 0xdade2b30, - 0x32c9bb91, 0x05579611, 0xed4006b0, 0x0e09b112, 0xe61e21b3, - 0x13ebd817, 0xfbfc48b6, 0x18b5ff14, 0xf0a26fb5, 0x282f0a1d, - 0xc0389abc, 0x23712d1e, 0xcb66bdbf, 0x3e93441b, 0xd684d4ba, - 0x35cd6318, 0xdddaf3b9, 0x5fa6ae09, 0xb7b13ea8, 0x54f8890a, - 0xbcef19ab, 0x491ae00f, 0xa10d70ae, 0x4244c70c, 0xaa5357ad, - 0x72de3205, 0x9ac9a2a4, 0x79801506, 0x919785a7, 0x64627c03, - 0x8c75eca2, 0x6f3c5b00, 0x872bcba1, 0xba1aca03, 0x520d5aa2, - 0xb144ed00, 0x59537da1, 0xaca68405, 0x44b114a4, 0xa7f8a306, - 0x4fef33a7, 0x9762560f, 0x7f75c6ae, 0x9c3c710c, 0x742be1ad, - 0x81de1809, 0x69c988a8, 0x8a803f0a, 0x6297afab, 0xe0ebf21b, - 0x08fc62ba, 0xebb5d518, 0x03a245b9, 0xf657bc1d, 0x1e402cbc, - 0xfd099b1e, 0x151e0bbf, 0xcd936e17, 0x2584feb6, 0xc6cd4914, - 0x2edad9b5, 0xdb2f2011, 0x3338b0b0, 0xd0710712, 0x386697b3, - 0x0ff8ba33, 0xe7ef2a92, 0x04a69d30, 0xecb10d91, 0x1944f435, - 0xf1536494, 0x121ad336, 0xfa0d4397, 0x2280263f, 0xca97b69e, - 0x29de013c, 0xc1c9919d, 0x343c6839, 0xdc2bf898, 0x3f624f3a, - 0xd775df9b, 0x5509822b, 0xbd1e128a, 0x5e57a528, 0xb6403589, - 0x43b5cc2d, 0xaba25c8c, 0x48ebeb2e, 0xa0fc7b8f, 0x78711e27, - 0x90668e86, 0x732f3924, 0x9b38a985, 0x6ecd5021, 0x86dac080, - 0x65937722, 0x8d84e783, 0x0aaf2c22, 0xe2b8bc83, 0x01f10b21, - 0xe9e69b80, 0x1c136224, 0xf404f285, 0x174d4527, 0xff5ad586, - 0x27d7b02e, 0xcfc0208f, 0x2c89972d, 0xc49e078c, 0x316bfe28, - 0xd97c6e89, 0x3a35d92b, 0xd222498a, 0x505e143a, 0xb849849b, - 0x5b003339, 0xb317a398, 0x46e25a3c, 0xaef5ca9d, 0x4dbc7d3f, - 0xa5abed9e, 0x7d268836, 0x95311897, 0x7678af35, 0x9e6f3f94, - 0x6b9ac630, 0x838d5691, 0x60c4e133, 0x88d37192, 0xbf4d5c12, - 0x575accb3, 0xb4137b11, 0x5c04ebb0, 0xa9f11214, 0x41e682b5, - 0xa2af3517, 0x4ab8a5b6, 0x9235c01e, 0x7a2250bf, 0x996be71d, - 0x717c77bc, 0x84898e18, 0x6c9e1eb9, 0x8fd7a91b, 0x67c039ba, - 0xe5bc640a, 0x0dabf4ab, 0xeee24309, 0x06f5d3a8, 0xf3002a0c, - 0x1b17baad, 0xf85e0d0f, 0x10499dae, 0xc8c4f806, 0x20d368a7, - 0xc39adf05, 0x2b8d4fa4, 0xde78b600, 0x366f26a1, 0xd5269103, - 0x3d3101a2}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0xa19017e800000000, 0x03275e0b00000000, - 0xa2b749e300000000, 0x064ebc1600000000, 0xa7deabfe00000000, - 0x0569e21d00000000, 0xa4f9f5f500000000, 0x0c9c782d00000000, - 0xad0c6fc500000000, 0x0fbb262600000000, 0xae2b31ce00000000, - 0x0ad2c43b00000000, 0xab42d3d300000000, 0x09f59a3000000000, - 0xa8658dd800000000, 0x1838f15a00000000, 0xb9a8e6b200000000, - 0x1b1faf5100000000, 0xba8fb8b900000000, 0x1e764d4c00000000, - 0xbfe65aa400000000, 0x1d51134700000000, 0xbcc104af00000000, - 0x14a4897700000000, 0xb5349e9f00000000, 0x1783d77c00000000, - 0xb613c09400000000, 0x12ea356100000000, 0xb37a228900000000, - 0x11cd6b6a00000000, 0xb05d7c8200000000, 0x3070e2b500000000, - 0x91e0f55d00000000, 0x3357bcbe00000000, 0x92c7ab5600000000, - 0x363e5ea300000000, 0x97ae494b00000000, 0x351900a800000000, - 0x9489174000000000, 0x3cec9a9800000000, 0x9d7c8d7000000000, - 0x3fcbc49300000000, 0x9e5bd37b00000000, 0x3aa2268e00000000, - 0x9b32316600000000, 0x3985788500000000, 0x98156f6d00000000, - 0x284813ef00000000, 0x89d8040700000000, 0x2b6f4de400000000, - 0x8aff5a0c00000000, 0x2e06aff900000000, 0x8f96b81100000000, - 0x2d21f1f200000000, 0x8cb1e61a00000000, 0x24d46bc200000000, - 0x85447c2a00000000, 0x27f335c900000000, 0x8663222100000000, - 0x229ad7d400000000, 0x830ac03c00000000, 0x21bd89df00000000, - 0x802d9e3700000000, 0x21e6b5b000000000, 0x8076a25800000000, - 0x22c1ebbb00000000, 0x8351fc5300000000, 0x27a809a600000000, - 0x86381e4e00000000, 0x248f57ad00000000, 0x851f404500000000, - 0x2d7acd9d00000000, 0x8ceada7500000000, 0x2e5d939600000000, - 0x8fcd847e00000000, 0x2b34718b00000000, 0x8aa4666300000000, - 0x28132f8000000000, 0x8983386800000000, 0x39de44ea00000000, - 0x984e530200000000, 0x3af91ae100000000, 0x9b690d0900000000, - 0x3f90f8fc00000000, 0x9e00ef1400000000, 0x3cb7a6f700000000, - 0x9d27b11f00000000, 0x35423cc700000000, 0x94d22b2f00000000, - 0x366562cc00000000, 0x97f5752400000000, 0x330c80d100000000, - 0x929c973900000000, 0x302bdeda00000000, 0x91bbc93200000000, - 0x1196570500000000, 0xb00640ed00000000, 0x12b1090e00000000, - 0xb3211ee600000000, 0x17d8eb1300000000, 0xb648fcfb00000000, - 0x14ffb51800000000, 0xb56fa2f000000000, 0x1d0a2f2800000000, - 0xbc9a38c000000000, 0x1e2d712300000000, 0xbfbd66cb00000000, - 0x1b44933e00000000, 0xbad484d600000000, 0x1863cd3500000000, - 0xb9f3dadd00000000, 0x09aea65f00000000, 0xa83eb1b700000000, - 0x0a89f85400000000, 0xab19efbc00000000, 0x0fe01a4900000000, - 0xae700da100000000, 0x0cc7444200000000, 0xad5753aa00000000, - 0x0532de7200000000, 0xa4a2c99a00000000, 0x0615807900000000, - 0xa785979100000000, 0x037c626400000000, 0xa2ec758c00000000, - 0x005b3c6f00000000, 0xa1cb2b8700000000, 0x03ca1aba00000000, - 0xa25a0d5200000000, 0x00ed44b100000000, 0xa17d535900000000, - 0x0584a6ac00000000, 0xa414b14400000000, 0x06a3f8a700000000, - 0xa733ef4f00000000, 0x0f56629700000000, 0xaec6757f00000000, - 0x0c713c9c00000000, 0xade12b7400000000, 0x0918de8100000000, - 0xa888c96900000000, 0x0a3f808a00000000, 0xabaf976200000000, - 0x1bf2ebe000000000, 0xba62fc0800000000, 0x18d5b5eb00000000, - 0xb945a20300000000, 0x1dbc57f600000000, 0xbc2c401e00000000, - 0x1e9b09fd00000000, 0xbf0b1e1500000000, 0x176e93cd00000000, - 0xb6fe842500000000, 0x1449cdc600000000, 0xb5d9da2e00000000, - 0x11202fdb00000000, 0xb0b0383300000000, 0x120771d000000000, - 0xb397663800000000, 0x33baf80f00000000, 0x922aefe700000000, - 0x309da60400000000, 0x910db1ec00000000, 0x35f4441900000000, - 0x946453f100000000, 0x36d31a1200000000, 0x97430dfa00000000, - 0x3f26802200000000, 0x9eb697ca00000000, 0x3c01de2900000000, - 0x9d91c9c100000000, 0x39683c3400000000, 0x98f82bdc00000000, - 0x3a4f623f00000000, 0x9bdf75d700000000, 0x2b82095500000000, - 0x8a121ebd00000000, 0x28a5575e00000000, 0x893540b600000000, - 0x2dccb54300000000, 0x8c5ca2ab00000000, 0x2eebeb4800000000, - 0x8f7bfca000000000, 0x271e717800000000, 0x868e669000000000, - 0x24392f7300000000, 0x85a9389b00000000, 0x2150cd6e00000000, - 0x80c0da8600000000, 0x2277936500000000, 0x83e7848d00000000, - 0x222caf0a00000000, 0x83bcb8e200000000, 0x210bf10100000000, - 0x809be6e900000000, 0x2462131c00000000, 0x85f204f400000000, - 0x27454d1700000000, 0x86d55aff00000000, 0x2eb0d72700000000, - 0x8f20c0cf00000000, 0x2d97892c00000000, 0x8c079ec400000000, - 0x28fe6b3100000000, 0x896e7cd900000000, 0x2bd9353a00000000, - 0x8a4922d200000000, 0x3a145e5000000000, 0x9b8449b800000000, - 0x3933005b00000000, 0x98a317b300000000, 0x3c5ae24600000000, - 0x9dcaf5ae00000000, 0x3f7dbc4d00000000, 0x9eedaba500000000, - 0x3688267d00000000, 0x9718319500000000, 0x35af787600000000, - 0x943f6f9e00000000, 0x30c69a6b00000000, 0x91568d8300000000, - 0x33e1c46000000000, 0x9271d38800000000, 0x125c4dbf00000000, - 0xb3cc5a5700000000, 0x117b13b400000000, 0xb0eb045c00000000, - 0x1412f1a900000000, 0xb582e64100000000, 0x1735afa200000000, - 0xb6a5b84a00000000, 0x1ec0359200000000, 0xbf50227a00000000, - 0x1de76b9900000000, 0xbc777c7100000000, 0x188e898400000000, - 0xb91e9e6c00000000, 0x1ba9d78f00000000, 0xba39c06700000000, - 0x0a64bce500000000, 0xabf4ab0d00000000, 0x0943e2ee00000000, - 0xa8d3f50600000000, 0x0c2a00f300000000, 0xadba171b00000000, - 0x0f0d5ef800000000, 0xae9d491000000000, 0x06f8c4c800000000, - 0xa768d32000000000, 0x05df9ac300000000, 0xa44f8d2b00000000, - 0x00b678de00000000, 0xa1266f3600000000, 0x039126d500000000, - 0xa201313d00000000}, - {0x0000000000000000, 0xee8439a100000000, 0x9d0f029900000000, - 0x738b3b3800000000, 0x7b1975e900000000, 0x959d4c4800000000, - 0xe616777000000000, 0x08924ed100000000, 0xb7349b0900000000, - 0x59b0a2a800000000, 0x2a3b999000000000, 0xc4bfa03100000000, - 0xcc2deee000000000, 0x22a9d74100000000, 0x5122ec7900000000, - 0xbfa6d5d800000000, 0x6e69361300000000, 0x80ed0fb200000000, - 0xf366348a00000000, 0x1de20d2b00000000, 0x157043fa00000000, - 0xfbf47a5b00000000, 0x887f416300000000, 0x66fb78c200000000, - 0xd95dad1a00000000, 0x37d994bb00000000, 0x4452af8300000000, - 0xaad6962200000000, 0xa244d8f300000000, 0x4cc0e15200000000, - 0x3f4bda6a00000000, 0xd1cfe3cb00000000, 0xdcd26c2600000000, - 0x3256558700000000, 0x41dd6ebf00000000, 0xaf59571e00000000, - 0xa7cb19cf00000000, 0x494f206e00000000, 0x3ac41b5600000000, - 0xd44022f700000000, 0x6be6f72f00000000, 0x8562ce8e00000000, - 0xf6e9f5b600000000, 0x186dcc1700000000, 0x10ff82c600000000, - 0xfe7bbb6700000000, 0x8df0805f00000000, 0x6374b9fe00000000, - 0xb2bb5a3500000000, 0x5c3f639400000000, 0x2fb458ac00000000, - 0xc130610d00000000, 0xc9a22fdc00000000, 0x2726167d00000000, - 0x54ad2d4500000000, 0xba2914e400000000, 0x058fc13c00000000, - 0xeb0bf89d00000000, 0x9880c3a500000000, 0x7604fa0400000000, - 0x7e96b4d500000000, 0x90128d7400000000, 0xe399b64c00000000, - 0x0d1d8fed00000000, 0xb8a5d94c00000000, 0x5621e0ed00000000, - 0x25aadbd500000000, 0xcb2ee27400000000, 0xc3bcaca500000000, - 0x2d38950400000000, 0x5eb3ae3c00000000, 0xb037979d00000000, - 0x0f91424500000000, 0xe1157be400000000, 0x929e40dc00000000, - 0x7c1a797d00000000, 0x748837ac00000000, 0x9a0c0e0d00000000, - 0xe987353500000000, 0x07030c9400000000, 0xd6ccef5f00000000, - 0x3848d6fe00000000, 0x4bc3edc600000000, 0xa547d46700000000, - 0xadd59ab600000000, 0x4351a31700000000, 0x30da982f00000000, - 0xde5ea18e00000000, 0x61f8745600000000, 0x8f7c4df700000000, - 0xfcf776cf00000000, 0x12734f6e00000000, 0x1ae101bf00000000, - 0xf465381e00000000, 0x87ee032600000000, 0x696a3a8700000000, - 0x6477b56a00000000, 0x8af38ccb00000000, 0xf978b7f300000000, - 0x17fc8e5200000000, 0x1f6ec08300000000, 0xf1eaf92200000000, - 0x8261c21a00000000, 0x6ce5fbbb00000000, 0xd3432e6300000000, - 0x3dc717c200000000, 0x4e4c2cfa00000000, 0xa0c8155b00000000, - 0xa85a5b8a00000000, 0x46de622b00000000, 0x3555591300000000, - 0xdbd160b200000000, 0x0a1e837900000000, 0xe49abad800000000, - 0x971181e000000000, 0x7995b84100000000, 0x7107f69000000000, - 0x9f83cf3100000000, 0xec08f40900000000, 0x028ccda800000000, - 0xbd2a187000000000, 0x53ae21d100000000, 0x20251ae900000000, - 0xcea1234800000000, 0xc6336d9900000000, 0x28b7543800000000, - 0x5b3c6f0000000000, 0xb5b856a100000000, 0x704bb39900000000, - 0x9ecf8a3800000000, 0xed44b10000000000, 0x03c088a100000000, - 0x0b52c67000000000, 0xe5d6ffd100000000, 0x965dc4e900000000, - 0x78d9fd4800000000, 0xc77f289000000000, 0x29fb113100000000, - 0x5a702a0900000000, 0xb4f413a800000000, 0xbc665d7900000000, - 0x52e264d800000000, 0x21695fe000000000, 0xcfed664100000000, - 0x1e22858a00000000, 0xf0a6bc2b00000000, 0x832d871300000000, - 0x6da9beb200000000, 0x653bf06300000000, 0x8bbfc9c200000000, - 0xf834f2fa00000000, 0x16b0cb5b00000000, 0xa9161e8300000000, - 0x4792272200000000, 0x34191c1a00000000, 0xda9d25bb00000000, - 0xd20f6b6a00000000, 0x3c8b52cb00000000, 0x4f0069f300000000, - 0xa184505200000000, 0xac99dfbf00000000, 0x421de61e00000000, - 0x3196dd2600000000, 0xdf12e48700000000, 0xd780aa5600000000, - 0x390493f700000000, 0x4a8fa8cf00000000, 0xa40b916e00000000, - 0x1bad44b600000000, 0xf5297d1700000000, 0x86a2462f00000000, - 0x68267f8e00000000, 0x60b4315f00000000, 0x8e3008fe00000000, - 0xfdbb33c600000000, 0x133f0a6700000000, 0xc2f0e9ac00000000, - 0x2c74d00d00000000, 0x5fffeb3500000000, 0xb17bd29400000000, - 0xb9e99c4500000000, 0x576da5e400000000, 0x24e69edc00000000, - 0xca62a77d00000000, 0x75c472a500000000, 0x9b404b0400000000, - 0xe8cb703c00000000, 0x064f499d00000000, 0x0edd074c00000000, - 0xe0593eed00000000, 0x93d205d500000000, 0x7d563c7400000000, - 0xc8ee6ad500000000, 0x266a537400000000, 0x55e1684c00000000, - 0xbb6551ed00000000, 0xb3f71f3c00000000, 0x5d73269d00000000, - 0x2ef81da500000000, 0xc07c240400000000, 0x7fdaf1dc00000000, - 0x915ec87d00000000, 0xe2d5f34500000000, 0x0c51cae400000000, - 0x04c3843500000000, 0xea47bd9400000000, 0x99cc86ac00000000, - 0x7748bf0d00000000, 0xa6875cc600000000, 0x4803656700000000, - 0x3b885e5f00000000, 0xd50c67fe00000000, 0xdd9e292f00000000, - 0x331a108e00000000, 0x40912bb600000000, 0xae15121700000000, - 0x11b3c7cf00000000, 0xff37fe6e00000000, 0x8cbcc55600000000, - 0x6238fcf700000000, 0x6aaab22600000000, 0x842e8b8700000000, - 0xf7a5b0bf00000000, 0x1921891e00000000, 0x143c06f300000000, - 0xfab83f5200000000, 0x8933046a00000000, 0x67b73dcb00000000, - 0x6f25731a00000000, 0x81a14abb00000000, 0xf22a718300000000, - 0x1cae482200000000, 0xa3089dfa00000000, 0x4d8ca45b00000000, - 0x3e079f6300000000, 0xd083a6c200000000, 0xd811e81300000000, - 0x3695d1b200000000, 0x451eea8a00000000, 0xab9ad32b00000000, - 0x7a5530e000000000, 0x94d1094100000000, 0xe75a327900000000, - 0x09de0bd800000000, 0x014c450900000000, 0xefc87ca800000000, - 0x9c43479000000000, 0x72c77e3100000000, 0xcd61abe900000000, - 0x23e5924800000000, 0x506ea97000000000, 0xbeea90d100000000, - 0xb678de0000000000, 0x58fce7a100000000, 0x2b77dc9900000000, - 0xc5f3e53800000000}, - {0x0000000000000000, 0xfbf6134700000000, 0xf6ed278e00000000, - 0x0d1b34c900000000, 0xaddd3ec700000000, 0x562b2d8000000000, - 0x5b30194900000000, 0xa0c60a0e00000000, 0x1bbd0c5500000000, - 0xe04b1f1200000000, 0xed502bdb00000000, 0x16a6389c00000000, - 0xb660329200000000, 0x4d9621d500000000, 0x408d151c00000000, - 0xbb7b065b00000000, 0x367a19aa00000000, 0xcd8c0aed00000000, - 0xc0973e2400000000, 0x3b612d6300000000, 0x9ba7276d00000000, - 0x6051342a00000000, 0x6d4a00e300000000, 0x96bc13a400000000, - 0x2dc715ff00000000, 0xd63106b800000000, 0xdb2a327100000000, - 0x20dc213600000000, 0x801a2b3800000000, 0x7bec387f00000000, - 0x76f70cb600000000, 0x8d011ff100000000, 0x2df2438f00000000, - 0xd60450c800000000, 0xdb1f640100000000, 0x20e9774600000000, - 0x802f7d4800000000, 0x7bd96e0f00000000, 0x76c25ac600000000, - 0x8d34498100000000, 0x364f4fda00000000, 0xcdb95c9d00000000, - 0xc0a2685400000000, 0x3b547b1300000000, 0x9b92711d00000000, - 0x6064625a00000000, 0x6d7f569300000000, 0x968945d400000000, - 0x1b885a2500000000, 0xe07e496200000000, 0xed657dab00000000, - 0x16936eec00000000, 0xb65564e200000000, 0x4da377a500000000, - 0x40b8436c00000000, 0xbb4e502b00000000, 0x0035567000000000, - 0xfbc3453700000000, 0xf6d871fe00000000, 0x0d2e62b900000000, - 0xade868b700000000, 0x561e7bf000000000, 0x5b054f3900000000, - 0xa0f35c7e00000000, 0x1be2f6c500000000, 0xe014e58200000000, - 0xed0fd14b00000000, 0x16f9c20c00000000, 0xb63fc80200000000, - 0x4dc9db4500000000, 0x40d2ef8c00000000, 0xbb24fccb00000000, - 0x005ffa9000000000, 0xfba9e9d700000000, 0xf6b2dd1e00000000, - 0x0d44ce5900000000, 0xad82c45700000000, 0x5674d71000000000, - 0x5b6fe3d900000000, 0xa099f09e00000000, 0x2d98ef6f00000000, - 0xd66efc2800000000, 0xdb75c8e100000000, 0x2083dba600000000, - 0x8045d1a800000000, 0x7bb3c2ef00000000, 0x76a8f62600000000, - 0x8d5ee56100000000, 0x3625e33a00000000, 0xcdd3f07d00000000, - 0xc0c8c4b400000000, 0x3b3ed7f300000000, 0x9bf8ddfd00000000, - 0x600eceba00000000, 0x6d15fa7300000000, 0x96e3e93400000000, - 0x3610b54a00000000, 0xcde6a60d00000000, 0xc0fd92c400000000, - 0x3b0b818300000000, 0x9bcd8b8d00000000, 0x603b98ca00000000, - 0x6d20ac0300000000, 0x96d6bf4400000000, 0x2dadb91f00000000, - 0xd65baa5800000000, 0xdb409e9100000000, 0x20b68dd600000000, - 0x807087d800000000, 0x7b86949f00000000, 0x769da05600000000, - 0x8d6bb31100000000, 0x006aace000000000, 0xfb9cbfa700000000, - 0xf6878b6e00000000, 0x0d71982900000000, 0xadb7922700000000, - 0x5641816000000000, 0x5b5ab5a900000000, 0xa0aca6ee00000000, - 0x1bd7a0b500000000, 0xe021b3f200000000, 0xed3a873b00000000, - 0x16cc947c00000000, 0xb60a9e7200000000, 0x4dfc8d3500000000, - 0x40e7b9fc00000000, 0xbb11aabb00000000, 0x77c29c5000000000, - 0x8c348f1700000000, 0x812fbbde00000000, 0x7ad9a89900000000, - 0xda1fa29700000000, 0x21e9b1d000000000, 0x2cf2851900000000, - 0xd704965e00000000, 0x6c7f900500000000, 0x9789834200000000, - 0x9a92b78b00000000, 0x6164a4cc00000000, 0xc1a2aec200000000, - 0x3a54bd8500000000, 0x374f894c00000000, 0xccb99a0b00000000, - 0x41b885fa00000000, 0xba4e96bd00000000, 0xb755a27400000000, - 0x4ca3b13300000000, 0xec65bb3d00000000, 0x1793a87a00000000, - 0x1a889cb300000000, 0xe17e8ff400000000, 0x5a0589af00000000, - 0xa1f39ae800000000, 0xace8ae2100000000, 0x571ebd6600000000, - 0xf7d8b76800000000, 0x0c2ea42f00000000, 0x013590e600000000, - 0xfac383a100000000, 0x5a30dfdf00000000, 0xa1c6cc9800000000, - 0xacddf85100000000, 0x572beb1600000000, 0xf7ede11800000000, - 0x0c1bf25f00000000, 0x0100c69600000000, 0xfaf6d5d100000000, - 0x418dd38a00000000, 0xba7bc0cd00000000, 0xb760f40400000000, - 0x4c96e74300000000, 0xec50ed4d00000000, 0x17a6fe0a00000000, - 0x1abdcac300000000, 0xe14bd98400000000, 0x6c4ac67500000000, - 0x97bcd53200000000, 0x9aa7e1fb00000000, 0x6151f2bc00000000, - 0xc197f8b200000000, 0x3a61ebf500000000, 0x377adf3c00000000, - 0xcc8ccc7b00000000, 0x77f7ca2000000000, 0x8c01d96700000000, - 0x811aedae00000000, 0x7aecfee900000000, 0xda2af4e700000000, - 0x21dce7a000000000, 0x2cc7d36900000000, 0xd731c02e00000000, - 0x6c206a9500000000, 0x97d679d200000000, 0x9acd4d1b00000000, - 0x613b5e5c00000000, 0xc1fd545200000000, 0x3a0b471500000000, - 0x371073dc00000000, 0xcce6609b00000000, 0x779d66c000000000, - 0x8c6b758700000000, 0x8170414e00000000, 0x7a86520900000000, - 0xda40580700000000, 0x21b64b4000000000, 0x2cad7f8900000000, - 0xd75b6cce00000000, 0x5a5a733f00000000, 0xa1ac607800000000, - 0xacb754b100000000, 0x574147f600000000, 0xf7874df800000000, - 0x0c715ebf00000000, 0x016a6a7600000000, 0xfa9c793100000000, - 0x41e77f6a00000000, 0xba116c2d00000000, 0xb70a58e400000000, - 0x4cfc4ba300000000, 0xec3a41ad00000000, 0x17cc52ea00000000, - 0x1ad7662300000000, 0xe121756400000000, 0x41d2291a00000000, - 0xba243a5d00000000, 0xb73f0e9400000000, 0x4cc91dd300000000, - 0xec0f17dd00000000, 0x17f9049a00000000, 0x1ae2305300000000, - 0xe114231400000000, 0x5a6f254f00000000, 0xa199360800000000, - 0xac8202c100000000, 0x5774118600000000, 0xf7b21b8800000000, - 0x0c4408cf00000000, 0x015f3c0600000000, 0xfaa92f4100000000, - 0x77a830b000000000, 0x8c5e23f700000000, 0x8145173e00000000, - 0x7ab3047900000000, 0xda750e7700000000, 0x21831d3000000000, - 0x2c9829f900000000, 0xd76e3abe00000000, 0x6c153ce500000000, - 0x97e32fa200000000, 0x9af81b6b00000000, 0x610e082c00000000, - 0xc1c8022200000000, 0x3a3e116500000000, 0x372525ac00000000, - 0xccd336eb00000000}, - {0x0000000000000000, 0x6238282a00000000, 0xc470505400000000, - 0xa648787e00000000, 0x88e1a0a800000000, 0xead9888200000000, - 0x4c91f0fc00000000, 0x2ea9d8d600000000, 0x51c5308a00000000, - 0x33fd18a000000000, 0x95b560de00000000, 0xf78d48f400000000, - 0xd924902200000000, 0xbb1cb80800000000, 0x1d54c07600000000, - 0x7f6ce85c00000000, 0xe38c10cf00000000, 0x81b438e500000000, - 0x27fc409b00000000, 0x45c468b100000000, 0x6b6db06700000000, - 0x0955984d00000000, 0xaf1de03300000000, 0xcd25c81900000000, - 0xb249204500000000, 0xd071086f00000000, 0x7639701100000000, - 0x1401583b00000000, 0x3aa880ed00000000, 0x5890a8c700000000, - 0xfed8d0b900000000, 0x9ce0f89300000000, 0x871f504500000000, - 0xe527786f00000000, 0x436f001100000000, 0x2157283b00000000, - 0x0ffef0ed00000000, 0x6dc6d8c700000000, 0xcb8ea0b900000000, - 0xa9b6889300000000, 0xd6da60cf00000000, 0xb4e248e500000000, - 0x12aa309b00000000, 0x709218b100000000, 0x5e3bc06700000000, - 0x3c03e84d00000000, 0x9a4b903300000000, 0xf873b81900000000, - 0x6493408a00000000, 0x06ab68a000000000, 0xa0e310de00000000, - 0xc2db38f400000000, 0xec72e02200000000, 0x8e4ac80800000000, - 0x2802b07600000000, 0x4a3a985c00000000, 0x3556700000000000, - 0x576e582a00000000, 0xf126205400000000, 0x931e087e00000000, - 0xbdb7d0a800000000, 0xdf8ff88200000000, 0x79c780fc00000000, - 0x1bffa8d600000000, 0x0e3fa08a00000000, 0x6c0788a000000000, - 0xca4ff0de00000000, 0xa877d8f400000000, 0x86de002200000000, - 0xe4e6280800000000, 0x42ae507600000000, 0x2096785c00000000, - 0x5ffa900000000000, 0x3dc2b82a00000000, 0x9b8ac05400000000, - 0xf9b2e87e00000000, 0xd71b30a800000000, 0xb523188200000000, - 0x136b60fc00000000, 0x715348d600000000, 0xedb3b04500000000, - 0x8f8b986f00000000, 0x29c3e01100000000, 0x4bfbc83b00000000, - 0x655210ed00000000, 0x076a38c700000000, 0xa12240b900000000, - 0xc31a689300000000, 0xbc7680cf00000000, 0xde4ea8e500000000, - 0x7806d09b00000000, 0x1a3ef8b100000000, 0x3497206700000000, - 0x56af084d00000000, 0xf0e7703300000000, 0x92df581900000000, - 0x8920f0cf00000000, 0xeb18d8e500000000, 0x4d50a09b00000000, - 0x2f6888b100000000, 0x01c1506700000000, 0x63f9784d00000000, - 0xc5b1003300000000, 0xa789281900000000, 0xd8e5c04500000000, - 0xbadde86f00000000, 0x1c95901100000000, 0x7eadb83b00000000, - 0x500460ed00000000, 0x323c48c700000000, 0x947430b900000000, - 0xf64c189300000000, 0x6aace00000000000, 0x0894c82a00000000, - 0xaedcb05400000000, 0xcce4987e00000000, 0xe24d40a800000000, - 0x8075688200000000, 0x263d10fc00000000, 0x440538d600000000, - 0x3b69d08a00000000, 0x5951f8a000000000, 0xff1980de00000000, - 0x9d21a8f400000000, 0xb388702200000000, 0xd1b0580800000000, - 0x77f8207600000000, 0x15c0085c00000000, 0x5d7831ce00000000, - 0x3f4019e400000000, 0x9908619a00000000, 0xfb3049b000000000, - 0xd599916600000000, 0xb7a1b94c00000000, 0x11e9c13200000000, - 0x73d1e91800000000, 0x0cbd014400000000, 0x6e85296e00000000, - 0xc8cd511000000000, 0xaaf5793a00000000, 0x845ca1ec00000000, - 0xe66489c600000000, 0x402cf1b800000000, 0x2214d99200000000, - 0xbef4210100000000, 0xdccc092b00000000, 0x7a84715500000000, - 0x18bc597f00000000, 0x361581a900000000, 0x542da98300000000, - 0xf265d1fd00000000, 0x905df9d700000000, 0xef31118b00000000, - 0x8d0939a100000000, 0x2b4141df00000000, 0x497969f500000000, - 0x67d0b12300000000, 0x05e8990900000000, 0xa3a0e17700000000, - 0xc198c95d00000000, 0xda67618b00000000, 0xb85f49a100000000, - 0x1e1731df00000000, 0x7c2f19f500000000, 0x5286c12300000000, - 0x30bee90900000000, 0x96f6917700000000, 0xf4ceb95d00000000, - 0x8ba2510100000000, 0xe99a792b00000000, 0x4fd2015500000000, - 0x2dea297f00000000, 0x0343f1a900000000, 0x617bd98300000000, - 0xc733a1fd00000000, 0xa50b89d700000000, 0x39eb714400000000, - 0x5bd3596e00000000, 0xfd9b211000000000, 0x9fa3093a00000000, - 0xb10ad1ec00000000, 0xd332f9c600000000, 0x757a81b800000000, - 0x1742a99200000000, 0x682e41ce00000000, 0x0a1669e400000000, - 0xac5e119a00000000, 0xce6639b000000000, 0xe0cfe16600000000, - 0x82f7c94c00000000, 0x24bfb13200000000, 0x4687991800000000, - 0x5347914400000000, 0x317fb96e00000000, 0x9737c11000000000, - 0xf50fe93a00000000, 0xdba631ec00000000, 0xb99e19c600000000, - 0x1fd661b800000000, 0x7dee499200000000, 0x0282a1ce00000000, - 0x60ba89e400000000, 0xc6f2f19a00000000, 0xa4cad9b000000000, - 0x8a63016600000000, 0xe85b294c00000000, 0x4e13513200000000, - 0x2c2b791800000000, 0xb0cb818b00000000, 0xd2f3a9a100000000, - 0x74bbd1df00000000, 0x1683f9f500000000, 0x382a212300000000, - 0x5a12090900000000, 0xfc5a717700000000, 0x9e62595d00000000, - 0xe10eb10100000000, 0x8336992b00000000, 0x257ee15500000000, - 0x4746c97f00000000, 0x69ef11a900000000, 0x0bd7398300000000, - 0xad9f41fd00000000, 0xcfa769d700000000, 0xd458c10100000000, - 0xb660e92b00000000, 0x1028915500000000, 0x7210b97f00000000, - 0x5cb961a900000000, 0x3e81498300000000, 0x98c931fd00000000, - 0xfaf119d700000000, 0x859df18b00000000, 0xe7a5d9a100000000, - 0x41eda1df00000000, 0x23d589f500000000, 0x0d7c512300000000, - 0x6f44790900000000, 0xc90c017700000000, 0xab34295d00000000, - 0x37d4d1ce00000000, 0x55ecf9e400000000, 0xf3a4819a00000000, - 0x919ca9b000000000, 0xbf35716600000000, 0xdd0d594c00000000, - 0x7b45213200000000, 0x197d091800000000, 0x6611e14400000000, - 0x0429c96e00000000, 0xa261b11000000000, 0xc059993a00000000, - 0xeef041ec00000000, 0x8cc869c600000000, 0x2a8011b800000000, - 0x48b8399200000000}, - {0x0000000000000000, 0x4c2896a300000000, 0xd9565d9c00000000, - 0x957ecb3f00000000, 0xf3abcbe300000000, 0xbf835d4000000000, - 0x2afd967f00000000, 0x66d500dc00000000, 0xa751e61c00000000, - 0xeb7970bf00000000, 0x7e07bb8000000000, 0x322f2d2300000000, - 0x54fa2dff00000000, 0x18d2bb5c00000000, 0x8dac706300000000, - 0xc184e6c000000000, 0x4ea3cc3900000000, 0x028b5a9a00000000, - 0x97f591a500000000, 0xdbdd070600000000, 0xbd0807da00000000, - 0xf120917900000000, 0x645e5a4600000000, 0x2876cce500000000, - 0xe9f22a2500000000, 0xa5dabc8600000000, 0x30a477b900000000, - 0x7c8ce11a00000000, 0x1a59e1c600000000, 0x5671776500000000, - 0xc30fbc5a00000000, 0x8f272af900000000, 0x9c46997300000000, - 0xd06e0fd000000000, 0x4510c4ef00000000, 0x0938524c00000000, - 0x6fed529000000000, 0x23c5c43300000000, 0xb6bb0f0c00000000, - 0xfa9399af00000000, 0x3b177f6f00000000, 0x773fe9cc00000000, - 0xe24122f300000000, 0xae69b45000000000, 0xc8bcb48c00000000, - 0x8494222f00000000, 0x11eae91000000000, 0x5dc27fb300000000, - 0xd2e5554a00000000, 0x9ecdc3e900000000, 0x0bb308d600000000, - 0x479b9e7500000000, 0x214e9ea900000000, 0x6d66080a00000000, - 0xf818c33500000000, 0xb430559600000000, 0x75b4b35600000000, - 0x399c25f500000000, 0xace2eeca00000000, 0xe0ca786900000000, - 0x861f78b500000000, 0xca37ee1600000000, 0x5f49252900000000, - 0x1361b38a00000000, 0x388d32e700000000, 0x74a5a44400000000, - 0xe1db6f7b00000000, 0xadf3f9d800000000, 0xcb26f90400000000, - 0x870e6fa700000000, 0x1270a49800000000, 0x5e58323b00000000, - 0x9fdcd4fb00000000, 0xd3f4425800000000, 0x468a896700000000, - 0x0aa21fc400000000, 0x6c771f1800000000, 0x205f89bb00000000, - 0xb521428400000000, 0xf909d42700000000, 0x762efede00000000, - 0x3a06687d00000000, 0xaf78a34200000000, 0xe35035e100000000, - 0x8585353d00000000, 0xc9ada39e00000000, 0x5cd368a100000000, - 0x10fbfe0200000000, 0xd17f18c200000000, 0x9d578e6100000000, - 0x0829455e00000000, 0x4401d3fd00000000, 0x22d4d32100000000, - 0x6efc458200000000, 0xfb828ebd00000000, 0xb7aa181e00000000, - 0xa4cbab9400000000, 0xe8e33d3700000000, 0x7d9df60800000000, - 0x31b560ab00000000, 0x5760607700000000, 0x1b48f6d400000000, - 0x8e363deb00000000, 0xc21eab4800000000, 0x039a4d8800000000, - 0x4fb2db2b00000000, 0xdacc101400000000, 0x96e486b700000000, - 0xf031866b00000000, 0xbc1910c800000000, 0x2967dbf700000000, - 0x654f4d5400000000, 0xea6867ad00000000, 0xa640f10e00000000, - 0x333e3a3100000000, 0x7f16ac9200000000, 0x19c3ac4e00000000, - 0x55eb3aed00000000, 0xc095f1d200000000, 0x8cbd677100000000, - 0x4d3981b100000000, 0x0111171200000000, 0x946fdc2d00000000, - 0xd8474a8e00000000, 0xbe924a5200000000, 0xf2badcf100000000, - 0x67c417ce00000000, 0x2bec816d00000000, 0x311c141500000000, - 0x7d3482b600000000, 0xe84a498900000000, 0xa462df2a00000000, - 0xc2b7dff600000000, 0x8e9f495500000000, 0x1be1826a00000000, - 0x57c914c900000000, 0x964df20900000000, 0xda6564aa00000000, - 0x4f1baf9500000000, 0x0333393600000000, 0x65e639ea00000000, - 0x29ceaf4900000000, 0xbcb0647600000000, 0xf098f2d500000000, - 0x7fbfd82c00000000, 0x33974e8f00000000, 0xa6e985b000000000, - 0xeac1131300000000, 0x8c1413cf00000000, 0xc03c856c00000000, - 0x55424e5300000000, 0x196ad8f000000000, 0xd8ee3e3000000000, - 0x94c6a89300000000, 0x01b863ac00000000, 0x4d90f50f00000000, - 0x2b45f5d300000000, 0x676d637000000000, 0xf213a84f00000000, - 0xbe3b3eec00000000, 0xad5a8d6600000000, 0xe1721bc500000000, - 0x740cd0fa00000000, 0x3824465900000000, 0x5ef1468500000000, - 0x12d9d02600000000, 0x87a71b1900000000, 0xcb8f8dba00000000, - 0x0a0b6b7a00000000, 0x4623fdd900000000, 0xd35d36e600000000, - 0x9f75a04500000000, 0xf9a0a09900000000, 0xb588363a00000000, - 0x20f6fd0500000000, 0x6cde6ba600000000, 0xe3f9415f00000000, - 0xafd1d7fc00000000, 0x3aaf1cc300000000, 0x76878a6000000000, - 0x10528abc00000000, 0x5c7a1c1f00000000, 0xc904d72000000000, - 0x852c418300000000, 0x44a8a74300000000, 0x088031e000000000, - 0x9dfefadf00000000, 0xd1d66c7c00000000, 0xb7036ca000000000, - 0xfb2bfa0300000000, 0x6e55313c00000000, 0x227da79f00000000, - 0x099126f200000000, 0x45b9b05100000000, 0xd0c77b6e00000000, - 0x9cefedcd00000000, 0xfa3aed1100000000, 0xb6127bb200000000, - 0x236cb08d00000000, 0x6f44262e00000000, 0xaec0c0ee00000000, - 0xe2e8564d00000000, 0x77969d7200000000, 0x3bbe0bd100000000, - 0x5d6b0b0d00000000, 0x11439dae00000000, 0x843d569100000000, - 0xc815c03200000000, 0x4732eacb00000000, 0x0b1a7c6800000000, - 0x9e64b75700000000, 0xd24c21f400000000, 0xb499212800000000, - 0xf8b1b78b00000000, 0x6dcf7cb400000000, 0x21e7ea1700000000, - 0xe0630cd700000000, 0xac4b9a7400000000, 0x3935514b00000000, - 0x751dc7e800000000, 0x13c8c73400000000, 0x5fe0519700000000, - 0xca9e9aa800000000, 0x86b60c0b00000000, 0x95d7bf8100000000, - 0xd9ff292200000000, 0x4c81e21d00000000, 0x00a974be00000000, - 0x667c746200000000, 0x2a54e2c100000000, 0xbf2a29fe00000000, - 0xf302bf5d00000000, 0x3286599d00000000, 0x7eaecf3e00000000, - 0xebd0040100000000, 0xa7f892a200000000, 0xc12d927e00000000, - 0x8d0504dd00000000, 0x187bcfe200000000, 0x5453594100000000, - 0xdb7473b800000000, 0x975ce51b00000000, 0x02222e2400000000, - 0x4e0ab88700000000, 0x28dfb85b00000000, 0x64f72ef800000000, - 0xf189e5c700000000, 0xbda1736400000000, 0x7c2595a400000000, - 0x300d030700000000, 0xa573c83800000000, 0xe95b5e9b00000000, - 0x8f8e5e4700000000, 0xc3a6c8e400000000, 0x56d803db00000000, - 0x1af0957800000000}, - {0x0000000000000000, 0x939bc97f00000000, 0x263793ff00000000, - 0xb5ac5a8000000000, 0x0d68572400000000, 0x9ef39e5b00000000, - 0x2b5fc4db00000000, 0xb8c40da400000000, 0x1ad0ae4800000000, - 0x894b673700000000, 0x3ce73db700000000, 0xaf7cf4c800000000, - 0x17b8f96c00000000, 0x8423301300000000, 0x318f6a9300000000, - 0xa214a3ec00000000, 0x34a05d9100000000, 0xa73b94ee00000000, - 0x1297ce6e00000000, 0x810c071100000000, 0x39c80ab500000000, - 0xaa53c3ca00000000, 0x1fff994a00000000, 0x8c64503500000000, - 0x2e70f3d900000000, 0xbdeb3aa600000000, 0x0847602600000000, - 0x9bdca95900000000, 0x2318a4fd00000000, 0xb0836d8200000000, - 0x052f370200000000, 0x96b4fe7d00000000, 0x2946caf900000000, - 0xbadd038600000000, 0x0f71590600000000, 0x9cea907900000000, - 0x242e9ddd00000000, 0xb7b554a200000000, 0x02190e2200000000, - 0x9182c75d00000000, 0x339664b100000000, 0xa00dadce00000000, - 0x15a1f74e00000000, 0x863a3e3100000000, 0x3efe339500000000, - 0xad65faea00000000, 0x18c9a06a00000000, 0x8b52691500000000, - 0x1de6976800000000, 0x8e7d5e1700000000, 0x3bd1049700000000, - 0xa84acde800000000, 0x108ec04c00000000, 0x8315093300000000, - 0x36b953b300000000, 0xa5229acc00000000, 0x0736392000000000, - 0x94adf05f00000000, 0x2101aadf00000000, 0xb29a63a000000000, - 0x0a5e6e0400000000, 0x99c5a77b00000000, 0x2c69fdfb00000000, - 0xbff2348400000000, 0x138ae52800000000, 0x80112c5700000000, - 0x35bd76d700000000, 0xa626bfa800000000, 0x1ee2b20c00000000, - 0x8d797b7300000000, 0x38d521f300000000, 0xab4ee88c00000000, - 0x095a4b6000000000, 0x9ac1821f00000000, 0x2f6dd89f00000000, - 0xbcf611e000000000, 0x04321c4400000000, 0x97a9d53b00000000, - 0x22058fbb00000000, 0xb19e46c400000000, 0x272ab8b900000000, - 0xb4b171c600000000, 0x011d2b4600000000, 0x9286e23900000000, - 0x2a42ef9d00000000, 0xb9d926e200000000, 0x0c757c6200000000, - 0x9feeb51d00000000, 0x3dfa16f100000000, 0xae61df8e00000000, - 0x1bcd850e00000000, 0x88564c7100000000, 0x309241d500000000, - 0xa30988aa00000000, 0x16a5d22a00000000, 0x853e1b5500000000, - 0x3acc2fd100000000, 0xa957e6ae00000000, 0x1cfbbc2e00000000, - 0x8f60755100000000, 0x37a478f500000000, 0xa43fb18a00000000, - 0x1193eb0a00000000, 0x8208227500000000, 0x201c819900000000, - 0xb38748e600000000, 0x062b126600000000, 0x95b0db1900000000, - 0x2d74d6bd00000000, 0xbeef1fc200000000, 0x0b43454200000000, - 0x98d88c3d00000000, 0x0e6c724000000000, 0x9df7bb3f00000000, - 0x285be1bf00000000, 0xbbc028c000000000, 0x0304256400000000, - 0x909fec1b00000000, 0x2533b69b00000000, 0xb6a87fe400000000, - 0x14bcdc0800000000, 0x8727157700000000, 0x328b4ff700000000, - 0xa110868800000000, 0x19d48b2c00000000, 0x8a4f425300000000, - 0x3fe318d300000000, 0xac78d1ac00000000, 0x2614cb5100000000, - 0xb58f022e00000000, 0x002358ae00000000, 0x93b891d100000000, - 0x2b7c9c7500000000, 0xb8e7550a00000000, 0x0d4b0f8a00000000, - 0x9ed0c6f500000000, 0x3cc4651900000000, 0xaf5fac6600000000, - 0x1af3f6e600000000, 0x89683f9900000000, 0x31ac323d00000000, - 0xa237fb4200000000, 0x179ba1c200000000, 0x840068bd00000000, - 0x12b496c000000000, 0x812f5fbf00000000, 0x3483053f00000000, - 0xa718cc4000000000, 0x1fdcc1e400000000, 0x8c47089b00000000, - 0x39eb521b00000000, 0xaa709b6400000000, 0x0864388800000000, - 0x9bfff1f700000000, 0x2e53ab7700000000, 0xbdc8620800000000, - 0x050c6fac00000000, 0x9697a6d300000000, 0x233bfc5300000000, - 0xb0a0352c00000000, 0x0f5201a800000000, 0x9cc9c8d700000000, - 0x2965925700000000, 0xbafe5b2800000000, 0x023a568c00000000, - 0x91a19ff300000000, 0x240dc57300000000, 0xb7960c0c00000000, - 0x1582afe000000000, 0x8619669f00000000, 0x33b53c1f00000000, - 0xa02ef56000000000, 0x18eaf8c400000000, 0x8b7131bb00000000, - 0x3edd6b3b00000000, 0xad46a24400000000, 0x3bf25c3900000000, - 0xa869954600000000, 0x1dc5cfc600000000, 0x8e5e06b900000000, - 0x369a0b1d00000000, 0xa501c26200000000, 0x10ad98e200000000, - 0x8336519d00000000, 0x2122f27100000000, 0xb2b93b0e00000000, - 0x0715618e00000000, 0x948ea8f100000000, 0x2c4aa55500000000, - 0xbfd16c2a00000000, 0x0a7d36aa00000000, 0x99e6ffd500000000, - 0x359e2e7900000000, 0xa605e70600000000, 0x13a9bd8600000000, - 0x803274f900000000, 0x38f6795d00000000, 0xab6db02200000000, - 0x1ec1eaa200000000, 0x8d5a23dd00000000, 0x2f4e803100000000, - 0xbcd5494e00000000, 0x097913ce00000000, 0x9ae2dab100000000, - 0x2226d71500000000, 0xb1bd1e6a00000000, 0x041144ea00000000, - 0x978a8d9500000000, 0x013e73e800000000, 0x92a5ba9700000000, - 0x2709e01700000000, 0xb492296800000000, 0x0c5624cc00000000, - 0x9fcdedb300000000, 0x2a61b73300000000, 0xb9fa7e4c00000000, - 0x1beedda000000000, 0x887514df00000000, 0x3dd94e5f00000000, - 0xae42872000000000, 0x16868a8400000000, 0x851d43fb00000000, - 0x30b1197b00000000, 0xa32ad00400000000, 0x1cd8e48000000000, - 0x8f432dff00000000, 0x3aef777f00000000, 0xa974be0000000000, - 0x11b0b3a400000000, 0x822b7adb00000000, 0x3787205b00000000, - 0xa41ce92400000000, 0x06084ac800000000, 0x959383b700000000, - 0x203fd93700000000, 0xb3a4104800000000, 0x0b601dec00000000, - 0x98fbd49300000000, 0x2d578e1300000000, 0xbecc476c00000000, - 0x2878b91100000000, 0xbbe3706e00000000, 0x0e4f2aee00000000, - 0x9dd4e39100000000, 0x2510ee3500000000, 0xb68b274a00000000, - 0x03277dca00000000, 0x90bcb4b500000000, 0x32a8175900000000, - 0xa133de2600000000, 0x149f84a600000000, 0x87044dd900000000, - 0x3fc0407d00000000, 0xac5b890200000000, 0x19f7d38200000000, - 0x8a6c1afd00000000}, - {0x0000000000000000, 0x650b796900000000, 0xca16f2d200000000, - 0xaf1d8bbb00000000, 0xd52b957e00000000, 0xb020ec1700000000, - 0x1f3d67ac00000000, 0x7a361ec500000000, 0xaa572afd00000000, - 0xcf5c539400000000, 0x6041d82f00000000, 0x054aa14600000000, - 0x7f7cbf8300000000, 0x1a77c6ea00000000, 0xb56a4d5100000000, - 0xd061343800000000, 0x15a9252100000000, 0x70a25c4800000000, - 0xdfbfd7f300000000, 0xbab4ae9a00000000, 0xc082b05f00000000, - 0xa589c93600000000, 0x0a94428d00000000, 0x6f9f3be400000000, - 0xbffe0fdc00000000, 0xdaf576b500000000, 0x75e8fd0e00000000, - 0x10e3846700000000, 0x6ad59aa200000000, 0x0fdee3cb00000000, - 0xa0c3687000000000, 0xc5c8111900000000, 0x2a524b4200000000, - 0x4f59322b00000000, 0xe044b99000000000, 0x854fc0f900000000, - 0xff79de3c00000000, 0x9a72a75500000000, 0x356f2cee00000000, - 0x5064558700000000, 0x800561bf00000000, 0xe50e18d600000000, - 0x4a13936d00000000, 0x2f18ea0400000000, 0x552ef4c100000000, - 0x30258da800000000, 0x9f38061300000000, 0xfa337f7a00000000, - 0x3ffb6e6300000000, 0x5af0170a00000000, 0xf5ed9cb100000000, - 0x90e6e5d800000000, 0xead0fb1d00000000, 0x8fdb827400000000, - 0x20c609cf00000000, 0x45cd70a600000000, 0x95ac449e00000000, - 0xf0a73df700000000, 0x5fbab64c00000000, 0x3ab1cf2500000000, - 0x4087d1e000000000, 0x258ca88900000000, 0x8a91233200000000, - 0xef9a5a5b00000000, 0x54a4968400000000, 0x31afefed00000000, - 0x9eb2645600000000, 0xfbb91d3f00000000, 0x818f03fa00000000, - 0xe4847a9300000000, 0x4b99f12800000000, 0x2e92884100000000, - 0xfef3bc7900000000, 0x9bf8c51000000000, 0x34e54eab00000000, - 0x51ee37c200000000, 0x2bd8290700000000, 0x4ed3506e00000000, - 0xe1cedbd500000000, 0x84c5a2bc00000000, 0x410db3a500000000, - 0x2406cacc00000000, 0x8b1b417700000000, 0xee10381e00000000, - 0x942626db00000000, 0xf12d5fb200000000, 0x5e30d40900000000, - 0x3b3bad6000000000, 0xeb5a995800000000, 0x8e51e03100000000, - 0x214c6b8a00000000, 0x444712e300000000, 0x3e710c2600000000, - 0x5b7a754f00000000, 0xf467fef400000000, 0x916c879d00000000, - 0x7ef6ddc600000000, 0x1bfda4af00000000, 0xb4e02f1400000000, - 0xd1eb567d00000000, 0xabdd48b800000000, 0xced631d100000000, - 0x61cbba6a00000000, 0x04c0c30300000000, 0xd4a1f73b00000000, - 0xb1aa8e5200000000, 0x1eb705e900000000, 0x7bbc7c8000000000, - 0x018a624500000000, 0x64811b2c00000000, 0xcb9c909700000000, - 0xae97e9fe00000000, 0x6b5ff8e700000000, 0x0e54818e00000000, - 0xa1490a3500000000, 0xc442735c00000000, 0xbe746d9900000000, - 0xdb7f14f000000000, 0x74629f4b00000000, 0x1169e62200000000, - 0xc108d21a00000000, 0xa403ab7300000000, 0x0b1e20c800000000, - 0x6e1559a100000000, 0x1423476400000000, 0x71283e0d00000000, - 0xde35b5b600000000, 0xbb3eccdf00000000, 0xe94e5cd200000000, - 0x8c4525bb00000000, 0x2358ae0000000000, 0x4653d76900000000, - 0x3c65c9ac00000000, 0x596eb0c500000000, 0xf6733b7e00000000, - 0x9378421700000000, 0x4319762f00000000, 0x26120f4600000000, - 0x890f84fd00000000, 0xec04fd9400000000, 0x9632e35100000000, - 0xf3399a3800000000, 0x5c24118300000000, 0x392f68ea00000000, - 0xfce779f300000000, 0x99ec009a00000000, 0x36f18b2100000000, - 0x53faf24800000000, 0x29ccec8d00000000, 0x4cc795e400000000, - 0xe3da1e5f00000000, 0x86d1673600000000, 0x56b0530e00000000, - 0x33bb2a6700000000, 0x9ca6a1dc00000000, 0xf9add8b500000000, - 0x839bc67000000000, 0xe690bf1900000000, 0x498d34a200000000, - 0x2c864dcb00000000, 0xc31c179000000000, 0xa6176ef900000000, - 0x090ae54200000000, 0x6c019c2b00000000, 0x163782ee00000000, - 0x733cfb8700000000, 0xdc21703c00000000, 0xb92a095500000000, - 0x694b3d6d00000000, 0x0c40440400000000, 0xa35dcfbf00000000, - 0xc656b6d600000000, 0xbc60a81300000000, 0xd96bd17a00000000, - 0x76765ac100000000, 0x137d23a800000000, 0xd6b532b100000000, - 0xb3be4bd800000000, 0x1ca3c06300000000, 0x79a8b90a00000000, - 0x039ea7cf00000000, 0x6695dea600000000, 0xc988551d00000000, - 0xac832c7400000000, 0x7ce2184c00000000, 0x19e9612500000000, - 0xb6f4ea9e00000000, 0xd3ff93f700000000, 0xa9c98d3200000000, - 0xccc2f45b00000000, 0x63df7fe000000000, 0x06d4068900000000, - 0xbdeaca5600000000, 0xd8e1b33f00000000, 0x77fc388400000000, - 0x12f741ed00000000, 0x68c15f2800000000, 0x0dca264100000000, - 0xa2d7adfa00000000, 0xc7dcd49300000000, 0x17bde0ab00000000, - 0x72b699c200000000, 0xddab127900000000, 0xb8a06b1000000000, - 0xc29675d500000000, 0xa79d0cbc00000000, 0x0880870700000000, - 0x6d8bfe6e00000000, 0xa843ef7700000000, 0xcd48961e00000000, - 0x62551da500000000, 0x075e64cc00000000, 0x7d687a0900000000, - 0x1863036000000000, 0xb77e88db00000000, 0xd275f1b200000000, - 0x0214c58a00000000, 0x671fbce300000000, 0xc802375800000000, - 0xad094e3100000000, 0xd73f50f400000000, 0xb234299d00000000, - 0x1d29a22600000000, 0x7822db4f00000000, 0x97b8811400000000, - 0xf2b3f87d00000000, 0x5dae73c600000000, 0x38a50aaf00000000, - 0x4293146a00000000, 0x27986d0300000000, 0x8885e6b800000000, - 0xed8e9fd100000000, 0x3defabe900000000, 0x58e4d28000000000, - 0xf7f9593b00000000, 0x92f2205200000000, 0xe8c43e9700000000, - 0x8dcf47fe00000000, 0x22d2cc4500000000, 0x47d9b52c00000000, - 0x8211a43500000000, 0xe71add5c00000000, 0x480756e700000000, - 0x2d0c2f8e00000000, 0x573a314b00000000, 0x3231482200000000, - 0x9d2cc39900000000, 0xf827baf000000000, 0x28468ec800000000, - 0x4d4df7a100000000, 0xe2507c1a00000000, 0x875b057300000000, - 0xfd6d1bb600000000, 0x986662df00000000, 0x377be96400000000, - 0x5270900d00000000}, - {0x0000000000000000, 0xdcecb13d00000000, 0xb8d9637b00000000, - 0x6435d24600000000, 0x70b3c7f600000000, 0xac5f76cb00000000, - 0xc86aa48d00000000, 0x148615b000000000, 0xa160fe3600000000, - 0x7d8c4f0b00000000, 0x19b99d4d00000000, 0xc5552c7000000000, - 0xd1d339c000000000, 0x0d3f88fd00000000, 0x690a5abb00000000, - 0xb5e6eb8600000000, 0x42c1fc6d00000000, 0x9e2d4d5000000000, - 0xfa189f1600000000, 0x26f42e2b00000000, 0x32723b9b00000000, - 0xee9e8aa600000000, 0x8aab58e000000000, 0x5647e9dd00000000, - 0xe3a1025b00000000, 0x3f4db36600000000, 0x5b78612000000000, - 0x8794d01d00000000, 0x9312c5ad00000000, 0x4ffe749000000000, - 0x2bcba6d600000000, 0xf72717eb00000000, 0x8482f9db00000000, - 0x586e48e600000000, 0x3c5b9aa000000000, 0xe0b72b9d00000000, - 0xf4313e2d00000000, 0x28dd8f1000000000, 0x4ce85d5600000000, - 0x9004ec6b00000000, 0x25e207ed00000000, 0xf90eb6d000000000, - 0x9d3b649600000000, 0x41d7d5ab00000000, 0x5551c01b00000000, - 0x89bd712600000000, 0xed88a36000000000, 0x3164125d00000000, - 0xc64305b600000000, 0x1aafb48b00000000, 0x7e9a66cd00000000, - 0xa276d7f000000000, 0xb6f0c24000000000, 0x6a1c737d00000000, - 0x0e29a13b00000000, 0xd2c5100600000000, 0x6723fb8000000000, - 0xbbcf4abd00000000, 0xdffa98fb00000000, 0x031629c600000000, - 0x17903c7600000000, 0xcb7c8d4b00000000, 0xaf495f0d00000000, - 0x73a5ee3000000000, 0x4903826c00000000, 0x95ef335100000000, - 0xf1dae11700000000, 0x2d36502a00000000, 0x39b0459a00000000, - 0xe55cf4a700000000, 0x816926e100000000, 0x5d8597dc00000000, - 0xe8637c5a00000000, 0x348fcd6700000000, 0x50ba1f2100000000, - 0x8c56ae1c00000000, 0x98d0bbac00000000, 0x443c0a9100000000, - 0x2009d8d700000000, 0xfce569ea00000000, 0x0bc27e0100000000, - 0xd72ecf3c00000000, 0xb31b1d7a00000000, 0x6ff7ac4700000000, - 0x7b71b9f700000000, 0xa79d08ca00000000, 0xc3a8da8c00000000, - 0x1f446bb100000000, 0xaaa2803700000000, 0x764e310a00000000, - 0x127be34c00000000, 0xce97527100000000, 0xda1147c100000000, - 0x06fdf6fc00000000, 0x62c824ba00000000, 0xbe24958700000000, - 0xcd817bb700000000, 0x116dca8a00000000, 0x755818cc00000000, - 0xa9b4a9f100000000, 0xbd32bc4100000000, 0x61de0d7c00000000, - 0x05ebdf3a00000000, 0xd9076e0700000000, 0x6ce1858100000000, - 0xb00d34bc00000000, 0xd438e6fa00000000, 0x08d457c700000000, - 0x1c52427700000000, 0xc0bef34a00000000, 0xa48b210c00000000, - 0x7867903100000000, 0x8f4087da00000000, 0x53ac36e700000000, - 0x3799e4a100000000, 0xeb75559c00000000, 0xfff3402c00000000, - 0x231ff11100000000, 0x472a235700000000, 0x9bc6926a00000000, - 0x2e2079ec00000000, 0xf2ccc8d100000000, 0x96f91a9700000000, - 0x4a15abaa00000000, 0x5e93be1a00000000, 0x827f0f2700000000, - 0xe64add6100000000, 0x3aa66c5c00000000, 0x920604d900000000, - 0x4eeab5e400000000, 0x2adf67a200000000, 0xf633d69f00000000, - 0xe2b5c32f00000000, 0x3e59721200000000, 0x5a6ca05400000000, - 0x8680116900000000, 0x3366faef00000000, 0xef8a4bd200000000, - 0x8bbf999400000000, 0x575328a900000000, 0x43d53d1900000000, - 0x9f398c2400000000, 0xfb0c5e6200000000, 0x27e0ef5f00000000, - 0xd0c7f8b400000000, 0x0c2b498900000000, 0x681e9bcf00000000, - 0xb4f22af200000000, 0xa0743f4200000000, 0x7c988e7f00000000, - 0x18ad5c3900000000, 0xc441ed0400000000, 0x71a7068200000000, - 0xad4bb7bf00000000, 0xc97e65f900000000, 0x1592d4c400000000, - 0x0114c17400000000, 0xddf8704900000000, 0xb9cda20f00000000, - 0x6521133200000000, 0x1684fd0200000000, 0xca684c3f00000000, - 0xae5d9e7900000000, 0x72b12f4400000000, 0x66373af400000000, - 0xbadb8bc900000000, 0xdeee598f00000000, 0x0202e8b200000000, - 0xb7e4033400000000, 0x6b08b20900000000, 0x0f3d604f00000000, - 0xd3d1d17200000000, 0xc757c4c200000000, 0x1bbb75ff00000000, - 0x7f8ea7b900000000, 0xa362168400000000, 0x5445016f00000000, - 0x88a9b05200000000, 0xec9c621400000000, 0x3070d32900000000, - 0x24f6c69900000000, 0xf81a77a400000000, 0x9c2fa5e200000000, - 0x40c314df00000000, 0xf525ff5900000000, 0x29c94e6400000000, - 0x4dfc9c2200000000, 0x91102d1f00000000, 0x859638af00000000, - 0x597a899200000000, 0x3d4f5bd400000000, 0xe1a3eae900000000, - 0xdb0586b500000000, 0x07e9378800000000, 0x63dce5ce00000000, - 0xbf3054f300000000, 0xabb6414300000000, 0x775af07e00000000, - 0x136f223800000000, 0xcf83930500000000, 0x7a65788300000000, - 0xa689c9be00000000, 0xc2bc1bf800000000, 0x1e50aac500000000, - 0x0ad6bf7500000000, 0xd63a0e4800000000, 0xb20fdc0e00000000, - 0x6ee36d3300000000, 0x99c47ad800000000, 0x4528cbe500000000, - 0x211d19a300000000, 0xfdf1a89e00000000, 0xe977bd2e00000000, - 0x359b0c1300000000, 0x51aede5500000000, 0x8d426f6800000000, - 0x38a484ee00000000, 0xe44835d300000000, 0x807de79500000000, - 0x5c9156a800000000, 0x4817431800000000, 0x94fbf22500000000, - 0xf0ce206300000000, 0x2c22915e00000000, 0x5f877f6e00000000, - 0x836bce5300000000, 0xe75e1c1500000000, 0x3bb2ad2800000000, - 0x2f34b89800000000, 0xf3d809a500000000, 0x97eddbe300000000, - 0x4b016ade00000000, 0xfee7815800000000, 0x220b306500000000, - 0x463ee22300000000, 0x9ad2531e00000000, 0x8e5446ae00000000, - 0x52b8f79300000000, 0x368d25d500000000, 0xea6194e800000000, - 0x1d46830300000000, 0xc1aa323e00000000, 0xa59fe07800000000, - 0x7973514500000000, 0x6df544f500000000, 0xb119f5c800000000, - 0xd52c278e00000000, 0x09c096b300000000, 0xbc267d3500000000, - 0x60cacc0800000000, 0x04ff1e4e00000000, 0xd813af7300000000, - 0xcc95bac300000000, 0x10790bfe00000000, 0x744cd9b800000000, - 0xa8a0688500000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, - 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, - 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, - 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, - 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, - 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, - 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, - 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, - 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, - 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, - 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, - 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, - 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, - 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, - 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, - 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, - 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, - 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, - 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, - 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, - 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, - 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, - 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, - 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, - 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, - 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, - 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, - 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, - 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, - 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, - 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, - 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, - 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, - 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, - 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, - 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, - 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, - 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, - 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, - 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, - 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, - 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, - 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, - 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, - 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, - 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, - 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, - 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, - 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, - 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, - 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, - 0x09cd8551}, - {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, - 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, - 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, - 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, - 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, - 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, - 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, - 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, - 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, - 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, - 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, - 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, - 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, - 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, - 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, - 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, - 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, - 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, - 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, - 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, - 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, - 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, - 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, - 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, - 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, - 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, - 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, - 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, - 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, - 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, - 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, - 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, - 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, - 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, - 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, - 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, - 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, - 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, - 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, - 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, - 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, - 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, - 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, - 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, - 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, - 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, - 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, - 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, - 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, - 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, - 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, - 0x7bc97a0c}, - {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, - 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, - 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, - 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, - 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, - 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, - 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, - 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, - 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, - 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, - 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, - 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, - 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, - 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, - 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, - 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, - 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, - 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, - 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, - 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, - 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, - 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, - 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, - 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, - 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, - 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, - 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, - 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, - 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, - 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, - 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, - 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, - 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, - 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, - 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, - 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, - 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, - 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, - 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, - 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, - 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, - 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, - 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, - 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, - 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, - 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, - 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, - 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, - 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, - 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, - 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, - 0x7851a2ca}, - {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, - 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, - 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, - 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, - 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, - 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, - 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, - 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, - 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, - 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, - 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, - 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, - 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, - 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, - 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, - 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, - 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, - 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, - 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, - 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, - 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, - 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, - 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, - 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, - 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, - 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, - 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, - 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, - 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, - 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, - 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, - 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, - 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, - 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, - 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, - 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, - 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, - 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, - 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, - 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, - 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, - 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, - 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, - 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, - 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, - 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, - 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, - 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, - 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, - 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, - 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, - 0x566b6848}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x9e83da9f, 0x7d01c4e4, 0xe3821e7b, 0xbb04f912, - 0x2587238d, 0xc6053df6, 0x5886e769, 0x7609f225, 0xe88a28ba, - 0x0b0836c1, 0x958bec5e, 0xcd0d0b37, 0x538ed1a8, 0xb00ccfd3, - 0x2e8f154c, 0xec12e44b, 0x72913ed4, 0x911320af, 0x0f90fa30, - 0x57161d59, 0xc995c7c6, 0x2a17d9bd, 0xb4940322, 0x9a1b166e, - 0x0498ccf1, 0xe71ad28a, 0x79990815, 0x211fef7c, 0xbf9c35e3, - 0x5c1e2b98, 0xc29df107, 0xd825c897, 0x46a61208, 0xa5240c73, - 0x3ba7d6ec, 0x63213185, 0xfda2eb1a, 0x1e20f561, 0x80a32ffe, - 0xae2c3ab2, 0x30afe02d, 0xd32dfe56, 0x4dae24c9, 0x1528c3a0, - 0x8bab193f, 0x68290744, 0xf6aadddb, 0x34372cdc, 0xaab4f643, - 0x4936e838, 0xd7b532a7, 0x8f33d5ce, 0x11b00f51, 0xf232112a, - 0x6cb1cbb5, 0x423edef9, 0xdcbd0466, 0x3f3f1a1d, 0xa1bcc082, - 0xf93a27eb, 0x67b9fd74, 0x843be30f, 0x1ab83990, 0xf14de1f4, - 0x6fce3b6b, 0x8c4c2510, 0x12cfff8f, 0x4a4918e6, 0xd4cac279, - 0x3748dc02, 0xa9cb069d, 0x874413d1, 0x19c7c94e, 0xfa45d735, - 0x64c60daa, 0x3c40eac3, 0xa2c3305c, 0x41412e27, 0xdfc2f4b8, - 0x1d5f05bf, 0x83dcdf20, 0x605ec15b, 0xfedd1bc4, 0xa65bfcad, - 0x38d82632, 0xdb5a3849, 0x45d9e2d6, 0x6b56f79a, 0xf5d52d05, - 0x1657337e, 0x88d4e9e1, 0xd0520e88, 0x4ed1d417, 0xad53ca6c, - 0x33d010f3, 0x29682963, 0xb7ebf3fc, 0x5469ed87, 0xcaea3718, - 0x926cd071, 0x0cef0aee, 0xef6d1495, 0x71eece0a, 0x5f61db46, - 0xc1e201d9, 0x22601fa2, 0xbce3c53d, 0xe4652254, 0x7ae6f8cb, - 0x9964e6b0, 0x07e73c2f, 0xc57acd28, 0x5bf917b7, 0xb87b09cc, - 0x26f8d353, 0x7e7e343a, 0xe0fdeea5, 0x037ff0de, 0x9dfc2a41, - 0xb3733f0d, 0x2df0e592, 0xce72fbe9, 0x50f12176, 0x0877c61f, - 0x96f41c80, 0x757602fb, 0xebf5d864, 0xa39db332, 0x3d1e69ad, - 0xde9c77d6, 0x401fad49, 0x18994a20, 0x861a90bf, 0x65988ec4, - 0xfb1b545b, 0xd5944117, 0x4b179b88, 0xa89585f3, 0x36165f6c, - 0x6e90b805, 0xf013629a, 0x13917ce1, 0x8d12a67e, 0x4f8f5779, - 0xd10c8de6, 0x328e939d, 0xac0d4902, 0xf48bae6b, 0x6a0874f4, - 0x898a6a8f, 0x1709b010, 0x3986a55c, 0xa7057fc3, 0x448761b8, - 0xda04bb27, 0x82825c4e, 0x1c0186d1, 0xff8398aa, 0x61004235, - 0x7bb87ba5, 0xe53ba13a, 0x06b9bf41, 0x983a65de, 0xc0bc82b7, - 0x5e3f5828, 0xbdbd4653, 0x233e9ccc, 0x0db18980, 0x9332531f, - 0x70b04d64, 0xee3397fb, 0xb6b57092, 0x2836aa0d, 0xcbb4b476, - 0x55376ee9, 0x97aa9fee, 0x09294571, 0xeaab5b0a, 0x74288195, - 0x2cae66fc, 0xb22dbc63, 0x51afa218, 0xcf2c7887, 0xe1a36dcb, - 0x7f20b754, 0x9ca2a92f, 0x022173b0, 0x5aa794d9, 0xc4244e46, - 0x27a6503d, 0xb9258aa2, 0x52d052c6, 0xcc538859, 0x2fd19622, - 0xb1524cbd, 0xe9d4abd4, 0x7757714b, 0x94d56f30, 0x0a56b5af, - 0x24d9a0e3, 0xba5a7a7c, 0x59d86407, 0xc75bbe98, 0x9fdd59f1, - 0x015e836e, 0xe2dc9d15, 0x7c5f478a, 0xbec2b68d, 0x20416c12, - 0xc3c37269, 0x5d40a8f6, 0x05c64f9f, 0x9b459500, 0x78c78b7b, - 0xe64451e4, 0xc8cb44a8, 0x56489e37, 0xb5ca804c, 0x2b495ad3, - 0x73cfbdba, 0xed4c6725, 0x0ece795e, 0x904da3c1, 0x8af59a51, - 0x147640ce, 0xf7f45eb5, 0x6977842a, 0x31f16343, 0xaf72b9dc, - 0x4cf0a7a7, 0xd2737d38, 0xfcfc6874, 0x627fb2eb, 0x81fdac90, - 0x1f7e760f, 0x47f89166, 0xd97b4bf9, 0x3af95582, 0xa47a8f1d, - 0x66e77e1a, 0xf864a485, 0x1be6bafe, 0x85656061, 0xdde38708, - 0x43605d97, 0xa0e243ec, 0x3e619973, 0x10ee8c3f, 0x8e6d56a0, - 0x6def48db, 0xf36c9244, 0xabea752d, 0x3569afb2, 0xd6ebb1c9, - 0x48686b56}, - {0x00000000, 0xc0642817, 0x80c9502e, 0x40ad7839, 0x0093a15c, - 0xc0f7894b, 0x805af172, 0x403ed965, 0x002643b9, 0xc0426bae, - 0x80ef1397, 0x408b3b80, 0x00b5e2e5, 0xc0d1caf2, 0x807cb2cb, - 0x40189adc, 0x414af7a9, 0x812edfbe, 0xc183a787, 0x01e78f90, - 0x41d956f5, 0x81bd7ee2, 0xc11006db, 0x01742ecc, 0x416cb410, - 0x81089c07, 0xc1a5e43e, 0x01c1cc29, 0x41ff154c, 0x819b3d5b, - 0xc1364562, 0x01526d75, 0xc3929f88, 0x03f6b79f, 0x435bcfa6, - 0x833fe7b1, 0xc3013ed4, 0x036516c3, 0x43c86efa, 0x83ac46ed, - 0xc3b4dc31, 0x03d0f426, 0x437d8c1f, 0x8319a408, 0xc3277d6d, - 0x0343557a, 0x43ee2d43, 0x838a0554, 0x82d86821, 0x42bc4036, - 0x0211380f, 0xc2751018, 0x824bc97d, 0x422fe16a, 0x02829953, - 0xc2e6b144, 0x82fe2b98, 0x429a038f, 0x02377bb6, 0xc25353a1, - 0x826d8ac4, 0x4209a2d3, 0x02a4daea, 0xc2c0f2fd, 0xc7234eca, - 0x074766dd, 0x47ea1ee4, 0x878e36f3, 0xc7b0ef96, 0x07d4c781, - 0x4779bfb8, 0x871d97af, 0xc7050d73, 0x07612564, 0x47cc5d5d, - 0x87a8754a, 0xc796ac2f, 0x07f28438, 0x475ffc01, 0x873bd416, - 0x8669b963, 0x460d9174, 0x06a0e94d, 0xc6c4c15a, 0x86fa183f, - 0x469e3028, 0x06334811, 0xc6576006, 0x864ffada, 0x462bd2cd, - 0x0686aaf4, 0xc6e282e3, 0x86dc5b86, 0x46b87391, 0x06150ba8, - 0xc67123bf, 0x04b1d142, 0xc4d5f955, 0x8478816c, 0x441ca97b, - 0x0422701e, 0xc4465809, 0x84eb2030, 0x448f0827, 0x049792fb, - 0xc4f3baec, 0x845ec2d5, 0x443aeac2, 0x040433a7, 0xc4601bb0, - 0x84cd6389, 0x44a94b9e, 0x45fb26eb, 0x859f0efc, 0xc53276c5, - 0x05565ed2, 0x456887b7, 0x850cafa0, 0xc5a1d799, 0x05c5ff8e, - 0x45dd6552, 0x85b94d45, 0xc514357c, 0x05701d6b, 0x454ec40e, - 0x852aec19, 0xc5879420, 0x05e3bc37, 0xcf41ed4f, 0x0f25c558, - 0x4f88bd61, 0x8fec9576, 0xcfd24c13, 0x0fb66404, 0x4f1b1c3d, - 0x8f7f342a, 0xcf67aef6, 0x0f0386e1, 0x4faefed8, 0x8fcad6cf, - 0xcff40faa, 0x0f9027bd, 0x4f3d5f84, 0x8f597793, 0x8e0b1ae6, - 0x4e6f32f1, 0x0ec24ac8, 0xcea662df, 0x8e98bbba, 0x4efc93ad, - 0x0e51eb94, 0xce35c383, 0x8e2d595f, 0x4e497148, 0x0ee40971, - 0xce802166, 0x8ebef803, 0x4edad014, 0x0e77a82d, 0xce13803a, - 0x0cd372c7, 0xccb75ad0, 0x8c1a22e9, 0x4c7e0afe, 0x0c40d39b, - 0xcc24fb8c, 0x8c8983b5, 0x4cedaba2, 0x0cf5317e, 0xcc911969, - 0x8c3c6150, 0x4c584947, 0x0c669022, 0xcc02b835, 0x8cafc00c, - 0x4ccbe81b, 0x4d99856e, 0x8dfdad79, 0xcd50d540, 0x0d34fd57, - 0x4d0a2432, 0x8d6e0c25, 0xcdc3741c, 0x0da75c0b, 0x4dbfc6d7, - 0x8ddbeec0, 0xcd7696f9, 0x0d12beee, 0x4d2c678b, 0x8d484f9c, - 0xcde537a5, 0x0d811fb2, 0x0862a385, 0xc8068b92, 0x88abf3ab, - 0x48cfdbbc, 0x08f102d9, 0xc8952ace, 0x883852f7, 0x485c7ae0, - 0x0844e03c, 0xc820c82b, 0x888db012, 0x48e99805, 0x08d74160, - 0xc8b36977, 0x881e114e, 0x487a3959, 0x4928542c, 0x894c7c3b, - 0xc9e10402, 0x09852c15, 0x49bbf570, 0x89dfdd67, 0xc972a55e, - 0x09168d49, 0x490e1795, 0x896a3f82, 0xc9c747bb, 0x09a36fac, - 0x499db6c9, 0x89f99ede, 0xc954e6e7, 0x0930cef0, 0xcbf03c0d, - 0x0b94141a, 0x4b396c23, 0x8b5d4434, 0xcb639d51, 0x0b07b546, - 0x4baacd7f, 0x8bcee568, 0xcbd67fb4, 0x0bb257a3, 0x4b1f2f9a, - 0x8b7b078d, 0xcb45dee8, 0x0b21f6ff, 0x4b8c8ec6, 0x8be8a6d1, - 0x8abacba4, 0x4adee3b3, 0x0a739b8a, 0xca17b39d, 0x8a296af8, - 0x4a4d42ef, 0x0ae03ad6, 0xca8412c1, 0x8a9c881d, 0x4af8a00a, - 0x0a55d833, 0xca31f024, 0x8a0f2941, 0x4a6b0156, 0x0ac6796f, - 0xcaa25178}, - {0x00000000, 0xd4ea739b, 0xe9d396ed, 0x3d39e576, 0x93a15c00, - 0x474b2f9b, 0x7a72caed, 0xae98b976, 0x2643b900, 0xf2a9ca9b, - 0xcf902fed, 0x1b7a5c76, 0xb5e2e500, 0x6108969b, 0x5c3173ed, - 0x88db0076, 0x4c867201, 0x986c019a, 0xa555e4ec, 0x71bf9777, - 0xdf272e01, 0x0bcd5d9a, 0x36f4b8ec, 0xe21ecb77, 0x6ac5cb01, - 0xbe2fb89a, 0x83165dec, 0x57fc2e77, 0xf9649701, 0x2d8ee49a, - 0x10b701ec, 0xc45d7277, 0x980ce502, 0x4ce69699, 0x71df73ef, - 0xa5350074, 0x0badb902, 0xdf47ca99, 0xe27e2fef, 0x36945c74, - 0xbe4f5c02, 0x6aa52f99, 0x579ccaef, 0x8376b974, 0x2dee0002, - 0xf9047399, 0xc43d96ef, 0x10d7e574, 0xd48a9703, 0x0060e498, - 0x3d5901ee, 0xe9b37275, 0x472bcb03, 0x93c1b898, 0xaef85dee, - 0x7a122e75, 0xf2c92e03, 0x26235d98, 0x1b1ab8ee, 0xcff0cb75, - 0x61687203, 0xb5820198, 0x88bbe4ee, 0x5c519775, 0x3019ca05, - 0xe4f3b99e, 0xd9ca5ce8, 0x0d202f73, 0xa3b89605, 0x7752e59e, - 0x4a6b00e8, 0x9e817373, 0x165a7305, 0xc2b0009e, 0xff89e5e8, - 0x2b639673, 0x85fb2f05, 0x51115c9e, 0x6c28b9e8, 0xb8c2ca73, - 0x7c9fb804, 0xa875cb9f, 0x954c2ee9, 0x41a65d72, 0xef3ee404, - 0x3bd4979f, 0x06ed72e9, 0xd2070172, 0x5adc0104, 0x8e36729f, - 0xb30f97e9, 0x67e5e472, 0xc97d5d04, 0x1d972e9f, 0x20aecbe9, - 0xf444b872, 0xa8152f07, 0x7cff5c9c, 0x41c6b9ea, 0x952cca71, - 0x3bb47307, 0xef5e009c, 0xd267e5ea, 0x068d9671, 0x8e569607, - 0x5abce59c, 0x678500ea, 0xb36f7371, 0x1df7ca07, 0xc91db99c, - 0xf4245cea, 0x20ce2f71, 0xe4935d06, 0x30792e9d, 0x0d40cbeb, - 0xd9aab870, 0x77320106, 0xa3d8729d, 0x9ee197eb, 0x4a0be470, - 0xc2d0e406, 0x163a979d, 0x2b0372eb, 0xffe90170, 0x5171b806, - 0x859bcb9d, 0xb8a22eeb, 0x6c485d70, 0x6032940b, 0xb4d8e790, - 0x89e102e6, 0x5d0b717d, 0xf393c80b, 0x2779bb90, 0x1a405ee6, - 0xceaa2d7d, 0x46712d0b, 0x929b5e90, 0xafa2bbe6, 0x7b48c87d, - 0xd5d0710b, 0x013a0290, 0x3c03e7e6, 0xe8e9947d, 0x2cb4e60a, - 0xf85e9591, 0xc56770e7, 0x118d037c, 0xbf15ba0a, 0x6bffc991, - 0x56c62ce7, 0x822c5f7c, 0x0af75f0a, 0xde1d2c91, 0xe324c9e7, - 0x37ceba7c, 0x9956030a, 0x4dbc7091, 0x708595e7, 0xa46fe67c, - 0xf83e7109, 0x2cd40292, 0x11ede7e4, 0xc507947f, 0x6b9f2d09, - 0xbf755e92, 0x824cbbe4, 0x56a6c87f, 0xde7dc809, 0x0a97bb92, - 0x37ae5ee4, 0xe3442d7f, 0x4ddc9409, 0x9936e792, 0xa40f02e4, - 0x70e5717f, 0xb4b80308, 0x60527093, 0x5d6b95e5, 0x8981e67e, - 0x27195f08, 0xf3f32c93, 0xcecac9e5, 0x1a20ba7e, 0x92fbba08, - 0x4611c993, 0x7b282ce5, 0xafc25f7e, 0x015ae608, 0xd5b09593, - 0xe88970e5, 0x3c63037e, 0x502b5e0e, 0x84c12d95, 0xb9f8c8e3, - 0x6d12bb78, 0xc38a020e, 0x17607195, 0x2a5994e3, 0xfeb3e778, - 0x7668e70e, 0xa2829495, 0x9fbb71e3, 0x4b510278, 0xe5c9bb0e, - 0x3123c895, 0x0c1a2de3, 0xd8f05e78, 0x1cad2c0f, 0xc8475f94, - 0xf57ebae2, 0x2194c979, 0x8f0c700f, 0x5be60394, 0x66dfe6e2, - 0xb2359579, 0x3aee950f, 0xee04e694, 0xd33d03e2, 0x07d77079, - 0xa94fc90f, 0x7da5ba94, 0x409c5fe2, 0x94762c79, 0xc827bb0c, - 0x1ccdc897, 0x21f42de1, 0xf51e5e7a, 0x5b86e70c, 0x8f6c9497, - 0xb25571e1, 0x66bf027a, 0xee64020c, 0x3a8e7197, 0x07b794e1, - 0xd35de77a, 0x7dc55e0c, 0xa92f2d97, 0x9416c8e1, 0x40fcbb7a, - 0x84a1c90d, 0x504bba96, 0x6d725fe0, 0xb9982c7b, 0x1700950d, - 0xc3eae696, 0xfed303e0, 0x2a39707b, 0xa2e2700d, 0x76080396, - 0x4b31e6e0, 0x9fdb957b, 0x31432c0d, 0xe5a95f96, 0xd890bae0, - 0x0c7ac97b}, - {0x00000000, 0x27652581, 0x0fcc3bd9, 0x28a91e58, 0x5f9e0669, - 0x78fb23e8, 0x50523db0, 0x77371831, 0xbe3c0dd2, 0x99592853, - 0xb1f0360b, 0x9695138a, 0xe1a20bbb, 0xc6c72e3a, 0xee6e3062, - 0xc90b15e3, 0x3d7f6b7f, 0x1a1a4efe, 0x32b350a6, 0x15d67527, - 0x62e16d16, 0x45844897, 0x6d2d56cf, 0x4a48734e, 0x834366ad, - 0xa426432c, 0x8c8f5d74, 0xabea78f5, 0xdcdd60c4, 0xfbb84545, - 0xd3115b1d, 0xf4747e9c, 0x7afed6fe, 0x5d9bf37f, 0x7532ed27, - 0x5257c8a6, 0x2560d097, 0x0205f516, 0x2aaceb4e, 0x0dc9cecf, - 0xc4c2db2c, 0xe3a7fead, 0xcb0ee0f5, 0xec6bc574, 0x9b5cdd45, - 0xbc39f8c4, 0x9490e69c, 0xb3f5c31d, 0x4781bd81, 0x60e49800, - 0x484d8658, 0x6f28a3d9, 0x181fbbe8, 0x3f7a9e69, 0x17d38031, - 0x30b6a5b0, 0xf9bdb053, 0xded895d2, 0xf6718b8a, 0xd114ae0b, - 0xa623b63a, 0x814693bb, 0xa9ef8de3, 0x8e8aa862, 0xb5fadc26, - 0x929ff9a7, 0xba36e7ff, 0x9d53c27e, 0xea64da4f, 0xcd01ffce, - 0xe5a8e196, 0xc2cdc417, 0x0bc6d1f4, 0x2ca3f475, 0x040aea2d, - 0x236fcfac, 0x5458d79d, 0x733df21c, 0x5b94ec44, 0x7cf1c9c5, - 0x8885b759, 0xafe092d8, 0x87498c80, 0xa02ca901, 0xd71bb130, - 0xf07e94b1, 0xd8d78ae9, 0xffb2af68, 0x36b9ba8b, 0x11dc9f0a, - 0x39758152, 0x1e10a4d3, 0x6927bce2, 0x4e429963, 0x66eb873b, - 0x418ea2ba, 0xcf040ad8, 0xe8612f59, 0xc0c83101, 0xe7ad1480, - 0x909a0cb1, 0xb7ff2930, 0x9f563768, 0xb83312e9, 0x7138070a, - 0x565d228b, 0x7ef43cd3, 0x59911952, 0x2ea60163, 0x09c324e2, - 0x216a3aba, 0x060f1f3b, 0xf27b61a7, 0xd51e4426, 0xfdb75a7e, - 0xdad27fff, 0xade567ce, 0x8a80424f, 0xa2295c17, 0x854c7996, - 0x4c476c75, 0x6b2249f4, 0x438b57ac, 0x64ee722d, 0x13d96a1c, - 0x34bc4f9d, 0x1c1551c5, 0x3b707444, 0x6af5b94d, 0x4d909ccc, - 0x65398294, 0x425ca715, 0x356bbf24, 0x120e9aa5, 0x3aa784fd, - 0x1dc2a17c, 0xd4c9b49f, 0xf3ac911e, 0xdb058f46, 0xfc60aac7, - 0x8b57b2f6, 0xac329777, 0x849b892f, 0xa3feacae, 0x578ad232, - 0x70eff7b3, 0x5846e9eb, 0x7f23cc6a, 0x0814d45b, 0x2f71f1da, - 0x07d8ef82, 0x20bdca03, 0xe9b6dfe0, 0xced3fa61, 0xe67ae439, - 0xc11fc1b8, 0xb628d989, 0x914dfc08, 0xb9e4e250, 0x9e81c7d1, - 0x100b6fb3, 0x376e4a32, 0x1fc7546a, 0x38a271eb, 0x4f9569da, - 0x68f04c5b, 0x40595203, 0x673c7782, 0xae376261, 0x895247e0, - 0xa1fb59b8, 0x869e7c39, 0xf1a96408, 0xd6cc4189, 0xfe655fd1, - 0xd9007a50, 0x2d7404cc, 0x0a11214d, 0x22b83f15, 0x05dd1a94, - 0x72ea02a5, 0x558f2724, 0x7d26397c, 0x5a431cfd, 0x9348091e, - 0xb42d2c9f, 0x9c8432c7, 0xbbe11746, 0xccd60f77, 0xebb32af6, - 0xc31a34ae, 0xe47f112f, 0xdf0f656b, 0xf86a40ea, 0xd0c35eb2, - 0xf7a67b33, 0x80916302, 0xa7f44683, 0x8f5d58db, 0xa8387d5a, - 0x613368b9, 0x46564d38, 0x6eff5360, 0x499a76e1, 0x3ead6ed0, - 0x19c84b51, 0x31615509, 0x16047088, 0xe2700e14, 0xc5152b95, - 0xedbc35cd, 0xcad9104c, 0xbdee087d, 0x9a8b2dfc, 0xb22233a4, - 0x95471625, 0x5c4c03c6, 0x7b292647, 0x5380381f, 0x74e51d9e, - 0x03d205af, 0x24b7202e, 0x0c1e3e76, 0x2b7b1bf7, 0xa5f1b395, - 0x82949614, 0xaa3d884c, 0x8d58adcd, 0xfa6fb5fc, 0xdd0a907d, - 0xf5a38e25, 0xd2c6aba4, 0x1bcdbe47, 0x3ca89bc6, 0x1401859e, - 0x3364a01f, 0x4453b82e, 0x63369daf, 0x4b9f83f7, 0x6cfaa676, - 0x988ed8ea, 0xbfebfd6b, 0x9742e333, 0xb027c6b2, 0xc710de83, - 0xe075fb02, 0xc8dce55a, 0xefb9c0db, 0x26b2d538, 0x01d7f0b9, - 0x297eeee1, 0x0e1bcb60, 0x792cd351, 0x5e49f6d0, 0x76e0e888, - 0x5185cd09}}; - -#endif - -#endif - -#endif - -local const z_crc_t FAR x2n_table[] = { - 0x40000000, 0x20000000, 0x08000000, 0x00800000, 0x00008000, - 0xedb88320, 0xb1e6b092, 0xa06a2517, 0xed627dae, 0x88d14467, - 0xd7bbfe6a, 0xec447f11, 0x8e7ea170, 0x6427800e, 0x4d47bae0, - 0x09fe548f, 0x83852d0f, 0x30362f1a, 0x7b5a9cc3, 0x31fec169, - 0x9fec022a, 0x6c8dedc4, 0x15d6874d, 0x5fde7a4e, 0xbad90e37, - 0x2e4e5eef, 0x4eaba214, 0xa8a472c0, 0x429a969e, 0x148d302a, - 0xc40ba6d0, 0xc4e22c3c}; diff --git a/thirdparty/freetype/src/gzip/gzguts.h b/thirdparty/freetype/src/gzip/gzguts.h deleted file mode 100644 index 4f09a52a7a..0000000000 --- a/thirdparty/freetype/src/gzip/gzguts.h +++ /dev/null @@ -1,219 +0,0 @@ -/* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004-2019 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#ifdef _LARGEFILE64_SOURCE -# ifndef _LARGEFILE_SOURCE -# define _LARGEFILE_SOURCE 1 -# endif -# ifdef _FILE_OFFSET_BITS -# undef _FILE_OFFSET_BITS -# endif -#endif - -#ifdef HAVE_HIDDEN -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#include <stdio.h> -#include "zlib.h" -#ifdef STDC -# include <string.h> -# include <stdlib.h> -# include <limits.h> -#endif - -#ifndef _POSIX_SOURCE -# define _POSIX_SOURCE -#endif -#include <fcntl.h> - -#ifdef _WIN32 -# include <stddef.h> -#endif - -#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) -# include <io.h> -#endif - -#if defined(_WIN32) -# define WIDECHAR -#endif - -#ifdef WINAPI_FAMILY -# define open _open -# define read _read -# define write _write -# define close _close -#endif - -#ifdef NO_DEFLATE /* for compatibility with old definition */ -# define NO_GZCOMPRESS -#endif - -#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#if defined(__CYGWIN__) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#ifndef HAVE_VSNPRINTF -# ifdef MSDOS -/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), - but for now we just assume it doesn't. */ -# define NO_vsnprintf -# endif -# ifdef __TURBOC__ -# define NO_vsnprintf -# endif -# ifdef WIN32 -/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ -# if !defined(vsnprintf) && !defined(NO_vsnprintf) -# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) -# define vsnprintf _vsnprintf -# endif -# endif -# endif -# ifdef __SASC -# define NO_vsnprintf -# endif -# ifdef VMS -# define NO_vsnprintf -# endif -# ifdef __OS400__ -# define NO_vsnprintf -# endif -# ifdef __MVS__ -# define NO_vsnprintf -# endif -#endif - -/* unlike snprintf (which is required in C99), _snprintf does not guarantee - null termination of the result -- however this is only used in gzlib.c where - the result is assured to fit in the space provided */ -#if defined(_MSC_VER) && _MSC_VER < 1900 -# define snprintf _snprintf -#endif - -#ifndef local -# define local static -#endif -/* since "static" is used to mean two completely different things in C, we - define "local" for the non-static meaning of "static", for readability - (compile with -Dlocal if your debugger can't find static symbols) */ - -/* gz* functions always use library allocation functions */ -#ifndef STDC - extern voidp malloc OF((uInt size)); - extern void free OF((voidpf ptr)); -#endif - -/* get errno and strerror definition */ -#if defined UNDER_CE -# include <windows.h> -# define zstrerror() gz_strwinerror((DWORD)GetLastError()) -#else -# ifndef NO_STRERROR -# include <errno.h> -# define zstrerror() strerror(errno) -# else -# define zstrerror() "stdio error (consult errno)" -# endif -#endif - -/* provide prototypes for these when building zlib without LFS */ -#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); -#endif - -/* default memLevel */ -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif - -/* default i/o buffer size -- double this for output when reading (this and - twice this must be able to fit in an unsigned type) */ -#define GZBUFSIZE 8192 - -/* gzip modes, also provide a little integrity check on the passed structure */ -#define GZ_NONE 0 -#define GZ_READ 7247 -#define GZ_WRITE 31153 -#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ - -/* values for gz_state how */ -#define LOOK 0 /* look for a gzip header */ -#define COPY__ 1 /* copy input directly */ -#define GZIP 2 /* decompress a gzip stream */ - -/* internal gzip file state data structure */ -typedef struct { - /* exposed contents for gzgetc() macro */ - struct gzFile_s x; /* "x" for exposed */ - /* x.have: number of bytes available at x.next */ - /* x.next: next output data to deliver or write */ - /* x.pos: current position in uncompressed data */ - /* used for both reading and writing */ - int mode; /* see gzip modes above */ - int fd; /* file descriptor */ - char *path; /* path or fd for error messages */ - unsigned size; /* buffer size, zero if not allocated yet */ - unsigned want; /* requested buffer size, default is GZBUFSIZE */ - unsigned char *in; /* input buffer (double-sized when writing) */ - unsigned char *out; /* output buffer (double-sized when reading) */ - int direct; /* 0 if processing gzip, 1 if transparent */ - /* just for reading */ - int how; /* 0: get header, 1: copy, 2: decompress */ - z_off64_t start; /* where the gzip data started, for rewinding */ - int eof; /* true if end of input file reached */ - int past; /* true if read requested past end */ - /* just for writing */ - int level; /* compression level */ - int strategy; /* compression strategy */ - int reset; /* true if a reset is pending after a Z_FINISH */ - /* seek request */ - z_off64_t skip; /* amount to skip (already rewound if backwards) */ - int seek; /* true if seek request pending */ - /* error information */ - int err; /* error code */ - char *msg; /* error message */ - /* zlib inflate or deflate stream */ - z_stream strm; /* stream structure in-place (not a pointer) */ -} gz_state; -typedef gz_state FAR *gz_statep; - -/* shared functions */ -void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); -#if defined UNDER_CE -char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); -#endif - -/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t - value -- needed when comparing unsigned to z_off64_t, which is signed - (possible z_off64_t types off_t, off64_t, and long are all signed) */ -#ifdef INT_MAX -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) -#else -unsigned ZLIB_INTERNAL gz_intmax OF((void)); -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) -#endif diff --git a/thirdparty/freetype/src/gzip/infback.c b/thirdparty/freetype/src/gzip/infback.c deleted file mode 100644 index 5fb8c67941..0000000000 --- a/thirdparty/freetype/src/gzip/infback.c +++ /dev/null @@ -1,641 +0,0 @@ -/* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2022 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - This code is largely copied from inflate.c. Normally either infback.o or - inflate.o would be linked into an application--not both. The interface - with inffast.c is retained so that optimized assembler-coded versions of - inflate_fast() can be used with either inflate.c or infback.c. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); - -/* - strm provides memory allocation functions in zalloc and zfree, or - Z_NULL to use the library memory allocation functions. - - windowBits is in the range 8..15, and window is a user-supplied - window and output buffer that is 2**windowBits bytes. - */ -int ZEXPORT inflateBackInit_( - z_streamp strm, - int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size) -{ - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL || window == Z_NULL || - windowBits < 8 || windowBits > 15) - return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *)ZALLOC(strm, 1, - sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->dmax = 32768U; - state->wbits = (uInt)windowBits; - state->wsize = 1U << windowBits; - state->window = window; - state->wnext = 0; - state->whave = 0; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables( - struct inflate_state FAR *state) -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -/* Macros for inflateBack(): */ - -/* Load returned state from inflate_fast() */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Set state from registers for inflate_fast() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Assure that some input is available. If input is requested, but denied, - then return a Z_BUF_ERROR from inflateBack(). */ -#define PULL() \ - do { \ - if (have == 0) { \ - have = in(in_desc, &next); \ - if (have == 0) { \ - next = Z_NULL; \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflateBack() - with an error if there is no input available. */ -#define PULLBYTE() \ - do { \ - PULL(); \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflateBack() with - an error. */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Assure that some output space is available, by writing out the window - if it's full. If the write fails, return from inflateBack() with a - Z_BUF_ERROR. */ -#define ROOM() \ - do { \ - if (left == 0) { \ - put = state->window; \ - left = state->wsize; \ - state->whave = left; \ - if (out(out_desc, put, left)) { \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* - strm provides the memory allocation functions and window buffer on input, - and provides information on the unused input on return. For Z_DATA_ERROR - returns, strm will also provide an error message. - - in() and out() are the call-back input and output functions. When - inflateBack() needs more input, it calls in(). When inflateBack() has - filled the window with output, or when it completes with data in the - window, it calls out() to write out the data. The application must not - change the provided input until in() is called again or inflateBack() - returns. The application must not change the window/output buffer until - inflateBack() returns. - - in() and out() are called with a descriptor parameter provided in the - inflateBack() call. This parameter can be a structure that provides the - information required to do the read or write, as well as accumulated - information on the input and output such as totals and check values. - - in() should return zero on failure. out() should return non-zero on - failure. If either in() or out() fails, than inflateBack() returns a - Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it - was in() or out() that caused in the error. Otherwise, inflateBack() - returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format - error, or Z_MEM_ERROR if it could not allocate memory for the state. - inflateBack() can also return Z_STREAM_ERROR if the input parameters - are not correct, i.e. strm is Z_NULL or the state was not initialized. - */ -int ZEXPORT inflateBack( - z_streamp strm, - in_func in, - void FAR *in_desc, - out_func out, - void FAR *out_desc) -{ - struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - /* Check that the strm exists and that the state was initialized */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* Reset the state */ - strm->msg = Z_NULL; - state->mode = TYPE; - state->last = 0; - state->whave = 0; - next = strm->next_in; - have = next != Z_NULL ? strm->avail_in : 0; - hold = 0; - bits = 0; - put = state->window; - left = state->wsize; - - /* Inflate until end of block marked as last */ - for (;;) - switch (state->mode) { - case TYPE: - /* determine and dispatch block type */ - if (state->last) { - BYTEBITS(); - state->mode = DONE; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - - case STORED: - /* get and verify stored block length */ - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - - /* copy stored block from input to output */ - while (state->length != 0) { - copy = state->length; - PULL(); - ROOM(); - if (copy > have) copy = have; - if (copy > left) copy = left; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - - case TABLE: - /* get dynamic table entries descriptor */ - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - - /* get code length code lengths (not a typo) */ - state->have = 0; - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - - /* get length and distance code code lengths */ - state->have = 0; - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = (unsigned)(state->lens[state->have - 1]); - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - /* fallthrough */ - - case LEN: - /* use inflate_fast() if we have enough input and output */ - if (have >= 6 && left >= 258) { - RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; - inflate_fast(strm, state->wsize); - LOAD(); - break; - } - - /* get a literal, length, or end-of-block code */ - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - state->length = (unsigned)here.val; - - /* process literal */ - if (here.op == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - ROOM(); - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - } - - /* process end of block */ - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - - /* invalid code */ - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - - /* length code -- get extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - - /* get distance code */ - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - - /* get distance extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } - if (state->offset > state->wsize - (state->whave < state->wsize ? - left : 0)) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - - /* copy match from window to output */ - do { - ROOM(); - copy = state->wsize - state->offset; - if (copy < left) { - from = put + copy; - copy = left - copy; - } - else { - from = put - state->offset; - copy = left; - } - if (copy > state->length) copy = state->length; - state->length -= copy; - left -= copy; - do { - *put++ = *from++; - } while (--copy); - } while (state->length != 0); - break; - - case DONE: - /* inflate stream terminated properly -- write leftover output */ - ret = Z_STREAM_END; - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left)) - ret = Z_BUF_ERROR; - } - goto inf_leave; - - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - - default: /* can't happen, but makes compilers happy */ - ret = Z_STREAM_ERROR; - goto inf_leave; - } - - /* Return unused input */ - inf_leave: - strm->next_in = next; - strm->avail_in = have; - return ret; -} - -int ZEXPORT inflateBackEnd( - z_streamp strm) -{ - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} diff --git a/thirdparty/freetype/src/gzip/inffast.c b/thirdparty/freetype/src/gzip/inffast.c deleted file mode 100644 index 809737b13c..0000000000 --- a/thirdparty/freetype/src/gzip/inffast.c +++ /dev/null @@ -1,323 +0,0 @@ -/* inffast.c -- fast decoding - * Copyright (C) 1995-2017 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef ASMINF -# pragma message("Assembler code may have bugs -- use at your own risk") -#else - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state->mode == LEN - strm->avail_in >= 6 - strm->avail_out >= 258 - start >= strm->avail_out - state->bits < 8 - - On return, state->mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm->avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm->avail_out >= 258 for each loop to avoid checking for - output space. - */ -void ZLIB_INTERNAL inflate_fast( - z_streamp strm, - unsigned start) -{ - struct inflate_state FAR *state; - z_const unsigned char FAR *in; /* local strm->next_in */ - z_const unsigned char FAR *last; /* have enough input while in < last */ - unsigned char FAR *out; /* local strm->next_out */ - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ - unsigned char FAR *end; /* while out < end, enough space available */ -#ifdef INFLATE_STRICT - unsigned dmax; /* maximum distance from zlib header */ -#endif - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ - unsigned long hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const FAR *lcode; /* local strm->lencode */ - code const FAR *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code const *here; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char FAR *from; /* where to copy match from */ - - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; - in = strm->next_in; - last = in + (strm->avail_in - 5); - out = strm->next_out; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); -#ifdef INFLATE_STRICT - dmax = state->dmax; -#endif - wsize = state->wsize; - whave = state->whave; - wnext = state->wnext; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - do { - if (bits < 15) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - here = lcode + (hold & lmask); - dolen: - op = (unsigned)(here->bits); - hold >>= op; - bits -= op; - op = (unsigned)(here->op); - if (op == 0) { /* literal */ - Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here->val)); - *out++ = (unsigned char)(here->val); - } - else if (op & 16) { /* length base */ - len = (unsigned)(here->val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - here = dcode + (hold & dmask); - dodist: - op = (unsigned)(here->bits); - hold >>= op; - bits -= op; - op = (unsigned)(here->op); - if (op & 16) { /* distance base */ - dist = (unsigned)(here->val); - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - } - dist += (unsigned)hold & ((1U << op) - 1); -#ifdef INFLATE_STRICT - if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - hold >>= op; - bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state->sane) { - strm->msg = - (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - if (len <= op - whave) { - do { - *out++ = 0; - } while (--len); - continue; - } - len -= op - whave; - do { - *out++ = 0; - } while (--op > whave); - if (op == 0) { - from = out - dist; - do { - *out++ = *from++; - } while (--len); - continue; - } -#endif - } - from = window; - if (wnext == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = window; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; - len -= 3; - } - if (len) { - *out++ = *from++; - if (len > 1) - *out++ = *from++; - } - } - else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; - len -= 3; - } while (len > 2); - if (len) { - *out++ = *from++; - if (len > 1) - *out++ = *from++; - } - } - } - else if ((op & 64) == 0) { /* 2nd level distance code */ - here = dcode + here->val + (hold & ((1U << op) - 1)); - goto dodist; - } - else { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - } - else if ((op & 64) == 0) { /* 2nd level length code */ - here = lcode + here->val + (hold & ((1U << op) - 1)); - goto dolen; - } - else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - else { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; - - /* update state and return */ - strm->next_in = in; - strm->next_out = out; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; -} - -/* - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - - Using bit fields for code structure - - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and wnext == 0 - - Special case for distance > 1 copies to do overlapped load and store copy - - Explicit branch predictions (based on measured branch probabilities) - - Deferring match copy and interspersed it with decoding subsequent codes - - Swapping literal/length else - - Swapping window/direct else - - Larger unrolled copy loops (three is about right) - - Moving len -= 3 statement into middle of loop - */ - -#endif /* !ASMINF */ diff --git a/thirdparty/freetype/src/gzip/inffast.h b/thirdparty/freetype/src/gzip/inffast.h deleted file mode 100644 index e5c1aa4ca8..0000000000 --- a/thirdparty/freetype/src/gzip/inffast.h +++ /dev/null @@ -1,11 +0,0 @@ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/thirdparty/freetype/src/gzip/inffixed.h b/thirdparty/freetype/src/gzip/inffixed.h deleted file mode 100644 index d628327769..0000000000 --- a/thirdparty/freetype/src/gzip/inffixed.h +++ /dev/null @@ -1,94 +0,0 @@ - /* inffixed.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ - - /* WARNING: this file should *not* be used by applications. - It is part of the implementation of this library and is - subject to change. Applications should only use zlib.h. - */ - - static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} - }; - - static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} - }; diff --git a/thirdparty/freetype/src/gzip/inflate.c b/thirdparty/freetype/src/gzip/inflate.c deleted file mode 100644 index 5bf5b815e5..0000000000 --- a/thirdparty/freetype/src/gzip/inflate.c +++ /dev/null @@ -1,1610 +0,0 @@ -/* inflate.c -- zlib decompression - * Copyright (C) 1995-2022 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * Change history: - * - * 1.2.beta0 24 Nov 2002 - * - First version -- complete rewrite of inflate to simplify code, avoid - * creation of window when not needed, minimize use of window when it is - * needed, make inffast.c even faster, implement gzip decoding, and to - * improve code readability and style over the previous zlib inflate code - * - * 1.2.beta1 25 Nov 2002 - * - Use pointers for available input and output checking in inffast.c - * - Remove input and output counters in inffast.c - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 - * - Remove unnecessary second byte pull from length extra in inffast.c - * - Unroll direct copy to three copies per loop in inffast.c - * - * 1.2.beta2 4 Dec 2002 - * - Change external routine names to reduce potential conflicts - * - Correct filename to inffixed.h for fixed tables in inflate.c - * - Make hbuf[] unsigned char to match parameter type in inflate.c - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) - * to avoid negation problem on Alphas (64 bit) in inflate.c - * - * 1.2.beta3 22 Dec 2002 - * - Add comments on state->bits assertion in inffast.c - * - Add comments on op field in inftrees.h - * - Fix bug in reuse of allocated window after inflateReset() - * - Remove bit fields--back to byte structure for speed - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths - * - Change post-increments to pre-increments in inflate_fast(), PPC biased? - * - Add compile time option, POSTINC, to use post-increments instead (Intel?) - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used - * - Use local copies of stream next and avail values, as well as local bit - * buffer and bit count in inflate()--for speed when inflate_fast() not used - * - * 1.2.beta4 1 Jan 2003 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings - * - Move a comment on output buffer sizes from inffast.c to inflate.c - * - Add comments in inffast.c to introduce the inflate_fast() routine - * - Rearrange window copies in inflate_fast() for speed and simplification - * - Unroll last copy for window match in inflate_fast() - * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common wnext == 0 case for speed in inflate_fast() - * - Make op and len in inflate_fast() unsigned for consistency - * - Add FAR to lcode and dcode declarations in inflate_fast() - * - Simplified bad distance check in inflate_fast() - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new - * source file infback.c to provide a call-back interface to inflate for - * programs like gzip and unzip -- uses window as output buffer to avoid - * window copying - * - * 1.2.beta5 1 Jan 2003 - * - Improved inflateBack() interface to allow the caller to provide initial - * input in strm. - * - Fixed stored blocks bug in inflateBack() - * - * 1.2.beta6 4 Jan 2003 - * - Added comments in inffast.c on effectiveness of POSTINC - * - Typecasting all around to reduce compiler warnings - * - Changed loops from while (1) or do {} while (1) to for (;;), again to - * make compilers happy - * - Changed type of window in inflateBackInit() to unsigned char * - * - * 1.2.beta7 27 Jan 2003 - * - Changed many types to unsigned or unsigned short to avoid warnings - * - Added inflateCopy() function - * - * 1.2.0 9 Mar 2003 - * - Changed inflateBack() interface to provide separate opaque descriptors - * for the in() and out() functions - * - Changed inflateBack() argument and in_func typedef to swap the length - * and buffer address return values for the input function - * - Check next_in and next_out for Z_NULL on entry to inflate() - * - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif - -/* function prototypes */ -local int inflateStateCheck OF((z_streamp strm)); -local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, - unsigned copy)); -#ifdef BUILDFIXED - void makefixed OF((void)); -#endif -#ifndef Z_FREETYPE -local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, - unsigned len)); -#endif - -local int inflateStateCheck( - z_streamp strm) -{ - struct inflate_state FAR *state; - if (strm == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) - return 1; - state = (struct inflate_state FAR *)strm->state; - if (state == Z_NULL || state->strm != strm || - state->mode < HEAD || state->mode > SYNC) - return 1; - return 0; -} - -int ZEXPORT inflateResetKeep( - z_streamp strm) -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - if (state->wrap) /* to support ill-conceived Java test suite */ - strm->adler = state->wrap & 1; - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->flags = -1; - state->dmax = 32768U; - state->head = Z_NULL; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - state->sane = 1; - state->back = -1; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -int ZEXPORT inflateReset( - z_streamp strm) -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - state->wsize = 0; - state->whave = 0; - state->wnext = 0; - return inflateResetKeep(strm); -} - -int ZEXPORT inflateReset2( - z_streamp strm, - int windowBits) -{ - int wrap; - struct inflate_state FAR *state; - - /* get the state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 5; -#ifdef GUNZIP - if (windowBits < 48) - windowBits &= 15; -#endif - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) - return Z_STREAM_ERROR; - if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { - ZFREE(strm, state->window); - state->window = Z_NULL; - } - - /* update state and reset the rest of it */ - state->wrap = wrap; - state->wbits = (unsigned)windowBits; - return inflateReset(strm); -} - -int ZEXPORT inflateInit2_( - z_streamp strm, - int windowBits, - const char *version, - int stream_size) -{ - int ret; - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *) - ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->strm = strm; - state->window = Z_NULL; - state->mode = HEAD; /* to pass state test in inflateReset2() */ - ret = inflateReset2(strm, windowBits); - if (ret != Z_OK) { - ZFREE(strm, state); - strm->state = Z_NULL; - } - return ret; -} - -int ZEXPORT inflateInit_( - z_streamp strm, - const char *version, - int stream_size) -{ - return inflateInit2_(strm, DEF_WBITS, version, stream_size); -} - -#ifndef Z_FREETYPE - -int ZEXPORT inflatePrime( - z_streamp strm, - int bits, - int value) -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (bits < 0) { - state->hold = 0; - state->bits = 0; - return Z_OK; - } - if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += (unsigned)value << state->bits; - state->bits += (uInt)bits; - return Z_OK; -} - -#endif /* !Z_FREETYPE */ - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables( - struct inflate_state FAR *state) -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include <stdio.h> - -/* - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes - those tables to stdout, which would be piped to inffixed.h. A small program - can simply call makefixed to do this: - - void makefixed(void); - - int main(void) - { - makefixed(); - return 0; - } - - Then that can be linked with zlib built with MAKEFIXED defined and run: - - a.out > inffixed.h - */ -void makefixed() -{ - unsigned low, size; - struct inflate_state state; - - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, - state.lencode[low].bits, state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); -} -#endif /* MAKEFIXED */ - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -local int updatewindow( - z_streamp strm, - const Bytef *end, - unsigned copy) -{ - struct inflate_state FAR *state; - unsigned dist; - - state = (struct inflate_state FAR *)strm->state; - - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char FAR *) - ZALLOC(strm, 1U << state->wbits, - sizeof(unsigned char)); - if (state->window == Z_NULL) return 1; - } - - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->wnext = 0; - state->whave = 0; - } - - /* copy state->wsize or less output bytes into the circular window */ - if (copy >= state->wsize) { - zmemcpy(state->window, end - state->wsize, state->wsize); - state->wnext = 0; - state->whave = state->wsize; - } - else { - dist = state->wsize - state->wnext; - if (dist > copy) dist = copy; - zmemcpy(state->window + state->wnext, end - copy, dist); - copy -= dist; - if (copy) { - zmemcpy(state->window, end - copy, copy); - state->wnext = copy; - state->whave = state->wsize; - } - else { - state->wnext += dist; - if (state->wnext == state->wsize) state->wnext = 0; - if (state->whave < state->wsize) state->whave += dist; - } - } - return 0; -} - -/* Macros for inflate(): */ - -/* check function to use adler32() for zlib or crc32() for gzip */ -#ifdef GUNZIP -# define UPDATE_CHECK(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) -#else -# define UPDATE_CHECK(check, buf, len) adler32(check, buf, len) -#endif - -/* check macros for header crc */ -#ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) - -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) -#endif - -/* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflate() - if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* - inflate() uses a state machine to process as much input data and generate as - much output data as possible before returning. The state machine is - structured roughly as follows: - - for (;;) switch (state) { - ... - case STATEn: - if (not enough input data or output space to make progress) - return; - ... make progress ... - state = STATEm; - break; - ... - } - - so when inflate() is called again, the same case is attempted again, and - if the appropriate resources are provided, the machine proceeds to the - next state. The NEEDBITS() macro is usually the way the state evaluates - whether it can proceed or should return. NEEDBITS() does the return if - the requested bits are not available. The typical use of the BITS macros - is: - - NEEDBITS(n); - ... do something with BITS(n) ... - DROPBITS(n); - - where NEEDBITS(n) either returns from inflate() if there isn't enough - input left to load n bits into the accumulator, or it continues. BITS(n) - gives the low n bits in the accumulator. When done, DROPBITS(n) drops - the low n bits off the accumulator. INITBITS() clears the accumulator - and sets the number of available bits to zero. BYTEBITS() discards just - enough bits to put the accumulator on a byte boundary. After BYTEBITS() - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. - - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return - if there is no input available. The decoding of variable length codes uses - PULLBYTE() directly in order to pull just enough bytes to decode the next - code, and no more. - - Some states loop until they get enough input, making sure that enough - state information is maintained to continue the loop where it left off - if NEEDBITS() returns in the loop. For example, want, need, and keep - would all have to actually be part of the saved state in case NEEDBITS() - returns: - - case STATEw: - while (want < need) { - NEEDBITS(n); - keep[want++] = BITS(n); - DROPBITS(n); - } - state = STATEx; - case STATEx: - - As shown above, if the next state is also the next case, then the break - is omitted. - - A state may also return if there is not enough output space available to - complete that state. Those states are copying stored data, writing a - literal byte, and copying a matching string. - - When returning, a "goto inf_leave" is used to update the total counters, - update the check value, and determine whether any progress has been made - during that inflate() call in order to return the proper return code. - Progress is defined as a change in either strm->avail_in or strm->avail_out. - When there is a window, goto inf_leave will update the window with the last - output written. If a goto inf_leave occurs in the middle of decompression - and there is no window currently, goto inf_leave will create one and copy - output to the window for the next call of inflate(). - - In this implementation, the flush parameter of inflate() only affects the - return code (per zlib.h). inflate() always writes as much as possible to - strm->next_out, given the space available and the provided input--the effect - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers - the allocation of and copying into a sliding window until necessary, which - provides the effect documented in zlib.h for Z_FINISH when the entire input - stream available. So the only thing the flush parameter actually does is: - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it - will return Z_BUF_ERROR if it has not reached the end of the stream. - */ - -int ZEXPORT inflate( - z_streamp strm, - int flush) -{ - struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ -#ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ -#endif - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - if (inflateStateCheck(strm) || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; - - state = (struct inflate_state FAR *)strm->state; - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); -#ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - if (state->wbits == 0) - state->wbits = 15; - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); - INITBITS(); - state->mode = FLAGS; - break; - } - if (state->head != Z_NULL) - state->head->done = -1; - if (!(state->wrap & 1) || /* check if zlib header allowed */ -#else - if ( -#endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - len = BITS(4) + 8; - if (state->wbits == 0) - state->wbits = len; - if (len > 15 || len > state->wbits) { - strm->msg = (char *)"invalid window size"; - state->mode = BAD; - break; - } - state->dmax = 1U << len; - state->flags = 0; /* indicate zlib header */ - Tracev((stderr, "inflate: zlib header ok\n")); - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; -#ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->head != Z_NULL) - state->head->text = (int)((hold >> 8) & 1); - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - state->mode = TIME; - /* fallthrough */ - case TIME: - NEEDBITS(32); - if (state->head != Z_NULL) - state->head->time = hold; - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC4(state->check, hold); - INITBITS(); - state->mode = OS; - /* fallthrough */ - case OS: - NEEDBITS(16); - if (state->head != Z_NULL) { - state->head->xflags = (int)(hold & 0xff); - state->head->os = (int)(hold >> 8); - } - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - state->mode = EXLEN; - /* fallthrough */ - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (unsigned)(hold); - if (state->head != Z_NULL) - state->head->extra_len = (unsigned)hold; - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - } - else if (state->head != Z_NULL) - state->head->extra = Z_NULL; - state->mode = EXTRA; - /* fallthrough */ - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) copy = have; - if (copy) { - if (state->head != Z_NULL && - state->head->extra != Z_NULL) { - len = state->head->extra_len - state->length; - zmemcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); - } - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) goto inf_leave; - } - state->length = 0; - state->mode = NAME; - /* fallthrough */ - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->name != Z_NULL && - state->length < state->head->name_max) - state->head->name[state->length++] = (Bytef)len; - } while (len && copy < have); - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->name = Z_NULL; - state->length = 0; - state->mode = COMMENT; - /* fallthrough */ - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->comment != Z_NULL && - state->length < state->head->comm_max) - state->head->comment[state->length++] = (Bytef)len; - } while (len && copy < have); - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->comment = Z_NULL; - state->mode = HCRC; - /* fallthrough */ - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); - if ((state->wrap & 4) && hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; - state->mode = BAD; - break; - } - INITBITS(); - } - if (state->head != Z_NULL) { - state->head->hcrc = (int)((state->flags >> 9) & 1); - state->head->done = 1; - } - strm->adler = state->check = crc32(0L, Z_NULL, 0); - state->mode = TYPE; - break; -#endif - case DICTID: - NEEDBITS(32); - strm->adler = state->check = ZSWAP32(hold); - INITBITS(); - state->mode = DICT; - /* fallthrough */ - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = TYPE; - /* fallthrough */ - case TYPE: - if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; - /* fallthrough */ - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN_; /* decode codes */ - if (flush == Z_TREES) { - DROPBITS(2); - goto inf_leave; - } - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - state->mode = COPY_; - if (flush == Z_TREES) goto inf_leave; - /* fallthrough */ - case COPY_: - state->mode = COPY; - /* fallthrough */ - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - /* fallthrough */ - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (const code FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - /* fallthrough */ - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (const code FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (const code FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN_; - if (flush == Z_TREES) goto inf_leave; - /* fallthrough */ - case LEN_: - state->mode = LEN; - /* fallthrough */ - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - if (state->mode == TYPE) - state->back = -1; - break; - } - state->back = 0; - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - state->length = (unsigned)here.val; - if ((int)(here.op) == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - state->mode = LIT; - break; - } - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->back = -1; - state->mode = TYPE; - break; - } - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (unsigned)(here.op) & 15; - state->mode = LENEXT; - /* fallthrough */ - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->was = state->length; - state->mode = DIST; - /* fallthrough */ - case DIST: - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - state->extra = (unsigned)(here.op) & 15; - state->mode = DISTEXT; - /* fallthrough */ - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } -#ifdef INFLATE_STRICT - if (state->offset > state->dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - /* fallthrough */ - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->whave) { - if (state->sane) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - Trace((stderr, "inflate.c too far\n")); - copy -= state->whave; - if (copy > state->length) copy = state->length; - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = 0; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; -#endif - } - if (copy > state->wnext) { - copy -= state->wnext; - from = state->window + (state->wsize - copy); - } - else - from = state->window + (state->wnext - copy); - if (copy > state->length) copy = state->length; - } - else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; - case LIT: - if (left == 0) goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; - if ((state->wrap & 4) && out) - strm->adler = state->check = - UPDATE_CHECK(state->check, put - out, out); - out = left; - if ((state->wrap & 4) && ( -#ifdef GUNZIP - state->flags ? hold : -#endif - ZSWAP32(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } -#ifdef GUNZIP - state->mode = LENGTH; - /* fallthrough */ - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) { - strm->msg = (char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } -#endif - state->mode = DONE; - /* fallthrough */ - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - /* fallthrough */ - default: - return Z_STREAM_ERROR; - } - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - inf_leave: - RESTORE(); - if (state->wsize || (out != strm->avail_out && state->mode < BAD && - (state->mode < CHECK || flush != Z_FINISH))) - if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; - if ((state->wrap & 4) && out) - strm->adler = state->check = - UPDATE_CHECK(state->check, strm->next_out - out, out); - strm->data_type = (int)state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0) + - (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; -} - -int ZEXPORT inflateEnd( - z_streamp strm) -{ - struct inflate_state FAR *state; - if (inflateStateCheck(strm)) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->window != Z_NULL) ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} - -#ifndef Z_FREETYPE - -int ZEXPORT inflateGetDictionary( - z_streamp strm, - Bytef *dictionary, - uInt *dictLength) -{ - struct inflate_state FAR *state; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* copy dictionary */ - if (state->whave && dictionary != Z_NULL) { - zmemcpy(dictionary, state->window + state->wnext, - state->whave - state->wnext); - zmemcpy(dictionary + state->whave - state->wnext, - state->window, state->wnext); - } - if (dictLength != Z_NULL) - *dictLength = state->whave; - return Z_OK; -} - -int ZEXPORT inflateSetDictionary( - z_streamp strm, - const Bytef *dictionary, - uInt dictLength) -{ - struct inflate_state FAR *state; - unsigned long dictid; - int ret; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->wrap != 0 && state->mode != DICT) - return Z_STREAM_ERROR; - - /* check for correct dictionary identifier */ - if (state->mode == DICT) { - dictid = adler32(0L, Z_NULL, 0); - dictid = adler32(dictid, dictionary, dictLength); - if (dictid != state->check) - return Z_DATA_ERROR; - } - - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - ret = updatewindow(strm, dictionary + dictLength, dictLength); - if (ret) { - state->mode = MEM; - return Z_MEM_ERROR; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -int ZEXPORT inflateGetHeader( - z_streamp strm, - gz_headerp head) -{ - struct inflate_state FAR *state; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; - - /* save header structure */ - state->head = head; - head->done = 0; - return Z_OK; -} - -/* - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found - or when out of input. When called, *have is the number of pattern bytes - found in order so far, in 0..3. On return *have is updated to the new - state. If on return *have equals four, then the pattern was found and the - return value is how many bytes were read including the last byte of the - pattern. If *have is less than four, then the pattern has not been found - yet and the return value is len. In the latter case, syncsearch() can be - called again with more data and the *have state. *have is initialized to - zero for the first call. - */ -local unsigned syncsearch( - unsigned FAR *have, - const unsigned char FAR *buf, - unsigned len) -{ - unsigned got; - unsigned next; - - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; -} - -int ZEXPORT inflateSync( - z_streamp strm) -{ - unsigned len; /* number of bytes to look at or looked at */ - int flags; /* temporary to save header status */ - unsigned long in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state FAR *state; - - /* check parameters */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; - - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold <<= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } - - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; - - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) return Z_DATA_ERROR; - if (state->flags == -1) - state->wrap = 0; /* if no header yet, treat as raw */ - else - state->wrap &= ~4; /* no point in computing a check value now */ - flags = state->flags; - in = strm->total_in; out = strm->total_out; - inflateReset(strm); - strm->total_in = in; strm->total_out = out; - state->flags = flags; - state->mode = TYPE; - return Z_OK; -} - -#endif /* !Z_FREETYPE */ - -/* - Returns true if inflate is currently at the end of a block generated by - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - implementation to provide an additional safety check. PPP uses - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored - block. When decompressing, PPP checks that at the end of input packet, - inflate is waiting for these length bytes. - */ -int ZEXPORT inflateSyncPoint( - z_streamp strm) -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; -} - -#ifndef Z_FREETYPE - -int ZEXPORT inflateCopy( - z_streamp dest, - z_streamp source) -{ - struct inflate_state FAR *state; - struct inflate_state FAR *copy; - unsigned char FAR *window; - unsigned wsize; - - /* check input */ - if (inflateStateCheck(source) || dest == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)source->state; - - /* allocate space */ - copy = (struct inflate_state FAR *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); - copy->strm = dest; - if (state->lencode >= state->codes && - state->lencode <= state->codes + ENOUGH - 1) { - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - } - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) { - wsize = 1U << state->wbits; - zmemcpy(window, state->window, wsize); - } - copy->window = window; - dest->state = (struct internal_state FAR *)copy; - return Z_OK; -} - -#endif /* !Z_FREETYPE */ - -int ZEXPORT inflateUndermine( - z_streamp strm, - int subvert) -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - state->sane = !subvert; - return Z_OK; -#else - (void)subvert; - state->sane = 1; - return Z_DATA_ERROR; -#endif -} - -int ZEXPORT inflateValidate( - z_streamp strm, - int check) -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (check && state->wrap) - state->wrap |= 4; - else - state->wrap &= ~4; - return Z_OK; -} - -#ifndef Z_FREETYPE - -long ZEXPORT inflateMark( - z_streamp strm) -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) - return -(1L << 16); - state = (struct inflate_state FAR *)strm->state; - return (long)(((unsigned long)((long)state->back)) << 16) + - (state->mode == COPY ? state->length : - (state->mode == MATCH ? state->was - state->length : 0)); -} - -unsigned long ZEXPORT inflateCodesUsed( - z_streamp strm) -{ - struct inflate_state FAR *state; - if (inflateStateCheck(strm)) return (unsigned long)-1; - state = (struct inflate_state FAR *)strm->state; - return (unsigned long)(state->next - state->codes); -} - -#endif /* !Z_FREETYPE */ diff --git a/thirdparty/freetype/src/gzip/inflate.h b/thirdparty/freetype/src/gzip/inflate.h deleted file mode 100644 index c6f5a52e16..0000000000 --- a/thirdparty/freetype/src/gzip/inflate.h +++ /dev/null @@ -1,131 +0,0 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2019 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#ifndef INFLATE_H -#define INFLATE_H - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip decoding - should be left enabled. */ -#ifndef NO_GZIP -# define GUNZIP -#endif - -/* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD = 16180, /* i: waiting for magic header */ - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY_, /* i/o: same as COPY below, but only first time in */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN_, /* i: same as LEN below, but only first time in */ - LEN, /* i: waiting for length/lit/eob code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ - LENGTH, /* i: waiting for 32-bit length (gzip) */ - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ -} inflate_mode; - -/* - State transitions between above modes - - - (most modes can go to BAD or MEM on error -- not shown for clarity) - - Process header: - HEAD -> (gzip) or (zlib) or (raw) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> - HCRC -> TYPE - (zlib) -> DICTID or TYPE - DICTID -> DICT -> TYPE - (raw) -> TYPEDO - Read deflate blocks: - TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK - STORED -> COPY_ -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN_ - LEN_ -> LEN - Read deflate codes in fixed or dynamic block: - LEN -> LENEXT or LIT or TYPE - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN - LIT -> LEN - Process trailer: - CHECK -> LENGTH -> DONE - */ - -/* State maintained between inflate() calls -- approximately 7K bytes, not - including the allocated sliding window, which is up to 32K bytes. */ -struct inflate_state { - z_streamp strm; /* pointer back to this zlib stream */ - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip, - bit 2 true to validate check value */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags, 0 if zlib, or - -1 if raw or no header yet */ - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - gz_headerp head; /* where to save gzip header information */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ - /* for string and stored block copying */ - unsigned length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const FAR *lencode; /* starting table for length/literal codes */ - code const FAR *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - unsigned have; /* number of code lengths in lens[] */ - code FAR *next; /* next available space in codes[] */ - unsigned short lens[320]; /* temporary storage for code lengths */ - unsigned short work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ - int sane; /* if false, allow invalid distance too far */ - int back; /* bits back of last unprocessed length/lit */ - unsigned was; /* initial length of match */ -}; - -#endif /* INFLATE_H */ diff --git a/thirdparty/freetype/src/gzip/inftrees.c b/thirdparty/freetype/src/gzip/inftrees.c deleted file mode 100644 index 0b58b29b1b..0000000000 --- a/thirdparty/freetype/src/gzip/inftrees.c +++ /dev/null @@ -1,304 +0,0 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2022 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" - -#define MAXBITS 15 - -const char inflate_copyright[] = - " inflate 1.2.12 Copyright 1995-2022 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* - Build a set of tables to decode the provided canonical Huffman code. - The code lengths are lens[0..codes-1]. The result starts at *table, - whose indices are 0..2^bits-1. work is a writable array of at least - lens shorts, which is used as a work area. type is the type of code - to be generated, CODES, LENS, or DISTS. On return, zero is success, - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table - on return points to the next available entry's address. bits is the - requested root table index bits, and on return it is the actual root - table index bits. It will differ if the request is greater than the - longest code or if it is less than the shortest code. - */ -int ZLIB_INTERNAL inflate_table( - codetype type, - unsigned short FAR *lens, - unsigned codes, - code FAR * FAR *table, - unsigned FAR *bits, - unsigned short FAR *work) -{ - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code here; /* table entry for duplication */ - code FAR *next; /* next available space in table */ - const unsigned short FAR *base; /* base value table to use */ - const unsigned short FAR *extra; /* extra bits table to use */ - unsigned match; /* use base and extra for symbol >= match */ - unsigned short count[MAXBITS+1]; /* number of codes of each length */ - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ - static const unsigned short lbase[31] = { /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const unsigned short lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 199, 202}; - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0}; - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64}; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; - - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) { /* no symbols to code at all */ - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)1; - here.val = (unsigned short)0; - *(*table)++ = here; /* make a table to force an error */ - *(*table)++ = here; - *bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) - if (count[min] != 0) break; - if (root < min) root = min; - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || max != 1)) - return -1; /* incomplete set */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - switch (type) { - case CODES: - base = extra = work; /* dummy value--not used */ - match = 20; - break; - case LENS: - base = lbase; - extra = lext; - match = 257; - break; - default: /* DISTS */ - base = dbase; - extra = dext; - match = 0; - } - - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type == LENS && used > ENOUGH_LENS) || - (type == DISTS && used > ENOUGH_DISTS)) - return 1; - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here.bits = (unsigned char)(len - drop); - if (work[sym] + 1U < match) { - here.op = (unsigned char)0; - here.val = work[sym]; - } - else if (work[sym] >= match) { - here.op = (unsigned char)(extra[work[sym] - match]); - here.val = base[work[sym] - match]; - } - else { - here.op = (unsigned char)(32 + 64); /* end of block */ - here.val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - next[(huff >> drop) + fill] = here; - } while (fill != 0); - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) break; - len = lens[work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) break; - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1U << curr; - if ((type == LENS && used > ENOUGH_LENS) || - (type == DISTS && used > ENOUGH_DISTS)) - return 1; - - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (unsigned short)(next - *table); - } - } - - /* fill in remaining table entry if code is incomplete (guaranteed to have - at most one remaining entry, since if the code is incomplete, the - maximum code length that was allowed to get this far is one bit) */ - if (huff != 0) { - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)(len - drop); - here.val = (unsigned short)0; - next[huff] = here; - } - - /* set return parameters */ - *table += used; - *bits = root; - return 0; -} diff --git a/thirdparty/freetype/src/gzip/inftrees.h b/thirdparty/freetype/src/gzip/inftrees.h deleted file mode 100644 index c94eb78b5d..0000000000 --- a/thirdparty/freetype/src/gzip/inftrees.h +++ /dev/null @@ -1,67 +0,0 @@ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#ifndef INFTREES_H -#define INFTREES_H - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Structure for decoding tables. Each entry provides either the - information needed to do the operation requested by the code that - indexed that table entry, or it provides a pointer to another - table that indexes more bits of the code. op indicates whether - the entry is a pointer to another table, a literal, a length or - distance, an end-of-block, or an invalid code. For a table - pointer, the low four bits of op is the number of index bits of - that table. For a length or distance, the low four bits of op - is the number of extra bits to get after the code. bits is - the number of bits in this code or part of the code to drop off - of the bit buffer. val is the actual byte to output in the case - of a literal, the base length or distance, or the offset from - the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - unsigned short val; /* offset in table or code value */ -} code; - -/* op values as set by inflate_table(): - 00000000 - literal - 0000tttt - table link, tttt != 0 is the number of table index bits - 0001eeee - length or distance, eeee is the number of extra bits - 01100000 - end of block - 01000000 - invalid code - */ - -/* Maximum size of the dynamic table. The maximum number of code structures is - 1444, which is the sum of 852 for literal/length codes and 592 for distance - codes. These values were found by exhaustive searches using the program - examples/enough.c found in the zlib distribtution. The arguments to that - program are the number of symbols, the initial root table size, and the - maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the - inflate_table() calls in inflate.c and infback.c. If the root table size is - changed, then these maximum sizes would be need to be recalculated and - updated. */ -#define ENOUGH_LENS 852 -#define ENOUGH_DISTS 592 -#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) - -/* Type of code to build for inflate_table() */ -typedef enum { - CODES, - LENS, - DISTS -} codetype; - -int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); - -#endif /* INFTREES_H_ */ diff --git a/thirdparty/freetype/src/gzip/zlib.h b/thirdparty/freetype/src/gzip/zlib.h deleted file mode 100644 index d760140c2e..0000000000 --- a/thirdparty/freetype/src/gzip/zlib.h +++ /dev/null @@ -1,1968 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.12, March 11th, 2022 - - Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 - (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "ftzconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.2.12" -#define ZLIB_VERNUM 0x12c0 -#define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 12 -#define ZLIB_VER_SUBREVISION 0 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed data. - This version of the library supports only one compression method (deflation) - but other algorithms will be added later and will have the same stream - interface. - - Compression can be done in a single step if the buffers are large enough, - or can be done by repeated calls of the compression function. In the latter - case, the application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip and raw deflate streams in - memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never crash - even in the case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - z_const Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total number of input bytes read so far */ - - Bytef *next_out; /* next output byte will go here */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total number of bytes output so far */ - - z_const char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text - for deflate, or the decoding state for inflate */ - uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has dropped - to zero. It must update next_out and avail_out when avail_out has dropped - to zero. The application must initialize zalloc, zfree and opaque before - calling the init function. All other fields are set by the compression - library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. In that case, zlib is thread-safe. When zalloc and zfree are - Z_NULL on entry to the initialization function, they are set to internal - routines that use the standard library functions malloc() and free(). - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this if - the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers - returned by zalloc for objects of exactly 65536 bytes *must* have their - offset normalized to zero. The default allocation function provided by this - library ensures this (see zutil.c). To reduce memory requirements and avoid - any allocation of 64K objects, at the expense of compression ratio, compile - the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or progress - reports. After compression, total_in holds the total size of the - uncompressed data and may be saved for use by the decompressor (particularly - if the decompressor wants to decompress everything in a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -#define Z_TREES 6 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field for deflate() */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#ifndef Z_FREETYPE - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is not - compatible with the zlib.h header file used by the application. This check - is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. If - zalloc and zfree are set to Z_NULL, deflateInit updates them to use default - allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at all - (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION - requests a default compromise between speed and compression (currently - equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if level is not a valid compression level, or - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). msg is set to null - if there is no error message. deflateInit does not perform any compression: - this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Generate more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary. Some output may be provided even if - flush is zero. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating avail_in or avail_out accordingly; avail_out should - never be zero before the call. The application can consume the compressed - output when it wants, for example when the output buffer is full (avail_out - == 0), or after each call of deflate(). If deflate returns Z_OK and with - zero avail_out, it must be called again after making room in the output - buffer because there might be more output pending. See deflatePending(), - which can be used if desired to determine whether or not there is more ouput - in that case. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumulate before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In - particular avail_in is zero after the call if enough output space has been - provided before the call.) Flushing may degrade compression for some - compression algorithms and so it should be used only when necessary. This - completes the current deflate block and follows it with an empty stored block - that is three bits plus filler bits to the next byte, followed by four bytes - (00 00 ff ff). - - If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the - output buffer, but the output is not aligned to a byte boundary. All of the - input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. - This completes the current deflate block and follows it with an empty fixed - codes block that is 10 bits long. This assures that enough bytes are output - in order for the decompressor to finish the block before the empty fixed - codes block. - - If flush is set to Z_BLOCK, a deflate block is completed and emitted, as - for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to - seven bits of the current block are held to be written as the next byte after - the next deflate block is completed. In this case, the decompressor may not - be provided enough bits at this point in order to complete decompression of - the data provided so far to the compressor. It may need to wait for the next - block to be emitted. This is for advanced applications that need to control - the emission of deflate blocks. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there was - enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this - function must be called again with Z_FINISH and more output space (updated - avail_out) but no more input data, until it returns with Z_STREAM_END or an - error. After deflate has returned Z_STREAM_END, the only possible operations - on the stream are deflateReset or deflateEnd. - - Z_FINISH can be used in the first deflate call after deflateInit if all the - compression is to be done in a single step. In order to complete in one - call, avail_out must be at least the value returned by deflateBound (see - below). Then deflate is guaranteed to return Z_STREAM_END. If not enough - output space is provided, deflate will not return Z_STREAM_END, and it must - be called again as described above. - - deflate() sets strm->adler to the Adler-32 checksum of all input read - so far (that is, total_in bytes). If a gzip stream is being generated, then - strm->adler will be the CRC-32 checksum of the input read so far. (See - deflateInit2 below.) - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is - considered binary. This field is only for information purposes and does not - affect the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was Z_NULL or the state was inadvertently written over - by the application), or Z_BUF_ERROR if no progress is possible (for example - avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and - deflate() can be called again with more input and more output space to - continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, msg - may be set but then points to a static string (which must not be - deallocated). -*/ - -#endif /* !Z_FREETYPE */ - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. In the current version of inflate, the provided input is not - read or consumed. The allocation of a sliding window will be deferred to - the first call of inflate (if the decompression does not complete on the - first call). If zalloc and zfree are set to Z_NULL, inflateInit updates - them to use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit does not perform any decompression. - Actual decompression will be done by inflate(). So next_in, and avail_in, - next_out, and avail_out are unused and unchanged. The current - implementation of inflateInit() does not process any header information -- - that is deferred until inflate() is called. -*/ - - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), then next_in and avail_in are updated - accordingly, and processing will resume at this point for the next call of - inflate(). - - - Generate more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there is - no more input data or no more space in the output buffer (see below about - the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating the next_* and avail_* values accordingly. If the - caller of inflate() does not provide both available input and available - output space, it is possible that there will be no progress made. The - application can consume the uncompressed output when it wants, for example - when the output buffer is full (avail_out == 0), or after each call of - inflate(). If inflate returns Z_OK and with zero avail_out, it must be - called again after making room in the output buffer because there might be - more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, - Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() - stop if and when it gets to the next deflate block boundary. When decoding - the zlib or gzip format, this will cause inflate() to return immediately - after the header and before the first block. When doing a raw inflate, - inflate() will go ahead and process the first block, and will return when it - gets to the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - To assist in this, on return inflate() always sets strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 if - inflate() is currently decoding the last block in the deflate stream, plus - 128 if inflate() returned immediately after decoding an end-of-block code or - decoding the complete header up to just before the first byte of the deflate - stream. The end-of-block will not be indicated until all of the uncompressed - data from that block has been written to strm->next_out. The number of - unused bits may in general be greater than seven, except when bit 7 of - data_type is set, in which case the number of unused bits will be less than - eight. data_type is set as noted here every time inflate() returns for all - flush options, and so can be used to determine the amount of currently - consumed input in bits. - - The Z_TREES option behaves as Z_BLOCK does, but it also returns when the - end of each deflate block header is reached, before any actual data in that - block is decoded. This allows the caller to determine the length of the - deflate block header for later use in random access within a deflate block. - 256 is added to the value of strm->data_type when inflate() returns - immediately after reaching the end of the deflate block header. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step (a - single call of inflate), the parameter flush should be set to Z_FINISH. In - this case all pending input is processed and all pending output is flushed; - avail_out must be large enough to hold all of the uncompressed data for the - operation to complete. (The size of the uncompressed data may have been - saved by the compressor for this purpose.) The use of Z_FINISH is not - required to perform an inflation in one step. However it may be used to - inform inflate that a faster approach can be used for the single inflate() - call. Z_FINISH also informs inflate to not maintain a sliding window if the - stream completes, which reduces inflate's memory footprint. If the stream - does not complete, either because not all of the stream is provided or not - enough output space is provided, then a sliding window will be allocated and - inflate() can be called again to continue the operation as if Z_NO_FLUSH had - been used. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the effects of the flush parameter in this implementation are - on the return value of inflate() as noted below, when inflate() returns early - when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of - memory for a sliding window when Z_FINISH is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the Adler-32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the Adler-32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed Adler-32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() can decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically, if requested when - initializing with inflateInit2(). Any information contained in the gzip - header is not retained unless inflateGetHeader() is used. When processing - gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output - produced so far. The CRC-32 is checked against the gzip trailer, as is the - uncompressed length, modulo 2^32. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value, in which case strm->msg points to a string with a more specific - error), Z_STREAM_ERROR if the stream structure was inconsistent (for example - next_in or next_out was Z_NULL, or the state was inadvertently written over - by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR - if no progress was possible or if there was not enough room in the output - buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may - then call inflateSync() to look for a good compression block if a partial - recovery of the data is to be attempted. -*/ - - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state - was inconsistent. -*/ - - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -#ifndef Z_FREETYPE - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields zalloc, zfree and opaque must be initialized before by the caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - For the current implementation of deflate(), a windowBits value of 8 (a - window size of 256 bytes) is not supported. As a result, a request for 8 - will result in 9 (a 512-byte window). In that case, providing 8 to - inflateInit2() will result in an error when the zlib header with 9 is - checked against the initialization of inflate(). The remedy is to not use 8 - with deflateInit2() with this initialization, or at least in that case use 9 - with inflateInit2(). - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute a check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), no - header crc, and the operating system will be set to the appropriate value, - if the operating system was determined at compile time. If a gzip stream is - being written, strm->adler is a CRC-32 instead of an Adler-32. - - For raw deflate or gzip encoding, a request for a 256-byte window is - rejected as invalid, since only the zlib header provides a means of - transmitting the window size to the decompressor. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but is - slow and reduces compression ratio; memLevel=9 uses maximum memory for - optimal speed. The default value is 8. See zconf.h for total memory usage - as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as - fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The - strategy parameter only affects the compression ratio but not the - correctness of the compressed output even if it is not set appropriately. - Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler - decoder for special applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid - method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is - incompatible with the version assumed by the caller (ZLIB_VERSION). msg is - set to null if there is no error message. deflateInit2 does not perform any - compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. When using the zlib format, this - function must be called immediately after deflateInit, deflateInit2 or - deflateReset, and before any call of deflate. When doing raw deflate, this - function must be called either before any call of deflate, or immediately - after the completion of a deflate block, i.e. after all input has been - consumed and all output has been delivered when using any of the flush - options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The - compressor and decompressor must use exactly the same dictionary (see - inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size - provided in deflateInit or deflateInit2. Thus the strings most likely to be - useful should be put at the end of the dictionary, not at the front. In - addition, the current implementation of deflate will use at most the window - size minus 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the Adler-32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The Adler-32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - Adler-32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if not at a block boundary for raw deflate). deflateSetDictionary does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); -/* - Returns the sliding dictionary being maintained by deflate. dictLength is - set to the number of bytes in the dictionary, and that many bytes are copied - to dictionary. dictionary must have enough space, where 32768 bytes is - always enough. If deflateGetDictionary() is called with dictionary equal to - Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similary, if dictLength is Z_NULL, then it is not set. - - deflateGetDictionary() may return a length less than the window size, even - when more than the window size in input has been provided. It may return up - to 258 bytes less in that case, due to how zlib's implementation of deflate - manages the sliding window and lookahead for matches, where matches can be - up to 258 bytes long. If the application needs the last window-size bytes of - input, then that would need to be saved by the application outside of zlib. - - deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the - stream state is inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and can - consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, but - does not free and reallocate the internal compression state. The stream - will leave the compression level and any other attributes that may have been - set unchanged. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2(). This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different strategy. - If the compression approach (which is a function of the level) or the - strategy is changed, and if there have been any deflate() calls since the - state was initialized or reset, then the input available so far is - compressed with the old level and strategy using deflate(strm, Z_BLOCK). - There are three approaches for the compression levels 0, 1..3, and 4..9 - respectively. The new level and strategy will take effect at the next call - of deflate(). - - If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does - not have enough output space to complete, then the parameter change will not - take effect. In this case, deflateParams() can be called again with the - same parameters and more output space to try again. - - In order to assure a change in the parameters on the first try, the - deflate stream should be flushed using deflate() with Z_BLOCK or other flush - request until strm.avail_out is not zero, before calling deflateParams(). - Then no more input data should be provided before the deflateParams() call. - If this is done, the old level and strategy will be applied to the data - compressed before deflateParams(), and the new level and strategy will be - applied to the the data compressed after deflateParams(). - - deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream - state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if - there was not enough output space to complete the compression of the - available input data before a change in the strategy or approach. Note that - in the case of a Z_BUF_ERROR, the parameters are not changed. A return - value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be - retried with more output space. -*/ - -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() or - deflateInit2(), and after deflateSetHeader(), if used. This would be used - to allocate an output buffer for deflation in a single pass, and so would be - called before deflate(). If that first deflate() call is provided the - sourceLen input bytes, an output buffer allocated to the size returned by - deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed - to return Z_STREAM_END. Note that it is possible for the compressed size to - be larger than the value returned by deflateBound() if flush options other - than Z_FINISH or Z_NO_FLUSH are used. -*/ - -ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, - unsigned *pending, - int *bits)); -/* - deflatePending() returns the number of bytes and bits of output that have - been generated, but not yet provided in the available output. The bytes not - provided would be due to the available output space having being consumed. - The number of bits of output not provided are between 0 and 7, where they - await more bits to join them in order to fill out a full byte. If pending - or bits are Z_NULL, then those values are not set. - - deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. - */ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the bits - leftover from a previous deflate stream when appending to it. As such, this - function can only be used for raw deflate, and must be used before the first - deflate() call after a deflateInit2() or deflateReset(). bits must be less - than or equal to 16, and that many of the least significant bits of value - will be inserted in the output. - - deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough - room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be zero to request that inflate use the window size in - the zlib header of the compressed stream. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an Adler-32 or a CRC-32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a - CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see - below), inflate() will *not* automatically decode concatenated gzip members. - inflate() will return Z_STREAM_END at the end of the gzip member. The state - would need to be reset to continue decoding a subsequent gzip member. This - *must* be done if there is more data after a gzip member, in order for the - decompression to be compliant with the gzip standard (RFC 1952). - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit2 does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit2() does not process any header information -- that is - deferred until inflate() is called. -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the Adler-32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called at any - time to set the dictionary. If the provided dictionary is smaller than the - window and there is already data in the window, then the provided dictionary - will amend what's there. The application must insure that the dictionary - that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect Adler-32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); -/* - Returns the sliding dictionary being maintained by inflate. dictLength is - set to the number of bytes in the dictionary, and that many bytes are copied - to dictionary. dictionary must have enough space, where 32768 bytes is - always enough. If inflateGetDictionary() is called with dictionary equal to - Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similary, if dictLength is Z_NULL, then it is not set. - - inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the - stream state is inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a possible full flush point (see above - for the description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync searches for a 00 00 FF FF pattern in the compressed data. - All full flush points have this pattern, but not all occurrences of this - pattern are full flush points. - - inflateSync returns Z_OK if a possible full flush point has been found, - Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point - has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current current value of - total_in which indicates where valid compressed data was found. In the - error case, the application may repeatedly call inflateSync, providing more - input each time, until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -#endif /* !Z_FREETYPE */ - -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate the internal decompression state. The - stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, - int windowBits)); -/* - This function is the same as inflateReset, but it also permits changing - the wrap and window size requests. The windowBits parameter is interpreted - the same as it is for inflateInit2. If the window size is changed, then the - memory allocated for the window is freed, and the window will be reallocated - by inflate() if needed. - - inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL), or if - the windowBits parameter is invalid. -*/ - -#ifndef Z_FREETYPE - -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - If bits is negative, then the input stream bit buffer is emptied. Then - inflatePrime() can be called again to put bits in the buffer. This is used - to clear out bits leftover after feeding inflate a block description prior - to feeding inflate codes. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); -/* - This function returns two values, one in the lower 16 bits of the return - value, and the other in the remaining upper bits, obtained by shifting the - return value down 16 bits. If the upper value is -1 and the lower value is - zero, then inflate() is currently decoding information outside of a block. - If the upper value is -1 and the lower value is non-zero, then inflate is in - the middle of a stored block, with the lower value equaling the number of - bytes from the input remaining to copy. If the upper value is not -1, then - it is the number of bits back from the current bit position in the input of - the code (literal or length/distance pair) currently being processed. In - that case the lower value is the number of bytes already emitted for that - code. - - A code is being processed if inflate is waiting for more input to complete - decoding of the code, or if it has completed decoding but is waiting for - more output space to write the literal or match data. - - inflateMark() is used to mark locations in the input data for random - access, which may be at bit positions, and to note those cases where the - output of a code may span boundaries of random access blocks. The current - location in the input stream can be determined from avail_in and data_type - as noted in the description for the Z_BLOCK flush parameter for inflate. - - inflateMark returns the value noted above, or -65536 if the provided - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be - used to force inflate() to return immediately after header processing is - complete and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When any - of extra, name, or comment are not Z_NULL and the respective field is not - present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -#endif /* !Z_FREETYPE */ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the parameters are invalid, Z_MEM_ERROR if the internal state could not be - allocated, or Z_VERSION_ERROR if the version of the library does not match - the version of the header file. -*/ - -typedef unsigned (*in_func) OF((void FAR *, - z_const unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -#ifndef Z_FREETYPE - -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is potentially more efficient than - inflate() for file i/o applications, in that it avoids copying between the - output and the sliding window by simply making the window itself the output - buffer. inflate() can be faster on modern CPUs when used with large - buffers. inflateBack() trusts the application to not change the output - buffer passed by the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free the - allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects only - the raw deflate stream to decompress. This is different from the default - behavior of inflate(), which expects a zlib header and trailer around the - deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero -- buf is ignored in that - case -- and inflateBack() will return a buffer error. inflateBack() will - call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. - out() should return zero on success, or non-zero on failure. If out() - returns non-zero, inflateBack() will return with an error. Neither in() nor - out() are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format error - in the deflate stream (in which case strm->msg is set to indicate the nature - of the error), or Z_STREAM_ERROR if the stream was not properly initialized. - In the case of Z_BUF_ERROR, an input or output error can be distinguished - using strm->next_in which will be Z_NULL only if in() returned an error. If - strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning - non-zero. (in() will always be called before out(), so strm->next_in is - assured to be defined if out() returns non-zero.) Note that inflateBack() - cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: ZLIB_DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - -#endif /* !Z_FREETYPE */ - -#ifndef Z_SOLO - - /* utility functions */ - -/* - The following utility functions are implemented on top of the basic - stream-oriented functions. To simplify the interface, some default options - are assumed (compression level and memory usage, standard memory allocation - functions). The source code of these utility functions can be modified if - you need special options. -*/ - -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed data. compress() is equivalent to compress2() with a level - parameter of Z_DEFAULT_COMPRESSION. - - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed data. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before a - compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, destLen - is the actual size of the uncompressed data. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In - the case where there is not enough room, uncompress() will fill the output - buffer with the uncompressed data up to that point. -*/ - -ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong *sourceLen)); -/* - Same as uncompress, except that sourceLen is a pointer, where the - length of the source is *sourceLen. On return, *sourceLen is the number of - source bytes consumed. -*/ - - /* gzip file access functions */ - -/* - This library supports reading and writing files in gzip (.gz) format with - an interface similar to that of stdio, using the functions that start with - "gz". The gzip format is different from the zlib format. gzip is a gzip - wrapper, documented in RFC 1952, wrapped around a deflate stream. -*/ - -typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ - -/* -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); - - Open the gzip (.gz) file at path for reading and decompressing, or - compressing and writing. The mode parameter is as in fopen ("rb" or "wb") - but can also include a compression level ("wb9") or a strategy: 'f' for - filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", - 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression - as in "wb9F". (See the description of deflateInit2 for more information - about the strategy parameter.) 'T' will request transparent writing or - appending with no compression and not using the gzip format. - - "a" can be used instead of "w" to request that the gzip stream that will - be written be appended to the file. "+" will result in an error, since - reading and writing to the same gzip file is not supported. The addition of - "x" when writing will create the file exclusively, which fails if the file - already exists. On systems that support it, the addition of "e" when - reading or writing will set the flag to close the file on an execve() call. - - These functions, as well as gzip, will read and decode a sequence of gzip - streams in a file. The append function of gzopen() can be used to create - such a file. (Also see gzflush() for another way to do this.) When - appending, gzopen does not test whether the file begins with a gzip stream, - nor does it look for the end of the gzip streams to begin appending. gzopen - will simply append a gzip stream to the existing file. - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. When - reading, this will be detected automatically by looking for the magic two- - byte gzip header. - - gzopen returns NULL if the file could not be opened, if there was - insufficient memory to allocate the gzFile state, or if an invalid mode was - specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). - errno can be checked to determine if the reason gzopen failed was that the - file could not be opened. -*/ - -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - Associate a gzFile with the file descriptor fd. File descriptors are - obtained from calls like open, dup, creat, pipe or fileno (if the file has - been previously opened with fopen). The mode parameter is as in gzopen. - - The next call of gzclose on the returned gzFile will also close the file - descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor - fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, - mode);. The duplicated descriptor should be saved to avoid a leak, since - gzdopen does not close fd if it fails. If you are using fileno() to get the - file descriptor from a FILE *, then you will have to use dup() to avoid - double-close()ing the file descriptor. Both gzclose() and fclose() will - close the associated file descriptor, so they need to have different file - descriptors. - - gzdopen returns NULL if there was insufficient memory to allocate the - gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not - provided, or '+' was provided), or if fd is -1. The file descriptor is not - used until the next gz* read, write, seek, or close operation, so gzdopen - will not detect if fd is invalid (unless fd is -1). -*/ - -ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); -/* - Set the internal buffer size used by this library's functions for file to - size. The default buffer size is 8192 bytes. This function must be called - after gzopen() or gzdopen(), and before any other calls that read or write - the file. The buffer memory allocation is always deferred to the first read - or write. Three times that size in buffer space is allocated. A larger - buffer size of, for example, 64K or 128K bytes will noticeably increase the - speed of decompression (reading). - - The new buffer size also affects the maximum length for gzprintf(). - - gzbuffer() returns 0 on success, or -1 on failure, such as being called - too late. -*/ - -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level and strategy for file. See the - description of deflateInit2 for the meaning of these parameters. Previously - provided data is flushed before applying the parameter changes. - - gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not - opened for writing, Z_ERRNO if there is an error writing the flushed data, - or Z_MEM_ERROR if there is a memory allocation error. -*/ - -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Read and decompress up to len uncompressed bytes from file into buf. If - the input file is not in gzip format, gzread copies the given number of - bytes into the buffer directly from the file. - - After reaching the end of a gzip stream in the input, gzread will continue - to read, looking for another gzip stream. Any number of gzip streams may be - concatenated in the input file, and will all be decompressed by gzread(). - If something other than a gzip stream is encountered after a gzip stream, - that remaining trailing garbage is ignored (and no error is returned). - - gzread can be used to read a gzip file that is being concurrently written. - Upon reaching the end of the input, gzread will return with the available - data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then - gzclearerr can be used to clear the end of file indicator in order to permit - gzread to be tried again. Z_OK indicates that a gzip stream was completed - on the last gzread. Z_BUF_ERROR indicates that the input file ended in the - middle of a gzip stream. Note that gzread does not return -1 in the event - of an incomplete gzip stream. This error is deferred until gzclose(), which - will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip - stream. Alternatively, gzerror can be used before gzclose to detect this - case. - - gzread returns the number of uncompressed bytes actually read, less than - len for end of file, or -1 for error. If len is too large to fit in an int, - then nothing is read, -1 is returned, and the error state is set to - Z_STREAM_ERROR. -*/ - -ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, - gzFile file)); -/* - Read and decompress up to nitems items of size size from file into buf, - otherwise operating as gzread() does. This duplicates the interface of - stdio's fread(), with size_t request and return types. If the library - defines size_t, then z_size_t is identical to size_t. If not, then z_size_t - is an unsigned integer type that can contain a pointer. - - gzfread() returns the number of full items read of size size, or zero if - the end of the file was reached and a full item could not be read, or if - there was an error. gzerror() must be consulted if zero is returned in - order to determine if there was an error. If the multiplication of size and - nitems overflows, i.e. the product does not fit in a z_size_t, then nothing - is read, zero is returned, and the error state is set to Z_STREAM_ERROR. - - In the event that the end of file is reached and only a partial item is - available at the end, i.e. the remaining uncompressed data length is not a - multiple of size, then the final partial item is nevetheless read into buf - and the end-of-file flag is set. The length of the partial item read is not - provided, but could be inferred from the result of gztell(). This behavior - is the same as the behavior of fread() implementations in common libraries, - but it prevents the direct use of gzfread() to read a concurrently written - file, reseting and retrying on end-of-file, when size is not 1. -*/ - -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len)); -/* - Compress and write the len uncompressed bytes at buf to file. gzwrite - returns the number of uncompressed bytes written or 0 in case of error. -*/ - -ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, - z_size_t nitems, gzFile file)); -/* - Compress and write nitems items of size size from buf to file, duplicating - the interface of stdio's fwrite(), with size_t request and return types. If - the library defines size_t, then z_size_t is identical to size_t. If not, - then z_size_t is an unsigned integer type that can contain a pointer. - - gzfwrite() returns the number of full items written of size size, or zero - if there was an error. If the multiplication of size and nitems overflows, - i.e. the product does not fit in a z_size_t, then nothing is written, zero - is returned, and the error state is set to Z_STREAM_ERROR. -*/ - -ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); -/* - Convert, format, compress, and write the arguments (...) to file under - control of the string format, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written, or a negative zlib error code in case - of error. The number of uncompressed bytes written is limited to 8191, or - one less than the buffer size given to gzbuffer(). The caller should assure - that this limit is not exceeded. If it is exceeded, then gzprintf() will - return an error (0) with nothing written. In this case, there may also be a - buffer overflow with unpredictable consequences, which is possible only if - zlib was compiled with the insecure functions sprintf() or vsprintf(), - because the secure snprintf() or vsnprintf() functions were not available. - This can be determined using zlibCompileFlags(). -*/ - -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Compress and write the given null-terminated string s to file, excluding - the terminating null character. - - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* - Read and decompress bytes from file into buf, until len-1 characters are - read, or until a newline character is read and transferred to buf, or an - end-of-file condition is encountered. If any characters are read or if len - is one, the string is terminated with a null character. If no characters - are read due to an end-of-file or len is less than one, then the buffer is - left untouched. - - gzgets returns buf which is a null-terminated string, or it returns NULL - for end-of-file or in case of error. If there was an error, the contents at - buf are indeterminate. -*/ - -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* - Compress and write c, converted to an unsigned char, into file. gzputc - returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* - Read and decompress one byte from file. gzgetc returns this byte or -1 - in case of end of file or error. This is implemented as a macro for speed. - As such, it does not do all of the checking the other functions do. I.e. - it does not check to see if file is NULL, nor whether the structure file - points to has been clobbered or not. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push c back onto the stream for file to be read as the first character on - the next read. At least one character of push-back is always allowed. - gzungetc() returns the character pushed, or -1 on failure. gzungetc() will - fail if c is -1, and may fail if a character has been pushed but not read - yet. If gzungetc is used immediately after gzopen or gzdopen, at least the - output buffer size of pushed characters is allowed. (See gzbuffer above.) - The pushed character will be discarded if the stream is repositioned with - gzseek() or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flush all pending output to file. The parameter flush is as in the - deflate() function. The return value is the zlib error number (see function - gzerror below). gzflush is only permitted when writing. - - If the flush parameter is Z_FINISH, the remaining data is written and the - gzip stream is completed in the output. If gzwrite() is called again, a new - gzip stream will be started in the output. gzread() is able to read such - concatenated gzip streams. - - gzflush should be called only when strictly necessary because it will - degrade compression if called too often. -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); - - Set the starting position to offset relative to whence for the next gzread - or gzwrite on file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* - Rewind file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET). -*/ - -/* -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); - - Return the starting position for the next gzread or gzwrite on file. - This position represents a number of bytes in the uncompressed data stream, - and is zero when starting, even if appending or reading a gzip stream from - the middle of a file using gzdopen(). - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); - - Return the current compressed (actual) read or write offset of file. This - offset includes the count of bytes that precede the gzip stream, for example - when appending or when using gzdopen() for reading. When reading, the - offset does not include as yet unused buffered input. This information can - be used for a progress indicator. On error, gzoffset() returns -1. -*/ - -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* - Return true (1) if the end-of-file indicator for file has been set while - reading, false (0) otherwise. Note that the end-of-file indicator is set - only if the read tried to go past the end of the input, but came up short. - Therefore, just like feof(), gzeof() may return false even if there is no - more data to read, in the event that the last read request was for the exact - number of bytes remaining in the input file. This will happen if the input - file size is an exact multiple of the buffer size. - - If gzeof() returns true, then the read functions will return no more data, - unless the end-of-file indicator is reset by gzclearerr() and the input file - has grown since the previous end of file was detected. -*/ - -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* - Return true (1) if file is being copied directly while reading, or false - (0) if file is a gzip stream being decompressed. - - If the input file is empty, gzdirect() will return true, since the input - does not contain a gzip stream. - - If gzdirect() is used immediately after gzopen() or gzdopen() it will - cause buffers to be allocated to allow reading the file to determine if it - is a gzip file. Therefore if gzbuffer() is used, it should be called before - gzdirect(). - - When writing, gzdirect() returns true (1) if transparent writing was - requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: - gzdirect() is not needed when writing. Transparent writing must be - explicitly requested, so the application already knows the answer. When - linking statically, using gzdirect() will include all of the zlib code for - gzip file reading and decompression, which may not be desired.) -*/ - -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* - Flush all pending output for file, if necessary, close file and - deallocate the (de)compression state. Note that once file is closed, you - cannot call gzerror with file, since its structures have been deallocated. - gzclose must not be called more than once on the same file, just as free - must not be called more than once on the same allocation. - - gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a - file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the - last read ended in the middle of a gzip stream, or Z_OK on success. -*/ - -ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); -ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); -/* - Same as gzclose(), but gzclose_r() is only for use when reading, and - gzclose_w() is only for use when writing or appending. The advantage to - using these instead of gzclose() is that they avoid linking in zlib - compression or decompression code that is not used when only reading or only - writing respectively. If gzclose() is used, then both compression and - decompression code will be included the application when linking to a static - zlib library. -*/ - -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* - Return the error message for the last error which occurred on file. - errnum is set to zlib error number. If an error occurred in the file system - and not in the compression library, errnum is set to Z_ERRNO and the - application may consult errno to get the exact error code. - - The application must not modify the returned string. Future calls to - this function may invalidate the previously returned string. If file is - closed, then the string previously returned by gzerror will no longer be - available. - - gzerror() should be used to distinguish errors from end-of-file for those - functions above that do not distinguish those cases in their return values. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clear the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - -#endif /* !Z_SOLO */ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the compression - library. -*/ - -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. An Adler-32 value is in the range of a 32-bit - unsigned integer. If buf is Z_NULL, this function returns the required - initial value for the checksum. - - An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed - much faster. - - Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf, - z_size_t len)); -/* - Same as adler32(), but with a size_t length. -*/ - -/* -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); - - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note - that the z_off_t type (like off_t) is a signed integer. If len2 is - negative, the result has no meaning or utility. -*/ - -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. - If buf is Z_NULL, this function returns the required initial value for the - crc. Pre- and post-conditioning (one's complement) is performed within this - function so it shouldn't be done by the application. - - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -#ifndef Z_FREETYPE - -ZEXTERN uLong ZEXPORT crc32_z OF((uLong crc, const Bytef *buf, - z_size_t len)); -/* - Same as crc32(), but with a size_t length. -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); - - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t len2)); - - Return the operator corresponding to length len2, to be used with - crc32_combine_op(). -*/ - -ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op)); -/* - Give the same result as crc32_combine(), using op in place of len2. op is - is generated from len2 by crc32_combine_gen(). This will be faster than - crc32_combine() if the generated op is used more than once. -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#ifdef Z_PREFIX_SET -# define z_deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -# define z_inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) -#else -# define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -# define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -# define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -# define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) -#endif - -#else /* Z_FREETYPE */ - - -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); - -# define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) - -#endif /* Z_FREETYPE */ - - -#ifndef Z_SOLO - -/* gzgetc() macro and its supporting function and exposed data structure. Note - * that the real internal state is much larger than the exposed structure. - * This abbreviated structure exposes just enough for the gzgetc() macro. The - * user should not mess with these exposed elements, since their names or - * behavior could change in the future, perhaps even capriciously. They can - * only be used by the gzgetc() macro. You have been warned. - */ -struct gzFile_s { - unsigned have; - unsigned char *next; - z_off64_t pos; -}; -ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ -#ifdef Z_PREFIX_SET -# undef z_gzgetc -# define z_gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) -#else -# define gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) -#endif - -/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or - * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if - * both are true, the application gets the *64 functions, and the regular - * functions are changed to 64 bits) -- in case these are set on systems - * without large file support, _LFS64_LARGEFILE must also be true - */ -#ifdef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off64_t)); -#endif - -#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) -# ifdef Z_PREFIX_SET -# define z_gzopen z_gzopen64 -# define z_gzseek z_gzseek64 -# define z_gztell z_gztell64 -# define z_gzoffset z_gzoffset64 -# define z_adler32_combine z_adler32_combine64 -# define z_crc32_combine z_crc32_combine64 -# define z_crc32_combine_gen z_crc32_combine_gen64 -# else -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# define crc32_combine_gen crc32_combine_gen64 -# endif -# ifndef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t)); -# endif -#else - ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t)); -#endif - -#else /* Z_SOLO */ - -#ifndef Z_FREETYPE - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t)); -#endif - -#endif /* !Z_SOLO */ - -/* undocumented functions */ -#ifndef Z_FREETYPE -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); -ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); -ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); -ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int)); -ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF ((z_streamp)); -ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); -ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); -#if defined(_WIN32) && !defined(Z_SOLO) -ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, - const char *mode)); -#endif -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, - const char *format, - va_list va)); -# endif -#endif -#endif /* !Z_FREETYPE */ - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/thirdparty/freetype/src/gzip/zutil.c b/thirdparty/freetype/src/gzip/zutil.c deleted file mode 100644 index a19ac2b96d..0000000000 --- a/thirdparty/freetype/src/gzip/zutil.c +++ /dev/null @@ -1,325 +0,0 @@ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2017 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" -#ifndef Z_SOLO -# include "gzguts.h" -#endif - -z_const char * const z_errmsg[10] = { - (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ - (z_const char *)"stream end", /* Z_STREAM_END 1 */ - (z_const char *)"", /* Z_OK 0 */ - (z_const char *)"file error", /* Z_ERRNO (-1) */ - (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ - (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ - (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ - (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ - (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ - (z_const char *)"" -}; - - -const char * ZEXPORT zlibVersion() -{ - return ZLIB_VERSION; -} - -uLong ZEXPORT zlibCompileFlags() -{ - uLong flags; - - flags = 0; - switch ((int)(sizeof(uInt))) { - case 2: break; - case 4: flags += 1; break; - case 8: flags += 2; break; - default: flags += 3; - } - switch ((int)(sizeof(uLong))) { - case 2: break; - case 4: flags += 1 << 2; break; - case 8: flags += 2 << 2; break; - default: flags += 3 << 2; - } - switch ((int)(sizeof(voidpf))) { - case 2: break; - case 4: flags += 1 << 4; break; - case 8: flags += 2 << 4; break; - default: flags += 3 << 4; - } - switch ((int)(sizeof(z_off_t))) { - case 2: break; - case 4: flags += 1 << 6; break; - case 8: flags += 2 << 6; break; - default: flags += 3 << 6; - } -#ifdef ZLIB_DEBUG - flags += 1 << 8; -#endif -#if defined(ASMV) || defined(ASMINF) - flags += 1 << 9; -#endif -#ifdef ZLIB_WINAPI - flags += 1 << 10; -#endif -#ifdef BUILDFIXED - flags += 1 << 12; -#endif -#ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; -#endif -#ifdef NO_GZCOMPRESS - flags += 1L << 16; -#endif -#ifdef NO_GZIP - flags += 1L << 17; -#endif -#ifdef PKZIP_BUG_WORKAROUND - flags += 1L << 20; -#endif -#ifdef FASTEST - flags += 1L << 21; -#endif -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifdef NO_vsnprintf - flags += 1L << 25; -# ifdef HAS_vsprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1L << 26; -# endif -# endif -#else - flags += 1L << 24; -# ifdef NO_snprintf - flags += 1L << 25; -# ifdef HAS_sprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1L << 26; -# endif -# endif -#endif - return flags; -} - -#ifdef ZLIB_DEBUG -#include <stdlib.h> -# ifndef verbose -# define verbose 0 -# endif -int ZLIB_INTERNAL z_verbose = verbose; - -void ZLIB_INTERNAL z_error ( - char *m) -{ - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -/* exported to allow conversion of error code to string for compress() and - * uncompress() - */ -const char * ZEXPORT zError( - int err) -{ - return ERR_MSG(err); -} - -#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800 - /* The older Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. - */ - int errno = 0; -#endif - -#ifndef HAVE_MEMCPY - -void ZLIB_INTERNAL zmemcpy( - Bytef* dest, - const Bytef* source, - uInt len) -{ - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); -} - -int ZLIB_INTERNAL zmemcmp( - const Bytef* s1, - const Bytef* s2, - uInt len) -{ - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; - } - return 0; -} - -void ZLIB_INTERNAL zmemzero( - Bytef* dest, - uInt len) -{ - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); -} -#endif - -#ifndef Z_SOLO - -#ifdef SYS16BIT - -#ifdef __TURBOC__ -/* Turbo C in 16-bit mode */ - -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - voidpf buf; - ulg bsize = (ulg)items*size; - - (void)opaque; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) -{ - int n; - - (void)opaque; - - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - Assert(0, "zcfree: ptr not found"); -} - -#endif /* __TURBOC__ */ - - -#ifdef M_I86 -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) -{ - (void)opaque; - return _halloc((long)items, size); -} - -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) -{ - (void)opaque; - _hfree(ptr); -} - -#endif /* M_I86 */ - -#endif /* SYS16BIT */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); -#endif - -voidpf ZLIB_INTERNAL zcalloc ( - voidpf opaque, - unsigned items, - unsigned size) -{ - (void)opaque; - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : - (voidpf)calloc(items, size); -} - -void ZLIB_INTERNAL zcfree ( - voidpf opaque, - voidpf ptr) -{ - (void)opaque; - free(ptr); -} - -#endif /* MY_ZCALLOC */ - -#endif /* !Z_SOLO */ diff --git a/thirdparty/freetype/src/gzip/zutil.h b/thirdparty/freetype/src/gzip/zutil.h deleted file mode 100644 index 14f0f1a85e..0000000000 --- a/thirdparty/freetype/src/gzip/zutil.h +++ /dev/null @@ -1,278 +0,0 @@ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2022 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef ZUTIL_H -#define ZUTIL_H - -#ifdef HAVE_HIDDEN -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#include "zlib.h" - -#if defined(STDC) && !defined(Z_SOLO) -# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) -# include <stddef.h> -# endif -# include <string.h> -# include <stdlib.h> -#endif - -#ifndef local -# define local static -#endif -/* since "static" is used to mean two completely different things in C, we - define "local" for the non-static meaning of "static", for readability - (compile with -Dlocal if your debugger can't find static symbols) */ - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -#if !defined(Z_U8) && !defined(Z_SOLO) && defined(STDC) -# include <limits.h> -# if (ULONG_MAX == 0xffffffffffffffff) -# define Z_U8 unsigned long -# elif (ULLONG_MAX == 0xffffffffffffffff) -# define Z_U8 unsigned long long -# elif (UINT_MAX == 0xffffffffffffffff) -# define Z_U8 unsigned -# endif -#endif - -extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] - -#define ERR_RETURN(strm,err) \ - return (strm->msg = ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - - /* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - -#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) -# define OS_CODE 0x00 -# ifndef Z_SOLO -# if defined(__TURBOC__) || defined(__BORLANDC__) -# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) - /* Allow compilation with ANSI keywords only enabled */ - void _Cdecl farfree( void *block ); - void *_Cdecl farmalloc( unsigned long nbytes ); -# else -# include <alloc.h> -# endif -# else /* MSC or DJGPP */ -# include <malloc.h> -# endif -# endif -#endif - -#ifdef AMIGA -# define OS_CODE 1 -#endif - -#if defined(VAXC) || defined(VMS) -# define OS_CODE 2 -# define F_OPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -#endif - -#ifdef __370__ -# if __TARGET_LIB__ < 0x20000000 -# define OS_CODE 4 -# elif __TARGET_LIB__ < 0x40000000 -# define OS_CODE 11 -# else -# define OS_CODE 8 -# endif -#endif - -#if defined(ATARI) || defined(atarist) -# define OS_CODE 5 -#endif - -#ifdef OS2 -# define OS_CODE 6 -# if defined(M_I86) && !defined(Z_SOLO) -# include <malloc.h> -# endif -#endif - -#if defined(MACOS) || defined(TARGET_OS_MAC) -# define OS_CODE 7 -# ifndef Z_SOLO -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include <unix.h> /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -# endif -#endif - -#ifdef __acorn -# define OS_CODE 13 -#endif - -#if defined(WIN32) && !defined(__CYGWIN__) -# define OS_CODE 10 -#endif - -#ifdef _BEOS_ -# define OS_CODE 16 -#endif - -#ifdef __TOS_OS400__ -# define OS_CODE 18 -#endif - -#ifdef __APPLE__ -# define OS_CODE 19 -#endif - -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - -#if defined(__BORLANDC__) && !defined(MSDOS) - #pragma warn -8004 - #pragma warn -8008 - #pragma warn -8066 -#endif - -#ifndef Z_FREETYPE - -/* provide prototypes for these when building zlib without LFS */ -#if !defined(_WIN32) && \ - (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -#endif - -#endif /* !Z_FREETYPE */ - - /* common defaults */ - -#ifndef OS_CODE -# define OS_CODE 3 /* assume Unix */ -#endif - -#ifndef F_OPEN -# define F_OPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ - -#if defined(pyr) || defined(Z_SOLO) -# define NO_MEMCPY -#endif -#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) - /* Use our own functions for small and medium model with MSC <= 5.0. - * You may have to use the same strategy for Borland C (untested). - * The __SC__ check is for Symantec. - */ -# define NO_MEMCPY -#endif -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY -#endif -#ifdef HAVE_MEMCPY -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -# define zmemcpy _fmemcpy -# define zmemcmp _fmemcmp -# define zmemzero(dest, len) _fmemset(dest, 0, len) -# else -# define zmemcpy ft_memcpy -# define zmemcmp ft_memcmp -# define zmemzero(dest, len) ft_memset(dest, 0, len) -# endif -#else - void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); - int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); - void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); -#endif - -/* Diagnostic functions */ -#ifdef ZLIB_DEBUG -# include <stdio.h> - extern int ZLIB_INTERNAL z_verbose; - extern void ZLIB_INTERNAL z_error OF((char *m)); -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) {if (z_verbose>=0) fprintf x ;} -# define Tracev(x) {if (z_verbose>0) fprintf x ;} -# define Tracevv(x) {if (z_verbose>1) fprintf x ;} -# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} -# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - -#ifndef Z_SOLO - voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, - unsigned size)); - void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); -#endif - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -/* Reverse the bytes in a 32-bit value */ -#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) - -#endif /* ZUTIL_H */ diff --git a/thirdparty/glad/LICENSE b/thirdparty/glad/LICENSE index b6e2ca25b0..4965a6bffc 100644 --- a/thirdparty/glad/LICENSE +++ b/thirdparty/glad/LICENSE @@ -1,20 +1,63 @@ -The MIT License (MIT) - -Copyright (c) 2013-2018 David Herberth - -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. +The glad source code: + + The MIT License (MIT) + + Copyright (c) 2013-2022 David Herberth + + 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. + + +The Khronos Specifications: + + Copyright (c) 2013-2020 The Khronos Group Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +The EGL Specification and various headers: + + Copyright (c) 2007-2016 The Khronos Group Inc. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and/or associated documentation files (the + "Materials"), to deal in the Materials without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Materials, and to + permit persons to whom the Materials are 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 Materials. + + THE MATERIALS ARE 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 + MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. diff --git a/thirdparty/glad/gl.c b/thirdparty/glad/gl.c new file mode 100644 index 0000000000..6be716284c --- /dev/null +++ b/thirdparty/glad/gl.c @@ -0,0 +1,1995 @@ +/** + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <glad/gl.h> + +#ifndef GLAD_IMPL_UTIL_C_ +#define GLAD_IMPL_UTIL_C_ + +#ifdef _MSC_VER +#define GLAD_IMPL_UTIL_SSCANF sscanf_s +#else +#define GLAD_IMPL_UTIL_SSCANF sscanf +#endif + +#endif /* GLAD_IMPL_UTIL_C_ */ + +#ifdef __cplusplus +extern "C" { +#endif + + + +int GLAD_GL_VERSION_1_0 = 0; +int GLAD_GL_VERSION_1_1 = 0; +int GLAD_GL_VERSION_1_2 = 0; +int GLAD_GL_VERSION_1_3 = 0; +int GLAD_GL_VERSION_1_4 = 0; +int GLAD_GL_VERSION_1_5 = 0; +int GLAD_GL_VERSION_2_0 = 0; +int GLAD_GL_VERSION_2_1 = 0; +int GLAD_GL_VERSION_3_0 = 0; +int GLAD_GL_VERSION_3_1 = 0; +int GLAD_GL_VERSION_3_2 = 0; +int GLAD_GL_VERSION_3_3 = 0; +int GLAD_GL_ARB_debug_output = 0; +int GLAD_GL_ARB_framebuffer_object = 0; +int GLAD_GL_EXT_framebuffer_blit = 0; +int GLAD_GL_EXT_framebuffer_multisample = 0; +int GLAD_GL_EXT_framebuffer_object = 0; +int GLAD_GL_OVR_multiview = 0; +int GLAD_GL_OVR_multiview2 = 0; + + + +PFNGLACCUMPROC glad_glAccum = NULL; +PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; +PFNGLALPHAFUNCPROC glad_glAlphaFunc = NULL; +PFNGLARETEXTURESRESIDENTPROC glad_glAreTexturesResident = NULL; +PFNGLARRAYELEMENTPROC glad_glArrayElement = NULL; +PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; +PFNGLBEGINPROC glad_glBegin = NULL; +PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL; +PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL; +PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL; +PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL; +PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL; +PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL; +PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL; +PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation = NULL; +PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed = NULL; +PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL; +PFNGLBINDFRAMEBUFFEREXTPROC glad_glBindFramebufferEXT = NULL; +PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL; +PFNGLBINDRENDERBUFFEREXTPROC glad_glBindRenderbufferEXT = NULL; +PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL; +PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL; +PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL; +PFNGLBITMAPPROC glad_glBitmap = NULL; +PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; +PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL; +PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL; +PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL; +PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL; +PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL; +PFNGLBLITFRAMEBUFFEREXTPROC glad_glBlitFramebufferEXT = NULL; +PFNGLBUFFERDATAPROC glad_glBufferData = NULL; +PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL; +PFNGLCALLLISTPROC glad_glCallList = NULL; +PFNGLCALLLISTSPROC glad_glCallLists = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glad_glCheckFramebufferStatusEXT = NULL; +PFNGLCLAMPCOLORPROC glad_glClampColor = NULL; +PFNGLCLEARPROC glad_glClear = NULL; +PFNGLCLEARACCUMPROC glad_glClearAccum = NULL; +PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL; +PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL; +PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL; +PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL; +PFNGLCLEARCOLORPROC glad_glClearColor = NULL; +PFNGLCLEARDEPTHPROC glad_glClearDepth = NULL; +PFNGLCLEARINDEXPROC glad_glClearIndex = NULL; +PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL; +PFNGLCLIENTACTIVETEXTUREPROC glad_glClientActiveTexture = NULL; +PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL; +PFNGLCLIPPLANEPROC glad_glClipPlane = NULL; +PFNGLCOLOR3BPROC glad_glColor3b = NULL; +PFNGLCOLOR3BVPROC glad_glColor3bv = NULL; +PFNGLCOLOR3DPROC glad_glColor3d = NULL; +PFNGLCOLOR3DVPROC glad_glColor3dv = NULL; +PFNGLCOLOR3FPROC glad_glColor3f = NULL; +PFNGLCOLOR3FVPROC glad_glColor3fv = NULL; +PFNGLCOLOR3IPROC glad_glColor3i = NULL; +PFNGLCOLOR3IVPROC glad_glColor3iv = NULL; +PFNGLCOLOR3SPROC glad_glColor3s = NULL; +PFNGLCOLOR3SVPROC glad_glColor3sv = NULL; +PFNGLCOLOR3UBPROC glad_glColor3ub = NULL; +PFNGLCOLOR3UBVPROC glad_glColor3ubv = NULL; +PFNGLCOLOR3UIPROC glad_glColor3ui = NULL; +PFNGLCOLOR3UIVPROC glad_glColor3uiv = NULL; +PFNGLCOLOR3USPROC glad_glColor3us = NULL; +PFNGLCOLOR3USVPROC glad_glColor3usv = NULL; +PFNGLCOLOR4BPROC glad_glColor4b = NULL; +PFNGLCOLOR4BVPROC glad_glColor4bv = NULL; +PFNGLCOLOR4DPROC glad_glColor4d = NULL; +PFNGLCOLOR4DVPROC glad_glColor4dv = NULL; +PFNGLCOLOR4FPROC glad_glColor4f = NULL; +PFNGLCOLOR4FVPROC glad_glColor4fv = NULL; +PFNGLCOLOR4IPROC glad_glColor4i = NULL; +PFNGLCOLOR4IVPROC glad_glColor4iv = NULL; +PFNGLCOLOR4SPROC glad_glColor4s = NULL; +PFNGLCOLOR4SVPROC glad_glColor4sv = NULL; +PFNGLCOLOR4UBPROC glad_glColor4ub = NULL; +PFNGLCOLOR4UBVPROC glad_glColor4ubv = NULL; +PFNGLCOLOR4UIPROC glad_glColor4ui = NULL; +PFNGLCOLOR4UIVPROC glad_glColor4uiv = NULL; +PFNGLCOLOR4USPROC glad_glColor4us = NULL; +PFNGLCOLOR4USVPROC glad_glColor4usv = NULL; +PFNGLCOLORMASKPROC glad_glColorMask = NULL; +PFNGLCOLORMASKIPROC glad_glColorMaski = NULL; +PFNGLCOLORMATERIALPROC glad_glColorMaterial = NULL; +PFNGLCOLORP3UIPROC glad_glColorP3ui = NULL; +PFNGLCOLORP3UIVPROC glad_glColorP3uiv = NULL; +PFNGLCOLORP4UIPROC glad_glColorP4ui = NULL; +PFNGLCOLORP4UIVPROC glad_glColorP4uiv = NULL; +PFNGLCOLORPOINTERPROC glad_glColorPointer = NULL; +PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; +PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D = NULL; +PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; +PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL; +PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL; +PFNGLCOPYPIXELSPROC glad_glCopyPixels = NULL; +PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL; +PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; +PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL; +PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL; +PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL; +PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL; +PFNGLCREATESHADERPROC glad_glCreateShader = NULL; +PFNGLCULLFACEPROC glad_glCullFace = NULL; +PFNGLDEBUGMESSAGECALLBACKARBPROC glad_glDebugMessageCallbackARB = NULL; +PFNGLDEBUGMESSAGECONTROLARBPROC glad_glDebugMessageControlARB = NULL; +PFNGLDEBUGMESSAGEINSERTARBPROC glad_glDebugMessageInsertARB = NULL; +PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL; +PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; +PFNGLDELETEFRAMEBUFFERSEXTPROC glad_glDeleteFramebuffersEXT = NULL; +PFNGLDELETELISTSPROC glad_glDeleteLists = NULL; +PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; +PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL; +PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL; +PFNGLDELETERENDERBUFFERSEXTPROC glad_glDeleteRenderbuffersEXT = NULL; +PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL; +PFNGLDELETESHADERPROC glad_glDeleteShader = NULL; +PFNGLDELETESYNCPROC glad_glDeleteSync = NULL; +PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL; +PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL; +PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL; +PFNGLDEPTHMASKPROC glad_glDepthMask = NULL; +PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL; +PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; +PFNGLDISABLEPROC glad_glDisable = NULL; +PFNGLDISABLECLIENTSTATEPROC glad_glDisableClientState = NULL; +PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL; +PFNGLDISABLEIPROC glad_glDisablei = NULL; +PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; +PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL; +PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL; +PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL; +PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; +PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex = NULL; +PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL; +PFNGLDRAWPIXELSPROC glad_glDrawPixels = NULL; +PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL; +PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL; +PFNGLEDGEFLAGPROC glad_glEdgeFlag = NULL; +PFNGLEDGEFLAGPOINTERPROC glad_glEdgeFlagPointer = NULL; +PFNGLEDGEFLAGVPROC glad_glEdgeFlagv = NULL; +PFNGLENABLEPROC glad_glEnable = NULL; +PFNGLENABLECLIENTSTATEPROC glad_glEnableClientState = NULL; +PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; +PFNGLENABLEIPROC glad_glEnablei = NULL; +PFNGLENDPROC glad_glEnd = NULL; +PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL; +PFNGLENDLISTPROC glad_glEndList = NULL; +PFNGLENDQUERYPROC glad_glEndQuery = NULL; +PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL; +PFNGLEVALCOORD1DPROC glad_glEvalCoord1d = NULL; +PFNGLEVALCOORD1DVPROC glad_glEvalCoord1dv = NULL; +PFNGLEVALCOORD1FPROC glad_glEvalCoord1f = NULL; +PFNGLEVALCOORD1FVPROC glad_glEvalCoord1fv = NULL; +PFNGLEVALCOORD2DPROC glad_glEvalCoord2d = NULL; +PFNGLEVALCOORD2DVPROC glad_glEvalCoord2dv = NULL; +PFNGLEVALCOORD2FPROC glad_glEvalCoord2f = NULL; +PFNGLEVALCOORD2FVPROC glad_glEvalCoord2fv = NULL; +PFNGLEVALMESH1PROC glad_glEvalMesh1 = NULL; +PFNGLEVALMESH2PROC glad_glEvalMesh2 = NULL; +PFNGLEVALPOINT1PROC glad_glEvalPoint1 = NULL; +PFNGLEVALPOINT2PROC glad_glEvalPoint2 = NULL; +PFNGLFEEDBACKBUFFERPROC glad_glFeedbackBuffer = NULL; +PFNGLFENCESYNCPROC glad_glFenceSync = NULL; +PFNGLFINISHPROC glad_glFinish = NULL; +PFNGLFLUSHPROC glad_glFlush = NULL; +PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL; +PFNGLFOGCOORDPOINTERPROC glad_glFogCoordPointer = NULL; +PFNGLFOGCOORDDPROC glad_glFogCoordd = NULL; +PFNGLFOGCOORDDVPROC glad_glFogCoorddv = NULL; +PFNGLFOGCOORDFPROC glad_glFogCoordf = NULL; +PFNGLFOGCOORDFVPROC glad_glFogCoordfv = NULL; +PFNGLFOGFPROC glad_glFogf = NULL; +PFNGLFOGFVPROC glad_glFogfv = NULL; +PFNGLFOGIPROC glad_glFogi = NULL; +PFNGLFOGIVPROC glad_glFogiv = NULL; +PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; +PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glad_glFramebufferRenderbufferEXT = NULL; +PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture = NULL; +PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D = NULL; +PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glad_glFramebufferTexture1DEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; +PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glad_glFramebufferTexture2DEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D = NULL; +PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glad_glFramebufferTexture3DEXT = NULL; +PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL; +PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glad_glFramebufferTextureMultiviewOVR = NULL; +PFNGLFRONTFACEPROC glad_glFrontFace = NULL; +PFNGLFRUSTUMPROC glad_glFrustum = NULL; +PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; +PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; +PFNGLGENFRAMEBUFFERSEXTPROC glad_glGenFramebuffersEXT = NULL; +PFNGLGENLISTSPROC glad_glGenLists = NULL; +PFNGLGENQUERIESPROC glad_glGenQueries = NULL; +PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; +PFNGLGENRENDERBUFFERSEXTPROC glad_glGenRenderbuffersEXT = NULL; +PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL; +PFNGLGENTEXTURESPROC glad_glGenTextures = NULL; +PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL; +PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL; +PFNGLGENERATEMIPMAPEXTPROC glad_glGenerateMipmapEXT = NULL; +PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL; +PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL; +PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL; +PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL; +PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName = NULL; +PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL; +PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL; +PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL; +PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL; +PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL; +PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL; +PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; +PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL; +PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData = NULL; +PFNGLGETCLIPPLANEPROC glad_glGetClipPlane = NULL; +PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage = NULL; +PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB = NULL; +PFNGLGETDOUBLEVPROC glad_glGetDoublev = NULL; +PFNGLGETERRORPROC glad_glGetError = NULL; +PFNGLGETFLOATVPROC glad_glGetFloatv = NULL; +PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex = NULL; +PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetFramebufferAttachmentParameterivEXT = NULL; +PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL; +PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL; +PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL; +PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; +PFNGLGETLIGHTFVPROC glad_glGetLightfv = NULL; +PFNGLGETLIGHTIVPROC glad_glGetLightiv = NULL; +PFNGLGETMAPDVPROC glad_glGetMapdv = NULL; +PFNGLGETMAPFVPROC glad_glGetMapfv = NULL; +PFNGLGETMAPIVPROC glad_glGetMapiv = NULL; +PFNGLGETMATERIALFVPROC glad_glGetMaterialfv = NULL; +PFNGLGETMATERIALIVPROC glad_glGetMaterialiv = NULL; +PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL; +PFNGLGETPIXELMAPFVPROC glad_glGetPixelMapfv = NULL; +PFNGLGETPIXELMAPUIVPROC glad_glGetPixelMapuiv = NULL; +PFNGLGETPIXELMAPUSVPROC glad_glGetPixelMapusv = NULL; +PFNGLGETPOINTERVPROC glad_glGetPointerv = NULL; +PFNGLGETPOLYGONSTIPPLEPROC glad_glGetPolygonStipple = NULL; +PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; +PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL; +PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v = NULL; +PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv = NULL; +PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v = NULL; +PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL; +PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glad_glGetRenderbufferParameterivEXT = NULL; +PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv = NULL; +PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv = NULL; +PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL; +PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL; +PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL; +PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL; +PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL; +PFNGLGETSTRINGPROC glad_glGetString = NULL; +PFNGLGETSTRINGIPROC glad_glGetStringi = NULL; +PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL; +PFNGLGETTEXENVFVPROC glad_glGetTexEnvfv = NULL; +PFNGLGETTEXENVIVPROC glad_glGetTexEnviv = NULL; +PFNGLGETTEXGENDVPROC glad_glGetTexGendv = NULL; +PFNGLGETTEXGENFVPROC glad_glGetTexGenfv = NULL; +PFNGLGETTEXGENIVPROC glad_glGetTexGeniv = NULL; +PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL; +PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL; +PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL; +PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv = NULL; +PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv = NULL; +PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL; +PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL; +PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL; +PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL; +PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL; +PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL; +PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL; +PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL; +PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL; +PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL; +PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL; +PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv = NULL; +PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL; +PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL; +PFNGLHINTPROC glad_glHint = NULL; +PFNGLINDEXMASKPROC glad_glIndexMask = NULL; +PFNGLINDEXPOINTERPROC glad_glIndexPointer = NULL; +PFNGLINDEXDPROC glad_glIndexd = NULL; +PFNGLINDEXDVPROC glad_glIndexdv = NULL; +PFNGLINDEXFPROC glad_glIndexf = NULL; +PFNGLINDEXFVPROC glad_glIndexfv = NULL; +PFNGLINDEXIPROC glad_glIndexi = NULL; +PFNGLINDEXIVPROC glad_glIndexiv = NULL; +PFNGLINDEXSPROC glad_glIndexs = NULL; +PFNGLINDEXSVPROC glad_glIndexsv = NULL; +PFNGLINDEXUBPROC glad_glIndexub = NULL; +PFNGLINDEXUBVPROC glad_glIndexubv = NULL; +PFNGLINITNAMESPROC glad_glInitNames = NULL; +PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays = NULL; +PFNGLISBUFFERPROC glad_glIsBuffer = NULL; +PFNGLISENABLEDPROC glad_glIsEnabled = NULL; +PFNGLISENABLEDIPROC glad_glIsEnabledi = NULL; +PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; +PFNGLISFRAMEBUFFEREXTPROC glad_glIsFramebufferEXT = NULL; +PFNGLISLISTPROC glad_glIsList = NULL; +PFNGLISPROGRAMPROC glad_glIsProgram = NULL; +PFNGLISQUERYPROC glad_glIsQuery = NULL; +PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL; +PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbufferEXT = NULL; +PFNGLISSAMPLERPROC glad_glIsSampler = NULL; +PFNGLISSHADERPROC glad_glIsShader = NULL; +PFNGLISSYNCPROC glad_glIsSync = NULL; +PFNGLISTEXTUREPROC glad_glIsTexture = NULL; +PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL; +PFNGLLIGHTMODELFPROC glad_glLightModelf = NULL; +PFNGLLIGHTMODELFVPROC glad_glLightModelfv = NULL; +PFNGLLIGHTMODELIPROC glad_glLightModeli = NULL; +PFNGLLIGHTMODELIVPROC glad_glLightModeliv = NULL; +PFNGLLIGHTFPROC glad_glLightf = NULL; +PFNGLLIGHTFVPROC glad_glLightfv = NULL; +PFNGLLIGHTIPROC glad_glLighti = NULL; +PFNGLLIGHTIVPROC glad_glLightiv = NULL; +PFNGLLINESTIPPLEPROC glad_glLineStipple = NULL; +PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; +PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL; +PFNGLLISTBASEPROC glad_glListBase = NULL; +PFNGLLOADIDENTITYPROC glad_glLoadIdentity = NULL; +PFNGLLOADMATRIXDPROC glad_glLoadMatrixd = NULL; +PFNGLLOADMATRIXFPROC glad_glLoadMatrixf = NULL; +PFNGLLOADNAMEPROC glad_glLoadName = NULL; +PFNGLLOADTRANSPOSEMATRIXDPROC glad_glLoadTransposeMatrixd = NULL; +PFNGLLOADTRANSPOSEMATRIXFPROC glad_glLoadTransposeMatrixf = NULL; +PFNGLLOGICOPPROC glad_glLogicOp = NULL; +PFNGLMAP1DPROC glad_glMap1d = NULL; +PFNGLMAP1FPROC glad_glMap1f = NULL; +PFNGLMAP2DPROC glad_glMap2d = NULL; +PFNGLMAP2FPROC glad_glMap2f = NULL; +PFNGLMAPBUFFERPROC glad_glMapBuffer = NULL; +PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL; +PFNGLMAPGRID1DPROC glad_glMapGrid1d = NULL; +PFNGLMAPGRID1FPROC glad_glMapGrid1f = NULL; +PFNGLMAPGRID2DPROC glad_glMapGrid2d = NULL; +PFNGLMAPGRID2FPROC glad_glMapGrid2f = NULL; +PFNGLMATERIALFPROC glad_glMaterialf = NULL; +PFNGLMATERIALFVPROC glad_glMaterialfv = NULL; +PFNGLMATERIALIPROC glad_glMateriali = NULL; +PFNGLMATERIALIVPROC glad_glMaterialiv = NULL; +PFNGLMATRIXMODEPROC glad_glMatrixMode = NULL; +PFNGLMULTMATRIXDPROC glad_glMultMatrixd = NULL; +PFNGLMULTMATRIXFPROC glad_glMultMatrixf = NULL; +PFNGLMULTTRANSPOSEMATRIXDPROC glad_glMultTransposeMatrixd = NULL; +PFNGLMULTTRANSPOSEMATRIXFPROC glad_glMultTransposeMatrixf = NULL; +PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL; +PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL; +PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex = NULL; +PFNGLMULTITEXCOORD1DPROC glad_glMultiTexCoord1d = NULL; +PFNGLMULTITEXCOORD1DVPROC glad_glMultiTexCoord1dv = NULL; +PFNGLMULTITEXCOORD1FPROC glad_glMultiTexCoord1f = NULL; +PFNGLMULTITEXCOORD1FVPROC glad_glMultiTexCoord1fv = NULL; +PFNGLMULTITEXCOORD1IPROC glad_glMultiTexCoord1i = NULL; +PFNGLMULTITEXCOORD1IVPROC glad_glMultiTexCoord1iv = NULL; +PFNGLMULTITEXCOORD1SPROC glad_glMultiTexCoord1s = NULL; +PFNGLMULTITEXCOORD1SVPROC glad_glMultiTexCoord1sv = NULL; +PFNGLMULTITEXCOORD2DPROC glad_glMultiTexCoord2d = NULL; +PFNGLMULTITEXCOORD2DVPROC glad_glMultiTexCoord2dv = NULL; +PFNGLMULTITEXCOORD2FPROC glad_glMultiTexCoord2f = NULL; +PFNGLMULTITEXCOORD2FVPROC glad_glMultiTexCoord2fv = NULL; +PFNGLMULTITEXCOORD2IPROC glad_glMultiTexCoord2i = NULL; +PFNGLMULTITEXCOORD2IVPROC glad_glMultiTexCoord2iv = NULL; +PFNGLMULTITEXCOORD2SPROC glad_glMultiTexCoord2s = NULL; +PFNGLMULTITEXCOORD2SVPROC glad_glMultiTexCoord2sv = NULL; +PFNGLMULTITEXCOORD3DPROC glad_glMultiTexCoord3d = NULL; +PFNGLMULTITEXCOORD3DVPROC glad_glMultiTexCoord3dv = NULL; +PFNGLMULTITEXCOORD3FPROC glad_glMultiTexCoord3f = NULL; +PFNGLMULTITEXCOORD3FVPROC glad_glMultiTexCoord3fv = NULL; +PFNGLMULTITEXCOORD3IPROC glad_glMultiTexCoord3i = NULL; +PFNGLMULTITEXCOORD3IVPROC glad_glMultiTexCoord3iv = NULL; +PFNGLMULTITEXCOORD3SPROC glad_glMultiTexCoord3s = NULL; +PFNGLMULTITEXCOORD3SVPROC glad_glMultiTexCoord3sv = NULL; +PFNGLMULTITEXCOORD4DPROC glad_glMultiTexCoord4d = NULL; +PFNGLMULTITEXCOORD4DVPROC glad_glMultiTexCoord4dv = NULL; +PFNGLMULTITEXCOORD4FPROC glad_glMultiTexCoord4f = NULL; +PFNGLMULTITEXCOORD4FVPROC glad_glMultiTexCoord4fv = NULL; +PFNGLMULTITEXCOORD4IPROC glad_glMultiTexCoord4i = NULL; +PFNGLMULTITEXCOORD4IVPROC glad_glMultiTexCoord4iv = NULL; +PFNGLMULTITEXCOORD4SPROC glad_glMultiTexCoord4s = NULL; +PFNGLMULTITEXCOORD4SVPROC glad_glMultiTexCoord4sv = NULL; +PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui = NULL; +PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv = NULL; +PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui = NULL; +PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv = NULL; +PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui = NULL; +PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv = NULL; +PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui = NULL; +PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv = NULL; +PFNGLNEWLISTPROC glad_glNewList = NULL; +PFNGLNORMAL3BPROC glad_glNormal3b = NULL; +PFNGLNORMAL3BVPROC glad_glNormal3bv = NULL; +PFNGLNORMAL3DPROC glad_glNormal3d = NULL; +PFNGLNORMAL3DVPROC glad_glNormal3dv = NULL; +PFNGLNORMAL3FPROC glad_glNormal3f = NULL; +PFNGLNORMAL3FVPROC glad_glNormal3fv = NULL; +PFNGLNORMAL3IPROC glad_glNormal3i = NULL; +PFNGLNORMAL3IVPROC glad_glNormal3iv = NULL; +PFNGLNORMAL3SPROC glad_glNormal3s = NULL; +PFNGLNORMAL3SVPROC glad_glNormal3sv = NULL; +PFNGLNORMALP3UIPROC glad_glNormalP3ui = NULL; +PFNGLNORMALP3UIVPROC glad_glNormalP3uiv = NULL; +PFNGLNORMALPOINTERPROC glad_glNormalPointer = NULL; +PFNGLORTHOPROC glad_glOrtho = NULL; +PFNGLPASSTHROUGHPROC glad_glPassThrough = NULL; +PFNGLPIXELMAPFVPROC glad_glPixelMapfv = NULL; +PFNGLPIXELMAPUIVPROC glad_glPixelMapuiv = NULL; +PFNGLPIXELMAPUSVPROC glad_glPixelMapusv = NULL; +PFNGLPIXELSTOREFPROC glad_glPixelStoref = NULL; +PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; +PFNGLPIXELTRANSFERFPROC glad_glPixelTransferf = NULL; +PFNGLPIXELTRANSFERIPROC glad_glPixelTransferi = NULL; +PFNGLPIXELZOOMPROC glad_glPixelZoom = NULL; +PFNGLPOINTPARAMETERFPROC glad_glPointParameterf = NULL; +PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv = NULL; +PFNGLPOINTPARAMETERIPROC glad_glPointParameteri = NULL; +PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv = NULL; +PFNGLPOINTSIZEPROC glad_glPointSize = NULL; +PFNGLPOLYGONMODEPROC glad_glPolygonMode = NULL; +PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; +PFNGLPOLYGONSTIPPLEPROC glad_glPolygonStipple = NULL; +PFNGLPOPATTRIBPROC glad_glPopAttrib = NULL; +PFNGLPOPCLIENTATTRIBPROC glad_glPopClientAttrib = NULL; +PFNGLPOPMATRIXPROC glad_glPopMatrix = NULL; +PFNGLPOPNAMEPROC glad_glPopName = NULL; +PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex = NULL; +PFNGLPRIORITIZETEXTURESPROC glad_glPrioritizeTextures = NULL; +PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex = NULL; +PFNGLPUSHATTRIBPROC glad_glPushAttrib = NULL; +PFNGLPUSHCLIENTATTRIBPROC glad_glPushClientAttrib = NULL; +PFNGLPUSHMATRIXPROC glad_glPushMatrix = NULL; +PFNGLPUSHNAMEPROC glad_glPushName = NULL; +PFNGLQUERYCOUNTERPROC glad_glQueryCounter = NULL; +PFNGLRASTERPOS2DPROC glad_glRasterPos2d = NULL; +PFNGLRASTERPOS2DVPROC glad_glRasterPos2dv = NULL; +PFNGLRASTERPOS2FPROC glad_glRasterPos2f = NULL; +PFNGLRASTERPOS2FVPROC glad_glRasterPos2fv = NULL; +PFNGLRASTERPOS2IPROC glad_glRasterPos2i = NULL; +PFNGLRASTERPOS2IVPROC glad_glRasterPos2iv = NULL; +PFNGLRASTERPOS2SPROC glad_glRasterPos2s = NULL; +PFNGLRASTERPOS2SVPROC glad_glRasterPos2sv = NULL; +PFNGLRASTERPOS3DPROC glad_glRasterPos3d = NULL; +PFNGLRASTERPOS3DVPROC glad_glRasterPos3dv = NULL; +PFNGLRASTERPOS3FPROC glad_glRasterPos3f = NULL; +PFNGLRASTERPOS3FVPROC glad_glRasterPos3fv = NULL; +PFNGLRASTERPOS3IPROC glad_glRasterPos3i = NULL; +PFNGLRASTERPOS3IVPROC glad_glRasterPos3iv = NULL; +PFNGLRASTERPOS3SPROC glad_glRasterPos3s = NULL; +PFNGLRASTERPOS3SVPROC glad_glRasterPos3sv = NULL; +PFNGLRASTERPOS4DPROC glad_glRasterPos4d = NULL; +PFNGLRASTERPOS4DVPROC glad_glRasterPos4dv = NULL; +PFNGLRASTERPOS4FPROC glad_glRasterPos4f = NULL; +PFNGLRASTERPOS4FVPROC glad_glRasterPos4fv = NULL; +PFNGLRASTERPOS4IPROC glad_glRasterPos4i = NULL; +PFNGLRASTERPOS4IVPROC glad_glRasterPos4iv = NULL; +PFNGLRASTERPOS4SPROC glad_glRasterPos4s = NULL; +PFNGLRASTERPOS4SVPROC glad_glRasterPos4sv = NULL; +PFNGLREADBUFFERPROC glad_glReadBuffer = NULL; +PFNGLREADPIXELSPROC glad_glReadPixels = NULL; +PFNGLRECTDPROC glad_glRectd = NULL; +PFNGLRECTDVPROC glad_glRectdv = NULL; +PFNGLRECTFPROC glad_glRectf = NULL; +PFNGLRECTFVPROC glad_glRectfv = NULL; +PFNGLRECTIPROC glad_glRecti = NULL; +PFNGLRECTIVPROC glad_glRectiv = NULL; +PFNGLRECTSPROC glad_glRects = NULL; +PFNGLRECTSVPROC glad_glRectsv = NULL; +PFNGLRENDERMODEPROC glad_glRenderMode = NULL; +PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; +PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT = NULL; +PFNGLROTATEDPROC glad_glRotated = NULL; +PFNGLROTATEFPROC glad_glRotatef = NULL; +PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; +PFNGLSAMPLEMASKIPROC glad_glSampleMaski = NULL; +PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv = NULL; +PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv = NULL; +PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL; +PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL; +PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL; +PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = NULL; +PFNGLSCALEDPROC glad_glScaled = NULL; +PFNGLSCALEFPROC glad_glScalef = NULL; +PFNGLSCISSORPROC glad_glScissor = NULL; +PFNGLSECONDARYCOLOR3BPROC glad_glSecondaryColor3b = NULL; +PFNGLSECONDARYCOLOR3BVPROC glad_glSecondaryColor3bv = NULL; +PFNGLSECONDARYCOLOR3DPROC glad_glSecondaryColor3d = NULL; +PFNGLSECONDARYCOLOR3DVPROC glad_glSecondaryColor3dv = NULL; +PFNGLSECONDARYCOLOR3FPROC glad_glSecondaryColor3f = NULL; +PFNGLSECONDARYCOLOR3FVPROC glad_glSecondaryColor3fv = NULL; +PFNGLSECONDARYCOLOR3IPROC glad_glSecondaryColor3i = NULL; +PFNGLSECONDARYCOLOR3IVPROC glad_glSecondaryColor3iv = NULL; +PFNGLSECONDARYCOLOR3SPROC glad_glSecondaryColor3s = NULL; +PFNGLSECONDARYCOLOR3SVPROC glad_glSecondaryColor3sv = NULL; +PFNGLSECONDARYCOLOR3UBPROC glad_glSecondaryColor3ub = NULL; +PFNGLSECONDARYCOLOR3UBVPROC glad_glSecondaryColor3ubv = NULL; +PFNGLSECONDARYCOLOR3UIPROC glad_glSecondaryColor3ui = NULL; +PFNGLSECONDARYCOLOR3UIVPROC glad_glSecondaryColor3uiv = NULL; +PFNGLSECONDARYCOLOR3USPROC glad_glSecondaryColor3us = NULL; +PFNGLSECONDARYCOLOR3USVPROC glad_glSecondaryColor3usv = NULL; +PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui = NULL; +PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv = NULL; +PFNGLSECONDARYCOLORPOINTERPROC glad_glSecondaryColorPointer = NULL; +PFNGLSELECTBUFFERPROC glad_glSelectBuffer = NULL; +PFNGLSHADEMODELPROC glad_glShadeModel = NULL; +PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL; +PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL; +PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL; +PFNGLSTENCILMASKPROC glad_glStencilMask = NULL; +PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL; +PFNGLSTENCILOPPROC glad_glStencilOp = NULL; +PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL; +PFNGLTEXBUFFERPROC glad_glTexBuffer = NULL; +PFNGLTEXCOORD1DPROC glad_glTexCoord1d = NULL; +PFNGLTEXCOORD1DVPROC glad_glTexCoord1dv = NULL; +PFNGLTEXCOORD1FPROC glad_glTexCoord1f = NULL; +PFNGLTEXCOORD1FVPROC glad_glTexCoord1fv = NULL; +PFNGLTEXCOORD1IPROC glad_glTexCoord1i = NULL; +PFNGLTEXCOORD1IVPROC glad_glTexCoord1iv = NULL; +PFNGLTEXCOORD1SPROC glad_glTexCoord1s = NULL; +PFNGLTEXCOORD1SVPROC glad_glTexCoord1sv = NULL; +PFNGLTEXCOORD2DPROC glad_glTexCoord2d = NULL; +PFNGLTEXCOORD2DVPROC glad_glTexCoord2dv = NULL; +PFNGLTEXCOORD2FPROC glad_glTexCoord2f = NULL; +PFNGLTEXCOORD2FVPROC glad_glTexCoord2fv = NULL; +PFNGLTEXCOORD2IPROC glad_glTexCoord2i = NULL; +PFNGLTEXCOORD2IVPROC glad_glTexCoord2iv = NULL; +PFNGLTEXCOORD2SPROC glad_glTexCoord2s = NULL; +PFNGLTEXCOORD2SVPROC glad_glTexCoord2sv = NULL; +PFNGLTEXCOORD3DPROC glad_glTexCoord3d = NULL; +PFNGLTEXCOORD3DVPROC glad_glTexCoord3dv = NULL; +PFNGLTEXCOORD3FPROC glad_glTexCoord3f = NULL; +PFNGLTEXCOORD3FVPROC glad_glTexCoord3fv = NULL; +PFNGLTEXCOORD3IPROC glad_glTexCoord3i = NULL; +PFNGLTEXCOORD3IVPROC glad_glTexCoord3iv = NULL; +PFNGLTEXCOORD3SPROC glad_glTexCoord3s = NULL; +PFNGLTEXCOORD3SVPROC glad_glTexCoord3sv = NULL; +PFNGLTEXCOORD4DPROC glad_glTexCoord4d = NULL; +PFNGLTEXCOORD4DVPROC glad_glTexCoord4dv = NULL; +PFNGLTEXCOORD4FPROC glad_glTexCoord4f = NULL; +PFNGLTEXCOORD4FVPROC glad_glTexCoord4fv = NULL; +PFNGLTEXCOORD4IPROC glad_glTexCoord4i = NULL; +PFNGLTEXCOORD4IVPROC glad_glTexCoord4iv = NULL; +PFNGLTEXCOORD4SPROC glad_glTexCoord4s = NULL; +PFNGLTEXCOORD4SVPROC glad_glTexCoord4sv = NULL; +PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui = NULL; +PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv = NULL; +PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui = NULL; +PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv = NULL; +PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui = NULL; +PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv = NULL; +PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui = NULL; +PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv = NULL; +PFNGLTEXCOORDPOINTERPROC glad_glTexCoordPointer = NULL; +PFNGLTEXENVFPROC glad_glTexEnvf = NULL; +PFNGLTEXENVFVPROC glad_glTexEnvfv = NULL; +PFNGLTEXENVIPROC glad_glTexEnvi = NULL; +PFNGLTEXENVIVPROC glad_glTexEnviv = NULL; +PFNGLTEXGENDPROC glad_glTexGend = NULL; +PFNGLTEXGENDVPROC glad_glTexGendv = NULL; +PFNGLTEXGENFPROC glad_glTexGenf = NULL; +PFNGLTEXGENFVPROC glad_glTexGenfv = NULL; +PFNGLTEXGENIPROC glad_glTexGeni = NULL; +PFNGLTEXGENIVPROC glad_glTexGeniv = NULL; +PFNGLTEXIMAGE1DPROC glad_glTexImage1D = NULL; +PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL; +PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample = NULL; +PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL; +PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample = NULL; +PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv = NULL; +PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv = NULL; +PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL; +PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL; +PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL; +PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL; +PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D = NULL; +PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL; +PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL; +PFNGLTRANSLATEDPROC glad_glTranslated = NULL; +PFNGLTRANSLATEFPROC glad_glTranslatef = NULL; +PFNGLUNIFORM1FPROC glad_glUniform1f = NULL; +PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL; +PFNGLUNIFORM1IPROC glad_glUniform1i = NULL; +PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL; +PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL; +PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL; +PFNGLUNIFORM2FPROC glad_glUniform2f = NULL; +PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL; +PFNGLUNIFORM2IPROC glad_glUniform2i = NULL; +PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL; +PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL; +PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL; +PFNGLUNIFORM3FPROC glad_glUniform3f = NULL; +PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL; +PFNGLUNIFORM3IPROC glad_glUniform3i = NULL; +PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL; +PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL; +PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL; +PFNGLUNIFORM4FPROC glad_glUniform4f = NULL; +PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL; +PFNGLUNIFORM4IPROC glad_glUniform4i = NULL; +PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL; +PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL; +PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL; +PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL; +PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL; +PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL; +PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL; +PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL; +PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL; +PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL; +PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL; +PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL; +PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL; +PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL; +PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL; +PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL; +PFNGLVERTEX2DPROC glad_glVertex2d = NULL; +PFNGLVERTEX2DVPROC glad_glVertex2dv = NULL; +PFNGLVERTEX2FPROC glad_glVertex2f = NULL; +PFNGLVERTEX2FVPROC glad_glVertex2fv = NULL; +PFNGLVERTEX2IPROC glad_glVertex2i = NULL; +PFNGLVERTEX2IVPROC glad_glVertex2iv = NULL; +PFNGLVERTEX2SPROC glad_glVertex2s = NULL; +PFNGLVERTEX2SVPROC glad_glVertex2sv = NULL; +PFNGLVERTEX3DPROC glad_glVertex3d = NULL; +PFNGLVERTEX3DVPROC glad_glVertex3dv = NULL; +PFNGLVERTEX3FPROC glad_glVertex3f = NULL; +PFNGLVERTEX3FVPROC glad_glVertex3fv = NULL; +PFNGLVERTEX3IPROC glad_glVertex3i = NULL; +PFNGLVERTEX3IVPROC glad_glVertex3iv = NULL; +PFNGLVERTEX3SPROC glad_glVertex3s = NULL; +PFNGLVERTEX3SVPROC glad_glVertex3sv = NULL; +PFNGLVERTEX4DPROC glad_glVertex4d = NULL; +PFNGLVERTEX4DVPROC glad_glVertex4dv = NULL; +PFNGLVERTEX4FPROC glad_glVertex4f = NULL; +PFNGLVERTEX4FVPROC glad_glVertex4fv = NULL; +PFNGLVERTEX4IPROC glad_glVertex4i = NULL; +PFNGLVERTEX4IVPROC glad_glVertex4iv = NULL; +PFNGLVERTEX4SPROC glad_glVertex4s = NULL; +PFNGLVERTEX4SVPROC glad_glVertex4sv = NULL; +PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d = NULL; +PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv = NULL; +PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL; +PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL; +PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s = NULL; +PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv = NULL; +PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d = NULL; +PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv = NULL; +PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL; +PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL; +PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s = NULL; +PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv = NULL; +PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d = NULL; +PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv = NULL; +PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL; +PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL; +PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s = NULL; +PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv = NULL; +PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv = NULL; +PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv = NULL; +PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv = NULL; +PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub = NULL; +PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv = NULL; +PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv = NULL; +PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv = NULL; +PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv = NULL; +PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d = NULL; +PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv = NULL; +PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL; +PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL; +PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv = NULL; +PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s = NULL; +PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv = NULL; +PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv = NULL; +PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv = NULL; +PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv = NULL; +PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL; +PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i = NULL; +PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv = NULL; +PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui = NULL; +PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv = NULL; +PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i = NULL; +PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv = NULL; +PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui = NULL; +PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv = NULL; +PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i = NULL; +PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv = NULL; +PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui = NULL; +PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv = NULL; +PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv = NULL; +PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL; +PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL; +PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv = NULL; +PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv = NULL; +PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL; +PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL; +PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv = NULL; +PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL; +PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui = NULL; +PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv = NULL; +PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui = NULL; +PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv = NULL; +PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui = NULL; +PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv = NULL; +PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui = NULL; +PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv = NULL; +PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL; +PFNGLVERTEXP2UIPROC glad_glVertexP2ui = NULL; +PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv = NULL; +PFNGLVERTEXP3UIPROC glad_glVertexP3ui = NULL; +PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv = NULL; +PFNGLVERTEXP4UIPROC glad_glVertexP4ui = NULL; +PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv = NULL; +PFNGLVERTEXPOINTERPROC glad_glVertexPointer = NULL; +PFNGLVIEWPORTPROC glad_glViewport = NULL; +PFNGLWAITSYNCPROC glad_glWaitSync = NULL; +PFNGLWINDOWPOS2DPROC glad_glWindowPos2d = NULL; +PFNGLWINDOWPOS2DVPROC glad_glWindowPos2dv = NULL; +PFNGLWINDOWPOS2FPROC glad_glWindowPos2f = NULL; +PFNGLWINDOWPOS2FVPROC glad_glWindowPos2fv = NULL; +PFNGLWINDOWPOS2IPROC glad_glWindowPos2i = NULL; +PFNGLWINDOWPOS2IVPROC glad_glWindowPos2iv = NULL; +PFNGLWINDOWPOS2SPROC glad_glWindowPos2s = NULL; +PFNGLWINDOWPOS2SVPROC glad_glWindowPos2sv = NULL; +PFNGLWINDOWPOS3DPROC glad_glWindowPos3d = NULL; +PFNGLWINDOWPOS3DVPROC glad_glWindowPos3dv = NULL; +PFNGLWINDOWPOS3FPROC glad_glWindowPos3f = NULL; +PFNGLWINDOWPOS3FVPROC glad_glWindowPos3fv = NULL; +PFNGLWINDOWPOS3IPROC glad_glWindowPos3i = NULL; +PFNGLWINDOWPOS3IVPROC glad_glWindowPos3iv = NULL; +PFNGLWINDOWPOS3SPROC glad_glWindowPos3s = NULL; +PFNGLWINDOWPOS3SVPROC glad_glWindowPos3sv = NULL; + + +static void glad_gl_load_GL_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_1_0) return; + glad_glAccum = (PFNGLACCUMPROC) load(userptr, "glAccum"); + glad_glAlphaFunc = (PFNGLALPHAFUNCPROC) load(userptr, "glAlphaFunc"); + glad_glBegin = (PFNGLBEGINPROC) load(userptr, "glBegin"); + glad_glBitmap = (PFNGLBITMAPPROC) load(userptr, "glBitmap"); + glad_glBlendFunc = (PFNGLBLENDFUNCPROC) load(userptr, "glBlendFunc"); + glad_glCallList = (PFNGLCALLLISTPROC) load(userptr, "glCallList"); + glad_glCallLists = (PFNGLCALLLISTSPROC) load(userptr, "glCallLists"); + glad_glClear = (PFNGLCLEARPROC) load(userptr, "glClear"); + glad_glClearAccum = (PFNGLCLEARACCUMPROC) load(userptr, "glClearAccum"); + glad_glClearColor = (PFNGLCLEARCOLORPROC) load(userptr, "glClearColor"); + glad_glClearDepth = (PFNGLCLEARDEPTHPROC) load(userptr, "glClearDepth"); + glad_glClearIndex = (PFNGLCLEARINDEXPROC) load(userptr, "glClearIndex"); + glad_glClearStencil = (PFNGLCLEARSTENCILPROC) load(userptr, "glClearStencil"); + glad_glClipPlane = (PFNGLCLIPPLANEPROC) load(userptr, "glClipPlane"); + glad_glColor3b = (PFNGLCOLOR3BPROC) load(userptr, "glColor3b"); + glad_glColor3bv = (PFNGLCOLOR3BVPROC) load(userptr, "glColor3bv"); + glad_glColor3d = (PFNGLCOLOR3DPROC) load(userptr, "glColor3d"); + glad_glColor3dv = (PFNGLCOLOR3DVPROC) load(userptr, "glColor3dv"); + glad_glColor3f = (PFNGLCOLOR3FPROC) load(userptr, "glColor3f"); + glad_glColor3fv = (PFNGLCOLOR3FVPROC) load(userptr, "glColor3fv"); + glad_glColor3i = (PFNGLCOLOR3IPROC) load(userptr, "glColor3i"); + glad_glColor3iv = (PFNGLCOLOR3IVPROC) load(userptr, "glColor3iv"); + glad_glColor3s = (PFNGLCOLOR3SPROC) load(userptr, "glColor3s"); + glad_glColor3sv = (PFNGLCOLOR3SVPROC) load(userptr, "glColor3sv"); + glad_glColor3ub = (PFNGLCOLOR3UBPROC) load(userptr, "glColor3ub"); + glad_glColor3ubv = (PFNGLCOLOR3UBVPROC) load(userptr, "glColor3ubv"); + glad_glColor3ui = (PFNGLCOLOR3UIPROC) load(userptr, "glColor3ui"); + glad_glColor3uiv = (PFNGLCOLOR3UIVPROC) load(userptr, "glColor3uiv"); + glad_glColor3us = (PFNGLCOLOR3USPROC) load(userptr, "glColor3us"); + glad_glColor3usv = (PFNGLCOLOR3USVPROC) load(userptr, "glColor3usv"); + glad_glColor4b = (PFNGLCOLOR4BPROC) load(userptr, "glColor4b"); + glad_glColor4bv = (PFNGLCOLOR4BVPROC) load(userptr, "glColor4bv"); + glad_glColor4d = (PFNGLCOLOR4DPROC) load(userptr, "glColor4d"); + glad_glColor4dv = (PFNGLCOLOR4DVPROC) load(userptr, "glColor4dv"); + glad_glColor4f = (PFNGLCOLOR4FPROC) load(userptr, "glColor4f"); + glad_glColor4fv = (PFNGLCOLOR4FVPROC) load(userptr, "glColor4fv"); + glad_glColor4i = (PFNGLCOLOR4IPROC) load(userptr, "glColor4i"); + glad_glColor4iv = (PFNGLCOLOR4IVPROC) load(userptr, "glColor4iv"); + glad_glColor4s = (PFNGLCOLOR4SPROC) load(userptr, "glColor4s"); + glad_glColor4sv = (PFNGLCOLOR4SVPROC) load(userptr, "glColor4sv"); + glad_glColor4ub = (PFNGLCOLOR4UBPROC) load(userptr, "glColor4ub"); + glad_glColor4ubv = (PFNGLCOLOR4UBVPROC) load(userptr, "glColor4ubv"); + glad_glColor4ui = (PFNGLCOLOR4UIPROC) load(userptr, "glColor4ui"); + glad_glColor4uiv = (PFNGLCOLOR4UIVPROC) load(userptr, "glColor4uiv"); + glad_glColor4us = (PFNGLCOLOR4USPROC) load(userptr, "glColor4us"); + glad_glColor4usv = (PFNGLCOLOR4USVPROC) load(userptr, "glColor4usv"); + glad_glColorMask = (PFNGLCOLORMASKPROC) load(userptr, "glColorMask"); + glad_glColorMaterial = (PFNGLCOLORMATERIALPROC) load(userptr, "glColorMaterial"); + glad_glCopyPixels = (PFNGLCOPYPIXELSPROC) load(userptr, "glCopyPixels"); + glad_glCullFace = (PFNGLCULLFACEPROC) load(userptr, "glCullFace"); + glad_glDeleteLists = (PFNGLDELETELISTSPROC) load(userptr, "glDeleteLists"); + glad_glDepthFunc = (PFNGLDEPTHFUNCPROC) load(userptr, "glDepthFunc"); + glad_glDepthMask = (PFNGLDEPTHMASKPROC) load(userptr, "glDepthMask"); + glad_glDepthRange = (PFNGLDEPTHRANGEPROC) load(userptr, "glDepthRange"); + glad_glDisable = (PFNGLDISABLEPROC) load(userptr, "glDisable"); + glad_glDrawBuffer = (PFNGLDRAWBUFFERPROC) load(userptr, "glDrawBuffer"); + glad_glDrawPixels = (PFNGLDRAWPIXELSPROC) load(userptr, "glDrawPixels"); + glad_glEdgeFlag = (PFNGLEDGEFLAGPROC) load(userptr, "glEdgeFlag"); + glad_glEdgeFlagv = (PFNGLEDGEFLAGVPROC) load(userptr, "glEdgeFlagv"); + glad_glEnable = (PFNGLENABLEPROC) load(userptr, "glEnable"); + glad_glEnd = (PFNGLENDPROC) load(userptr, "glEnd"); + glad_glEndList = (PFNGLENDLISTPROC) load(userptr, "glEndList"); + glad_glEvalCoord1d = (PFNGLEVALCOORD1DPROC) load(userptr, "glEvalCoord1d"); + glad_glEvalCoord1dv = (PFNGLEVALCOORD1DVPROC) load(userptr, "glEvalCoord1dv"); + glad_glEvalCoord1f = (PFNGLEVALCOORD1FPROC) load(userptr, "glEvalCoord1f"); + glad_glEvalCoord1fv = (PFNGLEVALCOORD1FVPROC) load(userptr, "glEvalCoord1fv"); + glad_glEvalCoord2d = (PFNGLEVALCOORD2DPROC) load(userptr, "glEvalCoord2d"); + glad_glEvalCoord2dv = (PFNGLEVALCOORD2DVPROC) load(userptr, "glEvalCoord2dv"); + glad_glEvalCoord2f = (PFNGLEVALCOORD2FPROC) load(userptr, "glEvalCoord2f"); + glad_glEvalCoord2fv = (PFNGLEVALCOORD2FVPROC) load(userptr, "glEvalCoord2fv"); + glad_glEvalMesh1 = (PFNGLEVALMESH1PROC) load(userptr, "glEvalMesh1"); + glad_glEvalMesh2 = (PFNGLEVALMESH2PROC) load(userptr, "glEvalMesh2"); + glad_glEvalPoint1 = (PFNGLEVALPOINT1PROC) load(userptr, "glEvalPoint1"); + glad_glEvalPoint2 = (PFNGLEVALPOINT2PROC) load(userptr, "glEvalPoint2"); + glad_glFeedbackBuffer = (PFNGLFEEDBACKBUFFERPROC) load(userptr, "glFeedbackBuffer"); + glad_glFinish = (PFNGLFINISHPROC) load(userptr, "glFinish"); + glad_glFlush = (PFNGLFLUSHPROC) load(userptr, "glFlush"); + glad_glFogf = (PFNGLFOGFPROC) load(userptr, "glFogf"); + glad_glFogfv = (PFNGLFOGFVPROC) load(userptr, "glFogfv"); + glad_glFogi = (PFNGLFOGIPROC) load(userptr, "glFogi"); + glad_glFogiv = (PFNGLFOGIVPROC) load(userptr, "glFogiv"); + glad_glFrontFace = (PFNGLFRONTFACEPROC) load(userptr, "glFrontFace"); + glad_glFrustum = (PFNGLFRUSTUMPROC) load(userptr, "glFrustum"); + glad_glGenLists = (PFNGLGENLISTSPROC) load(userptr, "glGenLists"); + glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC) load(userptr, "glGetBooleanv"); + glad_glGetClipPlane = (PFNGLGETCLIPPLANEPROC) load(userptr, "glGetClipPlane"); + glad_glGetDoublev = (PFNGLGETDOUBLEVPROC) load(userptr, "glGetDoublev"); + glad_glGetError = (PFNGLGETERRORPROC) load(userptr, "glGetError"); + glad_glGetFloatv = (PFNGLGETFLOATVPROC) load(userptr, "glGetFloatv"); + glad_glGetIntegerv = (PFNGLGETINTEGERVPROC) load(userptr, "glGetIntegerv"); + glad_glGetLightfv = (PFNGLGETLIGHTFVPROC) load(userptr, "glGetLightfv"); + glad_glGetLightiv = (PFNGLGETLIGHTIVPROC) load(userptr, "glGetLightiv"); + glad_glGetMapdv = (PFNGLGETMAPDVPROC) load(userptr, "glGetMapdv"); + glad_glGetMapfv = (PFNGLGETMAPFVPROC) load(userptr, "glGetMapfv"); + glad_glGetMapiv = (PFNGLGETMAPIVPROC) load(userptr, "glGetMapiv"); + glad_glGetMaterialfv = (PFNGLGETMATERIALFVPROC) load(userptr, "glGetMaterialfv"); + glad_glGetMaterialiv = (PFNGLGETMATERIALIVPROC) load(userptr, "glGetMaterialiv"); + glad_glGetPixelMapfv = (PFNGLGETPIXELMAPFVPROC) load(userptr, "glGetPixelMapfv"); + glad_glGetPixelMapuiv = (PFNGLGETPIXELMAPUIVPROC) load(userptr, "glGetPixelMapuiv"); + glad_glGetPixelMapusv = (PFNGLGETPIXELMAPUSVPROC) load(userptr, "glGetPixelMapusv"); + glad_glGetPolygonStipple = (PFNGLGETPOLYGONSTIPPLEPROC) load(userptr, "glGetPolygonStipple"); + glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); + glad_glGetTexEnvfv = (PFNGLGETTEXENVFVPROC) load(userptr, "glGetTexEnvfv"); + glad_glGetTexEnviv = (PFNGLGETTEXENVIVPROC) load(userptr, "glGetTexEnviv"); + glad_glGetTexGendv = (PFNGLGETTEXGENDVPROC) load(userptr, "glGetTexGendv"); + glad_glGetTexGenfv = (PFNGLGETTEXGENFVPROC) load(userptr, "glGetTexGenfv"); + glad_glGetTexGeniv = (PFNGLGETTEXGENIVPROC) load(userptr, "glGetTexGeniv"); + glad_glGetTexImage = (PFNGLGETTEXIMAGEPROC) load(userptr, "glGetTexImage"); + glad_glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC) load(userptr, "glGetTexLevelParameterfv"); + glad_glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC) load(userptr, "glGetTexLevelParameteriv"); + glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) load(userptr, "glGetTexParameterfv"); + glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) load(userptr, "glGetTexParameteriv"); + glad_glHint = (PFNGLHINTPROC) load(userptr, "glHint"); + glad_glIndexMask = (PFNGLINDEXMASKPROC) load(userptr, "glIndexMask"); + glad_glIndexd = (PFNGLINDEXDPROC) load(userptr, "glIndexd"); + glad_glIndexdv = (PFNGLINDEXDVPROC) load(userptr, "glIndexdv"); + glad_glIndexf = (PFNGLINDEXFPROC) load(userptr, "glIndexf"); + glad_glIndexfv = (PFNGLINDEXFVPROC) load(userptr, "glIndexfv"); + glad_glIndexi = (PFNGLINDEXIPROC) load(userptr, "glIndexi"); + glad_glIndexiv = (PFNGLINDEXIVPROC) load(userptr, "glIndexiv"); + glad_glIndexs = (PFNGLINDEXSPROC) load(userptr, "glIndexs"); + glad_glIndexsv = (PFNGLINDEXSVPROC) load(userptr, "glIndexsv"); + glad_glInitNames = (PFNGLINITNAMESPROC) load(userptr, "glInitNames"); + glad_glIsEnabled = (PFNGLISENABLEDPROC) load(userptr, "glIsEnabled"); + glad_glIsList = (PFNGLISLISTPROC) load(userptr, "glIsList"); + glad_glLightModelf = (PFNGLLIGHTMODELFPROC) load(userptr, "glLightModelf"); + glad_glLightModelfv = (PFNGLLIGHTMODELFVPROC) load(userptr, "glLightModelfv"); + glad_glLightModeli = (PFNGLLIGHTMODELIPROC) load(userptr, "glLightModeli"); + glad_glLightModeliv = (PFNGLLIGHTMODELIVPROC) load(userptr, "glLightModeliv"); + glad_glLightf = (PFNGLLIGHTFPROC) load(userptr, "glLightf"); + glad_glLightfv = (PFNGLLIGHTFVPROC) load(userptr, "glLightfv"); + glad_glLighti = (PFNGLLIGHTIPROC) load(userptr, "glLighti"); + glad_glLightiv = (PFNGLLIGHTIVPROC) load(userptr, "glLightiv"); + glad_glLineStipple = (PFNGLLINESTIPPLEPROC) load(userptr, "glLineStipple"); + glad_glLineWidth = (PFNGLLINEWIDTHPROC) load(userptr, "glLineWidth"); + glad_glListBase = (PFNGLLISTBASEPROC) load(userptr, "glListBase"); + glad_glLoadIdentity = (PFNGLLOADIDENTITYPROC) load(userptr, "glLoadIdentity"); + glad_glLoadMatrixd = (PFNGLLOADMATRIXDPROC) load(userptr, "glLoadMatrixd"); + glad_glLoadMatrixf = (PFNGLLOADMATRIXFPROC) load(userptr, "glLoadMatrixf"); + glad_glLoadName = (PFNGLLOADNAMEPROC) load(userptr, "glLoadName"); + glad_glLogicOp = (PFNGLLOGICOPPROC) load(userptr, "glLogicOp"); + glad_glMap1d = (PFNGLMAP1DPROC) load(userptr, "glMap1d"); + glad_glMap1f = (PFNGLMAP1FPROC) load(userptr, "glMap1f"); + glad_glMap2d = (PFNGLMAP2DPROC) load(userptr, "glMap2d"); + glad_glMap2f = (PFNGLMAP2FPROC) load(userptr, "glMap2f"); + glad_glMapGrid1d = (PFNGLMAPGRID1DPROC) load(userptr, "glMapGrid1d"); + glad_glMapGrid1f = (PFNGLMAPGRID1FPROC) load(userptr, "glMapGrid1f"); + glad_glMapGrid2d = (PFNGLMAPGRID2DPROC) load(userptr, "glMapGrid2d"); + glad_glMapGrid2f = (PFNGLMAPGRID2FPROC) load(userptr, "glMapGrid2f"); + glad_glMaterialf = (PFNGLMATERIALFPROC) load(userptr, "glMaterialf"); + glad_glMaterialfv = (PFNGLMATERIALFVPROC) load(userptr, "glMaterialfv"); + glad_glMateriali = (PFNGLMATERIALIPROC) load(userptr, "glMateriali"); + glad_glMaterialiv = (PFNGLMATERIALIVPROC) load(userptr, "glMaterialiv"); + glad_glMatrixMode = (PFNGLMATRIXMODEPROC) load(userptr, "glMatrixMode"); + glad_glMultMatrixd = (PFNGLMULTMATRIXDPROC) load(userptr, "glMultMatrixd"); + glad_glMultMatrixf = (PFNGLMULTMATRIXFPROC) load(userptr, "glMultMatrixf"); + glad_glNewList = (PFNGLNEWLISTPROC) load(userptr, "glNewList"); + glad_glNormal3b = (PFNGLNORMAL3BPROC) load(userptr, "glNormal3b"); + glad_glNormal3bv = (PFNGLNORMAL3BVPROC) load(userptr, "glNormal3bv"); + glad_glNormal3d = (PFNGLNORMAL3DPROC) load(userptr, "glNormal3d"); + glad_glNormal3dv = (PFNGLNORMAL3DVPROC) load(userptr, "glNormal3dv"); + glad_glNormal3f = (PFNGLNORMAL3FPROC) load(userptr, "glNormal3f"); + glad_glNormal3fv = (PFNGLNORMAL3FVPROC) load(userptr, "glNormal3fv"); + glad_glNormal3i = (PFNGLNORMAL3IPROC) load(userptr, "glNormal3i"); + glad_glNormal3iv = (PFNGLNORMAL3IVPROC) load(userptr, "glNormal3iv"); + glad_glNormal3s = (PFNGLNORMAL3SPROC) load(userptr, "glNormal3s"); + glad_glNormal3sv = (PFNGLNORMAL3SVPROC) load(userptr, "glNormal3sv"); + glad_glOrtho = (PFNGLORTHOPROC) load(userptr, "glOrtho"); + glad_glPassThrough = (PFNGLPASSTHROUGHPROC) load(userptr, "glPassThrough"); + glad_glPixelMapfv = (PFNGLPIXELMAPFVPROC) load(userptr, "glPixelMapfv"); + glad_glPixelMapuiv = (PFNGLPIXELMAPUIVPROC) load(userptr, "glPixelMapuiv"); + glad_glPixelMapusv = (PFNGLPIXELMAPUSVPROC) load(userptr, "glPixelMapusv"); + glad_glPixelStoref = (PFNGLPIXELSTOREFPROC) load(userptr, "glPixelStoref"); + glad_glPixelStorei = (PFNGLPIXELSTOREIPROC) load(userptr, "glPixelStorei"); + glad_glPixelTransferf = (PFNGLPIXELTRANSFERFPROC) load(userptr, "glPixelTransferf"); + glad_glPixelTransferi = (PFNGLPIXELTRANSFERIPROC) load(userptr, "glPixelTransferi"); + glad_glPixelZoom = (PFNGLPIXELZOOMPROC) load(userptr, "glPixelZoom"); + glad_glPointSize = (PFNGLPOINTSIZEPROC) load(userptr, "glPointSize"); + glad_glPolygonMode = (PFNGLPOLYGONMODEPROC) load(userptr, "glPolygonMode"); + glad_glPolygonStipple = (PFNGLPOLYGONSTIPPLEPROC) load(userptr, "glPolygonStipple"); + glad_glPopAttrib = (PFNGLPOPATTRIBPROC) load(userptr, "glPopAttrib"); + glad_glPopMatrix = (PFNGLPOPMATRIXPROC) load(userptr, "glPopMatrix"); + glad_glPopName = (PFNGLPOPNAMEPROC) load(userptr, "glPopName"); + glad_glPushAttrib = (PFNGLPUSHATTRIBPROC) load(userptr, "glPushAttrib"); + glad_glPushMatrix = (PFNGLPUSHMATRIXPROC) load(userptr, "glPushMatrix"); + glad_glPushName = (PFNGLPUSHNAMEPROC) load(userptr, "glPushName"); + glad_glRasterPos2d = (PFNGLRASTERPOS2DPROC) load(userptr, "glRasterPos2d"); + glad_glRasterPos2dv = (PFNGLRASTERPOS2DVPROC) load(userptr, "glRasterPos2dv"); + glad_glRasterPos2f = (PFNGLRASTERPOS2FPROC) load(userptr, "glRasterPos2f"); + glad_glRasterPos2fv = (PFNGLRASTERPOS2FVPROC) load(userptr, "glRasterPos2fv"); + glad_glRasterPos2i = (PFNGLRASTERPOS2IPROC) load(userptr, "glRasterPos2i"); + glad_glRasterPos2iv = (PFNGLRASTERPOS2IVPROC) load(userptr, "glRasterPos2iv"); + glad_glRasterPos2s = (PFNGLRASTERPOS2SPROC) load(userptr, "glRasterPos2s"); + glad_glRasterPos2sv = (PFNGLRASTERPOS2SVPROC) load(userptr, "glRasterPos2sv"); + glad_glRasterPos3d = (PFNGLRASTERPOS3DPROC) load(userptr, "glRasterPos3d"); + glad_glRasterPos3dv = (PFNGLRASTERPOS3DVPROC) load(userptr, "glRasterPos3dv"); + glad_glRasterPos3f = (PFNGLRASTERPOS3FPROC) load(userptr, "glRasterPos3f"); + glad_glRasterPos3fv = (PFNGLRASTERPOS3FVPROC) load(userptr, "glRasterPos3fv"); + glad_glRasterPos3i = (PFNGLRASTERPOS3IPROC) load(userptr, "glRasterPos3i"); + glad_glRasterPos3iv = (PFNGLRASTERPOS3IVPROC) load(userptr, "glRasterPos3iv"); + glad_glRasterPos3s = (PFNGLRASTERPOS3SPROC) load(userptr, "glRasterPos3s"); + glad_glRasterPos3sv = (PFNGLRASTERPOS3SVPROC) load(userptr, "glRasterPos3sv"); + glad_glRasterPos4d = (PFNGLRASTERPOS4DPROC) load(userptr, "glRasterPos4d"); + glad_glRasterPos4dv = (PFNGLRASTERPOS4DVPROC) load(userptr, "glRasterPos4dv"); + glad_glRasterPos4f = (PFNGLRASTERPOS4FPROC) load(userptr, "glRasterPos4f"); + glad_glRasterPos4fv = (PFNGLRASTERPOS4FVPROC) load(userptr, "glRasterPos4fv"); + glad_glRasterPos4i = (PFNGLRASTERPOS4IPROC) load(userptr, "glRasterPos4i"); + glad_glRasterPos4iv = (PFNGLRASTERPOS4IVPROC) load(userptr, "glRasterPos4iv"); + glad_glRasterPos4s = (PFNGLRASTERPOS4SPROC) load(userptr, "glRasterPos4s"); + glad_glRasterPos4sv = (PFNGLRASTERPOS4SVPROC) load(userptr, "glRasterPos4sv"); + glad_glReadBuffer = (PFNGLREADBUFFERPROC) load(userptr, "glReadBuffer"); + glad_glReadPixels = (PFNGLREADPIXELSPROC) load(userptr, "glReadPixels"); + glad_glRectd = (PFNGLRECTDPROC) load(userptr, "glRectd"); + glad_glRectdv = (PFNGLRECTDVPROC) load(userptr, "glRectdv"); + glad_glRectf = (PFNGLRECTFPROC) load(userptr, "glRectf"); + glad_glRectfv = (PFNGLRECTFVPROC) load(userptr, "glRectfv"); + glad_glRecti = (PFNGLRECTIPROC) load(userptr, "glRecti"); + glad_glRectiv = (PFNGLRECTIVPROC) load(userptr, "glRectiv"); + glad_glRects = (PFNGLRECTSPROC) load(userptr, "glRects"); + glad_glRectsv = (PFNGLRECTSVPROC) load(userptr, "glRectsv"); + glad_glRenderMode = (PFNGLRENDERMODEPROC) load(userptr, "glRenderMode"); + glad_glRotated = (PFNGLROTATEDPROC) load(userptr, "glRotated"); + glad_glRotatef = (PFNGLROTATEFPROC) load(userptr, "glRotatef"); + glad_glScaled = (PFNGLSCALEDPROC) load(userptr, "glScaled"); + glad_glScalef = (PFNGLSCALEFPROC) load(userptr, "glScalef"); + glad_glScissor = (PFNGLSCISSORPROC) load(userptr, "glScissor"); + glad_glSelectBuffer = (PFNGLSELECTBUFFERPROC) load(userptr, "glSelectBuffer"); + glad_glShadeModel = (PFNGLSHADEMODELPROC) load(userptr, "glShadeModel"); + glad_glStencilFunc = (PFNGLSTENCILFUNCPROC) load(userptr, "glStencilFunc"); + glad_glStencilMask = (PFNGLSTENCILMASKPROC) load(userptr, "glStencilMask"); + glad_glStencilOp = (PFNGLSTENCILOPPROC) load(userptr, "glStencilOp"); + glad_glTexCoord1d = (PFNGLTEXCOORD1DPROC) load(userptr, "glTexCoord1d"); + glad_glTexCoord1dv = (PFNGLTEXCOORD1DVPROC) load(userptr, "glTexCoord1dv"); + glad_glTexCoord1f = (PFNGLTEXCOORD1FPROC) load(userptr, "glTexCoord1f"); + glad_glTexCoord1fv = (PFNGLTEXCOORD1FVPROC) load(userptr, "glTexCoord1fv"); + glad_glTexCoord1i = (PFNGLTEXCOORD1IPROC) load(userptr, "glTexCoord1i"); + glad_glTexCoord1iv = (PFNGLTEXCOORD1IVPROC) load(userptr, "glTexCoord1iv"); + glad_glTexCoord1s = (PFNGLTEXCOORD1SPROC) load(userptr, "glTexCoord1s"); + glad_glTexCoord1sv = (PFNGLTEXCOORD1SVPROC) load(userptr, "glTexCoord1sv"); + glad_glTexCoord2d = (PFNGLTEXCOORD2DPROC) load(userptr, "glTexCoord2d"); + glad_glTexCoord2dv = (PFNGLTEXCOORD2DVPROC) load(userptr, "glTexCoord2dv"); + glad_glTexCoord2f = (PFNGLTEXCOORD2FPROC) load(userptr, "glTexCoord2f"); + glad_glTexCoord2fv = (PFNGLTEXCOORD2FVPROC) load(userptr, "glTexCoord2fv"); + glad_glTexCoord2i = (PFNGLTEXCOORD2IPROC) load(userptr, "glTexCoord2i"); + glad_glTexCoord2iv = (PFNGLTEXCOORD2IVPROC) load(userptr, "glTexCoord2iv"); + glad_glTexCoord2s = (PFNGLTEXCOORD2SPROC) load(userptr, "glTexCoord2s"); + glad_glTexCoord2sv = (PFNGLTEXCOORD2SVPROC) load(userptr, "glTexCoord2sv"); + glad_glTexCoord3d = (PFNGLTEXCOORD3DPROC) load(userptr, "glTexCoord3d"); + glad_glTexCoord3dv = (PFNGLTEXCOORD3DVPROC) load(userptr, "glTexCoord3dv"); + glad_glTexCoord3f = (PFNGLTEXCOORD3FPROC) load(userptr, "glTexCoord3f"); + glad_glTexCoord3fv = (PFNGLTEXCOORD3FVPROC) load(userptr, "glTexCoord3fv"); + glad_glTexCoord3i = (PFNGLTEXCOORD3IPROC) load(userptr, "glTexCoord3i"); + glad_glTexCoord3iv = (PFNGLTEXCOORD3IVPROC) load(userptr, "glTexCoord3iv"); + glad_glTexCoord3s = (PFNGLTEXCOORD3SPROC) load(userptr, "glTexCoord3s"); + glad_glTexCoord3sv = (PFNGLTEXCOORD3SVPROC) load(userptr, "glTexCoord3sv"); + glad_glTexCoord4d = (PFNGLTEXCOORD4DPROC) load(userptr, "glTexCoord4d"); + glad_glTexCoord4dv = (PFNGLTEXCOORD4DVPROC) load(userptr, "glTexCoord4dv"); + glad_glTexCoord4f = (PFNGLTEXCOORD4FPROC) load(userptr, "glTexCoord4f"); + glad_glTexCoord4fv = (PFNGLTEXCOORD4FVPROC) load(userptr, "glTexCoord4fv"); + glad_glTexCoord4i = (PFNGLTEXCOORD4IPROC) load(userptr, "glTexCoord4i"); + glad_glTexCoord4iv = (PFNGLTEXCOORD4IVPROC) load(userptr, "glTexCoord4iv"); + glad_glTexCoord4s = (PFNGLTEXCOORD4SPROC) load(userptr, "glTexCoord4s"); + glad_glTexCoord4sv = (PFNGLTEXCOORD4SVPROC) load(userptr, "glTexCoord4sv"); + glad_glTexEnvf = (PFNGLTEXENVFPROC) load(userptr, "glTexEnvf"); + glad_glTexEnvfv = (PFNGLTEXENVFVPROC) load(userptr, "glTexEnvfv"); + glad_glTexEnvi = (PFNGLTEXENVIPROC) load(userptr, "glTexEnvi"); + glad_glTexEnviv = (PFNGLTEXENVIVPROC) load(userptr, "glTexEnviv"); + glad_glTexGend = (PFNGLTEXGENDPROC) load(userptr, "glTexGend"); + glad_glTexGendv = (PFNGLTEXGENDVPROC) load(userptr, "glTexGendv"); + glad_glTexGenf = (PFNGLTEXGENFPROC) load(userptr, "glTexGenf"); + glad_glTexGenfv = (PFNGLTEXGENFVPROC) load(userptr, "glTexGenfv"); + glad_glTexGeni = (PFNGLTEXGENIPROC) load(userptr, "glTexGeni"); + glad_glTexGeniv = (PFNGLTEXGENIVPROC) load(userptr, "glTexGeniv"); + glad_glTexImage1D = (PFNGLTEXIMAGE1DPROC) load(userptr, "glTexImage1D"); + glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC) load(userptr, "glTexImage2D"); + glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC) load(userptr, "glTexParameterf"); + glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC) load(userptr, "glTexParameterfv"); + glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC) load(userptr, "glTexParameteri"); + glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC) load(userptr, "glTexParameteriv"); + glad_glTranslated = (PFNGLTRANSLATEDPROC) load(userptr, "glTranslated"); + glad_glTranslatef = (PFNGLTRANSLATEFPROC) load(userptr, "glTranslatef"); + glad_glVertex2d = (PFNGLVERTEX2DPROC) load(userptr, "glVertex2d"); + glad_glVertex2dv = (PFNGLVERTEX2DVPROC) load(userptr, "glVertex2dv"); + glad_glVertex2f = (PFNGLVERTEX2FPROC) load(userptr, "glVertex2f"); + glad_glVertex2fv = (PFNGLVERTEX2FVPROC) load(userptr, "glVertex2fv"); + glad_glVertex2i = (PFNGLVERTEX2IPROC) load(userptr, "glVertex2i"); + glad_glVertex2iv = (PFNGLVERTEX2IVPROC) load(userptr, "glVertex2iv"); + glad_glVertex2s = (PFNGLVERTEX2SPROC) load(userptr, "glVertex2s"); + glad_glVertex2sv = (PFNGLVERTEX2SVPROC) load(userptr, "glVertex2sv"); + glad_glVertex3d = (PFNGLVERTEX3DPROC) load(userptr, "glVertex3d"); + glad_glVertex3dv = (PFNGLVERTEX3DVPROC) load(userptr, "glVertex3dv"); + glad_glVertex3f = (PFNGLVERTEX3FPROC) load(userptr, "glVertex3f"); + glad_glVertex3fv = (PFNGLVERTEX3FVPROC) load(userptr, "glVertex3fv"); + glad_glVertex3i = (PFNGLVERTEX3IPROC) load(userptr, "glVertex3i"); + glad_glVertex3iv = (PFNGLVERTEX3IVPROC) load(userptr, "glVertex3iv"); + glad_glVertex3s = (PFNGLVERTEX3SPROC) load(userptr, "glVertex3s"); + glad_glVertex3sv = (PFNGLVERTEX3SVPROC) load(userptr, "glVertex3sv"); + glad_glVertex4d = (PFNGLVERTEX4DPROC) load(userptr, "glVertex4d"); + glad_glVertex4dv = (PFNGLVERTEX4DVPROC) load(userptr, "glVertex4dv"); + glad_glVertex4f = (PFNGLVERTEX4FPROC) load(userptr, "glVertex4f"); + glad_glVertex4fv = (PFNGLVERTEX4FVPROC) load(userptr, "glVertex4fv"); + glad_glVertex4i = (PFNGLVERTEX4IPROC) load(userptr, "glVertex4i"); + glad_glVertex4iv = (PFNGLVERTEX4IVPROC) load(userptr, "glVertex4iv"); + glad_glVertex4s = (PFNGLVERTEX4SPROC) load(userptr, "glVertex4s"); + glad_glVertex4sv = (PFNGLVERTEX4SVPROC) load(userptr, "glVertex4sv"); + glad_glViewport = (PFNGLVIEWPORTPROC) load(userptr, "glViewport"); +} +static void glad_gl_load_GL_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_1_1) return; + glad_glAreTexturesResident = (PFNGLARETEXTURESRESIDENTPROC) load(userptr, "glAreTexturesResident"); + glad_glArrayElement = (PFNGLARRAYELEMENTPROC) load(userptr, "glArrayElement"); + glad_glBindTexture = (PFNGLBINDTEXTUREPROC) load(userptr, "glBindTexture"); + glad_glColorPointer = (PFNGLCOLORPOINTERPROC) load(userptr, "glColorPointer"); + glad_glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC) load(userptr, "glCopyTexImage1D"); + glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) load(userptr, "glCopyTexImage2D"); + glad_glCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC) load(userptr, "glCopyTexSubImage1D"); + glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) load(userptr, "glCopyTexSubImage2D"); + glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC) load(userptr, "glDeleteTextures"); + glad_glDisableClientState = (PFNGLDISABLECLIENTSTATEPROC) load(userptr, "glDisableClientState"); + glad_glDrawArrays = (PFNGLDRAWARRAYSPROC) load(userptr, "glDrawArrays"); + glad_glDrawElements = (PFNGLDRAWELEMENTSPROC) load(userptr, "glDrawElements"); + glad_glEdgeFlagPointer = (PFNGLEDGEFLAGPOINTERPROC) load(userptr, "glEdgeFlagPointer"); + glad_glEnableClientState = (PFNGLENABLECLIENTSTATEPROC) load(userptr, "glEnableClientState"); + glad_glGenTextures = (PFNGLGENTEXTURESPROC) load(userptr, "glGenTextures"); + glad_glGetPointerv = (PFNGLGETPOINTERVPROC) load(userptr, "glGetPointerv"); + glad_glIndexPointer = (PFNGLINDEXPOINTERPROC) load(userptr, "glIndexPointer"); + glad_glIndexub = (PFNGLINDEXUBPROC) load(userptr, "glIndexub"); + glad_glIndexubv = (PFNGLINDEXUBVPROC) load(userptr, "glIndexubv"); + glad_glInterleavedArrays = (PFNGLINTERLEAVEDARRAYSPROC) load(userptr, "glInterleavedArrays"); + glad_glIsTexture = (PFNGLISTEXTUREPROC) load(userptr, "glIsTexture"); + glad_glNormalPointer = (PFNGLNORMALPOINTERPROC) load(userptr, "glNormalPointer"); + glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC) load(userptr, "glPolygonOffset"); + glad_glPopClientAttrib = (PFNGLPOPCLIENTATTRIBPROC) load(userptr, "glPopClientAttrib"); + glad_glPrioritizeTextures = (PFNGLPRIORITIZETEXTURESPROC) load(userptr, "glPrioritizeTextures"); + glad_glPushClientAttrib = (PFNGLPUSHCLIENTATTRIBPROC) load(userptr, "glPushClientAttrib"); + glad_glTexCoordPointer = (PFNGLTEXCOORDPOINTERPROC) load(userptr, "glTexCoordPointer"); + glad_glTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC) load(userptr, "glTexSubImage1D"); + glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) load(userptr, "glTexSubImage2D"); + glad_glVertexPointer = (PFNGLVERTEXPOINTERPROC) load(userptr, "glVertexPointer"); +} +static void glad_gl_load_GL_VERSION_1_2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_1_2) return; + glad_glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) load(userptr, "glCopyTexSubImage3D"); + glad_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC) load(userptr, "glDrawRangeElements"); + glad_glTexImage3D = (PFNGLTEXIMAGE3DPROC) load(userptr, "glTexImage3D"); + glad_glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) load(userptr, "glTexSubImage3D"); +} +static void glad_gl_load_GL_VERSION_1_3( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_1_3) return; + glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC) load(userptr, "glActiveTexture"); + glad_glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC) load(userptr, "glClientActiveTexture"); + glad_glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC) load(userptr, "glCompressedTexImage1D"); + glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) load(userptr, "glCompressedTexImage2D"); + glad_glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC) load(userptr, "glCompressedTexImage3D"); + glad_glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) load(userptr, "glCompressedTexSubImage1D"); + glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) load(userptr, "glCompressedTexSubImage2D"); + glad_glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) load(userptr, "glCompressedTexSubImage3D"); + glad_glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC) load(userptr, "glGetCompressedTexImage"); + glad_glLoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC) load(userptr, "glLoadTransposeMatrixd"); + glad_glLoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC) load(userptr, "glLoadTransposeMatrixf"); + glad_glMultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC) load(userptr, "glMultTransposeMatrixd"); + glad_glMultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC) load(userptr, "glMultTransposeMatrixf"); + glad_glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC) load(userptr, "glMultiTexCoord1d"); + glad_glMultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC) load(userptr, "glMultiTexCoord1dv"); + glad_glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC) load(userptr, "glMultiTexCoord1f"); + glad_glMultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC) load(userptr, "glMultiTexCoord1fv"); + glad_glMultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC) load(userptr, "glMultiTexCoord1i"); + glad_glMultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC) load(userptr, "glMultiTexCoord1iv"); + glad_glMultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC) load(userptr, "glMultiTexCoord1s"); + glad_glMultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC) load(userptr, "glMultiTexCoord1sv"); + glad_glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC) load(userptr, "glMultiTexCoord2d"); + glad_glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC) load(userptr, "glMultiTexCoord2dv"); + glad_glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC) load(userptr, "glMultiTexCoord2f"); + glad_glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC) load(userptr, "glMultiTexCoord2fv"); + glad_glMultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC) load(userptr, "glMultiTexCoord2i"); + glad_glMultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC) load(userptr, "glMultiTexCoord2iv"); + glad_glMultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC) load(userptr, "glMultiTexCoord2s"); + glad_glMultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC) load(userptr, "glMultiTexCoord2sv"); + glad_glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC) load(userptr, "glMultiTexCoord3d"); + glad_glMultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC) load(userptr, "glMultiTexCoord3dv"); + glad_glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC) load(userptr, "glMultiTexCoord3f"); + glad_glMultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC) load(userptr, "glMultiTexCoord3fv"); + glad_glMultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC) load(userptr, "glMultiTexCoord3i"); + glad_glMultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC) load(userptr, "glMultiTexCoord3iv"); + glad_glMultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC) load(userptr, "glMultiTexCoord3s"); + glad_glMultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC) load(userptr, "glMultiTexCoord3sv"); + glad_glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC) load(userptr, "glMultiTexCoord4d"); + glad_glMultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC) load(userptr, "glMultiTexCoord4dv"); + glad_glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC) load(userptr, "glMultiTexCoord4f"); + glad_glMultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC) load(userptr, "glMultiTexCoord4fv"); + glad_glMultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC) load(userptr, "glMultiTexCoord4i"); + glad_glMultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC) load(userptr, "glMultiTexCoord4iv"); + glad_glMultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC) load(userptr, "glMultiTexCoord4s"); + glad_glMultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC) load(userptr, "glMultiTexCoord4sv"); + glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) load(userptr, "glSampleCoverage"); +} +static void glad_gl_load_GL_VERSION_1_4( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_1_4) return; + glad_glBlendColor = (PFNGLBLENDCOLORPROC) load(userptr, "glBlendColor"); + glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC) load(userptr, "glBlendEquation"); + glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) load(userptr, "glBlendFuncSeparate"); + glad_glFogCoordPointer = (PFNGLFOGCOORDPOINTERPROC) load(userptr, "glFogCoordPointer"); + glad_glFogCoordd = (PFNGLFOGCOORDDPROC) load(userptr, "glFogCoordd"); + glad_glFogCoorddv = (PFNGLFOGCOORDDVPROC) load(userptr, "glFogCoorddv"); + glad_glFogCoordf = (PFNGLFOGCOORDFPROC) load(userptr, "glFogCoordf"); + glad_glFogCoordfv = (PFNGLFOGCOORDFVPROC) load(userptr, "glFogCoordfv"); + glad_glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC) load(userptr, "glMultiDrawArrays"); + glad_glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC) load(userptr, "glMultiDrawElements"); + glad_glPointParameterf = (PFNGLPOINTPARAMETERFPROC) load(userptr, "glPointParameterf"); + glad_glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC) load(userptr, "glPointParameterfv"); + glad_glPointParameteri = (PFNGLPOINTPARAMETERIPROC) load(userptr, "glPointParameteri"); + glad_glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC) load(userptr, "glPointParameteriv"); + glad_glSecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC) load(userptr, "glSecondaryColor3b"); + glad_glSecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC) load(userptr, "glSecondaryColor3bv"); + glad_glSecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC) load(userptr, "glSecondaryColor3d"); + glad_glSecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC) load(userptr, "glSecondaryColor3dv"); + glad_glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC) load(userptr, "glSecondaryColor3f"); + glad_glSecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC) load(userptr, "glSecondaryColor3fv"); + glad_glSecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC) load(userptr, "glSecondaryColor3i"); + glad_glSecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC) load(userptr, "glSecondaryColor3iv"); + glad_glSecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC) load(userptr, "glSecondaryColor3s"); + glad_glSecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC) load(userptr, "glSecondaryColor3sv"); + glad_glSecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC) load(userptr, "glSecondaryColor3ub"); + glad_glSecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC) load(userptr, "glSecondaryColor3ubv"); + glad_glSecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC) load(userptr, "glSecondaryColor3ui"); + glad_glSecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC) load(userptr, "glSecondaryColor3uiv"); + glad_glSecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC) load(userptr, "glSecondaryColor3us"); + glad_glSecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC) load(userptr, "glSecondaryColor3usv"); + glad_glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC) load(userptr, "glSecondaryColorPointer"); + glad_glWindowPos2d = (PFNGLWINDOWPOS2DPROC) load(userptr, "glWindowPos2d"); + glad_glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC) load(userptr, "glWindowPos2dv"); + glad_glWindowPos2f = (PFNGLWINDOWPOS2FPROC) load(userptr, "glWindowPos2f"); + glad_glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC) load(userptr, "glWindowPos2fv"); + glad_glWindowPos2i = (PFNGLWINDOWPOS2IPROC) load(userptr, "glWindowPos2i"); + glad_glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC) load(userptr, "glWindowPos2iv"); + glad_glWindowPos2s = (PFNGLWINDOWPOS2SPROC) load(userptr, "glWindowPos2s"); + glad_glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC) load(userptr, "glWindowPos2sv"); + glad_glWindowPos3d = (PFNGLWINDOWPOS3DPROC) load(userptr, "glWindowPos3d"); + glad_glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC) load(userptr, "glWindowPos3dv"); + glad_glWindowPos3f = (PFNGLWINDOWPOS3FPROC) load(userptr, "glWindowPos3f"); + glad_glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC) load(userptr, "glWindowPos3fv"); + glad_glWindowPos3i = (PFNGLWINDOWPOS3IPROC) load(userptr, "glWindowPos3i"); + glad_glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC) load(userptr, "glWindowPos3iv"); + glad_glWindowPos3s = (PFNGLWINDOWPOS3SPROC) load(userptr, "glWindowPos3s"); + glad_glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC) load(userptr, "glWindowPos3sv"); +} +static void glad_gl_load_GL_VERSION_1_5( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_1_5) return; + glad_glBeginQuery = (PFNGLBEGINQUERYPROC) load(userptr, "glBeginQuery"); + glad_glBindBuffer = (PFNGLBINDBUFFERPROC) load(userptr, "glBindBuffer"); + glad_glBufferData = (PFNGLBUFFERDATAPROC) load(userptr, "glBufferData"); + glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC) load(userptr, "glBufferSubData"); + glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) load(userptr, "glDeleteBuffers"); + glad_glDeleteQueries = (PFNGLDELETEQUERIESPROC) load(userptr, "glDeleteQueries"); + glad_glEndQuery = (PFNGLENDQUERYPROC) load(userptr, "glEndQuery"); + glad_glGenBuffers = (PFNGLGENBUFFERSPROC) load(userptr, "glGenBuffers"); + glad_glGenQueries = (PFNGLGENQUERIESPROC) load(userptr, "glGenQueries"); + glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) load(userptr, "glGetBufferParameteriv"); + glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC) load(userptr, "glGetBufferPointerv"); + glad_glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC) load(userptr, "glGetBufferSubData"); + glad_glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC) load(userptr, "glGetQueryObjectiv"); + glad_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) load(userptr, "glGetQueryObjectuiv"); + glad_glGetQueryiv = (PFNGLGETQUERYIVPROC) load(userptr, "glGetQueryiv"); + glad_glIsBuffer = (PFNGLISBUFFERPROC) load(userptr, "glIsBuffer"); + glad_glIsQuery = (PFNGLISQUERYPROC) load(userptr, "glIsQuery"); + glad_glMapBuffer = (PFNGLMAPBUFFERPROC) load(userptr, "glMapBuffer"); + glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC) load(userptr, "glUnmapBuffer"); +} +static void glad_gl_load_GL_VERSION_2_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_2_0) return; + glad_glAttachShader = (PFNGLATTACHSHADERPROC) load(userptr, "glAttachShader"); + glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) load(userptr, "glBindAttribLocation"); + glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) load(userptr, "glBlendEquationSeparate"); + glad_glCompileShader = (PFNGLCOMPILESHADERPROC) load(userptr, "glCompileShader"); + glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC) load(userptr, "glCreateProgram"); + glad_glCreateShader = (PFNGLCREATESHADERPROC) load(userptr, "glCreateShader"); + glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC) load(userptr, "glDeleteProgram"); + glad_glDeleteShader = (PFNGLDELETESHADERPROC) load(userptr, "glDeleteShader"); + glad_glDetachShader = (PFNGLDETACHSHADERPROC) load(userptr, "glDetachShader"); + glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) load(userptr, "glDisableVertexAttribArray"); + glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC) load(userptr, "glDrawBuffers"); + glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) load(userptr, "glEnableVertexAttribArray"); + glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) load(userptr, "glGetActiveAttrib"); + glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) load(userptr, "glGetActiveUniform"); + glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) load(userptr, "glGetAttachedShaders"); + glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) load(userptr, "glGetAttribLocation"); + glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) load(userptr, "glGetProgramInfoLog"); + glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC) load(userptr, "glGetProgramiv"); + glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) load(userptr, "glGetShaderInfoLog"); + glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC) load(userptr, "glGetShaderSource"); + glad_glGetShaderiv = (PFNGLGETSHADERIVPROC) load(userptr, "glGetShaderiv"); + glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) load(userptr, "glGetUniformLocation"); + glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC) load(userptr, "glGetUniformfv"); + glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC) load(userptr, "glGetUniformiv"); + glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) load(userptr, "glGetVertexAttribPointerv"); + glad_glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC) load(userptr, "glGetVertexAttribdv"); + glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) load(userptr, "glGetVertexAttribfv"); + glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) load(userptr, "glGetVertexAttribiv"); + glad_glIsProgram = (PFNGLISPROGRAMPROC) load(userptr, "glIsProgram"); + glad_glIsShader = (PFNGLISSHADERPROC) load(userptr, "glIsShader"); + glad_glLinkProgram = (PFNGLLINKPROGRAMPROC) load(userptr, "glLinkProgram"); + glad_glShaderSource = (PFNGLSHADERSOURCEPROC) load(userptr, "glShaderSource"); + glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) load(userptr, "glStencilFuncSeparate"); + glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) load(userptr, "glStencilMaskSeparate"); + glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) load(userptr, "glStencilOpSeparate"); + glad_glUniform1f = (PFNGLUNIFORM1FPROC) load(userptr, "glUniform1f"); + glad_glUniform1fv = (PFNGLUNIFORM1FVPROC) load(userptr, "glUniform1fv"); + glad_glUniform1i = (PFNGLUNIFORM1IPROC) load(userptr, "glUniform1i"); + glad_glUniform1iv = (PFNGLUNIFORM1IVPROC) load(userptr, "glUniform1iv"); + glad_glUniform2f = (PFNGLUNIFORM2FPROC) load(userptr, "glUniform2f"); + glad_glUniform2fv = (PFNGLUNIFORM2FVPROC) load(userptr, "glUniform2fv"); + glad_glUniform2i = (PFNGLUNIFORM2IPROC) load(userptr, "glUniform2i"); + glad_glUniform2iv = (PFNGLUNIFORM2IVPROC) load(userptr, "glUniform2iv"); + glad_glUniform3f = (PFNGLUNIFORM3FPROC) load(userptr, "glUniform3f"); + glad_glUniform3fv = (PFNGLUNIFORM3FVPROC) load(userptr, "glUniform3fv"); + glad_glUniform3i = (PFNGLUNIFORM3IPROC) load(userptr, "glUniform3i"); + glad_glUniform3iv = (PFNGLUNIFORM3IVPROC) load(userptr, "glUniform3iv"); + glad_glUniform4f = (PFNGLUNIFORM4FPROC) load(userptr, "glUniform4f"); + glad_glUniform4fv = (PFNGLUNIFORM4FVPROC) load(userptr, "glUniform4fv"); + glad_glUniform4i = (PFNGLUNIFORM4IPROC) load(userptr, "glUniform4i"); + glad_glUniform4iv = (PFNGLUNIFORM4IVPROC) load(userptr, "glUniform4iv"); + glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) load(userptr, "glUniformMatrix2fv"); + glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) load(userptr, "glUniformMatrix3fv"); + glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) load(userptr, "glUniformMatrix4fv"); + glad_glUseProgram = (PFNGLUSEPROGRAMPROC) load(userptr, "glUseProgram"); + glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC) load(userptr, "glValidateProgram"); + glad_glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC) load(userptr, "glVertexAttrib1d"); + glad_glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC) load(userptr, "glVertexAttrib1dv"); + glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) load(userptr, "glVertexAttrib1f"); + glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) load(userptr, "glVertexAttrib1fv"); + glad_glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC) load(userptr, "glVertexAttrib1s"); + glad_glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC) load(userptr, "glVertexAttrib1sv"); + glad_glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC) load(userptr, "glVertexAttrib2d"); + glad_glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC) load(userptr, "glVertexAttrib2dv"); + glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) load(userptr, "glVertexAttrib2f"); + glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) load(userptr, "glVertexAttrib2fv"); + glad_glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC) load(userptr, "glVertexAttrib2s"); + glad_glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC) load(userptr, "glVertexAttrib2sv"); + glad_glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC) load(userptr, "glVertexAttrib3d"); + glad_glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC) load(userptr, "glVertexAttrib3dv"); + glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) load(userptr, "glVertexAttrib3f"); + glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) load(userptr, "glVertexAttrib3fv"); + glad_glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC) load(userptr, "glVertexAttrib3s"); + glad_glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC) load(userptr, "glVertexAttrib3sv"); + glad_glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC) load(userptr, "glVertexAttrib4Nbv"); + glad_glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC) load(userptr, "glVertexAttrib4Niv"); + glad_glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC) load(userptr, "glVertexAttrib4Nsv"); + glad_glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC) load(userptr, "glVertexAttrib4Nub"); + glad_glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC) load(userptr, "glVertexAttrib4Nubv"); + glad_glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC) load(userptr, "glVertexAttrib4Nuiv"); + glad_glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC) load(userptr, "glVertexAttrib4Nusv"); + glad_glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC) load(userptr, "glVertexAttrib4bv"); + glad_glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC) load(userptr, "glVertexAttrib4d"); + glad_glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC) load(userptr, "glVertexAttrib4dv"); + glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) load(userptr, "glVertexAttrib4f"); + glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) load(userptr, "glVertexAttrib4fv"); + glad_glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC) load(userptr, "glVertexAttrib4iv"); + glad_glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC) load(userptr, "glVertexAttrib4s"); + glad_glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC) load(userptr, "glVertexAttrib4sv"); + glad_glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC) load(userptr, "glVertexAttrib4ubv"); + glad_glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC) load(userptr, "glVertexAttrib4uiv"); + glad_glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC) load(userptr, "glVertexAttrib4usv"); + glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) load(userptr, "glVertexAttribPointer"); +} +static void glad_gl_load_GL_VERSION_2_1( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_2_1) return; + glad_glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) load(userptr, "glUniformMatrix2x3fv"); + glad_glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) load(userptr, "glUniformMatrix2x4fv"); + glad_glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) load(userptr, "glUniformMatrix3x2fv"); + glad_glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) load(userptr, "glUniformMatrix3x4fv"); + glad_glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) load(userptr, "glUniformMatrix4x2fv"); + glad_glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) load(userptr, "glUniformMatrix4x3fv"); +} +static void glad_gl_load_GL_VERSION_3_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_3_0) return; + glad_glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC) load(userptr, "glBeginConditionalRender"); + glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) load(userptr, "glBeginTransformFeedback"); + glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load(userptr, "glBindBufferBase"); + glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load(userptr, "glBindBufferRange"); + glad_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC) load(userptr, "glBindFragDataLocation"); + glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) load(userptr, "glBindFramebuffer"); + glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) load(userptr, "glBindRenderbuffer"); + glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) load(userptr, "glBindVertexArray"); + glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) load(userptr, "glBlitFramebuffer"); + glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckFramebufferStatus"); + glad_glClampColor = (PFNGLCLAMPCOLORPROC) load(userptr, "glClampColor"); + glad_glClearBufferfi = (PFNGLCLEARBUFFERFIPROC) load(userptr, "glClearBufferfi"); + glad_glClearBufferfv = (PFNGLCLEARBUFFERFVPROC) load(userptr, "glClearBufferfv"); + glad_glClearBufferiv = (PFNGLCLEARBUFFERIVPROC) load(userptr, "glClearBufferiv"); + glad_glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC) load(userptr, "glClearBufferuiv"); + glad_glColorMaski = (PFNGLCOLORMASKIPROC) load(userptr, "glColorMaski"); + glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) load(userptr, "glDeleteFramebuffers"); + glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) load(userptr, "glDeleteRenderbuffers"); + glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) load(userptr, "glDeleteVertexArrays"); + glad_glDisablei = (PFNGLDISABLEIPROC) load(userptr, "glDisablei"); + glad_glEnablei = (PFNGLENABLEIPROC) load(userptr, "glEnablei"); + glad_glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC) load(userptr, "glEndConditionalRender"); + glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) load(userptr, "glEndTransformFeedback"); + glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) load(userptr, "glFlushMappedBufferRange"); + glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glFramebufferRenderbuffer"); + glad_glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) load(userptr, "glFramebufferTexture1D"); + glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) load(userptr, "glFramebufferTexture2D"); + glad_glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) load(userptr, "glFramebufferTexture3D"); + glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) load(userptr, "glFramebufferTextureLayer"); + glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) load(userptr, "glGenFramebuffers"); + glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) load(userptr, "glGenRenderbuffers"); + glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) load(userptr, "glGenVertexArrays"); + glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) load(userptr, "glGenerateMipmap"); + glad_glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC) load(userptr, "glGetBooleani_v"); + glad_glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC) load(userptr, "glGetFragDataLocation"); + glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetFramebufferAttachmentParameteriv"); + glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load(userptr, "glGetIntegeri_v"); + glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetRenderbufferParameteriv"); + glad_glGetStringi = (PFNGLGETSTRINGIPROC) load(userptr, "glGetStringi"); + glad_glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC) load(userptr, "glGetTexParameterIiv"); + glad_glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC) load(userptr, "glGetTexParameterIuiv"); + glad_glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) load(userptr, "glGetTransformFeedbackVarying"); + glad_glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC) load(userptr, "glGetUniformuiv"); + glad_glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC) load(userptr, "glGetVertexAttribIiv"); + glad_glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC) load(userptr, "glGetVertexAttribIuiv"); + glad_glIsEnabledi = (PFNGLISENABLEDIPROC) load(userptr, "glIsEnabledi"); + glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) load(userptr, "glIsFramebuffer"); + glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) load(userptr, "glIsRenderbuffer"); + glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC) load(userptr, "glIsVertexArray"); + glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) load(userptr, "glMapBufferRange"); + glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) load(userptr, "glRenderbufferStorage"); + glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) load(userptr, "glRenderbufferStorageMultisample"); + glad_glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC) load(userptr, "glTexParameterIiv"); + glad_glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC) load(userptr, "glTexParameterIuiv"); + glad_glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) load(userptr, "glTransformFeedbackVaryings"); + glad_glUniform1ui = (PFNGLUNIFORM1UIPROC) load(userptr, "glUniform1ui"); + glad_glUniform1uiv = (PFNGLUNIFORM1UIVPROC) load(userptr, "glUniform1uiv"); + glad_glUniform2ui = (PFNGLUNIFORM2UIPROC) load(userptr, "glUniform2ui"); + glad_glUniform2uiv = (PFNGLUNIFORM2UIVPROC) load(userptr, "glUniform2uiv"); + glad_glUniform3ui = (PFNGLUNIFORM3UIPROC) load(userptr, "glUniform3ui"); + glad_glUniform3uiv = (PFNGLUNIFORM3UIVPROC) load(userptr, "glUniform3uiv"); + glad_glUniform4ui = (PFNGLUNIFORM4UIPROC) load(userptr, "glUniform4ui"); + glad_glUniform4uiv = (PFNGLUNIFORM4UIVPROC) load(userptr, "glUniform4uiv"); + glad_glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC) load(userptr, "glVertexAttribI1i"); + glad_glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC) load(userptr, "glVertexAttribI1iv"); + glad_glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC) load(userptr, "glVertexAttribI1ui"); + glad_glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC) load(userptr, "glVertexAttribI1uiv"); + glad_glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC) load(userptr, "glVertexAttribI2i"); + glad_glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC) load(userptr, "glVertexAttribI2iv"); + glad_glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC) load(userptr, "glVertexAttribI2ui"); + glad_glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC) load(userptr, "glVertexAttribI2uiv"); + glad_glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC) load(userptr, "glVertexAttribI3i"); + glad_glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC) load(userptr, "glVertexAttribI3iv"); + glad_glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC) load(userptr, "glVertexAttribI3ui"); + glad_glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC) load(userptr, "glVertexAttribI3uiv"); + glad_glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC) load(userptr, "glVertexAttribI4bv"); + glad_glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC) load(userptr, "glVertexAttribI4i"); + glad_glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC) load(userptr, "glVertexAttribI4iv"); + glad_glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC) load(userptr, "glVertexAttribI4sv"); + glad_glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC) load(userptr, "glVertexAttribI4ubv"); + glad_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC) load(userptr, "glVertexAttribI4ui"); + glad_glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC) load(userptr, "glVertexAttribI4uiv"); + glad_glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC) load(userptr, "glVertexAttribI4usv"); + glad_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) load(userptr, "glVertexAttribIPointer"); +} +static void glad_gl_load_GL_VERSION_3_1( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_3_1) return; + glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load(userptr, "glBindBufferBase"); + glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load(userptr, "glBindBufferRange"); + glad_glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC) load(userptr, "glCopyBufferSubData"); + glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC) load(userptr, "glDrawArraysInstanced"); + glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC) load(userptr, "glDrawElementsInstanced"); + glad_glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) load(userptr, "glGetActiveUniformBlockName"); + glad_glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC) load(userptr, "glGetActiveUniformBlockiv"); + glad_glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC) load(userptr, "glGetActiveUniformName"); + glad_glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC) load(userptr, "glGetActiveUniformsiv"); + glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load(userptr, "glGetIntegeri_v"); + glad_glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC) load(userptr, "glGetUniformBlockIndex"); + glad_glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC) load(userptr, "glGetUniformIndices"); + glad_glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC) load(userptr, "glPrimitiveRestartIndex"); + glad_glTexBuffer = (PFNGLTEXBUFFERPROC) load(userptr, "glTexBuffer"); + glad_glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC) load(userptr, "glUniformBlockBinding"); +} +static void glad_gl_load_GL_VERSION_3_2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_3_2) return; + glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) load(userptr, "glClientWaitSync"); + glad_glDeleteSync = (PFNGLDELETESYNCPROC) load(userptr, "glDeleteSync"); + glad_glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC) load(userptr, "glDrawElementsBaseVertex"); + glad_glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) load(userptr, "glDrawElementsInstancedBaseVertex"); + glad_glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) load(userptr, "glDrawRangeElementsBaseVertex"); + glad_glFenceSync = (PFNGLFENCESYNCPROC) load(userptr, "glFenceSync"); + glad_glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC) load(userptr, "glFramebufferTexture"); + glad_glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC) load(userptr, "glGetBufferParameteri64v"); + glad_glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC) load(userptr, "glGetInteger64i_v"); + glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC) load(userptr, "glGetInteger64v"); + glad_glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) load(userptr, "glGetMultisamplefv"); + glad_glGetSynciv = (PFNGLGETSYNCIVPROC) load(userptr, "glGetSynciv"); + glad_glIsSync = (PFNGLISSYNCPROC) load(userptr, "glIsSync"); + glad_glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) load(userptr, "glMultiDrawElementsBaseVertex"); + glad_glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC) load(userptr, "glProvokingVertex"); + glad_glSampleMaski = (PFNGLSAMPLEMASKIPROC) load(userptr, "glSampleMaski"); + glad_glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) load(userptr, "glTexImage2DMultisample"); + glad_glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) load(userptr, "glTexImage3DMultisample"); + glad_glWaitSync = (PFNGLWAITSYNCPROC) load(userptr, "glWaitSync"); +} +static void glad_gl_load_GL_VERSION_3_3( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_3_3) return; + glad_glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) load(userptr, "glBindFragDataLocationIndexed"); + glad_glBindSampler = (PFNGLBINDSAMPLERPROC) load(userptr, "glBindSampler"); + glad_glColorP3ui = (PFNGLCOLORP3UIPROC) load(userptr, "glColorP3ui"); + glad_glColorP3uiv = (PFNGLCOLORP3UIVPROC) load(userptr, "glColorP3uiv"); + glad_glColorP4ui = (PFNGLCOLORP4UIPROC) load(userptr, "glColorP4ui"); + glad_glColorP4uiv = (PFNGLCOLORP4UIVPROC) load(userptr, "glColorP4uiv"); + glad_glDeleteSamplers = (PFNGLDELETESAMPLERSPROC) load(userptr, "glDeleteSamplers"); + glad_glGenSamplers = (PFNGLGENSAMPLERSPROC) load(userptr, "glGenSamplers"); + glad_glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC) load(userptr, "glGetFragDataIndex"); + glad_glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC) load(userptr, "glGetQueryObjecti64v"); + glad_glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC) load(userptr, "glGetQueryObjectui64v"); + glad_glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC) load(userptr, "glGetSamplerParameterIiv"); + glad_glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC) load(userptr, "glGetSamplerParameterIuiv"); + glad_glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC) load(userptr, "glGetSamplerParameterfv"); + glad_glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC) load(userptr, "glGetSamplerParameteriv"); + glad_glIsSampler = (PFNGLISSAMPLERPROC) load(userptr, "glIsSampler"); + glad_glMultiTexCoordP1ui = (PFNGLMULTITEXCOORDP1UIPROC) load(userptr, "glMultiTexCoordP1ui"); + glad_glMultiTexCoordP1uiv = (PFNGLMULTITEXCOORDP1UIVPROC) load(userptr, "glMultiTexCoordP1uiv"); + glad_glMultiTexCoordP2ui = (PFNGLMULTITEXCOORDP2UIPROC) load(userptr, "glMultiTexCoordP2ui"); + glad_glMultiTexCoordP2uiv = (PFNGLMULTITEXCOORDP2UIVPROC) load(userptr, "glMultiTexCoordP2uiv"); + glad_glMultiTexCoordP3ui = (PFNGLMULTITEXCOORDP3UIPROC) load(userptr, "glMultiTexCoordP3ui"); + glad_glMultiTexCoordP3uiv = (PFNGLMULTITEXCOORDP3UIVPROC) load(userptr, "glMultiTexCoordP3uiv"); + glad_glMultiTexCoordP4ui = (PFNGLMULTITEXCOORDP4UIPROC) load(userptr, "glMultiTexCoordP4ui"); + glad_glMultiTexCoordP4uiv = (PFNGLMULTITEXCOORDP4UIVPROC) load(userptr, "glMultiTexCoordP4uiv"); + glad_glNormalP3ui = (PFNGLNORMALP3UIPROC) load(userptr, "glNormalP3ui"); + glad_glNormalP3uiv = (PFNGLNORMALP3UIVPROC) load(userptr, "glNormalP3uiv"); + glad_glQueryCounter = (PFNGLQUERYCOUNTERPROC) load(userptr, "glQueryCounter"); + glad_glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC) load(userptr, "glSamplerParameterIiv"); + glad_glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC) load(userptr, "glSamplerParameterIuiv"); + glad_glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) load(userptr, "glSamplerParameterf"); + glad_glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) load(userptr, "glSamplerParameterfv"); + glad_glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) load(userptr, "glSamplerParameteri"); + glad_glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) load(userptr, "glSamplerParameteriv"); + glad_glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC) load(userptr, "glSecondaryColorP3ui"); + glad_glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC) load(userptr, "glSecondaryColorP3uiv"); + glad_glTexCoordP1ui = (PFNGLTEXCOORDP1UIPROC) load(userptr, "glTexCoordP1ui"); + glad_glTexCoordP1uiv = (PFNGLTEXCOORDP1UIVPROC) load(userptr, "glTexCoordP1uiv"); + glad_glTexCoordP2ui = (PFNGLTEXCOORDP2UIPROC) load(userptr, "glTexCoordP2ui"); + glad_glTexCoordP2uiv = (PFNGLTEXCOORDP2UIVPROC) load(userptr, "glTexCoordP2uiv"); + glad_glTexCoordP3ui = (PFNGLTEXCOORDP3UIPROC) load(userptr, "glTexCoordP3ui"); + glad_glTexCoordP3uiv = (PFNGLTEXCOORDP3UIVPROC) load(userptr, "glTexCoordP3uiv"); + glad_glTexCoordP4ui = (PFNGLTEXCOORDP4UIPROC) load(userptr, "glTexCoordP4ui"); + glad_glTexCoordP4uiv = (PFNGLTEXCOORDP4UIVPROC) load(userptr, "glTexCoordP4uiv"); + glad_glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC) load(userptr, "glVertexAttribDivisor"); + glad_glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC) load(userptr, "glVertexAttribP1ui"); + glad_glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC) load(userptr, "glVertexAttribP1uiv"); + glad_glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC) load(userptr, "glVertexAttribP2ui"); + glad_glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC) load(userptr, "glVertexAttribP2uiv"); + glad_glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC) load(userptr, "glVertexAttribP3ui"); + glad_glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC) load(userptr, "glVertexAttribP3uiv"); + glad_glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC) load(userptr, "glVertexAttribP4ui"); + glad_glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC) load(userptr, "glVertexAttribP4uiv"); + glad_glVertexP2ui = (PFNGLVERTEXP2UIPROC) load(userptr, "glVertexP2ui"); + glad_glVertexP2uiv = (PFNGLVERTEXP2UIVPROC) load(userptr, "glVertexP2uiv"); + glad_glVertexP3ui = (PFNGLVERTEXP3UIPROC) load(userptr, "glVertexP3ui"); + glad_glVertexP3uiv = (PFNGLVERTEXP3UIVPROC) load(userptr, "glVertexP3uiv"); + glad_glVertexP4ui = (PFNGLVERTEXP4UIPROC) load(userptr, "glVertexP4ui"); + glad_glVertexP4uiv = (PFNGLVERTEXP4UIVPROC) load(userptr, "glVertexP4uiv"); +} +static void glad_gl_load_GL_ARB_debug_output( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_debug_output) return; + glad_glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC) load(userptr, "glDebugMessageCallbackARB"); + glad_glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) load(userptr, "glDebugMessageControlARB"); + glad_glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC) load(userptr, "glDebugMessageInsertARB"); + glad_glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC) load(userptr, "glGetDebugMessageLogARB"); +} +static void glad_gl_load_GL_ARB_framebuffer_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_framebuffer_object) return; + glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) load(userptr, "glBindFramebuffer"); + glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) load(userptr, "glBindRenderbuffer"); + glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) load(userptr, "glBlitFramebuffer"); + glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckFramebufferStatus"); + glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) load(userptr, "glDeleteFramebuffers"); + glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) load(userptr, "glDeleteRenderbuffers"); + glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glFramebufferRenderbuffer"); + glad_glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) load(userptr, "glFramebufferTexture1D"); + glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) load(userptr, "glFramebufferTexture2D"); + glad_glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) load(userptr, "glFramebufferTexture3D"); + glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) load(userptr, "glFramebufferTextureLayer"); + glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) load(userptr, "glGenFramebuffers"); + glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) load(userptr, "glGenRenderbuffers"); + glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) load(userptr, "glGenerateMipmap"); + glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetFramebufferAttachmentParameteriv"); + glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetRenderbufferParameteriv"); + glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) load(userptr, "glIsFramebuffer"); + glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) load(userptr, "glIsRenderbuffer"); + glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) load(userptr, "glRenderbufferStorage"); + glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) load(userptr, "glRenderbufferStorageMultisample"); +} +static void glad_gl_load_GL_EXT_framebuffer_blit( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_framebuffer_blit) return; + glad_glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC) load(userptr, "glBlitFramebufferEXT"); +} +static void glad_gl_load_GL_EXT_framebuffer_multisample( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_framebuffer_multisample) return; + glad_glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) load(userptr, "glRenderbufferStorageMultisampleEXT"); +} +static void glad_gl_load_GL_EXT_framebuffer_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_framebuffer_object) return; + glad_glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) load(userptr, "glBindFramebufferEXT"); + glad_glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC) load(userptr, "glBindRenderbufferEXT"); + glad_glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) load(userptr, "glCheckFramebufferStatusEXT"); + glad_glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) load(userptr, "glDeleteFramebuffersEXT"); + glad_glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC) load(userptr, "glDeleteRenderbuffersEXT"); + glad_glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) load(userptr, "glFramebufferRenderbufferEXT"); + glad_glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) load(userptr, "glFramebufferTexture1DEXT"); + glad_glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) load(userptr, "glFramebufferTexture2DEXT"); + glad_glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) load(userptr, "glFramebufferTexture3DEXT"); + glad_glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) load(userptr, "glGenFramebuffersEXT"); + glad_glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC) load(userptr, "glGenRenderbuffersEXT"); + glad_glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC) load(userptr, "glGenerateMipmapEXT"); + glad_glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) load(userptr, "glGetFramebufferAttachmentParameterivEXT"); + glad_glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) load(userptr, "glGetRenderbufferParameterivEXT"); + glad_glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC) load(userptr, "glIsFramebufferEXT"); + glad_glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC) load(userptr, "glIsRenderbufferEXT"); + glad_glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC) load(userptr, "glRenderbufferStorageEXT"); +} +static void glad_gl_load_GL_OVR_multiview( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OVR_multiview) return; + glad_glFramebufferTextureMultiviewOVR = (PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) load(userptr, "glFramebufferTextureMultiviewOVR"); +} + + + +#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) +#define GLAD_GL_IS_SOME_NEW_VERSION 1 +#else +#define GLAD_GL_IS_SOME_NEW_VERSION 0 +#endif + +static int glad_gl_get_extensions( int version, const char **out_exts, unsigned int *out_num_exts_i, char ***out_exts_i) { +#if GLAD_GL_IS_SOME_NEW_VERSION + if(GLAD_VERSION_MAJOR(version) < 3) { +#else + GLAD_UNUSED(version); + GLAD_UNUSED(out_num_exts_i); + GLAD_UNUSED(out_exts_i); +#endif + if (glad_glGetString == NULL) { + return 0; + } + *out_exts = (const char *)glad_glGetString(GL_EXTENSIONS); +#if GLAD_GL_IS_SOME_NEW_VERSION + } else { + unsigned int index = 0; + unsigned int num_exts_i = 0; + char **exts_i = NULL; + if (glad_glGetStringi == NULL || glad_glGetIntegerv == NULL) { + return 0; + } + glad_glGetIntegerv(GL_NUM_EXTENSIONS, (int*) &num_exts_i); + if (num_exts_i > 0) { + exts_i = (char **) malloc(num_exts_i * (sizeof *exts_i)); + } + if (exts_i == NULL) { + return 0; + } + for(index = 0; index < num_exts_i; index++) { + const char *gl_str_tmp = (const char*) glad_glGetStringi(GL_EXTENSIONS, index); + size_t len = strlen(gl_str_tmp) + 1; + + char *local_str = (char*) malloc(len * sizeof(char)); + if(local_str != NULL) { + memcpy(local_str, gl_str_tmp, len * sizeof(char)); + } + + exts_i[index] = local_str; + } + + *out_num_exts_i = num_exts_i; + *out_exts_i = exts_i; + } +#endif + return 1; +} +static void glad_gl_free_extensions(char **exts_i, unsigned int num_exts_i) { + if (exts_i != NULL) { + unsigned int index; + for(index = 0; index < num_exts_i; index++) { + free((void *) (exts_i[index])); + } + free((void *)exts_i); + exts_i = NULL; + } +} +static int glad_gl_has_extension(int version, const char *exts, unsigned int num_exts_i, char **exts_i, const char *ext) { + if(GLAD_VERSION_MAJOR(version) < 3 || !GLAD_GL_IS_SOME_NEW_VERSION) { + const char *extensions; + const char *loc; + const char *terminator; + extensions = exts; + if(extensions == NULL || ext == NULL) { + return 0; + } + while(1) { + loc = strstr(extensions, ext); + if(loc == NULL) { + return 0; + } + terminator = loc + strlen(ext); + if((loc == extensions || *(loc - 1) == ' ') && + (*terminator == ' ' || *terminator == '\0')) { + return 1; + } + extensions = terminator; + } + } else { + unsigned int index; + for(index = 0; index < num_exts_i; index++) { + const char *e = exts_i[index]; + if(strcmp(e, ext) == 0) { + return 1; + } + } + } + return 0; +} + +static GLADapiproc glad_gl_get_proc_from_userptr(void *userptr, const char* name) { + return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name); +} + +static int glad_gl_find_extensions_gl( int version) { + const char *exts = NULL; + unsigned int num_exts_i = 0; + char **exts_i = NULL; + if (!glad_gl_get_extensions(version, &exts, &num_exts_i, &exts_i)) return 0; + + GLAD_GL_ARB_debug_output = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_debug_output"); + GLAD_GL_ARB_framebuffer_object = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_framebuffer_object"); + GLAD_GL_EXT_framebuffer_blit = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_framebuffer_blit"); + GLAD_GL_EXT_framebuffer_multisample = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_framebuffer_multisample"); + GLAD_GL_EXT_framebuffer_object = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_framebuffer_object"); + GLAD_GL_OVR_multiview = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_OVR_multiview"); + GLAD_GL_OVR_multiview2 = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_OVR_multiview2"); + + glad_gl_free_extensions(exts_i, num_exts_i); + + return 1; +} + +static int glad_gl_find_core_gl(void) { + int i; + const char* version; + const char* prefixes[] = { + "OpenGL ES-CM ", + "OpenGL ES-CL ", + "OpenGL ES ", + "OpenGL SC ", + NULL + }; + int major = 0; + int minor = 0; + version = (const char*) glad_glGetString(GL_VERSION); + if (!version) return 0; + for (i = 0; prefixes[i]; i++) { + const size_t length = strlen(prefixes[i]); + if (strncmp(version, prefixes[i], length) == 0) { + version += length; + break; + } + } + + GLAD_IMPL_UTIL_SSCANF(version, "%d.%d", &major, &minor); + + GLAD_GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; + GLAD_GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; + GLAD_GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; + GLAD_GL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; + GLAD_GL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; + GLAD_GL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; + GLAD_GL_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; + GLAD_GL_VERSION_2_1 = (major == 2 && minor >= 1) || major > 2; + GLAD_GL_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; + GLAD_GL_VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; + GLAD_GL_VERSION_3_2 = (major == 3 && minor >= 2) || major > 3; + GLAD_GL_VERSION_3_3 = (major == 3 && minor >= 3) || major > 3; + + return GLAD_MAKE_VERSION(major, minor); +} + +int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr) { + int version; + + glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); + if(glad_glGetString == NULL) return 0; + if(glad_glGetString(GL_VERSION) == NULL) return 0; + version = glad_gl_find_core_gl(); + + glad_gl_load_GL_VERSION_1_0(load, userptr); + glad_gl_load_GL_VERSION_1_1(load, userptr); + glad_gl_load_GL_VERSION_1_2(load, userptr); + glad_gl_load_GL_VERSION_1_3(load, userptr); + glad_gl_load_GL_VERSION_1_4(load, userptr); + glad_gl_load_GL_VERSION_1_5(load, userptr); + glad_gl_load_GL_VERSION_2_0(load, userptr); + glad_gl_load_GL_VERSION_2_1(load, userptr); + glad_gl_load_GL_VERSION_3_0(load, userptr); + glad_gl_load_GL_VERSION_3_1(load, userptr); + glad_gl_load_GL_VERSION_3_2(load, userptr); + glad_gl_load_GL_VERSION_3_3(load, userptr); + + if (!glad_gl_find_extensions_gl(version)) return 0; + glad_gl_load_GL_ARB_debug_output(load, userptr); + glad_gl_load_GL_ARB_framebuffer_object(load, userptr); + glad_gl_load_GL_EXT_framebuffer_blit(load, userptr); + glad_gl_load_GL_EXT_framebuffer_multisample(load, userptr); + glad_gl_load_GL_EXT_framebuffer_object(load, userptr); + glad_gl_load_GL_OVR_multiview(load, userptr); + + + + return version; +} + + +int gladLoadGL( GLADloadfunc load) { + return gladLoadGLUserPtr( glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); +} + + + + + +#ifdef GLAD_GL + +#ifndef GLAD_LOADER_LIBRARY_C_ +#define GLAD_LOADER_LIBRARY_C_ + +#include <stddef.h> +#include <stdlib.h> + +#if GLAD_PLATFORM_WIN32 +#include <windows.h> +#else +#include <dlfcn.h> +#endif + + +static void* glad_get_dlopen_handle(const char *lib_names[], int length) { + void *handle = NULL; + int i; + + for (i = 0; i < length; ++i) { +#if GLAD_PLATFORM_WIN32 + #if GLAD_PLATFORM_UWP + size_t buffer_size = (strlen(lib_names[i]) + 1) * sizeof(WCHAR); + LPWSTR buffer = (LPWSTR) malloc(buffer_size); + if (buffer != NULL) { + int ret = MultiByteToWideChar(CP_ACP, 0, lib_names[i], -1, buffer, buffer_size); + if (ret != 0) { + handle = (void*) LoadPackagedLibrary(buffer, 0); + } + free((void*) buffer); + } + #else + handle = (void*) LoadLibraryA(lib_names[i]); + #endif +#else + handle = dlopen(lib_names[i], RTLD_LAZY | RTLD_LOCAL); +#endif + if (handle != NULL) { + return handle; + } + } + + return NULL; +} + +static void glad_close_dlopen_handle(void* handle) { + if (handle != NULL) { +#if GLAD_PLATFORM_WIN32 + FreeLibrary((HMODULE) handle); +#else + dlclose(handle); +#endif + } +} + +static GLADapiproc glad_dlsym_handle(void* handle, const char *name) { + if (handle == NULL) { + return NULL; + } + +#if GLAD_PLATFORM_WIN32 + return (GLADapiproc) GetProcAddress((HMODULE) handle, name); +#else + return GLAD_GNUC_EXTENSION (GLADapiproc) dlsym(handle, name); +#endif +} + +#endif /* GLAD_LOADER_LIBRARY_C_ */ + +typedef void* (GLAD_API_PTR *GLADglprocaddrfunc)(const char*); +struct _glad_gl_userptr { + void *handle; + GLADglprocaddrfunc gl_get_proc_address_ptr; +}; + +static GLADapiproc glad_gl_get_proc(void *vuserptr, const char *name) { + struct _glad_gl_userptr userptr = *(struct _glad_gl_userptr*) vuserptr; + GLADapiproc result = NULL; + + if(userptr.gl_get_proc_address_ptr != NULL) { + result = GLAD_GNUC_EXTENSION (GLADapiproc) userptr.gl_get_proc_address_ptr(name); + } + if(result == NULL) { + result = glad_dlsym_handle(userptr.handle, name); + } + + return result; +} + +static void* _glad_GL_loader_handle = NULL; + +static void* glad_gl_dlopen_handle(void) { +#if GLAD_PLATFORM_APPLE + static const char *NAMES[] = { + "../Frameworks/OpenGL.framework/OpenGL", + "/Library/Frameworks/OpenGL.framework/OpenGL", + "/System/Library/Frameworks/OpenGL.framework/OpenGL", + "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL" + }; +#elif GLAD_PLATFORM_WIN32 + static const char *NAMES[] = {"opengl32.dll"}; +#else + static const char *NAMES[] = { + #if defined(__CYGWIN__) + "libGL-1.so", + #endif + "libGL.so.1", + "libGL.so" + }; +#endif + + if (_glad_GL_loader_handle == NULL) { + _glad_GL_loader_handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0])); + } + + return _glad_GL_loader_handle; +} + +static struct _glad_gl_userptr glad_gl_build_userptr(void *handle) { + struct _glad_gl_userptr userptr; + + userptr.handle = handle; +#if GLAD_PLATFORM_APPLE || defined(__HAIKU__) + userptr.gl_get_proc_address_ptr = NULL; +#elif GLAD_PLATFORM_WIN32 + userptr.gl_get_proc_address_ptr = + (GLADglprocaddrfunc) glad_dlsym_handle(handle, "wglGetProcAddress"); +#else + userptr.gl_get_proc_address_ptr = + (GLADglprocaddrfunc) glad_dlsym_handle(handle, "glXGetProcAddressARB"); +#endif + + return userptr; +} + +int gladLoaderLoadGL(void) { + int version = 0; + void *handle; + int did_load = 0; + struct _glad_gl_userptr userptr; + + did_load = _glad_GL_loader_handle == NULL; + handle = glad_gl_dlopen_handle(); + if (handle) { + userptr = glad_gl_build_userptr(handle); + + version = gladLoadGLUserPtr(glad_gl_get_proc, &userptr); + + if (did_load) { + gladLoaderUnloadGL(); + } + } + + return version; +} + + + +void gladLoaderUnloadGL(void) { + if (_glad_GL_loader_handle != NULL) { + glad_close_dlopen_handle(_glad_GL_loader_handle); + _glad_GL_loader_handle = NULL; + } +} + +#endif /* GLAD_GL */ + +#ifdef __cplusplus +} +#endif diff --git a/thirdparty/glad/glad.c b/thirdparty/glad/glad.c deleted file mode 100644 index 4b20178ef7..0000000000 --- a/thirdparty/glad/glad.c +++ /dev/null @@ -1,1951 +0,0 @@ -/* - - OpenGL loader generated by glad 0.1.36 on Sun Sep 4 15:50:32 2022. - - Language/Generator: C/C++ - Specification: gl - APIs: gl=3.3 - Profile: compatibility - Extensions: - GL_ARB_debug_output, - GL_ARB_framebuffer_object, - GL_EXT_framebuffer_blit, - GL_EXT_framebuffer_multisample, - GL_EXT_framebuffer_object, - GL_OVR_multiview, - GL_OVR_multiview2 - Loader: True - Local files: False - Omit khrplatform: False - Reproducible: False - - Commandline: - --profile="compatibility" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_ARB_debug_output,GL_ARB_framebuffer_object,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_object,GL_OVR_multiview,GL_OVR_multiview2" - Online: - https://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gl%3D3.3&extensions=GL_ARB_debug_output&extensions=GL_ARB_framebuffer_object&extensions=GL_EXT_framebuffer_blit&extensions=GL_EXT_framebuffer_multisample&extensions=GL_EXT_framebuffer_object&extensions=GL_OVR_multiview&extensions=GL_OVR_multiview2 -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <glad/glad.h> - -static void* get_proc(const char *namez); - -#if defined(_WIN32) || defined(__CYGWIN__) -#ifndef _WINDOWS_ -#undef APIENTRY -#endif -#include <windows.h> -static HMODULE libGL; - -typedef void* (APIENTRYP PFNWGLGETPROCADDRESSPROC_PRIVATE)(const char*); -static PFNWGLGETPROCADDRESSPROC_PRIVATE gladGetProcAddressPtr; - -#ifdef _MSC_VER -#ifdef __has_include - #if __has_include(<winapifamily.h>) - #define HAVE_WINAPIFAMILY 1 - #endif -#elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ - #define HAVE_WINAPIFAMILY 1 -#endif -#endif - -#ifdef HAVE_WINAPIFAMILY - #include <winapifamily.h> - #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) - #define IS_UWP 1 - #endif -#endif - -static -int open_gl(void) { -#ifndef IS_UWP - libGL = LoadLibraryW(L"opengl32.dll"); - if(libGL != NULL) { - void (* tmp)(void); - tmp = (void(*)(void)) GetProcAddress(libGL, "wglGetProcAddress"); - gladGetProcAddressPtr = (PFNWGLGETPROCADDRESSPROC_PRIVATE) tmp; - return gladGetProcAddressPtr != NULL; - } -#endif - - return 0; -} - -static -void close_gl(void) { - if(libGL != NULL) { - FreeLibrary((HMODULE) libGL); - libGL = NULL; - } -} -#else -#include <dlfcn.h> -static void* libGL; - -#if !defined(__APPLE__) && !defined(__HAIKU__) -typedef void* (APIENTRYP PFNGLXGETPROCADDRESSPROC_PRIVATE)(const char*); -static PFNGLXGETPROCADDRESSPROC_PRIVATE gladGetProcAddressPtr; -#endif - -static -int open_gl(void) { -#ifdef __APPLE__ - static const char *NAMES[] = { - "../Frameworks/OpenGL.framework/OpenGL", - "/Library/Frameworks/OpenGL.framework/OpenGL", - "/System/Library/Frameworks/OpenGL.framework/OpenGL", - "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL" - }; -#else - static const char *NAMES[] = {"libGL.so.1", "libGL.so"}; -#endif - - unsigned int index = 0; - for(index = 0; index < (sizeof(NAMES) / sizeof(NAMES[0])); index++) { - libGL = dlopen(NAMES[index], RTLD_NOW | RTLD_GLOBAL); - - if(libGL != NULL) { -#if defined(__APPLE__) || defined(__HAIKU__) - return 1; -#else - gladGetProcAddressPtr = (PFNGLXGETPROCADDRESSPROC_PRIVATE)dlsym(libGL, - "glXGetProcAddressARB"); - return gladGetProcAddressPtr != NULL; -#endif - } - } - - return 0; -} - -static -void close_gl(void) { - if(libGL != NULL) { - dlclose(libGL); - libGL = NULL; - } -} -#endif - -static -void* get_proc(const char *namez) { - void* result = NULL; - if(libGL == NULL) return NULL; - -#if !defined(__APPLE__) && !defined(__HAIKU__) - if(gladGetProcAddressPtr != NULL) { - result = gladGetProcAddressPtr(namez); - } -#endif - if(result == NULL) { -#if defined(_WIN32) || defined(__CYGWIN__) - result = (void*)GetProcAddress((HMODULE) libGL, namez); -#else - result = dlsym(libGL, namez); -#endif - } - - return result; -} - -int gladLoadGL(void) { - int status = 0; - - if(open_gl()) { - status = gladLoadGLLoader(&get_proc); - close_gl(); - } - - return status; -} - -struct gladGLversionStruct GLVersion = { 0, 0 }; - -#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) -#define _GLAD_IS_SOME_NEW_VERSION 1 -#endif - -static int max_loaded_major; -static int max_loaded_minor; - -static const char *exts = NULL; -static int num_exts_i = 0; -static char **exts_i = NULL; - -static int get_exts(void) { -#ifdef _GLAD_IS_SOME_NEW_VERSION - if(max_loaded_major < 3) { -#endif - exts = (const char *)glGetString(GL_EXTENSIONS); -#ifdef _GLAD_IS_SOME_NEW_VERSION - } else { - unsigned int index; - - num_exts_i = 0; - glGetIntegerv(GL_NUM_EXTENSIONS, &num_exts_i); - if (num_exts_i > 0) { - exts_i = (char **)malloc((size_t)num_exts_i * (sizeof *exts_i)); - } - - if (exts_i == NULL) { - return 0; - } - - for(index = 0; index < (unsigned)num_exts_i; index++) { - const char *gl_str_tmp = (const char*)glGetStringi(GL_EXTENSIONS, index); - size_t len = strlen(gl_str_tmp); - - char *local_str = (char*)malloc((len+1) * sizeof(char)); - if(local_str != NULL) { - memcpy(local_str, gl_str_tmp, (len+1) * sizeof(char)); - } - exts_i[index] = local_str; - } - } -#endif - return 1; -} - -static void free_exts(void) { - if (exts_i != NULL) { - int index; - for(index = 0; index < num_exts_i; index++) { - free((char *)exts_i[index]); - } - free((void *)exts_i); - exts_i = NULL; - } -} - -static int has_ext(const char *ext) { -#ifdef _GLAD_IS_SOME_NEW_VERSION - if(max_loaded_major < 3) { -#endif - const char *extensions; - const char *loc; - const char *terminator; - extensions = exts; - if(extensions == NULL || ext == NULL) { - return 0; - } - - while(1) { - loc = strstr(extensions, ext); - if(loc == NULL) { - return 0; - } - - terminator = loc + strlen(ext); - if((loc == extensions || *(loc - 1) == ' ') && - (*terminator == ' ' || *terminator == '\0')) { - return 1; - } - extensions = terminator; - } -#ifdef _GLAD_IS_SOME_NEW_VERSION - } else { - int index; - if(exts_i == NULL) return 0; - for(index = 0; index < num_exts_i; index++) { - const char *e = exts_i[index]; - - if(exts_i[index] != NULL && strcmp(e, ext) == 0) { - return 1; - } - } - } -#endif - - return 0; -} -int GLAD_GL_VERSION_1_0 = 0; -int GLAD_GL_VERSION_1_1 = 0; -int GLAD_GL_VERSION_1_2 = 0; -int GLAD_GL_VERSION_1_3 = 0; -int GLAD_GL_VERSION_1_4 = 0; -int GLAD_GL_VERSION_1_5 = 0; -int GLAD_GL_VERSION_2_0 = 0; -int GLAD_GL_VERSION_2_1 = 0; -int GLAD_GL_VERSION_3_0 = 0; -int GLAD_GL_VERSION_3_1 = 0; -int GLAD_GL_VERSION_3_2 = 0; -int GLAD_GL_VERSION_3_3 = 0; -PFNGLACCUMPROC glad_glAccum = NULL; -PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; -PFNGLALPHAFUNCPROC glad_glAlphaFunc = NULL; -PFNGLARETEXTURESRESIDENTPROC glad_glAreTexturesResident = NULL; -PFNGLARRAYELEMENTPROC glad_glArrayElement = NULL; -PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; -PFNGLBEGINPROC glad_glBegin = NULL; -PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL; -PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL; -PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL; -PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL; -PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL; -PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL; -PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL; -PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation = NULL; -PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed = NULL; -PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL; -PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL; -PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL; -PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL; -PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL; -PFNGLBITMAPPROC glad_glBitmap = NULL; -PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; -PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL; -PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL; -PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL; -PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL; -PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL; -PFNGLBUFFERDATAPROC glad_glBufferData = NULL; -PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL; -PFNGLCALLLISTPROC glad_glCallList = NULL; -PFNGLCALLLISTSPROC glad_glCallLists = NULL; -PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL; -PFNGLCLAMPCOLORPROC glad_glClampColor = NULL; -PFNGLCLEARPROC glad_glClear = NULL; -PFNGLCLEARACCUMPROC glad_glClearAccum = NULL; -PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL; -PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL; -PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL; -PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL; -PFNGLCLEARCOLORPROC glad_glClearColor = NULL; -PFNGLCLEARDEPTHPROC glad_glClearDepth = NULL; -PFNGLCLEARINDEXPROC glad_glClearIndex = NULL; -PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL; -PFNGLCLIENTACTIVETEXTUREPROC glad_glClientActiveTexture = NULL; -PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL; -PFNGLCLIPPLANEPROC glad_glClipPlane = NULL; -PFNGLCOLOR3BPROC glad_glColor3b = NULL; -PFNGLCOLOR3BVPROC glad_glColor3bv = NULL; -PFNGLCOLOR3DPROC glad_glColor3d = NULL; -PFNGLCOLOR3DVPROC glad_glColor3dv = NULL; -PFNGLCOLOR3FPROC glad_glColor3f = NULL; -PFNGLCOLOR3FVPROC glad_glColor3fv = NULL; -PFNGLCOLOR3IPROC glad_glColor3i = NULL; -PFNGLCOLOR3IVPROC glad_glColor3iv = NULL; -PFNGLCOLOR3SPROC glad_glColor3s = NULL; -PFNGLCOLOR3SVPROC glad_glColor3sv = NULL; -PFNGLCOLOR3UBPROC glad_glColor3ub = NULL; -PFNGLCOLOR3UBVPROC glad_glColor3ubv = NULL; -PFNGLCOLOR3UIPROC glad_glColor3ui = NULL; -PFNGLCOLOR3UIVPROC glad_glColor3uiv = NULL; -PFNGLCOLOR3USPROC glad_glColor3us = NULL; -PFNGLCOLOR3USVPROC glad_glColor3usv = NULL; -PFNGLCOLOR4BPROC glad_glColor4b = NULL; -PFNGLCOLOR4BVPROC glad_glColor4bv = NULL; -PFNGLCOLOR4DPROC glad_glColor4d = NULL; -PFNGLCOLOR4DVPROC glad_glColor4dv = NULL; -PFNGLCOLOR4FPROC glad_glColor4f = NULL; -PFNGLCOLOR4FVPROC glad_glColor4fv = NULL; -PFNGLCOLOR4IPROC glad_glColor4i = NULL; -PFNGLCOLOR4IVPROC glad_glColor4iv = NULL; -PFNGLCOLOR4SPROC glad_glColor4s = NULL; -PFNGLCOLOR4SVPROC glad_glColor4sv = NULL; -PFNGLCOLOR4UBPROC glad_glColor4ub = NULL; -PFNGLCOLOR4UBVPROC glad_glColor4ubv = NULL; -PFNGLCOLOR4UIPROC glad_glColor4ui = NULL; -PFNGLCOLOR4UIVPROC glad_glColor4uiv = NULL; -PFNGLCOLOR4USPROC glad_glColor4us = NULL; -PFNGLCOLOR4USVPROC glad_glColor4usv = NULL; -PFNGLCOLORMASKPROC glad_glColorMask = NULL; -PFNGLCOLORMASKIPROC glad_glColorMaski = NULL; -PFNGLCOLORMATERIALPROC glad_glColorMaterial = NULL; -PFNGLCOLORP3UIPROC glad_glColorP3ui = NULL; -PFNGLCOLORP3UIVPROC glad_glColorP3uiv = NULL; -PFNGLCOLORP4UIPROC glad_glColorP4ui = NULL; -PFNGLCOLORP4UIVPROC glad_glColorP4uiv = NULL; -PFNGLCOLORPOINTERPROC glad_glColorPointer = NULL; -PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; -PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D = NULL; -PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; -PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL; -PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL; -PFNGLCOPYPIXELSPROC glad_glCopyPixels = NULL; -PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL; -PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; -PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL; -PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL; -PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL; -PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL; -PFNGLCREATESHADERPROC glad_glCreateShader = NULL; -PFNGLCULLFACEPROC glad_glCullFace = NULL; -PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL; -PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; -PFNGLDELETELISTSPROC glad_glDeleteLists = NULL; -PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; -PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL; -PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL; -PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL; -PFNGLDELETESHADERPROC glad_glDeleteShader = NULL; -PFNGLDELETESYNCPROC glad_glDeleteSync = NULL; -PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL; -PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL; -PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL; -PFNGLDEPTHMASKPROC glad_glDepthMask = NULL; -PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL; -PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; -PFNGLDISABLEPROC glad_glDisable = NULL; -PFNGLDISABLECLIENTSTATEPROC glad_glDisableClientState = NULL; -PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL; -PFNGLDISABLEIPROC glad_glDisablei = NULL; -PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; -PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL; -PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL; -PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL; -PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; -PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex = NULL; -PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL; -PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL; -PFNGLDRAWPIXELSPROC glad_glDrawPixels = NULL; -PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL; -PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL; -PFNGLEDGEFLAGPROC glad_glEdgeFlag = NULL; -PFNGLEDGEFLAGPOINTERPROC glad_glEdgeFlagPointer = NULL; -PFNGLEDGEFLAGVPROC glad_glEdgeFlagv = NULL; -PFNGLENABLEPROC glad_glEnable = NULL; -PFNGLENABLECLIENTSTATEPROC glad_glEnableClientState = NULL; -PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; -PFNGLENABLEIPROC glad_glEnablei = NULL; -PFNGLENDPROC glad_glEnd = NULL; -PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL; -PFNGLENDLISTPROC glad_glEndList = NULL; -PFNGLENDQUERYPROC glad_glEndQuery = NULL; -PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL; -PFNGLEVALCOORD1DPROC glad_glEvalCoord1d = NULL; -PFNGLEVALCOORD1DVPROC glad_glEvalCoord1dv = NULL; -PFNGLEVALCOORD1FPROC glad_glEvalCoord1f = NULL; -PFNGLEVALCOORD1FVPROC glad_glEvalCoord1fv = NULL; -PFNGLEVALCOORD2DPROC glad_glEvalCoord2d = NULL; -PFNGLEVALCOORD2DVPROC glad_glEvalCoord2dv = NULL; -PFNGLEVALCOORD2FPROC glad_glEvalCoord2f = NULL; -PFNGLEVALCOORD2FVPROC glad_glEvalCoord2fv = NULL; -PFNGLEVALMESH1PROC glad_glEvalMesh1 = NULL; -PFNGLEVALMESH2PROC glad_glEvalMesh2 = NULL; -PFNGLEVALPOINT1PROC glad_glEvalPoint1 = NULL; -PFNGLEVALPOINT2PROC glad_glEvalPoint2 = NULL; -PFNGLFEEDBACKBUFFERPROC glad_glFeedbackBuffer = NULL; -PFNGLFENCESYNCPROC glad_glFenceSync = NULL; -PFNGLFINISHPROC glad_glFinish = NULL; -PFNGLFLUSHPROC glad_glFlush = NULL; -PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL; -PFNGLFOGCOORDPOINTERPROC glad_glFogCoordPointer = NULL; -PFNGLFOGCOORDDPROC glad_glFogCoordd = NULL; -PFNGLFOGCOORDDVPROC glad_glFogCoorddv = NULL; -PFNGLFOGCOORDFPROC glad_glFogCoordf = NULL; -PFNGLFOGCOORDFVPROC glad_glFogCoordfv = NULL; -PFNGLFOGFPROC glad_glFogf = NULL; -PFNGLFOGFVPROC glad_glFogfv = NULL; -PFNGLFOGIPROC glad_glFogi = NULL; -PFNGLFOGIVPROC glad_glFogiv = NULL; -PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; -PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture = NULL; -PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D = NULL; -PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; -PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D = NULL; -PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL; -PFNGLFRONTFACEPROC glad_glFrontFace = NULL; -PFNGLFRUSTUMPROC glad_glFrustum = NULL; -PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; -PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; -PFNGLGENLISTSPROC glad_glGenLists = NULL; -PFNGLGENQUERIESPROC glad_glGenQueries = NULL; -PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; -PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL; -PFNGLGENTEXTURESPROC glad_glGenTextures = NULL; -PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL; -PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL; -PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL; -PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL; -PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL; -PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL; -PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName = NULL; -PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL; -PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL; -PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL; -PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL; -PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL; -PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL; -PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; -PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL; -PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData = NULL; -PFNGLGETCLIPPLANEPROC glad_glGetClipPlane = NULL; -PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage = NULL; -PFNGLGETDOUBLEVPROC glad_glGetDoublev = NULL; -PFNGLGETERRORPROC glad_glGetError = NULL; -PFNGLGETFLOATVPROC glad_glGetFloatv = NULL; -PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex = NULL; -PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL; -PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL; -PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL; -PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL; -PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL; -PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; -PFNGLGETLIGHTFVPROC glad_glGetLightfv = NULL; -PFNGLGETLIGHTIVPROC glad_glGetLightiv = NULL; -PFNGLGETMAPDVPROC glad_glGetMapdv = NULL; -PFNGLGETMAPFVPROC glad_glGetMapfv = NULL; -PFNGLGETMAPIVPROC glad_glGetMapiv = NULL; -PFNGLGETMATERIALFVPROC glad_glGetMaterialfv = NULL; -PFNGLGETMATERIALIVPROC glad_glGetMaterialiv = NULL; -PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL; -PFNGLGETPIXELMAPFVPROC glad_glGetPixelMapfv = NULL; -PFNGLGETPIXELMAPUIVPROC glad_glGetPixelMapuiv = NULL; -PFNGLGETPIXELMAPUSVPROC glad_glGetPixelMapusv = NULL; -PFNGLGETPOINTERVPROC glad_glGetPointerv = NULL; -PFNGLGETPOLYGONSTIPPLEPROC glad_glGetPolygonStipple = NULL; -PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; -PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL; -PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v = NULL; -PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv = NULL; -PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v = NULL; -PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL; -PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL; -PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL; -PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv = NULL; -PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv = NULL; -PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL; -PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL; -PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL; -PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL; -PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL; -PFNGLGETSTRINGPROC glad_glGetString = NULL; -PFNGLGETSTRINGIPROC glad_glGetStringi = NULL; -PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL; -PFNGLGETTEXENVFVPROC glad_glGetTexEnvfv = NULL; -PFNGLGETTEXENVIVPROC glad_glGetTexEnviv = NULL; -PFNGLGETTEXGENDVPROC glad_glGetTexGendv = NULL; -PFNGLGETTEXGENFVPROC glad_glGetTexGenfv = NULL; -PFNGLGETTEXGENIVPROC glad_glGetTexGeniv = NULL; -PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL; -PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL; -PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL; -PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv = NULL; -PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv = NULL; -PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL; -PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL; -PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL; -PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL; -PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL; -PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL; -PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL; -PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL; -PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL; -PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL; -PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL; -PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL; -PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv = NULL; -PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL; -PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL; -PFNGLHINTPROC glad_glHint = NULL; -PFNGLINDEXMASKPROC glad_glIndexMask = NULL; -PFNGLINDEXPOINTERPROC glad_glIndexPointer = NULL; -PFNGLINDEXDPROC glad_glIndexd = NULL; -PFNGLINDEXDVPROC glad_glIndexdv = NULL; -PFNGLINDEXFPROC glad_glIndexf = NULL; -PFNGLINDEXFVPROC glad_glIndexfv = NULL; -PFNGLINDEXIPROC glad_glIndexi = NULL; -PFNGLINDEXIVPROC glad_glIndexiv = NULL; -PFNGLINDEXSPROC glad_glIndexs = NULL; -PFNGLINDEXSVPROC glad_glIndexsv = NULL; -PFNGLINDEXUBPROC glad_glIndexub = NULL; -PFNGLINDEXUBVPROC glad_glIndexubv = NULL; -PFNGLINITNAMESPROC glad_glInitNames = NULL; -PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays = NULL; -PFNGLISBUFFERPROC glad_glIsBuffer = NULL; -PFNGLISENABLEDPROC glad_glIsEnabled = NULL; -PFNGLISENABLEDIPROC glad_glIsEnabledi = NULL; -PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; -PFNGLISLISTPROC glad_glIsList = NULL; -PFNGLISPROGRAMPROC glad_glIsProgram = NULL; -PFNGLISQUERYPROC glad_glIsQuery = NULL; -PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL; -PFNGLISSAMPLERPROC glad_glIsSampler = NULL; -PFNGLISSHADERPROC glad_glIsShader = NULL; -PFNGLISSYNCPROC glad_glIsSync = NULL; -PFNGLISTEXTUREPROC glad_glIsTexture = NULL; -PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL; -PFNGLLIGHTMODELFPROC glad_glLightModelf = NULL; -PFNGLLIGHTMODELFVPROC glad_glLightModelfv = NULL; -PFNGLLIGHTMODELIPROC glad_glLightModeli = NULL; -PFNGLLIGHTMODELIVPROC glad_glLightModeliv = NULL; -PFNGLLIGHTFPROC glad_glLightf = NULL; -PFNGLLIGHTFVPROC glad_glLightfv = NULL; -PFNGLLIGHTIPROC glad_glLighti = NULL; -PFNGLLIGHTIVPROC glad_glLightiv = NULL; -PFNGLLINESTIPPLEPROC glad_glLineStipple = NULL; -PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; -PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL; -PFNGLLISTBASEPROC glad_glListBase = NULL; -PFNGLLOADIDENTITYPROC glad_glLoadIdentity = NULL; -PFNGLLOADMATRIXDPROC glad_glLoadMatrixd = NULL; -PFNGLLOADMATRIXFPROC glad_glLoadMatrixf = NULL; -PFNGLLOADNAMEPROC glad_glLoadName = NULL; -PFNGLLOADTRANSPOSEMATRIXDPROC glad_glLoadTransposeMatrixd = NULL; -PFNGLLOADTRANSPOSEMATRIXFPROC glad_glLoadTransposeMatrixf = NULL; -PFNGLLOGICOPPROC glad_glLogicOp = NULL; -PFNGLMAP1DPROC glad_glMap1d = NULL; -PFNGLMAP1FPROC glad_glMap1f = NULL; -PFNGLMAP2DPROC glad_glMap2d = NULL; -PFNGLMAP2FPROC glad_glMap2f = NULL; -PFNGLMAPBUFFERPROC glad_glMapBuffer = NULL; -PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL; -PFNGLMAPGRID1DPROC glad_glMapGrid1d = NULL; -PFNGLMAPGRID1FPROC glad_glMapGrid1f = NULL; -PFNGLMAPGRID2DPROC glad_glMapGrid2d = NULL; -PFNGLMAPGRID2FPROC glad_glMapGrid2f = NULL; -PFNGLMATERIALFPROC glad_glMaterialf = NULL; -PFNGLMATERIALFVPROC glad_glMaterialfv = NULL; -PFNGLMATERIALIPROC glad_glMateriali = NULL; -PFNGLMATERIALIVPROC glad_glMaterialiv = NULL; -PFNGLMATRIXMODEPROC glad_glMatrixMode = NULL; -PFNGLMULTMATRIXDPROC glad_glMultMatrixd = NULL; -PFNGLMULTMATRIXFPROC glad_glMultMatrixf = NULL; -PFNGLMULTTRANSPOSEMATRIXDPROC glad_glMultTransposeMatrixd = NULL; -PFNGLMULTTRANSPOSEMATRIXFPROC glad_glMultTransposeMatrixf = NULL; -PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL; -PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL; -PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex = NULL; -PFNGLMULTITEXCOORD1DPROC glad_glMultiTexCoord1d = NULL; -PFNGLMULTITEXCOORD1DVPROC glad_glMultiTexCoord1dv = NULL; -PFNGLMULTITEXCOORD1FPROC glad_glMultiTexCoord1f = NULL; -PFNGLMULTITEXCOORD1FVPROC glad_glMultiTexCoord1fv = NULL; -PFNGLMULTITEXCOORD1IPROC glad_glMultiTexCoord1i = NULL; -PFNGLMULTITEXCOORD1IVPROC glad_glMultiTexCoord1iv = NULL; -PFNGLMULTITEXCOORD1SPROC glad_glMultiTexCoord1s = NULL; -PFNGLMULTITEXCOORD1SVPROC glad_glMultiTexCoord1sv = NULL; -PFNGLMULTITEXCOORD2DPROC glad_glMultiTexCoord2d = NULL; -PFNGLMULTITEXCOORD2DVPROC glad_glMultiTexCoord2dv = NULL; -PFNGLMULTITEXCOORD2FPROC glad_glMultiTexCoord2f = NULL; -PFNGLMULTITEXCOORD2FVPROC glad_glMultiTexCoord2fv = NULL; -PFNGLMULTITEXCOORD2IPROC glad_glMultiTexCoord2i = NULL; -PFNGLMULTITEXCOORD2IVPROC glad_glMultiTexCoord2iv = NULL; -PFNGLMULTITEXCOORD2SPROC glad_glMultiTexCoord2s = NULL; -PFNGLMULTITEXCOORD2SVPROC glad_glMultiTexCoord2sv = NULL; -PFNGLMULTITEXCOORD3DPROC glad_glMultiTexCoord3d = NULL; -PFNGLMULTITEXCOORD3DVPROC glad_glMultiTexCoord3dv = NULL; -PFNGLMULTITEXCOORD3FPROC glad_glMultiTexCoord3f = NULL; -PFNGLMULTITEXCOORD3FVPROC glad_glMultiTexCoord3fv = NULL; -PFNGLMULTITEXCOORD3IPROC glad_glMultiTexCoord3i = NULL; -PFNGLMULTITEXCOORD3IVPROC glad_glMultiTexCoord3iv = NULL; -PFNGLMULTITEXCOORD3SPROC glad_glMultiTexCoord3s = NULL; -PFNGLMULTITEXCOORD3SVPROC glad_glMultiTexCoord3sv = NULL; -PFNGLMULTITEXCOORD4DPROC glad_glMultiTexCoord4d = NULL; -PFNGLMULTITEXCOORD4DVPROC glad_glMultiTexCoord4dv = NULL; -PFNGLMULTITEXCOORD4FPROC glad_glMultiTexCoord4f = NULL; -PFNGLMULTITEXCOORD4FVPROC glad_glMultiTexCoord4fv = NULL; -PFNGLMULTITEXCOORD4IPROC glad_glMultiTexCoord4i = NULL; -PFNGLMULTITEXCOORD4IVPROC glad_glMultiTexCoord4iv = NULL; -PFNGLMULTITEXCOORD4SPROC glad_glMultiTexCoord4s = NULL; -PFNGLMULTITEXCOORD4SVPROC glad_glMultiTexCoord4sv = NULL; -PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui = NULL; -PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv = NULL; -PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui = NULL; -PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv = NULL; -PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui = NULL; -PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv = NULL; -PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui = NULL; -PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv = NULL; -PFNGLNEWLISTPROC glad_glNewList = NULL; -PFNGLNORMAL3BPROC glad_glNormal3b = NULL; -PFNGLNORMAL3BVPROC glad_glNormal3bv = NULL; -PFNGLNORMAL3DPROC glad_glNormal3d = NULL; -PFNGLNORMAL3DVPROC glad_glNormal3dv = NULL; -PFNGLNORMAL3FPROC glad_glNormal3f = NULL; -PFNGLNORMAL3FVPROC glad_glNormal3fv = NULL; -PFNGLNORMAL3IPROC glad_glNormal3i = NULL; -PFNGLNORMAL3IVPROC glad_glNormal3iv = NULL; -PFNGLNORMAL3SPROC glad_glNormal3s = NULL; -PFNGLNORMAL3SVPROC glad_glNormal3sv = NULL; -PFNGLNORMALP3UIPROC glad_glNormalP3ui = NULL; -PFNGLNORMALP3UIVPROC glad_glNormalP3uiv = NULL; -PFNGLNORMALPOINTERPROC glad_glNormalPointer = NULL; -PFNGLORTHOPROC glad_glOrtho = NULL; -PFNGLPASSTHROUGHPROC glad_glPassThrough = NULL; -PFNGLPIXELMAPFVPROC glad_glPixelMapfv = NULL; -PFNGLPIXELMAPUIVPROC glad_glPixelMapuiv = NULL; -PFNGLPIXELMAPUSVPROC glad_glPixelMapusv = NULL; -PFNGLPIXELSTOREFPROC glad_glPixelStoref = NULL; -PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; -PFNGLPIXELTRANSFERFPROC glad_glPixelTransferf = NULL; -PFNGLPIXELTRANSFERIPROC glad_glPixelTransferi = NULL; -PFNGLPIXELZOOMPROC glad_glPixelZoom = NULL; -PFNGLPOINTPARAMETERFPROC glad_glPointParameterf = NULL; -PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv = NULL; -PFNGLPOINTPARAMETERIPROC glad_glPointParameteri = NULL; -PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv = NULL; -PFNGLPOINTSIZEPROC glad_glPointSize = NULL; -PFNGLPOLYGONMODEPROC glad_glPolygonMode = NULL; -PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; -PFNGLPOLYGONSTIPPLEPROC glad_glPolygonStipple = NULL; -PFNGLPOPATTRIBPROC glad_glPopAttrib = NULL; -PFNGLPOPCLIENTATTRIBPROC glad_glPopClientAttrib = NULL; -PFNGLPOPMATRIXPROC glad_glPopMatrix = NULL; -PFNGLPOPNAMEPROC glad_glPopName = NULL; -PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex = NULL; -PFNGLPRIORITIZETEXTURESPROC glad_glPrioritizeTextures = NULL; -PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex = NULL; -PFNGLPUSHATTRIBPROC glad_glPushAttrib = NULL; -PFNGLPUSHCLIENTATTRIBPROC glad_glPushClientAttrib = NULL; -PFNGLPUSHMATRIXPROC glad_glPushMatrix = NULL; -PFNGLPUSHNAMEPROC glad_glPushName = NULL; -PFNGLQUERYCOUNTERPROC glad_glQueryCounter = NULL; -PFNGLRASTERPOS2DPROC glad_glRasterPos2d = NULL; -PFNGLRASTERPOS2DVPROC glad_glRasterPos2dv = NULL; -PFNGLRASTERPOS2FPROC glad_glRasterPos2f = NULL; -PFNGLRASTERPOS2FVPROC glad_glRasterPos2fv = NULL; -PFNGLRASTERPOS2IPROC glad_glRasterPos2i = NULL; -PFNGLRASTERPOS2IVPROC glad_glRasterPos2iv = NULL; -PFNGLRASTERPOS2SPROC glad_glRasterPos2s = NULL; -PFNGLRASTERPOS2SVPROC glad_glRasterPos2sv = NULL; -PFNGLRASTERPOS3DPROC glad_glRasterPos3d = NULL; -PFNGLRASTERPOS3DVPROC glad_glRasterPos3dv = NULL; -PFNGLRASTERPOS3FPROC glad_glRasterPos3f = NULL; -PFNGLRASTERPOS3FVPROC glad_glRasterPos3fv = NULL; -PFNGLRASTERPOS3IPROC glad_glRasterPos3i = NULL; -PFNGLRASTERPOS3IVPROC glad_glRasterPos3iv = NULL; -PFNGLRASTERPOS3SPROC glad_glRasterPos3s = NULL; -PFNGLRASTERPOS3SVPROC glad_glRasterPos3sv = NULL; -PFNGLRASTERPOS4DPROC glad_glRasterPos4d = NULL; -PFNGLRASTERPOS4DVPROC glad_glRasterPos4dv = NULL; -PFNGLRASTERPOS4FPROC glad_glRasterPos4f = NULL; -PFNGLRASTERPOS4FVPROC glad_glRasterPos4fv = NULL; -PFNGLRASTERPOS4IPROC glad_glRasterPos4i = NULL; -PFNGLRASTERPOS4IVPROC glad_glRasterPos4iv = NULL; -PFNGLRASTERPOS4SPROC glad_glRasterPos4s = NULL; -PFNGLRASTERPOS4SVPROC glad_glRasterPos4sv = NULL; -PFNGLREADBUFFERPROC glad_glReadBuffer = NULL; -PFNGLREADPIXELSPROC glad_glReadPixels = NULL; -PFNGLRECTDPROC glad_glRectd = NULL; -PFNGLRECTDVPROC glad_glRectdv = NULL; -PFNGLRECTFPROC glad_glRectf = NULL; -PFNGLRECTFVPROC glad_glRectfv = NULL; -PFNGLRECTIPROC glad_glRecti = NULL; -PFNGLRECTIVPROC glad_glRectiv = NULL; -PFNGLRECTSPROC glad_glRects = NULL; -PFNGLRECTSVPROC glad_glRectsv = NULL; -PFNGLRENDERMODEPROC glad_glRenderMode = NULL; -PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; -PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL; -PFNGLROTATEDPROC glad_glRotated = NULL; -PFNGLROTATEFPROC glad_glRotatef = NULL; -PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; -PFNGLSAMPLEMASKIPROC glad_glSampleMaski = NULL; -PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv = NULL; -PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv = NULL; -PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL; -PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL; -PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL; -PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = NULL; -PFNGLSCALEDPROC glad_glScaled = NULL; -PFNGLSCALEFPROC glad_glScalef = NULL; -PFNGLSCISSORPROC glad_glScissor = NULL; -PFNGLSECONDARYCOLOR3BPROC glad_glSecondaryColor3b = NULL; -PFNGLSECONDARYCOLOR3BVPROC glad_glSecondaryColor3bv = NULL; -PFNGLSECONDARYCOLOR3DPROC glad_glSecondaryColor3d = NULL; -PFNGLSECONDARYCOLOR3DVPROC glad_glSecondaryColor3dv = NULL; -PFNGLSECONDARYCOLOR3FPROC glad_glSecondaryColor3f = NULL; -PFNGLSECONDARYCOLOR3FVPROC glad_glSecondaryColor3fv = NULL; -PFNGLSECONDARYCOLOR3IPROC glad_glSecondaryColor3i = NULL; -PFNGLSECONDARYCOLOR3IVPROC glad_glSecondaryColor3iv = NULL; -PFNGLSECONDARYCOLOR3SPROC glad_glSecondaryColor3s = NULL; -PFNGLSECONDARYCOLOR3SVPROC glad_glSecondaryColor3sv = NULL; -PFNGLSECONDARYCOLOR3UBPROC glad_glSecondaryColor3ub = NULL; -PFNGLSECONDARYCOLOR3UBVPROC glad_glSecondaryColor3ubv = NULL; -PFNGLSECONDARYCOLOR3UIPROC glad_glSecondaryColor3ui = NULL; -PFNGLSECONDARYCOLOR3UIVPROC glad_glSecondaryColor3uiv = NULL; -PFNGLSECONDARYCOLOR3USPROC glad_glSecondaryColor3us = NULL; -PFNGLSECONDARYCOLOR3USVPROC glad_glSecondaryColor3usv = NULL; -PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui = NULL; -PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv = NULL; -PFNGLSECONDARYCOLORPOINTERPROC glad_glSecondaryColorPointer = NULL; -PFNGLSELECTBUFFERPROC glad_glSelectBuffer = NULL; -PFNGLSHADEMODELPROC glad_glShadeModel = NULL; -PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL; -PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL; -PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL; -PFNGLSTENCILMASKPROC glad_glStencilMask = NULL; -PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL; -PFNGLSTENCILOPPROC glad_glStencilOp = NULL; -PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL; -PFNGLTEXBUFFERPROC glad_glTexBuffer = NULL; -PFNGLTEXCOORD1DPROC glad_glTexCoord1d = NULL; -PFNGLTEXCOORD1DVPROC glad_glTexCoord1dv = NULL; -PFNGLTEXCOORD1FPROC glad_glTexCoord1f = NULL; -PFNGLTEXCOORD1FVPROC glad_glTexCoord1fv = NULL; -PFNGLTEXCOORD1IPROC glad_glTexCoord1i = NULL; -PFNGLTEXCOORD1IVPROC glad_glTexCoord1iv = NULL; -PFNGLTEXCOORD1SPROC glad_glTexCoord1s = NULL; -PFNGLTEXCOORD1SVPROC glad_glTexCoord1sv = NULL; -PFNGLTEXCOORD2DPROC glad_glTexCoord2d = NULL; -PFNGLTEXCOORD2DVPROC glad_glTexCoord2dv = NULL; -PFNGLTEXCOORD2FPROC glad_glTexCoord2f = NULL; -PFNGLTEXCOORD2FVPROC glad_glTexCoord2fv = NULL; -PFNGLTEXCOORD2IPROC glad_glTexCoord2i = NULL; -PFNGLTEXCOORD2IVPROC glad_glTexCoord2iv = NULL; -PFNGLTEXCOORD2SPROC glad_glTexCoord2s = NULL; -PFNGLTEXCOORD2SVPROC glad_glTexCoord2sv = NULL; -PFNGLTEXCOORD3DPROC glad_glTexCoord3d = NULL; -PFNGLTEXCOORD3DVPROC glad_glTexCoord3dv = NULL; -PFNGLTEXCOORD3FPROC glad_glTexCoord3f = NULL; -PFNGLTEXCOORD3FVPROC glad_glTexCoord3fv = NULL; -PFNGLTEXCOORD3IPROC glad_glTexCoord3i = NULL; -PFNGLTEXCOORD3IVPROC glad_glTexCoord3iv = NULL; -PFNGLTEXCOORD3SPROC glad_glTexCoord3s = NULL; -PFNGLTEXCOORD3SVPROC glad_glTexCoord3sv = NULL; -PFNGLTEXCOORD4DPROC glad_glTexCoord4d = NULL; -PFNGLTEXCOORD4DVPROC glad_glTexCoord4dv = NULL; -PFNGLTEXCOORD4FPROC glad_glTexCoord4f = NULL; -PFNGLTEXCOORD4FVPROC glad_glTexCoord4fv = NULL; -PFNGLTEXCOORD4IPROC glad_glTexCoord4i = NULL; -PFNGLTEXCOORD4IVPROC glad_glTexCoord4iv = NULL; -PFNGLTEXCOORD4SPROC glad_glTexCoord4s = NULL; -PFNGLTEXCOORD4SVPROC glad_glTexCoord4sv = NULL; -PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui = NULL; -PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv = NULL; -PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui = NULL; -PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv = NULL; -PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui = NULL; -PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv = NULL; -PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui = NULL; -PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv = NULL; -PFNGLTEXCOORDPOINTERPROC glad_glTexCoordPointer = NULL; -PFNGLTEXENVFPROC glad_glTexEnvf = NULL; -PFNGLTEXENVFVPROC glad_glTexEnvfv = NULL; -PFNGLTEXENVIPROC glad_glTexEnvi = NULL; -PFNGLTEXENVIVPROC glad_glTexEnviv = NULL; -PFNGLTEXGENDPROC glad_glTexGend = NULL; -PFNGLTEXGENDVPROC glad_glTexGendv = NULL; -PFNGLTEXGENFPROC glad_glTexGenf = NULL; -PFNGLTEXGENFVPROC glad_glTexGenfv = NULL; -PFNGLTEXGENIPROC glad_glTexGeni = NULL; -PFNGLTEXGENIVPROC glad_glTexGeniv = NULL; -PFNGLTEXIMAGE1DPROC glad_glTexImage1D = NULL; -PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL; -PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample = NULL; -PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL; -PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample = NULL; -PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv = NULL; -PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv = NULL; -PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL; -PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL; -PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL; -PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL; -PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D = NULL; -PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL; -PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL; -PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL; -PFNGLTRANSLATEDPROC glad_glTranslated = NULL; -PFNGLTRANSLATEFPROC glad_glTranslatef = NULL; -PFNGLUNIFORM1FPROC glad_glUniform1f = NULL; -PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL; -PFNGLUNIFORM1IPROC glad_glUniform1i = NULL; -PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL; -PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL; -PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL; -PFNGLUNIFORM2FPROC glad_glUniform2f = NULL; -PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL; -PFNGLUNIFORM2IPROC glad_glUniform2i = NULL; -PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL; -PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL; -PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL; -PFNGLUNIFORM3FPROC glad_glUniform3f = NULL; -PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL; -PFNGLUNIFORM3IPROC glad_glUniform3i = NULL; -PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL; -PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL; -PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL; -PFNGLUNIFORM4FPROC glad_glUniform4f = NULL; -PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL; -PFNGLUNIFORM4IPROC glad_glUniform4i = NULL; -PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL; -PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL; -PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL; -PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL; -PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL; -PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL; -PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL; -PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL; -PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL; -PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL; -PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL; -PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL; -PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL; -PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL; -PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL; -PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL; -PFNGLVERTEX2DPROC glad_glVertex2d = NULL; -PFNGLVERTEX2DVPROC glad_glVertex2dv = NULL; -PFNGLVERTEX2FPROC glad_glVertex2f = NULL; -PFNGLVERTEX2FVPROC glad_glVertex2fv = NULL; -PFNGLVERTEX2IPROC glad_glVertex2i = NULL; -PFNGLVERTEX2IVPROC glad_glVertex2iv = NULL; -PFNGLVERTEX2SPROC glad_glVertex2s = NULL; -PFNGLVERTEX2SVPROC glad_glVertex2sv = NULL; -PFNGLVERTEX3DPROC glad_glVertex3d = NULL; -PFNGLVERTEX3DVPROC glad_glVertex3dv = NULL; -PFNGLVERTEX3FPROC glad_glVertex3f = NULL; -PFNGLVERTEX3FVPROC glad_glVertex3fv = NULL; -PFNGLVERTEX3IPROC glad_glVertex3i = NULL; -PFNGLVERTEX3IVPROC glad_glVertex3iv = NULL; -PFNGLVERTEX3SPROC glad_glVertex3s = NULL; -PFNGLVERTEX3SVPROC glad_glVertex3sv = NULL; -PFNGLVERTEX4DPROC glad_glVertex4d = NULL; -PFNGLVERTEX4DVPROC glad_glVertex4dv = NULL; -PFNGLVERTEX4FPROC glad_glVertex4f = NULL; -PFNGLVERTEX4FVPROC glad_glVertex4fv = NULL; -PFNGLVERTEX4IPROC glad_glVertex4i = NULL; -PFNGLVERTEX4IVPROC glad_glVertex4iv = NULL; -PFNGLVERTEX4SPROC glad_glVertex4s = NULL; -PFNGLVERTEX4SVPROC glad_glVertex4sv = NULL; -PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d = NULL; -PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv = NULL; -PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL; -PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL; -PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s = NULL; -PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv = NULL; -PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d = NULL; -PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv = NULL; -PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL; -PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL; -PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s = NULL; -PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv = NULL; -PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d = NULL; -PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv = NULL; -PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL; -PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL; -PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s = NULL; -PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv = NULL; -PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv = NULL; -PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv = NULL; -PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv = NULL; -PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub = NULL; -PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv = NULL; -PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv = NULL; -PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv = NULL; -PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv = NULL; -PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d = NULL; -PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv = NULL; -PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL; -PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL; -PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv = NULL; -PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s = NULL; -PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv = NULL; -PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv = NULL; -PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv = NULL; -PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv = NULL; -PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL; -PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i = NULL; -PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv = NULL; -PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui = NULL; -PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv = NULL; -PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i = NULL; -PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv = NULL; -PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui = NULL; -PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv = NULL; -PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i = NULL; -PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv = NULL; -PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui = NULL; -PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv = NULL; -PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv = NULL; -PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL; -PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL; -PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv = NULL; -PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv = NULL; -PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL; -PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL; -PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv = NULL; -PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL; -PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui = NULL; -PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv = NULL; -PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui = NULL; -PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv = NULL; -PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui = NULL; -PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv = NULL; -PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui = NULL; -PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv = NULL; -PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL; -PFNGLVERTEXP2UIPROC glad_glVertexP2ui = NULL; -PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv = NULL; -PFNGLVERTEXP3UIPROC glad_glVertexP3ui = NULL; -PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv = NULL; -PFNGLVERTEXP4UIPROC glad_glVertexP4ui = NULL; -PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv = NULL; -PFNGLVERTEXPOINTERPROC glad_glVertexPointer = NULL; -PFNGLVIEWPORTPROC glad_glViewport = NULL; -PFNGLWAITSYNCPROC glad_glWaitSync = NULL; -PFNGLWINDOWPOS2DPROC glad_glWindowPos2d = NULL; -PFNGLWINDOWPOS2DVPROC glad_glWindowPos2dv = NULL; -PFNGLWINDOWPOS2FPROC glad_glWindowPos2f = NULL; -PFNGLWINDOWPOS2FVPROC glad_glWindowPos2fv = NULL; -PFNGLWINDOWPOS2IPROC glad_glWindowPos2i = NULL; -PFNGLWINDOWPOS2IVPROC glad_glWindowPos2iv = NULL; -PFNGLWINDOWPOS2SPROC glad_glWindowPos2s = NULL; -PFNGLWINDOWPOS2SVPROC glad_glWindowPos2sv = NULL; -PFNGLWINDOWPOS3DPROC glad_glWindowPos3d = NULL; -PFNGLWINDOWPOS3DVPROC glad_glWindowPos3dv = NULL; -PFNGLWINDOWPOS3FPROC glad_glWindowPos3f = NULL; -PFNGLWINDOWPOS3FVPROC glad_glWindowPos3fv = NULL; -PFNGLWINDOWPOS3IPROC glad_glWindowPos3i = NULL; -PFNGLWINDOWPOS3IVPROC glad_glWindowPos3iv = NULL; -PFNGLWINDOWPOS3SPROC glad_glWindowPos3s = NULL; -PFNGLWINDOWPOS3SVPROC glad_glWindowPos3sv = NULL; -int GLAD_GL_ARB_debug_output = 0; -int GLAD_GL_ARB_framebuffer_object = 0; -int GLAD_GL_EXT_framebuffer_blit = 0; -int GLAD_GL_EXT_framebuffer_multisample = 0; -int GLAD_GL_EXT_framebuffer_object = 0; -int GLAD_GL_OVR_multiview = 0; -int GLAD_GL_OVR_multiview2 = 0; -PFNGLDEBUGMESSAGECONTROLARBPROC glad_glDebugMessageControlARB = NULL; -PFNGLDEBUGMESSAGEINSERTARBPROC glad_glDebugMessageInsertARB = NULL; -PFNGLDEBUGMESSAGECALLBACKARBPROC glad_glDebugMessageCallbackARB = NULL; -PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB = NULL; -PFNGLBLITFRAMEBUFFEREXTPROC glad_glBlitFramebufferEXT = NULL; -PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT = NULL; -PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbufferEXT = NULL; -PFNGLBINDRENDERBUFFEREXTPROC glad_glBindRenderbufferEXT = NULL; -PFNGLDELETERENDERBUFFERSEXTPROC glad_glDeleteRenderbuffersEXT = NULL; -PFNGLGENRENDERBUFFERSEXTPROC glad_glGenRenderbuffersEXT = NULL; -PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT = NULL; -PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glad_glGetRenderbufferParameterivEXT = NULL; -PFNGLISFRAMEBUFFEREXTPROC glad_glIsFramebufferEXT = NULL; -PFNGLBINDFRAMEBUFFEREXTPROC glad_glBindFramebufferEXT = NULL; -PFNGLDELETEFRAMEBUFFERSEXTPROC glad_glDeleteFramebuffersEXT = NULL; -PFNGLGENFRAMEBUFFERSEXTPROC glad_glGenFramebuffersEXT = NULL; -PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glad_glCheckFramebufferStatusEXT = NULL; -PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glad_glFramebufferTexture1DEXT = NULL; -PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glad_glFramebufferTexture2DEXT = NULL; -PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glad_glFramebufferTexture3DEXT = NULL; -PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glad_glFramebufferRenderbufferEXT = NULL; -PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetFramebufferAttachmentParameterivEXT = NULL; -PFNGLGENERATEMIPMAPEXTPROC glad_glGenerateMipmapEXT = NULL; -PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glad_glFramebufferTextureMultiviewOVR = NULL; -static void load_GL_VERSION_1_0(GLADloadproc load) { - if(!GLAD_GL_VERSION_1_0) return; - glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace"); - glad_glFrontFace = (PFNGLFRONTFACEPROC)load("glFrontFace"); - glad_glHint = (PFNGLHINTPROC)load("glHint"); - glad_glLineWidth = (PFNGLLINEWIDTHPROC)load("glLineWidth"); - glad_glPointSize = (PFNGLPOINTSIZEPROC)load("glPointSize"); - glad_glPolygonMode = (PFNGLPOLYGONMODEPROC)load("glPolygonMode"); - glad_glScissor = (PFNGLSCISSORPROC)load("glScissor"); - glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC)load("glTexParameterf"); - glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC)load("glTexParameterfv"); - glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC)load("glTexParameteri"); - glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC)load("glTexParameteriv"); - glad_glTexImage1D = (PFNGLTEXIMAGE1DPROC)load("glTexImage1D"); - glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC)load("glTexImage2D"); - glad_glDrawBuffer = (PFNGLDRAWBUFFERPROC)load("glDrawBuffer"); - glad_glClear = (PFNGLCLEARPROC)load("glClear"); - glad_glClearColor = (PFNGLCLEARCOLORPROC)load("glClearColor"); - glad_glClearStencil = (PFNGLCLEARSTENCILPROC)load("glClearStencil"); - glad_glClearDepth = (PFNGLCLEARDEPTHPROC)load("glClearDepth"); - glad_glStencilMask = (PFNGLSTENCILMASKPROC)load("glStencilMask"); - glad_glColorMask = (PFNGLCOLORMASKPROC)load("glColorMask"); - glad_glDepthMask = (PFNGLDEPTHMASKPROC)load("glDepthMask"); - glad_glDisable = (PFNGLDISABLEPROC)load("glDisable"); - glad_glEnable = (PFNGLENABLEPROC)load("glEnable"); - glad_glFinish = (PFNGLFINISHPROC)load("glFinish"); - glad_glFlush = (PFNGLFLUSHPROC)load("glFlush"); - glad_glBlendFunc = (PFNGLBLENDFUNCPROC)load("glBlendFunc"); - glad_glLogicOp = (PFNGLLOGICOPPROC)load("glLogicOp"); - glad_glStencilFunc = (PFNGLSTENCILFUNCPROC)load("glStencilFunc"); - glad_glStencilOp = (PFNGLSTENCILOPPROC)load("glStencilOp"); - glad_glDepthFunc = (PFNGLDEPTHFUNCPROC)load("glDepthFunc"); - glad_glPixelStoref = (PFNGLPIXELSTOREFPROC)load("glPixelStoref"); - glad_glPixelStorei = (PFNGLPIXELSTOREIPROC)load("glPixelStorei"); - glad_glReadBuffer = (PFNGLREADBUFFERPROC)load("glReadBuffer"); - glad_glReadPixels = (PFNGLREADPIXELSPROC)load("glReadPixels"); - glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC)load("glGetBooleanv"); - glad_glGetDoublev = (PFNGLGETDOUBLEVPROC)load("glGetDoublev"); - glad_glGetError = (PFNGLGETERRORPROC)load("glGetError"); - glad_glGetFloatv = (PFNGLGETFLOATVPROC)load("glGetFloatv"); - glad_glGetIntegerv = (PFNGLGETINTEGERVPROC)load("glGetIntegerv"); - glad_glGetString = (PFNGLGETSTRINGPROC)load("glGetString"); - glad_glGetTexImage = (PFNGLGETTEXIMAGEPROC)load("glGetTexImage"); - glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC)load("glGetTexParameterfv"); - glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC)load("glGetTexParameteriv"); - glad_glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC)load("glGetTexLevelParameterfv"); - glad_glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC)load("glGetTexLevelParameteriv"); - glad_glIsEnabled = (PFNGLISENABLEDPROC)load("glIsEnabled"); - glad_glDepthRange = (PFNGLDEPTHRANGEPROC)load("glDepthRange"); - glad_glViewport = (PFNGLVIEWPORTPROC)load("glViewport"); - glad_glNewList = (PFNGLNEWLISTPROC)load("glNewList"); - glad_glEndList = (PFNGLENDLISTPROC)load("glEndList"); - glad_glCallList = (PFNGLCALLLISTPROC)load("glCallList"); - glad_glCallLists = (PFNGLCALLLISTSPROC)load("glCallLists"); - glad_glDeleteLists = (PFNGLDELETELISTSPROC)load("glDeleteLists"); - glad_glGenLists = (PFNGLGENLISTSPROC)load("glGenLists"); - glad_glListBase = (PFNGLLISTBASEPROC)load("glListBase"); - glad_glBegin = (PFNGLBEGINPROC)load("glBegin"); - glad_glBitmap = (PFNGLBITMAPPROC)load("glBitmap"); - glad_glColor3b = (PFNGLCOLOR3BPROC)load("glColor3b"); - glad_glColor3bv = (PFNGLCOLOR3BVPROC)load("glColor3bv"); - glad_glColor3d = (PFNGLCOLOR3DPROC)load("glColor3d"); - glad_glColor3dv = (PFNGLCOLOR3DVPROC)load("glColor3dv"); - glad_glColor3f = (PFNGLCOLOR3FPROC)load("glColor3f"); - glad_glColor3fv = (PFNGLCOLOR3FVPROC)load("glColor3fv"); - glad_glColor3i = (PFNGLCOLOR3IPROC)load("glColor3i"); - glad_glColor3iv = (PFNGLCOLOR3IVPROC)load("glColor3iv"); - glad_glColor3s = (PFNGLCOLOR3SPROC)load("glColor3s"); - glad_glColor3sv = (PFNGLCOLOR3SVPROC)load("glColor3sv"); - glad_glColor3ub = (PFNGLCOLOR3UBPROC)load("glColor3ub"); - glad_glColor3ubv = (PFNGLCOLOR3UBVPROC)load("glColor3ubv"); - glad_glColor3ui = (PFNGLCOLOR3UIPROC)load("glColor3ui"); - glad_glColor3uiv = (PFNGLCOLOR3UIVPROC)load("glColor3uiv"); - glad_glColor3us = (PFNGLCOLOR3USPROC)load("glColor3us"); - glad_glColor3usv = (PFNGLCOLOR3USVPROC)load("glColor3usv"); - glad_glColor4b = (PFNGLCOLOR4BPROC)load("glColor4b"); - glad_glColor4bv = (PFNGLCOLOR4BVPROC)load("glColor4bv"); - glad_glColor4d = (PFNGLCOLOR4DPROC)load("glColor4d"); - glad_glColor4dv = (PFNGLCOLOR4DVPROC)load("glColor4dv"); - glad_glColor4f = (PFNGLCOLOR4FPROC)load("glColor4f"); - glad_glColor4fv = (PFNGLCOLOR4FVPROC)load("glColor4fv"); - glad_glColor4i = (PFNGLCOLOR4IPROC)load("glColor4i"); - glad_glColor4iv = (PFNGLCOLOR4IVPROC)load("glColor4iv"); - glad_glColor4s = (PFNGLCOLOR4SPROC)load("glColor4s"); - glad_glColor4sv = (PFNGLCOLOR4SVPROC)load("glColor4sv"); - glad_glColor4ub = (PFNGLCOLOR4UBPROC)load("glColor4ub"); - glad_glColor4ubv = (PFNGLCOLOR4UBVPROC)load("glColor4ubv"); - glad_glColor4ui = (PFNGLCOLOR4UIPROC)load("glColor4ui"); - glad_glColor4uiv = (PFNGLCOLOR4UIVPROC)load("glColor4uiv"); - glad_glColor4us = (PFNGLCOLOR4USPROC)load("glColor4us"); - glad_glColor4usv = (PFNGLCOLOR4USVPROC)load("glColor4usv"); - glad_glEdgeFlag = (PFNGLEDGEFLAGPROC)load("glEdgeFlag"); - glad_glEdgeFlagv = (PFNGLEDGEFLAGVPROC)load("glEdgeFlagv"); - glad_glEnd = (PFNGLENDPROC)load("glEnd"); - glad_glIndexd = (PFNGLINDEXDPROC)load("glIndexd"); - glad_glIndexdv = (PFNGLINDEXDVPROC)load("glIndexdv"); - glad_glIndexf = (PFNGLINDEXFPROC)load("glIndexf"); - glad_glIndexfv = (PFNGLINDEXFVPROC)load("glIndexfv"); - glad_glIndexi = (PFNGLINDEXIPROC)load("glIndexi"); - glad_glIndexiv = (PFNGLINDEXIVPROC)load("glIndexiv"); - glad_glIndexs = (PFNGLINDEXSPROC)load("glIndexs"); - glad_glIndexsv = (PFNGLINDEXSVPROC)load("glIndexsv"); - glad_glNormal3b = (PFNGLNORMAL3BPROC)load("glNormal3b"); - glad_glNormal3bv = (PFNGLNORMAL3BVPROC)load("glNormal3bv"); - glad_glNormal3d = (PFNGLNORMAL3DPROC)load("glNormal3d"); - glad_glNormal3dv = (PFNGLNORMAL3DVPROC)load("glNormal3dv"); - glad_glNormal3f = (PFNGLNORMAL3FPROC)load("glNormal3f"); - glad_glNormal3fv = (PFNGLNORMAL3FVPROC)load("glNormal3fv"); - glad_glNormal3i = (PFNGLNORMAL3IPROC)load("glNormal3i"); - glad_glNormal3iv = (PFNGLNORMAL3IVPROC)load("glNormal3iv"); - glad_glNormal3s = (PFNGLNORMAL3SPROC)load("glNormal3s"); - glad_glNormal3sv = (PFNGLNORMAL3SVPROC)load("glNormal3sv"); - glad_glRasterPos2d = (PFNGLRASTERPOS2DPROC)load("glRasterPos2d"); - glad_glRasterPos2dv = (PFNGLRASTERPOS2DVPROC)load("glRasterPos2dv"); - glad_glRasterPos2f = (PFNGLRASTERPOS2FPROC)load("glRasterPos2f"); - glad_glRasterPos2fv = (PFNGLRASTERPOS2FVPROC)load("glRasterPos2fv"); - glad_glRasterPos2i = (PFNGLRASTERPOS2IPROC)load("glRasterPos2i"); - glad_glRasterPos2iv = (PFNGLRASTERPOS2IVPROC)load("glRasterPos2iv"); - glad_glRasterPos2s = (PFNGLRASTERPOS2SPROC)load("glRasterPos2s"); - glad_glRasterPos2sv = (PFNGLRASTERPOS2SVPROC)load("glRasterPos2sv"); - glad_glRasterPos3d = (PFNGLRASTERPOS3DPROC)load("glRasterPos3d"); - glad_glRasterPos3dv = (PFNGLRASTERPOS3DVPROC)load("glRasterPos3dv"); - glad_glRasterPos3f = (PFNGLRASTERPOS3FPROC)load("glRasterPos3f"); - glad_glRasterPos3fv = (PFNGLRASTERPOS3FVPROC)load("glRasterPos3fv"); - glad_glRasterPos3i = (PFNGLRASTERPOS3IPROC)load("glRasterPos3i"); - glad_glRasterPos3iv = (PFNGLRASTERPOS3IVPROC)load("glRasterPos3iv"); - glad_glRasterPos3s = (PFNGLRASTERPOS3SPROC)load("glRasterPos3s"); - glad_glRasterPos3sv = (PFNGLRASTERPOS3SVPROC)load("glRasterPos3sv"); - glad_glRasterPos4d = (PFNGLRASTERPOS4DPROC)load("glRasterPos4d"); - glad_glRasterPos4dv = (PFNGLRASTERPOS4DVPROC)load("glRasterPos4dv"); - glad_glRasterPos4f = (PFNGLRASTERPOS4FPROC)load("glRasterPos4f"); - glad_glRasterPos4fv = (PFNGLRASTERPOS4FVPROC)load("glRasterPos4fv"); - glad_glRasterPos4i = (PFNGLRASTERPOS4IPROC)load("glRasterPos4i"); - glad_glRasterPos4iv = (PFNGLRASTERPOS4IVPROC)load("glRasterPos4iv"); - glad_glRasterPos4s = (PFNGLRASTERPOS4SPROC)load("glRasterPos4s"); - glad_glRasterPos4sv = (PFNGLRASTERPOS4SVPROC)load("glRasterPos4sv"); - glad_glRectd = (PFNGLRECTDPROC)load("glRectd"); - glad_glRectdv = (PFNGLRECTDVPROC)load("glRectdv"); - glad_glRectf = (PFNGLRECTFPROC)load("glRectf"); - glad_glRectfv = (PFNGLRECTFVPROC)load("glRectfv"); - glad_glRecti = (PFNGLRECTIPROC)load("glRecti"); - glad_glRectiv = (PFNGLRECTIVPROC)load("glRectiv"); - glad_glRects = (PFNGLRECTSPROC)load("glRects"); - glad_glRectsv = (PFNGLRECTSVPROC)load("glRectsv"); - glad_glTexCoord1d = (PFNGLTEXCOORD1DPROC)load("glTexCoord1d"); - glad_glTexCoord1dv = (PFNGLTEXCOORD1DVPROC)load("glTexCoord1dv"); - glad_glTexCoord1f = (PFNGLTEXCOORD1FPROC)load("glTexCoord1f"); - glad_glTexCoord1fv = (PFNGLTEXCOORD1FVPROC)load("glTexCoord1fv"); - glad_glTexCoord1i = (PFNGLTEXCOORD1IPROC)load("glTexCoord1i"); - glad_glTexCoord1iv = (PFNGLTEXCOORD1IVPROC)load("glTexCoord1iv"); - glad_glTexCoord1s = (PFNGLTEXCOORD1SPROC)load("glTexCoord1s"); - glad_glTexCoord1sv = (PFNGLTEXCOORD1SVPROC)load("glTexCoord1sv"); - glad_glTexCoord2d = (PFNGLTEXCOORD2DPROC)load("glTexCoord2d"); - glad_glTexCoord2dv = (PFNGLTEXCOORD2DVPROC)load("glTexCoord2dv"); - glad_glTexCoord2f = (PFNGLTEXCOORD2FPROC)load("glTexCoord2f"); - glad_glTexCoord2fv = (PFNGLTEXCOORD2FVPROC)load("glTexCoord2fv"); - glad_glTexCoord2i = (PFNGLTEXCOORD2IPROC)load("glTexCoord2i"); - glad_glTexCoord2iv = (PFNGLTEXCOORD2IVPROC)load("glTexCoord2iv"); - glad_glTexCoord2s = (PFNGLTEXCOORD2SPROC)load("glTexCoord2s"); - glad_glTexCoord2sv = (PFNGLTEXCOORD2SVPROC)load("glTexCoord2sv"); - glad_glTexCoord3d = (PFNGLTEXCOORD3DPROC)load("glTexCoord3d"); - glad_glTexCoord3dv = (PFNGLTEXCOORD3DVPROC)load("glTexCoord3dv"); - glad_glTexCoord3f = (PFNGLTEXCOORD3FPROC)load("glTexCoord3f"); - glad_glTexCoord3fv = (PFNGLTEXCOORD3FVPROC)load("glTexCoord3fv"); - glad_glTexCoord3i = (PFNGLTEXCOORD3IPROC)load("glTexCoord3i"); - glad_glTexCoord3iv = (PFNGLTEXCOORD3IVPROC)load("glTexCoord3iv"); - glad_glTexCoord3s = (PFNGLTEXCOORD3SPROC)load("glTexCoord3s"); - glad_glTexCoord3sv = (PFNGLTEXCOORD3SVPROC)load("glTexCoord3sv"); - glad_glTexCoord4d = (PFNGLTEXCOORD4DPROC)load("glTexCoord4d"); - glad_glTexCoord4dv = (PFNGLTEXCOORD4DVPROC)load("glTexCoord4dv"); - glad_glTexCoord4f = (PFNGLTEXCOORD4FPROC)load("glTexCoord4f"); - glad_glTexCoord4fv = (PFNGLTEXCOORD4FVPROC)load("glTexCoord4fv"); - glad_glTexCoord4i = (PFNGLTEXCOORD4IPROC)load("glTexCoord4i"); - glad_glTexCoord4iv = (PFNGLTEXCOORD4IVPROC)load("glTexCoord4iv"); - glad_glTexCoord4s = (PFNGLTEXCOORD4SPROC)load("glTexCoord4s"); - glad_glTexCoord4sv = (PFNGLTEXCOORD4SVPROC)load("glTexCoord4sv"); - glad_glVertex2d = (PFNGLVERTEX2DPROC)load("glVertex2d"); - glad_glVertex2dv = (PFNGLVERTEX2DVPROC)load("glVertex2dv"); - glad_glVertex2f = (PFNGLVERTEX2FPROC)load("glVertex2f"); - glad_glVertex2fv = (PFNGLVERTEX2FVPROC)load("glVertex2fv"); - glad_glVertex2i = (PFNGLVERTEX2IPROC)load("glVertex2i"); - glad_glVertex2iv = (PFNGLVERTEX2IVPROC)load("glVertex2iv"); - glad_glVertex2s = (PFNGLVERTEX2SPROC)load("glVertex2s"); - glad_glVertex2sv = (PFNGLVERTEX2SVPROC)load("glVertex2sv"); - glad_glVertex3d = (PFNGLVERTEX3DPROC)load("glVertex3d"); - glad_glVertex3dv = (PFNGLVERTEX3DVPROC)load("glVertex3dv"); - glad_glVertex3f = (PFNGLVERTEX3FPROC)load("glVertex3f"); - glad_glVertex3fv = (PFNGLVERTEX3FVPROC)load("glVertex3fv"); - glad_glVertex3i = (PFNGLVERTEX3IPROC)load("glVertex3i"); - glad_glVertex3iv = (PFNGLVERTEX3IVPROC)load("glVertex3iv"); - glad_glVertex3s = (PFNGLVERTEX3SPROC)load("glVertex3s"); - glad_glVertex3sv = (PFNGLVERTEX3SVPROC)load("glVertex3sv"); - glad_glVertex4d = (PFNGLVERTEX4DPROC)load("glVertex4d"); - glad_glVertex4dv = (PFNGLVERTEX4DVPROC)load("glVertex4dv"); - glad_glVertex4f = (PFNGLVERTEX4FPROC)load("glVertex4f"); - glad_glVertex4fv = (PFNGLVERTEX4FVPROC)load("glVertex4fv"); - glad_glVertex4i = (PFNGLVERTEX4IPROC)load("glVertex4i"); - glad_glVertex4iv = (PFNGLVERTEX4IVPROC)load("glVertex4iv"); - glad_glVertex4s = (PFNGLVERTEX4SPROC)load("glVertex4s"); - glad_glVertex4sv = (PFNGLVERTEX4SVPROC)load("glVertex4sv"); - glad_glClipPlane = (PFNGLCLIPPLANEPROC)load("glClipPlane"); - glad_glColorMaterial = (PFNGLCOLORMATERIALPROC)load("glColorMaterial"); - glad_glFogf = (PFNGLFOGFPROC)load("glFogf"); - glad_glFogfv = (PFNGLFOGFVPROC)load("glFogfv"); - glad_glFogi = (PFNGLFOGIPROC)load("glFogi"); - glad_glFogiv = (PFNGLFOGIVPROC)load("glFogiv"); - glad_glLightf = (PFNGLLIGHTFPROC)load("glLightf"); - glad_glLightfv = (PFNGLLIGHTFVPROC)load("glLightfv"); - glad_glLighti = (PFNGLLIGHTIPROC)load("glLighti"); - glad_glLightiv = (PFNGLLIGHTIVPROC)load("glLightiv"); - glad_glLightModelf = (PFNGLLIGHTMODELFPROC)load("glLightModelf"); - glad_glLightModelfv = (PFNGLLIGHTMODELFVPROC)load("glLightModelfv"); - glad_glLightModeli = (PFNGLLIGHTMODELIPROC)load("glLightModeli"); - glad_glLightModeliv = (PFNGLLIGHTMODELIVPROC)load("glLightModeliv"); - glad_glLineStipple = (PFNGLLINESTIPPLEPROC)load("glLineStipple"); - glad_glMaterialf = (PFNGLMATERIALFPROC)load("glMaterialf"); - glad_glMaterialfv = (PFNGLMATERIALFVPROC)load("glMaterialfv"); - glad_glMateriali = (PFNGLMATERIALIPROC)load("glMateriali"); - glad_glMaterialiv = (PFNGLMATERIALIVPROC)load("glMaterialiv"); - glad_glPolygonStipple = (PFNGLPOLYGONSTIPPLEPROC)load("glPolygonStipple"); - glad_glShadeModel = (PFNGLSHADEMODELPROC)load("glShadeModel"); - glad_glTexEnvf = (PFNGLTEXENVFPROC)load("glTexEnvf"); - glad_glTexEnvfv = (PFNGLTEXENVFVPROC)load("glTexEnvfv"); - glad_glTexEnvi = (PFNGLTEXENVIPROC)load("glTexEnvi"); - glad_glTexEnviv = (PFNGLTEXENVIVPROC)load("glTexEnviv"); - glad_glTexGend = (PFNGLTEXGENDPROC)load("glTexGend"); - glad_glTexGendv = (PFNGLTEXGENDVPROC)load("glTexGendv"); - glad_glTexGenf = (PFNGLTEXGENFPROC)load("glTexGenf"); - glad_glTexGenfv = (PFNGLTEXGENFVPROC)load("glTexGenfv"); - glad_glTexGeni = (PFNGLTEXGENIPROC)load("glTexGeni"); - glad_glTexGeniv = (PFNGLTEXGENIVPROC)load("glTexGeniv"); - glad_glFeedbackBuffer = (PFNGLFEEDBACKBUFFERPROC)load("glFeedbackBuffer"); - glad_glSelectBuffer = (PFNGLSELECTBUFFERPROC)load("glSelectBuffer"); - glad_glRenderMode = (PFNGLRENDERMODEPROC)load("glRenderMode"); - glad_glInitNames = (PFNGLINITNAMESPROC)load("glInitNames"); - glad_glLoadName = (PFNGLLOADNAMEPROC)load("glLoadName"); - glad_glPassThrough = (PFNGLPASSTHROUGHPROC)load("glPassThrough"); - glad_glPopName = (PFNGLPOPNAMEPROC)load("glPopName"); - glad_glPushName = (PFNGLPUSHNAMEPROC)load("glPushName"); - glad_glClearAccum = (PFNGLCLEARACCUMPROC)load("glClearAccum"); - glad_glClearIndex = (PFNGLCLEARINDEXPROC)load("glClearIndex"); - glad_glIndexMask = (PFNGLINDEXMASKPROC)load("glIndexMask"); - glad_glAccum = (PFNGLACCUMPROC)load("glAccum"); - glad_glPopAttrib = (PFNGLPOPATTRIBPROC)load("glPopAttrib"); - glad_glPushAttrib = (PFNGLPUSHATTRIBPROC)load("glPushAttrib"); - glad_glMap1d = (PFNGLMAP1DPROC)load("glMap1d"); - glad_glMap1f = (PFNGLMAP1FPROC)load("glMap1f"); - glad_glMap2d = (PFNGLMAP2DPROC)load("glMap2d"); - glad_glMap2f = (PFNGLMAP2FPROC)load("glMap2f"); - glad_glMapGrid1d = (PFNGLMAPGRID1DPROC)load("glMapGrid1d"); - glad_glMapGrid1f = (PFNGLMAPGRID1FPROC)load("glMapGrid1f"); - glad_glMapGrid2d = (PFNGLMAPGRID2DPROC)load("glMapGrid2d"); - glad_glMapGrid2f = (PFNGLMAPGRID2FPROC)load("glMapGrid2f"); - glad_glEvalCoord1d = (PFNGLEVALCOORD1DPROC)load("glEvalCoord1d"); - glad_glEvalCoord1dv = (PFNGLEVALCOORD1DVPROC)load("glEvalCoord1dv"); - glad_glEvalCoord1f = (PFNGLEVALCOORD1FPROC)load("glEvalCoord1f"); - glad_glEvalCoord1fv = (PFNGLEVALCOORD1FVPROC)load("glEvalCoord1fv"); - glad_glEvalCoord2d = (PFNGLEVALCOORD2DPROC)load("glEvalCoord2d"); - glad_glEvalCoord2dv = (PFNGLEVALCOORD2DVPROC)load("glEvalCoord2dv"); - glad_glEvalCoord2f = (PFNGLEVALCOORD2FPROC)load("glEvalCoord2f"); - glad_glEvalCoord2fv = (PFNGLEVALCOORD2FVPROC)load("glEvalCoord2fv"); - glad_glEvalMesh1 = (PFNGLEVALMESH1PROC)load("glEvalMesh1"); - glad_glEvalPoint1 = (PFNGLEVALPOINT1PROC)load("glEvalPoint1"); - glad_glEvalMesh2 = (PFNGLEVALMESH2PROC)load("glEvalMesh2"); - glad_glEvalPoint2 = (PFNGLEVALPOINT2PROC)load("glEvalPoint2"); - glad_glAlphaFunc = (PFNGLALPHAFUNCPROC)load("glAlphaFunc"); - glad_glPixelZoom = (PFNGLPIXELZOOMPROC)load("glPixelZoom"); - glad_glPixelTransferf = (PFNGLPIXELTRANSFERFPROC)load("glPixelTransferf"); - glad_glPixelTransferi = (PFNGLPIXELTRANSFERIPROC)load("glPixelTransferi"); - glad_glPixelMapfv = (PFNGLPIXELMAPFVPROC)load("glPixelMapfv"); - glad_glPixelMapuiv = (PFNGLPIXELMAPUIVPROC)load("glPixelMapuiv"); - glad_glPixelMapusv = (PFNGLPIXELMAPUSVPROC)load("glPixelMapusv"); - glad_glCopyPixels = (PFNGLCOPYPIXELSPROC)load("glCopyPixels"); - glad_glDrawPixels = (PFNGLDRAWPIXELSPROC)load("glDrawPixels"); - glad_glGetClipPlane = (PFNGLGETCLIPPLANEPROC)load("glGetClipPlane"); - glad_glGetLightfv = (PFNGLGETLIGHTFVPROC)load("glGetLightfv"); - glad_glGetLightiv = (PFNGLGETLIGHTIVPROC)load("glGetLightiv"); - glad_glGetMapdv = (PFNGLGETMAPDVPROC)load("glGetMapdv"); - glad_glGetMapfv = (PFNGLGETMAPFVPROC)load("glGetMapfv"); - glad_glGetMapiv = (PFNGLGETMAPIVPROC)load("glGetMapiv"); - glad_glGetMaterialfv = (PFNGLGETMATERIALFVPROC)load("glGetMaterialfv"); - glad_glGetMaterialiv = (PFNGLGETMATERIALIVPROC)load("glGetMaterialiv"); - glad_glGetPixelMapfv = (PFNGLGETPIXELMAPFVPROC)load("glGetPixelMapfv"); - glad_glGetPixelMapuiv = (PFNGLGETPIXELMAPUIVPROC)load("glGetPixelMapuiv"); - glad_glGetPixelMapusv = (PFNGLGETPIXELMAPUSVPROC)load("glGetPixelMapusv"); - glad_glGetPolygonStipple = (PFNGLGETPOLYGONSTIPPLEPROC)load("glGetPolygonStipple"); - glad_glGetTexEnvfv = (PFNGLGETTEXENVFVPROC)load("glGetTexEnvfv"); - glad_glGetTexEnviv = (PFNGLGETTEXENVIVPROC)load("glGetTexEnviv"); - glad_glGetTexGendv = (PFNGLGETTEXGENDVPROC)load("glGetTexGendv"); - glad_glGetTexGenfv = (PFNGLGETTEXGENFVPROC)load("glGetTexGenfv"); - glad_glGetTexGeniv = (PFNGLGETTEXGENIVPROC)load("glGetTexGeniv"); - glad_glIsList = (PFNGLISLISTPROC)load("glIsList"); - glad_glFrustum = (PFNGLFRUSTUMPROC)load("glFrustum"); - glad_glLoadIdentity = (PFNGLLOADIDENTITYPROC)load("glLoadIdentity"); - glad_glLoadMatrixf = (PFNGLLOADMATRIXFPROC)load("glLoadMatrixf"); - glad_glLoadMatrixd = (PFNGLLOADMATRIXDPROC)load("glLoadMatrixd"); - glad_glMatrixMode = (PFNGLMATRIXMODEPROC)load("glMatrixMode"); - glad_glMultMatrixf = (PFNGLMULTMATRIXFPROC)load("glMultMatrixf"); - glad_glMultMatrixd = (PFNGLMULTMATRIXDPROC)load("glMultMatrixd"); - glad_glOrtho = (PFNGLORTHOPROC)load("glOrtho"); - glad_glPopMatrix = (PFNGLPOPMATRIXPROC)load("glPopMatrix"); - glad_glPushMatrix = (PFNGLPUSHMATRIXPROC)load("glPushMatrix"); - glad_glRotated = (PFNGLROTATEDPROC)load("glRotated"); - glad_glRotatef = (PFNGLROTATEFPROC)load("glRotatef"); - glad_glScaled = (PFNGLSCALEDPROC)load("glScaled"); - glad_glScalef = (PFNGLSCALEFPROC)load("glScalef"); - glad_glTranslated = (PFNGLTRANSLATEDPROC)load("glTranslated"); - glad_glTranslatef = (PFNGLTRANSLATEFPROC)load("glTranslatef"); -} -static void load_GL_VERSION_1_1(GLADloadproc load) { - if(!GLAD_GL_VERSION_1_1) return; - glad_glDrawArrays = (PFNGLDRAWARRAYSPROC)load("glDrawArrays"); - glad_glDrawElements = (PFNGLDRAWELEMENTSPROC)load("glDrawElements"); - glad_glGetPointerv = (PFNGLGETPOINTERVPROC)load("glGetPointerv"); - glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC)load("glPolygonOffset"); - glad_glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC)load("glCopyTexImage1D"); - glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC)load("glCopyTexImage2D"); - glad_glCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC)load("glCopyTexSubImage1D"); - glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC)load("glCopyTexSubImage2D"); - glad_glTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC)load("glTexSubImage1D"); - glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC)load("glTexSubImage2D"); - glad_glBindTexture = (PFNGLBINDTEXTUREPROC)load("glBindTexture"); - glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC)load("glDeleteTextures"); - glad_glGenTextures = (PFNGLGENTEXTURESPROC)load("glGenTextures"); - glad_glIsTexture = (PFNGLISTEXTUREPROC)load("glIsTexture"); - glad_glArrayElement = (PFNGLARRAYELEMENTPROC)load("glArrayElement"); - glad_glColorPointer = (PFNGLCOLORPOINTERPROC)load("glColorPointer"); - glad_glDisableClientState = (PFNGLDISABLECLIENTSTATEPROC)load("glDisableClientState"); - glad_glEdgeFlagPointer = (PFNGLEDGEFLAGPOINTERPROC)load("glEdgeFlagPointer"); - glad_glEnableClientState = (PFNGLENABLECLIENTSTATEPROC)load("glEnableClientState"); - glad_glIndexPointer = (PFNGLINDEXPOINTERPROC)load("glIndexPointer"); - glad_glInterleavedArrays = (PFNGLINTERLEAVEDARRAYSPROC)load("glInterleavedArrays"); - glad_glNormalPointer = (PFNGLNORMALPOINTERPROC)load("glNormalPointer"); - glad_glTexCoordPointer = (PFNGLTEXCOORDPOINTERPROC)load("glTexCoordPointer"); - glad_glVertexPointer = (PFNGLVERTEXPOINTERPROC)load("glVertexPointer"); - glad_glAreTexturesResident = (PFNGLARETEXTURESRESIDENTPROC)load("glAreTexturesResident"); - glad_glPrioritizeTextures = (PFNGLPRIORITIZETEXTURESPROC)load("glPrioritizeTextures"); - glad_glIndexub = (PFNGLINDEXUBPROC)load("glIndexub"); - glad_glIndexubv = (PFNGLINDEXUBVPROC)load("glIndexubv"); - glad_glPopClientAttrib = (PFNGLPOPCLIENTATTRIBPROC)load("glPopClientAttrib"); - glad_glPushClientAttrib = (PFNGLPUSHCLIENTATTRIBPROC)load("glPushClientAttrib"); -} -static void load_GL_VERSION_1_2(GLADloadproc load) { - if(!GLAD_GL_VERSION_1_2) return; - glad_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)load("glDrawRangeElements"); - glad_glTexImage3D = (PFNGLTEXIMAGE3DPROC)load("glTexImage3D"); - glad_glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)load("glTexSubImage3D"); - glad_glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)load("glCopyTexSubImage3D"); -} -static void load_GL_VERSION_1_3(GLADloadproc load) { - if(!GLAD_GL_VERSION_1_3) return; - glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC)load("glActiveTexture"); - glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)load("glSampleCoverage"); - glad_glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)load("glCompressedTexImage3D"); - glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)load("glCompressedTexImage2D"); - glad_glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)load("glCompressedTexImage1D"); - glad_glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)load("glCompressedTexSubImage3D"); - glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)load("glCompressedTexSubImage2D"); - glad_glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)load("glCompressedTexSubImage1D"); - glad_glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)load("glGetCompressedTexImage"); - glad_glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)load("glClientActiveTexture"); - glad_glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)load("glMultiTexCoord1d"); - glad_glMultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC)load("glMultiTexCoord1dv"); - glad_glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)load("glMultiTexCoord1f"); - glad_glMultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC)load("glMultiTexCoord1fv"); - glad_glMultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC)load("glMultiTexCoord1i"); - glad_glMultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC)load("glMultiTexCoord1iv"); - glad_glMultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC)load("glMultiTexCoord1s"); - glad_glMultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC)load("glMultiTexCoord1sv"); - glad_glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)load("glMultiTexCoord2d"); - glad_glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC)load("glMultiTexCoord2dv"); - glad_glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)load("glMultiTexCoord2f"); - glad_glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC)load("glMultiTexCoord2fv"); - glad_glMultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC)load("glMultiTexCoord2i"); - glad_glMultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC)load("glMultiTexCoord2iv"); - glad_glMultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC)load("glMultiTexCoord2s"); - glad_glMultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC)load("glMultiTexCoord2sv"); - glad_glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)load("glMultiTexCoord3d"); - glad_glMultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC)load("glMultiTexCoord3dv"); - glad_glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)load("glMultiTexCoord3f"); - glad_glMultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC)load("glMultiTexCoord3fv"); - glad_glMultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC)load("glMultiTexCoord3i"); - glad_glMultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC)load("glMultiTexCoord3iv"); - glad_glMultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC)load("glMultiTexCoord3s"); - glad_glMultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC)load("glMultiTexCoord3sv"); - glad_glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)load("glMultiTexCoord4d"); - glad_glMultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC)load("glMultiTexCoord4dv"); - glad_glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)load("glMultiTexCoord4f"); - glad_glMultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC)load("glMultiTexCoord4fv"); - glad_glMultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC)load("glMultiTexCoord4i"); - glad_glMultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC)load("glMultiTexCoord4iv"); - glad_glMultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC)load("glMultiTexCoord4s"); - glad_glMultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC)load("glMultiTexCoord4sv"); - glad_glLoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC)load("glLoadTransposeMatrixf"); - glad_glLoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC)load("glLoadTransposeMatrixd"); - glad_glMultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC)load("glMultTransposeMatrixf"); - glad_glMultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC)load("glMultTransposeMatrixd"); -} -static void load_GL_VERSION_1_4(GLADloadproc load) { - if(!GLAD_GL_VERSION_1_4) return; - glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)load("glBlendFuncSeparate"); - glad_glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC)load("glMultiDrawArrays"); - glad_glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC)load("glMultiDrawElements"); - glad_glPointParameterf = (PFNGLPOINTPARAMETERFPROC)load("glPointParameterf"); - glad_glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)load("glPointParameterfv"); - glad_glPointParameteri = (PFNGLPOINTPARAMETERIPROC)load("glPointParameteri"); - glad_glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC)load("glPointParameteriv"); - glad_glFogCoordf = (PFNGLFOGCOORDFPROC)load("glFogCoordf"); - glad_glFogCoordfv = (PFNGLFOGCOORDFVPROC)load("glFogCoordfv"); - glad_glFogCoordd = (PFNGLFOGCOORDDPROC)load("glFogCoordd"); - glad_glFogCoorddv = (PFNGLFOGCOORDDVPROC)load("glFogCoorddv"); - glad_glFogCoordPointer = (PFNGLFOGCOORDPOINTERPROC)load("glFogCoordPointer"); - glad_glSecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC)load("glSecondaryColor3b"); - glad_glSecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC)load("glSecondaryColor3bv"); - glad_glSecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC)load("glSecondaryColor3d"); - glad_glSecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC)load("glSecondaryColor3dv"); - glad_glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC)load("glSecondaryColor3f"); - glad_glSecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC)load("glSecondaryColor3fv"); - glad_glSecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC)load("glSecondaryColor3i"); - glad_glSecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC)load("glSecondaryColor3iv"); - glad_glSecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC)load("glSecondaryColor3s"); - glad_glSecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC)load("glSecondaryColor3sv"); - glad_glSecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC)load("glSecondaryColor3ub"); - glad_glSecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC)load("glSecondaryColor3ubv"); - glad_glSecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC)load("glSecondaryColor3ui"); - glad_glSecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC)load("glSecondaryColor3uiv"); - glad_glSecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC)load("glSecondaryColor3us"); - glad_glSecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC)load("glSecondaryColor3usv"); - glad_glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)load("glSecondaryColorPointer"); - glad_glWindowPos2d = (PFNGLWINDOWPOS2DPROC)load("glWindowPos2d"); - glad_glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC)load("glWindowPos2dv"); - glad_glWindowPos2f = (PFNGLWINDOWPOS2FPROC)load("glWindowPos2f"); - glad_glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC)load("glWindowPos2fv"); - glad_glWindowPos2i = (PFNGLWINDOWPOS2IPROC)load("glWindowPos2i"); - glad_glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC)load("glWindowPos2iv"); - glad_glWindowPos2s = (PFNGLWINDOWPOS2SPROC)load("glWindowPos2s"); - glad_glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC)load("glWindowPos2sv"); - glad_glWindowPos3d = (PFNGLWINDOWPOS3DPROC)load("glWindowPos3d"); - glad_glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC)load("glWindowPos3dv"); - glad_glWindowPos3f = (PFNGLWINDOWPOS3FPROC)load("glWindowPos3f"); - glad_glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC)load("glWindowPos3fv"); - glad_glWindowPos3i = (PFNGLWINDOWPOS3IPROC)load("glWindowPos3i"); - glad_glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC)load("glWindowPos3iv"); - glad_glWindowPos3s = (PFNGLWINDOWPOS3SPROC)load("glWindowPos3s"); - glad_glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC)load("glWindowPos3sv"); - glad_glBlendColor = (PFNGLBLENDCOLORPROC)load("glBlendColor"); - glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC)load("glBlendEquation"); -} -static void load_GL_VERSION_1_5(GLADloadproc load) { - if(!GLAD_GL_VERSION_1_5) return; - glad_glGenQueries = (PFNGLGENQUERIESPROC)load("glGenQueries"); - glad_glDeleteQueries = (PFNGLDELETEQUERIESPROC)load("glDeleteQueries"); - glad_glIsQuery = (PFNGLISQUERYPROC)load("glIsQuery"); - glad_glBeginQuery = (PFNGLBEGINQUERYPROC)load("glBeginQuery"); - glad_glEndQuery = (PFNGLENDQUERYPROC)load("glEndQuery"); - glad_glGetQueryiv = (PFNGLGETQUERYIVPROC)load("glGetQueryiv"); - glad_glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC)load("glGetQueryObjectiv"); - glad_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)load("glGetQueryObjectuiv"); - glad_glBindBuffer = (PFNGLBINDBUFFERPROC)load("glBindBuffer"); - glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)load("glDeleteBuffers"); - glad_glGenBuffers = (PFNGLGENBUFFERSPROC)load("glGenBuffers"); - glad_glIsBuffer = (PFNGLISBUFFERPROC)load("glIsBuffer"); - glad_glBufferData = (PFNGLBUFFERDATAPROC)load("glBufferData"); - glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC)load("glBufferSubData"); - glad_glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)load("glGetBufferSubData"); - glad_glMapBuffer = (PFNGLMAPBUFFERPROC)load("glMapBuffer"); - glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)load("glUnmapBuffer"); - glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)load("glGetBufferParameteriv"); - glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)load("glGetBufferPointerv"); -} -static void load_GL_VERSION_2_0(GLADloadproc load) { - if(!GLAD_GL_VERSION_2_0) return; - glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)load("glBlendEquationSeparate"); - glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC)load("glDrawBuffers"); - glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)load("glStencilOpSeparate"); - glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)load("glStencilFuncSeparate"); - glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)load("glStencilMaskSeparate"); - glad_glAttachShader = (PFNGLATTACHSHADERPROC)load("glAttachShader"); - glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)load("glBindAttribLocation"); - glad_glCompileShader = (PFNGLCOMPILESHADERPROC)load("glCompileShader"); - glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC)load("glCreateProgram"); - glad_glCreateShader = (PFNGLCREATESHADERPROC)load("glCreateShader"); - glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC)load("glDeleteProgram"); - glad_glDeleteShader = (PFNGLDELETESHADERPROC)load("glDeleteShader"); - glad_glDetachShader = (PFNGLDETACHSHADERPROC)load("glDetachShader"); - glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)load("glDisableVertexAttribArray"); - glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)load("glEnableVertexAttribArray"); - glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)load("glGetActiveAttrib"); - glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)load("glGetActiveUniform"); - glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)load("glGetAttachedShaders"); - glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)load("glGetAttribLocation"); - glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC)load("glGetProgramiv"); - glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)load("glGetProgramInfoLog"); - glad_glGetShaderiv = (PFNGLGETSHADERIVPROC)load("glGetShaderiv"); - glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)load("glGetShaderInfoLog"); - glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)load("glGetShaderSource"); - glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)load("glGetUniformLocation"); - glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC)load("glGetUniformfv"); - glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC)load("glGetUniformiv"); - glad_glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC)load("glGetVertexAttribdv"); - glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)load("glGetVertexAttribfv"); - glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)load("glGetVertexAttribiv"); - glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)load("glGetVertexAttribPointerv"); - glad_glIsProgram = (PFNGLISPROGRAMPROC)load("glIsProgram"); - glad_glIsShader = (PFNGLISSHADERPROC)load("glIsShader"); - glad_glLinkProgram = (PFNGLLINKPROGRAMPROC)load("glLinkProgram"); - glad_glShaderSource = (PFNGLSHADERSOURCEPROC)load("glShaderSource"); - glad_glUseProgram = (PFNGLUSEPROGRAMPROC)load("glUseProgram"); - glad_glUniform1f = (PFNGLUNIFORM1FPROC)load("glUniform1f"); - glad_glUniform2f = (PFNGLUNIFORM2FPROC)load("glUniform2f"); - glad_glUniform3f = (PFNGLUNIFORM3FPROC)load("glUniform3f"); - glad_glUniform4f = (PFNGLUNIFORM4FPROC)load("glUniform4f"); - glad_glUniform1i = (PFNGLUNIFORM1IPROC)load("glUniform1i"); - glad_glUniform2i = (PFNGLUNIFORM2IPROC)load("glUniform2i"); - glad_glUniform3i = (PFNGLUNIFORM3IPROC)load("glUniform3i"); - glad_glUniform4i = (PFNGLUNIFORM4IPROC)load("glUniform4i"); - glad_glUniform1fv = (PFNGLUNIFORM1FVPROC)load("glUniform1fv"); - glad_glUniform2fv = (PFNGLUNIFORM2FVPROC)load("glUniform2fv"); - glad_glUniform3fv = (PFNGLUNIFORM3FVPROC)load("glUniform3fv"); - glad_glUniform4fv = (PFNGLUNIFORM4FVPROC)load("glUniform4fv"); - glad_glUniform1iv = (PFNGLUNIFORM1IVPROC)load("glUniform1iv"); - glad_glUniform2iv = (PFNGLUNIFORM2IVPROC)load("glUniform2iv"); - glad_glUniform3iv = (PFNGLUNIFORM3IVPROC)load("glUniform3iv"); - glad_glUniform4iv = (PFNGLUNIFORM4IVPROC)load("glUniform4iv"); - glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)load("glUniformMatrix2fv"); - glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)load("glUniformMatrix3fv"); - glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)load("glUniformMatrix4fv"); - glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)load("glValidateProgram"); - glad_glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC)load("glVertexAttrib1d"); - glad_glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC)load("glVertexAttrib1dv"); - glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)load("glVertexAttrib1f"); - glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)load("glVertexAttrib1fv"); - glad_glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC)load("glVertexAttrib1s"); - glad_glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC)load("glVertexAttrib1sv"); - glad_glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC)load("glVertexAttrib2d"); - glad_glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC)load("glVertexAttrib2dv"); - glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)load("glVertexAttrib2f"); - glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)load("glVertexAttrib2fv"); - glad_glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC)load("glVertexAttrib2s"); - glad_glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)load("glVertexAttrib2sv"); - glad_glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC)load("glVertexAttrib3d"); - glad_glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC)load("glVertexAttrib3dv"); - glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)load("glVertexAttrib3f"); - glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)load("glVertexAttrib3fv"); - glad_glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC)load("glVertexAttrib3s"); - glad_glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC)load("glVertexAttrib3sv"); - glad_glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC)load("glVertexAttrib4Nbv"); - glad_glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC)load("glVertexAttrib4Niv"); - glad_glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC)load("glVertexAttrib4Nsv"); - glad_glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC)load("glVertexAttrib4Nub"); - glad_glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC)load("glVertexAttrib4Nubv"); - glad_glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC)load("glVertexAttrib4Nuiv"); - glad_glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC)load("glVertexAttrib4Nusv"); - glad_glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC)load("glVertexAttrib4bv"); - glad_glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC)load("glVertexAttrib4d"); - glad_glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)load("glVertexAttrib4dv"); - glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)load("glVertexAttrib4f"); - glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)load("glVertexAttrib4fv"); - glad_glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC)load("glVertexAttrib4iv"); - glad_glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC)load("glVertexAttrib4s"); - glad_glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC)load("glVertexAttrib4sv"); - glad_glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC)load("glVertexAttrib4ubv"); - glad_glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC)load("glVertexAttrib4uiv"); - glad_glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC)load("glVertexAttrib4usv"); - glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)load("glVertexAttribPointer"); -} -static void load_GL_VERSION_2_1(GLADloadproc load) { - if(!GLAD_GL_VERSION_2_1) return; - glad_glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC)load("glUniformMatrix2x3fv"); - glad_glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)load("glUniformMatrix3x2fv"); - glad_glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)load("glUniformMatrix2x4fv"); - glad_glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)load("glUniformMatrix4x2fv"); - glad_glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)load("glUniformMatrix3x4fv"); - glad_glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)load("glUniformMatrix4x3fv"); -} -static void load_GL_VERSION_3_0(GLADloadproc load) { - if(!GLAD_GL_VERSION_3_0) return; - glad_glColorMaski = (PFNGLCOLORMASKIPROC)load("glColorMaski"); - glad_glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC)load("glGetBooleani_v"); - glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)load("glGetIntegeri_v"); - glad_glEnablei = (PFNGLENABLEIPROC)load("glEnablei"); - glad_glDisablei = (PFNGLDISABLEIPROC)load("glDisablei"); - glad_glIsEnabledi = (PFNGLISENABLEDIPROC)load("glIsEnabledi"); - glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)load("glBeginTransformFeedback"); - glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)load("glEndTransformFeedback"); - glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)load("glBindBufferRange"); - glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)load("glBindBufferBase"); - glad_glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)load("glTransformFeedbackVaryings"); - glad_glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)load("glGetTransformFeedbackVarying"); - glad_glClampColor = (PFNGLCLAMPCOLORPROC)load("glClampColor"); - glad_glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC)load("glBeginConditionalRender"); - glad_glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC)load("glEndConditionalRender"); - glad_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)load("glVertexAttribIPointer"); - glad_glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC)load("glGetVertexAttribIiv"); - glad_glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC)load("glGetVertexAttribIuiv"); - glad_glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC)load("glVertexAttribI1i"); - glad_glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC)load("glVertexAttribI2i"); - glad_glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC)load("glVertexAttribI3i"); - glad_glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC)load("glVertexAttribI4i"); - glad_glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC)load("glVertexAttribI1ui"); - glad_glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC)load("glVertexAttribI2ui"); - glad_glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC)load("glVertexAttribI3ui"); - glad_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)load("glVertexAttribI4ui"); - glad_glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC)load("glVertexAttribI1iv"); - glad_glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC)load("glVertexAttribI2iv"); - glad_glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC)load("glVertexAttribI3iv"); - glad_glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC)load("glVertexAttribI4iv"); - glad_glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC)load("glVertexAttribI1uiv"); - glad_glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC)load("glVertexAttribI2uiv"); - glad_glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC)load("glVertexAttribI3uiv"); - glad_glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC)load("glVertexAttribI4uiv"); - glad_glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC)load("glVertexAttribI4bv"); - glad_glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC)load("glVertexAttribI4sv"); - glad_glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC)load("glVertexAttribI4ubv"); - glad_glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC)load("glVertexAttribI4usv"); - glad_glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC)load("glGetUniformuiv"); - glad_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)load("glBindFragDataLocation"); - glad_glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC)load("glGetFragDataLocation"); - glad_glUniform1ui = (PFNGLUNIFORM1UIPROC)load("glUniform1ui"); - glad_glUniform2ui = (PFNGLUNIFORM2UIPROC)load("glUniform2ui"); - glad_glUniform3ui = (PFNGLUNIFORM3UIPROC)load("glUniform3ui"); - glad_glUniform4ui = (PFNGLUNIFORM4UIPROC)load("glUniform4ui"); - glad_glUniform1uiv = (PFNGLUNIFORM1UIVPROC)load("glUniform1uiv"); - glad_glUniform2uiv = (PFNGLUNIFORM2UIVPROC)load("glUniform2uiv"); - glad_glUniform3uiv = (PFNGLUNIFORM3UIVPROC)load("glUniform3uiv"); - glad_glUniform4uiv = (PFNGLUNIFORM4UIVPROC)load("glUniform4uiv"); - glad_glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC)load("glTexParameterIiv"); - glad_glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC)load("glTexParameterIuiv"); - glad_glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC)load("glGetTexParameterIiv"); - glad_glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC)load("glGetTexParameterIuiv"); - glad_glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)load("glClearBufferiv"); - glad_glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC)load("glClearBufferuiv"); - glad_glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)load("glClearBufferfv"); - glad_glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)load("glClearBufferfi"); - glad_glGetStringi = (PFNGLGETSTRINGIPROC)load("glGetStringi"); - glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)load("glIsRenderbuffer"); - glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)load("glBindRenderbuffer"); - glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)load("glDeleteRenderbuffers"); - glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)load("glGenRenderbuffers"); - glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)load("glRenderbufferStorage"); - glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)load("glGetRenderbufferParameteriv"); - glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)load("glIsFramebuffer"); - glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)load("glBindFramebuffer"); - glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)load("glDeleteFramebuffers"); - glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)load("glGenFramebuffers"); - glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)load("glCheckFramebufferStatus"); - glad_glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)load("glFramebufferTexture1D"); - glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)load("glFramebufferTexture2D"); - glad_glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)load("glFramebufferTexture3D"); - glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)load("glFramebufferRenderbuffer"); - glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)load("glGetFramebufferAttachmentParameteriv"); - glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)load("glGenerateMipmap"); - glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)load("glBlitFramebuffer"); - glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)load("glRenderbufferStorageMultisample"); - glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)load("glFramebufferTextureLayer"); - glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)load("glMapBufferRange"); - glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)load("glFlushMappedBufferRange"); - glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)load("glBindVertexArray"); - glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)load("glDeleteVertexArrays"); - glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)load("glGenVertexArrays"); - glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC)load("glIsVertexArray"); -} -static void load_GL_VERSION_3_1(GLADloadproc load) { - if(!GLAD_GL_VERSION_3_1) return; - glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)load("glDrawArraysInstanced"); - glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)load("glDrawElementsInstanced"); - glad_glTexBuffer = (PFNGLTEXBUFFERPROC)load("glTexBuffer"); - glad_glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)load("glPrimitiveRestartIndex"); - glad_glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC)load("glCopyBufferSubData"); - glad_glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC)load("glGetUniformIndices"); - glad_glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)load("glGetActiveUniformsiv"); - glad_glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC)load("glGetActiveUniformName"); - glad_glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)load("glGetUniformBlockIndex"); - glad_glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)load("glGetActiveUniformBlockiv"); - glad_glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)load("glGetActiveUniformBlockName"); - glad_glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)load("glUniformBlockBinding"); - glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)load("glBindBufferRange"); - glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)load("glBindBufferBase"); - glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)load("glGetIntegeri_v"); -} -static void load_GL_VERSION_3_2(GLADloadproc load) { - if(!GLAD_GL_VERSION_3_2) return; - glad_glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)load("glDrawElementsBaseVertex"); - glad_glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)load("glDrawRangeElementsBaseVertex"); - glad_glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)load("glDrawElementsInstancedBaseVertex"); - glad_glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)load("glMultiDrawElementsBaseVertex"); - glad_glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC)load("glProvokingVertex"); - glad_glFenceSync = (PFNGLFENCESYNCPROC)load("glFenceSync"); - glad_glIsSync = (PFNGLISSYNCPROC)load("glIsSync"); - glad_glDeleteSync = (PFNGLDELETESYNCPROC)load("glDeleteSync"); - glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)load("glClientWaitSync"); - glad_glWaitSync = (PFNGLWAITSYNCPROC)load("glWaitSync"); - glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC)load("glGetInteger64v"); - glad_glGetSynciv = (PFNGLGETSYNCIVPROC)load("glGetSynciv"); - glad_glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC)load("glGetInteger64i_v"); - glad_glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC)load("glGetBufferParameteri64v"); - glad_glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)load("glFramebufferTexture"); - glad_glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)load("glTexImage2DMultisample"); - glad_glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC)load("glTexImage3DMultisample"); - glad_glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC)load("glGetMultisamplefv"); - glad_glSampleMaski = (PFNGLSAMPLEMASKIPROC)load("glSampleMaski"); -} -static void load_GL_VERSION_3_3(GLADloadproc load) { - if(!GLAD_GL_VERSION_3_3) return; - glad_glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)load("glBindFragDataLocationIndexed"); - glad_glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC)load("glGetFragDataIndex"); - glad_glGenSamplers = (PFNGLGENSAMPLERSPROC)load("glGenSamplers"); - glad_glDeleteSamplers = (PFNGLDELETESAMPLERSPROC)load("glDeleteSamplers"); - glad_glIsSampler = (PFNGLISSAMPLERPROC)load("glIsSampler"); - glad_glBindSampler = (PFNGLBINDSAMPLERPROC)load("glBindSampler"); - glad_glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC)load("glSamplerParameteri"); - glad_glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC)load("glSamplerParameteriv"); - glad_glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC)load("glSamplerParameterf"); - glad_glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC)load("glSamplerParameterfv"); - glad_glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC)load("glSamplerParameterIiv"); - glad_glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC)load("glSamplerParameterIuiv"); - glad_glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC)load("glGetSamplerParameteriv"); - glad_glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC)load("glGetSamplerParameterIiv"); - glad_glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC)load("glGetSamplerParameterfv"); - glad_glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC)load("glGetSamplerParameterIuiv"); - glad_glQueryCounter = (PFNGLQUERYCOUNTERPROC)load("glQueryCounter"); - glad_glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC)load("glGetQueryObjecti64v"); - glad_glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)load("glGetQueryObjectui64v"); - glad_glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)load("glVertexAttribDivisor"); - glad_glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC)load("glVertexAttribP1ui"); - glad_glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC)load("glVertexAttribP1uiv"); - glad_glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC)load("glVertexAttribP2ui"); - glad_glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC)load("glVertexAttribP2uiv"); - glad_glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC)load("glVertexAttribP3ui"); - glad_glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC)load("glVertexAttribP3uiv"); - glad_glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC)load("glVertexAttribP4ui"); - glad_glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC)load("glVertexAttribP4uiv"); - glad_glVertexP2ui = (PFNGLVERTEXP2UIPROC)load("glVertexP2ui"); - glad_glVertexP2uiv = (PFNGLVERTEXP2UIVPROC)load("glVertexP2uiv"); - glad_glVertexP3ui = (PFNGLVERTEXP3UIPROC)load("glVertexP3ui"); - glad_glVertexP3uiv = (PFNGLVERTEXP3UIVPROC)load("glVertexP3uiv"); - glad_glVertexP4ui = (PFNGLVERTEXP4UIPROC)load("glVertexP4ui"); - glad_glVertexP4uiv = (PFNGLVERTEXP4UIVPROC)load("glVertexP4uiv"); - glad_glTexCoordP1ui = (PFNGLTEXCOORDP1UIPROC)load("glTexCoordP1ui"); - glad_glTexCoordP1uiv = (PFNGLTEXCOORDP1UIVPROC)load("glTexCoordP1uiv"); - glad_glTexCoordP2ui = (PFNGLTEXCOORDP2UIPROC)load("glTexCoordP2ui"); - glad_glTexCoordP2uiv = (PFNGLTEXCOORDP2UIVPROC)load("glTexCoordP2uiv"); - glad_glTexCoordP3ui = (PFNGLTEXCOORDP3UIPROC)load("glTexCoordP3ui"); - glad_glTexCoordP3uiv = (PFNGLTEXCOORDP3UIVPROC)load("glTexCoordP3uiv"); - glad_glTexCoordP4ui = (PFNGLTEXCOORDP4UIPROC)load("glTexCoordP4ui"); - glad_glTexCoordP4uiv = (PFNGLTEXCOORDP4UIVPROC)load("glTexCoordP4uiv"); - glad_glMultiTexCoordP1ui = (PFNGLMULTITEXCOORDP1UIPROC)load("glMultiTexCoordP1ui"); - glad_glMultiTexCoordP1uiv = (PFNGLMULTITEXCOORDP1UIVPROC)load("glMultiTexCoordP1uiv"); - glad_glMultiTexCoordP2ui = (PFNGLMULTITEXCOORDP2UIPROC)load("glMultiTexCoordP2ui"); - glad_glMultiTexCoordP2uiv = (PFNGLMULTITEXCOORDP2UIVPROC)load("glMultiTexCoordP2uiv"); - glad_glMultiTexCoordP3ui = (PFNGLMULTITEXCOORDP3UIPROC)load("glMultiTexCoordP3ui"); - glad_glMultiTexCoordP3uiv = (PFNGLMULTITEXCOORDP3UIVPROC)load("glMultiTexCoordP3uiv"); - glad_glMultiTexCoordP4ui = (PFNGLMULTITEXCOORDP4UIPROC)load("glMultiTexCoordP4ui"); - glad_glMultiTexCoordP4uiv = (PFNGLMULTITEXCOORDP4UIVPROC)load("glMultiTexCoordP4uiv"); - glad_glNormalP3ui = (PFNGLNORMALP3UIPROC)load("glNormalP3ui"); - glad_glNormalP3uiv = (PFNGLNORMALP3UIVPROC)load("glNormalP3uiv"); - glad_glColorP3ui = (PFNGLCOLORP3UIPROC)load("glColorP3ui"); - glad_glColorP3uiv = (PFNGLCOLORP3UIVPROC)load("glColorP3uiv"); - glad_glColorP4ui = (PFNGLCOLORP4UIPROC)load("glColorP4ui"); - glad_glColorP4uiv = (PFNGLCOLORP4UIVPROC)load("glColorP4uiv"); - glad_glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC)load("glSecondaryColorP3ui"); - glad_glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC)load("glSecondaryColorP3uiv"); -} -static void load_GL_ARB_debug_output(GLADloadproc load) { - if(!GLAD_GL_ARB_debug_output) return; - glad_glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC)load("glDebugMessageControlARB"); - glad_glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC)load("glDebugMessageInsertARB"); - glad_glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)load("glDebugMessageCallbackARB"); - glad_glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC)load("glGetDebugMessageLogARB"); -} -static void load_GL_ARB_framebuffer_object(GLADloadproc load) { - if(!GLAD_GL_ARB_framebuffer_object) return; - glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)load("glIsRenderbuffer"); - glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)load("glBindRenderbuffer"); - glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)load("glDeleteRenderbuffers"); - glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)load("glGenRenderbuffers"); - glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)load("glRenderbufferStorage"); - glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)load("glGetRenderbufferParameteriv"); - glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)load("glIsFramebuffer"); - glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)load("glBindFramebuffer"); - glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)load("glDeleteFramebuffers"); - glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)load("glGenFramebuffers"); - glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)load("glCheckFramebufferStatus"); - glad_glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)load("glFramebufferTexture1D"); - glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)load("glFramebufferTexture2D"); - glad_glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)load("glFramebufferTexture3D"); - glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)load("glFramebufferRenderbuffer"); - glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)load("glGetFramebufferAttachmentParameteriv"); - glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)load("glGenerateMipmap"); - glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)load("glBlitFramebuffer"); - glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)load("glRenderbufferStorageMultisample"); - glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)load("glFramebufferTextureLayer"); -} -static void load_GL_EXT_framebuffer_blit(GLADloadproc load) { - if(!GLAD_GL_EXT_framebuffer_blit) return; - glad_glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC)load("glBlitFramebufferEXT"); -} -static void load_GL_EXT_framebuffer_multisample(GLADloadproc load) { - if(!GLAD_GL_EXT_framebuffer_multisample) return; - glad_glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)load("glRenderbufferStorageMultisampleEXT"); -} -static void load_GL_EXT_framebuffer_object(GLADloadproc load) { - if(!GLAD_GL_EXT_framebuffer_object) return; - glad_glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC)load("glIsRenderbufferEXT"); - glad_glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)load("glBindRenderbufferEXT"); - glad_glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)load("glDeleteRenderbuffersEXT"); - glad_glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)load("glGenRenderbuffersEXT"); - glad_glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)load("glRenderbufferStorageEXT"); - glad_glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)load("glGetRenderbufferParameterivEXT"); - glad_glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC)load("glIsFramebufferEXT"); - glad_glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)load("glBindFramebufferEXT"); - glad_glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)load("glDeleteFramebuffersEXT"); - glad_glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)load("glGenFramebuffersEXT"); - glad_glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)load("glCheckFramebufferStatusEXT"); - glad_glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)load("glFramebufferTexture1DEXT"); - glad_glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)load("glFramebufferTexture2DEXT"); - glad_glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)load("glFramebufferTexture3DEXT"); - glad_glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)load("glFramebufferRenderbufferEXT"); - glad_glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)load("glGetFramebufferAttachmentParameterivEXT"); - glad_glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC)load("glGenerateMipmapEXT"); -} -static void load_GL_OVR_multiview(GLADloadproc load) { - if(!GLAD_GL_OVR_multiview) return; - glad_glFramebufferTextureMultiviewOVR = (PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC)load("glFramebufferTextureMultiviewOVR"); -} -static int find_extensionsGL(void) { - if (!get_exts()) return 0; - GLAD_GL_ARB_debug_output = has_ext("GL_ARB_debug_output"); - GLAD_GL_ARB_framebuffer_object = has_ext("GL_ARB_framebuffer_object"); - GLAD_GL_EXT_framebuffer_blit = has_ext("GL_EXT_framebuffer_blit"); - GLAD_GL_EXT_framebuffer_multisample = has_ext("GL_EXT_framebuffer_multisample"); - GLAD_GL_EXT_framebuffer_object = has_ext("GL_EXT_framebuffer_object"); - GLAD_GL_OVR_multiview = has_ext("GL_OVR_multiview"); - GLAD_GL_OVR_multiview2 = has_ext("GL_OVR_multiview2"); - free_exts(); - return 1; -} - -static void find_coreGL(void) { - - /* Thank you @elmindreda - * https://github.com/elmindreda/greg/blob/master/templates/greg.c.in#L176 - * https://github.com/glfw/glfw/blob/master/src/context.c#L36 - */ - int i, major, minor; - - const char* version; - const char* prefixes[] = { - "OpenGL ES-CM ", - "OpenGL ES-CL ", - "OpenGL ES ", - NULL - }; - - version = (const char*) glGetString(GL_VERSION); - if (!version) return; - - for (i = 0; prefixes[i]; i++) { - const size_t length = strlen(prefixes[i]); - if (strncmp(version, prefixes[i], length) == 0) { - version += length; - break; - } - } - -/* PR #18 */ -#ifdef _MSC_VER - sscanf_s(version, "%d.%d", &major, &minor); -#else - sscanf(version, "%d.%d", &major, &minor); -#endif - - GLVersion.major = major; GLVersion.minor = minor; - max_loaded_major = major; max_loaded_minor = minor; - GLAD_GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; - GLAD_GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; - GLAD_GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; - GLAD_GL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; - GLAD_GL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; - GLAD_GL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; - GLAD_GL_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; - GLAD_GL_VERSION_2_1 = (major == 2 && minor >= 1) || major > 2; - GLAD_GL_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; - GLAD_GL_VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; - GLAD_GL_VERSION_3_2 = (major == 3 && minor >= 2) || major > 3; - GLAD_GL_VERSION_3_3 = (major == 3 && minor >= 3) || major > 3; - if (GLVersion.major > 3 || (GLVersion.major >= 3 && GLVersion.minor >= 3)) { - max_loaded_major = 3; - max_loaded_minor = 3; - } -} - -int gladLoadGLLoader(GLADloadproc load) { - GLVersion.major = 0; GLVersion.minor = 0; - glGetString = (PFNGLGETSTRINGPROC)load("glGetString"); - if(glGetString == NULL) return 0; - if(glGetString(GL_VERSION) == NULL) return 0; - find_coreGL(); - load_GL_VERSION_1_0(load); - load_GL_VERSION_1_1(load); - load_GL_VERSION_1_2(load); - load_GL_VERSION_1_3(load); - load_GL_VERSION_1_4(load); - load_GL_VERSION_1_5(load); - load_GL_VERSION_2_0(load); - load_GL_VERSION_2_1(load); - load_GL_VERSION_3_0(load); - load_GL_VERSION_3_1(load); - load_GL_VERSION_3_2(load); - load_GL_VERSION_3_3(load); - - if (!find_extensionsGL()) return 0; - load_GL_ARB_debug_output(load); - load_GL_ARB_framebuffer_object(load); - load_GL_EXT_framebuffer_blit(load); - load_GL_EXT_framebuffer_multisample(load); - load_GL_EXT_framebuffer_object(load); - load_GL_OVR_multiview(load); - return GLVersion.major != 0 || GLVersion.minor != 0; -} - diff --git a/thirdparty/glad/glad/gl.h b/thirdparty/glad/glad/gl.h new file mode 100644 index 0000000000..9836296226 --- /dev/null +++ b/thirdparty/glad/glad/gl.h @@ -0,0 +1,3884 @@ +/** + * Loader generated by glad 2.0.2 on Mon Nov 7 12:17:15 2022 + * + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + * + * Generator: C/C++ + * Specification: gl + * Extensions: 7 + * + * APIs: + * - gl:compatibility=3.3 + * + * Options: + * - ALIAS = False + * - DEBUG = False + * - HEADER_ONLY = False + * - LOADER = True + * - MX = False + * - ON_DEMAND = False + * + * Commandline: + * --api='gl:compatibility=3.3' --extensions='GL_ARB_debug_output,GL_ARB_framebuffer_object,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_object,GL_OVR_multiview,GL_OVR_multiview2' c --loader + * + * Online: + * http://glad.sh/#api=gl%3Acompatibility%3D3.3&extensions=GL_ARB_debug_output%2CGL_ARB_framebuffer_object%2CGL_EXT_framebuffer_blit%2CGL_EXT_framebuffer_multisample%2CGL_EXT_framebuffer_object%2CGL_OVR_multiview%2CGL_OVR_multiview2&generator=c&options=LOADER + * + */ + +#ifndef GLAD_GL_H_ +#define GLAD_GL_H_ + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreserved-id-macro" +#endif +#ifdef __gl_h_ + #error OpenGL (gl.h) header already included (API: gl), remove previous include! +#endif +#define __gl_h_ 1 +#ifdef __gl3_h_ + #error OpenGL (gl3.h) header already included (API: gl), remove previous include! +#endif +#define __gl3_h_ 1 +#ifdef __glext_h_ + #error OpenGL (glext.h) header already included (API: gl), remove previous include! +#endif +#define __glext_h_ 1 +#ifdef __gl3ext_h_ + #error OpenGL (gl3ext.h) header already included (API: gl), remove previous include! +#endif +#define __gl3ext_h_ 1 +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#define GLAD_GL +#define GLAD_OPTION_GL_LOADER + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef GLAD_PLATFORM_H_ +#define GLAD_PLATFORM_H_ + +#ifndef GLAD_PLATFORM_WIN32 + #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__) + #define GLAD_PLATFORM_WIN32 1 + #else + #define GLAD_PLATFORM_WIN32 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_APPLE + #ifdef __APPLE__ + #define GLAD_PLATFORM_APPLE 1 + #else + #define GLAD_PLATFORM_APPLE 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_EMSCRIPTEN + #ifdef __EMSCRIPTEN__ + #define GLAD_PLATFORM_EMSCRIPTEN 1 + #else + #define GLAD_PLATFORM_EMSCRIPTEN 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_UWP + #if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY) + #ifdef __has_include + #if __has_include(<winapifamily.h>) + #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 + #endif + #elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ + #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 + #endif + #endif + + #ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY + #include <winapifamily.h> + #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) + #define GLAD_PLATFORM_UWP 1 + #endif + #endif + + #ifndef GLAD_PLATFORM_UWP + #define GLAD_PLATFORM_UWP 0 + #endif +#endif + +#ifdef __GNUC__ + #define GLAD_GNUC_EXTENSION __extension__ +#else + #define GLAD_GNUC_EXTENSION +#endif + +#define GLAD_UNUSED(x) (void)(x) + +#ifndef GLAD_API_CALL + #if defined(GLAD_API_CALL_EXPORT) + #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) + #if defined(GLAD_API_CALL_EXPORT_BUILD) + #if defined(__GNUC__) + #define GLAD_API_CALL __attribute__ ((dllexport)) extern + #else + #define GLAD_API_CALL __declspec(dllexport) extern + #endif + #else + #if defined(__GNUC__) + #define GLAD_API_CALL __attribute__ ((dllimport)) extern + #else + #define GLAD_API_CALL __declspec(dllimport) extern + #endif + #endif + #elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD) + #define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern + #else + #define GLAD_API_CALL extern + #endif + #else + #define GLAD_API_CALL extern + #endif +#endif + +#ifdef APIENTRY + #define GLAD_API_PTR APIENTRY +#elif GLAD_PLATFORM_WIN32 + #define GLAD_API_PTR __stdcall +#else + #define GLAD_API_PTR +#endif + +#ifndef GLAPI +#define GLAPI GLAD_API_CALL +#endif + +#ifndef GLAPIENTRY +#define GLAPIENTRY GLAD_API_PTR +#endif + +#define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor) +#define GLAD_VERSION_MAJOR(version) (version / 10000) +#define GLAD_VERSION_MINOR(version) (version % 10000) + +#define GLAD_GENERATOR_VERSION "2.0.2" + +typedef void (*GLADapiproc)(void); + +typedef GLADapiproc (*GLADloadfunc)(const char *name); +typedef GLADapiproc (*GLADuserptrloadfunc)(void *userptr, const char *name); + +typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...); +typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...); + +#endif /* GLAD_PLATFORM_H_ */ + +#define GL_2D 0x0600 +#define GL_2_BYTES 0x1407 +#define GL_3D 0x0601 +#define GL_3D_COLOR 0x0602 +#define GL_3D_COLOR_TEXTURE 0x0603 +#define GL_3_BYTES 0x1408 +#define GL_4D_COLOR_TEXTURE 0x0604 +#define GL_4_BYTES 0x1409 +#define GL_ACCUM 0x0100 +#define GL_ACCUM_ALPHA_BITS 0x0D5B +#define GL_ACCUM_BLUE_BITS 0x0D5A +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#define GL_ACCUM_CLEAR_VALUE 0x0B80 +#define GL_ACCUM_GREEN_BITS 0x0D59 +#define GL_ACCUM_RED_BITS 0x0D58 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ADD 0x0104 +#define GL_ADD_SIGNED 0x8574 +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALL_ATTRIB_BITS 0xFFFFFFFF +#define GL_ALPHA 0x1906 +#define GL_ALPHA12 0x803D +#define GL_ALPHA16 0x803E +#define GL_ALPHA4 0x803B +#define GL_ALPHA8 0x803C +#define GL_ALPHA_BIAS 0x0D1D +#define GL_ALPHA_BITS 0x0D55 +#define GL_ALPHA_INTEGER 0x8D97 +#define GL_ALPHA_SCALE 0x0D1C +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_FUNC 0x0BC1 +#define GL_ALPHA_TEST_REF 0x0BC2 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_ALWAYS 0x0207 +#define GL_AMBIENT 0x1200 +#define GL_AMBIENT_AND_DIFFUSE 0x1602 +#define GL_AND 0x1501 +#define GL_AND_INVERTED 0x1504 +#define GL_AND_REVERSE 0x1502 +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ATTRIB_STACK_DEPTH 0x0BB0 +#define GL_AUTO_NORMAL 0x0D80 +#define GL_AUX0 0x0409 +#define GL_AUX1 0x040A +#define GL_AUX2 0x040B +#define GL_AUX3 0x040C +#define GL_AUX_BUFFERS 0x0C00 +#define GL_BACK 0x0405 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_BGRA_INTEGER 0x8D9B +#define GL_BGR_INTEGER 0x8D9A +#define GL_BITMAP 0x1A00 +#define GL_BITMAP_TOKEN 0x0704 +#define GL_BLEND 0x0BE2 +#define GL_BLEND_COLOR 0x8005 +#define GL_BLEND_DST 0x0BE0 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLUE 0x1905 +#define GL_BLUE_BIAS 0x0D1B +#define GL_BLUE_BITS 0x0D54 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_BLUE_SCALE 0x0D1A +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_BYTE 0x1400 +#define GL_C3F_V3F 0x2A24 +#define GL_C4F_N3F_V3F 0x2A26 +#define GL_C4UB_V2F 0x2A22 +#define GL_C4UB_V3F 0x2A23 +#define GL_CCW 0x0901 +#define GL_CLAMP 0x2900 +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_CLAMP_VERTEX_COLOR 0x891A +#define GL_CLEAR 0x1500 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF +#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_CLIP_DISTANCE0 0x3000 +#define GL_CLIP_DISTANCE1 0x3001 +#define GL_CLIP_DISTANCE2 0x3002 +#define GL_CLIP_DISTANCE3 0x3003 +#define GL_CLIP_DISTANCE4 0x3004 +#define GL_CLIP_DISTANCE5 0x3005 +#define GL_CLIP_DISTANCE6 0x3006 +#define GL_CLIP_DISTANCE7 0x3007 +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE5 0x3005 +#define GL_COEFF 0x0A00 +#define GL_COLOR 0x1800 +#define GL_COLOR_ARRAY 0x8076 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_COLOR_ARRAY_POINTER 0x8090 +#define GL_COLOR_ARRAY_SIZE 0x8081 +#define GL_COLOR_ARRAY_STRIDE 0x8083 +#define GL_COLOR_ARRAY_TYPE 0x8082 +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_COLOR_ATTACHMENT16 0x8CF0 +#define GL_COLOR_ATTACHMENT17 0x8CF1 +#define GL_COLOR_ATTACHMENT18 0x8CF2 +#define GL_COLOR_ATTACHMENT19 0x8CF3 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT20 0x8CF4 +#define GL_COLOR_ATTACHMENT21 0x8CF5 +#define GL_COLOR_ATTACHMENT22 0x8CF6 +#define GL_COLOR_ATTACHMENT23 0x8CF7 +#define GL_COLOR_ATTACHMENT24 0x8CF8 +#define GL_COLOR_ATTACHMENT25 0x8CF9 +#define GL_COLOR_ATTACHMENT26 0x8CFA +#define GL_COLOR_ATTACHMENT27 0x8CFB +#define GL_COLOR_ATTACHMENT28 0x8CFC +#define GL_COLOR_ATTACHMENT29 0x8CFD +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT30 0x8CFE +#define GL_COLOR_ATTACHMENT31 0x8CFF +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_INDEX 0x1900 +#define GL_COLOR_INDEXES 0x1603 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_COLOR_MATERIAL 0x0B57 +#define GL_COLOR_MATERIAL_FACE 0x0B55 +#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 +#define GL_COLOR_SUM 0x8458 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_COMBINE 0x8570 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_COMPARE_R_TO_TEXTURE 0x884E +#define GL_COMPILE 0x1300 +#define GL_COMPILE_AND_EXECUTE 0x1301 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_RG 0x8226 +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_CONDITION_SATISFIED 0x911C +#define GL_CONSTANT 0x8576 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_CONSTANT_ATTENUATION 0x1207 +#define GL_CONSTANT_COLOR 0x8001 +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_FLAGS 0x821E +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 +#define GL_CONTEXT_PROFILE_MASK 0x9126 +#define GL_COORD_REPLACE 0x8862 +#define GL_COPY 0x1503 +#define GL_COPY_INVERTED 0x150C +#define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_CURRENT_BIT 0x00000001 +#define GL_CURRENT_COLOR 0x0B00 +#define GL_CURRENT_FOG_COORD 0x8453 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_CURRENT_INDEX 0x0B01 +#define GL_CURRENT_NORMAL 0x0B02 +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_CURRENT_QUERY 0x8865 +#define GL_CURRENT_RASTER_COLOR 0x0B04 +#define GL_CURRENT_RASTER_DISTANCE 0x0B09 +#define GL_CURRENT_RASTER_INDEX 0x0B05 +#define GL_CURRENT_RASTER_POSITION 0x0B07 +#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_CURRENT_TEXTURE_COORDS 0x0B03 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_CW 0x0900 +#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 +#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 +#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 +#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 +#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 +#define GL_DEBUG_SOURCE_API_ARB 0x8246 +#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A +#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B +#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D +#define GL_DEBUG_TYPE_ERROR_ARB 0x824C +#define GL_DEBUG_TYPE_OTHER_ARB 0x8251 +#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 +#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E +#define GL_DECAL 0x2101 +#define GL_DECR 0x1E03 +#define GL_DECR_WRAP 0x8508 +#define GL_DELETE_STATUS 0x8B80 +#define GL_DEPTH 0x1801 +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_DEPTH_BIAS 0x0D1F +#define GL_DEPTH_BITS 0x0D56 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_DEPTH_CLAMP 0x864F +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH_FUNC 0x0B74 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_SCALE 0x0D1E +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DIFFUSE 0x1201 +#define GL_DITHER 0x0BD0 +#define GL_DOMAIN 0x0A02 +#define GL_DONT_CARE 0x1100 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#define GL_DOUBLE 0x140A +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_DRAW_PIXEL_TOKEN 0x0705 +#define GL_DST_ALPHA 0x0304 +#define GL_DST_COLOR 0x0306 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_EDGE_FLAG 0x0B43 +#define GL_EDGE_FLAG_ARRAY 0x8079 +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 +#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_EMISSION 0x1600 +#define GL_ENABLE_BIT 0x00002000 +#define GL_EQUAL 0x0202 +#define GL_EQUIV 0x1509 +#define GL_EVAL_BIT 0x00010000 +#define GL_EXP 0x0800 +#define GL_EXP2 0x0801 +#define GL_EXTENSIONS 0x1F03 +#define GL_EYE_LINEAR 0x2400 +#define GL_EYE_PLANE 0x2502 +#define GL_FALSE 0 +#define GL_FASTEST 0x1101 +#define GL_FEEDBACK 0x1C01 +#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 +#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 +#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 +#define GL_FILL 0x1B02 +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_FIXED_ONLY 0x891D +#define GL_FLAT 0x1D00 +#define GL_FLOAT 0x1406 +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4 0x8B5C +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_FOG 0x0B60 +#define GL_FOG_BIT 0x00000080 +#define GL_FOG_COLOR 0x0B66 +#define GL_FOG_COORD 0x8451 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORD_ARRAY 0x8457 +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D +#define GL_FOG_COORD_ARRAY_POINTER 0x8456 +#define GL_FOG_COORD_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORD_ARRAY_TYPE 0x8454 +#define GL_FOG_COORD_SRC 0x8450 +#define GL_FOG_DENSITY 0x0B62 +#define GL_FOG_END 0x0B64 +#define GL_FOG_HINT 0x0C54 +#define GL_FOG_INDEX 0x0B61 +#define GL_FOG_MODE 0x0B65 +#define GL_FOG_START 0x0B63 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_FRAMEBUFFER 0x8D40 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR 0x9633 +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_FRONT 0x0404 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_FRONT_FACE 0x0B46 +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_FUNC_SUBTRACT 0x800A +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEQUAL 0x0206 +#define GL_GREATER 0x0204 +#define GL_GREEN 0x1904 +#define GL_GREEN_BIAS 0x0D19 +#define GL_GREEN_BITS 0x0D53 +#define GL_GREEN_INTEGER 0x8D95 +#define GL_GREEN_SCALE 0x0D18 +#define GL_HALF_FLOAT 0x140B +#define GL_HINT_BIT 0x00008000 +#define GL_INCR 0x1E02 +#define GL_INCR_WRAP 0x8507 +#define GL_INDEX 0x8222 +#define GL_INDEX_ARRAY 0x8077 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_INDEX_ARRAY_POINTER 0x8091 +#define GL_INDEX_ARRAY_STRIDE 0x8086 +#define GL_INDEX_ARRAY_TYPE 0x8085 +#define GL_INDEX_BITS 0x0D51 +#define GL_INDEX_CLEAR_VALUE 0x0C20 +#define GL_INDEX_LOGIC_OP 0x0BF1 +#define GL_INDEX_MODE 0x0C30 +#define GL_INDEX_OFFSET 0x0D13 +#define GL_INDEX_SHIFT 0x0D12 +#define GL_INDEX_WRITEMASK 0x0C21 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_INT 0x1404 +#define GL_INTENSITY 0x8049 +#define GL_INTENSITY12 0x804C +#define GL_INTENSITY16 0x804D +#define GL_INTENSITY4 0x804A +#define GL_INTENSITY8 0x804B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_INTERPOLATE 0x8575 +#define GL_INT_2_10_10_10_REV 0x8D9F +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#define GL_INVALID_INDEX 0xFFFFFFFF +#define GL_INVALID_OPERATION 0x0502 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVERT 0x150A +#define GL_KEEP 0x1E00 +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_LEFT 0x0406 +#define GL_LEQUAL 0x0203 +#define GL_LESS 0x0201 +#define GL_LIGHT0 0x4000 +#define GL_LIGHT1 0x4001 +#define GL_LIGHT2 0x4002 +#define GL_LIGHT3 0x4003 +#define GL_LIGHT4 0x4004 +#define GL_LIGHT5 0x4005 +#define GL_LIGHT6 0x4006 +#define GL_LIGHT7 0x4007 +#define GL_LIGHTING 0x0B50 +#define GL_LIGHTING_BIT 0x00000040 +#define GL_LIGHT_MODEL_AMBIENT 0x0B53 +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 +#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 +#define GL_LINE 0x1B01 +#define GL_LINEAR 0x2601 +#define GL_LINEAR_ATTENUATION 0x1208 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_LINES 0x0001 +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINE_BIT 0x00000004 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_RESET_TOKEN 0x0707 +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_LINE_STIPPLE 0x0B24 +#define GL_LINE_STIPPLE_PATTERN 0x0B25 +#define GL_LINE_STIPPLE_REPEAT 0x0B26 +#define GL_LINE_STRIP 0x0003 +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_LINE_TOKEN 0x0702 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_LINE_WIDTH_RANGE 0x0B22 +#define GL_LINK_STATUS 0x8B82 +#define GL_LIST_BASE 0x0B32 +#define GL_LIST_BIT 0x00020000 +#define GL_LIST_INDEX 0x0B33 +#define GL_LIST_MODE 0x0B30 +#define GL_LOAD 0x0101 +#define GL_LOGIC_OP 0x0BF1 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE12 0x8041 +#define GL_LUMINANCE12_ALPHA12 0x8047 +#define GL_LUMINANCE12_ALPHA4 0x8046 +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_LUMINANCE4 0x803F +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_LUMINANCE6_ALPHA2 0x8044 +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_MAJOR_VERSION 0x821B +#define GL_MAP1_COLOR_4 0x0D90 +#define GL_MAP1_GRID_DOMAIN 0x0DD0 +#define GL_MAP1_GRID_SEGMENTS 0x0DD1 +#define GL_MAP1_INDEX 0x0D91 +#define GL_MAP1_NORMAL 0x0D92 +#define GL_MAP1_TEXTURE_COORD_1 0x0D93 +#define GL_MAP1_TEXTURE_COORD_2 0x0D94 +#define GL_MAP1_TEXTURE_COORD_3 0x0D95 +#define GL_MAP1_TEXTURE_COORD_4 0x0D96 +#define GL_MAP1_VERTEX_3 0x0D97 +#define GL_MAP1_VERTEX_4 0x0D98 +#define GL_MAP2_COLOR_4 0x0DB0 +#define GL_MAP2_GRID_DOMAIN 0x0DD2 +#define GL_MAP2_GRID_SEGMENTS 0x0DD3 +#define GL_MAP2_INDEX 0x0DB1 +#define GL_MAP2_NORMAL 0x0DB2 +#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GL_MAP2_VERTEX_3 0x0DB7 +#define GL_MAP2_VERTEX_4 0x0DB8 +#define GL_MAP_COLOR 0x0D10 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_STENCIL 0x0D11 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MATRIX_MODE 0x0BA0 +#define GL_MAX 0x8008 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 +#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B +#define GL_MAX_CLIP_DISTANCES 0x0D32 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_EVAL_ORDER 0x0D30 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_INTEGER_SAMPLES 0x9110 +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_LIST_NESTING 0x0B31 +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_NAME_STACK_DEPTH 0x0D37 +#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_MAX_SAMPLES_EXT 0x8D57 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_MAX_TEXTURE_COORDS 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MAX_VIEWS_OVR 0x9631 +#define GL_MIN 0x8007 +#define GL_MINOR_VERSION 0x821C +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_MODELVIEW 0x1700 +#define GL_MODELVIEW_MATRIX 0x0BA6 +#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 +#define GL_MODULATE 0x2100 +#define GL_MULT 0x0103 +#define GL_MULTISAMPLE 0x809D +#define GL_MULTISAMPLE_BIT 0x20000000 +#define GL_N3F_V3F 0x2A25 +#define GL_NAME_STACK_DEPTH 0x0D70 +#define GL_NAND 0x150E +#define GL_NEAREST 0x2600 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_NEVER 0x0200 +#define GL_NICEST 0x1102 +#define GL_NONE 0 +#define GL_NOOP 0x1505 +#define GL_NOR 0x1508 +#define GL_NORMALIZE 0x0BA1 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_NORMAL_ARRAY_POINTER 0x808F +#define GL_NORMAL_ARRAY_STRIDE 0x807F +#define GL_NORMAL_ARRAY_TYPE 0x807E +#define GL_NORMAL_MAP 0x8511 +#define GL_NOTEQUAL 0x0205 +#define GL_NO_ERROR 0 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_NUM_EXTENSIONS 0x821D +#define GL_OBJECT_LINEAR 0x2401 +#define GL_OBJECT_PLANE 0x2501 +#define GL_OBJECT_TYPE 0x9112 +#define GL_ONE 1 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB +#define GL_ONE_MINUS_SRC1_COLOR 0x88FA +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_OPERAND2_RGB 0x8592 +#define GL_OR 0x1507 +#define GL_ORDER 0x0A01 +#define GL_OR_INVERTED 0x150D +#define GL_OR_REVERSE 0x150B +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_PASS_THROUGH_TOKEN 0x0700 +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_PIXEL_MAP_A_TO_A 0x0C79 +#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 +#define GL_PIXEL_MAP_B_TO_B 0x0C78 +#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 +#define GL_PIXEL_MAP_G_TO_G 0x0C77 +#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 +#define GL_PIXEL_MAP_I_TO_A 0x0C75 +#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 +#define GL_PIXEL_MAP_I_TO_B 0x0C74 +#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 +#define GL_PIXEL_MAP_I_TO_G 0x0C73 +#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 +#define GL_PIXEL_MAP_I_TO_I 0x0C70 +#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 +#define GL_PIXEL_MAP_I_TO_R 0x0C72 +#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 +#define GL_PIXEL_MAP_R_TO_R 0x0C76 +#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 +#define GL_PIXEL_MAP_S_TO_S 0x0C71 +#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 +#define GL_PIXEL_MODE_BIT 0x00000020 +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_POINT 0x1B00 +#define GL_POINTS 0x0000 +#define GL_POINT_BIT 0x00000002 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_RANGE 0x0B12 +#define GL_POINT_SMOOTH 0x0B10 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_POINT_SPRITE 0x8861 +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_POINT_TOKEN 0x0701 +#define GL_POLYGON 0x0009 +#define GL_POLYGON_BIT 0x00000008 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_POLYGON_STIPPLE 0x0B42 +#define GL_POLYGON_STIPPLE_BIT 0x00000010 +#define GL_POLYGON_TOKEN 0x0703 +#define GL_POSITION 0x1203 +#define GL_PREVIOUS 0x8578 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_PROJECTION 0x1701 +#define GL_PROJECTION_MATRIX 0x0BA7 +#define GL_PROJECTION_STACK_DEPTH 0x0BA4 +#define GL_PROVOKING_VERTEX 0x8E4F +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_Q 0x2003 +#define GL_QUADRATIC_ATTENUATION 0x1209 +#define GL_QUADS 0x0007 +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C +#define GL_QUAD_STRIP 0x0008 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_QUERY_WAIT 0x8E13 +#define GL_R 0x2002 +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_R16 0x822A +#define GL_R16F 0x822D +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R16_SNORM 0x8F98 +#define GL_R32F 0x822E +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_R3_G3_B2 0x2A10 +#define GL_R8 0x8229 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R8_SNORM 0x8F94 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_READ_BUFFER 0x0C02 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_READ_ONLY 0x88B8 +#define GL_READ_WRITE 0x88BA +#define GL_RED 0x1903 +#define GL_RED_BIAS 0x0D15 +#define GL_RED_BITS 0x0D52 +#define GL_RED_INTEGER 0x8D94 +#define GL_RED_SCALE 0x0D14 +#define GL_REFLECTION_MAP 0x8512 +#define GL_RENDER 0x1C00 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERER 0x1F01 +#define GL_RENDER_MODE 0x0C40 +#define GL_REPEAT 0x2901 +#define GL_REPLACE 0x1E01 +#define GL_RESCALE_NORMAL 0x803A +#define GL_RETURN 0x0102 +#define GL_RG 0x8227 +#define GL_RG16 0x822C +#define GL_RG16F 0x822F +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG16_SNORM 0x8F99 +#define GL_RG32F 0x8230 +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_RG8 0x822B +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB 0x1907 +#define GL_RGB10 0x8052 +#define GL_RGB10_A2 0x8059 +#define GL_RGB10_A2UI 0x906F +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGB16F 0x881B +#define GL_RGB16I 0x8D89 +#define GL_RGB16UI 0x8D77 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGB32F 0x8815 +#define GL_RGB32I 0x8D83 +#define GL_RGB32UI 0x8D71 +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB5_A1 0x8057 +#define GL_RGB8 0x8051 +#define GL_RGB8I 0x8D8F +#define GL_RGB8UI 0x8D7D +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGB9_E5 0x8C3D +#define GL_RGBA 0x1908 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#define GL_RGBA16F 0x881A +#define GL_RGBA16I 0x8D88 +#define GL_RGBA16UI 0x8D76 +#define GL_RGBA16_SNORM 0x8F9B +#define GL_RGBA2 0x8055 +#define GL_RGBA32F 0x8814 +#define GL_RGBA32I 0x8D82 +#define GL_RGBA32UI 0x8D70 +#define GL_RGBA4 0x8056 +#define GL_RGBA8 0x8058 +#define GL_RGBA8I 0x8D8E +#define GL_RGBA8UI 0x8D7C +#define GL_RGBA8_SNORM 0x8F97 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_RGBA_MODE 0x0C31 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGB_SCALE 0x8573 +#define GL_RG_INTEGER 0x8228 +#define GL_RIGHT 0x0407 +#define GL_S 0x2000 +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_BINDING 0x8919 +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLES_PASSED 0x8914 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SCISSOR_BIT 0x00080000 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SELECT 0x1C02 +#define GL_SELECTION_BUFFER_POINTER 0x0DF3 +#define GL_SELECTION_BUFFER_SIZE 0x0DF4 +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_SET 0x150F +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_TYPE 0x8B4F +#define GL_SHADE_MODEL 0x0B54 +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_SHININESS 0x1601 +#define GL_SHORT 0x1402 +#define GL_SIGNALED 0x9119 +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SMOOTH 0x1D01 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_SOURCE2_RGB 0x8582 +#define GL_SPECULAR 0x1202 +#define GL_SPHERE_MAP 0x2402 +#define GL_SPOT_CUTOFF 0x1206 +#define GL_SPOT_DIRECTION 0x1204 +#define GL_SPOT_EXPONENT 0x1205 +#define GL_SRC0_ALPHA 0x8588 +#define GL_SRC0_RGB 0x8580 +#define GL_SRC1_ALPHA 0x8589 +#define GL_SRC1_COLOR 0x88F9 +#define GL_SRC1_RGB 0x8581 +#define GL_SRC2_ALPHA 0x858A +#define GL_SRC2_RGB 0x8582 +#define GL_SRC_ALPHA 0x0302 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_SRC_COLOR 0x0300 +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_STATIC_COPY 0x88E6 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STENCIL 0x1802 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_STENCIL_BITS 0x0D57 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_INDEX 0x1901 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STEREO 0x0C33 +#define GL_STREAM_COPY 0x88E2 +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_SUBTRACT 0x84E7 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_SYNC_STATUS 0x9114 +#define GL_T 0x2001 +#define GL_T2F_C3F_V3F 0x2A2A +#define GL_T2F_C4F_N3F_V3F 0x2A2C +#define GL_T2F_C4UB_V3F 0x2A29 +#define GL_T2F_N3F_V3F 0x2A2B +#define GL_T2F_V3F 0x2A27 +#define GL_T4F_C4F_N3F_V4F 0x2A2D +#define GL_T4F_V4F 0x2A28 +#define GL_TEXTURE 0x1702 +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_TEXTURE_3D 0x806F +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_TEXTURE_BIT 0x00040000 +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_BORDER 0x1005 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPONENTS 0x1003 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COORD_ARRAY 0x8078 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 +#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 +#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A +#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_TEXTURE_ENV 0x2300 +#define GL_TEXTURE_ENV_COLOR 0x2201 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_TEXTURE_GEN_Q 0x0C63 +#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_INTENSITY_SIZE 0x8061 +#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 +#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MATRIX 0x0BA8 +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_PRIORITY 0x8066 +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_RESIDENT 0x8067 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TEXTURE_STACK_DEPTH 0x0BA5 +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF +#define GL_TIMESTAMP 0x8E28 +#define GL_TIME_ELAPSED 0x88BF +#define GL_TRANSFORM_BIT 0x00001000 +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLE_FAN 0x0006 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_TRUE 1 +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_UNSIGNALED 0x9118 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_INT 0x1405 +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_V2F 0x2A20 +#define GL_V3F 0x2A21 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_VENDOR 0x1F00 +#define GL_VERSION 0x1F02 +#define GL_VERTEX_ARRAY 0x8074 +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_VERTEX_ARRAY_POINTER 0x808E +#define GL_VERTEX_ARRAY_SIZE 0x807A +#define GL_VERTEX_ARRAY_STRIDE 0x807C +#define GL_VERTEX_ARRAY_TYPE 0x807B +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_VIEWPORT 0x0BA2 +#define GL_VIEWPORT_BIT 0x00000800 +#define GL_WAIT_FAILED 0x911D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_WRITE_ONLY 0x88B9 +#define GL_XOR 0x1506 +#define GL_ZERO 0 +#define GL_ZOOM_X 0x0D16 +#define GL_ZOOM_Y 0x0D17 + + +#include <KHR/khrplatform.h> +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef void GLvoid; +typedef khronos_int8_t GLbyte; +typedef khronos_uint8_t GLubyte; +typedef khronos_int16_t GLshort; +typedef khronos_uint16_t GLushort; +typedef int GLint; +typedef unsigned int GLuint; +typedef khronos_int32_t GLclampx; +typedef int GLsizei; +typedef khronos_float_t GLfloat; +typedef khronos_float_t GLclampf; +typedef double GLdouble; +typedef double GLclampd; +typedef void *GLeglClientBufferEXT; +typedef void *GLeglImageOES; +typedef char GLchar; +typedef char GLcharARB; +#ifdef __APPLE__ +typedef void *GLhandleARB; +#else +typedef unsigned int GLhandleARB; +#endif +typedef khronos_uint16_t GLhalf; +typedef khronos_uint16_t GLhalfARB; +typedef khronos_int32_t GLfixed; +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_intptr_t GLintptr; +#else +typedef khronos_intptr_t GLintptr; +#endif +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_intptr_t GLintptrARB; +#else +typedef khronos_intptr_t GLintptrARB; +#endif +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_ssize_t GLsizeiptr; +#else +typedef khronos_ssize_t GLsizeiptr; +#endif +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_ssize_t GLsizeiptrARB; +#else +typedef khronos_ssize_t GLsizeiptrARB; +#endif +typedef khronos_int64_t GLint64; +typedef khronos_int64_t GLint64EXT; +typedef khronos_uint64_t GLuint64; +typedef khronos_uint64_t GLuint64EXT; +typedef struct __GLsync *GLsync; +struct _cl_context; +struct _cl_event; +typedef void (GLAD_API_PTR *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (GLAD_API_PTR *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (GLAD_API_PTR *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (GLAD_API_PTR *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); +typedef unsigned short GLhalfNV; +typedef GLintptr GLvdpauSurfaceNV; +typedef void (GLAD_API_PTR *GLVULKANPROCNV)(void); + + +#define GL_VERSION_1_0 1 +GLAD_API_CALL int GLAD_GL_VERSION_1_0; +#define GL_VERSION_1_1 1 +GLAD_API_CALL int GLAD_GL_VERSION_1_1; +#define GL_VERSION_1_2 1 +GLAD_API_CALL int GLAD_GL_VERSION_1_2; +#define GL_VERSION_1_3 1 +GLAD_API_CALL int GLAD_GL_VERSION_1_3; +#define GL_VERSION_1_4 1 +GLAD_API_CALL int GLAD_GL_VERSION_1_4; +#define GL_VERSION_1_5 1 +GLAD_API_CALL int GLAD_GL_VERSION_1_5; +#define GL_VERSION_2_0 1 +GLAD_API_CALL int GLAD_GL_VERSION_2_0; +#define GL_VERSION_2_1 1 +GLAD_API_CALL int GLAD_GL_VERSION_2_1; +#define GL_VERSION_3_0 1 +GLAD_API_CALL int GLAD_GL_VERSION_3_0; +#define GL_VERSION_3_1 1 +GLAD_API_CALL int GLAD_GL_VERSION_3_1; +#define GL_VERSION_3_2 1 +GLAD_API_CALL int GLAD_GL_VERSION_3_2; +#define GL_VERSION_3_3 1 +GLAD_API_CALL int GLAD_GL_VERSION_3_3; +#define GL_ARB_debug_output 1 +GLAD_API_CALL int GLAD_GL_ARB_debug_output; +#define GL_ARB_framebuffer_object 1 +GLAD_API_CALL int GLAD_GL_ARB_framebuffer_object; +#define GL_EXT_framebuffer_blit 1 +GLAD_API_CALL int GLAD_GL_EXT_framebuffer_blit; +#define GL_EXT_framebuffer_multisample 1 +GLAD_API_CALL int GLAD_GL_EXT_framebuffer_multisample; +#define GL_EXT_framebuffer_object 1 +GLAD_API_CALL int GLAD_GL_EXT_framebuffer_object; +#define GL_OVR_multiview 1 +GLAD_API_CALL int GLAD_GL_OVR_multiview; +#define GL_OVR_multiview2 1 +GLAD_API_CALL int GLAD_GL_OVR_multiview2; + + +typedef void (GLAD_API_PTR *PFNGLACCUMPROC)(GLenum op, GLfloat value); +typedef void (GLAD_API_PTR *PFNGLACTIVETEXTUREPROC)(GLenum texture); +typedef void (GLAD_API_PTR *PFNGLALPHAFUNCPROC)(GLenum func, GLfloat ref); +typedef GLboolean (GLAD_API_PTR *PFNGLARETEXTURESRESIDENTPROC)(GLsizei n, const GLuint * textures, GLboolean * residences); +typedef void (GLAD_API_PTR *PFNGLARRAYELEMENTPROC)(GLint i); +typedef void (GLAD_API_PTR *PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader); +typedef void (GLAD_API_PTR *PFNGLBEGINPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLBEGINCONDITIONALRENDERPROC)(GLuint id, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLBEGINQUERYPROC)(GLenum target, GLuint id); +typedef void (GLAD_API_PTR *PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum primitiveMode); +typedef void (GLAD_API_PTR *PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERBASEPROC)(GLenum target, GLuint index, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERRANGEPROC)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLBINDFRAGDATALOCATIONPROC)(GLuint program, GLuint color, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)(GLuint program, GLuint colorNumber, GLuint index, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer); +typedef void (GLAD_API_PTR *PFNGLBINDFRAMEBUFFEREXTPROC)(GLenum target, GLuint framebuffer); +typedef void (GLAD_API_PTR *PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLBINDRENDERBUFFEREXTPROC)(GLenum target, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLBINDSAMPLERPROC)(GLuint unit, GLuint sampler); +typedef void (GLAD_API_PTR *PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture); +typedef void (GLAD_API_PTR *PFNGLBINDVERTEXARRAYPROC)(GLuint array); +typedef void (GLAD_API_PTR *PFNGLBITMAPPROC)(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte * bitmap); +typedef void (GLAD_API_PTR *PFNGLBLENDCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCPROC)(GLenum sfactor, GLenum dfactor); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GLAD_API_PTR *PFNGLBLITFRAMEBUFFERPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GLAD_API_PTR *PFNGLBLITFRAMEBUFFEREXTPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GLAD_API_PTR *PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void * data, GLenum usage); +typedef void (GLAD_API_PTR *PFNGLBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, const void * data); +typedef void (GLAD_API_PTR *PFNGLCALLLISTPROC)(GLuint list); +typedef void (GLAD_API_PTR *PFNGLCALLLISTSPROC)(GLsizei n, GLenum type, const void * lists); +typedef GLenum (GLAD_API_PTR *PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target); +typedef GLenum (GLAD_API_PTR *PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLCLAMPCOLORPROC)(GLenum target, GLenum clamp); +typedef void (GLAD_API_PTR *PFNGLCLEARPROC)(GLbitfield mask); +typedef void (GLAD_API_PTR *PFNGLCLEARACCUMPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERFIPROC)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERFVPROC)(GLenum buffer, GLint drawbuffer, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERIVPROC)(GLenum buffer, GLint drawbuffer, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERUIVPROC)(GLenum buffer, GLint drawbuffer, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHPROC)(GLdouble depth); +typedef void (GLAD_API_PTR *PFNGLCLEARINDEXPROC)(GLfloat c); +typedef void (GLAD_API_PTR *PFNGLCLEARSTENCILPROC)(GLint s); +typedef void (GLAD_API_PTR *PFNGLCLIENTACTIVETEXTUREPROC)(GLenum texture); +typedef GLenum (GLAD_API_PTR *PFNGLCLIENTWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GLAD_API_PTR *PFNGLCLIPPLANEPROC)(GLenum plane, const GLdouble * equation); +typedef void (GLAD_API_PTR *PFNGLCOLOR3BPROC)(GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAD_API_PTR *PFNGLCOLOR3BVPROC)(const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR3DPROC)(GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAD_API_PTR *PFNGLCOLOR3DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR3FPROC)(GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAD_API_PTR *PFNGLCOLOR3FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR3IPROC)(GLint red, GLint green, GLint blue); +typedef void (GLAD_API_PTR *PFNGLCOLOR3IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR3SPROC)(GLshort red, GLshort green, GLshort blue); +typedef void (GLAD_API_PTR *PFNGLCOLOR3SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR3UBPROC)(GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAD_API_PTR *PFNGLCOLOR3UBVPROC)(const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR3UIPROC)(GLuint red, GLuint green, GLuint blue); +typedef void (GLAD_API_PTR *PFNGLCOLOR3UIVPROC)(const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR3USPROC)(GLushort red, GLushort green, GLushort blue); +typedef void (GLAD_API_PTR *PFNGLCOLOR3USVPROC)(const GLushort * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4BPROC)(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); +typedef void (GLAD_API_PTR *PFNGLCOLOR4BVPROC)(const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4DPROC)(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); +typedef void (GLAD_API_PTR *PFNGLCOLOR4DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4FPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GLAD_API_PTR *PFNGLCOLOR4FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4IPROC)(GLint red, GLint green, GLint blue, GLint alpha); +typedef void (GLAD_API_PTR *PFNGLCOLOR4IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4SPROC)(GLshort red, GLshort green, GLshort blue, GLshort alpha); +typedef void (GLAD_API_PTR *PFNGLCOLOR4SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4UBPROC)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +typedef void (GLAD_API_PTR *PFNGLCOLOR4UBVPROC)(const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4UIPROC)(GLuint red, GLuint green, GLuint blue, GLuint alpha); +typedef void (GLAD_API_PTR *PFNGLCOLOR4UIVPROC)(const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4USPROC)(GLushort red, GLushort green, GLushort blue, GLushort alpha); +typedef void (GLAD_API_PTR *PFNGLCOLOR4USVPROC)(const GLushort * v); +typedef void (GLAD_API_PTR *PFNGLCOLORMASKPROC)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +typedef void (GLAD_API_PTR *PFNGLCOLORMASKIPROC)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (GLAD_API_PTR *PFNGLCOLORMATERIALPROC)(GLenum face, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLCOLORP3UIPROC)(GLenum type, GLuint color); +typedef void (GLAD_API_PTR *PFNGLCOLORP3UIVPROC)(GLenum type, const GLuint * color); +typedef void (GLAD_API_PTR *PFNGLCOLORP4UIPROC)(GLenum type, GLuint color); +typedef void (GLAD_API_PTR *PFNGLCOLORP4UIVPROC)(GLenum type, const GLuint * color); +typedef void (GLAD_API_PTR *PFNGLCOLORPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLCOMPILESHADERPROC)(GLuint shader); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE3DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOPYBUFFERSUBDATAPROC)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLCOPYPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef GLuint (GLAD_API_PTR *PFNGLCREATEPROGRAMPROC)(void); +typedef GLuint (GLAD_API_PTR *PFNGLCREATESHADERPROC)(GLenum type); +typedef void (GLAD_API_PTR *PFNGLCULLFACEPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECALLBACKARBPROC)(GLDEBUGPROCARB callback, const void * userParam); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECONTROLARBPROC)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGEINSERTARBPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar * buf); +typedef void (GLAD_API_PTR *PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint * buffers); +typedef void (GLAD_API_PTR *PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint * framebuffers); +typedef void (GLAD_API_PTR *PFNGLDELETEFRAMEBUFFERSEXTPROC)(GLsizei n, const GLuint * framebuffers); +typedef void (GLAD_API_PTR *PFNGLDELETELISTSPROC)(GLuint list, GLsizei range); +typedef void (GLAD_API_PTR *PFNGLDELETEPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLDELETEQUERIESPROC)(GLsizei n, const GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLDELETERENDERBUFFERSEXTPROC)(GLsizei n, const GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLDELETESAMPLERSPROC)(GLsizei count, const GLuint * samplers); +typedef void (GLAD_API_PTR *PFNGLDELETESHADERPROC)(GLuint shader); +typedef void (GLAD_API_PTR *PFNGLDELETESYNCPROC)(GLsync sync); +typedef void (GLAD_API_PTR *PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint * textures); +typedef void (GLAD_API_PTR *PFNGLDELETEVERTEXARRAYSPROC)(GLsizei n, const GLuint * arrays); +typedef void (GLAD_API_PTR *PFNGLDEPTHFUNCPROC)(GLenum func); +typedef void (GLAD_API_PTR *PFNGLDEPTHMASKPROC)(GLboolean flag); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEPROC)(GLdouble n, GLdouble f); +typedef void (GLAD_API_PTR *PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader); +typedef void (GLAD_API_PTR *PFNGLDISABLEPROC)(GLenum cap); +typedef void (GLAD_API_PTR *PFNGLDISABLECLIENTSTATEPROC)(GLenum array); +typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index); +typedef void (GLAD_API_PTR *PFNGLDISABLEIPROC)(GLenum target, GLuint index); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERPROC)(GLenum buf); +typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSPROC)(GLsizei n, const GLenum * bufs); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLint basevertex); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex); +typedef void (GLAD_API_PTR *PFNGLDRAWPIXELSPROC)(GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices); +typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices, GLint basevertex); +typedef void (GLAD_API_PTR *PFNGLEDGEFLAGPROC)(GLboolean flag); +typedef void (GLAD_API_PTR *PFNGLEDGEFLAGPOINTERPROC)(GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLEDGEFLAGVPROC)(const GLboolean * flag); +typedef void (GLAD_API_PTR *PFNGLENABLEPROC)(GLenum cap); +typedef void (GLAD_API_PTR *PFNGLENABLECLIENTSTATEPROC)(GLenum array); +typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index); +typedef void (GLAD_API_PTR *PFNGLENABLEIPROC)(GLenum target, GLuint index); +typedef void (GLAD_API_PTR *PFNGLENDPROC)(void); +typedef void (GLAD_API_PTR *PFNGLENDCONDITIONALRENDERPROC)(void); +typedef void (GLAD_API_PTR *PFNGLENDLISTPROC)(void); +typedef void (GLAD_API_PTR *PFNGLENDQUERYPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLENDTRANSFORMFEEDBACKPROC)(void); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD1DPROC)(GLdouble u); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD1DVPROC)(const GLdouble * u); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD1FPROC)(GLfloat u); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD1FVPROC)(const GLfloat * u); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD2DPROC)(GLdouble u, GLdouble v); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD2DVPROC)(const GLdouble * u); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD2FPROC)(GLfloat u, GLfloat v); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD2FVPROC)(const GLfloat * u); +typedef void (GLAD_API_PTR *PFNGLEVALMESH1PROC)(GLenum mode, GLint i1, GLint i2); +typedef void (GLAD_API_PTR *PFNGLEVALMESH2PROC)(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +typedef void (GLAD_API_PTR *PFNGLEVALPOINT1PROC)(GLint i); +typedef void (GLAD_API_PTR *PFNGLEVALPOINT2PROC)(GLint i, GLint j); +typedef void (GLAD_API_PTR *PFNGLFEEDBACKBUFFERPROC)(GLsizei size, GLenum type, GLfloat * buffer); +typedef GLsync (GLAD_API_PTR *PFNGLFENCESYNCPROC)(GLenum condition, GLbitfield flags); +typedef void (GLAD_API_PTR *PFNGLFINISHPROC)(void); +typedef void (GLAD_API_PTR *PFNGLFLUSHPROC)(void); +typedef void (GLAD_API_PTR *PFNGLFLUSHMAPPEDBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length); +typedef void (GLAD_API_PTR *PFNGLFOGCOORDPOINTERPROC)(GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLFOGCOORDDPROC)(GLdouble coord); +typedef void (GLAD_API_PTR *PFNGLFOGCOORDDVPROC)(const GLdouble * coord); +typedef void (GLAD_API_PTR *PFNGLFOGCOORDFPROC)(GLfloat coord); +typedef void (GLAD_API_PTR *PFNGLFOGCOORDFVPROC)(const GLfloat * coord); +typedef void (GLAD_API_PTR *PFNGLFOGFPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLFOGFVPROC)(GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLFOGIPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLFOGIVPROC)(GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTUREPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE1DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE3DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURELAYERPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); +typedef void (GLAD_API_PTR *PFNGLFRONTFACEPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLFRUSTUMPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (GLAD_API_PTR *PFNGLGENBUFFERSPROC)(GLsizei n, GLuint * buffers); +typedef void (GLAD_API_PTR *PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint * framebuffers); +typedef void (GLAD_API_PTR *PFNGLGENFRAMEBUFFERSEXTPROC)(GLsizei n, GLuint * framebuffers); +typedef GLuint (GLAD_API_PTR *PFNGLGENLISTSPROC)(GLsizei range); +typedef void (GLAD_API_PTR *PFNGLGENQUERIESPROC)(GLsizei n, GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLGENRENDERBUFFERSEXTPROC)(GLsizei n, GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLGENSAMPLERSPROC)(GLsizei count, GLuint * samplers); +typedef void (GLAD_API_PTR *PFNGLGENTEXTURESPROC)(GLsizei n, GLuint * textures); +typedef void (GLAD_API_PTR *PFNGLGENVERTEXARRAYSPROC)(GLsizei n, GLuint * arrays); +typedef void (GLAD_API_PTR *PFNGLGENERATEMIPMAPPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLGENERATEMIPMAPEXTPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEATTRIBPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei * length, GLchar * uniformBlockName); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMNAMEPROC)(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei * length, GLchar * uniformName); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint program, GLsizei uniformCount, const GLuint * uniformIndices, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETATTACHEDSHADERSPROC)(GLuint program, GLsizei maxCount, GLsizei * count, GLuint * shaders); +typedef GLint (GLAD_API_PTR *PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETBOOLEANI_VPROC)(GLenum target, GLuint index, GLboolean * data); +typedef void (GLAD_API_PTR *PFNGLGETBOOLEANVPROC)(GLenum pname, GLboolean * data); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum target, GLenum pname, GLint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPOINTERVPROC)(GLenum target, GLenum pname, void ** params); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, void * data); +typedef void (GLAD_API_PTR *PFNGLGETCLIPPLANEPROC)(GLenum plane, GLdouble * equation); +typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint level, void * img); +typedef GLuint (GLAD_API_PTR *PFNGLGETDEBUGMESSAGELOGARBPROC)(GLuint count, GLsizei bufSize, GLenum * sources, GLenum * types, GLuint * ids, GLenum * severities, GLsizei * lengths, GLchar * messageLog); +typedef void (GLAD_API_PTR *PFNGLGETDOUBLEVPROC)(GLenum pname, GLdouble * data); +typedef GLenum (GLAD_API_PTR *PFNGLGETERRORPROC)(void); +typedef void (GLAD_API_PTR *PFNGLGETFLOATVPROC)(GLenum pname, GLfloat * data); +typedef GLint (GLAD_API_PTR *PFNGLGETFRAGDATAINDEXPROC)(GLuint program, const GLchar * name); +typedef GLint (GLAD_API_PTR *PFNGLGETFRAGDATALOCATIONPROC)(GLuint program, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum target, GLenum attachment, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)(GLenum target, GLenum attachment, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETINTEGER64I_VPROC)(GLenum target, GLuint index, GLint64 * data); +typedef void (GLAD_API_PTR *PFNGLGETINTEGER64VPROC)(GLenum pname, GLint64 * data); +typedef void (GLAD_API_PTR *PFNGLGETINTEGERI_VPROC)(GLenum target, GLuint index, GLint * data); +typedef void (GLAD_API_PTR *PFNGLGETINTEGERVPROC)(GLenum pname, GLint * data); +typedef void (GLAD_API_PTR *PFNGLGETLIGHTFVPROC)(GLenum light, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETLIGHTIVPROC)(GLenum light, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETMAPDVPROC)(GLenum target, GLenum query, GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLGETMAPFVPROC)(GLenum target, GLenum query, GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLGETMAPIVPROC)(GLenum target, GLenum query, GLint * v); +typedef void (GLAD_API_PTR *PFNGLGETMATERIALFVPROC)(GLenum face, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETMATERIALIVPROC)(GLenum face, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETMULTISAMPLEFVPROC)(GLenum pname, GLuint index, GLfloat * val); +typedef void (GLAD_API_PTR *PFNGLGETPIXELMAPFVPROC)(GLenum map, GLfloat * values); +typedef void (GLAD_API_PTR *PFNGLGETPIXELMAPUIVPROC)(GLenum map, GLuint * values); +typedef void (GLAD_API_PTR *PFNGLGETPIXELMAPUSVPROC)(GLenum map, GLushort * values); +typedef void (GLAD_API_PTR *PFNGLGETPOINTERVPROC)(GLenum pname, void ** params); +typedef void (GLAD_API_PTR *PFNGLGETPOLYGONSTIPPLEPROC)(GLubyte * mask); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLchar * infoLog); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTI64VPROC)(GLuint id, GLenum pname, GLint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTIVPROC)(GLuint id, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTUI64VPROC)(GLuint id, GLenum pname, GLuint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTUIVPROC)(GLuint id, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * infoLog); +typedef void (GLAD_API_PTR *PFNGLGETSHADERSOURCEPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * source); +typedef void (GLAD_API_PTR *PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint * params); +typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGPROC)(GLenum name); +typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGIPROC)(GLenum name, GLuint index); +typedef void (GLAD_API_PTR *PFNGLGETSYNCIVPROC)(GLsync sync, GLenum pname, GLsizei count, GLsizei * length, GLint * values); +typedef void (GLAD_API_PTR *PFNGLGETTEXENVFVPROC)(GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXENVIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXGENDVPROC)(GLenum coord, GLenum pname, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXGENFVPROC)(GLenum coord, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXGENIVPROC)(GLenum coord, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXIMAGEPROC)(GLenum target, GLint level, GLenum format, GLenum type, void * pixels); +typedef void (GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERFVPROC)(GLenum target, GLint level, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERIVPROC)(GLenum target, GLint level, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name); +typedef GLuint (GLAD_API_PTR *PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint program, const GLchar * uniformBlockName); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMINDICESPROC)(GLuint program, GLsizei uniformCount, const GLchar *const* uniformNames, GLuint * uniformIndices); +typedef GLint (GLAD_API_PTR *PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMFVPROC)(GLuint program, GLint location, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMIVPROC)(GLuint program, GLint location, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMUIVPROC)(GLuint program, GLint location, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIIVPROC)(GLuint index, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint index, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void ** pointer); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBDVPROC)(GLuint index, GLenum pname, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBFVPROC)(GLuint index, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLHINTPROC)(GLenum target, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLINDEXMASKPROC)(GLuint mask); +typedef void (GLAD_API_PTR *PFNGLINDEXPOINTERPROC)(GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLINDEXDPROC)(GLdouble c); +typedef void (GLAD_API_PTR *PFNGLINDEXDVPROC)(const GLdouble * c); +typedef void (GLAD_API_PTR *PFNGLINDEXFPROC)(GLfloat c); +typedef void (GLAD_API_PTR *PFNGLINDEXFVPROC)(const GLfloat * c); +typedef void (GLAD_API_PTR *PFNGLINDEXIPROC)(GLint c); +typedef void (GLAD_API_PTR *PFNGLINDEXIVPROC)(const GLint * c); +typedef void (GLAD_API_PTR *PFNGLINDEXSPROC)(GLshort c); +typedef void (GLAD_API_PTR *PFNGLINDEXSVPROC)(const GLshort * c); +typedef void (GLAD_API_PTR *PFNGLINDEXUBPROC)(GLubyte c); +typedef void (GLAD_API_PTR *PFNGLINDEXUBVPROC)(const GLubyte * c); +typedef void (GLAD_API_PTR *PFNGLINITNAMESPROC)(void); +typedef void (GLAD_API_PTR *PFNGLINTERLEAVEDARRAYSPROC)(GLenum format, GLsizei stride, const void * pointer); +typedef GLboolean (GLAD_API_PTR *PFNGLISBUFFERPROC)(GLuint buffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDPROC)(GLenum cap); +typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDIPROC)(GLenum target, GLuint index); +typedef GLboolean (GLAD_API_PTR *PFNGLISFRAMEBUFFERPROC)(GLuint framebuffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISFRAMEBUFFEREXTPROC)(GLuint framebuffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISLISTPROC)(GLuint list); +typedef GLboolean (GLAD_API_PTR *PFNGLISPROGRAMPROC)(GLuint program); +typedef GLboolean (GLAD_API_PTR *PFNGLISQUERYPROC)(GLuint id); +typedef GLboolean (GLAD_API_PTR *PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISRENDERBUFFEREXTPROC)(GLuint renderbuffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISSAMPLERPROC)(GLuint sampler); +typedef GLboolean (GLAD_API_PTR *PFNGLISSHADERPROC)(GLuint shader); +typedef GLboolean (GLAD_API_PTR *PFNGLISSYNCPROC)(GLsync sync); +typedef GLboolean (GLAD_API_PTR *PFNGLISTEXTUREPROC)(GLuint texture); +typedef GLboolean (GLAD_API_PTR *PFNGLISVERTEXARRAYPROC)(GLuint array); +typedef void (GLAD_API_PTR *PFNGLLIGHTMODELFPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLLIGHTMODELFVPROC)(GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLLIGHTMODELIPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLLIGHTMODELIVPROC)(GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLLIGHTFPROC)(GLenum light, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLLIGHTFVPROC)(GLenum light, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLLIGHTIPROC)(GLenum light, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLLIGHTIVPROC)(GLenum light, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLLINESTIPPLEPROC)(GLint factor, GLushort pattern); +typedef void (GLAD_API_PTR *PFNGLLINEWIDTHPROC)(GLfloat width); +typedef void (GLAD_API_PTR *PFNGLLINKPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLLISTBASEPROC)(GLuint base); +typedef void (GLAD_API_PTR *PFNGLLOADIDENTITYPROC)(void); +typedef void (GLAD_API_PTR *PFNGLLOADMATRIXDPROC)(const GLdouble * m); +typedef void (GLAD_API_PTR *PFNGLLOADMATRIXFPROC)(const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLLOADNAMEPROC)(GLuint name); +typedef void (GLAD_API_PTR *PFNGLLOADTRANSPOSEMATRIXDPROC)(const GLdouble * m); +typedef void (GLAD_API_PTR *PFNGLLOADTRANSPOSEMATRIXFPROC)(const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLLOGICOPPROC)(GLenum opcode); +typedef void (GLAD_API_PTR *PFNGLMAP1DPROC)(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble * points); +typedef void (GLAD_API_PTR *PFNGLMAP1FPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat * points); +typedef void (GLAD_API_PTR *PFNGLMAP2DPROC)(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble * points); +typedef void (GLAD_API_PTR *PFNGLMAP2FPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat * points); +typedef void * (GLAD_API_PTR *PFNGLMAPBUFFERPROC)(GLenum target, GLenum access); +typedef void * (GLAD_API_PTR *PFNGLMAPBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GLAD_API_PTR *PFNGLMAPGRID1DPROC)(GLint un, GLdouble u1, GLdouble u2); +typedef void (GLAD_API_PTR *PFNGLMAPGRID1FPROC)(GLint un, GLfloat u1, GLfloat u2); +typedef void (GLAD_API_PTR *PFNGLMAPGRID2DPROC)(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); +typedef void (GLAD_API_PTR *PFNGLMAPGRID2FPROC)(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +typedef void (GLAD_API_PTR *PFNGLMATERIALFPROC)(GLenum face, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLMATERIALFVPROC)(GLenum face, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLMATERIALIPROC)(GLenum face, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLMATERIALIVPROC)(GLenum face, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLMATRIXMODEPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLMULTMATRIXDPROC)(const GLdouble * m); +typedef void (GLAD_API_PTR *PFNGLMULTMATRIXFPROC)(const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLMULTTRANSPOSEMATRIXDPROC)(const GLdouble * m); +typedef void (GLAD_API_PTR *PFNGLMULTTRANSPOSEMATRIXFPROC)(const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSPROC)(GLenum mode, const GLint * first, const GLsizei * count, GLsizei drawcount); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSPROC)(GLenum mode, const GLsizei * count, GLenum type, const void *const* indices, GLsizei drawcount); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, const GLsizei * count, GLenum type, const void *const* indices, GLsizei drawcount, const GLint * basevertex); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1DPROC)(GLenum target, GLdouble s); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1DVPROC)(GLenum target, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1FPROC)(GLenum target, GLfloat s); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1FVPROC)(GLenum target, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1IPROC)(GLenum target, GLint s); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1IVPROC)(GLenum target, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1SPROC)(GLenum target, GLshort s); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1SVPROC)(GLenum target, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2DPROC)(GLenum target, GLdouble s, GLdouble t); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2DVPROC)(GLenum target, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2FPROC)(GLenum target, GLfloat s, GLfloat t); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2FVPROC)(GLenum target, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2IPROC)(GLenum target, GLint s, GLint t); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2IVPROC)(GLenum target, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2SPROC)(GLenum target, GLshort s, GLshort t); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2SVPROC)(GLenum target, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3DPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3DVPROC)(GLenum target, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3FPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3FVPROC)(GLenum target, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3IPROC)(GLenum target, GLint s, GLint t, GLint r); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3IVPROC)(GLenum target, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3SPROC)(GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3SVPROC)(GLenum target, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4DPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4DVPROC)(GLenum target, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4FPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4FVPROC)(GLenum target, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4IPROC)(GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4IVPROC)(GLenum target, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4SPROC)(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4SVPROC)(GLenum target, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP1UIPROC)(GLenum texture, GLenum type, GLuint coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP1UIVPROC)(GLenum texture, GLenum type, const GLuint * coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP2UIPROC)(GLenum texture, GLenum type, GLuint coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP2UIVPROC)(GLenum texture, GLenum type, const GLuint * coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP3UIPROC)(GLenum texture, GLenum type, GLuint coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP3UIVPROC)(GLenum texture, GLenum type, const GLuint * coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP4UIPROC)(GLenum texture, GLenum type, GLuint coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP4UIVPROC)(GLenum texture, GLenum type, const GLuint * coords); +typedef void (GLAD_API_PTR *PFNGLNEWLISTPROC)(GLuint list, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLNORMAL3BPROC)(GLbyte nx, GLbyte ny, GLbyte nz); +typedef void (GLAD_API_PTR *PFNGLNORMAL3BVPROC)(const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLNORMAL3DPROC)(GLdouble nx, GLdouble ny, GLdouble nz); +typedef void (GLAD_API_PTR *PFNGLNORMAL3DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLNORMAL3FPROC)(GLfloat nx, GLfloat ny, GLfloat nz); +typedef void (GLAD_API_PTR *PFNGLNORMAL3FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLNORMAL3IPROC)(GLint nx, GLint ny, GLint nz); +typedef void (GLAD_API_PTR *PFNGLNORMAL3IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLNORMAL3SPROC)(GLshort nx, GLshort ny, GLshort nz); +typedef void (GLAD_API_PTR *PFNGLNORMAL3SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLNORMALP3UIPROC)(GLenum type, GLuint coords); +typedef void (GLAD_API_PTR *PFNGLNORMALP3UIVPROC)(GLenum type, const GLuint * coords); +typedef void (GLAD_API_PTR *PFNGLNORMALPOINTERPROC)(GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLORTHOPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (GLAD_API_PTR *PFNGLPASSTHROUGHPROC)(GLfloat token); +typedef void (GLAD_API_PTR *PFNGLPIXELMAPFVPROC)(GLenum map, GLsizei mapsize, const GLfloat * values); +typedef void (GLAD_API_PTR *PFNGLPIXELMAPUIVPROC)(GLenum map, GLsizei mapsize, const GLuint * values); +typedef void (GLAD_API_PTR *PFNGLPIXELMAPUSVPROC)(GLenum map, GLsizei mapsize, const GLushort * values); +typedef void (GLAD_API_PTR *PFNGLPIXELSTOREFPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLPIXELSTOREIPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLPIXELTRANSFERFPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLPIXELTRANSFERIPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLPIXELZOOMPROC)(GLfloat xfactor, GLfloat yfactor); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFVPROC)(GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERIPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERIVPROC)(GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLPOINTSIZEPROC)(GLfloat size); +typedef void (GLAD_API_PTR *PFNGLPOLYGONMODEPROC)(GLenum face, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLPOLYGONOFFSETPROC)(GLfloat factor, GLfloat units); +typedef void (GLAD_API_PTR *PFNGLPOLYGONSTIPPLEPROC)(const GLubyte * mask); +typedef void (GLAD_API_PTR *PFNGLPOPATTRIBPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPOPCLIENTATTRIBPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPOPMATRIXPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPOPNAMEPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint index); +typedef void (GLAD_API_PTR *PFNGLPRIORITIZETEXTURESPROC)(GLsizei n, const GLuint * textures, const GLfloat * priorities); +typedef void (GLAD_API_PTR *PFNGLPROVOKINGVERTEXPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLPUSHATTRIBPROC)(GLbitfield mask); +typedef void (GLAD_API_PTR *PFNGLPUSHCLIENTATTRIBPROC)(GLbitfield mask); +typedef void (GLAD_API_PTR *PFNGLPUSHMATRIXPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPUSHNAMEPROC)(GLuint name); +typedef void (GLAD_API_PTR *PFNGLQUERYCOUNTERPROC)(GLuint id, GLenum target); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS2DPROC)(GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS2DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS2FPROC)(GLfloat x, GLfloat y); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS2FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS2IPROC)(GLint x, GLint y); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS2IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS2SPROC)(GLshort x, GLshort y); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS2SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS3DPROC)(GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS3DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS3FPROC)(GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS3FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS3IPROC)(GLint x, GLint y, GLint z); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS3IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS3SPROC)(GLshort x, GLshort y, GLshort z); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS3SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS4DPROC)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS4DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS4FPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS4FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS4IPROC)(GLint x, GLint y, GLint z, GLint w); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS4IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS4SPROC)(GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS4SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLREADBUFFERPROC)(GLenum src); +typedef void (GLAD_API_PTR *PFNGLREADPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * pixels); +typedef void (GLAD_API_PTR *PFNGLRECTDPROC)(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); +typedef void (GLAD_API_PTR *PFNGLRECTDVPROC)(const GLdouble * v1, const GLdouble * v2); +typedef void (GLAD_API_PTR *PFNGLRECTFPROC)(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); +typedef void (GLAD_API_PTR *PFNGLRECTFVPROC)(const GLfloat * v1, const GLfloat * v2); +typedef void (GLAD_API_PTR *PFNGLRECTIPROC)(GLint x1, GLint y1, GLint x2, GLint y2); +typedef void (GLAD_API_PTR *PFNGLRECTIVPROC)(const GLint * v1, const GLint * v2); +typedef void (GLAD_API_PTR *PFNGLRECTSPROC)(GLshort x1, GLshort y1, GLshort x2, GLshort y2); +typedef void (GLAD_API_PTR *PFNGLRECTSVPROC)(const GLshort * v1, const GLshort * v2); +typedef GLint (GLAD_API_PTR *PFNGLRENDERMODEPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEEXTPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLROTATEDPROC)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLROTATEFPROC)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLSAMPLECOVERAGEPROC)(GLfloat value, GLboolean invert); +typedef void (GLAD_API_PTR *PFNGLSAMPLEMASKIPROC)(GLuint maskNumber, GLbitfield mask); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, const GLint * param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, const GLuint * param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERFPROC)(GLuint sampler, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, const GLfloat * param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIPROC)(GLuint sampler, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, const GLint * param); +typedef void (GLAD_API_PTR *PFNGLSCALEDPROC)(GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLSCALEFPROC)(GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLSCISSORPROC)(GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3BPROC)(GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3BVPROC)(const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3DPROC)(GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3FPROC)(GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3IPROC)(GLint red, GLint green, GLint blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3SPROC)(GLshort red, GLshort green, GLshort blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UBPROC)(GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UBVPROC)(const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UIPROC)(GLuint red, GLuint green, GLuint blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UIVPROC)(const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3USPROC)(GLushort red, GLushort green, GLushort blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3USVPROC)(const GLushort * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLORP3UIPROC)(GLenum type, GLuint color); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLORP3UIVPROC)(GLenum type, const GLuint * color); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLORPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLSELECTBUFFERPROC)(GLsizei size, GLuint * buffer); +typedef void (GLAD_API_PTR *PFNGLSHADEMODELPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar *const* string, const GLint * length); +typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCPROC)(GLenum func, GLint ref, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCSEPARATEPROC)(GLenum face, GLenum func, GLint ref, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILMASKPROC)(GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILMASKSEPARATEPROC)(GLenum face, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILOPPROC)(GLenum fail, GLenum zfail, GLenum zpass); +typedef void (GLAD_API_PTR *PFNGLSTENCILOPSEPARATEPROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (GLAD_API_PTR *PFNGLTEXBUFFERPROC)(GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1DPROC)(GLdouble s); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1FPROC)(GLfloat s); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1IPROC)(GLint s); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1SPROC)(GLshort s); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2DPROC)(GLdouble s, GLdouble t); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2FPROC)(GLfloat s, GLfloat t); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2IPROC)(GLint s, GLint t); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2SPROC)(GLshort s, GLshort t); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3DPROC)(GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3FPROC)(GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3IPROC)(GLint s, GLint t, GLint r); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3SPROC)(GLshort s, GLshort t, GLshort r); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4DPROC)(GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4FPROC)(GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4IPROC)(GLint s, GLint t, GLint r, GLint q); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4SPROC)(GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDP1UIPROC)(GLenum type, GLuint coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDP1UIVPROC)(GLenum type, const GLuint * coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDP2UIPROC)(GLenum type, GLuint coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDP2UIVPROC)(GLenum type, const GLuint * coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDP3UIPROC)(GLenum type, GLuint coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDP3UIVPROC)(GLenum type, const GLuint * coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDP4UIPROC)(GLenum type, GLuint coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDP4UIVPROC)(GLenum type, const GLuint * coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLTEXENVFPROC)(GLenum target, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLTEXENVFVPROC)(GLenum target, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLTEXENVIPROC)(GLenum target, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLTEXENVIVPROC)(GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLTEXGENDPROC)(GLenum coord, GLenum pname, GLdouble param); +typedef void (GLAD_API_PTR *PFNGLTEXGENDVPROC)(GLenum coord, GLenum pname, const GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLTEXGENFPROC)(GLenum coord, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLTEXGENFVPROC)(GLenum coord, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLTEXGENIPROC)(GLenum coord, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLTEXGENIVPROC)(GLenum coord, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE1DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE3DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, const GLuint * params); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFPROC)(GLenum target, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKVARYINGSPROC)(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode); +typedef void (GLAD_API_PTR *PFNGLTRANSLATEDPROC)(GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLTRANSLATEFPROC)(GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1IPROC)(GLint location, GLint v0); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1UIPROC)(GLint location, GLuint v0); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1UIVPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2IPROC)(GLint location, GLint v0, GLint v1); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2UIPROC)(GLint location, GLuint v0, GLuint v1); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2UIVPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3IPROC)(GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3UIVPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4IPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4UIVPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef GLboolean (GLAD_API_PTR *PFNGLUNMAPBUFFERPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLVERTEX2DPROC)(GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLVERTEX2DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX2FPROC)(GLfloat x, GLfloat y); +typedef void (GLAD_API_PTR *PFNGLVERTEX2FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX2IPROC)(GLint x, GLint y); +typedef void (GLAD_API_PTR *PFNGLVERTEX2IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX2SPROC)(GLshort x, GLshort y); +typedef void (GLAD_API_PTR *PFNGLVERTEX2SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX3DPROC)(GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLVERTEX3DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX3FPROC)(GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLVERTEX3FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX3IPROC)(GLint x, GLint y, GLint z); +typedef void (GLAD_API_PTR *PFNGLVERTEX3IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX3SPROC)(GLshort x, GLshort y, GLshort z); +typedef void (GLAD_API_PTR *PFNGLVERTEX3SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX4DPROC)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLVERTEX4DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX4FPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLVERTEX4FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX4IPROC)(GLint x, GLint y, GLint z, GLint w); +typedef void (GLAD_API_PTR *PFNGLVERTEX4IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX4SPROC)(GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAD_API_PTR *PFNGLVERTEX4SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1DPROC)(GLuint index, GLdouble x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FPROC)(GLuint index, GLfloat x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1SPROC)(GLuint index, GLshort x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1SVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2DPROC)(GLuint index, GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FPROC)(GLuint index, GLfloat x, GLfloat y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2SPROC)(GLuint index, GLshort x, GLshort y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2SVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3SPROC)(GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3SVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NBVPROC)(GLuint index, const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NIVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NSVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUBPROC)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUBVPROC)(GLuint index, const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUSVPROC)(GLuint index, const GLushort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4BVPROC)(GLuint index, const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4IVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4SPROC)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4SVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4UBVPROC)(GLuint index, const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4UIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4USVPROC)(GLuint index, const GLushort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBDIVISORPROC)(GLuint index, GLuint divisor); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1IPROC)(GLuint index, GLint x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1IVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1UIPROC)(GLuint index, GLuint x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1UIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2IPROC)(GLuint index, GLint x, GLint y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2IVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2UIPROC)(GLuint index, GLuint x, GLuint y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2UIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3IPROC)(GLuint index, GLint x, GLint y, GLint z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3IVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3UIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4BVPROC)(GLuint index, const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IPROC)(GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4SVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UBVPROC)(GLuint index, const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4USVPROC)(GLuint index, const GLushort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBIPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP1UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP1UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP2UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP2UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP3UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP3UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP4UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP4UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXP2UIPROC)(GLenum type, GLuint value); +typedef void (GLAD_API_PTR *PFNGLVERTEXP2UIVPROC)(GLenum type, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLVERTEXP3UIPROC)(GLenum type, GLuint value); +typedef void (GLAD_API_PTR *PFNGLVERTEXP3UIVPROC)(GLenum type, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLVERTEXP4UIPROC)(GLenum type, GLuint value); +typedef void (GLAD_API_PTR *PFNGLVERTEXP4UIVPROC)(GLenum type, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLVERTEXPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2DPROC)(GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2FPROC)(GLfloat x, GLfloat y); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2IPROC)(GLint x, GLint y); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2SPROC)(GLshort x, GLshort y); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3DPROC)(GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3FPROC)(GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3IPROC)(GLint x, GLint y, GLint z); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3SPROC)(GLshort x, GLshort y, GLshort z); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3SVPROC)(const GLshort * v); + +GLAD_API_CALL PFNGLACCUMPROC glad_glAccum; +#define glAccum glad_glAccum +GLAD_API_CALL PFNGLACTIVETEXTUREPROC glad_glActiveTexture; +#define glActiveTexture glad_glActiveTexture +GLAD_API_CALL PFNGLALPHAFUNCPROC glad_glAlphaFunc; +#define glAlphaFunc glad_glAlphaFunc +GLAD_API_CALL PFNGLARETEXTURESRESIDENTPROC glad_glAreTexturesResident; +#define glAreTexturesResident glad_glAreTexturesResident +GLAD_API_CALL PFNGLARRAYELEMENTPROC glad_glArrayElement; +#define glArrayElement glad_glArrayElement +GLAD_API_CALL PFNGLATTACHSHADERPROC glad_glAttachShader; +#define glAttachShader glad_glAttachShader +GLAD_API_CALL PFNGLBEGINPROC glad_glBegin; +#define glBegin glad_glBegin +GLAD_API_CALL PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender; +#define glBeginConditionalRender glad_glBeginConditionalRender +GLAD_API_CALL PFNGLBEGINQUERYPROC glad_glBeginQuery; +#define glBeginQuery glad_glBeginQuery +GLAD_API_CALL PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; +#define glBeginTransformFeedback glad_glBeginTransformFeedback +GLAD_API_CALL PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; +#define glBindAttribLocation glad_glBindAttribLocation +GLAD_API_CALL PFNGLBINDBUFFERPROC glad_glBindBuffer; +#define glBindBuffer glad_glBindBuffer +GLAD_API_CALL PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; +#define glBindBufferBase glad_glBindBufferBase +GLAD_API_CALL PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; +#define glBindBufferRange glad_glBindBufferRange +GLAD_API_CALL PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation; +#define glBindFragDataLocation glad_glBindFragDataLocation +GLAD_API_CALL PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed; +#define glBindFragDataLocationIndexed glad_glBindFragDataLocationIndexed +GLAD_API_CALL PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; +#define glBindFramebuffer glad_glBindFramebuffer +GLAD_API_CALL PFNGLBINDFRAMEBUFFEREXTPROC glad_glBindFramebufferEXT; +#define glBindFramebufferEXT glad_glBindFramebufferEXT +GLAD_API_CALL PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; +#define glBindRenderbuffer glad_glBindRenderbuffer +GLAD_API_CALL PFNGLBINDRENDERBUFFEREXTPROC glad_glBindRenderbufferEXT; +#define glBindRenderbufferEXT glad_glBindRenderbufferEXT +GLAD_API_CALL PFNGLBINDSAMPLERPROC glad_glBindSampler; +#define glBindSampler glad_glBindSampler +GLAD_API_CALL PFNGLBINDTEXTUREPROC glad_glBindTexture; +#define glBindTexture glad_glBindTexture +GLAD_API_CALL PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; +#define glBindVertexArray glad_glBindVertexArray +GLAD_API_CALL PFNGLBITMAPPROC glad_glBitmap; +#define glBitmap glad_glBitmap +GLAD_API_CALL PFNGLBLENDCOLORPROC glad_glBlendColor; +#define glBlendColor glad_glBlendColor +GLAD_API_CALL PFNGLBLENDEQUATIONPROC glad_glBlendEquation; +#define glBlendEquation glad_glBlendEquation +GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; +#define glBlendEquationSeparate glad_glBlendEquationSeparate +GLAD_API_CALL PFNGLBLENDFUNCPROC glad_glBlendFunc; +#define glBlendFunc glad_glBlendFunc +GLAD_API_CALL PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; +#define glBlendFuncSeparate glad_glBlendFuncSeparate +GLAD_API_CALL PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; +#define glBlitFramebuffer glad_glBlitFramebuffer +GLAD_API_CALL PFNGLBLITFRAMEBUFFEREXTPROC glad_glBlitFramebufferEXT; +#define glBlitFramebufferEXT glad_glBlitFramebufferEXT +GLAD_API_CALL PFNGLBUFFERDATAPROC glad_glBufferData; +#define glBufferData glad_glBufferData +GLAD_API_CALL PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; +#define glBufferSubData glad_glBufferSubData +GLAD_API_CALL PFNGLCALLLISTPROC glad_glCallList; +#define glCallList glad_glCallList +GLAD_API_CALL PFNGLCALLLISTSPROC glad_glCallLists; +#define glCallLists glad_glCallLists +GLAD_API_CALL PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; +#define glCheckFramebufferStatus glad_glCheckFramebufferStatus +GLAD_API_CALL PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glad_glCheckFramebufferStatusEXT; +#define glCheckFramebufferStatusEXT glad_glCheckFramebufferStatusEXT +GLAD_API_CALL PFNGLCLAMPCOLORPROC glad_glClampColor; +#define glClampColor glad_glClampColor +GLAD_API_CALL PFNGLCLEARPROC glad_glClear; +#define glClear glad_glClear +GLAD_API_CALL PFNGLCLEARACCUMPROC glad_glClearAccum; +#define glClearAccum glad_glClearAccum +GLAD_API_CALL PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; +#define glClearBufferfi glad_glClearBufferfi +GLAD_API_CALL PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; +#define glClearBufferfv glad_glClearBufferfv +GLAD_API_CALL PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; +#define glClearBufferiv glad_glClearBufferiv +GLAD_API_CALL PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; +#define glClearBufferuiv glad_glClearBufferuiv +GLAD_API_CALL PFNGLCLEARCOLORPROC glad_glClearColor; +#define glClearColor glad_glClearColor +GLAD_API_CALL PFNGLCLEARDEPTHPROC glad_glClearDepth; +#define glClearDepth glad_glClearDepth +GLAD_API_CALL PFNGLCLEARINDEXPROC glad_glClearIndex; +#define glClearIndex glad_glClearIndex +GLAD_API_CALL PFNGLCLEARSTENCILPROC glad_glClearStencil; +#define glClearStencil glad_glClearStencil +GLAD_API_CALL PFNGLCLIENTACTIVETEXTUREPROC glad_glClientActiveTexture; +#define glClientActiveTexture glad_glClientActiveTexture +GLAD_API_CALL PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; +#define glClientWaitSync glad_glClientWaitSync +GLAD_API_CALL PFNGLCLIPPLANEPROC glad_glClipPlane; +#define glClipPlane glad_glClipPlane +GLAD_API_CALL PFNGLCOLOR3BPROC glad_glColor3b; +#define glColor3b glad_glColor3b +GLAD_API_CALL PFNGLCOLOR3BVPROC glad_glColor3bv; +#define glColor3bv glad_glColor3bv +GLAD_API_CALL PFNGLCOLOR3DPROC glad_glColor3d; +#define glColor3d glad_glColor3d +GLAD_API_CALL PFNGLCOLOR3DVPROC glad_glColor3dv; +#define glColor3dv glad_glColor3dv +GLAD_API_CALL PFNGLCOLOR3FPROC glad_glColor3f; +#define glColor3f glad_glColor3f +GLAD_API_CALL PFNGLCOLOR3FVPROC glad_glColor3fv; +#define glColor3fv glad_glColor3fv +GLAD_API_CALL PFNGLCOLOR3IPROC glad_glColor3i; +#define glColor3i glad_glColor3i +GLAD_API_CALL PFNGLCOLOR3IVPROC glad_glColor3iv; +#define glColor3iv glad_glColor3iv +GLAD_API_CALL PFNGLCOLOR3SPROC glad_glColor3s; +#define glColor3s glad_glColor3s +GLAD_API_CALL PFNGLCOLOR3SVPROC glad_glColor3sv; +#define glColor3sv glad_glColor3sv +GLAD_API_CALL PFNGLCOLOR3UBPROC glad_glColor3ub; +#define glColor3ub glad_glColor3ub +GLAD_API_CALL PFNGLCOLOR3UBVPROC glad_glColor3ubv; +#define glColor3ubv glad_glColor3ubv +GLAD_API_CALL PFNGLCOLOR3UIPROC glad_glColor3ui; +#define glColor3ui glad_glColor3ui +GLAD_API_CALL PFNGLCOLOR3UIVPROC glad_glColor3uiv; +#define glColor3uiv glad_glColor3uiv +GLAD_API_CALL PFNGLCOLOR3USPROC glad_glColor3us; +#define glColor3us glad_glColor3us +GLAD_API_CALL PFNGLCOLOR3USVPROC glad_glColor3usv; +#define glColor3usv glad_glColor3usv +GLAD_API_CALL PFNGLCOLOR4BPROC glad_glColor4b; +#define glColor4b glad_glColor4b +GLAD_API_CALL PFNGLCOLOR4BVPROC glad_glColor4bv; +#define glColor4bv glad_glColor4bv +GLAD_API_CALL PFNGLCOLOR4DPROC glad_glColor4d; +#define glColor4d glad_glColor4d +GLAD_API_CALL PFNGLCOLOR4DVPROC glad_glColor4dv; +#define glColor4dv glad_glColor4dv +GLAD_API_CALL PFNGLCOLOR4FPROC glad_glColor4f; +#define glColor4f glad_glColor4f +GLAD_API_CALL PFNGLCOLOR4FVPROC glad_glColor4fv; +#define glColor4fv glad_glColor4fv +GLAD_API_CALL PFNGLCOLOR4IPROC glad_glColor4i; +#define glColor4i glad_glColor4i +GLAD_API_CALL PFNGLCOLOR4IVPROC glad_glColor4iv; +#define glColor4iv glad_glColor4iv +GLAD_API_CALL PFNGLCOLOR4SPROC glad_glColor4s; +#define glColor4s glad_glColor4s +GLAD_API_CALL PFNGLCOLOR4SVPROC glad_glColor4sv; +#define glColor4sv glad_glColor4sv +GLAD_API_CALL PFNGLCOLOR4UBPROC glad_glColor4ub; +#define glColor4ub glad_glColor4ub +GLAD_API_CALL PFNGLCOLOR4UBVPROC glad_glColor4ubv; +#define glColor4ubv glad_glColor4ubv +GLAD_API_CALL PFNGLCOLOR4UIPROC glad_glColor4ui; +#define glColor4ui glad_glColor4ui +GLAD_API_CALL PFNGLCOLOR4UIVPROC glad_glColor4uiv; +#define glColor4uiv glad_glColor4uiv +GLAD_API_CALL PFNGLCOLOR4USPROC glad_glColor4us; +#define glColor4us glad_glColor4us +GLAD_API_CALL PFNGLCOLOR4USVPROC glad_glColor4usv; +#define glColor4usv glad_glColor4usv +GLAD_API_CALL PFNGLCOLORMASKPROC glad_glColorMask; +#define glColorMask glad_glColorMask +GLAD_API_CALL PFNGLCOLORMASKIPROC glad_glColorMaski; +#define glColorMaski glad_glColorMaski +GLAD_API_CALL PFNGLCOLORMATERIALPROC glad_glColorMaterial; +#define glColorMaterial glad_glColorMaterial +GLAD_API_CALL PFNGLCOLORP3UIPROC glad_glColorP3ui; +#define glColorP3ui glad_glColorP3ui +GLAD_API_CALL PFNGLCOLORP3UIVPROC glad_glColorP3uiv; +#define glColorP3uiv glad_glColorP3uiv +GLAD_API_CALL PFNGLCOLORP4UIPROC glad_glColorP4ui; +#define glColorP4ui glad_glColorP4ui +GLAD_API_CALL PFNGLCOLORP4UIVPROC glad_glColorP4uiv; +#define glColorP4uiv glad_glColorP4uiv +GLAD_API_CALL PFNGLCOLORPOINTERPROC glad_glColorPointer; +#define glColorPointer glad_glColorPointer +GLAD_API_CALL PFNGLCOMPILESHADERPROC glad_glCompileShader; +#define glCompileShader glad_glCompileShader +GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; +#define glCompressedTexImage1D glad_glCompressedTexImage1D +GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; +#define glCompressedTexImage2D glad_glCompressedTexImage2D +GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; +#define glCompressedTexImage3D glad_glCompressedTexImage3D +GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; +#define glCompressedTexSubImage1D glad_glCompressedTexSubImage1D +GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; +#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D +GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; +#define glCompressedTexSubImage3D glad_glCompressedTexSubImage3D +GLAD_API_CALL PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; +#define glCopyBufferSubData glad_glCopyBufferSubData +GLAD_API_CALL PFNGLCOPYPIXELSPROC glad_glCopyPixels; +#define glCopyPixels glad_glCopyPixels +GLAD_API_CALL PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; +#define glCopyTexImage1D glad_glCopyTexImage1D +GLAD_API_CALL PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; +#define glCopyTexImage2D glad_glCopyTexImage2D +GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; +#define glCopyTexSubImage1D glad_glCopyTexSubImage1D +GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; +#define glCopyTexSubImage2D glad_glCopyTexSubImage2D +GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; +#define glCopyTexSubImage3D glad_glCopyTexSubImage3D +GLAD_API_CALL PFNGLCREATEPROGRAMPROC glad_glCreateProgram; +#define glCreateProgram glad_glCreateProgram +GLAD_API_CALL PFNGLCREATESHADERPROC glad_glCreateShader; +#define glCreateShader glad_glCreateShader +GLAD_API_CALL PFNGLCULLFACEPROC glad_glCullFace; +#define glCullFace glad_glCullFace +GLAD_API_CALL PFNGLDEBUGMESSAGECALLBACKARBPROC glad_glDebugMessageCallbackARB; +#define glDebugMessageCallbackARB glad_glDebugMessageCallbackARB +GLAD_API_CALL PFNGLDEBUGMESSAGECONTROLARBPROC glad_glDebugMessageControlARB; +#define glDebugMessageControlARB glad_glDebugMessageControlARB +GLAD_API_CALL PFNGLDEBUGMESSAGEINSERTARBPROC glad_glDebugMessageInsertARB; +#define glDebugMessageInsertARB glad_glDebugMessageInsertARB +GLAD_API_CALL PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; +#define glDeleteBuffers glad_glDeleteBuffers +GLAD_API_CALL PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; +#define glDeleteFramebuffers glad_glDeleteFramebuffers +GLAD_API_CALL PFNGLDELETEFRAMEBUFFERSEXTPROC glad_glDeleteFramebuffersEXT; +#define glDeleteFramebuffersEXT glad_glDeleteFramebuffersEXT +GLAD_API_CALL PFNGLDELETELISTSPROC glad_glDeleteLists; +#define glDeleteLists glad_glDeleteLists +GLAD_API_CALL PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; +#define glDeleteProgram glad_glDeleteProgram +GLAD_API_CALL PFNGLDELETEQUERIESPROC glad_glDeleteQueries; +#define glDeleteQueries glad_glDeleteQueries +GLAD_API_CALL PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; +#define glDeleteRenderbuffers glad_glDeleteRenderbuffers +GLAD_API_CALL PFNGLDELETERENDERBUFFERSEXTPROC glad_glDeleteRenderbuffersEXT; +#define glDeleteRenderbuffersEXT glad_glDeleteRenderbuffersEXT +GLAD_API_CALL PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers; +#define glDeleteSamplers glad_glDeleteSamplers +GLAD_API_CALL PFNGLDELETESHADERPROC glad_glDeleteShader; +#define glDeleteShader glad_glDeleteShader +GLAD_API_CALL PFNGLDELETESYNCPROC glad_glDeleteSync; +#define glDeleteSync glad_glDeleteSync +GLAD_API_CALL PFNGLDELETETEXTURESPROC glad_glDeleteTextures; +#define glDeleteTextures glad_glDeleteTextures +GLAD_API_CALL PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; +#define glDeleteVertexArrays glad_glDeleteVertexArrays +GLAD_API_CALL PFNGLDEPTHFUNCPROC glad_glDepthFunc; +#define glDepthFunc glad_glDepthFunc +GLAD_API_CALL PFNGLDEPTHMASKPROC glad_glDepthMask; +#define glDepthMask glad_glDepthMask +GLAD_API_CALL PFNGLDEPTHRANGEPROC glad_glDepthRange; +#define glDepthRange glad_glDepthRange +GLAD_API_CALL PFNGLDETACHSHADERPROC glad_glDetachShader; +#define glDetachShader glad_glDetachShader +GLAD_API_CALL PFNGLDISABLEPROC glad_glDisable; +#define glDisable glad_glDisable +GLAD_API_CALL PFNGLDISABLECLIENTSTATEPROC glad_glDisableClientState; +#define glDisableClientState glad_glDisableClientState +GLAD_API_CALL PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; +#define glDisableVertexAttribArray glad_glDisableVertexAttribArray +GLAD_API_CALL PFNGLDISABLEIPROC glad_glDisablei; +#define glDisablei glad_glDisablei +GLAD_API_CALL PFNGLDRAWARRAYSPROC glad_glDrawArrays; +#define glDrawArrays glad_glDrawArrays +GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; +#define glDrawArraysInstanced glad_glDrawArraysInstanced +GLAD_API_CALL PFNGLDRAWBUFFERPROC glad_glDrawBuffer; +#define glDrawBuffer glad_glDrawBuffer +GLAD_API_CALL PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; +#define glDrawBuffers glad_glDrawBuffers +GLAD_API_CALL PFNGLDRAWELEMENTSPROC glad_glDrawElements; +#define glDrawElements glad_glDrawElements +GLAD_API_CALL PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; +#define glDrawElementsBaseVertex glad_glDrawElementsBaseVertex +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; +#define glDrawElementsInstanced glad_glDrawElementsInstanced +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; +#define glDrawElementsInstancedBaseVertex glad_glDrawElementsInstancedBaseVertex +GLAD_API_CALL PFNGLDRAWPIXELSPROC glad_glDrawPixels; +#define glDrawPixels glad_glDrawPixels +GLAD_API_CALL PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; +#define glDrawRangeElements glad_glDrawRangeElements +GLAD_API_CALL PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; +#define glDrawRangeElementsBaseVertex glad_glDrawRangeElementsBaseVertex +GLAD_API_CALL PFNGLEDGEFLAGPROC glad_glEdgeFlag; +#define glEdgeFlag glad_glEdgeFlag +GLAD_API_CALL PFNGLEDGEFLAGPOINTERPROC glad_glEdgeFlagPointer; +#define glEdgeFlagPointer glad_glEdgeFlagPointer +GLAD_API_CALL PFNGLEDGEFLAGVPROC glad_glEdgeFlagv; +#define glEdgeFlagv glad_glEdgeFlagv +GLAD_API_CALL PFNGLENABLEPROC glad_glEnable; +#define glEnable glad_glEnable +GLAD_API_CALL PFNGLENABLECLIENTSTATEPROC glad_glEnableClientState; +#define glEnableClientState glad_glEnableClientState +GLAD_API_CALL PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; +#define glEnableVertexAttribArray glad_glEnableVertexAttribArray +GLAD_API_CALL PFNGLENABLEIPROC glad_glEnablei; +#define glEnablei glad_glEnablei +GLAD_API_CALL PFNGLENDPROC glad_glEnd; +#define glEnd glad_glEnd +GLAD_API_CALL PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender; +#define glEndConditionalRender glad_glEndConditionalRender +GLAD_API_CALL PFNGLENDLISTPROC glad_glEndList; +#define glEndList glad_glEndList +GLAD_API_CALL PFNGLENDQUERYPROC glad_glEndQuery; +#define glEndQuery glad_glEndQuery +GLAD_API_CALL PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; +#define glEndTransformFeedback glad_glEndTransformFeedback +GLAD_API_CALL PFNGLEVALCOORD1DPROC glad_glEvalCoord1d; +#define glEvalCoord1d glad_glEvalCoord1d +GLAD_API_CALL PFNGLEVALCOORD1DVPROC glad_glEvalCoord1dv; +#define glEvalCoord1dv glad_glEvalCoord1dv +GLAD_API_CALL PFNGLEVALCOORD1FPROC glad_glEvalCoord1f; +#define glEvalCoord1f glad_glEvalCoord1f +GLAD_API_CALL PFNGLEVALCOORD1FVPROC glad_glEvalCoord1fv; +#define glEvalCoord1fv glad_glEvalCoord1fv +GLAD_API_CALL PFNGLEVALCOORD2DPROC glad_glEvalCoord2d; +#define glEvalCoord2d glad_glEvalCoord2d +GLAD_API_CALL PFNGLEVALCOORD2DVPROC glad_glEvalCoord2dv; +#define glEvalCoord2dv glad_glEvalCoord2dv +GLAD_API_CALL PFNGLEVALCOORD2FPROC glad_glEvalCoord2f; +#define glEvalCoord2f glad_glEvalCoord2f +GLAD_API_CALL PFNGLEVALCOORD2FVPROC glad_glEvalCoord2fv; +#define glEvalCoord2fv glad_glEvalCoord2fv +GLAD_API_CALL PFNGLEVALMESH1PROC glad_glEvalMesh1; +#define glEvalMesh1 glad_glEvalMesh1 +GLAD_API_CALL PFNGLEVALMESH2PROC glad_glEvalMesh2; +#define glEvalMesh2 glad_glEvalMesh2 +GLAD_API_CALL PFNGLEVALPOINT1PROC glad_glEvalPoint1; +#define glEvalPoint1 glad_glEvalPoint1 +GLAD_API_CALL PFNGLEVALPOINT2PROC glad_glEvalPoint2; +#define glEvalPoint2 glad_glEvalPoint2 +GLAD_API_CALL PFNGLFEEDBACKBUFFERPROC glad_glFeedbackBuffer; +#define glFeedbackBuffer glad_glFeedbackBuffer +GLAD_API_CALL PFNGLFENCESYNCPROC glad_glFenceSync; +#define glFenceSync glad_glFenceSync +GLAD_API_CALL PFNGLFINISHPROC glad_glFinish; +#define glFinish glad_glFinish +GLAD_API_CALL PFNGLFLUSHPROC glad_glFlush; +#define glFlush glad_glFlush +GLAD_API_CALL PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; +#define glFlushMappedBufferRange glad_glFlushMappedBufferRange +GLAD_API_CALL PFNGLFOGCOORDPOINTERPROC glad_glFogCoordPointer; +#define glFogCoordPointer glad_glFogCoordPointer +GLAD_API_CALL PFNGLFOGCOORDDPROC glad_glFogCoordd; +#define glFogCoordd glad_glFogCoordd +GLAD_API_CALL PFNGLFOGCOORDDVPROC glad_glFogCoorddv; +#define glFogCoorddv glad_glFogCoorddv +GLAD_API_CALL PFNGLFOGCOORDFPROC glad_glFogCoordf; +#define glFogCoordf glad_glFogCoordf +GLAD_API_CALL PFNGLFOGCOORDFVPROC glad_glFogCoordfv; +#define glFogCoordfv glad_glFogCoordfv +GLAD_API_CALL PFNGLFOGFPROC glad_glFogf; +#define glFogf glad_glFogf +GLAD_API_CALL PFNGLFOGFVPROC glad_glFogfv; +#define glFogfv glad_glFogfv +GLAD_API_CALL PFNGLFOGIPROC glad_glFogi; +#define glFogi glad_glFogi +GLAD_API_CALL PFNGLFOGIVPROC glad_glFogiv; +#define glFogiv glad_glFogiv +GLAD_API_CALL PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; +#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer +GLAD_API_CALL PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glad_glFramebufferRenderbufferEXT; +#define glFramebufferRenderbufferEXT glad_glFramebufferRenderbufferEXT +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; +#define glFramebufferTexture glad_glFramebufferTexture +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; +#define glFramebufferTexture1D glad_glFramebufferTexture1D +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glad_glFramebufferTexture1DEXT; +#define glFramebufferTexture1DEXT glad_glFramebufferTexture1DEXT +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; +#define glFramebufferTexture2D glad_glFramebufferTexture2D +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glad_glFramebufferTexture2DEXT; +#define glFramebufferTexture2DEXT glad_glFramebufferTexture2DEXT +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; +#define glFramebufferTexture3D glad_glFramebufferTexture3D +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glad_glFramebufferTexture3DEXT; +#define glFramebufferTexture3DEXT glad_glFramebufferTexture3DEXT +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; +#define glFramebufferTextureLayer glad_glFramebufferTextureLayer +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glad_glFramebufferTextureMultiviewOVR; +#define glFramebufferTextureMultiviewOVR glad_glFramebufferTextureMultiviewOVR +GLAD_API_CALL PFNGLFRONTFACEPROC glad_glFrontFace; +#define glFrontFace glad_glFrontFace +GLAD_API_CALL PFNGLFRUSTUMPROC glad_glFrustum; +#define glFrustum glad_glFrustum +GLAD_API_CALL PFNGLGENBUFFERSPROC glad_glGenBuffers; +#define glGenBuffers glad_glGenBuffers +GLAD_API_CALL PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; +#define glGenFramebuffers glad_glGenFramebuffers +GLAD_API_CALL PFNGLGENFRAMEBUFFERSEXTPROC glad_glGenFramebuffersEXT; +#define glGenFramebuffersEXT glad_glGenFramebuffersEXT +GLAD_API_CALL PFNGLGENLISTSPROC glad_glGenLists; +#define glGenLists glad_glGenLists +GLAD_API_CALL PFNGLGENQUERIESPROC glad_glGenQueries; +#define glGenQueries glad_glGenQueries +GLAD_API_CALL PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; +#define glGenRenderbuffers glad_glGenRenderbuffers +GLAD_API_CALL PFNGLGENRENDERBUFFERSEXTPROC glad_glGenRenderbuffersEXT; +#define glGenRenderbuffersEXT glad_glGenRenderbuffersEXT +GLAD_API_CALL PFNGLGENSAMPLERSPROC glad_glGenSamplers; +#define glGenSamplers glad_glGenSamplers +GLAD_API_CALL PFNGLGENTEXTURESPROC glad_glGenTextures; +#define glGenTextures glad_glGenTextures +GLAD_API_CALL PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; +#define glGenVertexArrays glad_glGenVertexArrays +GLAD_API_CALL PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; +#define glGenerateMipmap glad_glGenerateMipmap +GLAD_API_CALL PFNGLGENERATEMIPMAPEXTPROC glad_glGenerateMipmapEXT; +#define glGenerateMipmapEXT glad_glGenerateMipmapEXT +GLAD_API_CALL PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; +#define glGetActiveAttrib glad_glGetActiveAttrib +GLAD_API_CALL PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; +#define glGetActiveUniform glad_glGetActiveUniform +GLAD_API_CALL PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; +#define glGetActiveUniformBlockName glad_glGetActiveUniformBlockName +GLAD_API_CALL PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; +#define glGetActiveUniformBlockiv glad_glGetActiveUniformBlockiv +GLAD_API_CALL PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; +#define glGetActiveUniformName glad_glGetActiveUniformName +GLAD_API_CALL PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; +#define glGetActiveUniformsiv glad_glGetActiveUniformsiv +GLAD_API_CALL PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; +#define glGetAttachedShaders glad_glGetAttachedShaders +GLAD_API_CALL PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; +#define glGetAttribLocation glad_glGetAttribLocation +GLAD_API_CALL PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; +#define glGetBooleani_v glad_glGetBooleani_v +GLAD_API_CALL PFNGLGETBOOLEANVPROC glad_glGetBooleanv; +#define glGetBooleanv glad_glGetBooleanv +GLAD_API_CALL PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; +#define glGetBufferParameteri64v glad_glGetBufferParameteri64v +GLAD_API_CALL PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; +#define glGetBufferParameteriv glad_glGetBufferParameteriv +GLAD_API_CALL PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; +#define glGetBufferPointerv glad_glGetBufferPointerv +GLAD_API_CALL PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; +#define glGetBufferSubData glad_glGetBufferSubData +GLAD_API_CALL PFNGLGETCLIPPLANEPROC glad_glGetClipPlane; +#define glGetClipPlane glad_glGetClipPlane +GLAD_API_CALL PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; +#define glGetCompressedTexImage glad_glGetCompressedTexImage +GLAD_API_CALL PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB; +#define glGetDebugMessageLogARB glad_glGetDebugMessageLogARB +GLAD_API_CALL PFNGLGETDOUBLEVPROC glad_glGetDoublev; +#define glGetDoublev glad_glGetDoublev +GLAD_API_CALL PFNGLGETERRORPROC glad_glGetError; +#define glGetError glad_glGetError +GLAD_API_CALL PFNGLGETFLOATVPROC glad_glGetFloatv; +#define glGetFloatv glad_glGetFloatv +GLAD_API_CALL PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex; +#define glGetFragDataIndex glad_glGetFragDataIndex +GLAD_API_CALL PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; +#define glGetFragDataLocation glad_glGetFragDataLocation +GLAD_API_CALL PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; +#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv +GLAD_API_CALL PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetFramebufferAttachmentParameterivEXT; +#define glGetFramebufferAttachmentParameterivEXT glad_glGetFramebufferAttachmentParameterivEXT +GLAD_API_CALL PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; +#define glGetInteger64i_v glad_glGetInteger64i_v +GLAD_API_CALL PFNGLGETINTEGER64VPROC glad_glGetInteger64v; +#define glGetInteger64v glad_glGetInteger64v +GLAD_API_CALL PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; +#define glGetIntegeri_v glad_glGetIntegeri_v +GLAD_API_CALL PFNGLGETINTEGERVPROC glad_glGetIntegerv; +#define glGetIntegerv glad_glGetIntegerv +GLAD_API_CALL PFNGLGETLIGHTFVPROC glad_glGetLightfv; +#define glGetLightfv glad_glGetLightfv +GLAD_API_CALL PFNGLGETLIGHTIVPROC glad_glGetLightiv; +#define glGetLightiv glad_glGetLightiv +GLAD_API_CALL PFNGLGETMAPDVPROC glad_glGetMapdv; +#define glGetMapdv glad_glGetMapdv +GLAD_API_CALL PFNGLGETMAPFVPROC glad_glGetMapfv; +#define glGetMapfv glad_glGetMapfv +GLAD_API_CALL PFNGLGETMAPIVPROC glad_glGetMapiv; +#define glGetMapiv glad_glGetMapiv +GLAD_API_CALL PFNGLGETMATERIALFVPROC glad_glGetMaterialfv; +#define glGetMaterialfv glad_glGetMaterialfv +GLAD_API_CALL PFNGLGETMATERIALIVPROC glad_glGetMaterialiv; +#define glGetMaterialiv glad_glGetMaterialiv +GLAD_API_CALL PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; +#define glGetMultisamplefv glad_glGetMultisamplefv +GLAD_API_CALL PFNGLGETPIXELMAPFVPROC glad_glGetPixelMapfv; +#define glGetPixelMapfv glad_glGetPixelMapfv +GLAD_API_CALL PFNGLGETPIXELMAPUIVPROC glad_glGetPixelMapuiv; +#define glGetPixelMapuiv glad_glGetPixelMapuiv +GLAD_API_CALL PFNGLGETPIXELMAPUSVPROC glad_glGetPixelMapusv; +#define glGetPixelMapusv glad_glGetPixelMapusv +GLAD_API_CALL PFNGLGETPOINTERVPROC glad_glGetPointerv; +#define glGetPointerv glad_glGetPointerv +GLAD_API_CALL PFNGLGETPOLYGONSTIPPLEPROC glad_glGetPolygonStipple; +#define glGetPolygonStipple glad_glGetPolygonStipple +GLAD_API_CALL PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; +#define glGetProgramInfoLog glad_glGetProgramInfoLog +GLAD_API_CALL PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; +#define glGetProgramiv glad_glGetProgramiv +GLAD_API_CALL PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v; +#define glGetQueryObjecti64v glad_glGetQueryObjecti64v +GLAD_API_CALL PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; +#define glGetQueryObjectiv glad_glGetQueryObjectiv +GLAD_API_CALL PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v; +#define glGetQueryObjectui64v glad_glGetQueryObjectui64v +GLAD_API_CALL PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; +#define glGetQueryObjectuiv glad_glGetQueryObjectuiv +GLAD_API_CALL PFNGLGETQUERYIVPROC glad_glGetQueryiv; +#define glGetQueryiv glad_glGetQueryiv +GLAD_API_CALL PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; +#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv +GLAD_API_CALL PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glad_glGetRenderbufferParameterivEXT; +#define glGetRenderbufferParameterivEXT glad_glGetRenderbufferParameterivEXT +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv; +#define glGetSamplerParameterIiv glad_glGetSamplerParameterIiv +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv; +#define glGetSamplerParameterIuiv glad_glGetSamplerParameterIuiv +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv; +#define glGetSamplerParameterfv glad_glGetSamplerParameterfv +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv; +#define glGetSamplerParameteriv glad_glGetSamplerParameteriv +GLAD_API_CALL PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; +#define glGetShaderInfoLog glad_glGetShaderInfoLog +GLAD_API_CALL PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; +#define glGetShaderSource glad_glGetShaderSource +GLAD_API_CALL PFNGLGETSHADERIVPROC glad_glGetShaderiv; +#define glGetShaderiv glad_glGetShaderiv +GLAD_API_CALL PFNGLGETSTRINGPROC glad_glGetString; +#define glGetString glad_glGetString +GLAD_API_CALL PFNGLGETSTRINGIPROC glad_glGetStringi; +#define glGetStringi glad_glGetStringi +GLAD_API_CALL PFNGLGETSYNCIVPROC glad_glGetSynciv; +#define glGetSynciv glad_glGetSynciv +GLAD_API_CALL PFNGLGETTEXENVFVPROC glad_glGetTexEnvfv; +#define glGetTexEnvfv glad_glGetTexEnvfv +GLAD_API_CALL PFNGLGETTEXENVIVPROC glad_glGetTexEnviv; +#define glGetTexEnviv glad_glGetTexEnviv +GLAD_API_CALL PFNGLGETTEXGENDVPROC glad_glGetTexGendv; +#define glGetTexGendv glad_glGetTexGendv +GLAD_API_CALL PFNGLGETTEXGENFVPROC glad_glGetTexGenfv; +#define glGetTexGenfv glad_glGetTexGenfv +GLAD_API_CALL PFNGLGETTEXGENIVPROC glad_glGetTexGeniv; +#define glGetTexGeniv glad_glGetTexGeniv +GLAD_API_CALL PFNGLGETTEXIMAGEPROC glad_glGetTexImage; +#define glGetTexImage glad_glGetTexImage +GLAD_API_CALL PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; +#define glGetTexLevelParameterfv glad_glGetTexLevelParameterfv +GLAD_API_CALL PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; +#define glGetTexLevelParameteriv glad_glGetTexLevelParameteriv +GLAD_API_CALL PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; +#define glGetTexParameterIiv glad_glGetTexParameterIiv +GLAD_API_CALL PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; +#define glGetTexParameterIuiv glad_glGetTexParameterIuiv +GLAD_API_CALL PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; +#define glGetTexParameterfv glad_glGetTexParameterfv +GLAD_API_CALL PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; +#define glGetTexParameteriv glad_glGetTexParameteriv +GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; +#define glGetTransformFeedbackVarying glad_glGetTransformFeedbackVarying +GLAD_API_CALL PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; +#define glGetUniformBlockIndex glad_glGetUniformBlockIndex +GLAD_API_CALL PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; +#define glGetUniformIndices glad_glGetUniformIndices +GLAD_API_CALL PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; +#define glGetUniformLocation glad_glGetUniformLocation +GLAD_API_CALL PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; +#define glGetUniformfv glad_glGetUniformfv +GLAD_API_CALL PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; +#define glGetUniformiv glad_glGetUniformiv +GLAD_API_CALL PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; +#define glGetUniformuiv glad_glGetUniformuiv +GLAD_API_CALL PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; +#define glGetVertexAttribIiv glad_glGetVertexAttribIiv +GLAD_API_CALL PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; +#define glGetVertexAttribIuiv glad_glGetVertexAttribIuiv +GLAD_API_CALL PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; +#define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv +GLAD_API_CALL PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; +#define glGetVertexAttribdv glad_glGetVertexAttribdv +GLAD_API_CALL PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; +#define glGetVertexAttribfv glad_glGetVertexAttribfv +GLAD_API_CALL PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; +#define glGetVertexAttribiv glad_glGetVertexAttribiv +GLAD_API_CALL PFNGLHINTPROC glad_glHint; +#define glHint glad_glHint +GLAD_API_CALL PFNGLINDEXMASKPROC glad_glIndexMask; +#define glIndexMask glad_glIndexMask +GLAD_API_CALL PFNGLINDEXPOINTERPROC glad_glIndexPointer; +#define glIndexPointer glad_glIndexPointer +GLAD_API_CALL PFNGLINDEXDPROC glad_glIndexd; +#define glIndexd glad_glIndexd +GLAD_API_CALL PFNGLINDEXDVPROC glad_glIndexdv; +#define glIndexdv glad_glIndexdv +GLAD_API_CALL PFNGLINDEXFPROC glad_glIndexf; +#define glIndexf glad_glIndexf +GLAD_API_CALL PFNGLINDEXFVPROC glad_glIndexfv; +#define glIndexfv glad_glIndexfv +GLAD_API_CALL PFNGLINDEXIPROC glad_glIndexi; +#define glIndexi glad_glIndexi +GLAD_API_CALL PFNGLINDEXIVPROC glad_glIndexiv; +#define glIndexiv glad_glIndexiv +GLAD_API_CALL PFNGLINDEXSPROC glad_glIndexs; +#define glIndexs glad_glIndexs +GLAD_API_CALL PFNGLINDEXSVPROC glad_glIndexsv; +#define glIndexsv glad_glIndexsv +GLAD_API_CALL PFNGLINDEXUBPROC glad_glIndexub; +#define glIndexub glad_glIndexub +GLAD_API_CALL PFNGLINDEXUBVPROC glad_glIndexubv; +#define glIndexubv glad_glIndexubv +GLAD_API_CALL PFNGLINITNAMESPROC glad_glInitNames; +#define glInitNames glad_glInitNames +GLAD_API_CALL PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays; +#define glInterleavedArrays glad_glInterleavedArrays +GLAD_API_CALL PFNGLISBUFFERPROC glad_glIsBuffer; +#define glIsBuffer glad_glIsBuffer +GLAD_API_CALL PFNGLISENABLEDPROC glad_glIsEnabled; +#define glIsEnabled glad_glIsEnabled +GLAD_API_CALL PFNGLISENABLEDIPROC glad_glIsEnabledi; +#define glIsEnabledi glad_glIsEnabledi +GLAD_API_CALL PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; +#define glIsFramebuffer glad_glIsFramebuffer +GLAD_API_CALL PFNGLISFRAMEBUFFEREXTPROC glad_glIsFramebufferEXT; +#define glIsFramebufferEXT glad_glIsFramebufferEXT +GLAD_API_CALL PFNGLISLISTPROC glad_glIsList; +#define glIsList glad_glIsList +GLAD_API_CALL PFNGLISPROGRAMPROC glad_glIsProgram; +#define glIsProgram glad_glIsProgram +GLAD_API_CALL PFNGLISQUERYPROC glad_glIsQuery; +#define glIsQuery glad_glIsQuery +GLAD_API_CALL PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; +#define glIsRenderbuffer glad_glIsRenderbuffer +GLAD_API_CALL PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbufferEXT; +#define glIsRenderbufferEXT glad_glIsRenderbufferEXT +GLAD_API_CALL PFNGLISSAMPLERPROC glad_glIsSampler; +#define glIsSampler glad_glIsSampler +GLAD_API_CALL PFNGLISSHADERPROC glad_glIsShader; +#define glIsShader glad_glIsShader +GLAD_API_CALL PFNGLISSYNCPROC glad_glIsSync; +#define glIsSync glad_glIsSync +GLAD_API_CALL PFNGLISTEXTUREPROC glad_glIsTexture; +#define glIsTexture glad_glIsTexture +GLAD_API_CALL PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; +#define glIsVertexArray glad_glIsVertexArray +GLAD_API_CALL PFNGLLIGHTMODELFPROC glad_glLightModelf; +#define glLightModelf glad_glLightModelf +GLAD_API_CALL PFNGLLIGHTMODELFVPROC glad_glLightModelfv; +#define glLightModelfv glad_glLightModelfv +GLAD_API_CALL PFNGLLIGHTMODELIPROC glad_glLightModeli; +#define glLightModeli glad_glLightModeli +GLAD_API_CALL PFNGLLIGHTMODELIVPROC glad_glLightModeliv; +#define glLightModeliv glad_glLightModeliv +GLAD_API_CALL PFNGLLIGHTFPROC glad_glLightf; +#define glLightf glad_glLightf +GLAD_API_CALL PFNGLLIGHTFVPROC glad_glLightfv; +#define glLightfv glad_glLightfv +GLAD_API_CALL PFNGLLIGHTIPROC glad_glLighti; +#define glLighti glad_glLighti +GLAD_API_CALL PFNGLLIGHTIVPROC glad_glLightiv; +#define glLightiv glad_glLightiv +GLAD_API_CALL PFNGLLINESTIPPLEPROC glad_glLineStipple; +#define glLineStipple glad_glLineStipple +GLAD_API_CALL PFNGLLINEWIDTHPROC glad_glLineWidth; +#define glLineWidth glad_glLineWidth +GLAD_API_CALL PFNGLLINKPROGRAMPROC glad_glLinkProgram; +#define glLinkProgram glad_glLinkProgram +GLAD_API_CALL PFNGLLISTBASEPROC glad_glListBase; +#define glListBase glad_glListBase +GLAD_API_CALL PFNGLLOADIDENTITYPROC glad_glLoadIdentity; +#define glLoadIdentity glad_glLoadIdentity +GLAD_API_CALL PFNGLLOADMATRIXDPROC glad_glLoadMatrixd; +#define glLoadMatrixd glad_glLoadMatrixd +GLAD_API_CALL PFNGLLOADMATRIXFPROC glad_glLoadMatrixf; +#define glLoadMatrixf glad_glLoadMatrixf +GLAD_API_CALL PFNGLLOADNAMEPROC glad_glLoadName; +#define glLoadName glad_glLoadName +GLAD_API_CALL PFNGLLOADTRANSPOSEMATRIXDPROC glad_glLoadTransposeMatrixd; +#define glLoadTransposeMatrixd glad_glLoadTransposeMatrixd +GLAD_API_CALL PFNGLLOADTRANSPOSEMATRIXFPROC glad_glLoadTransposeMatrixf; +#define glLoadTransposeMatrixf glad_glLoadTransposeMatrixf +GLAD_API_CALL PFNGLLOGICOPPROC glad_glLogicOp; +#define glLogicOp glad_glLogicOp +GLAD_API_CALL PFNGLMAP1DPROC glad_glMap1d; +#define glMap1d glad_glMap1d +GLAD_API_CALL PFNGLMAP1FPROC glad_glMap1f; +#define glMap1f glad_glMap1f +GLAD_API_CALL PFNGLMAP2DPROC glad_glMap2d; +#define glMap2d glad_glMap2d +GLAD_API_CALL PFNGLMAP2FPROC glad_glMap2f; +#define glMap2f glad_glMap2f +GLAD_API_CALL PFNGLMAPBUFFERPROC glad_glMapBuffer; +#define glMapBuffer glad_glMapBuffer +GLAD_API_CALL PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; +#define glMapBufferRange glad_glMapBufferRange +GLAD_API_CALL PFNGLMAPGRID1DPROC glad_glMapGrid1d; +#define glMapGrid1d glad_glMapGrid1d +GLAD_API_CALL PFNGLMAPGRID1FPROC glad_glMapGrid1f; +#define glMapGrid1f glad_glMapGrid1f +GLAD_API_CALL PFNGLMAPGRID2DPROC glad_glMapGrid2d; +#define glMapGrid2d glad_glMapGrid2d +GLAD_API_CALL PFNGLMAPGRID2FPROC glad_glMapGrid2f; +#define glMapGrid2f glad_glMapGrid2f +GLAD_API_CALL PFNGLMATERIALFPROC glad_glMaterialf; +#define glMaterialf glad_glMaterialf +GLAD_API_CALL PFNGLMATERIALFVPROC glad_glMaterialfv; +#define glMaterialfv glad_glMaterialfv +GLAD_API_CALL PFNGLMATERIALIPROC glad_glMateriali; +#define glMateriali glad_glMateriali +GLAD_API_CALL PFNGLMATERIALIVPROC glad_glMaterialiv; +#define glMaterialiv glad_glMaterialiv +GLAD_API_CALL PFNGLMATRIXMODEPROC glad_glMatrixMode; +#define glMatrixMode glad_glMatrixMode +GLAD_API_CALL PFNGLMULTMATRIXDPROC glad_glMultMatrixd; +#define glMultMatrixd glad_glMultMatrixd +GLAD_API_CALL PFNGLMULTMATRIXFPROC glad_glMultMatrixf; +#define glMultMatrixf glad_glMultMatrixf +GLAD_API_CALL PFNGLMULTTRANSPOSEMATRIXDPROC glad_glMultTransposeMatrixd; +#define glMultTransposeMatrixd glad_glMultTransposeMatrixd +GLAD_API_CALL PFNGLMULTTRANSPOSEMATRIXFPROC glad_glMultTransposeMatrixf; +#define glMultTransposeMatrixf glad_glMultTransposeMatrixf +GLAD_API_CALL PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; +#define glMultiDrawArrays glad_glMultiDrawArrays +GLAD_API_CALL PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; +#define glMultiDrawElements glad_glMultiDrawElements +GLAD_API_CALL PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; +#define glMultiDrawElementsBaseVertex glad_glMultiDrawElementsBaseVertex +GLAD_API_CALL PFNGLMULTITEXCOORD1DPROC glad_glMultiTexCoord1d; +#define glMultiTexCoord1d glad_glMultiTexCoord1d +GLAD_API_CALL PFNGLMULTITEXCOORD1DVPROC glad_glMultiTexCoord1dv; +#define glMultiTexCoord1dv glad_glMultiTexCoord1dv +GLAD_API_CALL PFNGLMULTITEXCOORD1FPROC glad_glMultiTexCoord1f; +#define glMultiTexCoord1f glad_glMultiTexCoord1f +GLAD_API_CALL PFNGLMULTITEXCOORD1FVPROC glad_glMultiTexCoord1fv; +#define glMultiTexCoord1fv glad_glMultiTexCoord1fv +GLAD_API_CALL PFNGLMULTITEXCOORD1IPROC glad_glMultiTexCoord1i; +#define glMultiTexCoord1i glad_glMultiTexCoord1i +GLAD_API_CALL PFNGLMULTITEXCOORD1IVPROC glad_glMultiTexCoord1iv; +#define glMultiTexCoord1iv glad_glMultiTexCoord1iv +GLAD_API_CALL PFNGLMULTITEXCOORD1SPROC glad_glMultiTexCoord1s; +#define glMultiTexCoord1s glad_glMultiTexCoord1s +GLAD_API_CALL PFNGLMULTITEXCOORD1SVPROC glad_glMultiTexCoord1sv; +#define glMultiTexCoord1sv glad_glMultiTexCoord1sv +GLAD_API_CALL PFNGLMULTITEXCOORD2DPROC glad_glMultiTexCoord2d; +#define glMultiTexCoord2d glad_glMultiTexCoord2d +GLAD_API_CALL PFNGLMULTITEXCOORD2DVPROC glad_glMultiTexCoord2dv; +#define glMultiTexCoord2dv glad_glMultiTexCoord2dv +GLAD_API_CALL PFNGLMULTITEXCOORD2FPROC glad_glMultiTexCoord2f; +#define glMultiTexCoord2f glad_glMultiTexCoord2f +GLAD_API_CALL PFNGLMULTITEXCOORD2FVPROC glad_glMultiTexCoord2fv; +#define glMultiTexCoord2fv glad_glMultiTexCoord2fv +GLAD_API_CALL PFNGLMULTITEXCOORD2IPROC glad_glMultiTexCoord2i; +#define glMultiTexCoord2i glad_glMultiTexCoord2i +GLAD_API_CALL PFNGLMULTITEXCOORD2IVPROC glad_glMultiTexCoord2iv; +#define glMultiTexCoord2iv glad_glMultiTexCoord2iv +GLAD_API_CALL PFNGLMULTITEXCOORD2SPROC glad_glMultiTexCoord2s; +#define glMultiTexCoord2s glad_glMultiTexCoord2s +GLAD_API_CALL PFNGLMULTITEXCOORD2SVPROC glad_glMultiTexCoord2sv; +#define glMultiTexCoord2sv glad_glMultiTexCoord2sv +GLAD_API_CALL PFNGLMULTITEXCOORD3DPROC glad_glMultiTexCoord3d; +#define glMultiTexCoord3d glad_glMultiTexCoord3d +GLAD_API_CALL PFNGLMULTITEXCOORD3DVPROC glad_glMultiTexCoord3dv; +#define glMultiTexCoord3dv glad_glMultiTexCoord3dv +GLAD_API_CALL PFNGLMULTITEXCOORD3FPROC glad_glMultiTexCoord3f; +#define glMultiTexCoord3f glad_glMultiTexCoord3f +GLAD_API_CALL PFNGLMULTITEXCOORD3FVPROC glad_glMultiTexCoord3fv; +#define glMultiTexCoord3fv glad_glMultiTexCoord3fv +GLAD_API_CALL PFNGLMULTITEXCOORD3IPROC glad_glMultiTexCoord3i; +#define glMultiTexCoord3i glad_glMultiTexCoord3i +GLAD_API_CALL PFNGLMULTITEXCOORD3IVPROC glad_glMultiTexCoord3iv; +#define glMultiTexCoord3iv glad_glMultiTexCoord3iv +GLAD_API_CALL PFNGLMULTITEXCOORD3SPROC glad_glMultiTexCoord3s; +#define glMultiTexCoord3s glad_glMultiTexCoord3s +GLAD_API_CALL PFNGLMULTITEXCOORD3SVPROC glad_glMultiTexCoord3sv; +#define glMultiTexCoord3sv glad_glMultiTexCoord3sv +GLAD_API_CALL PFNGLMULTITEXCOORD4DPROC glad_glMultiTexCoord4d; +#define glMultiTexCoord4d glad_glMultiTexCoord4d +GLAD_API_CALL PFNGLMULTITEXCOORD4DVPROC glad_glMultiTexCoord4dv; +#define glMultiTexCoord4dv glad_glMultiTexCoord4dv +GLAD_API_CALL PFNGLMULTITEXCOORD4FPROC glad_glMultiTexCoord4f; +#define glMultiTexCoord4f glad_glMultiTexCoord4f +GLAD_API_CALL PFNGLMULTITEXCOORD4FVPROC glad_glMultiTexCoord4fv; +#define glMultiTexCoord4fv glad_glMultiTexCoord4fv +GLAD_API_CALL PFNGLMULTITEXCOORD4IPROC glad_glMultiTexCoord4i; +#define glMultiTexCoord4i glad_glMultiTexCoord4i +GLAD_API_CALL PFNGLMULTITEXCOORD4IVPROC glad_glMultiTexCoord4iv; +#define glMultiTexCoord4iv glad_glMultiTexCoord4iv +GLAD_API_CALL PFNGLMULTITEXCOORD4SPROC glad_glMultiTexCoord4s; +#define glMultiTexCoord4s glad_glMultiTexCoord4s +GLAD_API_CALL PFNGLMULTITEXCOORD4SVPROC glad_glMultiTexCoord4sv; +#define glMultiTexCoord4sv glad_glMultiTexCoord4sv +GLAD_API_CALL PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui; +#define glMultiTexCoordP1ui glad_glMultiTexCoordP1ui +GLAD_API_CALL PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv; +#define glMultiTexCoordP1uiv glad_glMultiTexCoordP1uiv +GLAD_API_CALL PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui; +#define glMultiTexCoordP2ui glad_glMultiTexCoordP2ui +GLAD_API_CALL PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv; +#define glMultiTexCoordP2uiv glad_glMultiTexCoordP2uiv +GLAD_API_CALL PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui; +#define glMultiTexCoordP3ui glad_glMultiTexCoordP3ui +GLAD_API_CALL PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv; +#define glMultiTexCoordP3uiv glad_glMultiTexCoordP3uiv +GLAD_API_CALL PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui; +#define glMultiTexCoordP4ui glad_glMultiTexCoordP4ui +GLAD_API_CALL PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv; +#define glMultiTexCoordP4uiv glad_glMultiTexCoordP4uiv +GLAD_API_CALL PFNGLNEWLISTPROC glad_glNewList; +#define glNewList glad_glNewList +GLAD_API_CALL PFNGLNORMAL3BPROC glad_glNormal3b; +#define glNormal3b glad_glNormal3b +GLAD_API_CALL PFNGLNORMAL3BVPROC glad_glNormal3bv; +#define glNormal3bv glad_glNormal3bv +GLAD_API_CALL PFNGLNORMAL3DPROC glad_glNormal3d; +#define glNormal3d glad_glNormal3d +GLAD_API_CALL PFNGLNORMAL3DVPROC glad_glNormal3dv; +#define glNormal3dv glad_glNormal3dv +GLAD_API_CALL PFNGLNORMAL3FPROC glad_glNormal3f; +#define glNormal3f glad_glNormal3f +GLAD_API_CALL PFNGLNORMAL3FVPROC glad_glNormal3fv; +#define glNormal3fv glad_glNormal3fv +GLAD_API_CALL PFNGLNORMAL3IPROC glad_glNormal3i; +#define glNormal3i glad_glNormal3i +GLAD_API_CALL PFNGLNORMAL3IVPROC glad_glNormal3iv; +#define glNormal3iv glad_glNormal3iv +GLAD_API_CALL PFNGLNORMAL3SPROC glad_glNormal3s; +#define glNormal3s glad_glNormal3s +GLAD_API_CALL PFNGLNORMAL3SVPROC glad_glNormal3sv; +#define glNormal3sv glad_glNormal3sv +GLAD_API_CALL PFNGLNORMALP3UIPROC glad_glNormalP3ui; +#define glNormalP3ui glad_glNormalP3ui +GLAD_API_CALL PFNGLNORMALP3UIVPROC glad_glNormalP3uiv; +#define glNormalP3uiv glad_glNormalP3uiv +GLAD_API_CALL PFNGLNORMALPOINTERPROC glad_glNormalPointer; +#define glNormalPointer glad_glNormalPointer +GLAD_API_CALL PFNGLORTHOPROC glad_glOrtho; +#define glOrtho glad_glOrtho +GLAD_API_CALL PFNGLPASSTHROUGHPROC glad_glPassThrough; +#define glPassThrough glad_glPassThrough +GLAD_API_CALL PFNGLPIXELMAPFVPROC glad_glPixelMapfv; +#define glPixelMapfv glad_glPixelMapfv +GLAD_API_CALL PFNGLPIXELMAPUIVPROC glad_glPixelMapuiv; +#define glPixelMapuiv glad_glPixelMapuiv +GLAD_API_CALL PFNGLPIXELMAPUSVPROC glad_glPixelMapusv; +#define glPixelMapusv glad_glPixelMapusv +GLAD_API_CALL PFNGLPIXELSTOREFPROC glad_glPixelStoref; +#define glPixelStoref glad_glPixelStoref +GLAD_API_CALL PFNGLPIXELSTOREIPROC glad_glPixelStorei; +#define glPixelStorei glad_glPixelStorei +GLAD_API_CALL PFNGLPIXELTRANSFERFPROC glad_glPixelTransferf; +#define glPixelTransferf glad_glPixelTransferf +GLAD_API_CALL PFNGLPIXELTRANSFERIPROC glad_glPixelTransferi; +#define glPixelTransferi glad_glPixelTransferi +GLAD_API_CALL PFNGLPIXELZOOMPROC glad_glPixelZoom; +#define glPixelZoom glad_glPixelZoom +GLAD_API_CALL PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; +#define glPointParameterf glad_glPointParameterf +GLAD_API_CALL PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; +#define glPointParameterfv glad_glPointParameterfv +GLAD_API_CALL PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; +#define glPointParameteri glad_glPointParameteri +GLAD_API_CALL PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; +#define glPointParameteriv glad_glPointParameteriv +GLAD_API_CALL PFNGLPOINTSIZEPROC glad_glPointSize; +#define glPointSize glad_glPointSize +GLAD_API_CALL PFNGLPOLYGONMODEPROC glad_glPolygonMode; +#define glPolygonMode glad_glPolygonMode +GLAD_API_CALL PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; +#define glPolygonOffset glad_glPolygonOffset +GLAD_API_CALL PFNGLPOLYGONSTIPPLEPROC glad_glPolygonStipple; +#define glPolygonStipple glad_glPolygonStipple +GLAD_API_CALL PFNGLPOPATTRIBPROC glad_glPopAttrib; +#define glPopAttrib glad_glPopAttrib +GLAD_API_CALL PFNGLPOPCLIENTATTRIBPROC glad_glPopClientAttrib; +#define glPopClientAttrib glad_glPopClientAttrib +GLAD_API_CALL PFNGLPOPMATRIXPROC glad_glPopMatrix; +#define glPopMatrix glad_glPopMatrix +GLAD_API_CALL PFNGLPOPNAMEPROC glad_glPopName; +#define glPopName glad_glPopName +GLAD_API_CALL PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; +#define glPrimitiveRestartIndex glad_glPrimitiveRestartIndex +GLAD_API_CALL PFNGLPRIORITIZETEXTURESPROC glad_glPrioritizeTextures; +#define glPrioritizeTextures glad_glPrioritizeTextures +GLAD_API_CALL PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; +#define glProvokingVertex glad_glProvokingVertex +GLAD_API_CALL PFNGLPUSHATTRIBPROC glad_glPushAttrib; +#define glPushAttrib glad_glPushAttrib +GLAD_API_CALL PFNGLPUSHCLIENTATTRIBPROC glad_glPushClientAttrib; +#define glPushClientAttrib glad_glPushClientAttrib +GLAD_API_CALL PFNGLPUSHMATRIXPROC glad_glPushMatrix; +#define glPushMatrix glad_glPushMatrix +GLAD_API_CALL PFNGLPUSHNAMEPROC glad_glPushName; +#define glPushName glad_glPushName +GLAD_API_CALL PFNGLQUERYCOUNTERPROC glad_glQueryCounter; +#define glQueryCounter glad_glQueryCounter +GLAD_API_CALL PFNGLRASTERPOS2DPROC glad_glRasterPos2d; +#define glRasterPos2d glad_glRasterPos2d +GLAD_API_CALL PFNGLRASTERPOS2DVPROC glad_glRasterPos2dv; +#define glRasterPos2dv glad_glRasterPos2dv +GLAD_API_CALL PFNGLRASTERPOS2FPROC glad_glRasterPos2f; +#define glRasterPos2f glad_glRasterPos2f +GLAD_API_CALL PFNGLRASTERPOS2FVPROC glad_glRasterPos2fv; +#define glRasterPos2fv glad_glRasterPos2fv +GLAD_API_CALL PFNGLRASTERPOS2IPROC glad_glRasterPos2i; +#define glRasterPos2i glad_glRasterPos2i +GLAD_API_CALL PFNGLRASTERPOS2IVPROC glad_glRasterPos2iv; +#define glRasterPos2iv glad_glRasterPos2iv +GLAD_API_CALL PFNGLRASTERPOS2SPROC glad_glRasterPos2s; +#define glRasterPos2s glad_glRasterPos2s +GLAD_API_CALL PFNGLRASTERPOS2SVPROC glad_glRasterPos2sv; +#define glRasterPos2sv glad_glRasterPos2sv +GLAD_API_CALL PFNGLRASTERPOS3DPROC glad_glRasterPos3d; +#define glRasterPos3d glad_glRasterPos3d +GLAD_API_CALL PFNGLRASTERPOS3DVPROC glad_glRasterPos3dv; +#define glRasterPos3dv glad_glRasterPos3dv +GLAD_API_CALL PFNGLRASTERPOS3FPROC glad_glRasterPos3f; +#define glRasterPos3f glad_glRasterPos3f +GLAD_API_CALL PFNGLRASTERPOS3FVPROC glad_glRasterPos3fv; +#define glRasterPos3fv glad_glRasterPos3fv +GLAD_API_CALL PFNGLRASTERPOS3IPROC glad_glRasterPos3i; +#define glRasterPos3i glad_glRasterPos3i +GLAD_API_CALL PFNGLRASTERPOS3IVPROC glad_glRasterPos3iv; +#define glRasterPos3iv glad_glRasterPos3iv +GLAD_API_CALL PFNGLRASTERPOS3SPROC glad_glRasterPos3s; +#define glRasterPos3s glad_glRasterPos3s +GLAD_API_CALL PFNGLRASTERPOS3SVPROC glad_glRasterPos3sv; +#define glRasterPos3sv glad_glRasterPos3sv +GLAD_API_CALL PFNGLRASTERPOS4DPROC glad_glRasterPos4d; +#define glRasterPos4d glad_glRasterPos4d +GLAD_API_CALL PFNGLRASTERPOS4DVPROC glad_glRasterPos4dv; +#define glRasterPos4dv glad_glRasterPos4dv +GLAD_API_CALL PFNGLRASTERPOS4FPROC glad_glRasterPos4f; +#define glRasterPos4f glad_glRasterPos4f +GLAD_API_CALL PFNGLRASTERPOS4FVPROC glad_glRasterPos4fv; +#define glRasterPos4fv glad_glRasterPos4fv +GLAD_API_CALL PFNGLRASTERPOS4IPROC glad_glRasterPos4i; +#define glRasterPos4i glad_glRasterPos4i +GLAD_API_CALL PFNGLRASTERPOS4IVPROC glad_glRasterPos4iv; +#define glRasterPos4iv glad_glRasterPos4iv +GLAD_API_CALL PFNGLRASTERPOS4SPROC glad_glRasterPos4s; +#define glRasterPos4s glad_glRasterPos4s +GLAD_API_CALL PFNGLRASTERPOS4SVPROC glad_glRasterPos4sv; +#define glRasterPos4sv glad_glRasterPos4sv +GLAD_API_CALL PFNGLREADBUFFERPROC glad_glReadBuffer; +#define glReadBuffer glad_glReadBuffer +GLAD_API_CALL PFNGLREADPIXELSPROC glad_glReadPixels; +#define glReadPixels glad_glReadPixels +GLAD_API_CALL PFNGLRECTDPROC glad_glRectd; +#define glRectd glad_glRectd +GLAD_API_CALL PFNGLRECTDVPROC glad_glRectdv; +#define glRectdv glad_glRectdv +GLAD_API_CALL PFNGLRECTFPROC glad_glRectf; +#define glRectf glad_glRectf +GLAD_API_CALL PFNGLRECTFVPROC glad_glRectfv; +#define glRectfv glad_glRectfv +GLAD_API_CALL PFNGLRECTIPROC glad_glRecti; +#define glRecti glad_glRecti +GLAD_API_CALL PFNGLRECTIVPROC glad_glRectiv; +#define glRectiv glad_glRectiv +GLAD_API_CALL PFNGLRECTSPROC glad_glRects; +#define glRects glad_glRects +GLAD_API_CALL PFNGLRECTSVPROC glad_glRectsv; +#define glRectsv glad_glRectsv +GLAD_API_CALL PFNGLRENDERMODEPROC glad_glRenderMode; +#define glRenderMode glad_glRenderMode +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; +#define glRenderbufferStorage glad_glRenderbufferStorage +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT; +#define glRenderbufferStorageEXT glad_glRenderbufferStorageEXT +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; +#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT; +#define glRenderbufferStorageMultisampleEXT glad_glRenderbufferStorageMultisampleEXT +GLAD_API_CALL PFNGLROTATEDPROC glad_glRotated; +#define glRotated glad_glRotated +GLAD_API_CALL PFNGLROTATEFPROC glad_glRotatef; +#define glRotatef glad_glRotatef +GLAD_API_CALL PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; +#define glSampleCoverage glad_glSampleCoverage +GLAD_API_CALL PFNGLSAMPLEMASKIPROC glad_glSampleMaski; +#define glSampleMaski glad_glSampleMaski +GLAD_API_CALL PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv; +#define glSamplerParameterIiv glad_glSamplerParameterIiv +GLAD_API_CALL PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv; +#define glSamplerParameterIuiv glad_glSamplerParameterIuiv +GLAD_API_CALL PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf; +#define glSamplerParameterf glad_glSamplerParameterf +GLAD_API_CALL PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv; +#define glSamplerParameterfv glad_glSamplerParameterfv +GLAD_API_CALL PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri; +#define glSamplerParameteri glad_glSamplerParameteri +GLAD_API_CALL PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv; +#define glSamplerParameteriv glad_glSamplerParameteriv +GLAD_API_CALL PFNGLSCALEDPROC glad_glScaled; +#define glScaled glad_glScaled +GLAD_API_CALL PFNGLSCALEFPROC glad_glScalef; +#define glScalef glad_glScalef +GLAD_API_CALL PFNGLSCISSORPROC glad_glScissor; +#define glScissor glad_glScissor +GLAD_API_CALL PFNGLSECONDARYCOLOR3BPROC glad_glSecondaryColor3b; +#define glSecondaryColor3b glad_glSecondaryColor3b +GLAD_API_CALL PFNGLSECONDARYCOLOR3BVPROC glad_glSecondaryColor3bv; +#define glSecondaryColor3bv glad_glSecondaryColor3bv +GLAD_API_CALL PFNGLSECONDARYCOLOR3DPROC glad_glSecondaryColor3d; +#define glSecondaryColor3d glad_glSecondaryColor3d +GLAD_API_CALL PFNGLSECONDARYCOLOR3DVPROC glad_glSecondaryColor3dv; +#define glSecondaryColor3dv glad_glSecondaryColor3dv +GLAD_API_CALL PFNGLSECONDARYCOLOR3FPROC glad_glSecondaryColor3f; +#define glSecondaryColor3f glad_glSecondaryColor3f +GLAD_API_CALL PFNGLSECONDARYCOLOR3FVPROC glad_glSecondaryColor3fv; +#define glSecondaryColor3fv glad_glSecondaryColor3fv +GLAD_API_CALL PFNGLSECONDARYCOLOR3IPROC glad_glSecondaryColor3i; +#define glSecondaryColor3i glad_glSecondaryColor3i +GLAD_API_CALL PFNGLSECONDARYCOLOR3IVPROC glad_glSecondaryColor3iv; +#define glSecondaryColor3iv glad_glSecondaryColor3iv +GLAD_API_CALL PFNGLSECONDARYCOLOR3SPROC glad_glSecondaryColor3s; +#define glSecondaryColor3s glad_glSecondaryColor3s +GLAD_API_CALL PFNGLSECONDARYCOLOR3SVPROC glad_glSecondaryColor3sv; +#define glSecondaryColor3sv glad_glSecondaryColor3sv +GLAD_API_CALL PFNGLSECONDARYCOLOR3UBPROC glad_glSecondaryColor3ub; +#define glSecondaryColor3ub glad_glSecondaryColor3ub +GLAD_API_CALL PFNGLSECONDARYCOLOR3UBVPROC glad_glSecondaryColor3ubv; +#define glSecondaryColor3ubv glad_glSecondaryColor3ubv +GLAD_API_CALL PFNGLSECONDARYCOLOR3UIPROC glad_glSecondaryColor3ui; +#define glSecondaryColor3ui glad_glSecondaryColor3ui +GLAD_API_CALL PFNGLSECONDARYCOLOR3UIVPROC glad_glSecondaryColor3uiv; +#define glSecondaryColor3uiv glad_glSecondaryColor3uiv +GLAD_API_CALL PFNGLSECONDARYCOLOR3USPROC glad_glSecondaryColor3us; +#define glSecondaryColor3us glad_glSecondaryColor3us +GLAD_API_CALL PFNGLSECONDARYCOLOR3USVPROC glad_glSecondaryColor3usv; +#define glSecondaryColor3usv glad_glSecondaryColor3usv +GLAD_API_CALL PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui; +#define glSecondaryColorP3ui glad_glSecondaryColorP3ui +GLAD_API_CALL PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv; +#define glSecondaryColorP3uiv glad_glSecondaryColorP3uiv +GLAD_API_CALL PFNGLSECONDARYCOLORPOINTERPROC glad_glSecondaryColorPointer; +#define glSecondaryColorPointer glad_glSecondaryColorPointer +GLAD_API_CALL PFNGLSELECTBUFFERPROC glad_glSelectBuffer; +#define glSelectBuffer glad_glSelectBuffer +GLAD_API_CALL PFNGLSHADEMODELPROC glad_glShadeModel; +#define glShadeModel glad_glShadeModel +GLAD_API_CALL PFNGLSHADERSOURCEPROC glad_glShaderSource; +#define glShaderSource glad_glShaderSource +GLAD_API_CALL PFNGLSTENCILFUNCPROC glad_glStencilFunc; +#define glStencilFunc glad_glStencilFunc +GLAD_API_CALL PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; +#define glStencilFuncSeparate glad_glStencilFuncSeparate +GLAD_API_CALL PFNGLSTENCILMASKPROC glad_glStencilMask; +#define glStencilMask glad_glStencilMask +GLAD_API_CALL PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; +#define glStencilMaskSeparate glad_glStencilMaskSeparate +GLAD_API_CALL PFNGLSTENCILOPPROC glad_glStencilOp; +#define glStencilOp glad_glStencilOp +GLAD_API_CALL PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; +#define glStencilOpSeparate glad_glStencilOpSeparate +GLAD_API_CALL PFNGLTEXBUFFERPROC glad_glTexBuffer; +#define glTexBuffer glad_glTexBuffer +GLAD_API_CALL PFNGLTEXCOORD1DPROC glad_glTexCoord1d; +#define glTexCoord1d glad_glTexCoord1d +GLAD_API_CALL PFNGLTEXCOORD1DVPROC glad_glTexCoord1dv; +#define glTexCoord1dv glad_glTexCoord1dv +GLAD_API_CALL PFNGLTEXCOORD1FPROC glad_glTexCoord1f; +#define glTexCoord1f glad_glTexCoord1f +GLAD_API_CALL PFNGLTEXCOORD1FVPROC glad_glTexCoord1fv; +#define glTexCoord1fv glad_glTexCoord1fv +GLAD_API_CALL PFNGLTEXCOORD1IPROC glad_glTexCoord1i; +#define glTexCoord1i glad_glTexCoord1i +GLAD_API_CALL PFNGLTEXCOORD1IVPROC glad_glTexCoord1iv; +#define glTexCoord1iv glad_glTexCoord1iv +GLAD_API_CALL PFNGLTEXCOORD1SPROC glad_glTexCoord1s; +#define glTexCoord1s glad_glTexCoord1s +GLAD_API_CALL PFNGLTEXCOORD1SVPROC glad_glTexCoord1sv; +#define glTexCoord1sv glad_glTexCoord1sv +GLAD_API_CALL PFNGLTEXCOORD2DPROC glad_glTexCoord2d; +#define glTexCoord2d glad_glTexCoord2d +GLAD_API_CALL PFNGLTEXCOORD2DVPROC glad_glTexCoord2dv; +#define glTexCoord2dv glad_glTexCoord2dv +GLAD_API_CALL PFNGLTEXCOORD2FPROC glad_glTexCoord2f; +#define glTexCoord2f glad_glTexCoord2f +GLAD_API_CALL PFNGLTEXCOORD2FVPROC glad_glTexCoord2fv; +#define glTexCoord2fv glad_glTexCoord2fv +GLAD_API_CALL PFNGLTEXCOORD2IPROC glad_glTexCoord2i; +#define glTexCoord2i glad_glTexCoord2i +GLAD_API_CALL PFNGLTEXCOORD2IVPROC glad_glTexCoord2iv; +#define glTexCoord2iv glad_glTexCoord2iv +GLAD_API_CALL PFNGLTEXCOORD2SPROC glad_glTexCoord2s; +#define glTexCoord2s glad_glTexCoord2s +GLAD_API_CALL PFNGLTEXCOORD2SVPROC glad_glTexCoord2sv; +#define glTexCoord2sv glad_glTexCoord2sv +GLAD_API_CALL PFNGLTEXCOORD3DPROC glad_glTexCoord3d; +#define glTexCoord3d glad_glTexCoord3d +GLAD_API_CALL PFNGLTEXCOORD3DVPROC glad_glTexCoord3dv; +#define glTexCoord3dv glad_glTexCoord3dv +GLAD_API_CALL PFNGLTEXCOORD3FPROC glad_glTexCoord3f; +#define glTexCoord3f glad_glTexCoord3f +GLAD_API_CALL PFNGLTEXCOORD3FVPROC glad_glTexCoord3fv; +#define glTexCoord3fv glad_glTexCoord3fv +GLAD_API_CALL PFNGLTEXCOORD3IPROC glad_glTexCoord3i; +#define glTexCoord3i glad_glTexCoord3i +GLAD_API_CALL PFNGLTEXCOORD3IVPROC glad_glTexCoord3iv; +#define glTexCoord3iv glad_glTexCoord3iv +GLAD_API_CALL PFNGLTEXCOORD3SPROC glad_glTexCoord3s; +#define glTexCoord3s glad_glTexCoord3s +GLAD_API_CALL PFNGLTEXCOORD3SVPROC glad_glTexCoord3sv; +#define glTexCoord3sv glad_glTexCoord3sv +GLAD_API_CALL PFNGLTEXCOORD4DPROC glad_glTexCoord4d; +#define glTexCoord4d glad_glTexCoord4d +GLAD_API_CALL PFNGLTEXCOORD4DVPROC glad_glTexCoord4dv; +#define glTexCoord4dv glad_glTexCoord4dv +GLAD_API_CALL PFNGLTEXCOORD4FPROC glad_glTexCoord4f; +#define glTexCoord4f glad_glTexCoord4f +GLAD_API_CALL PFNGLTEXCOORD4FVPROC glad_glTexCoord4fv; +#define glTexCoord4fv glad_glTexCoord4fv +GLAD_API_CALL PFNGLTEXCOORD4IPROC glad_glTexCoord4i; +#define glTexCoord4i glad_glTexCoord4i +GLAD_API_CALL PFNGLTEXCOORD4IVPROC glad_glTexCoord4iv; +#define glTexCoord4iv glad_glTexCoord4iv +GLAD_API_CALL PFNGLTEXCOORD4SPROC glad_glTexCoord4s; +#define glTexCoord4s glad_glTexCoord4s +GLAD_API_CALL PFNGLTEXCOORD4SVPROC glad_glTexCoord4sv; +#define glTexCoord4sv glad_glTexCoord4sv +GLAD_API_CALL PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui; +#define glTexCoordP1ui glad_glTexCoordP1ui +GLAD_API_CALL PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv; +#define glTexCoordP1uiv glad_glTexCoordP1uiv +GLAD_API_CALL PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui; +#define glTexCoordP2ui glad_glTexCoordP2ui +GLAD_API_CALL PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv; +#define glTexCoordP2uiv glad_glTexCoordP2uiv +GLAD_API_CALL PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui; +#define glTexCoordP3ui glad_glTexCoordP3ui +GLAD_API_CALL PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv; +#define glTexCoordP3uiv glad_glTexCoordP3uiv +GLAD_API_CALL PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui; +#define glTexCoordP4ui glad_glTexCoordP4ui +GLAD_API_CALL PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv; +#define glTexCoordP4uiv glad_glTexCoordP4uiv +GLAD_API_CALL PFNGLTEXCOORDPOINTERPROC glad_glTexCoordPointer; +#define glTexCoordPointer glad_glTexCoordPointer +GLAD_API_CALL PFNGLTEXENVFPROC glad_glTexEnvf; +#define glTexEnvf glad_glTexEnvf +GLAD_API_CALL PFNGLTEXENVFVPROC glad_glTexEnvfv; +#define glTexEnvfv glad_glTexEnvfv +GLAD_API_CALL PFNGLTEXENVIPROC glad_glTexEnvi; +#define glTexEnvi glad_glTexEnvi +GLAD_API_CALL PFNGLTEXENVIVPROC glad_glTexEnviv; +#define glTexEnviv glad_glTexEnviv +GLAD_API_CALL PFNGLTEXGENDPROC glad_glTexGend; +#define glTexGend glad_glTexGend +GLAD_API_CALL PFNGLTEXGENDVPROC glad_glTexGendv; +#define glTexGendv glad_glTexGendv +GLAD_API_CALL PFNGLTEXGENFPROC glad_glTexGenf; +#define glTexGenf glad_glTexGenf +GLAD_API_CALL PFNGLTEXGENFVPROC glad_glTexGenfv; +#define glTexGenfv glad_glTexGenfv +GLAD_API_CALL PFNGLTEXGENIPROC glad_glTexGeni; +#define glTexGeni glad_glTexGeni +GLAD_API_CALL PFNGLTEXGENIVPROC glad_glTexGeniv; +#define glTexGeniv glad_glTexGeniv +GLAD_API_CALL PFNGLTEXIMAGE1DPROC glad_glTexImage1D; +#define glTexImage1D glad_glTexImage1D +GLAD_API_CALL PFNGLTEXIMAGE2DPROC glad_glTexImage2D; +#define glTexImage2D glad_glTexImage2D +GLAD_API_CALL PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; +#define glTexImage2DMultisample glad_glTexImage2DMultisample +GLAD_API_CALL PFNGLTEXIMAGE3DPROC glad_glTexImage3D; +#define glTexImage3D glad_glTexImage3D +GLAD_API_CALL PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; +#define glTexImage3DMultisample glad_glTexImage3DMultisample +GLAD_API_CALL PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; +#define glTexParameterIiv glad_glTexParameterIiv +GLAD_API_CALL PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; +#define glTexParameterIuiv glad_glTexParameterIuiv +GLAD_API_CALL PFNGLTEXPARAMETERFPROC glad_glTexParameterf; +#define glTexParameterf glad_glTexParameterf +GLAD_API_CALL PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; +#define glTexParameterfv glad_glTexParameterfv +GLAD_API_CALL PFNGLTEXPARAMETERIPROC glad_glTexParameteri; +#define glTexParameteri glad_glTexParameteri +GLAD_API_CALL PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; +#define glTexParameteriv glad_glTexParameteriv +GLAD_API_CALL PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; +#define glTexSubImage1D glad_glTexSubImage1D +GLAD_API_CALL PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; +#define glTexSubImage2D glad_glTexSubImage2D +GLAD_API_CALL PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; +#define glTexSubImage3D glad_glTexSubImage3D +GLAD_API_CALL PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; +#define glTransformFeedbackVaryings glad_glTransformFeedbackVaryings +GLAD_API_CALL PFNGLTRANSLATEDPROC glad_glTranslated; +#define glTranslated glad_glTranslated +GLAD_API_CALL PFNGLTRANSLATEFPROC glad_glTranslatef; +#define glTranslatef glad_glTranslatef +GLAD_API_CALL PFNGLUNIFORM1FPROC glad_glUniform1f; +#define glUniform1f glad_glUniform1f +GLAD_API_CALL PFNGLUNIFORM1FVPROC glad_glUniform1fv; +#define glUniform1fv glad_glUniform1fv +GLAD_API_CALL PFNGLUNIFORM1IPROC glad_glUniform1i; +#define glUniform1i glad_glUniform1i +GLAD_API_CALL PFNGLUNIFORM1IVPROC glad_glUniform1iv; +#define glUniform1iv glad_glUniform1iv +GLAD_API_CALL PFNGLUNIFORM1UIPROC glad_glUniform1ui; +#define glUniform1ui glad_glUniform1ui +GLAD_API_CALL PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; +#define glUniform1uiv glad_glUniform1uiv +GLAD_API_CALL PFNGLUNIFORM2FPROC glad_glUniform2f; +#define glUniform2f glad_glUniform2f +GLAD_API_CALL PFNGLUNIFORM2FVPROC glad_glUniform2fv; +#define glUniform2fv glad_glUniform2fv +GLAD_API_CALL PFNGLUNIFORM2IPROC glad_glUniform2i; +#define glUniform2i glad_glUniform2i +GLAD_API_CALL PFNGLUNIFORM2IVPROC glad_glUniform2iv; +#define glUniform2iv glad_glUniform2iv +GLAD_API_CALL PFNGLUNIFORM2UIPROC glad_glUniform2ui; +#define glUniform2ui glad_glUniform2ui +GLAD_API_CALL PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; +#define glUniform2uiv glad_glUniform2uiv +GLAD_API_CALL PFNGLUNIFORM3FPROC glad_glUniform3f; +#define glUniform3f glad_glUniform3f +GLAD_API_CALL PFNGLUNIFORM3FVPROC glad_glUniform3fv; +#define glUniform3fv glad_glUniform3fv +GLAD_API_CALL PFNGLUNIFORM3IPROC glad_glUniform3i; +#define glUniform3i glad_glUniform3i +GLAD_API_CALL PFNGLUNIFORM3IVPROC glad_glUniform3iv; +#define glUniform3iv glad_glUniform3iv +GLAD_API_CALL PFNGLUNIFORM3UIPROC glad_glUniform3ui; +#define glUniform3ui glad_glUniform3ui +GLAD_API_CALL PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; +#define glUniform3uiv glad_glUniform3uiv +GLAD_API_CALL PFNGLUNIFORM4FPROC glad_glUniform4f; +#define glUniform4f glad_glUniform4f +GLAD_API_CALL PFNGLUNIFORM4FVPROC glad_glUniform4fv; +#define glUniform4fv glad_glUniform4fv +GLAD_API_CALL PFNGLUNIFORM4IPROC glad_glUniform4i; +#define glUniform4i glad_glUniform4i +GLAD_API_CALL PFNGLUNIFORM4IVPROC glad_glUniform4iv; +#define glUniform4iv glad_glUniform4iv +GLAD_API_CALL PFNGLUNIFORM4UIPROC glad_glUniform4ui; +#define glUniform4ui glad_glUniform4ui +GLAD_API_CALL PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; +#define glUniform4uiv glad_glUniform4uiv +GLAD_API_CALL PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; +#define glUniformBlockBinding glad_glUniformBlockBinding +GLAD_API_CALL PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; +#define glUniformMatrix2fv glad_glUniformMatrix2fv +GLAD_API_CALL PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; +#define glUniformMatrix2x3fv glad_glUniformMatrix2x3fv +GLAD_API_CALL PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; +#define glUniformMatrix2x4fv glad_glUniformMatrix2x4fv +GLAD_API_CALL PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; +#define glUniformMatrix3fv glad_glUniformMatrix3fv +GLAD_API_CALL PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; +#define glUniformMatrix3x2fv glad_glUniformMatrix3x2fv +GLAD_API_CALL PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; +#define glUniformMatrix3x4fv glad_glUniformMatrix3x4fv +GLAD_API_CALL PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; +#define glUniformMatrix4fv glad_glUniformMatrix4fv +GLAD_API_CALL PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; +#define glUniformMatrix4x2fv glad_glUniformMatrix4x2fv +GLAD_API_CALL PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; +#define glUniformMatrix4x3fv glad_glUniformMatrix4x3fv +GLAD_API_CALL PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; +#define glUnmapBuffer glad_glUnmapBuffer +GLAD_API_CALL PFNGLUSEPROGRAMPROC glad_glUseProgram; +#define glUseProgram glad_glUseProgram +GLAD_API_CALL PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; +#define glValidateProgram glad_glValidateProgram +GLAD_API_CALL PFNGLVERTEX2DPROC glad_glVertex2d; +#define glVertex2d glad_glVertex2d +GLAD_API_CALL PFNGLVERTEX2DVPROC glad_glVertex2dv; +#define glVertex2dv glad_glVertex2dv +GLAD_API_CALL PFNGLVERTEX2FPROC glad_glVertex2f; +#define glVertex2f glad_glVertex2f +GLAD_API_CALL PFNGLVERTEX2FVPROC glad_glVertex2fv; +#define glVertex2fv glad_glVertex2fv +GLAD_API_CALL PFNGLVERTEX2IPROC glad_glVertex2i; +#define glVertex2i glad_glVertex2i +GLAD_API_CALL PFNGLVERTEX2IVPROC glad_glVertex2iv; +#define glVertex2iv glad_glVertex2iv +GLAD_API_CALL PFNGLVERTEX2SPROC glad_glVertex2s; +#define glVertex2s glad_glVertex2s +GLAD_API_CALL PFNGLVERTEX2SVPROC glad_glVertex2sv; +#define glVertex2sv glad_glVertex2sv +GLAD_API_CALL PFNGLVERTEX3DPROC glad_glVertex3d; +#define glVertex3d glad_glVertex3d +GLAD_API_CALL PFNGLVERTEX3DVPROC glad_glVertex3dv; +#define glVertex3dv glad_glVertex3dv +GLAD_API_CALL PFNGLVERTEX3FPROC glad_glVertex3f; +#define glVertex3f glad_glVertex3f +GLAD_API_CALL PFNGLVERTEX3FVPROC glad_glVertex3fv; +#define glVertex3fv glad_glVertex3fv +GLAD_API_CALL PFNGLVERTEX3IPROC glad_glVertex3i; +#define glVertex3i glad_glVertex3i +GLAD_API_CALL PFNGLVERTEX3IVPROC glad_glVertex3iv; +#define glVertex3iv glad_glVertex3iv +GLAD_API_CALL PFNGLVERTEX3SPROC glad_glVertex3s; +#define glVertex3s glad_glVertex3s +GLAD_API_CALL PFNGLVERTEX3SVPROC glad_glVertex3sv; +#define glVertex3sv glad_glVertex3sv +GLAD_API_CALL PFNGLVERTEX4DPROC glad_glVertex4d; +#define glVertex4d glad_glVertex4d +GLAD_API_CALL PFNGLVERTEX4DVPROC glad_glVertex4dv; +#define glVertex4dv glad_glVertex4dv +GLAD_API_CALL PFNGLVERTEX4FPROC glad_glVertex4f; +#define glVertex4f glad_glVertex4f +GLAD_API_CALL PFNGLVERTEX4FVPROC glad_glVertex4fv; +#define glVertex4fv glad_glVertex4fv +GLAD_API_CALL PFNGLVERTEX4IPROC glad_glVertex4i; +#define glVertex4i glad_glVertex4i +GLAD_API_CALL PFNGLVERTEX4IVPROC glad_glVertex4iv; +#define glVertex4iv glad_glVertex4iv +GLAD_API_CALL PFNGLVERTEX4SPROC glad_glVertex4s; +#define glVertex4s glad_glVertex4s +GLAD_API_CALL PFNGLVERTEX4SVPROC glad_glVertex4sv; +#define glVertex4sv glad_glVertex4sv +GLAD_API_CALL PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; +#define glVertexAttrib1d glad_glVertexAttrib1d +GLAD_API_CALL PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; +#define glVertexAttrib1dv glad_glVertexAttrib1dv +GLAD_API_CALL PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; +#define glVertexAttrib1f glad_glVertexAttrib1f +GLAD_API_CALL PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; +#define glVertexAttrib1fv glad_glVertexAttrib1fv +GLAD_API_CALL PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; +#define glVertexAttrib1s glad_glVertexAttrib1s +GLAD_API_CALL PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; +#define glVertexAttrib1sv glad_glVertexAttrib1sv +GLAD_API_CALL PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; +#define glVertexAttrib2d glad_glVertexAttrib2d +GLAD_API_CALL PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; +#define glVertexAttrib2dv glad_glVertexAttrib2dv +GLAD_API_CALL PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; +#define glVertexAttrib2f glad_glVertexAttrib2f +GLAD_API_CALL PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; +#define glVertexAttrib2fv glad_glVertexAttrib2fv +GLAD_API_CALL PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; +#define glVertexAttrib2s glad_glVertexAttrib2s +GLAD_API_CALL PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; +#define glVertexAttrib2sv glad_glVertexAttrib2sv +GLAD_API_CALL PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; +#define glVertexAttrib3d glad_glVertexAttrib3d +GLAD_API_CALL PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; +#define glVertexAttrib3dv glad_glVertexAttrib3dv +GLAD_API_CALL PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; +#define glVertexAttrib3f glad_glVertexAttrib3f +GLAD_API_CALL PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; +#define glVertexAttrib3fv glad_glVertexAttrib3fv +GLAD_API_CALL PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; +#define glVertexAttrib3s glad_glVertexAttrib3s +GLAD_API_CALL PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; +#define glVertexAttrib3sv glad_glVertexAttrib3sv +GLAD_API_CALL PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; +#define glVertexAttrib4Nbv glad_glVertexAttrib4Nbv +GLAD_API_CALL PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; +#define glVertexAttrib4Niv glad_glVertexAttrib4Niv +GLAD_API_CALL PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; +#define glVertexAttrib4Nsv glad_glVertexAttrib4Nsv +GLAD_API_CALL PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; +#define glVertexAttrib4Nub glad_glVertexAttrib4Nub +GLAD_API_CALL PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; +#define glVertexAttrib4Nubv glad_glVertexAttrib4Nubv +GLAD_API_CALL PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; +#define glVertexAttrib4Nuiv glad_glVertexAttrib4Nuiv +GLAD_API_CALL PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; +#define glVertexAttrib4Nusv glad_glVertexAttrib4Nusv +GLAD_API_CALL PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; +#define glVertexAttrib4bv glad_glVertexAttrib4bv +GLAD_API_CALL PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; +#define glVertexAttrib4d glad_glVertexAttrib4d +GLAD_API_CALL PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; +#define glVertexAttrib4dv glad_glVertexAttrib4dv +GLAD_API_CALL PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; +#define glVertexAttrib4f glad_glVertexAttrib4f +GLAD_API_CALL PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; +#define glVertexAttrib4fv glad_glVertexAttrib4fv +GLAD_API_CALL PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; +#define glVertexAttrib4iv glad_glVertexAttrib4iv +GLAD_API_CALL PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; +#define glVertexAttrib4s glad_glVertexAttrib4s +GLAD_API_CALL PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; +#define glVertexAttrib4sv glad_glVertexAttrib4sv +GLAD_API_CALL PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; +#define glVertexAttrib4ubv glad_glVertexAttrib4ubv +GLAD_API_CALL PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; +#define glVertexAttrib4uiv glad_glVertexAttrib4uiv +GLAD_API_CALL PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; +#define glVertexAttrib4usv glad_glVertexAttrib4usv +GLAD_API_CALL PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor; +#define glVertexAttribDivisor glad_glVertexAttribDivisor +GLAD_API_CALL PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; +#define glVertexAttribI1i glad_glVertexAttribI1i +GLAD_API_CALL PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; +#define glVertexAttribI1iv glad_glVertexAttribI1iv +GLAD_API_CALL PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; +#define glVertexAttribI1ui glad_glVertexAttribI1ui +GLAD_API_CALL PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; +#define glVertexAttribI1uiv glad_glVertexAttribI1uiv +GLAD_API_CALL PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; +#define glVertexAttribI2i glad_glVertexAttribI2i +GLAD_API_CALL PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; +#define glVertexAttribI2iv glad_glVertexAttribI2iv +GLAD_API_CALL PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; +#define glVertexAttribI2ui glad_glVertexAttribI2ui +GLAD_API_CALL PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; +#define glVertexAttribI2uiv glad_glVertexAttribI2uiv +GLAD_API_CALL PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; +#define glVertexAttribI3i glad_glVertexAttribI3i +GLAD_API_CALL PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; +#define glVertexAttribI3iv glad_glVertexAttribI3iv +GLAD_API_CALL PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; +#define glVertexAttribI3ui glad_glVertexAttribI3ui +GLAD_API_CALL PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; +#define glVertexAttribI3uiv glad_glVertexAttribI3uiv +GLAD_API_CALL PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; +#define glVertexAttribI4bv glad_glVertexAttribI4bv +GLAD_API_CALL PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; +#define glVertexAttribI4i glad_glVertexAttribI4i +GLAD_API_CALL PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; +#define glVertexAttribI4iv glad_glVertexAttribI4iv +GLAD_API_CALL PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; +#define glVertexAttribI4sv glad_glVertexAttribI4sv +GLAD_API_CALL PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; +#define glVertexAttribI4ubv glad_glVertexAttribI4ubv +GLAD_API_CALL PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; +#define glVertexAttribI4ui glad_glVertexAttribI4ui +GLAD_API_CALL PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; +#define glVertexAttribI4uiv glad_glVertexAttribI4uiv +GLAD_API_CALL PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; +#define glVertexAttribI4usv glad_glVertexAttribI4usv +GLAD_API_CALL PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; +#define glVertexAttribIPointer glad_glVertexAttribIPointer +GLAD_API_CALL PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui; +#define glVertexAttribP1ui glad_glVertexAttribP1ui +GLAD_API_CALL PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv; +#define glVertexAttribP1uiv glad_glVertexAttribP1uiv +GLAD_API_CALL PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui; +#define glVertexAttribP2ui glad_glVertexAttribP2ui +GLAD_API_CALL PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv; +#define glVertexAttribP2uiv glad_glVertexAttribP2uiv +GLAD_API_CALL PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui; +#define glVertexAttribP3ui glad_glVertexAttribP3ui +GLAD_API_CALL PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv; +#define glVertexAttribP3uiv glad_glVertexAttribP3uiv +GLAD_API_CALL PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui; +#define glVertexAttribP4ui glad_glVertexAttribP4ui +GLAD_API_CALL PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv; +#define glVertexAttribP4uiv glad_glVertexAttribP4uiv +GLAD_API_CALL PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; +#define glVertexAttribPointer glad_glVertexAttribPointer +GLAD_API_CALL PFNGLVERTEXP2UIPROC glad_glVertexP2ui; +#define glVertexP2ui glad_glVertexP2ui +GLAD_API_CALL PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv; +#define glVertexP2uiv glad_glVertexP2uiv +GLAD_API_CALL PFNGLVERTEXP3UIPROC glad_glVertexP3ui; +#define glVertexP3ui glad_glVertexP3ui +GLAD_API_CALL PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv; +#define glVertexP3uiv glad_glVertexP3uiv +GLAD_API_CALL PFNGLVERTEXP4UIPROC glad_glVertexP4ui; +#define glVertexP4ui glad_glVertexP4ui +GLAD_API_CALL PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv; +#define glVertexP4uiv glad_glVertexP4uiv +GLAD_API_CALL PFNGLVERTEXPOINTERPROC glad_glVertexPointer; +#define glVertexPointer glad_glVertexPointer +GLAD_API_CALL PFNGLVIEWPORTPROC glad_glViewport; +#define glViewport glad_glViewport +GLAD_API_CALL PFNGLWAITSYNCPROC glad_glWaitSync; +#define glWaitSync glad_glWaitSync +GLAD_API_CALL PFNGLWINDOWPOS2DPROC glad_glWindowPos2d; +#define glWindowPos2d glad_glWindowPos2d +GLAD_API_CALL PFNGLWINDOWPOS2DVPROC glad_glWindowPos2dv; +#define glWindowPos2dv glad_glWindowPos2dv +GLAD_API_CALL PFNGLWINDOWPOS2FPROC glad_glWindowPos2f; +#define glWindowPos2f glad_glWindowPos2f +GLAD_API_CALL PFNGLWINDOWPOS2FVPROC glad_glWindowPos2fv; +#define glWindowPos2fv glad_glWindowPos2fv +GLAD_API_CALL PFNGLWINDOWPOS2IPROC glad_glWindowPos2i; +#define glWindowPos2i glad_glWindowPos2i +GLAD_API_CALL PFNGLWINDOWPOS2IVPROC glad_glWindowPos2iv; +#define glWindowPos2iv glad_glWindowPos2iv +GLAD_API_CALL PFNGLWINDOWPOS2SPROC glad_glWindowPos2s; +#define glWindowPos2s glad_glWindowPos2s +GLAD_API_CALL PFNGLWINDOWPOS2SVPROC glad_glWindowPos2sv; +#define glWindowPos2sv glad_glWindowPos2sv +GLAD_API_CALL PFNGLWINDOWPOS3DPROC glad_glWindowPos3d; +#define glWindowPos3d glad_glWindowPos3d +GLAD_API_CALL PFNGLWINDOWPOS3DVPROC glad_glWindowPos3dv; +#define glWindowPos3dv glad_glWindowPos3dv +GLAD_API_CALL PFNGLWINDOWPOS3FPROC glad_glWindowPos3f; +#define glWindowPos3f glad_glWindowPos3f +GLAD_API_CALL PFNGLWINDOWPOS3FVPROC glad_glWindowPos3fv; +#define glWindowPos3fv glad_glWindowPos3fv +GLAD_API_CALL PFNGLWINDOWPOS3IPROC glad_glWindowPos3i; +#define glWindowPos3i glad_glWindowPos3i +GLAD_API_CALL PFNGLWINDOWPOS3IVPROC glad_glWindowPos3iv; +#define glWindowPos3iv glad_glWindowPos3iv +GLAD_API_CALL PFNGLWINDOWPOS3SPROC glad_glWindowPos3s; +#define glWindowPos3s glad_glWindowPos3s +GLAD_API_CALL PFNGLWINDOWPOS3SVPROC glad_glWindowPos3sv; +#define glWindowPos3sv glad_glWindowPos3sv + + + + + +GLAD_API_CALL int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr); +GLAD_API_CALL int gladLoadGL( GLADloadfunc load); + + +#ifdef GLAD_GL + +GLAD_API_CALL int gladLoaderLoadGL(void); +GLAD_API_CALL void gladLoaderUnloadGL(void); + +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/thirdparty/glad/glad/glad.h b/thirdparty/glad/glad/glad.h deleted file mode 100644 index 37d12e4ee2..0000000000 --- a/thirdparty/glad/glad/glad.h +++ /dev/null @@ -1,3801 +0,0 @@ -/* - - OpenGL loader generated by glad 0.1.36 on Sun Sep 4 15:50:32 2022. - - Language/Generator: C/C++ - Specification: gl - APIs: gl=3.3 - Profile: compatibility - Extensions: - GL_ARB_debug_output, - GL_ARB_framebuffer_object, - GL_EXT_framebuffer_blit, - GL_EXT_framebuffer_multisample, - GL_EXT_framebuffer_object, - GL_OVR_multiview, - GL_OVR_multiview2 - Loader: True - Local files: False - Omit khrplatform: False - Reproducible: False - - Commandline: - --profile="compatibility" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_ARB_debug_output,GL_ARB_framebuffer_object,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_object,GL_OVR_multiview,GL_OVR_multiview2" - Online: - https://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gl%3D3.3&extensions=GL_ARB_debug_output&extensions=GL_ARB_framebuffer_object&extensions=GL_EXT_framebuffer_blit&extensions=GL_EXT_framebuffer_multisample&extensions=GL_EXT_framebuffer_object&extensions=GL_OVR_multiview&extensions=GL_OVR_multiview2 -*/ - - -#ifndef __glad_h_ -#define __glad_h_ - -#ifdef __gl_h_ -#error OpenGL header already included, remove this include, glad already provides it -#endif -#define __gl_h_ - -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#define APIENTRY __stdcall -#endif - -#ifndef APIENTRY -#define APIENTRY -#endif -#ifndef APIENTRYP -#define APIENTRYP APIENTRY * -#endif - -#ifndef GLAPIENTRY -#define GLAPIENTRY APIENTRY -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -struct gladGLversionStruct { - int major; - int minor; -}; - -typedef void* (* GLADloadproc)(const char *name); - -#ifndef GLAPI -# if defined(GLAD_GLAPI_EXPORT) -# if defined(_WIN32) || defined(__CYGWIN__) -# if defined(GLAD_GLAPI_EXPORT_BUILD) -# if defined(__GNUC__) -# define GLAPI __attribute__ ((dllexport)) extern -# else -# define GLAPI __declspec(dllexport) extern -# endif -# else -# if defined(__GNUC__) -# define GLAPI __attribute__ ((dllimport)) extern -# else -# define GLAPI __declspec(dllimport) extern -# endif -# endif -# elif defined(__GNUC__) && defined(GLAD_GLAPI_EXPORT_BUILD) -# define GLAPI __attribute__ ((visibility ("default"))) extern -# else -# define GLAPI extern -# endif -# else -# define GLAPI extern -# endif -#endif - -GLAPI struct gladGLversionStruct GLVersion; - -GLAPI int gladLoadGL(void); - -GLAPI int gladLoadGLLoader(GLADloadproc); - -#include <KHR/khrplatform.h> -typedef unsigned int GLenum; -typedef unsigned char GLboolean; -typedef unsigned int GLbitfield; -typedef void GLvoid; -typedef khronos_int8_t GLbyte; -typedef khronos_uint8_t GLubyte; -typedef khronos_int16_t GLshort; -typedef khronos_uint16_t GLushort; -typedef int GLint; -typedef unsigned int GLuint; -typedef khronos_int32_t GLclampx; -typedef int GLsizei; -typedef khronos_float_t GLfloat; -typedef khronos_float_t GLclampf; -typedef double GLdouble; -typedef double GLclampd; -typedef void *GLeglClientBufferEXT; -typedef void *GLeglImageOES; -typedef char GLchar; -typedef char GLcharARB; -#ifdef __APPLE__ -typedef void *GLhandleARB; -#else -typedef unsigned int GLhandleARB; -#endif -typedef khronos_uint16_t GLhalf; -typedef khronos_uint16_t GLhalfARB; -typedef khronos_int32_t GLfixed; -typedef khronos_intptr_t GLintptr; -typedef khronos_intptr_t GLintptrARB; -typedef khronos_ssize_t GLsizeiptr; -typedef khronos_ssize_t GLsizeiptrARB; -typedef khronos_int64_t GLint64; -typedef khronos_int64_t GLint64EXT; -typedef khronos_uint64_t GLuint64; -typedef khronos_uint64_t GLuint64EXT; -typedef struct __GLsync *GLsync; -struct _cl_context; -struct _cl_event; -typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); -typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); -typedef void (APIENTRY *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); -typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); -typedef unsigned short GLhalfNV; -typedef GLintptr GLvdpauSurfaceNV; -typedef void (APIENTRY *GLVULKANPROCNV)(void); -#define GL_DEPTH_BUFFER_BIT 0x00000100 -#define GL_STENCIL_BUFFER_BIT 0x00000400 -#define GL_COLOR_BUFFER_BIT 0x00004000 -#define GL_FALSE 0 -#define GL_TRUE 1 -#define GL_POINTS 0x0000 -#define GL_LINES 0x0001 -#define GL_LINE_LOOP 0x0002 -#define GL_LINE_STRIP 0x0003 -#define GL_TRIANGLES 0x0004 -#define GL_TRIANGLE_STRIP 0x0005 -#define GL_TRIANGLE_FAN 0x0006 -#define GL_QUADS 0x0007 -#define GL_NEVER 0x0200 -#define GL_LESS 0x0201 -#define GL_EQUAL 0x0202 -#define GL_LEQUAL 0x0203 -#define GL_GREATER 0x0204 -#define GL_NOTEQUAL 0x0205 -#define GL_GEQUAL 0x0206 -#define GL_ALWAYS 0x0207 -#define GL_ZERO 0 -#define GL_ONE 1 -#define GL_SRC_COLOR 0x0300 -#define GL_ONE_MINUS_SRC_COLOR 0x0301 -#define GL_SRC_ALPHA 0x0302 -#define GL_ONE_MINUS_SRC_ALPHA 0x0303 -#define GL_DST_ALPHA 0x0304 -#define GL_ONE_MINUS_DST_ALPHA 0x0305 -#define GL_DST_COLOR 0x0306 -#define GL_ONE_MINUS_DST_COLOR 0x0307 -#define GL_SRC_ALPHA_SATURATE 0x0308 -#define GL_NONE 0 -#define GL_FRONT_LEFT 0x0400 -#define GL_FRONT_RIGHT 0x0401 -#define GL_BACK_LEFT 0x0402 -#define GL_BACK_RIGHT 0x0403 -#define GL_FRONT 0x0404 -#define GL_BACK 0x0405 -#define GL_LEFT 0x0406 -#define GL_RIGHT 0x0407 -#define GL_FRONT_AND_BACK 0x0408 -#define GL_NO_ERROR 0 -#define GL_INVALID_ENUM 0x0500 -#define GL_INVALID_VALUE 0x0501 -#define GL_INVALID_OPERATION 0x0502 -#define GL_OUT_OF_MEMORY 0x0505 -#define GL_CW 0x0900 -#define GL_CCW 0x0901 -#define GL_POINT_SIZE 0x0B11 -#define GL_POINT_SIZE_RANGE 0x0B12 -#define GL_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_LINE_SMOOTH 0x0B20 -#define GL_LINE_WIDTH 0x0B21 -#define GL_LINE_WIDTH_RANGE 0x0B22 -#define GL_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_POLYGON_MODE 0x0B40 -#define GL_POLYGON_SMOOTH 0x0B41 -#define GL_CULL_FACE 0x0B44 -#define GL_CULL_FACE_MODE 0x0B45 -#define GL_FRONT_FACE 0x0B46 -#define GL_DEPTH_RANGE 0x0B70 -#define GL_DEPTH_TEST 0x0B71 -#define GL_DEPTH_WRITEMASK 0x0B72 -#define GL_DEPTH_CLEAR_VALUE 0x0B73 -#define GL_DEPTH_FUNC 0x0B74 -#define GL_STENCIL_TEST 0x0B90 -#define GL_STENCIL_CLEAR_VALUE 0x0B91 -#define GL_STENCIL_FUNC 0x0B92 -#define GL_STENCIL_VALUE_MASK 0x0B93 -#define GL_STENCIL_FAIL 0x0B94 -#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 -#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 -#define GL_STENCIL_REF 0x0B97 -#define GL_STENCIL_WRITEMASK 0x0B98 -#define GL_VIEWPORT 0x0BA2 -#define GL_DITHER 0x0BD0 -#define GL_BLEND_DST 0x0BE0 -#define GL_BLEND_SRC 0x0BE1 -#define GL_BLEND 0x0BE2 -#define GL_LOGIC_OP_MODE 0x0BF0 -#define GL_DRAW_BUFFER 0x0C01 -#define GL_READ_BUFFER 0x0C02 -#define GL_SCISSOR_BOX 0x0C10 -#define GL_SCISSOR_TEST 0x0C11 -#define GL_COLOR_CLEAR_VALUE 0x0C22 -#define GL_COLOR_WRITEMASK 0x0C23 -#define GL_DOUBLEBUFFER 0x0C32 -#define GL_STEREO 0x0C33 -#define GL_LINE_SMOOTH_HINT 0x0C52 -#define GL_POLYGON_SMOOTH_HINT 0x0C53 -#define GL_UNPACK_SWAP_BYTES 0x0CF0 -#define GL_UNPACK_LSB_FIRST 0x0CF1 -#define GL_UNPACK_ROW_LENGTH 0x0CF2 -#define GL_UNPACK_SKIP_ROWS 0x0CF3 -#define GL_UNPACK_SKIP_PIXELS 0x0CF4 -#define GL_UNPACK_ALIGNMENT 0x0CF5 -#define GL_PACK_SWAP_BYTES 0x0D00 -#define GL_PACK_LSB_FIRST 0x0D01 -#define GL_PACK_ROW_LENGTH 0x0D02 -#define GL_PACK_SKIP_ROWS 0x0D03 -#define GL_PACK_SKIP_PIXELS 0x0D04 -#define GL_PACK_ALIGNMENT 0x0D05 -#define GL_MAX_TEXTURE_SIZE 0x0D33 -#define GL_MAX_VIEWPORT_DIMS 0x0D3A -#define GL_SUBPIXEL_BITS 0x0D50 -#define GL_TEXTURE_1D 0x0DE0 -#define GL_TEXTURE_2D 0x0DE1 -#define GL_TEXTURE_WIDTH 0x1000 -#define GL_TEXTURE_HEIGHT 0x1001 -#define GL_TEXTURE_BORDER_COLOR 0x1004 -#define GL_DONT_CARE 0x1100 -#define GL_FASTEST 0x1101 -#define GL_NICEST 0x1102 -#define GL_BYTE 0x1400 -#define GL_UNSIGNED_BYTE 0x1401 -#define GL_SHORT 0x1402 -#define GL_UNSIGNED_SHORT 0x1403 -#define GL_INT 0x1404 -#define GL_UNSIGNED_INT 0x1405 -#define GL_FLOAT 0x1406 -#define GL_STACK_OVERFLOW 0x0503 -#define GL_STACK_UNDERFLOW 0x0504 -#define GL_CLEAR 0x1500 -#define GL_AND 0x1501 -#define GL_AND_REVERSE 0x1502 -#define GL_COPY 0x1503 -#define GL_AND_INVERTED 0x1504 -#define GL_NOOP 0x1505 -#define GL_XOR 0x1506 -#define GL_OR 0x1507 -#define GL_NOR 0x1508 -#define GL_EQUIV 0x1509 -#define GL_INVERT 0x150A -#define GL_OR_REVERSE 0x150B -#define GL_COPY_INVERTED 0x150C -#define GL_OR_INVERTED 0x150D -#define GL_NAND 0x150E -#define GL_SET 0x150F -#define GL_TEXTURE 0x1702 -#define GL_COLOR 0x1800 -#define GL_DEPTH 0x1801 -#define GL_STENCIL 0x1802 -#define GL_STENCIL_INDEX 0x1901 -#define GL_DEPTH_COMPONENT 0x1902 -#define GL_RED 0x1903 -#define GL_GREEN 0x1904 -#define GL_BLUE 0x1905 -#define GL_ALPHA 0x1906 -#define GL_RGB 0x1907 -#define GL_RGBA 0x1908 -#define GL_POINT 0x1B00 -#define GL_LINE 0x1B01 -#define GL_FILL 0x1B02 -#define GL_KEEP 0x1E00 -#define GL_REPLACE 0x1E01 -#define GL_INCR 0x1E02 -#define GL_DECR 0x1E03 -#define GL_VENDOR 0x1F00 -#define GL_RENDERER 0x1F01 -#define GL_VERSION 0x1F02 -#define GL_EXTENSIONS 0x1F03 -#define GL_NEAREST 0x2600 -#define GL_LINEAR 0x2601 -#define GL_NEAREST_MIPMAP_NEAREST 0x2700 -#define GL_LINEAR_MIPMAP_NEAREST 0x2701 -#define GL_NEAREST_MIPMAP_LINEAR 0x2702 -#define GL_LINEAR_MIPMAP_LINEAR 0x2703 -#define GL_TEXTURE_MAG_FILTER 0x2800 -#define GL_TEXTURE_MIN_FILTER 0x2801 -#define GL_TEXTURE_WRAP_S 0x2802 -#define GL_TEXTURE_WRAP_T 0x2803 -#define GL_REPEAT 0x2901 -#define GL_CURRENT_BIT 0x00000001 -#define GL_POINT_BIT 0x00000002 -#define GL_LINE_BIT 0x00000004 -#define GL_POLYGON_BIT 0x00000008 -#define GL_POLYGON_STIPPLE_BIT 0x00000010 -#define GL_PIXEL_MODE_BIT 0x00000020 -#define GL_LIGHTING_BIT 0x00000040 -#define GL_FOG_BIT 0x00000080 -#define GL_ACCUM_BUFFER_BIT 0x00000200 -#define GL_VIEWPORT_BIT 0x00000800 -#define GL_TRANSFORM_BIT 0x00001000 -#define GL_ENABLE_BIT 0x00002000 -#define GL_HINT_BIT 0x00008000 -#define GL_EVAL_BIT 0x00010000 -#define GL_LIST_BIT 0x00020000 -#define GL_TEXTURE_BIT 0x00040000 -#define GL_SCISSOR_BIT 0x00080000 -#define GL_ALL_ATTRIB_BITS 0xFFFFFFFF -#define GL_QUAD_STRIP 0x0008 -#define GL_POLYGON 0x0009 -#define GL_ACCUM 0x0100 -#define GL_LOAD 0x0101 -#define GL_RETURN 0x0102 -#define GL_MULT 0x0103 -#define GL_ADD 0x0104 -#define GL_AUX0 0x0409 -#define GL_AUX1 0x040A -#define GL_AUX2 0x040B -#define GL_AUX3 0x040C -#define GL_2D 0x0600 -#define GL_3D 0x0601 -#define GL_3D_COLOR 0x0602 -#define GL_3D_COLOR_TEXTURE 0x0603 -#define GL_4D_COLOR_TEXTURE 0x0604 -#define GL_PASS_THROUGH_TOKEN 0x0700 -#define GL_POINT_TOKEN 0x0701 -#define GL_LINE_TOKEN 0x0702 -#define GL_POLYGON_TOKEN 0x0703 -#define GL_BITMAP_TOKEN 0x0704 -#define GL_DRAW_PIXEL_TOKEN 0x0705 -#define GL_COPY_PIXEL_TOKEN 0x0706 -#define GL_LINE_RESET_TOKEN 0x0707 -#define GL_EXP 0x0800 -#define GL_EXP2 0x0801 -#define GL_COEFF 0x0A00 -#define GL_ORDER 0x0A01 -#define GL_DOMAIN 0x0A02 -#define GL_PIXEL_MAP_I_TO_I 0x0C70 -#define GL_PIXEL_MAP_S_TO_S 0x0C71 -#define GL_PIXEL_MAP_I_TO_R 0x0C72 -#define GL_PIXEL_MAP_I_TO_G 0x0C73 -#define GL_PIXEL_MAP_I_TO_B 0x0C74 -#define GL_PIXEL_MAP_I_TO_A 0x0C75 -#define GL_PIXEL_MAP_R_TO_R 0x0C76 -#define GL_PIXEL_MAP_G_TO_G 0x0C77 -#define GL_PIXEL_MAP_B_TO_B 0x0C78 -#define GL_PIXEL_MAP_A_TO_A 0x0C79 -#define GL_CURRENT_COLOR 0x0B00 -#define GL_CURRENT_INDEX 0x0B01 -#define GL_CURRENT_NORMAL 0x0B02 -#define GL_CURRENT_TEXTURE_COORDS 0x0B03 -#define GL_CURRENT_RASTER_COLOR 0x0B04 -#define GL_CURRENT_RASTER_INDEX 0x0B05 -#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 -#define GL_CURRENT_RASTER_POSITION 0x0B07 -#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 -#define GL_CURRENT_RASTER_DISTANCE 0x0B09 -#define GL_POINT_SMOOTH 0x0B10 -#define GL_LINE_STIPPLE 0x0B24 -#define GL_LINE_STIPPLE_PATTERN 0x0B25 -#define GL_LINE_STIPPLE_REPEAT 0x0B26 -#define GL_LIST_MODE 0x0B30 -#define GL_MAX_LIST_NESTING 0x0B31 -#define GL_LIST_BASE 0x0B32 -#define GL_LIST_INDEX 0x0B33 -#define GL_POLYGON_STIPPLE 0x0B42 -#define GL_EDGE_FLAG 0x0B43 -#define GL_LIGHTING 0x0B50 -#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 -#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 -#define GL_LIGHT_MODEL_AMBIENT 0x0B53 -#define GL_SHADE_MODEL 0x0B54 -#define GL_COLOR_MATERIAL_FACE 0x0B55 -#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 -#define GL_COLOR_MATERIAL 0x0B57 -#define GL_FOG 0x0B60 -#define GL_FOG_INDEX 0x0B61 -#define GL_FOG_DENSITY 0x0B62 -#define GL_FOG_START 0x0B63 -#define GL_FOG_END 0x0B64 -#define GL_FOG_MODE 0x0B65 -#define GL_FOG_COLOR 0x0B66 -#define GL_ACCUM_CLEAR_VALUE 0x0B80 -#define GL_MATRIX_MODE 0x0BA0 -#define GL_NORMALIZE 0x0BA1 -#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 -#define GL_PROJECTION_STACK_DEPTH 0x0BA4 -#define GL_TEXTURE_STACK_DEPTH 0x0BA5 -#define GL_MODELVIEW_MATRIX 0x0BA6 -#define GL_PROJECTION_MATRIX 0x0BA7 -#define GL_TEXTURE_MATRIX 0x0BA8 -#define GL_ATTRIB_STACK_DEPTH 0x0BB0 -#define GL_ALPHA_TEST 0x0BC0 -#define GL_ALPHA_TEST_FUNC 0x0BC1 -#define GL_ALPHA_TEST_REF 0x0BC2 -#define GL_LOGIC_OP 0x0BF1 -#define GL_AUX_BUFFERS 0x0C00 -#define GL_INDEX_CLEAR_VALUE 0x0C20 -#define GL_INDEX_WRITEMASK 0x0C21 -#define GL_INDEX_MODE 0x0C30 -#define GL_RGBA_MODE 0x0C31 -#define GL_RENDER_MODE 0x0C40 -#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 -#define GL_POINT_SMOOTH_HINT 0x0C51 -#define GL_FOG_HINT 0x0C54 -#define GL_TEXTURE_GEN_S 0x0C60 -#define GL_TEXTURE_GEN_T 0x0C61 -#define GL_TEXTURE_GEN_R 0x0C62 -#define GL_TEXTURE_GEN_Q 0x0C63 -#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 -#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 -#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 -#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 -#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 -#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 -#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 -#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 -#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 -#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 -#define GL_MAP_COLOR 0x0D10 -#define GL_MAP_STENCIL 0x0D11 -#define GL_INDEX_SHIFT 0x0D12 -#define GL_INDEX_OFFSET 0x0D13 -#define GL_RED_SCALE 0x0D14 -#define GL_RED_BIAS 0x0D15 -#define GL_ZOOM_X 0x0D16 -#define GL_ZOOM_Y 0x0D17 -#define GL_GREEN_SCALE 0x0D18 -#define GL_GREEN_BIAS 0x0D19 -#define GL_BLUE_SCALE 0x0D1A -#define GL_BLUE_BIAS 0x0D1B -#define GL_ALPHA_SCALE 0x0D1C -#define GL_ALPHA_BIAS 0x0D1D -#define GL_DEPTH_SCALE 0x0D1E -#define GL_DEPTH_BIAS 0x0D1F -#define GL_MAX_EVAL_ORDER 0x0D30 -#define GL_MAX_LIGHTS 0x0D31 -#define GL_MAX_CLIP_PLANES 0x0D32 -#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 -#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 -#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 -#define GL_MAX_NAME_STACK_DEPTH 0x0D37 -#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 -#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 -#define GL_INDEX_BITS 0x0D51 -#define GL_RED_BITS 0x0D52 -#define GL_GREEN_BITS 0x0D53 -#define GL_BLUE_BITS 0x0D54 -#define GL_ALPHA_BITS 0x0D55 -#define GL_DEPTH_BITS 0x0D56 -#define GL_STENCIL_BITS 0x0D57 -#define GL_ACCUM_RED_BITS 0x0D58 -#define GL_ACCUM_GREEN_BITS 0x0D59 -#define GL_ACCUM_BLUE_BITS 0x0D5A -#define GL_ACCUM_ALPHA_BITS 0x0D5B -#define GL_NAME_STACK_DEPTH 0x0D70 -#define GL_AUTO_NORMAL 0x0D80 -#define GL_MAP1_COLOR_4 0x0D90 -#define GL_MAP1_INDEX 0x0D91 -#define GL_MAP1_NORMAL 0x0D92 -#define GL_MAP1_TEXTURE_COORD_1 0x0D93 -#define GL_MAP1_TEXTURE_COORD_2 0x0D94 -#define GL_MAP1_TEXTURE_COORD_3 0x0D95 -#define GL_MAP1_TEXTURE_COORD_4 0x0D96 -#define GL_MAP1_VERTEX_3 0x0D97 -#define GL_MAP1_VERTEX_4 0x0D98 -#define GL_MAP2_COLOR_4 0x0DB0 -#define GL_MAP2_INDEX 0x0DB1 -#define GL_MAP2_NORMAL 0x0DB2 -#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 -#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 -#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 -#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 -#define GL_MAP2_VERTEX_3 0x0DB7 -#define GL_MAP2_VERTEX_4 0x0DB8 -#define GL_MAP1_GRID_DOMAIN 0x0DD0 -#define GL_MAP1_GRID_SEGMENTS 0x0DD1 -#define GL_MAP2_GRID_DOMAIN 0x0DD2 -#define GL_MAP2_GRID_SEGMENTS 0x0DD3 -#define GL_TEXTURE_COMPONENTS 0x1003 -#define GL_TEXTURE_BORDER 0x1005 -#define GL_AMBIENT 0x1200 -#define GL_DIFFUSE 0x1201 -#define GL_SPECULAR 0x1202 -#define GL_POSITION 0x1203 -#define GL_SPOT_DIRECTION 0x1204 -#define GL_SPOT_EXPONENT 0x1205 -#define GL_SPOT_CUTOFF 0x1206 -#define GL_CONSTANT_ATTENUATION 0x1207 -#define GL_LINEAR_ATTENUATION 0x1208 -#define GL_QUADRATIC_ATTENUATION 0x1209 -#define GL_COMPILE 0x1300 -#define GL_COMPILE_AND_EXECUTE 0x1301 -#define GL_2_BYTES 0x1407 -#define GL_3_BYTES 0x1408 -#define GL_4_BYTES 0x1409 -#define GL_EMISSION 0x1600 -#define GL_SHININESS 0x1601 -#define GL_AMBIENT_AND_DIFFUSE 0x1602 -#define GL_COLOR_INDEXES 0x1603 -#define GL_MODELVIEW 0x1700 -#define GL_PROJECTION 0x1701 -#define GL_COLOR_INDEX 0x1900 -#define GL_LUMINANCE 0x1909 -#define GL_LUMINANCE_ALPHA 0x190A -#define GL_BITMAP 0x1A00 -#define GL_RENDER 0x1C00 -#define GL_FEEDBACK 0x1C01 -#define GL_SELECT 0x1C02 -#define GL_FLAT 0x1D00 -#define GL_SMOOTH 0x1D01 -#define GL_S 0x2000 -#define GL_T 0x2001 -#define GL_R 0x2002 -#define GL_Q 0x2003 -#define GL_MODULATE 0x2100 -#define GL_DECAL 0x2101 -#define GL_TEXTURE_ENV_MODE 0x2200 -#define GL_TEXTURE_ENV_COLOR 0x2201 -#define GL_TEXTURE_ENV 0x2300 -#define GL_EYE_LINEAR 0x2400 -#define GL_OBJECT_LINEAR 0x2401 -#define GL_SPHERE_MAP 0x2402 -#define GL_TEXTURE_GEN_MODE 0x2500 -#define GL_OBJECT_PLANE 0x2501 -#define GL_EYE_PLANE 0x2502 -#define GL_CLAMP 0x2900 -#define GL_CLIP_PLANE0 0x3000 -#define GL_CLIP_PLANE1 0x3001 -#define GL_CLIP_PLANE2 0x3002 -#define GL_CLIP_PLANE3 0x3003 -#define GL_CLIP_PLANE4 0x3004 -#define GL_CLIP_PLANE5 0x3005 -#define GL_LIGHT0 0x4000 -#define GL_LIGHT1 0x4001 -#define GL_LIGHT2 0x4002 -#define GL_LIGHT3 0x4003 -#define GL_LIGHT4 0x4004 -#define GL_LIGHT5 0x4005 -#define GL_LIGHT6 0x4006 -#define GL_LIGHT7 0x4007 -#define GL_COLOR_LOGIC_OP 0x0BF2 -#define GL_POLYGON_OFFSET_UNITS 0x2A00 -#define GL_POLYGON_OFFSET_POINT 0x2A01 -#define GL_POLYGON_OFFSET_LINE 0x2A02 -#define GL_POLYGON_OFFSET_FILL 0x8037 -#define GL_POLYGON_OFFSET_FACTOR 0x8038 -#define GL_TEXTURE_BINDING_1D 0x8068 -#define GL_TEXTURE_BINDING_2D 0x8069 -#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 -#define GL_TEXTURE_RED_SIZE 0x805C -#define GL_TEXTURE_GREEN_SIZE 0x805D -#define GL_TEXTURE_BLUE_SIZE 0x805E -#define GL_TEXTURE_ALPHA_SIZE 0x805F -#define GL_DOUBLE 0x140A -#define GL_PROXY_TEXTURE_1D 0x8063 -#define GL_PROXY_TEXTURE_2D 0x8064 -#define GL_R3_G3_B2 0x2A10 -#define GL_RGB4 0x804F -#define GL_RGB5 0x8050 -#define GL_RGB8 0x8051 -#define GL_RGB10 0x8052 -#define GL_RGB12 0x8053 -#define GL_RGB16 0x8054 -#define GL_RGBA2 0x8055 -#define GL_RGBA4 0x8056 -#define GL_RGB5_A1 0x8057 -#define GL_RGBA8 0x8058 -#define GL_RGB10_A2 0x8059 -#define GL_RGBA12 0x805A -#define GL_RGBA16 0x805B -#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 -#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 -#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF -#define GL_VERTEX_ARRAY_POINTER 0x808E -#define GL_NORMAL_ARRAY_POINTER 0x808F -#define GL_COLOR_ARRAY_POINTER 0x8090 -#define GL_INDEX_ARRAY_POINTER 0x8091 -#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 -#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 -#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 -#define GL_SELECTION_BUFFER_POINTER 0x0DF3 -#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 -#define GL_INDEX_LOGIC_OP 0x0BF1 -#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B -#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 -#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 -#define GL_SELECTION_BUFFER_SIZE 0x0DF4 -#define GL_VERTEX_ARRAY 0x8074 -#define GL_NORMAL_ARRAY 0x8075 -#define GL_COLOR_ARRAY 0x8076 -#define GL_INDEX_ARRAY 0x8077 -#define GL_TEXTURE_COORD_ARRAY 0x8078 -#define GL_EDGE_FLAG_ARRAY 0x8079 -#define GL_VERTEX_ARRAY_SIZE 0x807A -#define GL_VERTEX_ARRAY_TYPE 0x807B -#define GL_VERTEX_ARRAY_STRIDE 0x807C -#define GL_NORMAL_ARRAY_TYPE 0x807E -#define GL_NORMAL_ARRAY_STRIDE 0x807F -#define GL_COLOR_ARRAY_SIZE 0x8081 -#define GL_COLOR_ARRAY_TYPE 0x8082 -#define GL_COLOR_ARRAY_STRIDE 0x8083 -#define GL_INDEX_ARRAY_TYPE 0x8085 -#define GL_INDEX_ARRAY_STRIDE 0x8086 -#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 -#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 -#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A -#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C -#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 -#define GL_TEXTURE_INTENSITY_SIZE 0x8061 -#define GL_TEXTURE_PRIORITY 0x8066 -#define GL_TEXTURE_RESIDENT 0x8067 -#define GL_ALPHA4 0x803B -#define GL_ALPHA8 0x803C -#define GL_ALPHA12 0x803D -#define GL_ALPHA16 0x803E -#define GL_LUMINANCE4 0x803F -#define GL_LUMINANCE8 0x8040 -#define GL_LUMINANCE12 0x8041 -#define GL_LUMINANCE16 0x8042 -#define GL_LUMINANCE4_ALPHA4 0x8043 -#define GL_LUMINANCE6_ALPHA2 0x8044 -#define GL_LUMINANCE8_ALPHA8 0x8045 -#define GL_LUMINANCE12_ALPHA4 0x8046 -#define GL_LUMINANCE12_ALPHA12 0x8047 -#define GL_LUMINANCE16_ALPHA16 0x8048 -#define GL_INTENSITY 0x8049 -#define GL_INTENSITY4 0x804A -#define GL_INTENSITY8 0x804B -#define GL_INTENSITY12 0x804C -#define GL_INTENSITY16 0x804D -#define GL_V2F 0x2A20 -#define GL_V3F 0x2A21 -#define GL_C4UB_V2F 0x2A22 -#define GL_C4UB_V3F 0x2A23 -#define GL_C3F_V3F 0x2A24 -#define GL_N3F_V3F 0x2A25 -#define GL_C4F_N3F_V3F 0x2A26 -#define GL_T2F_V3F 0x2A27 -#define GL_T4F_V4F 0x2A28 -#define GL_T2F_C4UB_V3F 0x2A29 -#define GL_T2F_C3F_V3F 0x2A2A -#define GL_T2F_N3F_V3F 0x2A2B -#define GL_T2F_C4F_N3F_V3F 0x2A2C -#define GL_T4F_C4F_N3F_V4F 0x2A2D -#define GL_UNSIGNED_BYTE_3_3_2 0x8032 -#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 -#define GL_UNSIGNED_INT_8_8_8_8 0x8035 -#define GL_UNSIGNED_INT_10_10_10_2 0x8036 -#define GL_TEXTURE_BINDING_3D 0x806A -#define GL_PACK_SKIP_IMAGES 0x806B -#define GL_PACK_IMAGE_HEIGHT 0x806C -#define GL_UNPACK_SKIP_IMAGES 0x806D -#define GL_UNPACK_IMAGE_HEIGHT 0x806E -#define GL_TEXTURE_3D 0x806F -#define GL_PROXY_TEXTURE_3D 0x8070 -#define GL_TEXTURE_DEPTH 0x8071 -#define GL_TEXTURE_WRAP_R 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE 0x8073 -#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 -#define GL_UNSIGNED_SHORT_5_6_5 0x8363 -#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 -#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 -#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 -#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 -#define GL_BGR 0x80E0 -#define GL_BGRA 0x80E1 -#define GL_MAX_ELEMENTS_VERTICES 0x80E8 -#define GL_MAX_ELEMENTS_INDICES 0x80E9 -#define GL_CLAMP_TO_EDGE 0x812F -#define GL_TEXTURE_MIN_LOD 0x813A -#define GL_TEXTURE_MAX_LOD 0x813B -#define GL_TEXTURE_BASE_LEVEL 0x813C -#define GL_TEXTURE_MAX_LEVEL 0x813D -#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 -#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 -#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E -#define GL_RESCALE_NORMAL 0x803A -#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 -#define GL_SINGLE_COLOR 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR 0x81FA -#define GL_ALIASED_POINT_SIZE_RANGE 0x846D -#define GL_TEXTURE0 0x84C0 -#define GL_TEXTURE1 0x84C1 -#define GL_TEXTURE2 0x84C2 -#define GL_TEXTURE3 0x84C3 -#define GL_TEXTURE4 0x84C4 -#define GL_TEXTURE5 0x84C5 -#define GL_TEXTURE6 0x84C6 -#define GL_TEXTURE7 0x84C7 -#define GL_TEXTURE8 0x84C8 -#define GL_TEXTURE9 0x84C9 -#define GL_TEXTURE10 0x84CA -#define GL_TEXTURE11 0x84CB -#define GL_TEXTURE12 0x84CC -#define GL_TEXTURE13 0x84CD -#define GL_TEXTURE14 0x84CE -#define GL_TEXTURE15 0x84CF -#define GL_TEXTURE16 0x84D0 -#define GL_TEXTURE17 0x84D1 -#define GL_TEXTURE18 0x84D2 -#define GL_TEXTURE19 0x84D3 -#define GL_TEXTURE20 0x84D4 -#define GL_TEXTURE21 0x84D5 -#define GL_TEXTURE22 0x84D6 -#define GL_TEXTURE23 0x84D7 -#define GL_TEXTURE24 0x84D8 -#define GL_TEXTURE25 0x84D9 -#define GL_TEXTURE26 0x84DA -#define GL_TEXTURE27 0x84DB -#define GL_TEXTURE28 0x84DC -#define GL_TEXTURE29 0x84DD -#define GL_TEXTURE30 0x84DE -#define GL_TEXTURE31 0x84DF -#define GL_ACTIVE_TEXTURE 0x84E0 -#define GL_MULTISAMPLE 0x809D -#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE 0x809F -#define GL_SAMPLE_COVERAGE 0x80A0 -#define GL_SAMPLE_BUFFERS 0x80A8 -#define GL_SAMPLES 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT 0x80AB -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C -#define GL_COMPRESSED_RGB 0x84ED -#define GL_COMPRESSED_RGBA 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT 0x84EF -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 -#define GL_TEXTURE_COMPRESSED 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 -#define GL_CLAMP_TO_BORDER 0x812D -#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 -#define GL_MAX_TEXTURE_UNITS 0x84E2 -#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 -#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 -#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 -#define GL_MULTISAMPLE_BIT 0x20000000 -#define GL_NORMAL_MAP 0x8511 -#define GL_REFLECTION_MAP 0x8512 -#define GL_COMPRESSED_ALPHA 0x84E9 -#define GL_COMPRESSED_LUMINANCE 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB -#define GL_COMPRESSED_INTENSITY 0x84EC -#define GL_COMBINE 0x8570 -#define GL_COMBINE_RGB 0x8571 -#define GL_COMBINE_ALPHA 0x8572 -#define GL_SOURCE0_RGB 0x8580 -#define GL_SOURCE1_RGB 0x8581 -#define GL_SOURCE2_RGB 0x8582 -#define GL_SOURCE0_ALPHA 0x8588 -#define GL_SOURCE1_ALPHA 0x8589 -#define GL_SOURCE2_ALPHA 0x858A -#define GL_OPERAND0_RGB 0x8590 -#define GL_OPERAND1_RGB 0x8591 -#define GL_OPERAND2_RGB 0x8592 -#define GL_OPERAND0_ALPHA 0x8598 -#define GL_OPERAND1_ALPHA 0x8599 -#define GL_OPERAND2_ALPHA 0x859A -#define GL_RGB_SCALE 0x8573 -#define GL_ADD_SIGNED 0x8574 -#define GL_INTERPOLATE 0x8575 -#define GL_SUBTRACT 0x84E7 -#define GL_CONSTANT 0x8576 -#define GL_PRIMARY_COLOR 0x8577 -#define GL_PREVIOUS 0x8578 -#define GL_DOT3_RGB 0x86AE -#define GL_DOT3_RGBA 0x86AF -#define GL_BLEND_DST_RGB 0x80C8 -#define GL_BLEND_SRC_RGB 0x80C9 -#define GL_BLEND_DST_ALPHA 0x80CA -#define GL_BLEND_SRC_ALPHA 0x80CB -#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 -#define GL_DEPTH_COMPONENT16 0x81A5 -#define GL_DEPTH_COMPONENT24 0x81A6 -#define GL_DEPTH_COMPONENT32 0x81A7 -#define GL_MIRRORED_REPEAT 0x8370 -#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD -#define GL_TEXTURE_LOD_BIAS 0x8501 -#define GL_INCR_WRAP 0x8507 -#define GL_DECR_WRAP 0x8508 -#define GL_TEXTURE_DEPTH_SIZE 0x884A -#define GL_TEXTURE_COMPARE_MODE 0x884C -#define GL_TEXTURE_COMPARE_FUNC 0x884D -#define GL_POINT_SIZE_MIN 0x8126 -#define GL_POINT_SIZE_MAX 0x8127 -#define GL_POINT_DISTANCE_ATTENUATION 0x8129 -#define GL_GENERATE_MIPMAP 0x8191 -#define GL_GENERATE_MIPMAP_HINT 0x8192 -#define GL_FOG_COORDINATE_SOURCE 0x8450 -#define GL_FOG_COORDINATE 0x8451 -#define GL_FRAGMENT_DEPTH 0x8452 -#define GL_CURRENT_FOG_COORDINATE 0x8453 -#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 -#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 -#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 -#define GL_FOG_COORDINATE_ARRAY 0x8457 -#define GL_COLOR_SUM 0x8458 -#define GL_CURRENT_SECONDARY_COLOR 0x8459 -#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A -#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B -#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C -#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D -#define GL_SECONDARY_COLOR_ARRAY 0x845E -#define GL_TEXTURE_FILTER_CONTROL 0x8500 -#define GL_DEPTH_TEXTURE_MODE 0x884B -#define GL_COMPARE_R_TO_TEXTURE 0x884E -#define GL_BLEND_COLOR 0x8005 -#define GL_BLEND_EQUATION 0x8009 -#define GL_CONSTANT_COLOR 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 -#define GL_CONSTANT_ALPHA 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 -#define GL_FUNC_ADD 0x8006 -#define GL_FUNC_REVERSE_SUBTRACT 0x800B -#define GL_FUNC_SUBTRACT 0x800A -#define GL_MIN 0x8007 -#define GL_MAX 0x8008 -#define GL_BUFFER_SIZE 0x8764 -#define GL_BUFFER_USAGE 0x8765 -#define GL_QUERY_COUNTER_BITS 0x8864 -#define GL_CURRENT_QUERY 0x8865 -#define GL_QUERY_RESULT 0x8866 -#define GL_QUERY_RESULT_AVAILABLE 0x8867 -#define GL_ARRAY_BUFFER 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#define GL_ARRAY_BUFFER_BINDING 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F -#define GL_READ_ONLY 0x88B8 -#define GL_WRITE_ONLY 0x88B9 -#define GL_READ_WRITE 0x88BA -#define GL_BUFFER_ACCESS 0x88BB -#define GL_BUFFER_MAPPED 0x88BC -#define GL_BUFFER_MAP_POINTER 0x88BD -#define GL_STREAM_DRAW 0x88E0 -#define GL_STREAM_READ 0x88E1 -#define GL_STREAM_COPY 0x88E2 -#define GL_STATIC_DRAW 0x88E4 -#define GL_STATIC_READ 0x88E5 -#define GL_STATIC_COPY 0x88E6 -#define GL_DYNAMIC_DRAW 0x88E8 -#define GL_DYNAMIC_READ 0x88E9 -#define GL_DYNAMIC_COPY 0x88EA -#define GL_SAMPLES_PASSED 0x8914 -#define GL_SRC1_ALPHA 0x8589 -#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 -#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 -#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 -#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D -#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E -#define GL_FOG_COORD_SRC 0x8450 -#define GL_FOG_COORD 0x8451 -#define GL_CURRENT_FOG_COORD 0x8453 -#define GL_FOG_COORD_ARRAY_TYPE 0x8454 -#define GL_FOG_COORD_ARRAY_STRIDE 0x8455 -#define GL_FOG_COORD_ARRAY_POINTER 0x8456 -#define GL_FOG_COORD_ARRAY 0x8457 -#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D -#define GL_SRC0_RGB 0x8580 -#define GL_SRC1_RGB 0x8581 -#define GL_SRC2_RGB 0x8582 -#define GL_SRC0_ALPHA 0x8588 -#define GL_SRC2_ALPHA 0x858A -#define GL_BLEND_EQUATION_RGB 0x8009 -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 -#define GL_CURRENT_VERTEX_ATTRIB 0x8626 -#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 -#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 -#define GL_STENCIL_BACK_FUNC 0x8800 -#define GL_STENCIL_BACK_FAIL 0x8801 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 -#define GL_MAX_DRAW_BUFFERS 0x8824 -#define GL_DRAW_BUFFER0 0x8825 -#define GL_DRAW_BUFFER1 0x8826 -#define GL_DRAW_BUFFER2 0x8827 -#define GL_DRAW_BUFFER3 0x8828 -#define GL_DRAW_BUFFER4 0x8829 -#define GL_DRAW_BUFFER5 0x882A -#define GL_DRAW_BUFFER6 0x882B -#define GL_DRAW_BUFFER7 0x882C -#define GL_DRAW_BUFFER8 0x882D -#define GL_DRAW_BUFFER9 0x882E -#define GL_DRAW_BUFFER10 0x882F -#define GL_DRAW_BUFFER11 0x8830 -#define GL_DRAW_BUFFER12 0x8831 -#define GL_DRAW_BUFFER13 0x8832 -#define GL_DRAW_BUFFER14 0x8833 -#define GL_DRAW_BUFFER15 0x8834 -#define GL_BLEND_EQUATION_ALPHA 0x883D -#define GL_MAX_VERTEX_ATTRIBS 0x8869 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A -#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 -#define GL_FRAGMENT_SHADER 0x8B30 -#define GL_VERTEX_SHADER 0x8B31 -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A -#define GL_MAX_VARYING_FLOATS 0x8B4B -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D -#define GL_SHADER_TYPE 0x8B4F -#define GL_FLOAT_VEC2 0x8B50 -#define GL_FLOAT_VEC3 0x8B51 -#define GL_FLOAT_VEC4 0x8B52 -#define GL_INT_VEC2 0x8B53 -#define GL_INT_VEC3 0x8B54 -#define GL_INT_VEC4 0x8B55 -#define GL_BOOL 0x8B56 -#define GL_BOOL_VEC2 0x8B57 -#define GL_BOOL_VEC3 0x8B58 -#define GL_BOOL_VEC4 0x8B59 -#define GL_FLOAT_MAT2 0x8B5A -#define GL_FLOAT_MAT3 0x8B5B -#define GL_FLOAT_MAT4 0x8B5C -#define GL_SAMPLER_1D 0x8B5D -#define GL_SAMPLER_2D 0x8B5E -#define GL_SAMPLER_3D 0x8B5F -#define GL_SAMPLER_CUBE 0x8B60 -#define GL_SAMPLER_1D_SHADOW 0x8B61 -#define GL_SAMPLER_2D_SHADOW 0x8B62 -#define GL_DELETE_STATUS 0x8B80 -#define GL_COMPILE_STATUS 0x8B81 -#define GL_LINK_STATUS 0x8B82 -#define GL_VALIDATE_STATUS 0x8B83 -#define GL_INFO_LOG_LENGTH 0x8B84 -#define GL_ATTACHED_SHADERS 0x8B85 -#define GL_ACTIVE_UNIFORMS 0x8B86 -#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 -#define GL_SHADER_SOURCE_LENGTH 0x8B88 -#define GL_ACTIVE_ATTRIBUTES 0x8B89 -#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B -#define GL_SHADING_LANGUAGE_VERSION 0x8B8C -#define GL_CURRENT_PROGRAM 0x8B8D -#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 -#define GL_LOWER_LEFT 0x8CA1 -#define GL_UPPER_LEFT 0x8CA2 -#define GL_STENCIL_BACK_REF 0x8CA3 -#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 -#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 -#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 -#define GL_POINT_SPRITE 0x8861 -#define GL_COORD_REPLACE 0x8862 -#define GL_MAX_TEXTURE_COORDS 0x8871 -#define GL_PIXEL_PACK_BUFFER 0x88EB -#define GL_PIXEL_UNPACK_BUFFER 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF -#define GL_FLOAT_MAT2x3 0x8B65 -#define GL_FLOAT_MAT2x4 0x8B66 -#define GL_FLOAT_MAT3x2 0x8B67 -#define GL_FLOAT_MAT3x4 0x8B68 -#define GL_FLOAT_MAT4x2 0x8B69 -#define GL_FLOAT_MAT4x3 0x8B6A -#define GL_SRGB 0x8C40 -#define GL_SRGB8 0x8C41 -#define GL_SRGB_ALPHA 0x8C42 -#define GL_SRGB8_ALPHA8 0x8C43 -#define GL_COMPRESSED_SRGB 0x8C48 -#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 -#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F -#define GL_SLUMINANCE_ALPHA 0x8C44 -#define GL_SLUMINANCE8_ALPHA8 0x8C45 -#define GL_SLUMINANCE 0x8C46 -#define GL_SLUMINANCE8 0x8C47 -#define GL_COMPRESSED_SLUMINANCE 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B -#define GL_COMPARE_REF_TO_TEXTURE 0x884E -#define GL_CLIP_DISTANCE0 0x3000 -#define GL_CLIP_DISTANCE1 0x3001 -#define GL_CLIP_DISTANCE2 0x3002 -#define GL_CLIP_DISTANCE3 0x3003 -#define GL_CLIP_DISTANCE4 0x3004 -#define GL_CLIP_DISTANCE5 0x3005 -#define GL_CLIP_DISTANCE6 0x3006 -#define GL_CLIP_DISTANCE7 0x3007 -#define GL_MAX_CLIP_DISTANCES 0x0D32 -#define GL_MAJOR_VERSION 0x821B -#define GL_MINOR_VERSION 0x821C -#define GL_NUM_EXTENSIONS 0x821D -#define GL_CONTEXT_FLAGS 0x821E -#define GL_COMPRESSED_RED 0x8225 -#define GL_COMPRESSED_RG 0x8226 -#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 -#define GL_RGBA32F 0x8814 -#define GL_RGB32F 0x8815 -#define GL_RGBA16F 0x881A -#define GL_RGB16F 0x881B -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD -#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF -#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 -#define GL_CLAMP_READ_COLOR 0x891C -#define GL_FIXED_ONLY 0x891D -#define GL_MAX_VARYING_COMPONENTS 0x8B4B -#define GL_TEXTURE_1D_ARRAY 0x8C18 -#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 -#define GL_TEXTURE_2D_ARRAY 0x8C1A -#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B -#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C -#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D -#define GL_R11F_G11F_B10F 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B -#define GL_RGB9_E5 0x8C3D -#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E -#define GL_TEXTURE_SHARED_SIZE 0x8C3F -#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 -#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 -#define GL_PRIMITIVES_GENERATED 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 -#define GL_RASTERIZER_DISCARD 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B -#define GL_INTERLEAVED_ATTRIBS 0x8C8C -#define GL_SEPARATE_ATTRIBS 0x8C8D -#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F -#define GL_RGBA32UI 0x8D70 -#define GL_RGB32UI 0x8D71 -#define GL_RGBA16UI 0x8D76 -#define GL_RGB16UI 0x8D77 -#define GL_RGBA8UI 0x8D7C -#define GL_RGB8UI 0x8D7D -#define GL_RGBA32I 0x8D82 -#define GL_RGB32I 0x8D83 -#define GL_RGBA16I 0x8D88 -#define GL_RGB16I 0x8D89 -#define GL_RGBA8I 0x8D8E -#define GL_RGB8I 0x8D8F -#define GL_RED_INTEGER 0x8D94 -#define GL_GREEN_INTEGER 0x8D95 -#define GL_BLUE_INTEGER 0x8D96 -#define GL_RGB_INTEGER 0x8D98 -#define GL_RGBA_INTEGER 0x8D99 -#define GL_BGR_INTEGER 0x8D9A -#define GL_BGRA_INTEGER 0x8D9B -#define GL_SAMPLER_1D_ARRAY 0x8DC0 -#define GL_SAMPLER_2D_ARRAY 0x8DC1 -#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 -#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 -#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 -#define GL_UNSIGNED_INT_VEC2 0x8DC6 -#define GL_UNSIGNED_INT_VEC3 0x8DC7 -#define GL_UNSIGNED_INT_VEC4 0x8DC8 -#define GL_INT_SAMPLER_1D 0x8DC9 -#define GL_INT_SAMPLER_2D 0x8DCA -#define GL_INT_SAMPLER_3D 0x8DCB -#define GL_INT_SAMPLER_CUBE 0x8DCC -#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE -#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF -#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 -#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 -#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 -#define GL_QUERY_WAIT 0x8E13 -#define GL_QUERY_NO_WAIT 0x8E14 -#define GL_QUERY_BY_REGION_WAIT 0x8E15 -#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 -#define GL_BUFFER_ACCESS_FLAGS 0x911F -#define GL_BUFFER_MAP_LENGTH 0x9120 -#define GL_BUFFER_MAP_OFFSET 0x9121 -#define GL_DEPTH_COMPONENT32F 0x8CAC -#define GL_DEPTH32F_STENCIL8 0x8CAD -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD -#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 -#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 -#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 -#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 -#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 -#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 -#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 -#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 -#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 -#define GL_FRAMEBUFFER_DEFAULT 0x8218 -#define GL_FRAMEBUFFER_UNDEFINED 0x8219 -#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A -#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 -#define GL_DEPTH_STENCIL 0x84F9 -#define GL_UNSIGNED_INT_24_8 0x84FA -#define GL_DEPTH24_STENCIL8 0x88F0 -#define GL_TEXTURE_STENCIL_SIZE 0x88F1 -#define GL_TEXTURE_RED_TYPE 0x8C10 -#define GL_TEXTURE_GREEN_TYPE 0x8C11 -#define GL_TEXTURE_BLUE_TYPE 0x8C12 -#define GL_TEXTURE_ALPHA_TYPE 0x8C13 -#define GL_TEXTURE_DEPTH_TYPE 0x8C16 -#define GL_UNSIGNED_NORMALIZED 0x8C17 -#define GL_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_RENDERBUFFER_BINDING 0x8CA7 -#define GL_READ_FRAMEBUFFER 0x8CA8 -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA -#define GL_RENDERBUFFER_SAMPLES 0x8CAB -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC -#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD -#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#define GL_COLOR_ATTACHMENT1 0x8CE1 -#define GL_COLOR_ATTACHMENT2 0x8CE2 -#define GL_COLOR_ATTACHMENT3 0x8CE3 -#define GL_COLOR_ATTACHMENT4 0x8CE4 -#define GL_COLOR_ATTACHMENT5 0x8CE5 -#define GL_COLOR_ATTACHMENT6 0x8CE6 -#define GL_COLOR_ATTACHMENT7 0x8CE7 -#define GL_COLOR_ATTACHMENT8 0x8CE8 -#define GL_COLOR_ATTACHMENT9 0x8CE9 -#define GL_COLOR_ATTACHMENT10 0x8CEA -#define GL_COLOR_ATTACHMENT11 0x8CEB -#define GL_COLOR_ATTACHMENT12 0x8CEC -#define GL_COLOR_ATTACHMENT13 0x8CED -#define GL_COLOR_ATTACHMENT14 0x8CEE -#define GL_COLOR_ATTACHMENT15 0x8CEF -#define GL_COLOR_ATTACHMENT16 0x8CF0 -#define GL_COLOR_ATTACHMENT17 0x8CF1 -#define GL_COLOR_ATTACHMENT18 0x8CF2 -#define GL_COLOR_ATTACHMENT19 0x8CF3 -#define GL_COLOR_ATTACHMENT20 0x8CF4 -#define GL_COLOR_ATTACHMENT21 0x8CF5 -#define GL_COLOR_ATTACHMENT22 0x8CF6 -#define GL_COLOR_ATTACHMENT23 0x8CF7 -#define GL_COLOR_ATTACHMENT24 0x8CF8 -#define GL_COLOR_ATTACHMENT25 0x8CF9 -#define GL_COLOR_ATTACHMENT26 0x8CFA -#define GL_COLOR_ATTACHMENT27 0x8CFB -#define GL_COLOR_ATTACHMENT28 0x8CFC -#define GL_COLOR_ATTACHMENT29 0x8CFD -#define GL_COLOR_ATTACHMENT30 0x8CFE -#define GL_COLOR_ATTACHMENT31 0x8CFF -#define GL_DEPTH_ATTACHMENT 0x8D00 -#define GL_STENCIL_ATTACHMENT 0x8D20 -#define GL_FRAMEBUFFER 0x8D40 -#define GL_RENDERBUFFER 0x8D41 -#define GL_RENDERBUFFER_WIDTH 0x8D42 -#define GL_RENDERBUFFER_HEIGHT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 -#define GL_STENCIL_INDEX1 0x8D46 -#define GL_STENCIL_INDEX4 0x8D47 -#define GL_STENCIL_INDEX8 0x8D48 -#define GL_STENCIL_INDEX16 0x8D49 -#define GL_RENDERBUFFER_RED_SIZE 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 -#define GL_MAX_SAMPLES 0x8D57 -#define GL_INDEX 0x8222 -#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 -#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 -#define GL_FRAMEBUFFER_SRGB 0x8DB9 -#define GL_HALF_FLOAT 0x140B -#define GL_MAP_READ_BIT 0x0001 -#define GL_MAP_WRITE_BIT 0x0002 -#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 -#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 -#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 -#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 -#define GL_COMPRESSED_RED_RGTC1 0x8DBB -#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC -#define GL_COMPRESSED_RG_RGTC2 0x8DBD -#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE -#define GL_RG 0x8227 -#define GL_RG_INTEGER 0x8228 -#define GL_R8 0x8229 -#define GL_R16 0x822A -#define GL_RG8 0x822B -#define GL_RG16 0x822C -#define GL_R16F 0x822D -#define GL_R32F 0x822E -#define GL_RG16F 0x822F -#define GL_RG32F 0x8230 -#define GL_R8I 0x8231 -#define GL_R8UI 0x8232 -#define GL_R16I 0x8233 -#define GL_R16UI 0x8234 -#define GL_R32I 0x8235 -#define GL_R32UI 0x8236 -#define GL_RG8I 0x8237 -#define GL_RG8UI 0x8238 -#define GL_RG16I 0x8239 -#define GL_RG16UI 0x823A -#define GL_RG32I 0x823B -#define GL_RG32UI 0x823C -#define GL_VERTEX_ARRAY_BINDING 0x85B5 -#define GL_CLAMP_VERTEX_COLOR 0x891A -#define GL_CLAMP_FRAGMENT_COLOR 0x891B -#define GL_ALPHA_INTEGER 0x8D97 -#define GL_SAMPLER_2D_RECT 0x8B63 -#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 -#define GL_SAMPLER_BUFFER 0x8DC2 -#define GL_INT_SAMPLER_2D_RECT 0x8DCD -#define GL_INT_SAMPLER_BUFFER 0x8DD0 -#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 -#define GL_TEXTURE_BUFFER 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D -#define GL_TEXTURE_RECTANGLE 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 -#define GL_R8_SNORM 0x8F94 -#define GL_RG8_SNORM 0x8F95 -#define GL_RGB8_SNORM 0x8F96 -#define GL_RGBA8_SNORM 0x8F97 -#define GL_R16_SNORM 0x8F98 -#define GL_RG16_SNORM 0x8F99 -#define GL_RGB16_SNORM 0x8F9A -#define GL_RGBA16_SNORM 0x8F9B -#define GL_SIGNED_NORMALIZED 0x8F9C -#define GL_PRIMITIVE_RESTART 0x8F9D -#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E -#define GL_COPY_READ_BUFFER 0x8F36 -#define GL_COPY_WRITE_BUFFER 0x8F37 -#define GL_UNIFORM_BUFFER 0x8A11 -#define GL_UNIFORM_BUFFER_BINDING 0x8A28 -#define GL_UNIFORM_BUFFER_START 0x8A29 -#define GL_UNIFORM_BUFFER_SIZE 0x8A2A -#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B -#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C -#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D -#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E -#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F -#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 -#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 -#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 -#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 -#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 -#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 -#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 -#define GL_UNIFORM_TYPE 0x8A37 -#define GL_UNIFORM_SIZE 0x8A38 -#define GL_UNIFORM_NAME_LENGTH 0x8A39 -#define GL_UNIFORM_BLOCK_INDEX 0x8A3A -#define GL_UNIFORM_OFFSET 0x8A3B -#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C -#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D -#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E -#define GL_UNIFORM_BLOCK_BINDING 0x8A3F -#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 -#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 -#define GL_INVALID_INDEX 0xFFFFFFFF -#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 -#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 -#define GL_LINES_ADJACENCY 0x000A -#define GL_LINE_STRIP_ADJACENCY 0x000B -#define GL_TRIANGLES_ADJACENCY 0x000C -#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D -#define GL_PROGRAM_POINT_SIZE 0x8642 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 -#define GL_GEOMETRY_SHADER 0x8DD9 -#define GL_GEOMETRY_VERTICES_OUT 0x8916 -#define GL_GEOMETRY_INPUT_TYPE 0x8917 -#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 -#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 -#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 -#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 -#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 -#define GL_CONTEXT_PROFILE_MASK 0x9126 -#define GL_DEPTH_CLAMP 0x864F -#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C -#define GL_FIRST_VERTEX_CONVENTION 0x8E4D -#define GL_LAST_VERTEX_CONVENTION 0x8E4E -#define GL_PROVOKING_VERTEX 0x8E4F -#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F -#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 -#define GL_OBJECT_TYPE 0x9112 -#define GL_SYNC_CONDITION 0x9113 -#define GL_SYNC_STATUS 0x9114 -#define GL_SYNC_FLAGS 0x9115 -#define GL_SYNC_FENCE 0x9116 -#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 -#define GL_UNSIGNALED 0x9118 -#define GL_SIGNALED 0x9119 -#define GL_ALREADY_SIGNALED 0x911A -#define GL_TIMEOUT_EXPIRED 0x911B -#define GL_CONDITION_SATISFIED 0x911C -#define GL_WAIT_FAILED 0x911D -#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF -#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 -#define GL_SAMPLE_POSITION 0x8E50 -#define GL_SAMPLE_MASK 0x8E51 -#define GL_SAMPLE_MASK_VALUE 0x8E52 -#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 -#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 -#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 -#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 -#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 -#define GL_TEXTURE_SAMPLES 0x9106 -#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 -#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 -#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A -#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B -#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D -#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E -#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F -#define GL_MAX_INTEGER_SAMPLES 0x9110 -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE -#define GL_SRC1_COLOR 0x88F9 -#define GL_ONE_MINUS_SRC1_COLOR 0x88FA -#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB -#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC -#define GL_ANY_SAMPLES_PASSED 0x8C2F -#define GL_SAMPLER_BINDING 0x8919 -#define GL_RGB10_A2UI 0x906F -#define GL_TEXTURE_SWIZZLE_R 0x8E42 -#define GL_TEXTURE_SWIZZLE_G 0x8E43 -#define GL_TEXTURE_SWIZZLE_B 0x8E44 -#define GL_TEXTURE_SWIZZLE_A 0x8E45 -#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 -#define GL_TIME_ELAPSED 0x88BF -#define GL_TIMESTAMP 0x8E28 -#define GL_INT_2_10_10_10_REV 0x8D9F -#ifndef GL_VERSION_1_0 -#define GL_VERSION_1_0 1 -GLAPI int GLAD_GL_VERSION_1_0; -typedef void (APIENTRYP PFNGLCULLFACEPROC)(GLenum mode); -GLAPI PFNGLCULLFACEPROC glad_glCullFace; -#define glCullFace glad_glCullFace -typedef void (APIENTRYP PFNGLFRONTFACEPROC)(GLenum mode); -GLAPI PFNGLFRONTFACEPROC glad_glFrontFace; -#define glFrontFace glad_glFrontFace -typedef void (APIENTRYP PFNGLHINTPROC)(GLenum target, GLenum mode); -GLAPI PFNGLHINTPROC glad_glHint; -#define glHint glad_glHint -typedef void (APIENTRYP PFNGLLINEWIDTHPROC)(GLfloat width); -GLAPI PFNGLLINEWIDTHPROC glad_glLineWidth; -#define glLineWidth glad_glLineWidth -typedef void (APIENTRYP PFNGLPOINTSIZEPROC)(GLfloat size); -GLAPI PFNGLPOINTSIZEPROC glad_glPointSize; -#define glPointSize glad_glPointSize -typedef void (APIENTRYP PFNGLPOLYGONMODEPROC)(GLenum face, GLenum mode); -GLAPI PFNGLPOLYGONMODEPROC glad_glPolygonMode; -#define glPolygonMode glad_glPolygonMode -typedef void (APIENTRYP PFNGLSCISSORPROC)(GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI PFNGLSCISSORPROC glad_glScissor; -#define glScissor glad_glScissor -typedef void (APIENTRYP PFNGLTEXPARAMETERFPROC)(GLenum target, GLenum pname, GLfloat param); -GLAPI PFNGLTEXPARAMETERFPROC glad_glTexParameterf; -#define glTexParameterf glad_glTexParameterf -typedef void (APIENTRYP PFNGLTEXPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat *params); -GLAPI PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; -#define glTexParameterfv glad_glTexParameterfv -typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); -GLAPI PFNGLTEXPARAMETERIPROC glad_glTexParameteri; -#define glTexParameteri glad_glTexParameteri -typedef void (APIENTRYP PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint *params); -GLAPI PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; -#define glTexParameteriv glad_glTexParameteriv -typedef void (APIENTRYP PFNGLTEXIMAGE1DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI PFNGLTEXIMAGE1DPROC glad_glTexImage1D; -#define glTexImage1D glad_glTexImage1D -typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI PFNGLTEXIMAGE2DPROC glad_glTexImage2D; -#define glTexImage2D glad_glTexImage2D -typedef void (APIENTRYP PFNGLDRAWBUFFERPROC)(GLenum buf); -GLAPI PFNGLDRAWBUFFERPROC glad_glDrawBuffer; -#define glDrawBuffer glad_glDrawBuffer -typedef void (APIENTRYP PFNGLCLEARPROC)(GLbitfield mask); -GLAPI PFNGLCLEARPROC glad_glClear; -#define glClear glad_glClear -typedef void (APIENTRYP PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -GLAPI PFNGLCLEARCOLORPROC glad_glClearColor; -#define glClearColor glad_glClearColor -typedef void (APIENTRYP PFNGLCLEARSTENCILPROC)(GLint s); -GLAPI PFNGLCLEARSTENCILPROC glad_glClearStencil; -#define glClearStencil glad_glClearStencil -typedef void (APIENTRYP PFNGLCLEARDEPTHPROC)(GLdouble depth); -GLAPI PFNGLCLEARDEPTHPROC glad_glClearDepth; -#define glClearDepth glad_glClearDepth -typedef void (APIENTRYP PFNGLSTENCILMASKPROC)(GLuint mask); -GLAPI PFNGLSTENCILMASKPROC glad_glStencilMask; -#define glStencilMask glad_glStencilMask -typedef void (APIENTRYP PFNGLCOLORMASKPROC)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -GLAPI PFNGLCOLORMASKPROC glad_glColorMask; -#define glColorMask glad_glColorMask -typedef void (APIENTRYP PFNGLDEPTHMASKPROC)(GLboolean flag); -GLAPI PFNGLDEPTHMASKPROC glad_glDepthMask; -#define glDepthMask glad_glDepthMask -typedef void (APIENTRYP PFNGLDISABLEPROC)(GLenum cap); -GLAPI PFNGLDISABLEPROC glad_glDisable; -#define glDisable glad_glDisable -typedef void (APIENTRYP PFNGLENABLEPROC)(GLenum cap); -GLAPI PFNGLENABLEPROC glad_glEnable; -#define glEnable glad_glEnable -typedef void (APIENTRYP PFNGLFINISHPROC)(void); -GLAPI PFNGLFINISHPROC glad_glFinish; -#define glFinish glad_glFinish -typedef void (APIENTRYP PFNGLFLUSHPROC)(void); -GLAPI PFNGLFLUSHPROC glad_glFlush; -#define glFlush glad_glFlush -typedef void (APIENTRYP PFNGLBLENDFUNCPROC)(GLenum sfactor, GLenum dfactor); -GLAPI PFNGLBLENDFUNCPROC glad_glBlendFunc; -#define glBlendFunc glad_glBlendFunc -typedef void (APIENTRYP PFNGLLOGICOPPROC)(GLenum opcode); -GLAPI PFNGLLOGICOPPROC glad_glLogicOp; -#define glLogicOp glad_glLogicOp -typedef void (APIENTRYP PFNGLSTENCILFUNCPROC)(GLenum func, GLint ref, GLuint mask); -GLAPI PFNGLSTENCILFUNCPROC glad_glStencilFunc; -#define glStencilFunc glad_glStencilFunc -typedef void (APIENTRYP PFNGLSTENCILOPPROC)(GLenum fail, GLenum zfail, GLenum zpass); -GLAPI PFNGLSTENCILOPPROC glad_glStencilOp; -#define glStencilOp glad_glStencilOp -typedef void (APIENTRYP PFNGLDEPTHFUNCPROC)(GLenum func); -GLAPI PFNGLDEPTHFUNCPROC glad_glDepthFunc; -#define glDepthFunc glad_glDepthFunc -typedef void (APIENTRYP PFNGLPIXELSTOREFPROC)(GLenum pname, GLfloat param); -GLAPI PFNGLPIXELSTOREFPROC glad_glPixelStoref; -#define glPixelStoref glad_glPixelStoref -typedef void (APIENTRYP PFNGLPIXELSTOREIPROC)(GLenum pname, GLint param); -GLAPI PFNGLPIXELSTOREIPROC glad_glPixelStorei; -#define glPixelStorei glad_glPixelStorei -typedef void (APIENTRYP PFNGLREADBUFFERPROC)(GLenum src); -GLAPI PFNGLREADBUFFERPROC glad_glReadBuffer; -#define glReadBuffer glad_glReadBuffer -typedef void (APIENTRYP PFNGLREADPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); -GLAPI PFNGLREADPIXELSPROC glad_glReadPixels; -#define glReadPixels glad_glReadPixels -typedef void (APIENTRYP PFNGLGETBOOLEANVPROC)(GLenum pname, GLboolean *data); -GLAPI PFNGLGETBOOLEANVPROC glad_glGetBooleanv; -#define glGetBooleanv glad_glGetBooleanv -typedef void (APIENTRYP PFNGLGETDOUBLEVPROC)(GLenum pname, GLdouble *data); -GLAPI PFNGLGETDOUBLEVPROC glad_glGetDoublev; -#define glGetDoublev glad_glGetDoublev -typedef GLenum (APIENTRYP PFNGLGETERRORPROC)(void); -GLAPI PFNGLGETERRORPROC glad_glGetError; -#define glGetError glad_glGetError -typedef void (APIENTRYP PFNGLGETFLOATVPROC)(GLenum pname, GLfloat *data); -GLAPI PFNGLGETFLOATVPROC glad_glGetFloatv; -#define glGetFloatv glad_glGetFloatv -typedef void (APIENTRYP PFNGLGETINTEGERVPROC)(GLenum pname, GLint *data); -GLAPI PFNGLGETINTEGERVPROC glad_glGetIntegerv; -#define glGetIntegerv glad_glGetIntegerv -typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGPROC)(GLenum name); -GLAPI PFNGLGETSTRINGPROC glad_glGetString; -#define glGetString glad_glGetString -typedef void (APIENTRYP PFNGLGETTEXIMAGEPROC)(GLenum target, GLint level, GLenum format, GLenum type, void *pixels); -GLAPI PFNGLGETTEXIMAGEPROC glad_glGetTexImage; -#define glGetTexImage glad_glGetTexImage -typedef void (APIENTRYP PFNGLGETTEXPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat *params); -GLAPI PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; -#define glGetTexParameterfv glad_glGetTexParameterfv -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIVPROC)(GLenum target, GLenum pname, GLint *params); -GLAPI PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; -#define glGetTexParameteriv glad_glGetTexParameteriv -typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERFVPROC)(GLenum target, GLint level, GLenum pname, GLfloat *params); -GLAPI PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; -#define glGetTexLevelParameterfv glad_glGetTexLevelParameterfv -typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERIVPROC)(GLenum target, GLint level, GLenum pname, GLint *params); -GLAPI PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; -#define glGetTexLevelParameteriv glad_glGetTexLevelParameteriv -typedef GLboolean (APIENTRYP PFNGLISENABLEDPROC)(GLenum cap); -GLAPI PFNGLISENABLEDPROC glad_glIsEnabled; -#define glIsEnabled glad_glIsEnabled -typedef void (APIENTRYP PFNGLDEPTHRANGEPROC)(GLdouble n, GLdouble f); -GLAPI PFNGLDEPTHRANGEPROC glad_glDepthRange; -#define glDepthRange glad_glDepthRange -typedef void (APIENTRYP PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI PFNGLVIEWPORTPROC glad_glViewport; -#define glViewport glad_glViewport -typedef void (APIENTRYP PFNGLNEWLISTPROC)(GLuint list, GLenum mode); -GLAPI PFNGLNEWLISTPROC glad_glNewList; -#define glNewList glad_glNewList -typedef void (APIENTRYP PFNGLENDLISTPROC)(void); -GLAPI PFNGLENDLISTPROC glad_glEndList; -#define glEndList glad_glEndList -typedef void (APIENTRYP PFNGLCALLLISTPROC)(GLuint list); -GLAPI PFNGLCALLLISTPROC glad_glCallList; -#define glCallList glad_glCallList -typedef void (APIENTRYP PFNGLCALLLISTSPROC)(GLsizei n, GLenum type, const void *lists); -GLAPI PFNGLCALLLISTSPROC glad_glCallLists; -#define glCallLists glad_glCallLists -typedef void (APIENTRYP PFNGLDELETELISTSPROC)(GLuint list, GLsizei range); -GLAPI PFNGLDELETELISTSPROC glad_glDeleteLists; -#define glDeleteLists glad_glDeleteLists -typedef GLuint (APIENTRYP PFNGLGENLISTSPROC)(GLsizei range); -GLAPI PFNGLGENLISTSPROC glad_glGenLists; -#define glGenLists glad_glGenLists -typedef void (APIENTRYP PFNGLLISTBASEPROC)(GLuint base); -GLAPI PFNGLLISTBASEPROC glad_glListBase; -#define glListBase glad_glListBase -typedef void (APIENTRYP PFNGLBEGINPROC)(GLenum mode); -GLAPI PFNGLBEGINPROC glad_glBegin; -#define glBegin glad_glBegin -typedef void (APIENTRYP PFNGLBITMAPPROC)(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); -GLAPI PFNGLBITMAPPROC glad_glBitmap; -#define glBitmap glad_glBitmap -typedef void (APIENTRYP PFNGLCOLOR3BPROC)(GLbyte red, GLbyte green, GLbyte blue); -GLAPI PFNGLCOLOR3BPROC glad_glColor3b; -#define glColor3b glad_glColor3b -typedef void (APIENTRYP PFNGLCOLOR3BVPROC)(const GLbyte *v); -GLAPI PFNGLCOLOR3BVPROC glad_glColor3bv; -#define glColor3bv glad_glColor3bv -typedef void (APIENTRYP PFNGLCOLOR3DPROC)(GLdouble red, GLdouble green, GLdouble blue); -GLAPI PFNGLCOLOR3DPROC glad_glColor3d; -#define glColor3d glad_glColor3d -typedef void (APIENTRYP PFNGLCOLOR3DVPROC)(const GLdouble *v); -GLAPI PFNGLCOLOR3DVPROC glad_glColor3dv; -#define glColor3dv glad_glColor3dv -typedef void (APIENTRYP PFNGLCOLOR3FPROC)(GLfloat red, GLfloat green, GLfloat blue); -GLAPI PFNGLCOLOR3FPROC glad_glColor3f; -#define glColor3f glad_glColor3f -typedef void (APIENTRYP PFNGLCOLOR3FVPROC)(const GLfloat *v); -GLAPI PFNGLCOLOR3FVPROC glad_glColor3fv; -#define glColor3fv glad_glColor3fv -typedef void (APIENTRYP PFNGLCOLOR3IPROC)(GLint red, GLint green, GLint blue); -GLAPI PFNGLCOLOR3IPROC glad_glColor3i; -#define glColor3i glad_glColor3i -typedef void (APIENTRYP PFNGLCOLOR3IVPROC)(const GLint *v); -GLAPI PFNGLCOLOR3IVPROC glad_glColor3iv; -#define glColor3iv glad_glColor3iv -typedef void (APIENTRYP PFNGLCOLOR3SPROC)(GLshort red, GLshort green, GLshort blue); -GLAPI PFNGLCOLOR3SPROC glad_glColor3s; -#define glColor3s glad_glColor3s -typedef void (APIENTRYP PFNGLCOLOR3SVPROC)(const GLshort *v); -GLAPI PFNGLCOLOR3SVPROC glad_glColor3sv; -#define glColor3sv glad_glColor3sv -typedef void (APIENTRYP PFNGLCOLOR3UBPROC)(GLubyte red, GLubyte green, GLubyte blue); -GLAPI PFNGLCOLOR3UBPROC glad_glColor3ub; -#define glColor3ub glad_glColor3ub -typedef void (APIENTRYP PFNGLCOLOR3UBVPROC)(const GLubyte *v); -GLAPI PFNGLCOLOR3UBVPROC glad_glColor3ubv; -#define glColor3ubv glad_glColor3ubv -typedef void (APIENTRYP PFNGLCOLOR3UIPROC)(GLuint red, GLuint green, GLuint blue); -GLAPI PFNGLCOLOR3UIPROC glad_glColor3ui; -#define glColor3ui glad_glColor3ui -typedef void (APIENTRYP PFNGLCOLOR3UIVPROC)(const GLuint *v); -GLAPI PFNGLCOLOR3UIVPROC glad_glColor3uiv; -#define glColor3uiv glad_glColor3uiv -typedef void (APIENTRYP PFNGLCOLOR3USPROC)(GLushort red, GLushort green, GLushort blue); -GLAPI PFNGLCOLOR3USPROC glad_glColor3us; -#define glColor3us glad_glColor3us -typedef void (APIENTRYP PFNGLCOLOR3USVPROC)(const GLushort *v); -GLAPI PFNGLCOLOR3USVPROC glad_glColor3usv; -#define glColor3usv glad_glColor3usv -typedef void (APIENTRYP PFNGLCOLOR4BPROC)(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); -GLAPI PFNGLCOLOR4BPROC glad_glColor4b; -#define glColor4b glad_glColor4b -typedef void (APIENTRYP PFNGLCOLOR4BVPROC)(const GLbyte *v); -GLAPI PFNGLCOLOR4BVPROC glad_glColor4bv; -#define glColor4bv glad_glColor4bv -typedef void (APIENTRYP PFNGLCOLOR4DPROC)(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); -GLAPI PFNGLCOLOR4DPROC glad_glColor4d; -#define glColor4d glad_glColor4d -typedef void (APIENTRYP PFNGLCOLOR4DVPROC)(const GLdouble *v); -GLAPI PFNGLCOLOR4DVPROC glad_glColor4dv; -#define glColor4dv glad_glColor4dv -typedef void (APIENTRYP PFNGLCOLOR4FPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -GLAPI PFNGLCOLOR4FPROC glad_glColor4f; -#define glColor4f glad_glColor4f -typedef void (APIENTRYP PFNGLCOLOR4FVPROC)(const GLfloat *v); -GLAPI PFNGLCOLOR4FVPROC glad_glColor4fv; -#define glColor4fv glad_glColor4fv -typedef void (APIENTRYP PFNGLCOLOR4IPROC)(GLint red, GLint green, GLint blue, GLint alpha); -GLAPI PFNGLCOLOR4IPROC glad_glColor4i; -#define glColor4i glad_glColor4i -typedef void (APIENTRYP PFNGLCOLOR4IVPROC)(const GLint *v); -GLAPI PFNGLCOLOR4IVPROC glad_glColor4iv; -#define glColor4iv glad_glColor4iv -typedef void (APIENTRYP PFNGLCOLOR4SPROC)(GLshort red, GLshort green, GLshort blue, GLshort alpha); -GLAPI PFNGLCOLOR4SPROC glad_glColor4s; -#define glColor4s glad_glColor4s -typedef void (APIENTRYP PFNGLCOLOR4SVPROC)(const GLshort *v); -GLAPI PFNGLCOLOR4SVPROC glad_glColor4sv; -#define glColor4sv glad_glColor4sv -typedef void (APIENTRYP PFNGLCOLOR4UBPROC)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); -GLAPI PFNGLCOLOR4UBPROC glad_glColor4ub; -#define glColor4ub glad_glColor4ub -typedef void (APIENTRYP PFNGLCOLOR4UBVPROC)(const GLubyte *v); -GLAPI PFNGLCOLOR4UBVPROC glad_glColor4ubv; -#define glColor4ubv glad_glColor4ubv -typedef void (APIENTRYP PFNGLCOLOR4UIPROC)(GLuint red, GLuint green, GLuint blue, GLuint alpha); -GLAPI PFNGLCOLOR4UIPROC glad_glColor4ui; -#define glColor4ui glad_glColor4ui -typedef void (APIENTRYP PFNGLCOLOR4UIVPROC)(const GLuint *v); -GLAPI PFNGLCOLOR4UIVPROC glad_glColor4uiv; -#define glColor4uiv glad_glColor4uiv -typedef void (APIENTRYP PFNGLCOLOR4USPROC)(GLushort red, GLushort green, GLushort blue, GLushort alpha); -GLAPI PFNGLCOLOR4USPROC glad_glColor4us; -#define glColor4us glad_glColor4us -typedef void (APIENTRYP PFNGLCOLOR4USVPROC)(const GLushort *v); -GLAPI PFNGLCOLOR4USVPROC glad_glColor4usv; -#define glColor4usv glad_glColor4usv -typedef void (APIENTRYP PFNGLEDGEFLAGPROC)(GLboolean flag); -GLAPI PFNGLEDGEFLAGPROC glad_glEdgeFlag; -#define glEdgeFlag glad_glEdgeFlag -typedef void (APIENTRYP PFNGLEDGEFLAGVPROC)(const GLboolean *flag); -GLAPI PFNGLEDGEFLAGVPROC glad_glEdgeFlagv; -#define glEdgeFlagv glad_glEdgeFlagv -typedef void (APIENTRYP PFNGLENDPROC)(void); -GLAPI PFNGLENDPROC glad_glEnd; -#define glEnd glad_glEnd -typedef void (APIENTRYP PFNGLINDEXDPROC)(GLdouble c); -GLAPI PFNGLINDEXDPROC glad_glIndexd; -#define glIndexd glad_glIndexd -typedef void (APIENTRYP PFNGLINDEXDVPROC)(const GLdouble *c); -GLAPI PFNGLINDEXDVPROC glad_glIndexdv; -#define glIndexdv glad_glIndexdv -typedef void (APIENTRYP PFNGLINDEXFPROC)(GLfloat c); -GLAPI PFNGLINDEXFPROC glad_glIndexf; -#define glIndexf glad_glIndexf -typedef void (APIENTRYP PFNGLINDEXFVPROC)(const GLfloat *c); -GLAPI PFNGLINDEXFVPROC glad_glIndexfv; -#define glIndexfv glad_glIndexfv -typedef void (APIENTRYP PFNGLINDEXIPROC)(GLint c); -GLAPI PFNGLINDEXIPROC glad_glIndexi; -#define glIndexi glad_glIndexi -typedef void (APIENTRYP PFNGLINDEXIVPROC)(const GLint *c); -GLAPI PFNGLINDEXIVPROC glad_glIndexiv; -#define glIndexiv glad_glIndexiv -typedef void (APIENTRYP PFNGLINDEXSPROC)(GLshort c); -GLAPI PFNGLINDEXSPROC glad_glIndexs; -#define glIndexs glad_glIndexs -typedef void (APIENTRYP PFNGLINDEXSVPROC)(const GLshort *c); -GLAPI PFNGLINDEXSVPROC glad_glIndexsv; -#define glIndexsv glad_glIndexsv -typedef void (APIENTRYP PFNGLNORMAL3BPROC)(GLbyte nx, GLbyte ny, GLbyte nz); -GLAPI PFNGLNORMAL3BPROC glad_glNormal3b; -#define glNormal3b glad_glNormal3b -typedef void (APIENTRYP PFNGLNORMAL3BVPROC)(const GLbyte *v); -GLAPI PFNGLNORMAL3BVPROC glad_glNormal3bv; -#define glNormal3bv glad_glNormal3bv -typedef void (APIENTRYP PFNGLNORMAL3DPROC)(GLdouble nx, GLdouble ny, GLdouble nz); -GLAPI PFNGLNORMAL3DPROC glad_glNormal3d; -#define glNormal3d glad_glNormal3d -typedef void (APIENTRYP PFNGLNORMAL3DVPROC)(const GLdouble *v); -GLAPI PFNGLNORMAL3DVPROC glad_glNormal3dv; -#define glNormal3dv glad_glNormal3dv -typedef void (APIENTRYP PFNGLNORMAL3FPROC)(GLfloat nx, GLfloat ny, GLfloat nz); -GLAPI PFNGLNORMAL3FPROC glad_glNormal3f; -#define glNormal3f glad_glNormal3f -typedef void (APIENTRYP PFNGLNORMAL3FVPROC)(const GLfloat *v); -GLAPI PFNGLNORMAL3FVPROC glad_glNormal3fv; -#define glNormal3fv glad_glNormal3fv -typedef void (APIENTRYP PFNGLNORMAL3IPROC)(GLint nx, GLint ny, GLint nz); -GLAPI PFNGLNORMAL3IPROC glad_glNormal3i; -#define glNormal3i glad_glNormal3i -typedef void (APIENTRYP PFNGLNORMAL3IVPROC)(const GLint *v); -GLAPI PFNGLNORMAL3IVPROC glad_glNormal3iv; -#define glNormal3iv glad_glNormal3iv -typedef void (APIENTRYP PFNGLNORMAL3SPROC)(GLshort nx, GLshort ny, GLshort nz); -GLAPI PFNGLNORMAL3SPROC glad_glNormal3s; -#define glNormal3s glad_glNormal3s -typedef void (APIENTRYP PFNGLNORMAL3SVPROC)(const GLshort *v); -GLAPI PFNGLNORMAL3SVPROC glad_glNormal3sv; -#define glNormal3sv glad_glNormal3sv -typedef void (APIENTRYP PFNGLRASTERPOS2DPROC)(GLdouble x, GLdouble y); -GLAPI PFNGLRASTERPOS2DPROC glad_glRasterPos2d; -#define glRasterPos2d glad_glRasterPos2d -typedef void (APIENTRYP PFNGLRASTERPOS2DVPROC)(const GLdouble *v); -GLAPI PFNGLRASTERPOS2DVPROC glad_glRasterPos2dv; -#define glRasterPos2dv glad_glRasterPos2dv -typedef void (APIENTRYP PFNGLRASTERPOS2FPROC)(GLfloat x, GLfloat y); -GLAPI PFNGLRASTERPOS2FPROC glad_glRasterPos2f; -#define glRasterPos2f glad_glRasterPos2f -typedef void (APIENTRYP PFNGLRASTERPOS2FVPROC)(const GLfloat *v); -GLAPI PFNGLRASTERPOS2FVPROC glad_glRasterPos2fv; -#define glRasterPos2fv glad_glRasterPos2fv -typedef void (APIENTRYP PFNGLRASTERPOS2IPROC)(GLint x, GLint y); -GLAPI PFNGLRASTERPOS2IPROC glad_glRasterPos2i; -#define glRasterPos2i glad_glRasterPos2i -typedef void (APIENTRYP PFNGLRASTERPOS2IVPROC)(const GLint *v); -GLAPI PFNGLRASTERPOS2IVPROC glad_glRasterPos2iv; -#define glRasterPos2iv glad_glRasterPos2iv -typedef void (APIENTRYP PFNGLRASTERPOS2SPROC)(GLshort x, GLshort y); -GLAPI PFNGLRASTERPOS2SPROC glad_glRasterPos2s; -#define glRasterPos2s glad_glRasterPos2s -typedef void (APIENTRYP PFNGLRASTERPOS2SVPROC)(const GLshort *v); -GLAPI PFNGLRASTERPOS2SVPROC glad_glRasterPos2sv; -#define glRasterPos2sv glad_glRasterPos2sv -typedef void (APIENTRYP PFNGLRASTERPOS3DPROC)(GLdouble x, GLdouble y, GLdouble z); -GLAPI PFNGLRASTERPOS3DPROC glad_glRasterPos3d; -#define glRasterPos3d glad_glRasterPos3d -typedef void (APIENTRYP PFNGLRASTERPOS3DVPROC)(const GLdouble *v); -GLAPI PFNGLRASTERPOS3DVPROC glad_glRasterPos3dv; -#define glRasterPos3dv glad_glRasterPos3dv -typedef void (APIENTRYP PFNGLRASTERPOS3FPROC)(GLfloat x, GLfloat y, GLfloat z); -GLAPI PFNGLRASTERPOS3FPROC glad_glRasterPos3f; -#define glRasterPos3f glad_glRasterPos3f -typedef void (APIENTRYP PFNGLRASTERPOS3FVPROC)(const GLfloat *v); -GLAPI PFNGLRASTERPOS3FVPROC glad_glRasterPos3fv; -#define glRasterPos3fv glad_glRasterPos3fv -typedef void (APIENTRYP PFNGLRASTERPOS3IPROC)(GLint x, GLint y, GLint z); -GLAPI PFNGLRASTERPOS3IPROC glad_glRasterPos3i; -#define glRasterPos3i glad_glRasterPos3i -typedef void (APIENTRYP PFNGLRASTERPOS3IVPROC)(const GLint *v); -GLAPI PFNGLRASTERPOS3IVPROC glad_glRasterPos3iv; -#define glRasterPos3iv glad_glRasterPos3iv -typedef void (APIENTRYP PFNGLRASTERPOS3SPROC)(GLshort x, GLshort y, GLshort z); -GLAPI PFNGLRASTERPOS3SPROC glad_glRasterPos3s; -#define glRasterPos3s glad_glRasterPos3s -typedef void (APIENTRYP PFNGLRASTERPOS3SVPROC)(const GLshort *v); -GLAPI PFNGLRASTERPOS3SVPROC glad_glRasterPos3sv; -#define glRasterPos3sv glad_glRasterPos3sv -typedef void (APIENTRYP PFNGLRASTERPOS4DPROC)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI PFNGLRASTERPOS4DPROC glad_glRasterPos4d; -#define glRasterPos4d glad_glRasterPos4d -typedef void (APIENTRYP PFNGLRASTERPOS4DVPROC)(const GLdouble *v); -GLAPI PFNGLRASTERPOS4DVPROC glad_glRasterPos4dv; -#define glRasterPos4dv glad_glRasterPos4dv -typedef void (APIENTRYP PFNGLRASTERPOS4FPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI PFNGLRASTERPOS4FPROC glad_glRasterPos4f; -#define glRasterPos4f glad_glRasterPos4f -typedef void (APIENTRYP PFNGLRASTERPOS4FVPROC)(const GLfloat *v); -GLAPI PFNGLRASTERPOS4FVPROC glad_glRasterPos4fv; -#define glRasterPos4fv glad_glRasterPos4fv -typedef void (APIENTRYP PFNGLRASTERPOS4IPROC)(GLint x, GLint y, GLint z, GLint w); -GLAPI PFNGLRASTERPOS4IPROC glad_glRasterPos4i; -#define glRasterPos4i glad_glRasterPos4i -typedef void (APIENTRYP PFNGLRASTERPOS4IVPROC)(const GLint *v); -GLAPI PFNGLRASTERPOS4IVPROC glad_glRasterPos4iv; -#define glRasterPos4iv glad_glRasterPos4iv -typedef void (APIENTRYP PFNGLRASTERPOS4SPROC)(GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI PFNGLRASTERPOS4SPROC glad_glRasterPos4s; -#define glRasterPos4s glad_glRasterPos4s -typedef void (APIENTRYP PFNGLRASTERPOS4SVPROC)(const GLshort *v); -GLAPI PFNGLRASTERPOS4SVPROC glad_glRasterPos4sv; -#define glRasterPos4sv glad_glRasterPos4sv -typedef void (APIENTRYP PFNGLRECTDPROC)(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); -GLAPI PFNGLRECTDPROC glad_glRectd; -#define glRectd glad_glRectd -typedef void (APIENTRYP PFNGLRECTDVPROC)(const GLdouble *v1, const GLdouble *v2); -GLAPI PFNGLRECTDVPROC glad_glRectdv; -#define glRectdv glad_glRectdv -typedef void (APIENTRYP PFNGLRECTFPROC)(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); -GLAPI PFNGLRECTFPROC glad_glRectf; -#define glRectf glad_glRectf -typedef void (APIENTRYP PFNGLRECTFVPROC)(const GLfloat *v1, const GLfloat *v2); -GLAPI PFNGLRECTFVPROC glad_glRectfv; -#define glRectfv glad_glRectfv -typedef void (APIENTRYP PFNGLRECTIPROC)(GLint x1, GLint y1, GLint x2, GLint y2); -GLAPI PFNGLRECTIPROC glad_glRecti; -#define glRecti glad_glRecti -typedef void (APIENTRYP PFNGLRECTIVPROC)(const GLint *v1, const GLint *v2); -GLAPI PFNGLRECTIVPROC glad_glRectiv; -#define glRectiv glad_glRectiv -typedef void (APIENTRYP PFNGLRECTSPROC)(GLshort x1, GLshort y1, GLshort x2, GLshort y2); -GLAPI PFNGLRECTSPROC glad_glRects; -#define glRects glad_glRects -typedef void (APIENTRYP PFNGLRECTSVPROC)(const GLshort *v1, const GLshort *v2); -GLAPI PFNGLRECTSVPROC glad_glRectsv; -#define glRectsv glad_glRectsv -typedef void (APIENTRYP PFNGLTEXCOORD1DPROC)(GLdouble s); -GLAPI PFNGLTEXCOORD1DPROC glad_glTexCoord1d; -#define glTexCoord1d glad_glTexCoord1d -typedef void (APIENTRYP PFNGLTEXCOORD1DVPROC)(const GLdouble *v); -GLAPI PFNGLTEXCOORD1DVPROC glad_glTexCoord1dv; -#define glTexCoord1dv glad_glTexCoord1dv -typedef void (APIENTRYP PFNGLTEXCOORD1FPROC)(GLfloat s); -GLAPI PFNGLTEXCOORD1FPROC glad_glTexCoord1f; -#define glTexCoord1f glad_glTexCoord1f -typedef void (APIENTRYP PFNGLTEXCOORD1FVPROC)(const GLfloat *v); -GLAPI PFNGLTEXCOORD1FVPROC glad_glTexCoord1fv; -#define glTexCoord1fv glad_glTexCoord1fv -typedef void (APIENTRYP PFNGLTEXCOORD1IPROC)(GLint s); -GLAPI PFNGLTEXCOORD1IPROC glad_glTexCoord1i; -#define glTexCoord1i glad_glTexCoord1i -typedef void (APIENTRYP PFNGLTEXCOORD1IVPROC)(const GLint *v); -GLAPI PFNGLTEXCOORD1IVPROC glad_glTexCoord1iv; -#define glTexCoord1iv glad_glTexCoord1iv -typedef void (APIENTRYP PFNGLTEXCOORD1SPROC)(GLshort s); -GLAPI PFNGLTEXCOORD1SPROC glad_glTexCoord1s; -#define glTexCoord1s glad_glTexCoord1s -typedef void (APIENTRYP PFNGLTEXCOORD1SVPROC)(const GLshort *v); -GLAPI PFNGLTEXCOORD1SVPROC glad_glTexCoord1sv; -#define glTexCoord1sv glad_glTexCoord1sv -typedef void (APIENTRYP PFNGLTEXCOORD2DPROC)(GLdouble s, GLdouble t); -GLAPI PFNGLTEXCOORD2DPROC glad_glTexCoord2d; -#define glTexCoord2d glad_glTexCoord2d -typedef void (APIENTRYP PFNGLTEXCOORD2DVPROC)(const GLdouble *v); -GLAPI PFNGLTEXCOORD2DVPROC glad_glTexCoord2dv; -#define glTexCoord2dv glad_glTexCoord2dv -typedef void (APIENTRYP PFNGLTEXCOORD2FPROC)(GLfloat s, GLfloat t); -GLAPI PFNGLTEXCOORD2FPROC glad_glTexCoord2f; -#define glTexCoord2f glad_glTexCoord2f -typedef void (APIENTRYP PFNGLTEXCOORD2FVPROC)(const GLfloat *v); -GLAPI PFNGLTEXCOORD2FVPROC glad_glTexCoord2fv; -#define glTexCoord2fv glad_glTexCoord2fv -typedef void (APIENTRYP PFNGLTEXCOORD2IPROC)(GLint s, GLint t); -GLAPI PFNGLTEXCOORD2IPROC glad_glTexCoord2i; -#define glTexCoord2i glad_glTexCoord2i -typedef void (APIENTRYP PFNGLTEXCOORD2IVPROC)(const GLint *v); -GLAPI PFNGLTEXCOORD2IVPROC glad_glTexCoord2iv; -#define glTexCoord2iv glad_glTexCoord2iv -typedef void (APIENTRYP PFNGLTEXCOORD2SPROC)(GLshort s, GLshort t); -GLAPI PFNGLTEXCOORD2SPROC glad_glTexCoord2s; -#define glTexCoord2s glad_glTexCoord2s -typedef void (APIENTRYP PFNGLTEXCOORD2SVPROC)(const GLshort *v); -GLAPI PFNGLTEXCOORD2SVPROC glad_glTexCoord2sv; -#define glTexCoord2sv glad_glTexCoord2sv -typedef void (APIENTRYP PFNGLTEXCOORD3DPROC)(GLdouble s, GLdouble t, GLdouble r); -GLAPI PFNGLTEXCOORD3DPROC glad_glTexCoord3d; -#define glTexCoord3d glad_glTexCoord3d -typedef void (APIENTRYP PFNGLTEXCOORD3DVPROC)(const GLdouble *v); -GLAPI PFNGLTEXCOORD3DVPROC glad_glTexCoord3dv; -#define glTexCoord3dv glad_glTexCoord3dv -typedef void (APIENTRYP PFNGLTEXCOORD3FPROC)(GLfloat s, GLfloat t, GLfloat r); -GLAPI PFNGLTEXCOORD3FPROC glad_glTexCoord3f; -#define glTexCoord3f glad_glTexCoord3f -typedef void (APIENTRYP PFNGLTEXCOORD3FVPROC)(const GLfloat *v); -GLAPI PFNGLTEXCOORD3FVPROC glad_glTexCoord3fv; -#define glTexCoord3fv glad_glTexCoord3fv -typedef void (APIENTRYP PFNGLTEXCOORD3IPROC)(GLint s, GLint t, GLint r); -GLAPI PFNGLTEXCOORD3IPROC glad_glTexCoord3i; -#define glTexCoord3i glad_glTexCoord3i -typedef void (APIENTRYP PFNGLTEXCOORD3IVPROC)(const GLint *v); -GLAPI PFNGLTEXCOORD3IVPROC glad_glTexCoord3iv; -#define glTexCoord3iv glad_glTexCoord3iv -typedef void (APIENTRYP PFNGLTEXCOORD3SPROC)(GLshort s, GLshort t, GLshort r); -GLAPI PFNGLTEXCOORD3SPROC glad_glTexCoord3s; -#define glTexCoord3s glad_glTexCoord3s -typedef void (APIENTRYP PFNGLTEXCOORD3SVPROC)(const GLshort *v); -GLAPI PFNGLTEXCOORD3SVPROC glad_glTexCoord3sv; -#define glTexCoord3sv glad_glTexCoord3sv -typedef void (APIENTRYP PFNGLTEXCOORD4DPROC)(GLdouble s, GLdouble t, GLdouble r, GLdouble q); -GLAPI PFNGLTEXCOORD4DPROC glad_glTexCoord4d; -#define glTexCoord4d glad_glTexCoord4d -typedef void (APIENTRYP PFNGLTEXCOORD4DVPROC)(const GLdouble *v); -GLAPI PFNGLTEXCOORD4DVPROC glad_glTexCoord4dv; -#define glTexCoord4dv glad_glTexCoord4dv -typedef void (APIENTRYP PFNGLTEXCOORD4FPROC)(GLfloat s, GLfloat t, GLfloat r, GLfloat q); -GLAPI PFNGLTEXCOORD4FPROC glad_glTexCoord4f; -#define glTexCoord4f glad_glTexCoord4f -typedef void (APIENTRYP PFNGLTEXCOORD4FVPROC)(const GLfloat *v); -GLAPI PFNGLTEXCOORD4FVPROC glad_glTexCoord4fv; -#define glTexCoord4fv glad_glTexCoord4fv -typedef void (APIENTRYP PFNGLTEXCOORD4IPROC)(GLint s, GLint t, GLint r, GLint q); -GLAPI PFNGLTEXCOORD4IPROC glad_glTexCoord4i; -#define glTexCoord4i glad_glTexCoord4i -typedef void (APIENTRYP PFNGLTEXCOORD4IVPROC)(const GLint *v); -GLAPI PFNGLTEXCOORD4IVPROC glad_glTexCoord4iv; -#define glTexCoord4iv glad_glTexCoord4iv -typedef void (APIENTRYP PFNGLTEXCOORD4SPROC)(GLshort s, GLshort t, GLshort r, GLshort q); -GLAPI PFNGLTEXCOORD4SPROC glad_glTexCoord4s; -#define glTexCoord4s glad_glTexCoord4s -typedef void (APIENTRYP PFNGLTEXCOORD4SVPROC)(const GLshort *v); -GLAPI PFNGLTEXCOORD4SVPROC glad_glTexCoord4sv; -#define glTexCoord4sv glad_glTexCoord4sv -typedef void (APIENTRYP PFNGLVERTEX2DPROC)(GLdouble x, GLdouble y); -GLAPI PFNGLVERTEX2DPROC glad_glVertex2d; -#define glVertex2d glad_glVertex2d -typedef void (APIENTRYP PFNGLVERTEX2DVPROC)(const GLdouble *v); -GLAPI PFNGLVERTEX2DVPROC glad_glVertex2dv; -#define glVertex2dv glad_glVertex2dv -typedef void (APIENTRYP PFNGLVERTEX2FPROC)(GLfloat x, GLfloat y); -GLAPI PFNGLVERTEX2FPROC glad_glVertex2f; -#define glVertex2f glad_glVertex2f -typedef void (APIENTRYP PFNGLVERTEX2FVPROC)(const GLfloat *v); -GLAPI PFNGLVERTEX2FVPROC glad_glVertex2fv; -#define glVertex2fv glad_glVertex2fv -typedef void (APIENTRYP PFNGLVERTEX2IPROC)(GLint x, GLint y); -GLAPI PFNGLVERTEX2IPROC glad_glVertex2i; -#define glVertex2i glad_glVertex2i -typedef void (APIENTRYP PFNGLVERTEX2IVPROC)(const GLint *v); -GLAPI PFNGLVERTEX2IVPROC glad_glVertex2iv; -#define glVertex2iv glad_glVertex2iv -typedef void (APIENTRYP PFNGLVERTEX2SPROC)(GLshort x, GLshort y); -GLAPI PFNGLVERTEX2SPROC glad_glVertex2s; -#define glVertex2s glad_glVertex2s -typedef void (APIENTRYP PFNGLVERTEX2SVPROC)(const GLshort *v); -GLAPI PFNGLVERTEX2SVPROC glad_glVertex2sv; -#define glVertex2sv glad_glVertex2sv -typedef void (APIENTRYP PFNGLVERTEX3DPROC)(GLdouble x, GLdouble y, GLdouble z); -GLAPI PFNGLVERTEX3DPROC glad_glVertex3d; -#define glVertex3d glad_glVertex3d -typedef void (APIENTRYP PFNGLVERTEX3DVPROC)(const GLdouble *v); -GLAPI PFNGLVERTEX3DVPROC glad_glVertex3dv; -#define glVertex3dv glad_glVertex3dv -typedef void (APIENTRYP PFNGLVERTEX3FPROC)(GLfloat x, GLfloat y, GLfloat z); -GLAPI PFNGLVERTEX3FPROC glad_glVertex3f; -#define glVertex3f glad_glVertex3f -typedef void (APIENTRYP PFNGLVERTEX3FVPROC)(const GLfloat *v); -GLAPI PFNGLVERTEX3FVPROC glad_glVertex3fv; -#define glVertex3fv glad_glVertex3fv -typedef void (APIENTRYP PFNGLVERTEX3IPROC)(GLint x, GLint y, GLint z); -GLAPI PFNGLVERTEX3IPROC glad_glVertex3i; -#define glVertex3i glad_glVertex3i -typedef void (APIENTRYP PFNGLVERTEX3IVPROC)(const GLint *v); -GLAPI PFNGLVERTEX3IVPROC glad_glVertex3iv; -#define glVertex3iv glad_glVertex3iv -typedef void (APIENTRYP PFNGLVERTEX3SPROC)(GLshort x, GLshort y, GLshort z); -GLAPI PFNGLVERTEX3SPROC glad_glVertex3s; -#define glVertex3s glad_glVertex3s -typedef void (APIENTRYP PFNGLVERTEX3SVPROC)(const GLshort *v); -GLAPI PFNGLVERTEX3SVPROC glad_glVertex3sv; -#define glVertex3sv glad_glVertex3sv -typedef void (APIENTRYP PFNGLVERTEX4DPROC)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI PFNGLVERTEX4DPROC glad_glVertex4d; -#define glVertex4d glad_glVertex4d -typedef void (APIENTRYP PFNGLVERTEX4DVPROC)(const GLdouble *v); -GLAPI PFNGLVERTEX4DVPROC glad_glVertex4dv; -#define glVertex4dv glad_glVertex4dv -typedef void (APIENTRYP PFNGLVERTEX4FPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI PFNGLVERTEX4FPROC glad_glVertex4f; -#define glVertex4f glad_glVertex4f -typedef void (APIENTRYP PFNGLVERTEX4FVPROC)(const GLfloat *v); -GLAPI PFNGLVERTEX4FVPROC glad_glVertex4fv; -#define glVertex4fv glad_glVertex4fv -typedef void (APIENTRYP PFNGLVERTEX4IPROC)(GLint x, GLint y, GLint z, GLint w); -GLAPI PFNGLVERTEX4IPROC glad_glVertex4i; -#define glVertex4i glad_glVertex4i -typedef void (APIENTRYP PFNGLVERTEX4IVPROC)(const GLint *v); -GLAPI PFNGLVERTEX4IVPROC glad_glVertex4iv; -#define glVertex4iv glad_glVertex4iv -typedef void (APIENTRYP PFNGLVERTEX4SPROC)(GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI PFNGLVERTEX4SPROC glad_glVertex4s; -#define glVertex4s glad_glVertex4s -typedef void (APIENTRYP PFNGLVERTEX4SVPROC)(const GLshort *v); -GLAPI PFNGLVERTEX4SVPROC glad_glVertex4sv; -#define glVertex4sv glad_glVertex4sv -typedef void (APIENTRYP PFNGLCLIPPLANEPROC)(GLenum plane, const GLdouble *equation); -GLAPI PFNGLCLIPPLANEPROC glad_glClipPlane; -#define glClipPlane glad_glClipPlane -typedef void (APIENTRYP PFNGLCOLORMATERIALPROC)(GLenum face, GLenum mode); -GLAPI PFNGLCOLORMATERIALPROC glad_glColorMaterial; -#define glColorMaterial glad_glColorMaterial -typedef void (APIENTRYP PFNGLFOGFPROC)(GLenum pname, GLfloat param); -GLAPI PFNGLFOGFPROC glad_glFogf; -#define glFogf glad_glFogf -typedef void (APIENTRYP PFNGLFOGFVPROC)(GLenum pname, const GLfloat *params); -GLAPI PFNGLFOGFVPROC glad_glFogfv; -#define glFogfv glad_glFogfv -typedef void (APIENTRYP PFNGLFOGIPROC)(GLenum pname, GLint param); -GLAPI PFNGLFOGIPROC glad_glFogi; -#define glFogi glad_glFogi -typedef void (APIENTRYP PFNGLFOGIVPROC)(GLenum pname, const GLint *params); -GLAPI PFNGLFOGIVPROC glad_glFogiv; -#define glFogiv glad_glFogiv -typedef void (APIENTRYP PFNGLLIGHTFPROC)(GLenum light, GLenum pname, GLfloat param); -GLAPI PFNGLLIGHTFPROC glad_glLightf; -#define glLightf glad_glLightf -typedef void (APIENTRYP PFNGLLIGHTFVPROC)(GLenum light, GLenum pname, const GLfloat *params); -GLAPI PFNGLLIGHTFVPROC glad_glLightfv; -#define glLightfv glad_glLightfv -typedef void (APIENTRYP PFNGLLIGHTIPROC)(GLenum light, GLenum pname, GLint param); -GLAPI PFNGLLIGHTIPROC glad_glLighti; -#define glLighti glad_glLighti -typedef void (APIENTRYP PFNGLLIGHTIVPROC)(GLenum light, GLenum pname, const GLint *params); -GLAPI PFNGLLIGHTIVPROC glad_glLightiv; -#define glLightiv glad_glLightiv -typedef void (APIENTRYP PFNGLLIGHTMODELFPROC)(GLenum pname, GLfloat param); -GLAPI PFNGLLIGHTMODELFPROC glad_glLightModelf; -#define glLightModelf glad_glLightModelf -typedef void (APIENTRYP PFNGLLIGHTMODELFVPROC)(GLenum pname, const GLfloat *params); -GLAPI PFNGLLIGHTMODELFVPROC glad_glLightModelfv; -#define glLightModelfv glad_glLightModelfv -typedef void (APIENTRYP PFNGLLIGHTMODELIPROC)(GLenum pname, GLint param); -GLAPI PFNGLLIGHTMODELIPROC glad_glLightModeli; -#define glLightModeli glad_glLightModeli -typedef void (APIENTRYP PFNGLLIGHTMODELIVPROC)(GLenum pname, const GLint *params); -GLAPI PFNGLLIGHTMODELIVPROC glad_glLightModeliv; -#define glLightModeliv glad_glLightModeliv -typedef void (APIENTRYP PFNGLLINESTIPPLEPROC)(GLint factor, GLushort pattern); -GLAPI PFNGLLINESTIPPLEPROC glad_glLineStipple; -#define glLineStipple glad_glLineStipple -typedef void (APIENTRYP PFNGLMATERIALFPROC)(GLenum face, GLenum pname, GLfloat param); -GLAPI PFNGLMATERIALFPROC glad_glMaterialf; -#define glMaterialf glad_glMaterialf -typedef void (APIENTRYP PFNGLMATERIALFVPROC)(GLenum face, GLenum pname, const GLfloat *params); -GLAPI PFNGLMATERIALFVPROC glad_glMaterialfv; -#define glMaterialfv glad_glMaterialfv -typedef void (APIENTRYP PFNGLMATERIALIPROC)(GLenum face, GLenum pname, GLint param); -GLAPI PFNGLMATERIALIPROC glad_glMateriali; -#define glMateriali glad_glMateriali -typedef void (APIENTRYP PFNGLMATERIALIVPROC)(GLenum face, GLenum pname, const GLint *params); -GLAPI PFNGLMATERIALIVPROC glad_glMaterialiv; -#define glMaterialiv glad_glMaterialiv -typedef void (APIENTRYP PFNGLPOLYGONSTIPPLEPROC)(const GLubyte *mask); -GLAPI PFNGLPOLYGONSTIPPLEPROC glad_glPolygonStipple; -#define glPolygonStipple glad_glPolygonStipple -typedef void (APIENTRYP PFNGLSHADEMODELPROC)(GLenum mode); -GLAPI PFNGLSHADEMODELPROC glad_glShadeModel; -#define glShadeModel glad_glShadeModel -typedef void (APIENTRYP PFNGLTEXENVFPROC)(GLenum target, GLenum pname, GLfloat param); -GLAPI PFNGLTEXENVFPROC glad_glTexEnvf; -#define glTexEnvf glad_glTexEnvf -typedef void (APIENTRYP PFNGLTEXENVFVPROC)(GLenum target, GLenum pname, const GLfloat *params); -GLAPI PFNGLTEXENVFVPROC glad_glTexEnvfv; -#define glTexEnvfv glad_glTexEnvfv -typedef void (APIENTRYP PFNGLTEXENVIPROC)(GLenum target, GLenum pname, GLint param); -GLAPI PFNGLTEXENVIPROC glad_glTexEnvi; -#define glTexEnvi glad_glTexEnvi -typedef void (APIENTRYP PFNGLTEXENVIVPROC)(GLenum target, GLenum pname, const GLint *params); -GLAPI PFNGLTEXENVIVPROC glad_glTexEnviv; -#define glTexEnviv glad_glTexEnviv -typedef void (APIENTRYP PFNGLTEXGENDPROC)(GLenum coord, GLenum pname, GLdouble param); -GLAPI PFNGLTEXGENDPROC glad_glTexGend; -#define glTexGend glad_glTexGend -typedef void (APIENTRYP PFNGLTEXGENDVPROC)(GLenum coord, GLenum pname, const GLdouble *params); -GLAPI PFNGLTEXGENDVPROC glad_glTexGendv; -#define glTexGendv glad_glTexGendv -typedef void (APIENTRYP PFNGLTEXGENFPROC)(GLenum coord, GLenum pname, GLfloat param); -GLAPI PFNGLTEXGENFPROC glad_glTexGenf; -#define glTexGenf glad_glTexGenf -typedef void (APIENTRYP PFNGLTEXGENFVPROC)(GLenum coord, GLenum pname, const GLfloat *params); -GLAPI PFNGLTEXGENFVPROC glad_glTexGenfv; -#define glTexGenfv glad_glTexGenfv -typedef void (APIENTRYP PFNGLTEXGENIPROC)(GLenum coord, GLenum pname, GLint param); -GLAPI PFNGLTEXGENIPROC glad_glTexGeni; -#define glTexGeni glad_glTexGeni -typedef void (APIENTRYP PFNGLTEXGENIVPROC)(GLenum coord, GLenum pname, const GLint *params); -GLAPI PFNGLTEXGENIVPROC glad_glTexGeniv; -#define glTexGeniv glad_glTexGeniv -typedef void (APIENTRYP PFNGLFEEDBACKBUFFERPROC)(GLsizei size, GLenum type, GLfloat *buffer); -GLAPI PFNGLFEEDBACKBUFFERPROC glad_glFeedbackBuffer; -#define glFeedbackBuffer glad_glFeedbackBuffer -typedef void (APIENTRYP PFNGLSELECTBUFFERPROC)(GLsizei size, GLuint *buffer); -GLAPI PFNGLSELECTBUFFERPROC glad_glSelectBuffer; -#define glSelectBuffer glad_glSelectBuffer -typedef GLint (APIENTRYP PFNGLRENDERMODEPROC)(GLenum mode); -GLAPI PFNGLRENDERMODEPROC glad_glRenderMode; -#define glRenderMode glad_glRenderMode -typedef void (APIENTRYP PFNGLINITNAMESPROC)(void); -GLAPI PFNGLINITNAMESPROC glad_glInitNames; -#define glInitNames glad_glInitNames -typedef void (APIENTRYP PFNGLLOADNAMEPROC)(GLuint name); -GLAPI PFNGLLOADNAMEPROC glad_glLoadName; -#define glLoadName glad_glLoadName -typedef void (APIENTRYP PFNGLPASSTHROUGHPROC)(GLfloat token); -GLAPI PFNGLPASSTHROUGHPROC glad_glPassThrough; -#define glPassThrough glad_glPassThrough -typedef void (APIENTRYP PFNGLPOPNAMEPROC)(void); -GLAPI PFNGLPOPNAMEPROC glad_glPopName; -#define glPopName glad_glPopName -typedef void (APIENTRYP PFNGLPUSHNAMEPROC)(GLuint name); -GLAPI PFNGLPUSHNAMEPROC glad_glPushName; -#define glPushName glad_glPushName -typedef void (APIENTRYP PFNGLCLEARACCUMPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -GLAPI PFNGLCLEARACCUMPROC glad_glClearAccum; -#define glClearAccum glad_glClearAccum -typedef void (APIENTRYP PFNGLCLEARINDEXPROC)(GLfloat c); -GLAPI PFNGLCLEARINDEXPROC glad_glClearIndex; -#define glClearIndex glad_glClearIndex -typedef void (APIENTRYP PFNGLINDEXMASKPROC)(GLuint mask); -GLAPI PFNGLINDEXMASKPROC glad_glIndexMask; -#define glIndexMask glad_glIndexMask -typedef void (APIENTRYP PFNGLACCUMPROC)(GLenum op, GLfloat value); -GLAPI PFNGLACCUMPROC glad_glAccum; -#define glAccum glad_glAccum -typedef void (APIENTRYP PFNGLPOPATTRIBPROC)(void); -GLAPI PFNGLPOPATTRIBPROC glad_glPopAttrib; -#define glPopAttrib glad_glPopAttrib -typedef void (APIENTRYP PFNGLPUSHATTRIBPROC)(GLbitfield mask); -GLAPI PFNGLPUSHATTRIBPROC glad_glPushAttrib; -#define glPushAttrib glad_glPushAttrib -typedef void (APIENTRYP PFNGLMAP1DPROC)(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); -GLAPI PFNGLMAP1DPROC glad_glMap1d; -#define glMap1d glad_glMap1d -typedef void (APIENTRYP PFNGLMAP1FPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); -GLAPI PFNGLMAP1FPROC glad_glMap1f; -#define glMap1f glad_glMap1f -typedef void (APIENTRYP PFNGLMAP2DPROC)(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); -GLAPI PFNGLMAP2DPROC glad_glMap2d; -#define glMap2d glad_glMap2d -typedef void (APIENTRYP PFNGLMAP2FPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); -GLAPI PFNGLMAP2FPROC glad_glMap2f; -#define glMap2f glad_glMap2f -typedef void (APIENTRYP PFNGLMAPGRID1DPROC)(GLint un, GLdouble u1, GLdouble u2); -GLAPI PFNGLMAPGRID1DPROC glad_glMapGrid1d; -#define glMapGrid1d glad_glMapGrid1d -typedef void (APIENTRYP PFNGLMAPGRID1FPROC)(GLint un, GLfloat u1, GLfloat u2); -GLAPI PFNGLMAPGRID1FPROC glad_glMapGrid1f; -#define glMapGrid1f glad_glMapGrid1f -typedef void (APIENTRYP PFNGLMAPGRID2DPROC)(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); -GLAPI PFNGLMAPGRID2DPROC glad_glMapGrid2d; -#define glMapGrid2d glad_glMapGrid2d -typedef void (APIENTRYP PFNGLMAPGRID2FPROC)(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); -GLAPI PFNGLMAPGRID2FPROC glad_glMapGrid2f; -#define glMapGrid2f glad_glMapGrid2f -typedef void (APIENTRYP PFNGLEVALCOORD1DPROC)(GLdouble u); -GLAPI PFNGLEVALCOORD1DPROC glad_glEvalCoord1d; -#define glEvalCoord1d glad_glEvalCoord1d -typedef void (APIENTRYP PFNGLEVALCOORD1DVPROC)(const GLdouble *u); -GLAPI PFNGLEVALCOORD1DVPROC glad_glEvalCoord1dv; -#define glEvalCoord1dv glad_glEvalCoord1dv -typedef void (APIENTRYP PFNGLEVALCOORD1FPROC)(GLfloat u); -GLAPI PFNGLEVALCOORD1FPROC glad_glEvalCoord1f; -#define glEvalCoord1f glad_glEvalCoord1f -typedef void (APIENTRYP PFNGLEVALCOORD1FVPROC)(const GLfloat *u); -GLAPI PFNGLEVALCOORD1FVPROC glad_glEvalCoord1fv; -#define glEvalCoord1fv glad_glEvalCoord1fv -typedef void (APIENTRYP PFNGLEVALCOORD2DPROC)(GLdouble u, GLdouble v); -GLAPI PFNGLEVALCOORD2DPROC glad_glEvalCoord2d; -#define glEvalCoord2d glad_glEvalCoord2d -typedef void (APIENTRYP PFNGLEVALCOORD2DVPROC)(const GLdouble *u); -GLAPI PFNGLEVALCOORD2DVPROC glad_glEvalCoord2dv; -#define glEvalCoord2dv glad_glEvalCoord2dv -typedef void (APIENTRYP PFNGLEVALCOORD2FPROC)(GLfloat u, GLfloat v); -GLAPI PFNGLEVALCOORD2FPROC glad_glEvalCoord2f; -#define glEvalCoord2f glad_glEvalCoord2f -typedef void (APIENTRYP PFNGLEVALCOORD2FVPROC)(const GLfloat *u); -GLAPI PFNGLEVALCOORD2FVPROC glad_glEvalCoord2fv; -#define glEvalCoord2fv glad_glEvalCoord2fv -typedef void (APIENTRYP PFNGLEVALMESH1PROC)(GLenum mode, GLint i1, GLint i2); -GLAPI PFNGLEVALMESH1PROC glad_glEvalMesh1; -#define glEvalMesh1 glad_glEvalMesh1 -typedef void (APIENTRYP PFNGLEVALPOINT1PROC)(GLint i); -GLAPI PFNGLEVALPOINT1PROC glad_glEvalPoint1; -#define glEvalPoint1 glad_glEvalPoint1 -typedef void (APIENTRYP PFNGLEVALMESH2PROC)(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); -GLAPI PFNGLEVALMESH2PROC glad_glEvalMesh2; -#define glEvalMesh2 glad_glEvalMesh2 -typedef void (APIENTRYP PFNGLEVALPOINT2PROC)(GLint i, GLint j); -GLAPI PFNGLEVALPOINT2PROC glad_glEvalPoint2; -#define glEvalPoint2 glad_glEvalPoint2 -typedef void (APIENTRYP PFNGLALPHAFUNCPROC)(GLenum func, GLfloat ref); -GLAPI PFNGLALPHAFUNCPROC glad_glAlphaFunc; -#define glAlphaFunc glad_glAlphaFunc -typedef void (APIENTRYP PFNGLPIXELZOOMPROC)(GLfloat xfactor, GLfloat yfactor); -GLAPI PFNGLPIXELZOOMPROC glad_glPixelZoom; -#define glPixelZoom glad_glPixelZoom -typedef void (APIENTRYP PFNGLPIXELTRANSFERFPROC)(GLenum pname, GLfloat param); -GLAPI PFNGLPIXELTRANSFERFPROC glad_glPixelTransferf; -#define glPixelTransferf glad_glPixelTransferf -typedef void (APIENTRYP PFNGLPIXELTRANSFERIPROC)(GLenum pname, GLint param); -GLAPI PFNGLPIXELTRANSFERIPROC glad_glPixelTransferi; -#define glPixelTransferi glad_glPixelTransferi -typedef void (APIENTRYP PFNGLPIXELMAPFVPROC)(GLenum map, GLsizei mapsize, const GLfloat *values); -GLAPI PFNGLPIXELMAPFVPROC glad_glPixelMapfv; -#define glPixelMapfv glad_glPixelMapfv -typedef void (APIENTRYP PFNGLPIXELMAPUIVPROC)(GLenum map, GLsizei mapsize, const GLuint *values); -GLAPI PFNGLPIXELMAPUIVPROC glad_glPixelMapuiv; -#define glPixelMapuiv glad_glPixelMapuiv -typedef void (APIENTRYP PFNGLPIXELMAPUSVPROC)(GLenum map, GLsizei mapsize, const GLushort *values); -GLAPI PFNGLPIXELMAPUSVPROC glad_glPixelMapusv; -#define glPixelMapusv glad_glPixelMapusv -typedef void (APIENTRYP PFNGLCOPYPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); -GLAPI PFNGLCOPYPIXELSPROC glad_glCopyPixels; -#define glCopyPixels glad_glCopyPixels -typedef void (APIENTRYP PFNGLDRAWPIXELSPROC)(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -GLAPI PFNGLDRAWPIXELSPROC glad_glDrawPixels; -#define glDrawPixels glad_glDrawPixels -typedef void (APIENTRYP PFNGLGETCLIPPLANEPROC)(GLenum plane, GLdouble *equation); -GLAPI PFNGLGETCLIPPLANEPROC glad_glGetClipPlane; -#define glGetClipPlane glad_glGetClipPlane -typedef void (APIENTRYP PFNGLGETLIGHTFVPROC)(GLenum light, GLenum pname, GLfloat *params); -GLAPI PFNGLGETLIGHTFVPROC glad_glGetLightfv; -#define glGetLightfv glad_glGetLightfv -typedef void (APIENTRYP PFNGLGETLIGHTIVPROC)(GLenum light, GLenum pname, GLint *params); -GLAPI PFNGLGETLIGHTIVPROC glad_glGetLightiv; -#define glGetLightiv glad_glGetLightiv -typedef void (APIENTRYP PFNGLGETMAPDVPROC)(GLenum target, GLenum query, GLdouble *v); -GLAPI PFNGLGETMAPDVPROC glad_glGetMapdv; -#define glGetMapdv glad_glGetMapdv -typedef void (APIENTRYP PFNGLGETMAPFVPROC)(GLenum target, GLenum query, GLfloat *v); -GLAPI PFNGLGETMAPFVPROC glad_glGetMapfv; -#define glGetMapfv glad_glGetMapfv -typedef void (APIENTRYP PFNGLGETMAPIVPROC)(GLenum target, GLenum query, GLint *v); -GLAPI PFNGLGETMAPIVPROC glad_glGetMapiv; -#define glGetMapiv glad_glGetMapiv -typedef void (APIENTRYP PFNGLGETMATERIALFVPROC)(GLenum face, GLenum pname, GLfloat *params); -GLAPI PFNGLGETMATERIALFVPROC glad_glGetMaterialfv; -#define glGetMaterialfv glad_glGetMaterialfv -typedef void (APIENTRYP PFNGLGETMATERIALIVPROC)(GLenum face, GLenum pname, GLint *params); -GLAPI PFNGLGETMATERIALIVPROC glad_glGetMaterialiv; -#define glGetMaterialiv glad_glGetMaterialiv -typedef void (APIENTRYP PFNGLGETPIXELMAPFVPROC)(GLenum map, GLfloat *values); -GLAPI PFNGLGETPIXELMAPFVPROC glad_glGetPixelMapfv; -#define glGetPixelMapfv glad_glGetPixelMapfv -typedef void (APIENTRYP PFNGLGETPIXELMAPUIVPROC)(GLenum map, GLuint *values); -GLAPI PFNGLGETPIXELMAPUIVPROC glad_glGetPixelMapuiv; -#define glGetPixelMapuiv glad_glGetPixelMapuiv -typedef void (APIENTRYP PFNGLGETPIXELMAPUSVPROC)(GLenum map, GLushort *values); -GLAPI PFNGLGETPIXELMAPUSVPROC glad_glGetPixelMapusv; -#define glGetPixelMapusv glad_glGetPixelMapusv -typedef void (APIENTRYP PFNGLGETPOLYGONSTIPPLEPROC)(GLubyte *mask); -GLAPI PFNGLGETPOLYGONSTIPPLEPROC glad_glGetPolygonStipple; -#define glGetPolygonStipple glad_glGetPolygonStipple -typedef void (APIENTRYP PFNGLGETTEXENVFVPROC)(GLenum target, GLenum pname, GLfloat *params); -GLAPI PFNGLGETTEXENVFVPROC glad_glGetTexEnvfv; -#define glGetTexEnvfv glad_glGetTexEnvfv -typedef void (APIENTRYP PFNGLGETTEXENVIVPROC)(GLenum target, GLenum pname, GLint *params); -GLAPI PFNGLGETTEXENVIVPROC glad_glGetTexEnviv; -#define glGetTexEnviv glad_glGetTexEnviv -typedef void (APIENTRYP PFNGLGETTEXGENDVPROC)(GLenum coord, GLenum pname, GLdouble *params); -GLAPI PFNGLGETTEXGENDVPROC glad_glGetTexGendv; -#define glGetTexGendv glad_glGetTexGendv -typedef void (APIENTRYP PFNGLGETTEXGENFVPROC)(GLenum coord, GLenum pname, GLfloat *params); -GLAPI PFNGLGETTEXGENFVPROC glad_glGetTexGenfv; -#define glGetTexGenfv glad_glGetTexGenfv -typedef void (APIENTRYP PFNGLGETTEXGENIVPROC)(GLenum coord, GLenum pname, GLint *params); -GLAPI PFNGLGETTEXGENIVPROC glad_glGetTexGeniv; -#define glGetTexGeniv glad_glGetTexGeniv -typedef GLboolean (APIENTRYP PFNGLISLISTPROC)(GLuint list); -GLAPI PFNGLISLISTPROC glad_glIsList; -#define glIsList glad_glIsList -typedef void (APIENTRYP PFNGLFRUSTUMPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -GLAPI PFNGLFRUSTUMPROC glad_glFrustum; -#define glFrustum glad_glFrustum -typedef void (APIENTRYP PFNGLLOADIDENTITYPROC)(void); -GLAPI PFNGLLOADIDENTITYPROC glad_glLoadIdentity; -#define glLoadIdentity glad_glLoadIdentity -typedef void (APIENTRYP PFNGLLOADMATRIXFPROC)(const GLfloat *m); -GLAPI PFNGLLOADMATRIXFPROC glad_glLoadMatrixf; -#define glLoadMatrixf glad_glLoadMatrixf -typedef void (APIENTRYP PFNGLLOADMATRIXDPROC)(const GLdouble *m); -GLAPI PFNGLLOADMATRIXDPROC glad_glLoadMatrixd; -#define glLoadMatrixd glad_glLoadMatrixd -typedef void (APIENTRYP PFNGLMATRIXMODEPROC)(GLenum mode); -GLAPI PFNGLMATRIXMODEPROC glad_glMatrixMode; -#define glMatrixMode glad_glMatrixMode -typedef void (APIENTRYP PFNGLMULTMATRIXFPROC)(const GLfloat *m); -GLAPI PFNGLMULTMATRIXFPROC glad_glMultMatrixf; -#define glMultMatrixf glad_glMultMatrixf -typedef void (APIENTRYP PFNGLMULTMATRIXDPROC)(const GLdouble *m); -GLAPI PFNGLMULTMATRIXDPROC glad_glMultMatrixd; -#define glMultMatrixd glad_glMultMatrixd -typedef void (APIENTRYP PFNGLORTHOPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -GLAPI PFNGLORTHOPROC glad_glOrtho; -#define glOrtho glad_glOrtho -typedef void (APIENTRYP PFNGLPOPMATRIXPROC)(void); -GLAPI PFNGLPOPMATRIXPROC glad_glPopMatrix; -#define glPopMatrix glad_glPopMatrix -typedef void (APIENTRYP PFNGLPUSHMATRIXPROC)(void); -GLAPI PFNGLPUSHMATRIXPROC glad_glPushMatrix; -#define glPushMatrix glad_glPushMatrix -typedef void (APIENTRYP PFNGLROTATEDPROC)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); -GLAPI PFNGLROTATEDPROC glad_glRotated; -#define glRotated glad_glRotated -typedef void (APIENTRYP PFNGLROTATEFPROC)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); -GLAPI PFNGLROTATEFPROC glad_glRotatef; -#define glRotatef glad_glRotatef -typedef void (APIENTRYP PFNGLSCALEDPROC)(GLdouble x, GLdouble y, GLdouble z); -GLAPI PFNGLSCALEDPROC glad_glScaled; -#define glScaled glad_glScaled -typedef void (APIENTRYP PFNGLSCALEFPROC)(GLfloat x, GLfloat y, GLfloat z); -GLAPI PFNGLSCALEFPROC glad_glScalef; -#define glScalef glad_glScalef -typedef void (APIENTRYP PFNGLTRANSLATEDPROC)(GLdouble x, GLdouble y, GLdouble z); -GLAPI PFNGLTRANSLATEDPROC glad_glTranslated; -#define glTranslated glad_glTranslated -typedef void (APIENTRYP PFNGLTRANSLATEFPROC)(GLfloat x, GLfloat y, GLfloat z); -GLAPI PFNGLTRANSLATEFPROC glad_glTranslatef; -#define glTranslatef glad_glTranslatef -#endif -#ifndef GL_VERSION_1_1 -#define GL_VERSION_1_1 1 -GLAPI int GLAD_GL_VERSION_1_1; -typedef void (APIENTRYP PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count); -GLAPI PFNGLDRAWARRAYSPROC glad_glDrawArrays; -#define glDrawArrays glad_glDrawArrays -typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices); -GLAPI PFNGLDRAWELEMENTSPROC glad_glDrawElements; -#define glDrawElements glad_glDrawElements -typedef void (APIENTRYP PFNGLGETPOINTERVPROC)(GLenum pname, void **params); -GLAPI PFNGLGETPOINTERVPROC glad_glGetPointerv; -#define glGetPointerv glad_glGetPointerv -typedef void (APIENTRYP PFNGLPOLYGONOFFSETPROC)(GLfloat factor, GLfloat units); -GLAPI PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; -#define glPolygonOffset glad_glPolygonOffset -typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -GLAPI PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; -#define glCopyTexImage1D glad_glCopyTexImage1D -typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -GLAPI PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; -#define glCopyTexImage2D glad_glCopyTexImage2D -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -GLAPI PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; -#define glCopyTexSubImage1D glad_glCopyTexSubImage1D -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; -#define glCopyTexSubImage2D glad_glCopyTexSubImage2D -typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -GLAPI PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; -#define glTexSubImage1D glad_glTexSubImage1D -typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -GLAPI PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; -#define glTexSubImage2D glad_glTexSubImage2D -typedef void (APIENTRYP PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture); -GLAPI PFNGLBINDTEXTUREPROC glad_glBindTexture; -#define glBindTexture glad_glBindTexture -typedef void (APIENTRYP PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint *textures); -GLAPI PFNGLDELETETEXTURESPROC glad_glDeleteTextures; -#define glDeleteTextures glad_glDeleteTextures -typedef void (APIENTRYP PFNGLGENTEXTURESPROC)(GLsizei n, GLuint *textures); -GLAPI PFNGLGENTEXTURESPROC glad_glGenTextures; -#define glGenTextures glad_glGenTextures -typedef GLboolean (APIENTRYP PFNGLISTEXTUREPROC)(GLuint texture); -GLAPI PFNGLISTEXTUREPROC glad_glIsTexture; -#define glIsTexture glad_glIsTexture -typedef void (APIENTRYP PFNGLARRAYELEMENTPROC)(GLint i); -GLAPI PFNGLARRAYELEMENTPROC glad_glArrayElement; -#define glArrayElement glad_glArrayElement -typedef void (APIENTRYP PFNGLCOLORPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI PFNGLCOLORPOINTERPROC glad_glColorPointer; -#define glColorPointer glad_glColorPointer -typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEPROC)(GLenum array); -GLAPI PFNGLDISABLECLIENTSTATEPROC glad_glDisableClientState; -#define glDisableClientState glad_glDisableClientState -typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERPROC)(GLsizei stride, const void *pointer); -GLAPI PFNGLEDGEFLAGPOINTERPROC glad_glEdgeFlagPointer; -#define glEdgeFlagPointer glad_glEdgeFlagPointer -typedef void (APIENTRYP PFNGLENABLECLIENTSTATEPROC)(GLenum array); -GLAPI PFNGLENABLECLIENTSTATEPROC glad_glEnableClientState; -#define glEnableClientState glad_glEnableClientState -typedef void (APIENTRYP PFNGLINDEXPOINTERPROC)(GLenum type, GLsizei stride, const void *pointer); -GLAPI PFNGLINDEXPOINTERPROC glad_glIndexPointer; -#define glIndexPointer glad_glIndexPointer -typedef void (APIENTRYP PFNGLINTERLEAVEDARRAYSPROC)(GLenum format, GLsizei stride, const void *pointer); -GLAPI PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays; -#define glInterleavedArrays glad_glInterleavedArrays -typedef void (APIENTRYP PFNGLNORMALPOINTERPROC)(GLenum type, GLsizei stride, const void *pointer); -GLAPI PFNGLNORMALPOINTERPROC glad_glNormalPointer; -#define glNormalPointer glad_glNormalPointer -typedef void (APIENTRYP PFNGLTEXCOORDPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI PFNGLTEXCOORDPOINTERPROC glad_glTexCoordPointer; -#define glTexCoordPointer glad_glTexCoordPointer -typedef void (APIENTRYP PFNGLVERTEXPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI PFNGLVERTEXPOINTERPROC glad_glVertexPointer; -#define glVertexPointer glad_glVertexPointer -typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTPROC)(GLsizei n, const GLuint *textures, GLboolean *residences); -GLAPI PFNGLARETEXTURESRESIDENTPROC glad_glAreTexturesResident; -#define glAreTexturesResident glad_glAreTexturesResident -typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESPROC)(GLsizei n, const GLuint *textures, const GLfloat *priorities); -GLAPI PFNGLPRIORITIZETEXTURESPROC glad_glPrioritizeTextures; -#define glPrioritizeTextures glad_glPrioritizeTextures -typedef void (APIENTRYP PFNGLINDEXUBPROC)(GLubyte c); -GLAPI PFNGLINDEXUBPROC glad_glIndexub; -#define glIndexub glad_glIndexub -typedef void (APIENTRYP PFNGLINDEXUBVPROC)(const GLubyte *c); -GLAPI PFNGLINDEXUBVPROC glad_glIndexubv; -#define glIndexubv glad_glIndexubv -typedef void (APIENTRYP PFNGLPOPCLIENTATTRIBPROC)(void); -GLAPI PFNGLPOPCLIENTATTRIBPROC glad_glPopClientAttrib; -#define glPopClientAttrib glad_glPopClientAttrib -typedef void (APIENTRYP PFNGLPUSHCLIENTATTRIBPROC)(GLbitfield mask); -GLAPI PFNGLPUSHCLIENTATTRIBPROC glad_glPushClientAttrib; -#define glPushClientAttrib glad_glPushClientAttrib -#endif -#ifndef GL_VERSION_1_2 -#define GL_VERSION_1_2 1 -GLAPI int GLAD_GL_VERSION_1_2; -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); -GLAPI PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; -#define glDrawRangeElements glad_glDrawRangeElements -typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI PFNGLTEXIMAGE3DPROC glad_glTexImage3D; -#define glTexImage3D glad_glTexImage3D -typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -GLAPI PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; -#define glTexSubImage3D glad_glTexSubImage3D -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; -#define glCopyTexSubImage3D glad_glCopyTexSubImage3D -#endif -#ifndef GL_VERSION_1_3 -#define GL_VERSION_1_3 1 -GLAPI int GLAD_GL_VERSION_1_3; -typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC)(GLenum texture); -GLAPI PFNGLACTIVETEXTUREPROC glad_glActiveTexture; -#define glActiveTexture glad_glActiveTexture -typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC)(GLfloat value, GLboolean invert); -GLAPI PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; -#define glSampleCoverage glad_glSampleCoverage -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); -GLAPI PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; -#define glCompressedTexImage3D glad_glCompressedTexImage3D -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); -GLAPI PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; -#define glCompressedTexImage2D glad_glCompressedTexImage2D -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); -GLAPI PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; -#define glCompressedTexImage1D glad_glCompressedTexImage1D -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; -#define glCompressedTexSubImage3D glad_glCompressedTexSubImage3D -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; -#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; -#define glCompressedTexSubImage1D glad_glCompressedTexSubImage1D -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint level, void *img); -GLAPI PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; -#define glGetCompressedTexImage glad_glGetCompressedTexImage -typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC)(GLenum texture); -GLAPI PFNGLCLIENTACTIVETEXTUREPROC glad_glClientActiveTexture; -#define glClientActiveTexture glad_glClientActiveTexture -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC)(GLenum target, GLdouble s); -GLAPI PFNGLMULTITEXCOORD1DPROC glad_glMultiTexCoord1d; -#define glMultiTexCoord1d glad_glMultiTexCoord1d -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC)(GLenum target, const GLdouble *v); -GLAPI PFNGLMULTITEXCOORD1DVPROC glad_glMultiTexCoord1dv; -#define glMultiTexCoord1dv glad_glMultiTexCoord1dv -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC)(GLenum target, GLfloat s); -GLAPI PFNGLMULTITEXCOORD1FPROC glad_glMultiTexCoord1f; -#define glMultiTexCoord1f glad_glMultiTexCoord1f -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC)(GLenum target, const GLfloat *v); -GLAPI PFNGLMULTITEXCOORD1FVPROC glad_glMultiTexCoord1fv; -#define glMultiTexCoord1fv glad_glMultiTexCoord1fv -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC)(GLenum target, GLint s); -GLAPI PFNGLMULTITEXCOORD1IPROC glad_glMultiTexCoord1i; -#define glMultiTexCoord1i glad_glMultiTexCoord1i -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC)(GLenum target, const GLint *v); -GLAPI PFNGLMULTITEXCOORD1IVPROC glad_glMultiTexCoord1iv; -#define glMultiTexCoord1iv glad_glMultiTexCoord1iv -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC)(GLenum target, GLshort s); -GLAPI PFNGLMULTITEXCOORD1SPROC glad_glMultiTexCoord1s; -#define glMultiTexCoord1s glad_glMultiTexCoord1s -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC)(GLenum target, const GLshort *v); -GLAPI PFNGLMULTITEXCOORD1SVPROC glad_glMultiTexCoord1sv; -#define glMultiTexCoord1sv glad_glMultiTexCoord1sv -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC)(GLenum target, GLdouble s, GLdouble t); -GLAPI PFNGLMULTITEXCOORD2DPROC glad_glMultiTexCoord2d; -#define glMultiTexCoord2d glad_glMultiTexCoord2d -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC)(GLenum target, const GLdouble *v); -GLAPI PFNGLMULTITEXCOORD2DVPROC glad_glMultiTexCoord2dv; -#define glMultiTexCoord2dv glad_glMultiTexCoord2dv -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC)(GLenum target, GLfloat s, GLfloat t); -GLAPI PFNGLMULTITEXCOORD2FPROC glad_glMultiTexCoord2f; -#define glMultiTexCoord2f glad_glMultiTexCoord2f -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC)(GLenum target, const GLfloat *v); -GLAPI PFNGLMULTITEXCOORD2FVPROC glad_glMultiTexCoord2fv; -#define glMultiTexCoord2fv glad_glMultiTexCoord2fv -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC)(GLenum target, GLint s, GLint t); -GLAPI PFNGLMULTITEXCOORD2IPROC glad_glMultiTexCoord2i; -#define glMultiTexCoord2i glad_glMultiTexCoord2i -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC)(GLenum target, const GLint *v); -GLAPI PFNGLMULTITEXCOORD2IVPROC glad_glMultiTexCoord2iv; -#define glMultiTexCoord2iv glad_glMultiTexCoord2iv -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC)(GLenum target, GLshort s, GLshort t); -GLAPI PFNGLMULTITEXCOORD2SPROC glad_glMultiTexCoord2s; -#define glMultiTexCoord2s glad_glMultiTexCoord2s -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC)(GLenum target, const GLshort *v); -GLAPI PFNGLMULTITEXCOORD2SVPROC glad_glMultiTexCoord2sv; -#define glMultiTexCoord2sv glad_glMultiTexCoord2sv -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r); -GLAPI PFNGLMULTITEXCOORD3DPROC glad_glMultiTexCoord3d; -#define glMultiTexCoord3d glad_glMultiTexCoord3d -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC)(GLenum target, const GLdouble *v); -GLAPI PFNGLMULTITEXCOORD3DVPROC glad_glMultiTexCoord3dv; -#define glMultiTexCoord3dv glad_glMultiTexCoord3dv -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r); -GLAPI PFNGLMULTITEXCOORD3FPROC glad_glMultiTexCoord3f; -#define glMultiTexCoord3f glad_glMultiTexCoord3f -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC)(GLenum target, const GLfloat *v); -GLAPI PFNGLMULTITEXCOORD3FVPROC glad_glMultiTexCoord3fv; -#define glMultiTexCoord3fv glad_glMultiTexCoord3fv -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC)(GLenum target, GLint s, GLint t, GLint r); -GLAPI PFNGLMULTITEXCOORD3IPROC glad_glMultiTexCoord3i; -#define glMultiTexCoord3i glad_glMultiTexCoord3i -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC)(GLenum target, const GLint *v); -GLAPI PFNGLMULTITEXCOORD3IVPROC glad_glMultiTexCoord3iv; -#define glMultiTexCoord3iv glad_glMultiTexCoord3iv -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC)(GLenum target, GLshort s, GLshort t, GLshort r); -GLAPI PFNGLMULTITEXCOORD3SPROC glad_glMultiTexCoord3s; -#define glMultiTexCoord3s glad_glMultiTexCoord3s -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC)(GLenum target, const GLshort *v); -GLAPI PFNGLMULTITEXCOORD3SVPROC glad_glMultiTexCoord3sv; -#define glMultiTexCoord3sv glad_glMultiTexCoord3sv -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -GLAPI PFNGLMULTITEXCOORD4DPROC glad_glMultiTexCoord4d; -#define glMultiTexCoord4d glad_glMultiTexCoord4d -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC)(GLenum target, const GLdouble *v); -GLAPI PFNGLMULTITEXCOORD4DVPROC glad_glMultiTexCoord4dv; -#define glMultiTexCoord4dv glad_glMultiTexCoord4dv -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -GLAPI PFNGLMULTITEXCOORD4FPROC glad_glMultiTexCoord4f; -#define glMultiTexCoord4f glad_glMultiTexCoord4f -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC)(GLenum target, const GLfloat *v); -GLAPI PFNGLMULTITEXCOORD4FVPROC glad_glMultiTexCoord4fv; -#define glMultiTexCoord4fv glad_glMultiTexCoord4fv -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC)(GLenum target, GLint s, GLint t, GLint r, GLint q); -GLAPI PFNGLMULTITEXCOORD4IPROC glad_glMultiTexCoord4i; -#define glMultiTexCoord4i glad_glMultiTexCoord4i -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC)(GLenum target, const GLint *v); -GLAPI PFNGLMULTITEXCOORD4IVPROC glad_glMultiTexCoord4iv; -#define glMultiTexCoord4iv glad_glMultiTexCoord4iv -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC)(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -GLAPI PFNGLMULTITEXCOORD4SPROC glad_glMultiTexCoord4s; -#define glMultiTexCoord4s glad_glMultiTexCoord4s -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC)(GLenum target, const GLshort *v); -GLAPI PFNGLMULTITEXCOORD4SVPROC glad_glMultiTexCoord4sv; -#define glMultiTexCoord4sv glad_glMultiTexCoord4sv -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC)(const GLfloat *m); -GLAPI PFNGLLOADTRANSPOSEMATRIXFPROC glad_glLoadTransposeMatrixf; -#define glLoadTransposeMatrixf glad_glLoadTransposeMatrixf -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC)(const GLdouble *m); -GLAPI PFNGLLOADTRANSPOSEMATRIXDPROC glad_glLoadTransposeMatrixd; -#define glLoadTransposeMatrixd glad_glLoadTransposeMatrixd -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC)(const GLfloat *m); -GLAPI PFNGLMULTTRANSPOSEMATRIXFPROC glad_glMultTransposeMatrixf; -#define glMultTransposeMatrixf glad_glMultTransposeMatrixf -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC)(const GLdouble *m); -GLAPI PFNGLMULTTRANSPOSEMATRIXDPROC glad_glMultTransposeMatrixd; -#define glMultTransposeMatrixd glad_glMultTransposeMatrixd -#endif -#ifndef GL_VERSION_1_4 -#define GL_VERSION_1_4 1 -GLAPI int GLAD_GL_VERSION_1_4; -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -GLAPI PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; -#define glBlendFuncSeparate glad_glBlendFuncSeparate -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC)(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); -GLAPI PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; -#define glMultiDrawArrays glad_glMultiDrawArrays -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC)(GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount); -GLAPI PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; -#define glMultiDrawElements glad_glMultiDrawElements -typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC)(GLenum pname, GLfloat param); -GLAPI PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; -#define glPointParameterf glad_glPointParameterf -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC)(GLenum pname, const GLfloat *params); -GLAPI PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; -#define glPointParameterfv glad_glPointParameterfv -typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC)(GLenum pname, GLint param); -GLAPI PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; -#define glPointParameteri glad_glPointParameteri -typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC)(GLenum pname, const GLint *params); -GLAPI PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; -#define glPointParameteriv glad_glPointParameteriv -typedef void (APIENTRYP PFNGLFOGCOORDFPROC)(GLfloat coord); -GLAPI PFNGLFOGCOORDFPROC glad_glFogCoordf; -#define glFogCoordf glad_glFogCoordf -typedef void (APIENTRYP PFNGLFOGCOORDFVPROC)(const GLfloat *coord); -GLAPI PFNGLFOGCOORDFVPROC glad_glFogCoordfv; -#define glFogCoordfv glad_glFogCoordfv -typedef void (APIENTRYP PFNGLFOGCOORDDPROC)(GLdouble coord); -GLAPI PFNGLFOGCOORDDPROC glad_glFogCoordd; -#define glFogCoordd glad_glFogCoordd -typedef void (APIENTRYP PFNGLFOGCOORDDVPROC)(const GLdouble *coord); -GLAPI PFNGLFOGCOORDDVPROC glad_glFogCoorddv; -#define glFogCoorddv glad_glFogCoorddv -typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC)(GLenum type, GLsizei stride, const void *pointer); -GLAPI PFNGLFOGCOORDPOINTERPROC glad_glFogCoordPointer; -#define glFogCoordPointer glad_glFogCoordPointer -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC)(GLbyte red, GLbyte green, GLbyte blue); -GLAPI PFNGLSECONDARYCOLOR3BPROC glad_glSecondaryColor3b; -#define glSecondaryColor3b glad_glSecondaryColor3b -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC)(const GLbyte *v); -GLAPI PFNGLSECONDARYCOLOR3BVPROC glad_glSecondaryColor3bv; -#define glSecondaryColor3bv glad_glSecondaryColor3bv -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC)(GLdouble red, GLdouble green, GLdouble blue); -GLAPI PFNGLSECONDARYCOLOR3DPROC glad_glSecondaryColor3d; -#define glSecondaryColor3d glad_glSecondaryColor3d -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC)(const GLdouble *v); -GLAPI PFNGLSECONDARYCOLOR3DVPROC glad_glSecondaryColor3dv; -#define glSecondaryColor3dv glad_glSecondaryColor3dv -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC)(GLfloat red, GLfloat green, GLfloat blue); -GLAPI PFNGLSECONDARYCOLOR3FPROC glad_glSecondaryColor3f; -#define glSecondaryColor3f glad_glSecondaryColor3f -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC)(const GLfloat *v); -GLAPI PFNGLSECONDARYCOLOR3FVPROC glad_glSecondaryColor3fv; -#define glSecondaryColor3fv glad_glSecondaryColor3fv -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC)(GLint red, GLint green, GLint blue); -GLAPI PFNGLSECONDARYCOLOR3IPROC glad_glSecondaryColor3i; -#define glSecondaryColor3i glad_glSecondaryColor3i -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC)(const GLint *v); -GLAPI PFNGLSECONDARYCOLOR3IVPROC glad_glSecondaryColor3iv; -#define glSecondaryColor3iv glad_glSecondaryColor3iv -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC)(GLshort red, GLshort green, GLshort blue); -GLAPI PFNGLSECONDARYCOLOR3SPROC glad_glSecondaryColor3s; -#define glSecondaryColor3s glad_glSecondaryColor3s -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC)(const GLshort *v); -GLAPI PFNGLSECONDARYCOLOR3SVPROC glad_glSecondaryColor3sv; -#define glSecondaryColor3sv glad_glSecondaryColor3sv -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC)(GLubyte red, GLubyte green, GLubyte blue); -GLAPI PFNGLSECONDARYCOLOR3UBPROC glad_glSecondaryColor3ub; -#define glSecondaryColor3ub glad_glSecondaryColor3ub -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC)(const GLubyte *v); -GLAPI PFNGLSECONDARYCOLOR3UBVPROC glad_glSecondaryColor3ubv; -#define glSecondaryColor3ubv glad_glSecondaryColor3ubv -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC)(GLuint red, GLuint green, GLuint blue); -GLAPI PFNGLSECONDARYCOLOR3UIPROC glad_glSecondaryColor3ui; -#define glSecondaryColor3ui glad_glSecondaryColor3ui -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC)(const GLuint *v); -GLAPI PFNGLSECONDARYCOLOR3UIVPROC glad_glSecondaryColor3uiv; -#define glSecondaryColor3uiv glad_glSecondaryColor3uiv -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC)(GLushort red, GLushort green, GLushort blue); -GLAPI PFNGLSECONDARYCOLOR3USPROC glad_glSecondaryColor3us; -#define glSecondaryColor3us glad_glSecondaryColor3us -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC)(const GLushort *v); -GLAPI PFNGLSECONDARYCOLOR3USVPROC glad_glSecondaryColor3usv; -#define glSecondaryColor3usv glad_glSecondaryColor3usv -typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI PFNGLSECONDARYCOLORPOINTERPROC glad_glSecondaryColorPointer; -#define glSecondaryColorPointer glad_glSecondaryColorPointer -typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC)(GLdouble x, GLdouble y); -GLAPI PFNGLWINDOWPOS2DPROC glad_glWindowPos2d; -#define glWindowPos2d glad_glWindowPos2d -typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC)(const GLdouble *v); -GLAPI PFNGLWINDOWPOS2DVPROC glad_glWindowPos2dv; -#define glWindowPos2dv glad_glWindowPos2dv -typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC)(GLfloat x, GLfloat y); -GLAPI PFNGLWINDOWPOS2FPROC glad_glWindowPos2f; -#define glWindowPos2f glad_glWindowPos2f -typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC)(const GLfloat *v); -GLAPI PFNGLWINDOWPOS2FVPROC glad_glWindowPos2fv; -#define glWindowPos2fv glad_glWindowPos2fv -typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC)(GLint x, GLint y); -GLAPI PFNGLWINDOWPOS2IPROC glad_glWindowPos2i; -#define glWindowPos2i glad_glWindowPos2i -typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC)(const GLint *v); -GLAPI PFNGLWINDOWPOS2IVPROC glad_glWindowPos2iv; -#define glWindowPos2iv glad_glWindowPos2iv -typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC)(GLshort x, GLshort y); -GLAPI PFNGLWINDOWPOS2SPROC glad_glWindowPos2s; -#define glWindowPos2s glad_glWindowPos2s -typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC)(const GLshort *v); -GLAPI PFNGLWINDOWPOS2SVPROC glad_glWindowPos2sv; -#define glWindowPos2sv glad_glWindowPos2sv -typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC)(GLdouble x, GLdouble y, GLdouble z); -GLAPI PFNGLWINDOWPOS3DPROC glad_glWindowPos3d; -#define glWindowPos3d glad_glWindowPos3d -typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC)(const GLdouble *v); -GLAPI PFNGLWINDOWPOS3DVPROC glad_glWindowPos3dv; -#define glWindowPos3dv glad_glWindowPos3dv -typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC)(GLfloat x, GLfloat y, GLfloat z); -GLAPI PFNGLWINDOWPOS3FPROC glad_glWindowPos3f; -#define glWindowPos3f glad_glWindowPos3f -typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC)(const GLfloat *v); -GLAPI PFNGLWINDOWPOS3FVPROC glad_glWindowPos3fv; -#define glWindowPos3fv glad_glWindowPos3fv -typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC)(GLint x, GLint y, GLint z); -GLAPI PFNGLWINDOWPOS3IPROC glad_glWindowPos3i; -#define glWindowPos3i glad_glWindowPos3i -typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC)(const GLint *v); -GLAPI PFNGLWINDOWPOS3IVPROC glad_glWindowPos3iv; -#define glWindowPos3iv glad_glWindowPos3iv -typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC)(GLshort x, GLshort y, GLshort z); -GLAPI PFNGLWINDOWPOS3SPROC glad_glWindowPos3s; -#define glWindowPos3s glad_glWindowPos3s -typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC)(const GLshort *v); -GLAPI PFNGLWINDOWPOS3SVPROC glad_glWindowPos3sv; -#define glWindowPos3sv glad_glWindowPos3sv -typedef void (APIENTRYP PFNGLBLENDCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -GLAPI PFNGLBLENDCOLORPROC glad_glBlendColor; -#define glBlendColor glad_glBlendColor -typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC)(GLenum mode); -GLAPI PFNGLBLENDEQUATIONPROC glad_glBlendEquation; -#define glBlendEquation glad_glBlendEquation -#endif -#ifndef GL_VERSION_1_5 -#define GL_VERSION_1_5 1 -GLAPI int GLAD_GL_VERSION_1_5; -typedef void (APIENTRYP PFNGLGENQUERIESPROC)(GLsizei n, GLuint *ids); -GLAPI PFNGLGENQUERIESPROC glad_glGenQueries; -#define glGenQueries glad_glGenQueries -typedef void (APIENTRYP PFNGLDELETEQUERIESPROC)(GLsizei n, const GLuint *ids); -GLAPI PFNGLDELETEQUERIESPROC glad_glDeleteQueries; -#define glDeleteQueries glad_glDeleteQueries -typedef GLboolean (APIENTRYP PFNGLISQUERYPROC)(GLuint id); -GLAPI PFNGLISQUERYPROC glad_glIsQuery; -#define glIsQuery glad_glIsQuery -typedef void (APIENTRYP PFNGLBEGINQUERYPROC)(GLenum target, GLuint id); -GLAPI PFNGLBEGINQUERYPROC glad_glBeginQuery; -#define glBeginQuery glad_glBeginQuery -typedef void (APIENTRYP PFNGLENDQUERYPROC)(GLenum target); -GLAPI PFNGLENDQUERYPROC glad_glEndQuery; -#define glEndQuery glad_glEndQuery -typedef void (APIENTRYP PFNGLGETQUERYIVPROC)(GLenum target, GLenum pname, GLint *params); -GLAPI PFNGLGETQUERYIVPROC glad_glGetQueryiv; -#define glGetQueryiv glad_glGetQueryiv -typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC)(GLuint id, GLenum pname, GLint *params); -GLAPI PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; -#define glGetQueryObjectiv glad_glGetQueryObjectiv -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC)(GLuint id, GLenum pname, GLuint *params); -GLAPI PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; -#define glGetQueryObjectuiv glad_glGetQueryObjectuiv -typedef void (APIENTRYP PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer); -GLAPI PFNGLBINDBUFFERPROC glad_glBindBuffer; -#define glBindBuffer glad_glBindBuffer -typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint *buffers); -GLAPI PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; -#define glDeleteBuffers glad_glDeleteBuffers -typedef void (APIENTRYP PFNGLGENBUFFERSPROC)(GLsizei n, GLuint *buffers); -GLAPI PFNGLGENBUFFERSPROC glad_glGenBuffers; -#define glGenBuffers glad_glGenBuffers -typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC)(GLuint buffer); -GLAPI PFNGLISBUFFERPROC glad_glIsBuffer; -#define glIsBuffer glad_glIsBuffer -typedef void (APIENTRYP PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void *data, GLenum usage); -GLAPI PFNGLBUFFERDATAPROC glad_glBufferData; -#define glBufferData glad_glBufferData -typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, const void *data); -GLAPI PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; -#define glBufferSubData glad_glBufferSubData -typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, void *data); -GLAPI PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; -#define glGetBufferSubData glad_glGetBufferSubData -typedef void * (APIENTRYP PFNGLMAPBUFFERPROC)(GLenum target, GLenum access); -GLAPI PFNGLMAPBUFFERPROC glad_glMapBuffer; -#define glMapBuffer glad_glMapBuffer -typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC)(GLenum target); -GLAPI PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; -#define glUnmapBuffer glad_glUnmapBuffer -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint *params); -GLAPI PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; -#define glGetBufferParameteriv glad_glGetBufferParameteriv -typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC)(GLenum target, GLenum pname, void **params); -GLAPI PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; -#define glGetBufferPointerv glad_glGetBufferPointerv -#endif -#ifndef GL_VERSION_2_0 -#define GL_VERSION_2_0 1 -GLAPI int GLAD_GL_VERSION_2_0; -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha); -GLAPI PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; -#define glBlendEquationSeparate glad_glBlendEquationSeparate -typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC)(GLsizei n, const GLenum *bufs); -GLAPI PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; -#define glDrawBuffers glad_glDrawBuffers -typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -GLAPI PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; -#define glStencilOpSeparate glad_glStencilOpSeparate -typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC)(GLenum face, GLenum func, GLint ref, GLuint mask); -GLAPI PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; -#define glStencilFuncSeparate glad_glStencilFuncSeparate -typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC)(GLenum face, GLuint mask); -GLAPI PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; -#define glStencilMaskSeparate glad_glStencilMaskSeparate -typedef void (APIENTRYP PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader); -GLAPI PFNGLATTACHSHADERPROC glad_glAttachShader; -#define glAttachShader glad_glAttachShader -typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar *name); -GLAPI PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; -#define glBindAttribLocation glad_glBindAttribLocation -typedef void (APIENTRYP PFNGLCOMPILESHADERPROC)(GLuint shader); -GLAPI PFNGLCOMPILESHADERPROC glad_glCompileShader; -#define glCompileShader glad_glCompileShader -typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC)(void); -GLAPI PFNGLCREATEPROGRAMPROC glad_glCreateProgram; -#define glCreateProgram glad_glCreateProgram -typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC)(GLenum type); -GLAPI PFNGLCREATESHADERPROC glad_glCreateShader; -#define glCreateShader glad_glCreateShader -typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC)(GLuint program); -GLAPI PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; -#define glDeleteProgram glad_glDeleteProgram -typedef void (APIENTRYP PFNGLDELETESHADERPROC)(GLuint shader); -GLAPI PFNGLDELETESHADERPROC glad_glDeleteShader; -#define glDeleteShader glad_glDeleteShader -typedef void (APIENTRYP PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader); -GLAPI PFNGLDETACHSHADERPROC glad_glDetachShader; -#define glDetachShader glad_glDetachShader -typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index); -GLAPI PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; -#define glDisableVertexAttribArray glad_glDisableVertexAttribArray -typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index); -GLAPI PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; -#define glEnableVertexAttribArray glad_glEnableVertexAttribArray -typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -GLAPI PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; -#define glGetActiveAttrib glad_glGetActiveAttrib -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -GLAPI PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; -#define glGetActiveUniform glad_glGetActiveUniform -typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC)(GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); -GLAPI PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; -#define glGetAttachedShaders glad_glGetAttachedShaders -typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar *name); -GLAPI PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; -#define glGetAttribLocation glad_glGetAttribLocation -typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint *params); -GLAPI PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; -#define glGetProgramiv glad_glGetProgramiv -typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -GLAPI PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; -#define glGetProgramInfoLog glad_glGetProgramInfoLog -typedef void (APIENTRYP PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint *params); -GLAPI PFNGLGETSHADERIVPROC glad_glGetShaderiv; -#define glGetShaderiv glad_glGetShaderiv -typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -GLAPI PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; -#define glGetShaderInfoLog glad_glGetShaderInfoLog -typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); -GLAPI PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; -#define glGetShaderSource glad_glGetShaderSource -typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar *name); -GLAPI PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; -#define glGetUniformLocation glad_glGetUniformLocation -typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC)(GLuint program, GLint location, GLfloat *params); -GLAPI PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; -#define glGetUniformfv glad_glGetUniformfv -typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC)(GLuint program, GLint location, GLint *params); -GLAPI PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; -#define glGetUniformiv glad_glGetUniformiv -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC)(GLuint index, GLenum pname, GLdouble *params); -GLAPI PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; -#define glGetVertexAttribdv glad_glGetVertexAttribdv -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC)(GLuint index, GLenum pname, GLfloat *params); -GLAPI PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; -#define glGetVertexAttribfv glad_glGetVertexAttribfv -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint *params); -GLAPI PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; -#define glGetVertexAttribiv glad_glGetVertexAttribiv -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void **pointer); -GLAPI PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; -#define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv -typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC)(GLuint program); -GLAPI PFNGLISPROGRAMPROC glad_glIsProgram; -#define glIsProgram glad_glIsProgram -typedef GLboolean (APIENTRYP PFNGLISSHADERPROC)(GLuint shader); -GLAPI PFNGLISSHADERPROC glad_glIsShader; -#define glIsShader glad_glIsShader -typedef void (APIENTRYP PFNGLLINKPROGRAMPROC)(GLuint program); -GLAPI PFNGLLINKPROGRAMPROC glad_glLinkProgram; -#define glLinkProgram glad_glLinkProgram -typedef void (APIENTRYP PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); -GLAPI PFNGLSHADERSOURCEPROC glad_glShaderSource; -#define glShaderSource glad_glShaderSource -typedef void (APIENTRYP PFNGLUSEPROGRAMPROC)(GLuint program); -GLAPI PFNGLUSEPROGRAMPROC glad_glUseProgram; -#define glUseProgram glad_glUseProgram -typedef void (APIENTRYP PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0); -GLAPI PFNGLUNIFORM1FPROC glad_glUniform1f; -#define glUniform1f glad_glUniform1f -typedef void (APIENTRYP PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1); -GLAPI PFNGLUNIFORM2FPROC glad_glUniform2f; -#define glUniform2f glad_glUniform2f -typedef void (APIENTRYP PFNGLUNIFORM3FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -GLAPI PFNGLUNIFORM3FPROC glad_glUniform3f; -#define glUniform3f glad_glUniform3f -typedef void (APIENTRYP PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -GLAPI PFNGLUNIFORM4FPROC glad_glUniform4f; -#define glUniform4f glad_glUniform4f -typedef void (APIENTRYP PFNGLUNIFORM1IPROC)(GLint location, GLint v0); -GLAPI PFNGLUNIFORM1IPROC glad_glUniform1i; -#define glUniform1i glad_glUniform1i -typedef void (APIENTRYP PFNGLUNIFORM2IPROC)(GLint location, GLint v0, GLint v1); -GLAPI PFNGLUNIFORM2IPROC glad_glUniform2i; -#define glUniform2i glad_glUniform2i -typedef void (APIENTRYP PFNGLUNIFORM3IPROC)(GLint location, GLint v0, GLint v1, GLint v2); -GLAPI PFNGLUNIFORM3IPROC glad_glUniform3i; -#define glUniform3i glad_glUniform3i -typedef void (APIENTRYP PFNGLUNIFORM4IPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -GLAPI PFNGLUNIFORM4IPROC glad_glUniform4i; -#define glUniform4i glad_glUniform4i -typedef void (APIENTRYP PFNGLUNIFORM1FVPROC)(GLint location, GLsizei count, const GLfloat *value); -GLAPI PFNGLUNIFORM1FVPROC glad_glUniform1fv; -#define glUniform1fv glad_glUniform1fv -typedef void (APIENTRYP PFNGLUNIFORM2FVPROC)(GLint location, GLsizei count, const GLfloat *value); -GLAPI PFNGLUNIFORM2FVPROC glad_glUniform2fv; -#define glUniform2fv glad_glUniform2fv -typedef void (APIENTRYP PFNGLUNIFORM3FVPROC)(GLint location, GLsizei count, const GLfloat *value); -GLAPI PFNGLUNIFORM3FVPROC glad_glUniform3fv; -#define glUniform3fv glad_glUniform3fv -typedef void (APIENTRYP PFNGLUNIFORM4FVPROC)(GLint location, GLsizei count, const GLfloat *value); -GLAPI PFNGLUNIFORM4FVPROC glad_glUniform4fv; -#define glUniform4fv glad_glUniform4fv -typedef void (APIENTRYP PFNGLUNIFORM1IVPROC)(GLint location, GLsizei count, const GLint *value); -GLAPI PFNGLUNIFORM1IVPROC glad_glUniform1iv; -#define glUniform1iv glad_glUniform1iv -typedef void (APIENTRYP PFNGLUNIFORM2IVPROC)(GLint location, GLsizei count, const GLint *value); -GLAPI PFNGLUNIFORM2IVPROC glad_glUniform2iv; -#define glUniform2iv glad_glUniform2iv -typedef void (APIENTRYP PFNGLUNIFORM3IVPROC)(GLint location, GLsizei count, const GLint *value); -GLAPI PFNGLUNIFORM3IVPROC glad_glUniform3iv; -#define glUniform3iv glad_glUniform3iv -typedef void (APIENTRYP PFNGLUNIFORM4IVPROC)(GLint location, GLsizei count, const GLint *value); -GLAPI PFNGLUNIFORM4IVPROC glad_glUniform4iv; -#define glUniform4iv glad_glUniform4iv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; -#define glUniformMatrix2fv glad_glUniformMatrix2fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; -#define glUniformMatrix3fv glad_glUniformMatrix3fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; -#define glUniformMatrix4fv glad_glUniformMatrix4fv -typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC)(GLuint program); -GLAPI PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; -#define glValidateProgram glad_glValidateProgram -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC)(GLuint index, GLdouble x); -GLAPI PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; -#define glVertexAttrib1d glad_glVertexAttrib1d -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC)(GLuint index, const GLdouble *v); -GLAPI PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; -#define glVertexAttrib1dv glad_glVertexAttrib1dv -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC)(GLuint index, GLfloat x); -GLAPI PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; -#define glVertexAttrib1f glad_glVertexAttrib1f -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC)(GLuint index, const GLfloat *v); -GLAPI PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; -#define glVertexAttrib1fv glad_glVertexAttrib1fv -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC)(GLuint index, GLshort x); -GLAPI PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; -#define glVertexAttrib1s glad_glVertexAttrib1s -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC)(GLuint index, const GLshort *v); -GLAPI PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; -#define glVertexAttrib1sv glad_glVertexAttrib1sv -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC)(GLuint index, GLdouble x, GLdouble y); -GLAPI PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; -#define glVertexAttrib2d glad_glVertexAttrib2d -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC)(GLuint index, const GLdouble *v); -GLAPI PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; -#define glVertexAttrib2dv glad_glVertexAttrib2dv -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC)(GLuint index, GLfloat x, GLfloat y); -GLAPI PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; -#define glVertexAttrib2f glad_glVertexAttrib2f -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC)(GLuint index, const GLfloat *v); -GLAPI PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; -#define glVertexAttrib2fv glad_glVertexAttrib2fv -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC)(GLuint index, GLshort x, GLshort y); -GLAPI PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; -#define glVertexAttrib2s glad_glVertexAttrib2s -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC)(GLuint index, const GLshort *v); -GLAPI PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; -#define glVertexAttrib2sv glad_glVertexAttrib2sv -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z); -GLAPI PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; -#define glVertexAttrib3d glad_glVertexAttrib3d -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC)(GLuint index, const GLdouble *v); -GLAPI PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; -#define glVertexAttrib3dv glad_glVertexAttrib3dv -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z); -GLAPI PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; -#define glVertexAttrib3f glad_glVertexAttrib3f -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC)(GLuint index, const GLfloat *v); -GLAPI PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; -#define glVertexAttrib3fv glad_glVertexAttrib3fv -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC)(GLuint index, GLshort x, GLshort y, GLshort z); -GLAPI PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; -#define glVertexAttrib3s glad_glVertexAttrib3s -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC)(GLuint index, const GLshort *v); -GLAPI PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; -#define glVertexAttrib3sv glad_glVertexAttrib3sv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC)(GLuint index, const GLbyte *v); -GLAPI PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; -#define glVertexAttrib4Nbv glad_glVertexAttrib4Nbv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC)(GLuint index, const GLint *v); -GLAPI PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; -#define glVertexAttrib4Niv glad_glVertexAttrib4Niv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC)(GLuint index, const GLshort *v); -GLAPI PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; -#define glVertexAttrib4Nsv glad_glVertexAttrib4Nsv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -GLAPI PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; -#define glVertexAttrib4Nub glad_glVertexAttrib4Nub -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC)(GLuint index, const GLubyte *v); -GLAPI PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; -#define glVertexAttrib4Nubv glad_glVertexAttrib4Nubv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC)(GLuint index, const GLuint *v); -GLAPI PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; -#define glVertexAttrib4Nuiv glad_glVertexAttrib4Nuiv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC)(GLuint index, const GLushort *v); -GLAPI PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; -#define glVertexAttrib4Nusv glad_glVertexAttrib4Nusv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC)(GLuint index, const GLbyte *v); -GLAPI PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; -#define glVertexAttrib4bv glad_glVertexAttrib4bv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; -#define glVertexAttrib4d glad_glVertexAttrib4d -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC)(GLuint index, const GLdouble *v); -GLAPI PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; -#define glVertexAttrib4dv glad_glVertexAttrib4dv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; -#define glVertexAttrib4f glad_glVertexAttrib4f -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC)(GLuint index, const GLfloat *v); -GLAPI PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; -#define glVertexAttrib4fv glad_glVertexAttrib4fv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC)(GLuint index, const GLint *v); -GLAPI PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; -#define glVertexAttrib4iv glad_glVertexAttrib4iv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; -#define glVertexAttrib4s glad_glVertexAttrib4s -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC)(GLuint index, const GLshort *v); -GLAPI PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; -#define glVertexAttrib4sv glad_glVertexAttrib4sv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC)(GLuint index, const GLubyte *v); -GLAPI PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; -#define glVertexAttrib4ubv glad_glVertexAttrib4ubv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC)(GLuint index, const GLuint *v); -GLAPI PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; -#define glVertexAttrib4uiv glad_glVertexAttrib4uiv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC)(GLuint index, const GLushort *v); -GLAPI PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; -#define glVertexAttrib4usv glad_glVertexAttrib4usv -typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); -GLAPI PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; -#define glVertexAttribPointer glad_glVertexAttribPointer -#endif -#ifndef GL_VERSION_2_1 -#define GL_VERSION_2_1 1 -GLAPI int GLAD_GL_VERSION_2_1; -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; -#define glUniformMatrix2x3fv glad_glUniformMatrix2x3fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; -#define glUniformMatrix3x2fv glad_glUniformMatrix3x2fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; -#define glUniformMatrix2x4fv glad_glUniformMatrix2x4fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; -#define glUniformMatrix4x2fv glad_glUniformMatrix4x2fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; -#define glUniformMatrix3x4fv glad_glUniformMatrix3x4fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; -#define glUniformMatrix4x3fv glad_glUniformMatrix4x3fv -#endif -#ifndef GL_VERSION_3_0 -#define GL_VERSION_3_0 1 -GLAPI int GLAD_GL_VERSION_3_0; -typedef void (APIENTRYP PFNGLCOLORMASKIPROC)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -GLAPI PFNGLCOLORMASKIPROC glad_glColorMaski; -#define glColorMaski glad_glColorMaski -typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC)(GLenum target, GLuint index, GLboolean *data); -GLAPI PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; -#define glGetBooleani_v glad_glGetBooleani_v -typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC)(GLenum target, GLuint index, GLint *data); -GLAPI PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; -#define glGetIntegeri_v glad_glGetIntegeri_v -typedef void (APIENTRYP PFNGLENABLEIPROC)(GLenum target, GLuint index); -GLAPI PFNGLENABLEIPROC glad_glEnablei; -#define glEnablei glad_glEnablei -typedef void (APIENTRYP PFNGLDISABLEIPROC)(GLenum target, GLuint index); -GLAPI PFNGLDISABLEIPROC glad_glDisablei; -#define glDisablei glad_glDisablei -typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC)(GLenum target, GLuint index); -GLAPI PFNGLISENABLEDIPROC glad_glIsEnabledi; -#define glIsEnabledi glad_glIsEnabledi -typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum primitiveMode); -GLAPI PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; -#define glBeginTransformFeedback glad_glBeginTransformFeedback -typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC)(void); -GLAPI PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; -#define glEndTransformFeedback glad_glEndTransformFeedback -typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -GLAPI PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; -#define glBindBufferRange glad_glBindBufferRange -typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC)(GLenum target, GLuint index, GLuint buffer); -GLAPI PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; -#define glBindBufferBase glad_glBindBufferBase -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC)(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); -GLAPI PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; -#define glTransformFeedbackVaryings glad_glTransformFeedbackVaryings -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -GLAPI PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; -#define glGetTransformFeedbackVarying glad_glGetTransformFeedbackVarying -typedef void (APIENTRYP PFNGLCLAMPCOLORPROC)(GLenum target, GLenum clamp); -GLAPI PFNGLCLAMPCOLORPROC glad_glClampColor; -#define glClampColor glad_glClampColor -typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC)(GLuint id, GLenum mode); -GLAPI PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender; -#define glBeginConditionalRender glad_glBeginConditionalRender -typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC)(void); -GLAPI PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender; -#define glEndConditionalRender glad_glEndConditionalRender -typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; -#define glVertexAttribIPointer glad_glVertexAttribIPointer -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC)(GLuint index, GLenum pname, GLint *params); -GLAPI PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; -#define glGetVertexAttribIiv glad_glGetVertexAttribIiv -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint index, GLenum pname, GLuint *params); -GLAPI PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; -#define glGetVertexAttribIuiv glad_glGetVertexAttribIuiv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC)(GLuint index, GLint x); -GLAPI PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; -#define glVertexAttribI1i glad_glVertexAttribI1i -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC)(GLuint index, GLint x, GLint y); -GLAPI PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; -#define glVertexAttribI2i glad_glVertexAttribI2i -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC)(GLuint index, GLint x, GLint y, GLint z); -GLAPI PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; -#define glVertexAttribI3i glad_glVertexAttribI3i -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC)(GLuint index, GLint x, GLint y, GLint z, GLint w); -GLAPI PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; -#define glVertexAttribI4i glad_glVertexAttribI4i -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC)(GLuint index, GLuint x); -GLAPI PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; -#define glVertexAttribI1ui glad_glVertexAttribI1ui -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC)(GLuint index, GLuint x, GLuint y); -GLAPI PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; -#define glVertexAttribI2ui glad_glVertexAttribI2ui -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z); -GLAPI PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; -#define glVertexAttribI3ui glad_glVertexAttribI3ui -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -GLAPI PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; -#define glVertexAttribI4ui glad_glVertexAttribI4ui -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC)(GLuint index, const GLint *v); -GLAPI PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; -#define glVertexAttribI1iv glad_glVertexAttribI1iv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC)(GLuint index, const GLint *v); -GLAPI PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; -#define glVertexAttribI2iv glad_glVertexAttribI2iv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC)(GLuint index, const GLint *v); -GLAPI PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; -#define glVertexAttribI3iv glad_glVertexAttribI3iv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC)(GLuint index, const GLint *v); -GLAPI PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; -#define glVertexAttribI4iv glad_glVertexAttribI4iv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC)(GLuint index, const GLuint *v); -GLAPI PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; -#define glVertexAttribI1uiv glad_glVertexAttribI1uiv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC)(GLuint index, const GLuint *v); -GLAPI PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; -#define glVertexAttribI2uiv glad_glVertexAttribI2uiv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC)(GLuint index, const GLuint *v); -GLAPI PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; -#define glVertexAttribI3uiv glad_glVertexAttribI3uiv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC)(GLuint index, const GLuint *v); -GLAPI PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; -#define glVertexAttribI4uiv glad_glVertexAttribI4uiv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC)(GLuint index, const GLbyte *v); -GLAPI PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; -#define glVertexAttribI4bv glad_glVertexAttribI4bv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC)(GLuint index, const GLshort *v); -GLAPI PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; -#define glVertexAttribI4sv glad_glVertexAttribI4sv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC)(GLuint index, const GLubyte *v); -GLAPI PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; -#define glVertexAttribI4ubv glad_glVertexAttribI4ubv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC)(GLuint index, const GLushort *v); -GLAPI PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; -#define glVertexAttribI4usv glad_glVertexAttribI4usv -typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC)(GLuint program, GLint location, GLuint *params); -GLAPI PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; -#define glGetUniformuiv glad_glGetUniformuiv -typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC)(GLuint program, GLuint color, const GLchar *name); -GLAPI PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation; -#define glBindFragDataLocation glad_glBindFragDataLocation -typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC)(GLuint program, const GLchar *name); -GLAPI PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; -#define glGetFragDataLocation glad_glGetFragDataLocation -typedef void (APIENTRYP PFNGLUNIFORM1UIPROC)(GLint location, GLuint v0); -GLAPI PFNGLUNIFORM1UIPROC glad_glUniform1ui; -#define glUniform1ui glad_glUniform1ui -typedef void (APIENTRYP PFNGLUNIFORM2UIPROC)(GLint location, GLuint v0, GLuint v1); -GLAPI PFNGLUNIFORM2UIPROC glad_glUniform2ui; -#define glUniform2ui glad_glUniform2ui -typedef void (APIENTRYP PFNGLUNIFORM3UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2); -GLAPI PFNGLUNIFORM3UIPROC glad_glUniform3ui; -#define glUniform3ui glad_glUniform3ui -typedef void (APIENTRYP PFNGLUNIFORM4UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -GLAPI PFNGLUNIFORM4UIPROC glad_glUniform4ui; -#define glUniform4ui glad_glUniform4ui -typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC)(GLint location, GLsizei count, const GLuint *value); -GLAPI PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; -#define glUniform1uiv glad_glUniform1uiv -typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC)(GLint location, GLsizei count, const GLuint *value); -GLAPI PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; -#define glUniform2uiv glad_glUniform2uiv -typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC)(GLint location, GLsizei count, const GLuint *value); -GLAPI PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; -#define glUniform3uiv glad_glUniform3uiv -typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC)(GLint location, GLsizei count, const GLuint *value); -GLAPI PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; -#define glUniform4uiv glad_glUniform4uiv -typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, const GLint *params); -GLAPI PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; -#define glTexParameterIiv glad_glTexParameterIiv -typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, const GLuint *params); -GLAPI PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; -#define glTexParameterIuiv glad_glTexParameterIuiv -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, GLint *params); -GLAPI PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; -#define glGetTexParameterIiv glad_glGetTexParameterIiv -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, GLuint *params); -GLAPI PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; -#define glGetTexParameterIuiv glad_glGetTexParameterIuiv -typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC)(GLenum buffer, GLint drawbuffer, const GLint *value); -GLAPI PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; -#define glClearBufferiv glad_glClearBufferiv -typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC)(GLenum buffer, GLint drawbuffer, const GLuint *value); -GLAPI PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; -#define glClearBufferuiv glad_glClearBufferuiv -typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC)(GLenum buffer, GLint drawbuffer, const GLfloat *value); -GLAPI PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; -#define glClearBufferfv glad_glClearBufferfv -typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); -GLAPI PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; -#define glClearBufferfi glad_glClearBufferfi -typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGIPROC)(GLenum name, GLuint index); -GLAPI PFNGLGETSTRINGIPROC glad_glGetStringi; -#define glGetStringi glad_glGetStringi -typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer); -GLAPI PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; -#define glIsRenderbuffer glad_glIsRenderbuffer -typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer); -GLAPI PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; -#define glBindRenderbuffer glad_glBindRenderbuffer -typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint *renderbuffers); -GLAPI PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; -#define glDeleteRenderbuffers glad_glDeleteRenderbuffers -typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint *renderbuffers); -GLAPI PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; -#define glGenRenderbuffers glad_glGenRenderbuffers -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; -#define glRenderbufferStorage glad_glRenderbufferStorage -typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint *params); -GLAPI PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; -#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv -typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC)(GLuint framebuffer); -GLAPI PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; -#define glIsFramebuffer glad_glIsFramebuffer -typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer); -GLAPI PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; -#define glBindFramebuffer glad_glBindFramebuffer -typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint *framebuffers); -GLAPI PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; -#define glDeleteFramebuffers glad_glDeleteFramebuffers -typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint *framebuffers); -GLAPI PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; -#define glGenFramebuffers glad_glGenFramebuffers -typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target); -GLAPI PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; -#define glCheckFramebufferStatus glad_glCheckFramebufferStatus -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; -#define glFramebufferTexture1D glad_glFramebufferTexture1D -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; -#define glFramebufferTexture2D glad_glFramebufferTexture2D -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -GLAPI PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; -#define glFramebufferTexture3D glad_glFramebufferTexture3D -typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -GLAPI PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; -#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum target, GLenum attachment, GLenum pname, GLint *params); -GLAPI PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; -#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv -typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC)(GLenum target); -GLAPI PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; -#define glGenerateMipmap glad_glGenerateMipmap -typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -GLAPI PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; -#define glBlitFramebuffer glad_glBlitFramebuffer -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; -#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -GLAPI PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; -#define glFramebufferTextureLayer glad_glFramebufferTextureLayer -typedef void * (APIENTRYP PFNGLMAPBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); -GLAPI PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; -#define glMapBufferRange glad_glMapBufferRange -typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length); -GLAPI PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; -#define glFlushMappedBufferRange glad_glFlushMappedBufferRange -typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC)(GLuint array); -GLAPI PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; -#define glBindVertexArray glad_glBindVertexArray -typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC)(GLsizei n, const GLuint *arrays); -GLAPI PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; -#define glDeleteVertexArrays glad_glDeleteVertexArrays -typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC)(GLsizei n, GLuint *arrays); -GLAPI PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; -#define glGenVertexArrays glad_glGenVertexArrays -typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC)(GLuint array); -GLAPI PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; -#define glIsVertexArray glad_glIsVertexArray -#endif -#ifndef GL_VERSION_3_1 -#define GL_VERSION_3_1 1 -GLAPI int GLAD_GL_VERSION_3_1; -typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); -GLAPI PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; -#define glDrawArraysInstanced glad_glDrawArraysInstanced -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); -GLAPI PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; -#define glDrawElementsInstanced glad_glDrawElementsInstanced -typedef void (APIENTRYP PFNGLTEXBUFFERPROC)(GLenum target, GLenum internalformat, GLuint buffer); -GLAPI PFNGLTEXBUFFERPROC glad_glTexBuffer; -#define glTexBuffer glad_glTexBuffer -typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint index); -GLAPI PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; -#define glPrimitiveRestartIndex glad_glPrimitiveRestartIndex -typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -GLAPI PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; -#define glCopyBufferSubData glad_glCopyBufferSubData -typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC)(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); -GLAPI PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; -#define glGetUniformIndices glad_glGetUniformIndices -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); -GLAPI PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; -#define glGetActiveUniformsiv glad_glGetActiveUniformsiv -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC)(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); -GLAPI PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; -#define glGetActiveUniformName glad_glGetActiveUniformName -typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint program, const GLchar *uniformBlockName); -GLAPI PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; -#define glGetUniformBlockIndex glad_glGetUniformBlockIndex -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); -GLAPI PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; -#define glGetActiveUniformBlockiv glad_glGetActiveUniformBlockiv -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); -GLAPI PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; -#define glGetActiveUniformBlockName glad_glGetActiveUniformBlockName -typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); -GLAPI PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; -#define glUniformBlockBinding glad_glUniformBlockBinding -#endif -#ifndef GL_VERSION_3_2 -#define GL_VERSION_3_2 1 -GLAPI int GLAD_GL_VERSION_3_2; -typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); -GLAPI PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; -#define glDrawElementsBaseVertex glad_glDrawElementsBaseVertex -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); -GLAPI PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; -#define glDrawRangeElementsBaseVertex glad_glDrawRangeElementsBaseVertex -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); -GLAPI PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; -#define glDrawElementsInstancedBaseVertex glad_glDrawElementsInstancedBaseVertex -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); -GLAPI PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; -#define glMultiDrawElementsBaseVertex glad_glMultiDrawElementsBaseVertex -typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC)(GLenum mode); -GLAPI PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; -#define glProvokingVertex glad_glProvokingVertex -typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC)(GLenum condition, GLbitfield flags); -GLAPI PFNGLFENCESYNCPROC glad_glFenceSync; -#define glFenceSync glad_glFenceSync -typedef GLboolean (APIENTRYP PFNGLISSYNCPROC)(GLsync sync); -GLAPI PFNGLISSYNCPROC glad_glIsSync; -#define glIsSync glad_glIsSync -typedef void (APIENTRYP PFNGLDELETESYNCPROC)(GLsync sync); -GLAPI PFNGLDELETESYNCPROC glad_glDeleteSync; -#define glDeleteSync glad_glDeleteSync -typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); -GLAPI PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; -#define glClientWaitSync glad_glClientWaitSync -typedef void (APIENTRYP PFNGLWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); -GLAPI PFNGLWAITSYNCPROC glad_glWaitSync; -#define glWaitSync glad_glWaitSync -typedef void (APIENTRYP PFNGLGETINTEGER64VPROC)(GLenum pname, GLint64 *data); -GLAPI PFNGLGETINTEGER64VPROC glad_glGetInteger64v; -#define glGetInteger64v glad_glGetInteger64v -typedef void (APIENTRYP PFNGLGETSYNCIVPROC)(GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values); -GLAPI PFNGLGETSYNCIVPROC glad_glGetSynciv; -#define glGetSynciv glad_glGetSynciv -typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC)(GLenum target, GLuint index, GLint64 *data); -GLAPI PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; -#define glGetInteger64i_v glad_glGetInteger64i_v -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum target, GLenum pname, GLint64 *params); -GLAPI PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; -#define glGetBufferParameteri64v glad_glGetBufferParameteri64v -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level); -GLAPI PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; -#define glFramebufferTexture glad_glFramebufferTexture -typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -GLAPI PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; -#define glTexImage2DMultisample glad_glTexImage2DMultisample -typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -GLAPI PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; -#define glTexImage3DMultisample glad_glTexImage3DMultisample -typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC)(GLenum pname, GLuint index, GLfloat *val); -GLAPI PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; -#define glGetMultisamplefv glad_glGetMultisamplefv -typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC)(GLuint maskNumber, GLbitfield mask); -GLAPI PFNGLSAMPLEMASKIPROC glad_glSampleMaski; -#define glSampleMaski glad_glSampleMaski -#endif -#ifndef GL_VERSION_3_3 -#define GL_VERSION_3_3 1 -GLAPI int GLAD_GL_VERSION_3_3; -typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)(GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); -GLAPI PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed; -#define glBindFragDataLocationIndexed glad_glBindFragDataLocationIndexed -typedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC)(GLuint program, const GLchar *name); -GLAPI PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex; -#define glGetFragDataIndex glad_glGetFragDataIndex -typedef void (APIENTRYP PFNGLGENSAMPLERSPROC)(GLsizei count, GLuint *samplers); -GLAPI PFNGLGENSAMPLERSPROC glad_glGenSamplers; -#define glGenSamplers glad_glGenSamplers -typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC)(GLsizei count, const GLuint *samplers); -GLAPI PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers; -#define glDeleteSamplers glad_glDeleteSamplers -typedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC)(GLuint sampler); -GLAPI PFNGLISSAMPLERPROC glad_glIsSampler; -#define glIsSampler glad_glIsSampler -typedef void (APIENTRYP PFNGLBINDSAMPLERPROC)(GLuint unit, GLuint sampler); -GLAPI PFNGLBINDSAMPLERPROC glad_glBindSampler; -#define glBindSampler glad_glBindSampler -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC)(GLuint sampler, GLenum pname, GLint param); -GLAPI PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri; -#define glSamplerParameteri glad_glSamplerParameteri -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, const GLint *param); -GLAPI PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv; -#define glSamplerParameteriv glad_glSamplerParameteriv -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC)(GLuint sampler, GLenum pname, GLfloat param); -GLAPI PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf; -#define glSamplerParameterf glad_glSamplerParameterf -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, const GLfloat *param); -GLAPI PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv; -#define glSamplerParameterfv glad_glSamplerParameterfv -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, const GLint *param); -GLAPI PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv; -#define glSamplerParameterIiv glad_glSamplerParameterIiv -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, const GLuint *param); -GLAPI PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv; -#define glSamplerParameterIuiv glad_glSamplerParameterIuiv -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, GLint *params); -GLAPI PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv; -#define glGetSamplerParameteriv glad_glGetSamplerParameteriv -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, GLint *params); -GLAPI PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv; -#define glGetSamplerParameterIiv glad_glGetSamplerParameterIiv -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, GLfloat *params); -GLAPI PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv; -#define glGetSamplerParameterfv glad_glGetSamplerParameterfv -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, GLuint *params); -GLAPI PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv; -#define glGetSamplerParameterIuiv glad_glGetSamplerParameterIuiv -typedef void (APIENTRYP PFNGLQUERYCOUNTERPROC)(GLuint id, GLenum target); -GLAPI PFNGLQUERYCOUNTERPROC glad_glQueryCounter; -#define glQueryCounter glad_glQueryCounter -typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC)(GLuint id, GLenum pname, GLint64 *params); -GLAPI PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v; -#define glGetQueryObjecti64v glad_glGetQueryObjecti64v -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC)(GLuint id, GLenum pname, GLuint64 *params); -GLAPI PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v; -#define glGetQueryObjectui64v glad_glGetQueryObjectui64v -typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC)(GLuint index, GLuint divisor); -GLAPI PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor; -#define glVertexAttribDivisor glad_glVertexAttribDivisor -typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui; -#define glVertexAttribP1ui glad_glVertexAttribP1ui -typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -GLAPI PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv; -#define glVertexAttribP1uiv glad_glVertexAttribP1uiv -typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui; -#define glVertexAttribP2ui glad_glVertexAttribP2ui -typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -GLAPI PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv; -#define glVertexAttribP2uiv glad_glVertexAttribP2uiv -typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui; -#define glVertexAttribP3ui glad_glVertexAttribP3ui -typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -GLAPI PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv; -#define glVertexAttribP3uiv glad_glVertexAttribP3uiv -typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui; -#define glVertexAttribP4ui glad_glVertexAttribP4ui -typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -GLAPI PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv; -#define glVertexAttribP4uiv glad_glVertexAttribP4uiv -typedef void (APIENTRYP PFNGLVERTEXP2UIPROC)(GLenum type, GLuint value); -GLAPI PFNGLVERTEXP2UIPROC glad_glVertexP2ui; -#define glVertexP2ui glad_glVertexP2ui -typedef void (APIENTRYP PFNGLVERTEXP2UIVPROC)(GLenum type, const GLuint *value); -GLAPI PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv; -#define glVertexP2uiv glad_glVertexP2uiv -typedef void (APIENTRYP PFNGLVERTEXP3UIPROC)(GLenum type, GLuint value); -GLAPI PFNGLVERTEXP3UIPROC glad_glVertexP3ui; -#define glVertexP3ui glad_glVertexP3ui -typedef void (APIENTRYP PFNGLVERTEXP3UIVPROC)(GLenum type, const GLuint *value); -GLAPI PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv; -#define glVertexP3uiv glad_glVertexP3uiv -typedef void (APIENTRYP PFNGLVERTEXP4UIPROC)(GLenum type, GLuint value); -GLAPI PFNGLVERTEXP4UIPROC glad_glVertexP4ui; -#define glVertexP4ui glad_glVertexP4ui -typedef void (APIENTRYP PFNGLVERTEXP4UIVPROC)(GLenum type, const GLuint *value); -GLAPI PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv; -#define glVertexP4uiv glad_glVertexP4uiv -typedef void (APIENTRYP PFNGLTEXCOORDP1UIPROC)(GLenum type, GLuint coords); -GLAPI PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui; -#define glTexCoordP1ui glad_glTexCoordP1ui -typedef void (APIENTRYP PFNGLTEXCOORDP1UIVPROC)(GLenum type, const GLuint *coords); -GLAPI PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv; -#define glTexCoordP1uiv glad_glTexCoordP1uiv -typedef void (APIENTRYP PFNGLTEXCOORDP2UIPROC)(GLenum type, GLuint coords); -GLAPI PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui; -#define glTexCoordP2ui glad_glTexCoordP2ui -typedef void (APIENTRYP PFNGLTEXCOORDP2UIVPROC)(GLenum type, const GLuint *coords); -GLAPI PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv; -#define glTexCoordP2uiv glad_glTexCoordP2uiv -typedef void (APIENTRYP PFNGLTEXCOORDP3UIPROC)(GLenum type, GLuint coords); -GLAPI PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui; -#define glTexCoordP3ui glad_glTexCoordP3ui -typedef void (APIENTRYP PFNGLTEXCOORDP3UIVPROC)(GLenum type, const GLuint *coords); -GLAPI PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv; -#define glTexCoordP3uiv glad_glTexCoordP3uiv -typedef void (APIENTRYP PFNGLTEXCOORDP4UIPROC)(GLenum type, GLuint coords); -GLAPI PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui; -#define glTexCoordP4ui glad_glTexCoordP4ui -typedef void (APIENTRYP PFNGLTEXCOORDP4UIVPROC)(GLenum type, const GLuint *coords); -GLAPI PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv; -#define glTexCoordP4uiv glad_glTexCoordP4uiv -typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIPROC)(GLenum texture, GLenum type, GLuint coords); -GLAPI PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui; -#define glMultiTexCoordP1ui glad_glMultiTexCoordP1ui -typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIVPROC)(GLenum texture, GLenum type, const GLuint *coords); -GLAPI PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv; -#define glMultiTexCoordP1uiv glad_glMultiTexCoordP1uiv -typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIPROC)(GLenum texture, GLenum type, GLuint coords); -GLAPI PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui; -#define glMultiTexCoordP2ui glad_glMultiTexCoordP2ui -typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIVPROC)(GLenum texture, GLenum type, const GLuint *coords); -GLAPI PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv; -#define glMultiTexCoordP2uiv glad_glMultiTexCoordP2uiv -typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIPROC)(GLenum texture, GLenum type, GLuint coords); -GLAPI PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui; -#define glMultiTexCoordP3ui glad_glMultiTexCoordP3ui -typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIVPROC)(GLenum texture, GLenum type, const GLuint *coords); -GLAPI PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv; -#define glMultiTexCoordP3uiv glad_glMultiTexCoordP3uiv -typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIPROC)(GLenum texture, GLenum type, GLuint coords); -GLAPI PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui; -#define glMultiTexCoordP4ui glad_glMultiTexCoordP4ui -typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIVPROC)(GLenum texture, GLenum type, const GLuint *coords); -GLAPI PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv; -#define glMultiTexCoordP4uiv glad_glMultiTexCoordP4uiv -typedef void (APIENTRYP PFNGLNORMALP3UIPROC)(GLenum type, GLuint coords); -GLAPI PFNGLNORMALP3UIPROC glad_glNormalP3ui; -#define glNormalP3ui glad_glNormalP3ui -typedef void (APIENTRYP PFNGLNORMALP3UIVPROC)(GLenum type, const GLuint *coords); -GLAPI PFNGLNORMALP3UIVPROC glad_glNormalP3uiv; -#define glNormalP3uiv glad_glNormalP3uiv -typedef void (APIENTRYP PFNGLCOLORP3UIPROC)(GLenum type, GLuint color); -GLAPI PFNGLCOLORP3UIPROC glad_glColorP3ui; -#define glColorP3ui glad_glColorP3ui -typedef void (APIENTRYP PFNGLCOLORP3UIVPROC)(GLenum type, const GLuint *color); -GLAPI PFNGLCOLORP3UIVPROC glad_glColorP3uiv; -#define glColorP3uiv glad_glColorP3uiv -typedef void (APIENTRYP PFNGLCOLORP4UIPROC)(GLenum type, GLuint color); -GLAPI PFNGLCOLORP4UIPROC glad_glColorP4ui; -#define glColorP4ui glad_glColorP4ui -typedef void (APIENTRYP PFNGLCOLORP4UIVPROC)(GLenum type, const GLuint *color); -GLAPI PFNGLCOLORP4UIVPROC glad_glColorP4uiv; -#define glColorP4uiv glad_glColorP4uiv -typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIPROC)(GLenum type, GLuint color); -GLAPI PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui; -#define glSecondaryColorP3ui glad_glSecondaryColorP3ui -typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIVPROC)(GLenum type, const GLuint *color); -GLAPI PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv; -#define glSecondaryColorP3uiv glad_glSecondaryColorP3uiv -#endif -#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 -#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 -#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 -#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 -#define GL_DEBUG_SOURCE_API_ARB 0x8246 -#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 -#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 -#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 -#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A -#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B -#define GL_DEBUG_TYPE_ERROR_ARB 0x824C -#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D -#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E -#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F -#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 -#define GL_DEBUG_TYPE_OTHER_ARB 0x8251 -#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 -#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 -#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 -#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 -#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 -#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 -#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 -#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 -#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 -#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA -#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 -#define GL_MAX_SAMPLES_EXT 0x8D57 -#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 -#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 -#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 -#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 -#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 -#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC -#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD -#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF -#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 -#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 -#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 -#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 -#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 -#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 -#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 -#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 -#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 -#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 -#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA -#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB -#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC -#define GL_COLOR_ATTACHMENT13_EXT 0x8CED -#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE -#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF -#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 -#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 -#define GL_FRAMEBUFFER_EXT 0x8D40 -#define GL_RENDERBUFFER_EXT 0x8D41 -#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 -#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 -#define GL_STENCIL_INDEX1_EXT 0x8D46 -#define GL_STENCIL_INDEX4_EXT 0x8D47 -#define GL_STENCIL_INDEX8_EXT 0x8D48 -#define GL_STENCIL_INDEX16_EXT 0x8D49 -#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632 -#define GL_MAX_VIEWS_OVR 0x9631 -#define GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR 0x9633 -#ifndef GL_ARB_debug_output -#define GL_ARB_debug_output 1 -GLAPI int GLAD_GL_ARB_debug_output; -typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLARBPROC)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -GLAPI PFNGLDEBUGMESSAGECONTROLARBPROC glad_glDebugMessageControlARB; -#define glDebugMessageControlARB glad_glDebugMessageControlARB -typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTARBPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); -GLAPI PFNGLDEBUGMESSAGEINSERTARBPROC glad_glDebugMessageInsertARB; -#define glDebugMessageInsertARB glad_glDebugMessageInsertARB -typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKARBPROC)(GLDEBUGPROCARB callback, const void *userParam); -GLAPI PFNGLDEBUGMESSAGECALLBACKARBPROC glad_glDebugMessageCallbackARB; -#define glDebugMessageCallbackARB glad_glDebugMessageCallbackARB -typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGARBPROC)(GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); -GLAPI PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB; -#define glGetDebugMessageLogARB glad_glGetDebugMessageLogARB -#endif -#ifndef GL_ARB_framebuffer_object -#define GL_ARB_framebuffer_object 1 -GLAPI int GLAD_GL_ARB_framebuffer_object; -#endif -#ifndef GL_EXT_framebuffer_blit -#define GL_EXT_framebuffer_blit 1 -GLAPI int GLAD_GL_EXT_framebuffer_blit; -typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -GLAPI PFNGLBLITFRAMEBUFFEREXTPROC glad_glBlitFramebufferEXT; -#define glBlitFramebufferEXT glad_glBlitFramebufferEXT -#endif -#ifndef GL_EXT_framebuffer_multisample -#define GL_EXT_framebuffer_multisample 1 -GLAPI int GLAD_GL_EXT_framebuffer_multisample; -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT; -#define glRenderbufferStorageMultisampleEXT glad_glRenderbufferStorageMultisampleEXT -#endif -#ifndef GL_EXT_framebuffer_object -#define GL_EXT_framebuffer_object 1 -GLAPI int GLAD_GL_EXT_framebuffer_object; -typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC)(GLuint renderbuffer); -GLAPI PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbufferEXT; -#define glIsRenderbufferEXT glad_glIsRenderbufferEXT -typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC)(GLenum target, GLuint renderbuffer); -GLAPI PFNGLBINDRENDERBUFFEREXTPROC glad_glBindRenderbufferEXT; -#define glBindRenderbufferEXT glad_glBindRenderbufferEXT -typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC)(GLsizei n, const GLuint *renderbuffers); -GLAPI PFNGLDELETERENDERBUFFERSEXTPROC glad_glDeleteRenderbuffersEXT; -#define glDeleteRenderbuffersEXT glad_glDeleteRenderbuffersEXT -typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC)(GLsizei n, GLuint *renderbuffers); -GLAPI PFNGLGENRENDERBUFFERSEXTPROC glad_glGenRenderbuffersEXT; -#define glGenRenderbuffersEXT glad_glGenRenderbuffersEXT -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT; -#define glRenderbufferStorageEXT glad_glRenderbufferStorageEXT -typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)(GLenum target, GLenum pname, GLint *params); -GLAPI PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glad_glGetRenderbufferParameterivEXT; -#define glGetRenderbufferParameterivEXT glad_glGetRenderbufferParameterivEXT -typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC)(GLuint framebuffer); -GLAPI PFNGLISFRAMEBUFFEREXTPROC glad_glIsFramebufferEXT; -#define glIsFramebufferEXT glad_glIsFramebufferEXT -typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC)(GLenum target, GLuint framebuffer); -GLAPI PFNGLBINDFRAMEBUFFEREXTPROC glad_glBindFramebufferEXT; -#define glBindFramebufferEXT glad_glBindFramebufferEXT -typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC)(GLsizei n, const GLuint *framebuffers); -GLAPI PFNGLDELETEFRAMEBUFFERSEXTPROC glad_glDeleteFramebuffersEXT; -#define glDeleteFramebuffersEXT glad_glDeleteFramebuffersEXT -typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC)(GLsizei n, GLuint *framebuffers); -GLAPI PFNGLGENFRAMEBUFFERSEXTPROC glad_glGenFramebuffersEXT; -#define glGenFramebuffersEXT glad_glGenFramebuffersEXT -typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)(GLenum target); -GLAPI PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glad_glCheckFramebufferStatusEXT; -#define glCheckFramebufferStatusEXT glad_glCheckFramebufferStatusEXT -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glad_glFramebufferTexture1DEXT; -#define glFramebufferTexture1DEXT glad_glFramebufferTexture1DEXT -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glad_glFramebufferTexture2DEXT; -#define glFramebufferTexture2DEXT glad_glFramebufferTexture2DEXT -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -GLAPI PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glad_glFramebufferTexture3DEXT; -#define glFramebufferTexture3DEXT glad_glFramebufferTexture3DEXT -typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -GLAPI PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glad_glFramebufferRenderbufferEXT; -#define glFramebufferRenderbufferEXT glad_glFramebufferRenderbufferEXT -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)(GLenum target, GLenum attachment, GLenum pname, GLint *params); -GLAPI PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetFramebufferAttachmentParameterivEXT; -#define glGetFramebufferAttachmentParameterivEXT glad_glGetFramebufferAttachmentParameterivEXT -typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC)(GLenum target); -GLAPI PFNGLGENERATEMIPMAPEXTPROC glad_glGenerateMipmapEXT; -#define glGenerateMipmapEXT glad_glGenerateMipmapEXT -#endif -#ifndef GL_OVR_multiview -#define GL_OVR_multiview 1 -GLAPI int GLAD_GL_OVR_multiview; -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); -GLAPI PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glad_glFramebufferTextureMultiviewOVR; -#define glFramebufferTextureMultiviewOVR glad_glFramebufferTextureMultiviewOVR -#endif -#ifndef GL_OVR_multiview2 -#define GL_OVR_multiview2 1 -GLAPI int GLAD_GL_OVR_multiview2; -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/glad/glad/glx.h b/thirdparty/glad/glad/glx.h new file mode 100644 index 0000000000..ac115fa63b --- /dev/null +++ b/thirdparty/glad/glad/glx.h @@ -0,0 +1,605 @@ +/** + * Loader generated by glad 2.0.2 on Tue Nov 15 09:49:49 2022 + * + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + * + * Generator: C/C++ + * Specification: glx + * Extensions: 6 + * + * APIs: + * - glx=1.4 + * + * Options: + * - ALIAS = False + * - DEBUG = False + * - HEADER_ONLY = False + * - LOADER = True + * - MX = False + * - ON_DEMAND = False + * + * Commandline: + * --api='glx=1.4' --extensions='GLX_ARB_create_context,GLX_ARB_create_context_profile,GLX_ARB_get_proc_address,GLX_EXT_swap_control,GLX_MESA_swap_control,GLX_SGI_swap_control' c --loader + * + * Online: + * http://glad.sh/#api=glx%3D1.4&extensions=GLX_ARB_create_context%2CGLX_ARB_create_context_profile%2CGLX_ARB_get_proc_address%2CGLX_EXT_swap_control%2CGLX_MESA_swap_control%2CGLX_SGI_swap_control&generator=c&options=LOADER + * + */ + +#ifndef GLAD_GLX_H_ +#define GLAD_GLX_H_ + +#ifdef GLX_H + #error GLX header already included (API: glx), remove previous include! +#endif +#define GLX_H 1 + + +#include <X11/X.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +#include <glad/gl.h> + +#define GLAD_GLX +#define GLAD_OPTION_GLX_LOADER + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef GLAD_PLATFORM_H_ +#define GLAD_PLATFORM_H_ + +#ifndef GLAD_PLATFORM_WIN32 + #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__) + #define GLAD_PLATFORM_WIN32 1 + #else + #define GLAD_PLATFORM_WIN32 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_APPLE + #ifdef __APPLE__ + #define GLAD_PLATFORM_APPLE 1 + #else + #define GLAD_PLATFORM_APPLE 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_EMSCRIPTEN + #ifdef __EMSCRIPTEN__ + #define GLAD_PLATFORM_EMSCRIPTEN 1 + #else + #define GLAD_PLATFORM_EMSCRIPTEN 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_UWP + #if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY) + #ifdef __has_include + #if __has_include(<winapifamily.h>) + #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 + #endif + #elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ + #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 + #endif + #endif + + #ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY + #include <winapifamily.h> + #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) + #define GLAD_PLATFORM_UWP 1 + #endif + #endif + + #ifndef GLAD_PLATFORM_UWP + #define GLAD_PLATFORM_UWP 0 + #endif +#endif + +#ifdef __GNUC__ + #define GLAD_GNUC_EXTENSION __extension__ +#else + #define GLAD_GNUC_EXTENSION +#endif + +#define GLAD_UNUSED(x) (void)(x) + +#ifndef GLAD_API_CALL + #if defined(GLAD_API_CALL_EXPORT) + #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) + #if defined(GLAD_API_CALL_EXPORT_BUILD) + #if defined(__GNUC__) + #define GLAD_API_CALL __attribute__ ((dllexport)) extern + #else + #define GLAD_API_CALL __declspec(dllexport) extern + #endif + #else + #if defined(__GNUC__) + #define GLAD_API_CALL __attribute__ ((dllimport)) extern + #else + #define GLAD_API_CALL __declspec(dllimport) extern + #endif + #endif + #elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD) + #define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern + #else + #define GLAD_API_CALL extern + #endif + #else + #define GLAD_API_CALL extern + #endif +#endif + +#ifdef APIENTRY + #define GLAD_API_PTR APIENTRY +#elif GLAD_PLATFORM_WIN32 + #define GLAD_API_PTR __stdcall +#else + #define GLAD_API_PTR +#endif + +#ifndef GLAPI +#define GLAPI GLAD_API_CALL +#endif + +#ifndef GLAPIENTRY +#define GLAPIENTRY GLAD_API_PTR +#endif + +#define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor) +#define GLAD_VERSION_MAJOR(version) (version / 10000) +#define GLAD_VERSION_MINOR(version) (version % 10000) + +#define GLAD_GENERATOR_VERSION "2.0.2" + +typedef void (*GLADapiproc)(void); + +typedef GLADapiproc (*GLADloadfunc)(const char *name); +typedef GLADapiproc (*GLADuserptrloadfunc)(void *userptr, const char *name); + +typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...); +typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...); + +#endif /* GLAD_PLATFORM_H_ */ + +#define GLX_ACCUM_ALPHA_SIZE 17 +#define GLX_ACCUM_BLUE_SIZE 16 +#define GLX_ACCUM_BUFFER_BIT 0x00000080 +#define GLX_ACCUM_GREEN_SIZE 15 +#define GLX_ACCUM_RED_SIZE 14 +#define GLX_ALPHA_SIZE 11 +#define GLX_AUX_BUFFERS 7 +#define GLX_AUX_BUFFERS_BIT 0x00000010 +#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 +#define GLX_BAD_ATTRIBUTE 2 +#define GLX_BAD_CONTEXT 5 +#define GLX_BAD_ENUM 7 +#define GLX_BAD_SCREEN 1 +#define GLX_BAD_VALUE 6 +#define GLX_BAD_VISUAL 4 +#define GLX_BLUE_SIZE 10 +#define GLX_BUFFER_SIZE 2 +#define GLX_BufferSwapComplete 1 +#define GLX_COLOR_INDEX_BIT 0x00000002 +#define GLX_COLOR_INDEX_TYPE 0x8015 +#define GLX_CONFIG_CAVEAT 0x20 +#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 +#define GLX_CONTEXT_FLAGS_ARB 0x2094 +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 +#define GLX_DAMAGED 0x8020 +#define GLX_DEPTH_BUFFER_BIT 0x00000020 +#define GLX_DEPTH_SIZE 12 +#define GLX_DIRECT_COLOR 0x8003 +#define GLX_DONT_CARE 0xFFFFFFFF +#define GLX_DOUBLEBUFFER 5 +#define GLX_DRAWABLE_TYPE 0x8010 +#define GLX_EVENT_MASK 0x801F +#define GLX_EXTENSIONS 0x3 +#define GLX_EXTENSION_NAME "GLX" +#define GLX_FBCONFIG_ID 0x8013 +#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 +#define GLX_GRAY_SCALE 0x8006 +#define GLX_GREEN_SIZE 9 +#define GLX_HEIGHT 0x801E +#define GLX_LARGEST_PBUFFER 0x801C +#define GLX_LEVEL 3 +#define GLX_MAX_PBUFFER_HEIGHT 0x8017 +#define GLX_MAX_PBUFFER_PIXELS 0x8018 +#define GLX_MAX_PBUFFER_WIDTH 0x8016 +#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2 +#define GLX_NONE 0x8000 +#define GLX_NON_CONFORMANT_CONFIG 0x800D +#define GLX_NO_EXTENSION 3 +#define GLX_PBUFFER 0x8023 +#define GLX_PBUFFER_BIT 0x00000004 +#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 +#define GLX_PBUFFER_HEIGHT 0x8040 +#define GLX_PBUFFER_WIDTH 0x8041 +#define GLX_PIXMAP_BIT 0x00000002 +#define GLX_PRESERVED_CONTENTS 0x801B +#define GLX_PSEUDO_COLOR 0x8004 +#define GLX_PbufferClobber 0 +#define GLX_RED_SIZE 8 +#define GLX_RENDER_TYPE 0x8011 +#define GLX_RGBA 4 +#define GLX_RGBA_BIT 0x00000001 +#define GLX_RGBA_TYPE 0x8014 +#define GLX_SAMPLES 100001 +#define GLX_SAMPLE_BUFFERS 100000 +#define GLX_SAVED 0x8021 +#define GLX_SCREEN 0x800C +#define GLX_SLOW_CONFIG 0x8001 +#define GLX_STATIC_COLOR 0x8005 +#define GLX_STATIC_GRAY 0x8007 +#define GLX_STENCIL_BUFFER_BIT 0x00000040 +#define GLX_STENCIL_SIZE 13 +#define GLX_STEREO 6 +#define GLX_SWAP_INTERVAL_EXT 0x20F1 +#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 +#define GLX_TRANSPARENT_BLUE_VALUE 0x27 +#define GLX_TRANSPARENT_GREEN_VALUE 0x26 +#define GLX_TRANSPARENT_INDEX 0x8009 +#define GLX_TRANSPARENT_INDEX_VALUE 0x24 +#define GLX_TRANSPARENT_RED_VALUE 0x25 +#define GLX_TRANSPARENT_RGB 0x8008 +#define GLX_TRANSPARENT_TYPE 0x23 +#define GLX_TRUE_COLOR 0x8002 +#define GLX_USE_GL 1 +#define GLX_VENDOR 0x1 +#define GLX_VERSION 0x2 +#define GLX_VISUAL_ID 0x800B +#define GLX_WIDTH 0x801D +#define GLX_WINDOW 0x8022 +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_X_RENDERABLE 0x8012 +#define GLX_X_VISUAL_TYPE 0x22 +#define __GLX_NUMBER_EVENTS 17 + + +#ifndef GLEXT_64_TYPES_DEFINED +/* This code block is duplicated in glext.h, so must be protected */ +#define GLEXT_64_TYPES_DEFINED +/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ +/* (as used in the GLX_OML_sync_control extension). */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include <inttypes.h> +#elif defined(__sun__) || defined(__digital__) +#include <inttypes.h> +#if defined(__STDC__) +#if defined(__arch64__) || defined(_LP64) +typedef long int int64_t; +typedef unsigned long int uint64_t; +#else +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#endif /* __arch64__ */ +#endif /* __STDC__ */ +#elif defined( __VMS ) || defined(__sgi) +#include <inttypes.h> +#elif defined(__SCO__) || defined(__USLC__) +#include <stdint.h> +#elif defined(__UNIXOS2__) || defined(__SOL64__) +typedef long int int32_t; +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#elif defined(_WIN32) && defined(__GNUC__) +#include <stdint.h> +#elif defined(_WIN32) +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +/* Fallback if nothing above works */ +#include <inttypes.h> +#endif +#endif + + + + + + + + + + + + + + + + +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) + +#else + +#endif + +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) + +#else + +#endif + + + + + + + +typedef XID GLXFBConfigID; +typedef struct __GLXFBConfigRec *GLXFBConfig; +typedef XID GLXContextID; +typedef struct __GLXcontextRec *GLXContext; +typedef XID GLXPixmap; +typedef XID GLXDrawable; +typedef XID GLXWindow; +typedef XID GLXPbuffer; +typedef void (GLAD_API_PTR *__GLXextFuncPtr)(void); +typedef XID GLXVideoCaptureDeviceNV; +typedef unsigned int GLXVideoDeviceNV; +typedef XID GLXVideoSourceSGIX; +typedef XID GLXFBConfigIDSGIX; +typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; +typedef XID GLXPbufferSGIX; +typedef struct { + int event_type; /* GLX_DAMAGED or GLX_SAVED */ + int draw_type; /* GLX_WINDOW or GLX_PBUFFER */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came for SendEvent request */ + Display *display; /* display the event was read from */ + GLXDrawable drawable; /* XID of Drawable */ + unsigned int buffer_mask; /* mask indicating which buffers are affected */ + unsigned int aux_buffer; /* which aux buffer was affected */ + int x, y; + int width, height; + int count; /* if nonzero, at least this many more */ +} GLXPbufferClobberEvent; +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + GLXDrawable drawable; /* drawable on which event was requested in event mask */ + int event_type; + int64_t ust; + int64_t msc; + int64_t sbc; +} GLXBufferSwapComplete; +typedef union __GLXEvent { + GLXPbufferClobberEvent glxpbufferclobber; + GLXBufferSwapComplete glxbufferswapcomplete; + long pad[24]; +} GLXEvent; +typedef struct { + int type; + unsigned long serial; + Bool send_event; + Display *display; + int extension; + int evtype; + GLXDrawable window; + Bool stereo_tree; +} GLXStereoNotifyEventEXT; +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came for SendEvent request */ + Display *display; /* display the event was read from */ + GLXDrawable drawable; /* i.d. of Drawable */ + int event_type; /* GLX_DAMAGED_SGIX or GLX_SAVED_SGIX */ + int draw_type; /* GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX */ + unsigned int mask; /* mask indicating which buffers are affected*/ + int x, y; + int width, height; + int count; /* if nonzero, at least this many more */ +} GLXBufferClobberEventSGIX; +typedef struct { + char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ + int networkId; +} GLXHyperpipeNetworkSGIX; +typedef struct { + char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ + int channel; + unsigned int participationType; + int timeSlice; +} GLXHyperpipeConfigSGIX; +typedef struct { + char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ + int srcXOrigin, srcYOrigin, srcWidth, srcHeight; + int destXOrigin, destYOrigin, destWidth, destHeight; +} GLXPipeRect; +typedef struct { + char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ + int XOrigin, YOrigin, maxHeight, maxWidth; +} GLXPipeRectLimits; + + +#define GLX_VERSION_1_0 1 +GLAD_API_CALL int GLAD_GLX_VERSION_1_0; +#define GLX_VERSION_1_1 1 +GLAD_API_CALL int GLAD_GLX_VERSION_1_1; +#define GLX_VERSION_1_2 1 +GLAD_API_CALL int GLAD_GLX_VERSION_1_2; +#define GLX_VERSION_1_3 1 +GLAD_API_CALL int GLAD_GLX_VERSION_1_3; +#define GLX_VERSION_1_4 1 +GLAD_API_CALL int GLAD_GLX_VERSION_1_4; +#define GLX_ARB_create_context 1 +GLAD_API_CALL int GLAD_GLX_ARB_create_context; +#define GLX_ARB_create_context_profile 1 +GLAD_API_CALL int GLAD_GLX_ARB_create_context_profile; +#define GLX_ARB_get_proc_address 1 +GLAD_API_CALL int GLAD_GLX_ARB_get_proc_address; +#define GLX_EXT_swap_control 1 +GLAD_API_CALL int GLAD_GLX_EXT_swap_control; +#define GLX_MESA_swap_control 1 +GLAD_API_CALL int GLAD_GLX_MESA_swap_control; +#define GLX_SGI_swap_control 1 +GLAD_API_CALL int GLAD_GLX_SGI_swap_control; + + +typedef GLXFBConfig * (GLAD_API_PTR *PFNGLXCHOOSEFBCONFIGPROC)(Display * dpy, int screen, const int * attrib_list, int * nelements); +typedef XVisualInfo * (GLAD_API_PTR *PFNGLXCHOOSEVISUALPROC)(Display * dpy, int screen, int * attribList); +typedef void (GLAD_API_PTR *PFNGLXCOPYCONTEXTPROC)(Display * dpy, GLXContext src, GLXContext dst, unsigned long mask); +typedef GLXContext (GLAD_API_PTR *PFNGLXCREATECONTEXTPROC)(Display * dpy, XVisualInfo * vis, GLXContext shareList, Bool direct); +typedef GLXContext (GLAD_API_PTR *PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display * dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int * attrib_list); +typedef GLXPixmap (GLAD_API_PTR *PFNGLXCREATEGLXPIXMAPPROC)(Display * dpy, XVisualInfo * visual, Pixmap pixmap); +typedef GLXContext (GLAD_API_PTR *PFNGLXCREATENEWCONTEXTPROC)(Display * dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); +typedef GLXPbuffer (GLAD_API_PTR *PFNGLXCREATEPBUFFERPROC)(Display * dpy, GLXFBConfig config, const int * attrib_list); +typedef GLXPixmap (GLAD_API_PTR *PFNGLXCREATEPIXMAPPROC)(Display * dpy, GLXFBConfig config, Pixmap pixmap, const int * attrib_list); +typedef GLXWindow (GLAD_API_PTR *PFNGLXCREATEWINDOWPROC)(Display * dpy, GLXFBConfig config, Window win, const int * attrib_list); +typedef void (GLAD_API_PTR *PFNGLXDESTROYCONTEXTPROC)(Display * dpy, GLXContext ctx); +typedef void (GLAD_API_PTR *PFNGLXDESTROYGLXPIXMAPPROC)(Display * dpy, GLXPixmap pixmap); +typedef void (GLAD_API_PTR *PFNGLXDESTROYPBUFFERPROC)(Display * dpy, GLXPbuffer pbuf); +typedef void (GLAD_API_PTR *PFNGLXDESTROYPIXMAPPROC)(Display * dpy, GLXPixmap pixmap); +typedef void (GLAD_API_PTR *PFNGLXDESTROYWINDOWPROC)(Display * dpy, GLXWindow win); +typedef const char * (GLAD_API_PTR *PFNGLXGETCLIENTSTRINGPROC)(Display * dpy, int name); +typedef int (GLAD_API_PTR *PFNGLXGETCONFIGPROC)(Display * dpy, XVisualInfo * visual, int attrib, int * value); +typedef GLXContext (GLAD_API_PTR *PFNGLXGETCURRENTCONTEXTPROC)(void); +typedef Display * (GLAD_API_PTR *PFNGLXGETCURRENTDISPLAYPROC)(void); +typedef GLXDrawable (GLAD_API_PTR *PFNGLXGETCURRENTDRAWABLEPROC)(void); +typedef GLXDrawable (GLAD_API_PTR *PFNGLXGETCURRENTREADDRAWABLEPROC)(void); +typedef int (GLAD_API_PTR *PFNGLXGETFBCONFIGATTRIBPROC)(Display * dpy, GLXFBConfig config, int attribute, int * value); +typedef GLXFBConfig * (GLAD_API_PTR *PFNGLXGETFBCONFIGSPROC)(Display * dpy, int screen, int * nelements); +typedef __GLXextFuncPtr (GLAD_API_PTR *PFNGLXGETPROCADDRESSPROC)(const GLubyte * procName); +typedef __GLXextFuncPtr (GLAD_API_PTR *PFNGLXGETPROCADDRESSARBPROC)(const GLubyte * procName); +typedef void (GLAD_API_PTR *PFNGLXGETSELECTEDEVENTPROC)(Display * dpy, GLXDrawable draw, unsigned long * event_mask); +typedef int (GLAD_API_PTR *PFNGLXGETSWAPINTERVALMESAPROC)(void); +typedef XVisualInfo * (GLAD_API_PTR *PFNGLXGETVISUALFROMFBCONFIGPROC)(Display * dpy, GLXFBConfig config); +typedef Bool (GLAD_API_PTR *PFNGLXISDIRECTPROC)(Display * dpy, GLXContext ctx); +typedef Bool (GLAD_API_PTR *PFNGLXMAKECONTEXTCURRENTPROC)(Display * dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); +typedef Bool (GLAD_API_PTR *PFNGLXMAKECURRENTPROC)(Display * dpy, GLXDrawable drawable, GLXContext ctx); +typedef int (GLAD_API_PTR *PFNGLXQUERYCONTEXTPROC)(Display * dpy, GLXContext ctx, int attribute, int * value); +typedef void (GLAD_API_PTR *PFNGLXQUERYDRAWABLEPROC)(Display * dpy, GLXDrawable draw, int attribute, unsigned int * value); +typedef Bool (GLAD_API_PTR *PFNGLXQUERYEXTENSIONPROC)(Display * dpy, int * errorb, int * event); +typedef const char * (GLAD_API_PTR *PFNGLXQUERYEXTENSIONSSTRINGPROC)(Display * dpy, int screen); +typedef const char * (GLAD_API_PTR *PFNGLXQUERYSERVERSTRINGPROC)(Display * dpy, int screen, int name); +typedef Bool (GLAD_API_PTR *PFNGLXQUERYVERSIONPROC)(Display * dpy, int * maj, int * min); +typedef void (GLAD_API_PTR *PFNGLXSELECTEVENTPROC)(Display * dpy, GLXDrawable draw, unsigned long event_mask); +typedef void (GLAD_API_PTR *PFNGLXSWAPBUFFERSPROC)(Display * dpy, GLXDrawable drawable); +typedef void (GLAD_API_PTR *PFNGLXSWAPINTERVALEXTPROC)(Display * dpy, GLXDrawable drawable, int interval); +typedef int (GLAD_API_PTR *PFNGLXSWAPINTERVALMESAPROC)(unsigned int interval); +typedef int (GLAD_API_PTR *PFNGLXSWAPINTERVALSGIPROC)(int interval); +typedef void (GLAD_API_PTR *PFNGLXUSEXFONTPROC)(Font font, int first, int count, int list); +typedef void (GLAD_API_PTR *PFNGLXWAITGLPROC)(void); +typedef void (GLAD_API_PTR *PFNGLXWAITXPROC)(void); + +GLAD_API_CALL PFNGLXCHOOSEFBCONFIGPROC glad_glXChooseFBConfig; +#define glXChooseFBConfig glad_glXChooseFBConfig +GLAD_API_CALL PFNGLXCHOOSEVISUALPROC glad_glXChooseVisual; +#define glXChooseVisual glad_glXChooseVisual +GLAD_API_CALL PFNGLXCOPYCONTEXTPROC glad_glXCopyContext; +#define glXCopyContext glad_glXCopyContext +GLAD_API_CALL PFNGLXCREATECONTEXTPROC glad_glXCreateContext; +#define glXCreateContext glad_glXCreateContext +GLAD_API_CALL PFNGLXCREATECONTEXTATTRIBSARBPROC glad_glXCreateContextAttribsARB; +#define glXCreateContextAttribsARB glad_glXCreateContextAttribsARB +GLAD_API_CALL PFNGLXCREATEGLXPIXMAPPROC glad_glXCreateGLXPixmap; +#define glXCreateGLXPixmap glad_glXCreateGLXPixmap +GLAD_API_CALL PFNGLXCREATENEWCONTEXTPROC glad_glXCreateNewContext; +#define glXCreateNewContext glad_glXCreateNewContext +GLAD_API_CALL PFNGLXCREATEPBUFFERPROC glad_glXCreatePbuffer; +#define glXCreatePbuffer glad_glXCreatePbuffer +GLAD_API_CALL PFNGLXCREATEPIXMAPPROC glad_glXCreatePixmap; +#define glXCreatePixmap glad_glXCreatePixmap +GLAD_API_CALL PFNGLXCREATEWINDOWPROC glad_glXCreateWindow; +#define glXCreateWindow glad_glXCreateWindow +GLAD_API_CALL PFNGLXDESTROYCONTEXTPROC glad_glXDestroyContext; +#define glXDestroyContext glad_glXDestroyContext +GLAD_API_CALL PFNGLXDESTROYGLXPIXMAPPROC glad_glXDestroyGLXPixmap; +#define glXDestroyGLXPixmap glad_glXDestroyGLXPixmap +GLAD_API_CALL PFNGLXDESTROYPBUFFERPROC glad_glXDestroyPbuffer; +#define glXDestroyPbuffer glad_glXDestroyPbuffer +GLAD_API_CALL PFNGLXDESTROYPIXMAPPROC glad_glXDestroyPixmap; +#define glXDestroyPixmap glad_glXDestroyPixmap +GLAD_API_CALL PFNGLXDESTROYWINDOWPROC glad_glXDestroyWindow; +#define glXDestroyWindow glad_glXDestroyWindow +GLAD_API_CALL PFNGLXGETCLIENTSTRINGPROC glad_glXGetClientString; +#define glXGetClientString glad_glXGetClientString +GLAD_API_CALL PFNGLXGETCONFIGPROC glad_glXGetConfig; +#define glXGetConfig glad_glXGetConfig +GLAD_API_CALL PFNGLXGETCURRENTCONTEXTPROC glad_glXGetCurrentContext; +#define glXGetCurrentContext glad_glXGetCurrentContext +GLAD_API_CALL PFNGLXGETCURRENTDISPLAYPROC glad_glXGetCurrentDisplay; +#define glXGetCurrentDisplay glad_glXGetCurrentDisplay +GLAD_API_CALL PFNGLXGETCURRENTDRAWABLEPROC glad_glXGetCurrentDrawable; +#define glXGetCurrentDrawable glad_glXGetCurrentDrawable +GLAD_API_CALL PFNGLXGETCURRENTREADDRAWABLEPROC glad_glXGetCurrentReadDrawable; +#define glXGetCurrentReadDrawable glad_glXGetCurrentReadDrawable +GLAD_API_CALL PFNGLXGETFBCONFIGATTRIBPROC glad_glXGetFBConfigAttrib; +#define glXGetFBConfigAttrib glad_glXGetFBConfigAttrib +GLAD_API_CALL PFNGLXGETFBCONFIGSPROC glad_glXGetFBConfigs; +#define glXGetFBConfigs glad_glXGetFBConfigs +GLAD_API_CALL PFNGLXGETPROCADDRESSPROC glad_glXGetProcAddress; +#define glXGetProcAddress glad_glXGetProcAddress +GLAD_API_CALL PFNGLXGETPROCADDRESSARBPROC glad_glXGetProcAddressARB; +#define glXGetProcAddressARB glad_glXGetProcAddressARB +GLAD_API_CALL PFNGLXGETSELECTEDEVENTPROC glad_glXGetSelectedEvent; +#define glXGetSelectedEvent glad_glXGetSelectedEvent +GLAD_API_CALL PFNGLXGETSWAPINTERVALMESAPROC glad_glXGetSwapIntervalMESA; +#define glXGetSwapIntervalMESA glad_glXGetSwapIntervalMESA +GLAD_API_CALL PFNGLXGETVISUALFROMFBCONFIGPROC glad_glXGetVisualFromFBConfig; +#define glXGetVisualFromFBConfig glad_glXGetVisualFromFBConfig +GLAD_API_CALL PFNGLXISDIRECTPROC glad_glXIsDirect; +#define glXIsDirect glad_glXIsDirect +GLAD_API_CALL PFNGLXMAKECONTEXTCURRENTPROC glad_glXMakeContextCurrent; +#define glXMakeContextCurrent glad_glXMakeContextCurrent +GLAD_API_CALL PFNGLXMAKECURRENTPROC glad_glXMakeCurrent; +#define glXMakeCurrent glad_glXMakeCurrent +GLAD_API_CALL PFNGLXQUERYCONTEXTPROC glad_glXQueryContext; +#define glXQueryContext glad_glXQueryContext +GLAD_API_CALL PFNGLXQUERYDRAWABLEPROC glad_glXQueryDrawable; +#define glXQueryDrawable glad_glXQueryDrawable +GLAD_API_CALL PFNGLXQUERYEXTENSIONPROC glad_glXQueryExtension; +#define glXQueryExtension glad_glXQueryExtension +GLAD_API_CALL PFNGLXQUERYEXTENSIONSSTRINGPROC glad_glXQueryExtensionsString; +#define glXQueryExtensionsString glad_glXQueryExtensionsString +GLAD_API_CALL PFNGLXQUERYSERVERSTRINGPROC glad_glXQueryServerString; +#define glXQueryServerString glad_glXQueryServerString +GLAD_API_CALL PFNGLXQUERYVERSIONPROC glad_glXQueryVersion; +#define glXQueryVersion glad_glXQueryVersion +GLAD_API_CALL PFNGLXSELECTEVENTPROC glad_glXSelectEvent; +#define glXSelectEvent glad_glXSelectEvent +GLAD_API_CALL PFNGLXSWAPBUFFERSPROC glad_glXSwapBuffers; +#define glXSwapBuffers glad_glXSwapBuffers +GLAD_API_CALL PFNGLXSWAPINTERVALEXTPROC glad_glXSwapIntervalEXT; +#define glXSwapIntervalEXT glad_glXSwapIntervalEXT +GLAD_API_CALL PFNGLXSWAPINTERVALMESAPROC glad_glXSwapIntervalMESA; +#define glXSwapIntervalMESA glad_glXSwapIntervalMESA +GLAD_API_CALL PFNGLXSWAPINTERVALSGIPROC glad_glXSwapIntervalSGI; +#define glXSwapIntervalSGI glad_glXSwapIntervalSGI +GLAD_API_CALL PFNGLXUSEXFONTPROC glad_glXUseXFont; +#define glXUseXFont glad_glXUseXFont +GLAD_API_CALL PFNGLXWAITGLPROC glad_glXWaitGL; +#define glXWaitGL glad_glXWaitGL +GLAD_API_CALL PFNGLXWAITXPROC glad_glXWaitX; +#define glXWaitX glad_glXWaitX + + + + + +GLAD_API_CALL int gladLoadGLXUserPtr(Display *display, int screen, GLADuserptrloadfunc load, void *userptr); +GLAD_API_CALL int gladLoadGLX(Display *display, int screen, GLADloadfunc load); + +#ifdef GLAD_GLX + +GLAD_API_CALL int gladLoaderLoadGLX(Display *display, int screen); + +GLAD_API_CALL void gladLoaderUnloadGLX(void); + +#endif +#ifdef __cplusplus +} +#endif +#endif diff --git a/thirdparty/glad/glx.c b/thirdparty/glad/glx.c new file mode 100644 index 0000000000..6391027db2 --- /dev/null +++ b/thirdparty/glad/glx.c @@ -0,0 +1,395 @@ +/** + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <glad/glx.h> + +#ifndef GLAD_IMPL_UTIL_C_ +#define GLAD_IMPL_UTIL_C_ + +#ifdef _MSC_VER +#define GLAD_IMPL_UTIL_SSCANF sscanf_s +#else +#define GLAD_IMPL_UTIL_SSCANF sscanf +#endif + +#endif /* GLAD_IMPL_UTIL_C_ */ + +#ifdef __cplusplus +extern "C" { +#endif + + + +int GLAD_GLX_VERSION_1_0 = 0; +int GLAD_GLX_VERSION_1_1 = 0; +int GLAD_GLX_VERSION_1_2 = 0; +int GLAD_GLX_VERSION_1_3 = 0; +int GLAD_GLX_VERSION_1_4 = 0; +int GLAD_GLX_ARB_create_context = 0; +int GLAD_GLX_ARB_create_context_profile = 0; +int GLAD_GLX_ARB_get_proc_address = 0; +int GLAD_GLX_EXT_swap_control = 0; +int GLAD_GLX_MESA_swap_control = 0; +int GLAD_GLX_SGI_swap_control = 0; + + + +PFNGLXCHOOSEFBCONFIGPROC glad_glXChooseFBConfig = NULL; +PFNGLXCHOOSEVISUALPROC glad_glXChooseVisual = NULL; +PFNGLXCOPYCONTEXTPROC glad_glXCopyContext = NULL; +PFNGLXCREATECONTEXTPROC glad_glXCreateContext = NULL; +PFNGLXCREATECONTEXTATTRIBSARBPROC glad_glXCreateContextAttribsARB = NULL; +PFNGLXCREATEGLXPIXMAPPROC glad_glXCreateGLXPixmap = NULL; +PFNGLXCREATENEWCONTEXTPROC glad_glXCreateNewContext = NULL; +PFNGLXCREATEPBUFFERPROC glad_glXCreatePbuffer = NULL; +PFNGLXCREATEPIXMAPPROC glad_glXCreatePixmap = NULL; +PFNGLXCREATEWINDOWPROC glad_glXCreateWindow = NULL; +PFNGLXDESTROYCONTEXTPROC glad_glXDestroyContext = NULL; +PFNGLXDESTROYGLXPIXMAPPROC glad_glXDestroyGLXPixmap = NULL; +PFNGLXDESTROYPBUFFERPROC glad_glXDestroyPbuffer = NULL; +PFNGLXDESTROYPIXMAPPROC glad_glXDestroyPixmap = NULL; +PFNGLXDESTROYWINDOWPROC glad_glXDestroyWindow = NULL; +PFNGLXGETCLIENTSTRINGPROC glad_glXGetClientString = NULL; +PFNGLXGETCONFIGPROC glad_glXGetConfig = NULL; +PFNGLXGETCURRENTCONTEXTPROC glad_glXGetCurrentContext = NULL; +PFNGLXGETCURRENTDISPLAYPROC glad_glXGetCurrentDisplay = NULL; +PFNGLXGETCURRENTDRAWABLEPROC glad_glXGetCurrentDrawable = NULL; +PFNGLXGETCURRENTREADDRAWABLEPROC glad_glXGetCurrentReadDrawable = NULL; +PFNGLXGETFBCONFIGATTRIBPROC glad_glXGetFBConfigAttrib = NULL; +PFNGLXGETFBCONFIGSPROC glad_glXGetFBConfigs = NULL; +PFNGLXGETPROCADDRESSPROC glad_glXGetProcAddress = NULL; +PFNGLXGETPROCADDRESSARBPROC glad_glXGetProcAddressARB = NULL; +PFNGLXGETSELECTEDEVENTPROC glad_glXGetSelectedEvent = NULL; +PFNGLXGETSWAPINTERVALMESAPROC glad_glXGetSwapIntervalMESA = NULL; +PFNGLXGETVISUALFROMFBCONFIGPROC glad_glXGetVisualFromFBConfig = NULL; +PFNGLXISDIRECTPROC glad_glXIsDirect = NULL; +PFNGLXMAKECONTEXTCURRENTPROC glad_glXMakeContextCurrent = NULL; +PFNGLXMAKECURRENTPROC glad_glXMakeCurrent = NULL; +PFNGLXQUERYCONTEXTPROC glad_glXQueryContext = NULL; +PFNGLXQUERYDRAWABLEPROC glad_glXQueryDrawable = NULL; +PFNGLXQUERYEXTENSIONPROC glad_glXQueryExtension = NULL; +PFNGLXQUERYEXTENSIONSSTRINGPROC glad_glXQueryExtensionsString = NULL; +PFNGLXQUERYSERVERSTRINGPROC glad_glXQueryServerString = NULL; +PFNGLXQUERYVERSIONPROC glad_glXQueryVersion = NULL; +PFNGLXSELECTEVENTPROC glad_glXSelectEvent = NULL; +PFNGLXSWAPBUFFERSPROC glad_glXSwapBuffers = NULL; +PFNGLXSWAPINTERVALEXTPROC glad_glXSwapIntervalEXT = NULL; +PFNGLXSWAPINTERVALMESAPROC glad_glXSwapIntervalMESA = NULL; +PFNGLXSWAPINTERVALSGIPROC glad_glXSwapIntervalSGI = NULL; +PFNGLXUSEXFONTPROC glad_glXUseXFont = NULL; +PFNGLXWAITGLPROC glad_glXWaitGL = NULL; +PFNGLXWAITXPROC glad_glXWaitX = NULL; + + +static void glad_glx_load_GLX_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_VERSION_1_0) return; + glad_glXChooseVisual = (PFNGLXCHOOSEVISUALPROC) load(userptr, "glXChooseVisual"); + glad_glXCopyContext = (PFNGLXCOPYCONTEXTPROC) load(userptr, "glXCopyContext"); + glad_glXCreateContext = (PFNGLXCREATECONTEXTPROC) load(userptr, "glXCreateContext"); + glad_glXCreateGLXPixmap = (PFNGLXCREATEGLXPIXMAPPROC) load(userptr, "glXCreateGLXPixmap"); + glad_glXDestroyContext = (PFNGLXDESTROYCONTEXTPROC) load(userptr, "glXDestroyContext"); + glad_glXDestroyGLXPixmap = (PFNGLXDESTROYGLXPIXMAPPROC) load(userptr, "glXDestroyGLXPixmap"); + glad_glXGetConfig = (PFNGLXGETCONFIGPROC) load(userptr, "glXGetConfig"); + glad_glXGetCurrentContext = (PFNGLXGETCURRENTCONTEXTPROC) load(userptr, "glXGetCurrentContext"); + glad_glXGetCurrentDrawable = (PFNGLXGETCURRENTDRAWABLEPROC) load(userptr, "glXGetCurrentDrawable"); + glad_glXIsDirect = (PFNGLXISDIRECTPROC) load(userptr, "glXIsDirect"); + glad_glXMakeCurrent = (PFNGLXMAKECURRENTPROC) load(userptr, "glXMakeCurrent"); + glad_glXQueryExtension = (PFNGLXQUERYEXTENSIONPROC) load(userptr, "glXQueryExtension"); + glad_glXQueryVersion = (PFNGLXQUERYVERSIONPROC) load(userptr, "glXQueryVersion"); + glad_glXSwapBuffers = (PFNGLXSWAPBUFFERSPROC) load(userptr, "glXSwapBuffers"); + glad_glXUseXFont = (PFNGLXUSEXFONTPROC) load(userptr, "glXUseXFont"); + glad_glXWaitGL = (PFNGLXWAITGLPROC) load(userptr, "glXWaitGL"); + glad_glXWaitX = (PFNGLXWAITXPROC) load(userptr, "glXWaitX"); +} +static void glad_glx_load_GLX_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_VERSION_1_1) return; + glad_glXGetClientString = (PFNGLXGETCLIENTSTRINGPROC) load(userptr, "glXGetClientString"); + glad_glXQueryExtensionsString = (PFNGLXQUERYEXTENSIONSSTRINGPROC) load(userptr, "glXQueryExtensionsString"); + glad_glXQueryServerString = (PFNGLXQUERYSERVERSTRINGPROC) load(userptr, "glXQueryServerString"); +} +static void glad_glx_load_GLX_VERSION_1_2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_VERSION_1_2) return; + glad_glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC) load(userptr, "glXGetCurrentDisplay"); +} +static void glad_glx_load_GLX_VERSION_1_3( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_VERSION_1_3) return; + glad_glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) load(userptr, "glXChooseFBConfig"); + glad_glXCreateNewContext = (PFNGLXCREATENEWCONTEXTPROC) load(userptr, "glXCreateNewContext"); + glad_glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC) load(userptr, "glXCreatePbuffer"); + glad_glXCreatePixmap = (PFNGLXCREATEPIXMAPPROC) load(userptr, "glXCreatePixmap"); + glad_glXCreateWindow = (PFNGLXCREATEWINDOWPROC) load(userptr, "glXCreateWindow"); + glad_glXDestroyPbuffer = (PFNGLXDESTROYPBUFFERPROC) load(userptr, "glXDestroyPbuffer"); + glad_glXDestroyPixmap = (PFNGLXDESTROYPIXMAPPROC) load(userptr, "glXDestroyPixmap"); + glad_glXDestroyWindow = (PFNGLXDESTROYWINDOWPROC) load(userptr, "glXDestroyWindow"); + glad_glXGetCurrentReadDrawable = (PFNGLXGETCURRENTREADDRAWABLEPROC) load(userptr, "glXGetCurrentReadDrawable"); + glad_glXGetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC) load(userptr, "glXGetFBConfigAttrib"); + glad_glXGetFBConfigs = (PFNGLXGETFBCONFIGSPROC) load(userptr, "glXGetFBConfigs"); + glad_glXGetSelectedEvent = (PFNGLXGETSELECTEDEVENTPROC) load(userptr, "glXGetSelectedEvent"); + glad_glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC) load(userptr, "glXGetVisualFromFBConfig"); + glad_glXMakeContextCurrent = (PFNGLXMAKECONTEXTCURRENTPROC) load(userptr, "glXMakeContextCurrent"); + glad_glXQueryContext = (PFNGLXQUERYCONTEXTPROC) load(userptr, "glXQueryContext"); + glad_glXQueryDrawable = (PFNGLXQUERYDRAWABLEPROC) load(userptr, "glXQueryDrawable"); + glad_glXSelectEvent = (PFNGLXSELECTEVENTPROC) load(userptr, "glXSelectEvent"); +} +static void glad_glx_load_GLX_VERSION_1_4( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_VERSION_1_4) return; + glad_glXGetProcAddress = (PFNGLXGETPROCADDRESSPROC) load(userptr, "glXGetProcAddress"); +} +static void glad_glx_load_GLX_ARB_create_context( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_ARB_create_context) return; + glad_glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) load(userptr, "glXCreateContextAttribsARB"); +} +static void glad_glx_load_GLX_ARB_get_proc_address( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_ARB_get_proc_address) return; + glad_glXGetProcAddressARB = (PFNGLXGETPROCADDRESSARBPROC) load(userptr, "glXGetProcAddressARB"); +} +static void glad_glx_load_GLX_EXT_swap_control( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_EXT_swap_control) return; + glad_glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) load(userptr, "glXSwapIntervalEXT"); +} +static void glad_glx_load_GLX_MESA_swap_control( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_MESA_swap_control) return; + glad_glXGetSwapIntervalMESA = (PFNGLXGETSWAPINTERVALMESAPROC) load(userptr, "glXGetSwapIntervalMESA"); + glad_glXSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC) load(userptr, "glXSwapIntervalMESA"); +} +static void glad_glx_load_GLX_SGI_swap_control( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_SGI_swap_control) return; + glad_glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) load(userptr, "glXSwapIntervalSGI"); +} + + + +static int glad_glx_has_extension(Display *display, int screen, const char *ext) { +#ifndef GLX_VERSION_1_1 + GLAD_UNUSED(display); + GLAD_UNUSED(screen); + GLAD_UNUSED(ext); +#else + const char *terminator; + const char *loc; + const char *extensions; + + if (glXQueryExtensionsString == NULL) { + return 0; + } + + extensions = glXQueryExtensionsString(display, screen); + + if(extensions == NULL || ext == NULL) { + return 0; + } + + while(1) { + loc = strstr(extensions, ext); + if(loc == NULL) + break; + + terminator = loc + strlen(ext); + if((loc == extensions || *(loc - 1) == ' ') && + (*terminator == ' ' || *terminator == '\0')) { + return 1; + } + extensions = terminator; + } +#endif + + return 0; +} + +static GLADapiproc glad_glx_get_proc_from_userptr(void *userptr, const char* name) { + return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name); +} + +static int glad_glx_find_extensions(Display *display, int screen) { + GLAD_GLX_ARB_create_context = glad_glx_has_extension(display, screen, "GLX_ARB_create_context"); + GLAD_GLX_ARB_create_context_profile = glad_glx_has_extension(display, screen, "GLX_ARB_create_context_profile"); + GLAD_GLX_ARB_get_proc_address = glad_glx_has_extension(display, screen, "GLX_ARB_get_proc_address"); + GLAD_GLX_EXT_swap_control = glad_glx_has_extension(display, screen, "GLX_EXT_swap_control"); + GLAD_GLX_MESA_swap_control = glad_glx_has_extension(display, screen, "GLX_MESA_swap_control"); + GLAD_GLX_SGI_swap_control = glad_glx_has_extension(display, screen, "GLX_SGI_swap_control"); + return 1; +} + +static int glad_glx_find_core_glx(Display **display, int *screen) { + int major = 0, minor = 0; + if(*display == NULL) { +#ifdef GLAD_GLX_NO_X11 + GLAD_UNUSED(screen); + return 0; +#else + *display = XOpenDisplay(0); + if (*display == NULL) { + return 0; + } + *screen = XScreenNumberOfScreen(XDefaultScreenOfDisplay(*display)); +#endif + } + glXQueryVersion(*display, &major, &minor); + GLAD_GLX_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; + GLAD_GLX_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; + GLAD_GLX_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; + GLAD_GLX_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; + GLAD_GLX_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; + return GLAD_MAKE_VERSION(major, minor); +} + +int gladLoadGLXUserPtr(Display *display, int screen, GLADuserptrloadfunc load, void *userptr) { + int version; + glXQueryVersion = (PFNGLXQUERYVERSIONPROC) load(userptr, "glXQueryVersion"); + if(glXQueryVersion == NULL) return 0; + version = glad_glx_find_core_glx(&display, &screen); + + glad_glx_load_GLX_VERSION_1_0(load, userptr); + glad_glx_load_GLX_VERSION_1_1(load, userptr); + glad_glx_load_GLX_VERSION_1_2(load, userptr); + glad_glx_load_GLX_VERSION_1_3(load, userptr); + glad_glx_load_GLX_VERSION_1_4(load, userptr); + + if (!glad_glx_find_extensions(display, screen)) return 0; + glad_glx_load_GLX_ARB_create_context(load, userptr); + glad_glx_load_GLX_ARB_get_proc_address(load, userptr); + glad_glx_load_GLX_EXT_swap_control(load, userptr); + glad_glx_load_GLX_MESA_swap_control(load, userptr); + glad_glx_load_GLX_SGI_swap_control(load, userptr); + + + return version; +} + +int gladLoadGLX(Display *display, int screen, GLADloadfunc load) { + return gladLoadGLXUserPtr(display, screen, glad_glx_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); +} + + + +#ifdef GLAD_GLX + +#ifndef GLAD_LOADER_LIBRARY_C_ +#define GLAD_LOADER_LIBRARY_C_ + +#include <stddef.h> +#include <stdlib.h> + +#if GLAD_PLATFORM_WIN32 +#include <windows.h> +#else +#include <dlfcn.h> +#endif + + +static void* glad_get_dlopen_handle(const char *lib_names[], int length) { + void *handle = NULL; + int i; + + for (i = 0; i < length; ++i) { +#if GLAD_PLATFORM_WIN32 + #if GLAD_PLATFORM_UWP + size_t buffer_size = (strlen(lib_names[i]) + 1) * sizeof(WCHAR); + LPWSTR buffer = (LPWSTR) malloc(buffer_size); + if (buffer != NULL) { + int ret = MultiByteToWideChar(CP_ACP, 0, lib_names[i], -1, buffer, buffer_size); + if (ret != 0) { + handle = (void*) LoadPackagedLibrary(buffer, 0); + } + free((void*) buffer); + } + #else + handle = (void*) LoadLibraryA(lib_names[i]); + #endif +#else + handle = dlopen(lib_names[i], RTLD_LAZY | RTLD_LOCAL); +#endif + if (handle != NULL) { + return handle; + } + } + + return NULL; +} + +static void glad_close_dlopen_handle(void* handle) { + if (handle != NULL) { +#if GLAD_PLATFORM_WIN32 + FreeLibrary((HMODULE) handle); +#else + dlclose(handle); +#endif + } +} + +static GLADapiproc glad_dlsym_handle(void* handle, const char *name) { + if (handle == NULL) { + return NULL; + } + +#if GLAD_PLATFORM_WIN32 + return (GLADapiproc) GetProcAddress((HMODULE) handle, name); +#else + return GLAD_GNUC_EXTENSION (GLADapiproc) dlsym(handle, name); +#endif +} + +#endif /* GLAD_LOADER_LIBRARY_C_ */ + +typedef void* (GLAD_API_PTR *GLADglxprocaddrfunc)(const char*); + +static GLADapiproc glad_glx_get_proc(void *userptr, const char *name) { + return GLAD_GNUC_EXTENSION ((GLADapiproc (*)(const char *name)) userptr)(name); +} + +static void* _glx_handle; + +static void* glad_glx_dlopen_handle(void) { + static const char *NAMES[] = { +#if defined __CYGWIN__ + "libGL-1.so", +#endif + "libGL.so.1", + "libGL.so" + }; + + if (_glx_handle == NULL) { + _glx_handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0])); + } + + return _glx_handle; +} + +int gladLoaderLoadGLX(Display *display, int screen) { + int version = 0; + void *handle = NULL; + int did_load = 0; + GLADglxprocaddrfunc loader; + + did_load = _glx_handle == NULL; + handle = glad_glx_dlopen_handle(); + if (handle != NULL) { + loader = (GLADglxprocaddrfunc) glad_dlsym_handle(handle, "glXGetProcAddressARB"); + if (loader != NULL) { + version = gladLoadGLXUserPtr(display, screen, glad_glx_get_proc, GLAD_GNUC_EXTENSION (void*) loader); + } + + if (!version && did_load) { + gladLoaderUnloadGLX(); + } + } + + return version; +} + + +void gladLoaderUnloadGLX() { + if (_glx_handle != NULL) { + glad_close_dlopen_handle(_glx_handle); + _glx_handle = NULL; + } +} + +#endif /* GLAD_GLX */ + +#ifdef __cplusplus +} +#endif diff --git a/thirdparty/graphite/include/graphite2/Font.h b/thirdparty/graphite/include/graphite2/Font.h index fe569295a5..b0a1e36370 100644 --- a/thirdparty/graphite/include/graphite2/Font.h +++ b/thirdparty/graphite/include/graphite2/Font.h @@ -1,29 +1,5 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - - Alternatively, the contents of this file may be used under the terms - of the Mozilla Public License (http://mozilla.org/MPL) or the GNU - General Public License, as published by the Free Software Foundation, - either version 2 of the License or (at your option) any later version. -*/ +/* SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later */ +/* Copyright 2010, SIL International, All rights reserved. */ #pragma once #include "graphite2/Types.h" diff --git a/thirdparty/graphite/include/graphite2/Log.h b/thirdparty/graphite/include/graphite2/Log.h index a5a6947fab..d83b1b90e7 100644 --- a/thirdparty/graphite/include/graphite2/Log.h +++ b/thirdparty/graphite/include/graphite2/Log.h @@ -1,29 +1,5 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - - Alternatively, the contents of this file may be used under the terms - of the Mozilla Public License (http://mozilla.org/MPL) or the GNU - General Public License, as published by the Free Software Foundation, - either version 2 of the License or (at your option) any later version. -*/ +/* SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later */ +/* Copyright 2010, SIL International, All rights reserved. */ #pragma once #include <graphite2/Types.h> diff --git a/thirdparty/graphite/include/graphite2/Segment.h b/thirdparty/graphite/include/graphite2/Segment.h index 0e24f5d795..9969b4eb45 100644 --- a/thirdparty/graphite/include/graphite2/Segment.h +++ b/thirdparty/graphite/include/graphite2/Segment.h @@ -1,29 +1,5 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - - Alternatively, the contents of this file may be used under the terms - of the Mozilla Public License (http://mozilla.org/MPL) or the GNU - General Public License, as published by the Free Software Foundation, - either version 2 of the License or (at your option) any later version. -*/ +/* SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later */ +/* Copyright 2010, SIL International, All rights reserved. */ #pragma once #include "graphite2/Types.h" diff --git a/thirdparty/graphite/include/graphite2/Types.h b/thirdparty/graphite/include/graphite2/Types.h index 916c91191b..32236a6195 100644 --- a/thirdparty/graphite/include/graphite2/Types.h +++ b/thirdparty/graphite/include/graphite2/Types.h @@ -1,29 +1,5 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - - Alternatively, the contents of this file may be used under the terms - of the Mozilla Public License (http://mozilla.org/MPL) or the GNU - General Public License, as published by the Free Software Foundation, - either version 2 of the License or (at your option) any later version. -*/ +/* SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later */ +/* Copyright 2010, SIL International, All rights reserved. */ #pragma once #include <stddef.h> diff --git a/thirdparty/graphite/src/CmapCache.cpp b/thirdparty/graphite/src/CmapCache.cpp index d070019a34..ac860e9ee2 100644 --- a/thirdparty/graphite/src/CmapCache.cpp +++ b/thirdparty/graphite/src/CmapCache.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #include "inc/Main.h" #include "inc/CmapCache.h" diff --git a/thirdparty/graphite/src/Code.cpp b/thirdparty/graphite/src/Code.cpp index ec5ab298ca..4a53ae871b 100644 --- a/thirdparty/graphite/src/Code.cpp +++ b/thirdparty/graphite/src/Code.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + // This class represents loaded graphite stack machine code. It performs // basic sanity checks, on the incoming code to prevent more obvious problems // from crashing graphite. diff --git a/thirdparty/graphite/src/Collider.cpp b/thirdparty/graphite/src/Collider.cpp index 1929b39a58..ca36d4550a 100644 --- a/thirdparty/graphite/src/Collider.cpp +++ b/thirdparty/graphite/src/Collider.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #include <algorithm> #include <limits> #include <cmath> diff --git a/thirdparty/graphite/src/Decompressor.cpp b/thirdparty/graphite/src/Decompressor.cpp index 42dc9113e5..f9f1e28e5b 100644 --- a/thirdparty/graphite/src/Decompressor.cpp +++ b/thirdparty/graphite/src/Decompressor.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2015, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2015, SIL International, All rights reserved. + #include <cassert> #include "inc/Decompressor.h" diff --git a/thirdparty/graphite/src/Face.cpp b/thirdparty/graphite/src/Face.cpp index 3e106050d7..4dd5a780cf 100644 --- a/thirdparty/graphite/src/Face.cpp +++ b/thirdparty/graphite/src/Face.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #include <cstring> #include "graphite2/Segment.h" #include "inc/CmapCache.h" diff --git a/thirdparty/graphite/src/FeatureMap.cpp b/thirdparty/graphite/src/FeatureMap.cpp index 014a88fd08..992be05540 100644 --- a/thirdparty/graphite/src/FeatureMap.cpp +++ b/thirdparty/graphite/src/FeatureMap.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #include <cstring> #include "inc/Main.h" diff --git a/thirdparty/graphite/src/FileFace.cpp b/thirdparty/graphite/src/FileFace.cpp index 7e663876a7..2e41044688 100644 --- a/thirdparty/graphite/src/FileFace.cpp +++ b/thirdparty/graphite/src/FileFace.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2012, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2012, SIL International, All rights reserved. + #include <cstring> #include "inc/FileFace.h" diff --git a/thirdparty/graphite/src/Font.cpp b/thirdparty/graphite/src/Font.cpp index faf3715f9d..bffb4223d5 100644 --- a/thirdparty/graphite/src/Font.cpp +++ b/thirdparty/graphite/src/Font.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #include "inc/Face.h" #include "inc/Font.h" #include "inc/GlyphCache.h" diff --git a/thirdparty/graphite/src/GlyphCache.cpp b/thirdparty/graphite/src/GlyphCache.cpp index 282bdc18fd..30479bdc4d 100644 --- a/thirdparty/graphite/src/GlyphCache.cpp +++ b/thirdparty/graphite/src/GlyphCache.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2012, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2012, SIL International, All rights reserved. + #include "graphite2/Font.h" #include "inc/Main.h" @@ -44,12 +21,18 @@ namespace // variable length structures. template<typename W> - class _glat_iterator : public std::iterator<std::input_iterator_tag, std::pair<sparse::key_type, sparse::mapped_type> > + class _glat_iterator { unsigned short key() const { return uint16(be::peek<W>(_e) + _n); } unsigned int run() const { return be::peek<W>(_e+sizeof(W)); } void advance_entry() { _n = 0; _e = _v; be::skip<W>(_v,2); } public: + using iterator_category = std::input_iterator_tag; + using value_type = std::pair<sparse::key_type, sparse::mapped_type>; + using difference_type = ptrdiff_t; + using pointer = value_type *; + using reference = value_type &; + _glat_iterator(const void * glat=0) : _e(reinterpret_cast<const byte *>(glat)), _v(_e+2*sizeof(W)), _n(0) {} _glat_iterator<W> & operator ++ () { diff --git a/thirdparty/graphite/src/GlyphFace.cpp b/thirdparty/graphite/src/GlyphFace.cpp index bc5e63a9f0..d9408f556b 100644 --- a/thirdparty/graphite/src/GlyphFace.cpp +++ b/thirdparty/graphite/src/GlyphFace.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #include "inc/GlyphFace.h" diff --git a/thirdparty/graphite/src/Intervals.cpp b/thirdparty/graphite/src/Intervals.cpp index 0fe99a127a..b223a67f56 100644 --- a/thirdparty/graphite/src/Intervals.cpp +++ b/thirdparty/graphite/src/Intervals.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #include <algorithm> #include <cmath> #include <limits> diff --git a/thirdparty/graphite/src/Justifier.cpp b/thirdparty/graphite/src/Justifier.cpp index 78c11e6a51..0bb18225b9 100644 --- a/thirdparty/graphite/src/Justifier.cpp +++ b/thirdparty/graphite/src/Justifier.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2012, SIL International, All rights reserved. - Copyright 2012, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #include "inc/Segment.h" #include "graphite2/Font.h" diff --git a/thirdparty/graphite/src/NameTable.cpp b/thirdparty/graphite/src/NameTable.cpp index d42b7f95bd..85892f179c 100644 --- a/thirdparty/graphite/src/NameTable.cpp +++ b/thirdparty/graphite/src/NameTable.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #include "inc/Main.h" #include "inc/Endian.h" diff --git a/thirdparty/graphite/src/Pass.cpp b/thirdparty/graphite/src/Pass.cpp index 47ae2064f7..986fed83b1 100644 --- a/thirdparty/graphite/src/Pass.cpp +++ b/thirdparty/graphite/src/Pass.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #include "inc/Main.h" #include "inc/debug.h" #include "inc/Endian.h" @@ -194,7 +171,7 @@ bool Pass::readPass(const byte * const pass_start, size_t pass_length, size_t su m_cPConstraint = vm::Machine::Code(true, pcCode, pcCode + pass_constraint_len, precontext[0], be::peek<uint16>(sort_keys), *m_silf, face, PASS_TYPE_UNKNOWN); if (e.test(!m_cPConstraint, E_OUTOFMEM) - || e.test(m_cPConstraint.status() != Code::loaded, m_cPConstraint.status() + E_CODEFAILURE)) + || e.test(m_cPConstraint.status() != Code::loaded, int(m_cPConstraint.status()) + E_CODEFAILURE)) return face.error(e); face.error_context(face.error_context() - 1); } @@ -266,8 +243,8 @@ bool Pass::readRules(const byte * rule_map, const size_t num_entries, r->constraint = new (m_codes+n*2-1) vm::Machine::Code(true, rc_begin, rc_end, r->preContext, r->sort, *m_silf, face, pt, &prog_pool_free); if (e.test(!r->action || !r->constraint, E_OUTOFMEM) - || e.test(r->action->status() != Code::loaded, r->action->status() + E_CODEFAILURE) - || e.test(r->constraint->status() != Code::loaded, r->constraint->status() + E_CODEFAILURE) + || e.test(r->action->status() != Code::loaded, int(r->action->status()) + E_CODEFAILURE) + || e.test(r->constraint->status() != Code::loaded, int(r->constraint->status()) + E_CODEFAILURE) || e.test(!r->constraint->immutable(), E_MUTABLECCODE)) return face.error(e); } diff --git a/thirdparty/graphite/src/Position.cpp b/thirdparty/graphite/src/Position.cpp index d2fdbd4e7c..a727f61664 100644 --- a/thirdparty/graphite/src/Position.cpp +++ b/thirdparty/graphite/src/Position.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #include "inc/Position.h" #include <cmath> diff --git a/thirdparty/graphite/src/Segment.cpp b/thirdparty/graphite/src/Segment.cpp index 62edd4250f..7bb3d132fa 100644 --- a/thirdparty/graphite/src/Segment.cpp +++ b/thirdparty/graphite/src/Segment.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #include "inc/UtfCodec.h" #include <cstring> #include <cstdlib> diff --git a/thirdparty/graphite/src/Silf.cpp b/thirdparty/graphite/src/Silf.cpp index 44d3c96171..51a7473627 100644 --- a/thirdparty/graphite/src/Silf.cpp +++ b/thirdparty/graphite/src/Silf.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #include <cstdlib> #include "graphite2/Segment.h" #include "inc/debug.h" diff --git a/thirdparty/graphite/src/Slot.cpp b/thirdparty/graphite/src/Slot.cpp index 0fdb098952..040e90d109 100644 --- a/thirdparty/graphite/src/Slot.cpp +++ b/thirdparty/graphite/src/Slot.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #include "inc/Segment.h" #include "inc/Slot.h" #include "inc/Silf.h" diff --git a/thirdparty/graphite/src/Sparse.cpp b/thirdparty/graphite/src/Sparse.cpp index aa43113669..746dfc9522 100644 --- a/thirdparty/graphite/src/Sparse.cpp +++ b/thirdparty/graphite/src/Sparse.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2011, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2011, SIL International, All rights reserved. + #include <cassert> #include "inc/Sparse.h" #include "inc/bits.h" diff --git a/thirdparty/graphite/src/TtfUtil.cpp b/thirdparty/graphite/src/TtfUtil.cpp index 2eb46a11fb..47940112ee 100644 --- a/thirdparty/graphite/src/TtfUtil.cpp +++ b/thirdparty/graphite/src/TtfUtil.cpp @@ -1,39 +1,14 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ -/*--------------------------------------------------------------------*//*:Ignore this sentence. +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. -File: TtfUtil.cpp +/* Responsibility: Alan Ward Last reviewed: Not yet. Description Implements the methods for TtfUtil class. This file should remain portable to any C++ environment by only using standard C++ and the TTF structurs defined in Tt.h. --------------------------------------------------------------------------------*//*:End Ignore*/ +*/ /*********************************************************************************************** diff --git a/thirdparty/graphite/src/UtfCodec.cpp b/thirdparty/graphite/src/UtfCodec.cpp index a944bbf9d0..9156bad00f 100644 --- a/thirdparty/graphite/src/UtfCodec.cpp +++ b/thirdparty/graphite/src/UtfCodec.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #include "inc/UtfCodec.h" //using namespace graphite2; diff --git a/thirdparty/graphite/src/call_machine.cpp b/thirdparty/graphite/src/call_machine.cpp index fcd8a0c2c1..7d9d1ef315 100644 --- a/thirdparty/graphite/src/call_machine.cpp +++ b/thirdparty/graphite/src/call_machine.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + // This call threaded interpreter implmentation for machine.h // Author: Tim Eves diff --git a/thirdparty/graphite/src/direct_machine.cpp b/thirdparty/graphite/src/direct_machine.cpp index 86206cfe37..e3a28fa536 100644 --- a/thirdparty/graphite/src/direct_machine.cpp +++ b/thirdparty/graphite/src/direct_machine.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + // This direct threaded interpreter implmentation for machine.h // Author: Tim Eves diff --git a/thirdparty/graphite/src/gr_char_info.cpp b/thirdparty/graphite/src/gr_char_info.cpp index 612f9ba694..1345fae847 100644 --- a/thirdparty/graphite/src/gr_char_info.cpp +++ b/thirdparty/graphite/src/gr_char_info.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #include <cassert> #include "graphite2/Segment.h" #include "inc/CharInfo.h" diff --git a/thirdparty/graphite/src/gr_face.cpp b/thirdparty/graphite/src/gr_face.cpp index baa469727b..6e80036113 100644 --- a/thirdparty/graphite/src/gr_face.cpp +++ b/thirdparty/graphite/src/gr_face.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #include "graphite2/Font.h" #include "inc/Face.h" #include "inc/FileFace.h" diff --git a/thirdparty/graphite/src/gr_features.cpp b/thirdparty/graphite/src/gr_features.cpp index a560e053f2..67208f14e6 100644 --- a/thirdparty/graphite/src/gr_features.cpp +++ b/thirdparty/graphite/src/gr_features.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #include "graphite2/Font.h" #include "inc/Face.h" #include "inc/FeatureMap.h" diff --git a/thirdparty/graphite/src/gr_font.cpp b/thirdparty/graphite/src/gr_font.cpp index 724cc83c13..fc85112e24 100644 --- a/thirdparty/graphite/src/gr_font.cpp +++ b/thirdparty/graphite/src/gr_font.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #include "graphite2/Font.h" #include "inc/Font.h" diff --git a/thirdparty/graphite/src/gr_logging.cpp b/thirdparty/graphite/src/gr_logging.cpp index 8f1e675e62..c6f03fd616 100644 --- a/thirdparty/graphite/src/gr_logging.cpp +++ b/thirdparty/graphite/src/gr_logging.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #include <cstdio> #include "graphite2/Log.h" diff --git a/thirdparty/graphite/src/gr_segment.cpp b/thirdparty/graphite/src/gr_segment.cpp index 7a27e9c562..7592296c04 100644 --- a/thirdparty/graphite/src/gr_segment.cpp +++ b/thirdparty/graphite/src/gr_segment.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #include "graphite2/Segment.h" #include "inc/UtfCodec.h" #include "inc/Segment.h" diff --git a/thirdparty/graphite/src/gr_slot.cpp b/thirdparty/graphite/src/gr_slot.cpp index a3c6b46a7f..a6adefec61 100644 --- a/thirdparty/graphite/src/gr_slot.cpp +++ b/thirdparty/graphite/src/gr_slot.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #include "graphite2/Segment.h" #include "inc/Segment.h" #include "inc/Slot.h" diff --git a/thirdparty/graphite/src/inc/CharInfo.h b/thirdparty/graphite/src/inc/CharInfo.h index 01e7e31ac9..0fbfefda4d 100644 --- a/thirdparty/graphite/src/inc/CharInfo.h +++ b/thirdparty/graphite/src/inc/CharInfo.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #pragma once #include "inc/Main.h" diff --git a/thirdparty/graphite/src/inc/CmapCache.h b/thirdparty/graphite/src/inc/CmapCache.h index 7820c958b0..b18ce2929b 100644 --- a/thirdparty/graphite/src/inc/CmapCache.h +++ b/thirdparty/graphite/src/inc/CmapCache.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #pragma once #include "inc/Main.h" diff --git a/thirdparty/graphite/src/inc/Code.h b/thirdparty/graphite/src/inc/Code.h index 3cee67c81d..24e92e429d 100644 --- a/thirdparty/graphite/src/inc/Code.h +++ b/thirdparty/graphite/src/inc/Code.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + // This class represents loaded graphite stack machine code. It performs // basic sanity checks, on the incoming code to prevent more obvious problems // from crashing graphite. diff --git a/thirdparty/graphite/src/inc/Collider.h b/thirdparty/graphite/src/inc/Collider.h index 71e8400501..3a922660d4 100644 --- a/thirdparty/graphite/src/inc/Collider.h +++ b/thirdparty/graphite/src/inc/Collider.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #pragma once #include "inc/List.h" diff --git a/thirdparty/graphite/src/inc/Compression.h b/thirdparty/graphite/src/inc/Compression.h index 9fe10e025d..4f5193b931 100644 --- a/thirdparty/graphite/src/inc/Compression.h +++ b/thirdparty/graphite/src/inc/Compression.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2015, SIL International, All rights reserved. - Copyright 2015, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #pragma once diff --git a/thirdparty/graphite/src/inc/Decompressor.h b/thirdparty/graphite/src/inc/Decompressor.h index 10f21b7af1..1113e004c1 100644 --- a/thirdparty/graphite/src/inc/Decompressor.h +++ b/thirdparty/graphite/src/inc/Decompressor.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2015, SIL International, All rights reserved. - Copyright 2015, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #pragma once diff --git a/thirdparty/graphite/src/inc/Endian.h b/thirdparty/graphite/src/inc/Endian.h index 56ecfd8667..7bd201f92b 100644 --- a/thirdparty/graphite/src/inc/Endian.h +++ b/thirdparty/graphite/src/inc/Endian.h @@ -1,30 +1,5 @@ -/* GRAPHITE2 LICENSING - - Copyright 2011, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ - +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2011, SIL International, All rights reserved. /* Description: A set of fast template based decoders for decoding values of any C integer diff --git a/thirdparty/graphite/src/inc/Error.h b/thirdparty/graphite/src/inc/Error.h index 2b7ab763a2..7e14c8e754 100644 --- a/thirdparty/graphite/src/inc/Error.h +++ b/thirdparty/graphite/src/inc/Error.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2013, SIL International, All rights reserved. - Copyright 2013, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #pragma once // numbers are explicitly assigned for future proofing @@ -38,7 +15,7 @@ public: operator bool() { return (_e != 0); } int error() { return _e; } void error(int e) { _e = e; } - bool test(bool pr, int err) { return (_e = int(pr) * err); } + bool test(bool pr, int err) { return (_e = pr ? err : 0); } private: int _e; @@ -56,7 +33,7 @@ enum errcontext { EC_ARULEMAP = 9 // in Silf %d, pass %d, state %d }; -enum errors { +enum error { E_OUTOFMEM = 1, // Out of memory E_NOGLYPHS = 2, // There are no glyphs in the font E_BADUPEM = 3, // The units per em for the font is bad (0) @@ -125,7 +102,7 @@ enum errors { E_BADJUMPCODE = 65, // Code jumps past end of op codes E_CODEBADARGS = 66, // Code arguments exhausted E_CODENORETURN = 67, // Missing return type op code at end of code - E_CODENESTEDCTXT = 68, // Nested context encountered in code + E_CODENESTEDCTXT = 68, // Nested context encountered in code // Compression errors E_BADSCHEME = 69, E_SHRINKERFAILED = 70, diff --git a/thirdparty/graphite/src/inc/Face.h b/thirdparty/graphite/src/inc/Face.h index 355c5aa0d3..fac7fd4b8e 100644 --- a/thirdparty/graphite/src/inc/Face.h +++ b/thirdparty/graphite/src/inc/Face.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #pragma once #include <cstdio> diff --git a/thirdparty/graphite/src/inc/FeatureMap.h b/thirdparty/graphite/src/inc/FeatureMap.h index 0f05e941a2..a98008f738 100644 --- a/thirdparty/graphite/src/inc/FeatureMap.h +++ b/thirdparty/graphite/src/inc/FeatureMap.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #pragma once #include "inc/Main.h" #include "inc/FeatureVal.h" diff --git a/thirdparty/graphite/src/inc/FeatureVal.h b/thirdparty/graphite/src/inc/FeatureVal.h index cd3f93b2b5..35397f0f3b 100644 --- a/thirdparty/graphite/src/inc/FeatureVal.h +++ b/thirdparty/graphite/src/inc/FeatureVal.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #pragma once #include <cstring> #include <cassert> diff --git a/thirdparty/graphite/src/inc/FileFace.h b/thirdparty/graphite/src/inc/FileFace.h index 35927847f8..521942ee85 100644 --- a/thirdparty/graphite/src/inc/FileFace.h +++ b/thirdparty/graphite/src/inc/FileFace.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2012, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2012, SIL International, All rights reserved. + #pragma once //#include "inc/FeatureMap.h" diff --git a/thirdparty/graphite/src/inc/Font.h b/thirdparty/graphite/src/inc/Font.h index 9bc9ffb510..537ad9de0e 100644 --- a/thirdparty/graphite/src/inc/Font.h +++ b/thirdparty/graphite/src/inc/Font.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #pragma once #include <cassert> #include "graphite2/Font.h" diff --git a/thirdparty/graphite/src/inc/GlyphCache.h b/thirdparty/graphite/src/inc/GlyphCache.h index 7d5324e522..5f6d3eea18 100644 --- a/thirdparty/graphite/src/inc/GlyphCache.h +++ b/thirdparty/graphite/src/inc/GlyphCache.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2012, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2012, SIL International, All rights reserved. + #pragma once diff --git a/thirdparty/graphite/src/inc/GlyphFace.h b/thirdparty/graphite/src/inc/GlyphFace.h index fc29056146..f964c0581a 100644 --- a/thirdparty/graphite/src/inc/GlyphFace.h +++ b/thirdparty/graphite/src/inc/GlyphFace.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #pragma once #include "inc/Main.h" diff --git a/thirdparty/graphite/src/inc/Intervals.h b/thirdparty/graphite/src/inc/Intervals.h index 81d23187b6..15427d428a 100644 --- a/thirdparty/graphite/src/inc/Intervals.h +++ b/thirdparty/graphite/src/inc/Intervals.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #pragma once #include <utility> diff --git a/thirdparty/graphite/src/inc/List.h b/thirdparty/graphite/src/inc/List.h index a3b7a77961..3a36c17a7a 100644 --- a/thirdparty/graphite/src/inc/List.h +++ b/thirdparty/graphite/src/inc/List.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + // designed to have a limited subset of the std::vector api #pragma once diff --git a/thirdparty/graphite/src/inc/Machine.h b/thirdparty/graphite/src/inc/Machine.h index b23819fb98..5ceedc296d 100644 --- a/thirdparty/graphite/src/inc/Machine.h +++ b/thirdparty/graphite/src/inc/Machine.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + // This general interpreter interface. // Author: Tim Eves diff --git a/thirdparty/graphite/src/inc/Main.h b/thirdparty/graphite/src/inc/Main.h index ebf02dd553..6a412efeca 100644 --- a/thirdparty/graphite/src/inc/Main.h +++ b/thirdparty/graphite/src/inc/Main.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #pragma once #include <cstdlib> diff --git a/thirdparty/graphite/src/inc/NameTable.h b/thirdparty/graphite/src/inc/NameTable.h index 0fdbeb4d85..5a7913ddc5 100644 --- a/thirdparty/graphite/src/inc/NameTable.h +++ b/thirdparty/graphite/src/inc/NameTable.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #pragma once #include <graphite2/Segment.h> diff --git a/thirdparty/graphite/src/inc/Pass.h b/thirdparty/graphite/src/inc/Pass.h index e687a87d8c..fb507e6a04 100644 --- a/thirdparty/graphite/src/inc/Pass.h +++ b/thirdparty/graphite/src/inc/Pass.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #pragma once #include <cstdlib> diff --git a/thirdparty/graphite/src/inc/Position.h b/thirdparty/graphite/src/inc/Position.h index 510e4f4c41..554acc411e 100644 --- a/thirdparty/graphite/src/inc/Position.h +++ b/thirdparty/graphite/src/inc/Position.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #pragma once namespace graphite2 { diff --git a/thirdparty/graphite/src/inc/Rule.h b/thirdparty/graphite/src/inc/Rule.h index 5964e003a6..09025dc799 100644 --- a/thirdparty/graphite/src/inc/Rule.h +++ b/thirdparty/graphite/src/inc/Rule.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2011, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2011, SIL International, All rights reserved. + #pragma once diff --git a/thirdparty/graphite/src/inc/Segment.h b/thirdparty/graphite/src/inc/Segment.h index 6cf83408d4..a3a8eef648 100644 --- a/thirdparty/graphite/src/inc/Segment.h +++ b/thirdparty/graphite/src/inc/Segment.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #pragma once #include "inc/Main.h" diff --git a/thirdparty/graphite/src/inc/Silf.h b/thirdparty/graphite/src/inc/Silf.h index edc0c3a16d..6fe2aaef1f 100644 --- a/thirdparty/graphite/src/inc/Silf.h +++ b/thirdparty/graphite/src/inc/Silf.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #pragma once #include "graphite2/Font.h" diff --git a/thirdparty/graphite/src/inc/Slot.h b/thirdparty/graphite/src/inc/Slot.h index df39d9a3bb..0d8571d336 100644 --- a/thirdparty/graphite/src/inc/Slot.h +++ b/thirdparty/graphite/src/inc/Slot.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #pragma once #include "graphite2/Types.h" diff --git a/thirdparty/graphite/src/inc/Sparse.h b/thirdparty/graphite/src/inc/Sparse.h index fcda890171..3c5d33ae5d 100644 --- a/thirdparty/graphite/src/inc/Sparse.h +++ b/thirdparty/graphite/src/inc/Sparse.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2011, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2011, SIL International, All rights reserved. + #pragma once #include <iterator> #include <utility> diff --git a/thirdparty/graphite/src/inc/TtfTypes.h b/thirdparty/graphite/src/inc/TtfTypes.h index ae67915304..e4fd49f943 100644 --- a/thirdparty/graphite/src/inc/TtfTypes.h +++ b/thirdparty/graphite/src/inc/TtfTypes.h @@ -1,39 +1,14 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ -#pragma once -/*--------------------------------------------------------------------*//*:Ignore this sentence. +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. -File: TtfTypes.h +#pragma once +/* Responsibility: Tim Eves Last reviewed: Not yet. Description: Provides types required to represent the TTF basic types. --------------------------------------------------------------------------------*//*:End Ignore*/ +*/ //********************************************************************************************** diff --git a/thirdparty/graphite/src/inc/TtfUtil.h b/thirdparty/graphite/src/inc/TtfUtil.h index 3952bc06fb..1ccab42fb8 100644 --- a/thirdparty/graphite/src/inc/TtfUtil.h +++ b/thirdparty/graphite/src/inc/TtfUtil.h @@ -1,39 +1,13 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ -#pragma once -/*--------------------------------------------------------------------*//*:Ignore this sentence. - -File: TtfUtil.h +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. +/* Responsibility: Alan Ward Last reviewed: Not yet. Description: Utility class for handling TrueType font files. -----------------------------------------------------------------------------------------------*/ +*/ +#pragma once #include <cstddef> diff --git a/thirdparty/graphite/src/inc/UtfCodec.h b/thirdparty/graphite/src/inc/UtfCodec.h index 24a343d8d9..bab652c119 100644 --- a/thirdparty/graphite/src/inc/UtfCodec.h +++ b/thirdparty/graphite/src/inc/UtfCodec.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2011, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2011, SIL International, All rights reserved. + #pragma once #include <cstdlib> diff --git a/thirdparty/graphite/src/inc/bits.h b/thirdparty/graphite/src/inc/bits.h index 9365986a10..168ff256d3 100644 --- a/thirdparty/graphite/src/inc/bits.h +++ b/thirdparty/graphite/src/inc/bits.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2012, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2012, SIL International, All rights reserved. + #pragma once namespace graphite2 diff --git a/thirdparty/graphite/src/inc/debug.h b/thirdparty/graphite/src/inc/debug.h index 97175eb2cc..5b9c63872b 100644 --- a/thirdparty/graphite/src/inc/debug.h +++ b/thirdparty/graphite/src/inc/debug.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2011, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2011, SIL International, All rights reserved. + // debug.h // // Created on: 22 Dec 2011 diff --git a/thirdparty/graphite/src/inc/json.h b/thirdparty/graphite/src/inc/json.h index 554cd9a3d1..72011ef198 100644 --- a/thirdparty/graphite/src/inc/json.h +++ b/thirdparty/graphite/src/inc/json.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2011, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2011, SIL International, All rights reserved. + // JSON pretty printer for graphite font debug output logging. // Created on: 15 Dec 2011 // Author: Tim Eves diff --git a/thirdparty/graphite/src/inc/locale2lcid.h b/thirdparty/graphite/src/inc/locale2lcid.h index 25d5c0a3c8..e591c42b28 100644 --- a/thirdparty/graphite/src/inc/locale2lcid.h +++ b/thirdparty/graphite/src/inc/locale2lcid.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ #pragma once #include <cstring> #include <cassert> diff --git a/thirdparty/graphite/src/inc/opcode_table.h b/thirdparty/graphite/src/inc/opcode_table.h index cb5acde9a4..01a84831bc 100644 --- a/thirdparty/graphite/src/inc/opcode_table.h +++ b/thirdparty/graphite/src/inc/opcode_table.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ // This file will be pulled into and integrated into a machine implmentation // DO NOT build directly #pragma once diff --git a/thirdparty/graphite/src/inc/opcodes.h b/thirdparty/graphite/src/inc/opcodes.h index ff2f1741e2..10ba177229 100644 --- a/thirdparty/graphite/src/inc/opcodes.h +++ b/thirdparty/graphite/src/inc/opcodes.h @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2010, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2010, SIL International, All rights reserved. + #pragma once // This file will be pulled into and integrated into a machine implmentation // DO NOT build directly and under no circumstances ever #include headers in diff --git a/thirdparty/graphite/src/json.cpp b/thirdparty/graphite/src/json.cpp index 25f2190f71..7990654eb8 100644 --- a/thirdparty/graphite/src/json.cpp +++ b/thirdparty/graphite/src/json.cpp @@ -1,29 +1,6 @@ -/* GRAPHITE2 LICENSING - - Copyright 2011, SIL International - All rights reserved. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should also have received a copy of the GNU Lesser General Public - License along with this library in the file named "LICENSE". - If not, write to the Free Software Foundation, 51 Franklin Street, - Suite 500, Boston, MA 02110-1335, USA or visit their web page on the - internet at http://www.fsf.org/licenses/lgpl.html. - -Alternatively, the contents of this file may be used under the terms of the -Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public -License, as published by the Free Software Foundation, either version 2 -of the License or (at your option) any later version. -*/ +// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later +// Copyright 2011, SIL International, All rights reserved. + // JSON debug logging // Author: Tim Eves diff --git a/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh b/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh index eef89a2879..fbd7c642ab 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh @@ -49,7 +49,7 @@ struct Coverage HBUINT16 format; /* Format identifier */ CoverageFormat1_3<SmallTypes> format1; CoverageFormat2_4<SmallTypes> format2; -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K CoverageFormat1_3<MediumTypes>format3; CoverageFormat2_4<MediumTypes>format4; #endif @@ -65,7 +65,7 @@ struct Coverage { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 3: return_trace (u.format3.sanitize (c)); case 4: return_trace (u.format4.sanitize (c)); #endif @@ -74,10 +74,8 @@ struct Coverage } /* Has interface. */ - static constexpr unsigned SENTINEL = NOT_COVERED; - typedef unsigned int value_t; - value_t operator [] (hb_codepoint_t k) const { return get (k); } - bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; } + unsigned operator [] (hb_codepoint_t k) const { return get (k); } + bool has (hb_codepoint_t k) const { return (*this)[k] != NOT_COVERED; } /* Predicate. */ bool operator () (hb_codepoint_t k) const { return has (k); } @@ -87,7 +85,7 @@ struct Coverage switch (u.format) { case 1: return u.format1.get_coverage (glyph_id); case 2: return u.format2.get_coverage (glyph_id); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 3: return u.format3.get_coverage (glyph_id); case 4: return u.format4.get_coverage (glyph_id); #endif @@ -100,7 +98,7 @@ struct Coverage switch (u.format) { case 1: return u.format1.get_population (); case 2: return u.format2.get_population (); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 3: return u.format3.get_population (); case 4: return u.format4.get_population (); #endif @@ -127,7 +125,7 @@ struct Coverage } u.format = count <= num_ranges * 3 ? 1 : 2; -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K if (count && last > 0xFFFFu) u.format += 2; #endif @@ -136,7 +134,7 @@ struct Coverage { case 1: return_trace (u.format1.serialize (c, glyphs)); case 2: return_trace (u.format2.serialize (c, glyphs)); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 3: return_trace (u.format3.serialize (c, glyphs)); case 4: return_trace (u.format4.serialize (c, glyphs)); #endif @@ -166,7 +164,7 @@ struct Coverage { case 1: return u.format1.intersects (glyphs); case 2: return u.format2.intersects (glyphs); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 3: return u.format3.intersects (glyphs); case 4: return u.format4.intersects (glyphs); #endif @@ -179,7 +177,7 @@ struct Coverage { case 1: return u.format1.intersects_coverage (glyphs, index); case 2: return u.format2.intersects_coverage (glyphs, index); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 3: return u.format3.intersects_coverage (glyphs, index); case 4: return u.format4.intersects_coverage (glyphs, index); #endif @@ -196,7 +194,7 @@ struct Coverage { case 1: return u.format1.collect_coverage (glyphs); case 2: return u.format2.collect_coverage (glyphs); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 3: return u.format3.collect_coverage (glyphs); case 4: return u.format4.collect_coverage (glyphs); #endif @@ -212,7 +210,7 @@ struct Coverage { case 1: return u.format1.intersect_set (glyphs, intersect_glyphs); case 2: return u.format2.intersect_set (glyphs, intersect_glyphs); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 3: return u.format3.intersect_set (glyphs, intersect_glyphs); case 4: return u.format4.intersect_set (glyphs, intersect_glyphs); #endif @@ -225,13 +223,13 @@ struct Coverage static constexpr bool is_sorted_iterator = true; iter_t (const Coverage &c_ = Null (Coverage)) { - memset (this, 0, sizeof (*this)); + hb_memset (this, 0, sizeof (*this)); format = c_.u.format; switch (format) { case 1: u.format1.init (c_.u.format1); return; case 2: u.format2.init (c_.u.format2); return; -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 3: u.format3.init (c_.u.format3); return; case 4: u.format4.init (c_.u.format4); return; #endif @@ -244,7 +242,7 @@ struct Coverage { case 1: return u.format1.__more__ (); case 2: return u.format2.__more__ (); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 3: return u.format3.__more__ (); case 4: return u.format4.__more__ (); #endif @@ -257,7 +255,7 @@ struct Coverage { case 1: u.format1.__next__ (); break; case 2: u.format2.__next__ (); break; -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 3: u.format3.__next__ (); break; case 4: u.format4.__next__ (); break; #endif @@ -273,7 +271,7 @@ struct Coverage { case 1: return u.format1.get_glyph (); case 2: return u.format2.get_glyph (); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 3: return u.format3.get_glyph (); case 4: return u.format4.get_glyph (); #endif @@ -287,7 +285,7 @@ struct Coverage { case 1: return u.format1 != o.u.format1; case 2: return u.format2 != o.u.format2; -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 3: return u.format3 != o.u.format3; case 4: return u.format4 != o.u.format4; #endif @@ -302,7 +300,7 @@ struct Coverage { case 1: it.u.format1 = u.format1.__end__ (); break; case 2: it.u.format2 = u.format2.__end__ (); break; -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 3: it.u.format3 = u.format3.__end__ (); break; case 4: it.u.format4 = u.format4.__end__ (); break; #endif @@ -314,7 +312,7 @@ struct Coverage private: unsigned int format; union { -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K CoverageFormat2_4<MediumTypes>::iter_t format4; /* Put this one first since it's larger; helps shut up compiler. */ CoverageFormat1_3<MediumTypes>::iter_t format3; #endif diff --git a/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh index 82fd48dc50..5d68e3d15e 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh @@ -77,7 +77,14 @@ struct CoverageFormat1_3 bool intersects (const hb_set_t *glyphs) const { - /* TODO Speed up, using hb_set_next() and bsearch()? */ + if (glyphArray.len > glyphs->get_population () * hb_bit_storage ((unsigned) glyphArray.len) / 2) + { + for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);) + if (get_coverage (g) != NOT_COVERED) + return true; + return false; + } + for (const auto& g : glyphArray.as_array ()) if (glyphs->has (g)) return true; diff --git a/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh index 974d094633..d7fcc35202 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh @@ -80,8 +80,6 @@ struct CoverageFormat2_4 TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (this))) return_trace (false); - /* TODO(iter) Write more efficiently? */ - unsigned num_ranges = 0; hb_codepoint_t last = (hb_codepoint_t) -2; for (auto g: glyphs) @@ -115,26 +113,22 @@ struct CoverageFormat2_4 bool intersects (const hb_set_t *glyphs) const { + if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2) + { + for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);) + if (get_coverage (g) != NOT_COVERED) + return true; + return false; + } + return hb_any (+ hb_iter (rangeRecord) | hb_map ([glyphs] (const RangeRecord<Types> &range) { return range.intersects (*glyphs); })); } bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { - auto cmp = [] (const void *pk, const void *pr) -> int - { - unsigned index = * (const unsigned *) pk; - const RangeRecord<Types> &range = * (const RangeRecord<Types> *) pr; - if (index < range.value) return -1; - if (index > (unsigned int) range.value + (range.last - range.first)) return +1; - return 0; - }; - - auto arr = rangeRecord.as_array (); - unsigned idx; - if (hb_bsearch_impl (&idx, index, - arr.arrayZ, arr.length, sizeof (arr[0]), - (int (*)(const void *_key, const void *_item)) cmp)) - return arr.arrayZ[idx].intersects (*glyphs); + auto *range = rangeRecord.as_array ().bsearch (index); + if (range) + return range->intersects (*glyphs); return false; } @@ -142,9 +136,14 @@ struct CoverageFormat2_4 hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))> void intersect_set (const hb_set_t &glyphs, IterableOut&& intersect_glyphs) const { + /* Break out of loop for overlapping, broken, tables, + * to avoid fuzzer timouts. */ + hb_codepoint_t last = 0; for (const auto& range : rangeRecord) { - hb_codepoint_t last = range.last; + if (unlikely (range.first < last)) + break; + last = range.last; for (hb_codepoint_t g = range.first - 1; glyphs.next (&g) && g <= last;) intersect_glyphs << g; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh index c99b6b2e4b..edf7099c07 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh @@ -13,7 +13,7 @@ struct MarkBasePos union { HBUINT16 format; /* Format identifier */ MarkBasePosFormat1_2<SmallTypes> format1; -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K MarkBasePosFormat1_2<MediumTypes> format2; #endif } u; @@ -26,7 +26,7 @@ struct MarkBasePos if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); #endif default:return_trace (c->default_return_value ()); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh index 8a4de9ffaa..09152fd876 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh @@ -13,7 +13,7 @@ struct MarkLigPos union { HBUINT16 format; /* Format identifier */ MarkLigPosFormat1_2<SmallTypes> format1; -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K MarkLigPosFormat1_2<MediumTypes> format2; #endif } u; @@ -26,7 +26,7 @@ struct MarkLigPos if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); #endif default:return_trace (c->default_return_value ()); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh index 74b5105c42..4118fc304f 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh @@ -13,7 +13,7 @@ struct MarkMarkPos union { HBUINT16 format; /* Format identifier */ MarkMarkPosFormat1_2<SmallTypes> format1; -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K MarkMarkPosFormat1_2<MediumTypes> format2; #endif } u; @@ -26,7 +26,7 @@ struct MarkMarkPos if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); #endif default:return_trace (c->default_return_value ()); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh index 72bfc43dc4..9823768cbc 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh @@ -15,7 +15,7 @@ struct PairPos HBUINT16 format; /* Format identifier */ PairPosFormat1_3<SmallTypes> format1; PairPosFormat2_4<SmallTypes> format2; -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K PairPosFormat1_3<MediumTypes> format3; PairPosFormat2_4<MediumTypes> format4; #endif @@ -30,7 +30,7 @@ struct PairPos switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...)); case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...)); #endif diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh index ddf7313f94..9c9b268889 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh @@ -51,8 +51,21 @@ struct PairPosFormat1_3 bool intersects (const hb_set_t *glyphs) const { + auto &cov = this+coverage; + + if (pairSet.len > glyphs->get_population () * hb_bit_storage ((unsigned) pairSet.len) / 4) + { + for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);) + { + unsigned i = cov.get_coverage (g); + if ((this+pairSet[i]).intersects (glyphs, valueFormat)) + return true; + } + return false; + } + return - + hb_zip (this+coverage, pairSet) + + hb_zip (cov, pairSet) | hb_filter (*glyphs, hb_first) | hb_map (hb_second) | hb_map ([glyphs, this] (const typename Types::template OffsetTo<PairSet> &_) @@ -171,12 +184,16 @@ struct PairPosFormat1_3 unsigned format1 = 0; unsigned format2 = 0; for (const auto & _ : - + hb_zip (this+coverage, pairSet) | hb_filter (glyphset, hb_first) | hb_map (hb_second)) + + hb_zip (this+coverage, pairSet) + | hb_filter (glyphset, hb_first) + | hb_map (hb_second) + ) { const PairSet& set = (this + _); const PairValueRecord *record = &set.firstPairValueRecord; - for (unsigned i = 0; i < set.len; i++) + unsigned count = set.len; + for (unsigned i = 0; i < count; i++) { if (record->intersects (glyphset)) { @@ -185,6 +202,9 @@ struct PairPosFormat1_3 } record = &StructAtOffset<const PairValueRecord> (record, record_size); } + + if (format1 == valueFormat[0] && format2 == valueFormat[1]) + break; } return hb_pair (format1, format2); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh index 83b093b988..9c87ac2b03 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh @@ -220,17 +220,25 @@ struct PairPosFormat2_4 if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) { c->buffer->message (c->font, - "kerning glyphs at %d,%d", + "try kerning glyphs at %d,%d", c->buffer->idx, skippy_iter.idx); } applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos()); applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]); + if (applied_first || applied_second) + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "kerned glyphs at %d,%d", + c->buffer->idx, skippy_iter.idx); + } + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) { c->buffer->message (c->font, - "kerned glyphs at %d,%d", + "tried kerning glyphs at %d,%d", c->buffer->idx, skippy_iter.idx); } @@ -241,10 +249,15 @@ struct PairPosFormat2_4 boring: buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1); + if (len2) + { + skippy_iter.idx++; + // https://github.com/harfbuzz/harfbuzz/issues/3824 + // https://github.com/harfbuzz/harfbuzz/issues/3888#issuecomment-1326781116 + buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1); + } buffer->idx = skippy_iter.idx; - if (len2) - buffer->idx++; return_trace (true); } @@ -309,6 +322,7 @@ struct PairPosFormat2_4 { unsigned len1 = valueFormat1.get_len (); unsigned len2 = valueFormat2.get_len (); + unsigned record_size = len1 + len2; unsigned format1 = 0; unsigned format2 = 0; @@ -317,10 +331,13 @@ struct PairPosFormat2_4 { for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map)) { - unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2); + unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * record_size; format1 = format1 | valueFormat1.get_effective_format (&values[idx]); format2 = format2 | valueFormat2.get_effective_format (&values[idx + len1]); } + + if (format1 == valueFormat1 && format2 == valueFormat2) + break; } return hb_pair (format1, format2); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh index aa48d933c3..a318f39913 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh @@ -112,24 +112,38 @@ struct PairSet if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) { c->buffer->message (c->font, - "kerning glyphs at %d,%d", + "try kerning glyphs at %d,%d", c->buffer->idx, pos); } bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()); bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]); + if (applied_first || applied_second) + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "kerned glyphs at %d,%d", + c->buffer->idx, pos); + } + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) { c->buffer->message (c->font, - "kerned glyphs at %d,%d", + "tried kerning glyphs at %d,%d", c->buffer->idx, pos); } if (applied_first || applied_second) buffer->unsafe_to_break (buffer->idx, pos + 1); + if (len2) - pos++; + { + pos++; + // https://github.com/harfbuzz/harfbuzz/issues/3824 + // https://github.com/harfbuzz/harfbuzz/issues/3888#issuecomment-1326781116 + buffer->unsafe_to_break (buffer->idx, pos + 1); + } buffer->idx = pos; return_trace (true); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh index 4a9e9672eb..6c50c9717a 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh @@ -84,7 +84,7 @@ struct AlternateSet { if (alternates.len && alternate_count) { - + alternates.sub_array (start_offset, alternate_count) + + alternates.as_array ().sub_array (start_offset, alternate_count) | hb_sink (hb_array (alternate_glyphs, *alternate_count)) ; } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubst.hh index 37406179a2..9d7cd6fddf 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubst.hh @@ -14,7 +14,7 @@ struct AlternateSubst union { HBUINT16 format; /* Format identifier */ AlternateSubstFormat1_2<SmallTypes> format1; -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K AlternateSubstFormat1_2<MediumTypes> format2; #endif } u; @@ -27,7 +27,7 @@ struct AlternateSubst if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); #endif default:return_trace (c->default_return_value ()); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh index 6caa80e056..cdb35f525b 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh @@ -118,7 +118,7 @@ struct Ligature match_positions[i] += delta; if (i) *p++ = ','; - snprintf (p, sizeof(buf), "%u", match_positions[i]); + snprintf (p, sizeof(buf) - (p - buf), "%u", match_positions[i]); p += strlen(p); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubst.hh index 63707972a8..7ba19e844c 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubst.hh @@ -14,7 +14,7 @@ struct LigatureSubst union { HBUINT16 format; /* Format identifier */ LigatureSubstFormat1_2<SmallTypes> format1; -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K LigatureSubstFormat1_2<MediumTypes> format2; #endif } u; @@ -27,7 +27,7 @@ struct LigatureSubst if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); #endif default:return_trace (c->default_return_value ()); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubst.hh index 852ca3eac5..95710ed2be 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubst.hh @@ -14,7 +14,7 @@ struct MultipleSubst union { HBUINT16 format; /* Format identifier */ MultipleSubstFormat1_2<SmallTypes> format1; -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K MultipleSubstFormat1_2<MediumTypes> format2; #endif } u; @@ -28,7 +28,7 @@ struct MultipleSubst if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); #endif default:return_trace (c->default_return_value ()); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh index abf1c643ff..e2190078b8 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh @@ -117,7 +117,7 @@ struct Sequence { if (buf < p) *p++ = ','; - snprintf (p, sizeof(buf), "%u", i); + snprintf (p, sizeof(buf) - (p - buf), "%u", i); p += strlen(p); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubst.hh index 6942e6997f..7da8103168 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubst.hh @@ -16,7 +16,7 @@ struct SingleSubst HBUINT16 format; /* Format identifier */ SingleSubstFormat1_3<SmallTypes> format1; SingleSubstFormat2_4<SmallTypes> format2; -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K SingleSubstFormat1_3<MediumTypes> format3; SingleSubstFormat2_4<MediumTypes> format4; #endif @@ -32,7 +32,7 @@ struct SingleSubst switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...)); case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...)); #endif @@ -55,7 +55,7 @@ struct SingleSubst format = 1; hb_codepoint_t mask = 0xFFFFu; -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K if (+ glyphs | hb_map_retains_sorting (hb_first) | hb_filter ([] (hb_codepoint_t gid) { return gid > 0xFFFFu; })) @@ -78,7 +78,7 @@ struct SingleSubst | hb_map_retains_sorting (hb_first), delta)); case 2: return_trace (u.format2.serialize (c, glyphs)); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 3: return_trace (u.format3.serialize (c, + glyphs | hb_map_retains_sorting (hb_first), diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh index 13665d7ba1..1be21b98bc 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh @@ -57,7 +57,7 @@ struct SingleSubstFormat1_3 hb_codepoint_t max_before = intersection.get_max (); hb_codepoint_t min_after = (min_before + d) & mask; hb_codepoint_t max_after = (max_before + d) & mask; - if (pop >= max_before - min_before && + if (intersection.get_population () == max_before - min_before + 1 && ((min_before <= min_after && min_after <= max_before) || (min_before <= max_after && max_after <= max_before))) return; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh index 5416299754..01df714525 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh @@ -36,8 +36,24 @@ struct SingleSubstFormat2_4 void closure (hb_closure_context_t *c) const { - + hb_zip (this+coverage, substitute) - | hb_filter (c->parent_active_glyphs (), hb_first) + auto &cov = this+coverage; + auto &glyph_set = c->parent_active_glyphs (); + + if (substitute.len > glyph_set.get_population () * 4) + { + for (auto g : glyph_set) + { + unsigned i = cov.get_coverage (g); + if (i == NOT_COVERED || i >= substitute.len) + continue; + c->output->add (substitute.arrayZ[i]); + } + + return; + } + + + hb_zip (cov, substitute) + | hb_filter (glyph_set, hb_first) | hb_map (hb_second) | hb_sink (c->output) ; diff --git a/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh index fc8e309bc9..edf8cd8797 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh @@ -3,6 +3,7 @@ #include "../../hb-open-type.hh" +#include "composite-iter.hh" namespace OT { @@ -121,7 +122,7 @@ struct CompositeGlyphRecord if (flags & ARG_1_AND_2_ARE_WORDS) { // no overflow, copy and update value with deltas - memcpy (out, this, len); + hb_memcpy (out, this, len); const HBINT16 *px = reinterpret_cast<const HBINT16 *> (p); HBINT16 *o = reinterpret_cast<HBINT16 *> (out + len_before_val); @@ -135,7 +136,7 @@ struct CompositeGlyphRecord if (new_x <= 127 && new_x >= -128 && new_y <= 127 && new_y >= -128) { - memcpy (out, this, len); + hb_memcpy (out, this, len); HBINT8 *o = reinterpret_cast<HBINT8 *> (out + len_before_val); o[0] = new_x; o[1] = new_y; @@ -143,7 +144,7 @@ struct CompositeGlyphRecord else { // int8 overflows after deltas applied - memcpy (out, this, len_before_val); + hb_memcpy (out, this, len_before_val); //update flags CompositeGlyphRecord *o = reinterpret_cast<CompositeGlyphRecord *> (out); @@ -152,14 +153,14 @@ struct CompositeGlyphRecord HBINT16 new_value; new_value = new_x; - memcpy (out, &new_value, HBINT16::static_size); + hb_memcpy (out, &new_value, HBINT16::static_size); out += HBINT16::static_size; new_value = new_y; - memcpy (out, &new_value, HBINT16::static_size); + hb_memcpy (out, &new_value, HBINT16::static_size); out += HBINT16::static_size; - memcpy (out, p+2, len - len_before_val - 2); + hb_memcpy (out, p+2, len - len_before_val - 2); len += 2; } } @@ -252,55 +253,7 @@ struct CompositeGlyphRecord DEFINE_SIZE_MIN (4); }; -struct composite_iter_t : hb_iter_with_fallback_t<composite_iter_t, const CompositeGlyphRecord &> -{ - typedef const CompositeGlyphRecord *__item_t__; - composite_iter_t (hb_bytes_t glyph_, __item_t__ current_) : - glyph (glyph_), current (nullptr), current_size (0) - { - set_current (current_); - } - - composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr), current_size (0) {} - - item_t __item__ () const { return *current; } - bool __more__ () const { return current; } - void __next__ () - { - if (!current->has_more ()) { current = nullptr; return; } - - set_current (&StructAtOffset<CompositeGlyphRecord> (current, current_size)); - } - composite_iter_t __end__ () const { return composite_iter_t (); } - bool operator != (const composite_iter_t& o) const - { return current != o.current; } - - - void set_current (__item_t__ current_) - { - if (!glyph.check_range (current_, CompositeGlyphRecord::min_size)) - { - current = nullptr; - current_size = 0; - return; - } - unsigned size = current_->get_size (); - if (!glyph.check_range (current_, size)) - { - current = nullptr; - current_size = 0; - return; - } - - current = current_; - current_size = size; - } - - private: - hb_bytes_t glyph; - __item_t__ current; - unsigned current_size; -}; +using composite_iter_t = composite_iter_tmpl<CompositeGlyphRecord>; struct CompositeGlyph { @@ -382,7 +335,7 @@ struct CompositeGlyph unsigned comp_len = component.get_size (); if (component.is_anchored ()) { - memcpy (p, &component, comp_len); + hb_memcpy (p, &component, comp_len); p += comp_len; } else @@ -398,7 +351,7 @@ struct CompositeGlyph if (source_len > source_comp_len) { unsigned instr_len = source_len - source_comp_len; - memcpy (p, (const char *)c + source_comp_len, instr_len); + hb_memcpy (p, (const char *)c + source_comp_len, instr_len); p += instr_len; } diff --git a/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh index 0b25659acc..b7215b0170 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh @@ -7,6 +7,8 @@ #include "GlyphHeader.hh" #include "SimpleGlyph.hh" #include "CompositeGlyph.hh" +#include "VarCompositeGlyph.hh" +#include "coord-setter.hh" namespace OT { @@ -16,6 +18,11 @@ struct glyf_accelerator_t; namespace glyf_impl { +#ifndef HB_GLYF_MAX_POINTS +#define HB_GLYF_MAX_POINTS 10000 +#endif + + enum phantom_point_index_t { PHANTOM_LEFT = 0, @@ -27,7 +34,7 @@ enum phantom_point_index_t struct Glyph { - enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE }; + enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE, VAR_COMPOSITE }; public: composite_iter_t get_composite_iterator () const @@ -35,6 +42,11 @@ struct Glyph if (type != COMPOSITE) return composite_iter_t (); return CompositeGlyph (*header, bytes).iter (); } + var_composite_iter_t get_var_composite_iterator () const + { + if (type != VAR_COMPOSITE) return var_composite_iter_t (); + return VarCompositeGlyph (*header, bytes).iter (); + } const hb_bytes_t trim_padding () const { @@ -108,25 +120,25 @@ struct Glyph if (unlikely (!glyph_header)) return false; } - int xMin = 0, xMax = 0; - int yMin = 0, yMax = 0; + float xMin = 0, xMax = 0; + float yMin = 0, yMax = 0; if (all_points.length > 4) { - xMin = xMax = roundf (all_points[0].x); - yMin = yMax = roundf (all_points[0].y); + xMin = xMax = all_points[0].x; + yMin = yMax = all_points[0].y; } for (unsigned i = 1; i < all_points.length - 4; i++) { - float rounded_x = roundf (all_points[i].x); - float rounded_y = roundf (all_points[i].y); - xMin = hb_min (xMin, rounded_x); - xMax = hb_max (xMax, rounded_x); - yMin = hb_min (yMin, rounded_y); - yMax = hb_max (yMax, rounded_y); + float x = all_points[i].x; + float y = all_points[i].y; + xMin = hb_min (xMin, x); + xMax = hb_max (xMax, x); + yMin = hb_min (yMin, y); + yMax = hb_max (yMax, y); } - update_mtx (plan, xMin, yMax, all_points); + update_mtx (plan, roundf (xMin), roundf (yMax), all_points); /*for empty glyphs: all_points only include phantom points. *just update metrics and then return */ @@ -134,10 +146,10 @@ struct Glyph return true; glyph_header->numberOfContours = header->numberOfContours; - glyph_header->xMin = xMin; - glyph_header->yMin = yMin; - glyph_header->xMax = xMax; - glyph_header->yMax = yMax; + glyph_header->xMin = roundf (xMin); + glyph_header->yMin = roundf (yMin); + glyph_header->xMax = roundf (xMax); + glyph_header->yMax = roundf (yMax); dest_bytes = hb_bytes_t ((const char *)glyph_header, GlyphHeader::static_size); return true; @@ -199,15 +211,24 @@ struct Glyph bool shift_points_hori = true, bool use_my_metrics = true, bool phantom_only = false, + hb_array_t<int> coords = hb_array_t<int> (), unsigned int depth = 0) const { if (unlikely (depth > HB_MAX_NESTING_LEVEL)) return false; + + if (!coords) + coords = hb_array (font->coords, font->num_coords); + contour_point_vector_t stack_points; bool inplace = type == SIMPLE && all_points.length == 0; /* Load into all_points if it's empty, as an optimization. */ contour_point_vector_t &points = inplace ? all_points : stack_points; switch (type) { + case SIMPLE: + if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only))) + return false; + break; case COMPOSITE: { /* pseudo component points for each component in composite glyph */ @@ -215,20 +236,25 @@ struct Glyph if (unlikely (!points.resize (num_points))) return false; break; } - case SIMPLE: - if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only))) - return false; +#ifndef HB_NO_VAR_COMPOSITES + case VAR_COMPOSITE: + { + for (auto &item : get_var_composite_iterator ()) + if (unlikely (!item.get_points (points))) return false; + } +#endif + default: break; } /* Init phantom points */ if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false; - hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); + hb_array_t<contour_point_t> phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); { int lsb = 0; int h_delta = glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ? (int) header->xMin - lsb : 0; - int tsb = 0; + HB_UNUSED int tsb = 0; int v_orig = (int) header->yMax + #ifndef HB_NO_VERTICAL ((void) glyf_accelerator.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb) @@ -257,7 +283,9 @@ struct Glyph } #ifndef HB_NO_VAR - glyf_accelerator.gvar->apply_deltas_to_points (gid, font, points.as_array ()); + glyf_accelerator.gvar->apply_deltas_to_points (gid, + coords, + points.as_array ()); #endif // mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it @@ -283,11 +311,24 @@ struct Glyph for (auto &item : get_composite_iterator ()) { comp_points.reset (); + if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ()) - .get_points (font, glyf_accelerator, comp_points, - deltas, shift_points_hori, use_my_metrics, phantom_only, depth + 1))) + .get_points (font, + glyf_accelerator, + comp_points, + deltas, + shift_points_hori, + use_my_metrics, + phantom_only, + coords, + depth + 1))) return false; + /* Copy phantom points from component if USE_MY_METRICS flag set */ + if (use_my_metrics && item.is_use_my_metrics ()) + for (unsigned int i = 0; i < PHANTOM_COUNT; i++) + phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i]; + /* Apply component transformation & translation */ item.transform_points (comp_points); @@ -308,20 +349,63 @@ struct Glyph } } + all_points.extend (comp_points.as_array ().sub_array (0, comp_points.length - PHANTOM_COUNT)); + + if (all_points.length > HB_GLYF_MAX_POINTS) + return false; + + comp_index++; + } + + all_points.extend (phantoms); + } break; +#ifndef HB_NO_VAR_COMPOSITES + case VAR_COMPOSITE: + { + contour_point_vector_t comp_points; + hb_array_t<contour_point_t> points_left = points.as_array (); + for (auto &item : get_var_composite_iterator ()) + { + hb_array_t<contour_point_t> record_points = points_left.sub_array (0, item.get_num_points ()); + + comp_points.reset (); + + coord_setter_t coord_setter (coords); + item.set_variations (coord_setter, record_points); + + if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ()) + .get_points (font, + glyf_accelerator, + comp_points, + deltas, + shift_points_hori, + use_my_metrics, + phantom_only, + coord_setter.get_coords (), + depth + 1))) + return false; + + /* Apply component transformation */ + item.transform_points (record_points, comp_points); + /* Copy phantom points from component if USE_MY_METRICS flag set */ if (use_my_metrics && item.is_use_my_metrics ()) for (unsigned int i = 0; i < PHANTOM_COUNT; i++) phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i]; - all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT)); + all_points.extend (comp_points.as_array ().sub_array (0, comp_points.length - PHANTOM_COUNT)); - comp_index++; - } + if (all_points.length > HB_GLYF_MAX_POINTS) + return false; + points_left += item.get_num_points (); + } all_points.extend (phantoms); } break; +#endif default: all_points.extend (phantoms); + break; } if (depth == 0 && shift_points_hori) /* Apply at top level */ @@ -360,6 +444,7 @@ struct Glyph int num_contours = header->numberOfContours; if (unlikely (num_contours == 0)) type = EMPTY; else if (num_contours > 0) type = SIMPLE; + else if (num_contours == -2) type = VAR_COMPOSITE; else type = COMPOSITE; /* negative numbers */ } diff --git a/thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh index d45f4eb350..2b4aa99d25 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh @@ -132,8 +132,8 @@ struct SimpleGlyph if (unlikely (p + 1 > end)) return false; unsigned int repeat_count = *p++; unsigned stop = hb_min (i + repeat_count, count); - for (; i < stop;) - points_.arrayZ[i++].flag = flag; + for (; i < stop; i++) + points_.arrayZ[i].flag = flag; } } return true; @@ -223,33 +223,34 @@ struct SimpleGlyph if (value > 0) flag |= same_flag; else value = -value; - coords.push ((uint8_t)value); + coords.arrayZ[coords.length++] = (uint8_t) value; } else { int16_t val = value; - coords.push (val >> 8); - coords.push (val & 0xff); + coords.arrayZ[coords.length++] = val >> 8; + coords.arrayZ[coords.length++] = val & 0xff; } } static void encode_flag (uint8_t &flag, uint8_t &repeat, - uint8_t &lastflag, + uint8_t lastflag, hb_vector_t<uint8_t> &flags /* OUT */) { if (flag == lastflag && repeat != 255) { - repeat = repeat + 1; + repeat++; if (repeat == 1) { - flags.push(flag); + /* We know there's room. */ + flags.arrayZ[flags.length++] = flag; } else { unsigned len = flags.length; - flags[len-2] = flag | FLAG_REPEAT; - flags[len-1] = repeat; + flags.arrayZ[len-2] = flag | FLAG_REPEAT; + flags.arrayZ[len-1] = repeat; } } else @@ -257,7 +258,6 @@ struct SimpleGlyph repeat = 0; flags.push (flag); } - lastflag = flag; } bool compile_bytes_with_deltas (const contour_point_vector_t &all_points, @@ -269,7 +269,6 @@ struct SimpleGlyph dest_bytes = hb_bytes_t (); return true; } - //convert absolute values to relative values unsigned num_points = all_points.length - 4; hb_vector_t<uint8_t> flags, x_coords, y_coords; @@ -277,23 +276,23 @@ struct SimpleGlyph if (unlikely (!x_coords.alloc (2*num_points))) return false; if (unlikely (!y_coords.alloc (2*num_points))) return false; - uint8_t lastflag = 0, repeat = 0; - int prev_x = 0.f, prev_y = 0.f; - + uint8_t lastflag = 255, repeat = 0; + int prev_x = 0, prev_y = 0; + for (unsigned i = 0; i < num_points; i++) { - uint8_t flag = all_points[i].flag; + uint8_t flag = all_points.arrayZ[i].flag; flag &= FLAG_ON_CURVE + FLAG_OVERLAP_SIMPLE; - float cur_x = roundf (all_points[i].x); - float cur_y = roundf (all_points[i].y); + int cur_x = roundf (all_points.arrayZ[i].x); + int cur_y = roundf (all_points.arrayZ[i].y); encode_coord (cur_x - prev_x, flag, FLAG_X_SHORT, FLAG_X_SAME, x_coords); encode_coord (cur_y - prev_y, flag, FLAG_Y_SHORT, FLAG_Y_SAME, y_coords); - if (i == 0) lastflag = flag + 1; //make lastflag != flag for the first point encode_flag (flag, repeat, lastflag, flags); prev_x = cur_x; prev_y = cur_y; + lastflag = flag; } unsigned len_before_instrs = 2 * header.numberOfContours + 2; @@ -303,29 +302,29 @@ struct SimpleGlyph if (!no_hinting) total_len += len_instrs; - char *p = (char *) hb_calloc (total_len, sizeof (char)); + char *p = (char *) hb_malloc (total_len); if (unlikely (!p)) return false; const char *src = bytes.arrayZ + GlyphHeader::static_size; char *cur = p; - memcpy (p, src, len_before_instrs); + hb_memcpy (p, src, len_before_instrs); cur += len_before_instrs; src += len_before_instrs; if (!no_hinting) { - memcpy (cur, src, len_instrs); + hb_memcpy (cur, src, len_instrs); cur += len_instrs; } - memcpy (cur, flags.arrayZ, flags.length); + hb_memcpy (cur, flags.arrayZ, flags.length); cur += flags.length; - memcpy (cur, x_coords.arrayZ, x_coords.length); + hb_memcpy (cur, x_coords.arrayZ, x_coords.length); cur += x_coords.length; - memcpy (cur, y_coords.arrayZ, y_coords.length); + hb_memcpy (cur, y_coords.arrayZ, y_coords.length); dest_bytes = hb_bytes_t (p, total_len); return true; diff --git a/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh index 88fc93c435..1a0370c757 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh @@ -21,10 +21,18 @@ struct SubsetGlyph bool serialize (hb_serialize_context_t *c, bool use_short_loca, - const hb_subset_plan_t *plan) const + const hb_subset_plan_t *plan, + hb_font_t *font) { TRACE_SERIALIZE (this); + if (font) + { + const OT::glyf_accelerator_t &glyf = *font->face->table.glyf; + if (!this->compile_bytes_with_deltas (plan, font, glyf)) + return_trace (false); + } + hb_bytes_t dest_glyph = dest_start.copy (c); dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length); unsigned int pad_length = use_short_loca ? padding () : 0; diff --git a/thirdparty/harfbuzz/src/OT/glyf/VarCompositeGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/VarCompositeGlyph.hh new file mode 100644 index 0000000000..0f4c71c83d --- /dev/null +++ b/thirdparty/harfbuzz/src/OT/glyf/VarCompositeGlyph.hh @@ -0,0 +1,353 @@ +#ifndef OT_GLYF_VARCOMPOSITEGLYPH_HH +#define OT_GLYF_VARCOMPOSITEGLYPH_HH + + +#include "../../hb-open-type.hh" +#include "coord-setter.hh" + + +namespace OT { +namespace glyf_impl { + + +struct VarCompositeGlyphRecord +{ + protected: + enum var_composite_glyph_flag_t + { + USE_MY_METRICS = 0x0001, + AXIS_INDICES_ARE_SHORT = 0x0002, + UNIFORM_SCALE = 0x0004, + HAVE_TRANSLATE_X = 0x0008, + HAVE_TRANSLATE_Y = 0x0010, + HAVE_ROTATION = 0x0020, + HAVE_SCALE_X = 0x0040, + HAVE_SCALE_Y = 0x0080, + HAVE_SKEW_X = 0x0100, + HAVE_SKEW_Y = 0x0200, + HAVE_TCENTER_X = 0x0400, + HAVE_TCENTER_Y = 0x0800, + GID_IS_24 = 0x1000, + AXES_HAVE_VARIATION = 0x2000, + }; + + public: + + unsigned int get_size () const + { + unsigned int size = min_size; + + unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 4 : 3; + size += numAxes * axis_width; + + // gid + size += 2; + if (flags & GID_IS_24) size += 1; + + if (flags & HAVE_TRANSLATE_X) size += 2; + if (flags & HAVE_TRANSLATE_Y) size += 2; + if (flags & HAVE_ROTATION) size += 2; + if (flags & HAVE_SCALE_X) size += 2; + if (flags & HAVE_SCALE_Y) size += 2; + if (flags & HAVE_SKEW_X) size += 2; + if (flags & HAVE_SKEW_Y) size += 2; + if (flags & HAVE_TCENTER_X) size += 2; + if (flags & HAVE_TCENTER_Y) size += 2; + + return size; + } + + bool has_more () const { return true; } + + bool is_use_my_metrics () const { return flags & USE_MY_METRICS; } + + hb_codepoint_t get_gid () const + { + if (flags & GID_IS_24) + return StructAfter<const HBGlyphID24> (numAxes); + else + return StructAfter<const HBGlyphID16> (numAxes); + } + + unsigned get_numAxes () const + { + return numAxes; + } + + unsigned get_num_points () const + { + unsigned num = 0; + if (flags & AXES_HAVE_VARIATION) num += numAxes; + if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y)) num++; + if (flags & HAVE_ROTATION) num++; + if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y)) num++; + if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y)) num++; + if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y)) num++; + return num; + } + + void transform_points (hb_array_t<contour_point_t> record_points, + contour_point_vector_t &points) const + { + float matrix[4]; + contour_point_t trans; + + get_transformation_from_points (record_points, matrix, trans); + + points.transform (matrix); + points.translate (trans); + } + + static inline void transform (float (&matrix)[4], contour_point_t &trans, + float (other)[6]) + { + // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L268 + float xx1 = other[0]; + float xy1 = other[1]; + float yx1 = other[2]; + float yy1 = other[3]; + float dx1 = other[4]; + float dy1 = other[5]; + float xx2 = matrix[0]; + float xy2 = matrix[1]; + float yx2 = matrix[2]; + float yy2 = matrix[3]; + float dx2 = trans.x; + float dy2 = trans.y; + + matrix[0] = xx1*xx2 + xy1*yx2; + matrix[1] = xx1*xy2 + xy1*yy2; + matrix[2] = yx1*xx2 + yy1*yx2; + matrix[3] = yx1*xy2 + yy1*yy2; + trans.x = xx2*dx1 + yx2*dy1 + dx2; + trans.y = xy2*dx1 + yy2*dy1 + dy2; + } + + static void translate (float (&matrix)[4], contour_point_t &trans, + float translateX, float translateY) + { + // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L213 + float other[6] = {1.f, 0.f, 0.f, 1.f, translateX, translateY}; + transform (matrix, trans, other); + } + + static void scale (float (&matrix)[4], contour_point_t &trans, + float scaleX, float scaleY) + { + // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L224 + float other[6] = {scaleX, 0.f, 0.f, scaleY, 0.f, 0.f}; + transform (matrix, trans, other); + } + + static void rotate (float (&matrix)[4], contour_point_t &trans, + float rotation) + { + // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240 + rotation = rotation * float (M_PI); + float c = cosf (rotation); + float s = sinf (rotation); + float other[6] = {c, s, -s, c, 0.f, 0.f}; + transform (matrix, trans, other); + } + + static void skew (float (&matrix)[4], contour_point_t &trans, + float skewX, float skewY) + { + // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255 + skewX = skewX * float (M_PI); + skewY = skewY * float (M_PI); + float other[6] = {1.f, tanf (skewY), tanf (skewX), 1.f, 0.f, 0.f}; + transform (matrix, trans, other); + } + + bool get_points (contour_point_vector_t &points) const + { + float translateX = 0.f; + float translateY = 0.f; + float rotation = 0.f; + float scaleX = 1.f * (1 << 12); + float scaleY = 1.f * (1 << 12); + float skewX = 0.f; + float skewY = 0.f; + float tCenterX = 0.f; + float tCenterY = 0.f; + + if (unlikely (!points.resize (points.length + get_num_points ()))) return false; + + unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1; + unsigned axes_size = numAxes * axis_width; + + const F2DOT14 *q = (const F2DOT14 *) (axes_size + + (flags & GID_IS_24 ? 3 : 2) + + &StructAfter<const HBUINT8> (numAxes)); + + hb_array_t<contour_point_t> rec_points = points.as_array ().sub_array (points.length - get_num_points ()); + + unsigned count = numAxes; + if (flags & AXES_HAVE_VARIATION) + { + for (unsigned i = 0; i < count; i++) + rec_points[i].x = *q++; + rec_points += count; + } + else + q += count; + + const HBUINT16 *p = (const HBUINT16 *) q; + + if (flags & HAVE_TRANSLATE_X) translateX = * (const FWORD *) p++; + if (flags & HAVE_TRANSLATE_Y) translateY = * (const FWORD *) p++; + if (flags & HAVE_ROTATION) rotation = * (const F2DOT14 *) p++; + if (flags & HAVE_SCALE_X) scaleX = * (const F4DOT12 *) p++; + if (flags & HAVE_SCALE_Y) scaleY = * (const F4DOT12 *) p++; + if (flags & HAVE_SKEW_X) skewX = * (const F2DOT14 *) p++; + if (flags & HAVE_SKEW_Y) skewY = * (const F2DOT14 *) p++; + if (flags & HAVE_TCENTER_X) tCenterX = * (const FWORD *) p++; + if (flags & HAVE_TCENTER_Y) tCenterY = * (const FWORD *) p++; + + if ((flags & UNIFORM_SCALE) && !(flags & HAVE_SCALE_Y)) + scaleY = scaleX; + + if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y)) + { + rec_points[0].x = translateX; + rec_points[0].y = translateY; + rec_points++; + } + if (flags & HAVE_ROTATION) + { + rec_points[0].x = rotation; + rec_points++; + } + if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y)) + { + rec_points[0].x = scaleX; + rec_points[0].y = scaleY; + rec_points++; + } + if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y)) + { + rec_points[0].x = skewX; + rec_points[0].y = skewY; + rec_points++; + } + if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y)) + { + rec_points[0].x = tCenterX; + rec_points[0].y = tCenterY; + rec_points++; + } + assert (!rec_points); + + return true; + } + + void get_transformation_from_points (hb_array_t<contour_point_t> rec_points, + float (&matrix)[4], contour_point_t &trans) const + { + if (flags & AXES_HAVE_VARIATION) + rec_points += numAxes; + + matrix[0] = matrix[3] = 1.f; + matrix[1] = matrix[2] = 0.f; + trans.init (0.f, 0.f); + + float translateX = 0.f; + float translateY = 0.f; + float rotation = 0.f; + float scaleX = 1.f; + float scaleY = 1.f; + float skewX = 0.f; + float skewY = 0.f; + float tCenterX = 0.f; + float tCenterY = 0.f; + + if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y)) + { + translateX = rec_points[0].x; + translateY = rec_points[0].y; + rec_points++; + } + if (flags & HAVE_ROTATION) + { + rotation = rec_points[0].x / (1 << 14); + rec_points++; + } + if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y)) + { + scaleX = rec_points[0].x / (1 << 12); + scaleY = rec_points[0].y / (1 << 12); + rec_points++; + } + if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y)) + { + skewX = rec_points[0].x / (1 << 14); + skewY = rec_points[0].y / (1 << 14); + rec_points++; + } + if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y)) + { + tCenterX = rec_points[0].x; + tCenterY = rec_points[0].y; + rec_points++; + } + assert (!rec_points); + + translate (matrix, trans, translateX + tCenterX, translateY + tCenterY); + rotate (matrix, trans, rotation); + scale (matrix, trans, scaleX, scaleY); + skew (matrix, trans, -skewX, skewY); + translate (matrix, trans, -tCenterX, -tCenterY); + } + + void set_variations (coord_setter_t &setter, + hb_array_t<contour_point_t> rec_points) const + { + bool have_variations = flags & AXES_HAVE_VARIATION; + unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1; + + const HBUINT8 *p = (const HBUINT8 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24 ? 3 : 2)); + const HBUINT16 *q = (const HBUINT16 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24 ? 3 : 2)); + + const F2DOT14 *a = (const F2DOT14 *) ((HBUINT8 *) (axis_width == 1 ? (p + numAxes) : (HBUINT8 *) (q + numAxes))); + + unsigned count = numAxes; + for (unsigned i = 0; i < count; i++) + { + unsigned axis_index = axis_width == 1 ? (unsigned) *p++ : (unsigned) *q++; + + signed v = have_variations ? rec_points[i].x : *a++; + + v += setter[axis_index]; + v = hb_clamp (v, -(1<<14), (1<<14)); + setter[axis_index] = v; + } + } + + protected: + HBUINT16 flags; + HBUINT8 numAxes; + public: + DEFINE_SIZE_MIN (3); +}; + +using var_composite_iter_t = composite_iter_tmpl<VarCompositeGlyphRecord>; + +struct VarCompositeGlyph +{ + const GlyphHeader &header; + hb_bytes_t bytes; + VarCompositeGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) : + header (header_), bytes (bytes_) {} + + var_composite_iter_t iter () const + { return var_composite_iter_t (bytes, &StructAfter<VarCompositeGlyphRecord, GlyphHeader> (header)); } + +}; + + +} /* namespace glyf_impl */ +} /* namespace OT */ + + +#endif /* OT_GLYF_VARCOMPOSITEGLYPH_HH */ diff --git a/thirdparty/harfbuzz/src/OT/glyf/composite-iter.hh b/thirdparty/harfbuzz/src/OT/glyf/composite-iter.hh new file mode 100644 index 0000000000..d05701f3d1 --- /dev/null +++ b/thirdparty/harfbuzz/src/OT/glyf/composite-iter.hh @@ -0,0 +1,68 @@ +#ifndef OT_GLYF_COMPOSITE_ITER_HH +#define OT_GLYF_COMPOSITE_ITER_HH + + +#include "../../hb.hh" + + +namespace OT { +namespace glyf_impl { + + +template <typename CompositeGlyphRecord> +struct composite_iter_tmpl : hb_iter_with_fallback_t<composite_iter_tmpl<CompositeGlyphRecord>, + const CompositeGlyphRecord &> +{ + typedef const CompositeGlyphRecord *__item_t__; + composite_iter_tmpl (hb_bytes_t glyph_, __item_t__ current_) : + glyph (glyph_), current (nullptr), current_size (0) + { + set_current (current_); + } + + composite_iter_tmpl () : glyph (hb_bytes_t ()), current (nullptr), current_size (0) {} + + const CompositeGlyphRecord & __item__ () const { return *current; } + bool __more__ () const { return current; } + void __next__ () + { + if (!current->has_more ()) { current = nullptr; return; } + + set_current (&StructAtOffset<CompositeGlyphRecord> (current, current_size)); + } + composite_iter_tmpl __end__ () const { return composite_iter_tmpl (); } + bool operator != (const composite_iter_tmpl& o) const + { return current != o.current; } + + + void set_current (__item_t__ current_) + { + if (!glyph.check_range (current_, CompositeGlyphRecord::min_size)) + { + current = nullptr; + current_size = 0; + return; + } + unsigned size = current_->get_size (); + if (!glyph.check_range (current_, size)) + { + current = nullptr; + current_size = 0; + return; + } + + current = current_; + current_size = size; + } + + private: + hb_bytes_t glyph; + __item_t__ current; + unsigned current_size; +}; + + +} /* namespace glyf_impl */ +} /* namespace OT */ + +#endif /* OT_GLYF_COMPOSITE_ITER_HH */ diff --git a/thirdparty/harfbuzz/src/OT/glyf/coord-setter.hh b/thirdparty/harfbuzz/src/OT/glyf/coord-setter.hh new file mode 100644 index 0000000000..df64ed5af7 --- /dev/null +++ b/thirdparty/harfbuzz/src/OT/glyf/coord-setter.hh @@ -0,0 +1,34 @@ +#ifndef OT_GLYF_COORD_SETTER_HH +#define OT_GLYF_COORD_SETTER_HH + + +#include "../../hb.hh" + + +namespace OT { +namespace glyf_impl { + + +struct coord_setter_t +{ + coord_setter_t (hb_array_t<int> coords) : + coords (coords) {} + + int& operator [] (unsigned idx) + { + if (coords.length < idx + 1) + coords.resize (idx + 1); + return coords[idx]; + } + + hb_array_t<int> get_coords () + { return coords.as_array (); } + + hb_vector_t<int> coords; +}; + + +} /* namespace glyf_impl */ +} /* namespace OT */ + +#endif /* OT_GLYF_COORD_SETTER_HH */ diff --git a/thirdparty/harfbuzz/src/OT/glyf/glyf.hh b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh index 5fb32f67f3..e6e985c38c 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/glyf.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh @@ -42,11 +42,15 @@ struct glyf bool serialize (hb_serialize_context_t *c, Iterator it, bool use_short_loca, - const hb_subset_plan_t *plan) + const hb_subset_plan_t *plan, + hb_font_t *font) { TRACE_SERIALIZE (this); + unsigned init_len = c->length (); - for (const auto &_ : it) _.serialize (c, use_short_loca, plan); + for (auto &_ : it) + if (unlikely (!_.serialize (c, use_short_loca, plan, font))) + return false; /* As a special case when all glyph in the font are empty, add a zero byte * to the table, so that OTS doesn’t reject it, and to make the table work @@ -74,10 +78,11 @@ struct glyf hb_vector_t<glyf_impl::SubsetGlyph> glyphs; _populate_subset_glyphs (c->plan, glyphs); + hb_font_t *font = nullptr; if (!c->plan->pinned_at_default) { - if (!_compile_subset_glyphs_with_deltas (c->plan, &glyphs)) - return_trace (false); + font = _create_font_for_instancing (c->plan); + if (unlikely (!font)) return false; } auto padded_offsets = @@ -85,11 +90,14 @@ struct glyf | hb_map (&glyf_impl::SubsetGlyph::padded_size) ; - unsigned max_offset = + padded_offsets | hb_reduce (hb_add, 0); - bool use_short_loca = max_offset < 0x1FFFF; - + bool use_short_loca = false; + if (likely (!c->plan->force_long_loca)) + { + unsigned max_offset = + padded_offsets | hb_reduce (hb_add, 0); + use_short_loca = max_offset < 0x1FFFF; + } - glyf_prime->serialize (c->serializer, hb_iter (glyphs), use_short_loca, c->plan); + glyf_prime->serialize (c->serializer, glyphs.writer (), use_short_loca, c->plan, font); if (!use_short_loca) { padded_offsets = + hb_iter (glyphs) @@ -97,9 +105,12 @@ struct glyf ; } - - if (!c->plan->pinned_at_default) + if (font) + { _free_compiled_subset_glyphs (&glyphs); + hb_font_destroy (font); + } + if (unlikely (c->serializer->in_error ())) return_trace (false); return_trace (c->serializer->check_success (glyf_impl::_add_loca_and_head (c->plan, padded_offsets, @@ -110,9 +121,8 @@ struct glyf _populate_subset_glyphs (const hb_subset_plan_t *plan, hb_vector_t<glyf_impl::SubsetGlyph> &glyphs /* OUT */) const; - bool - _compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan, - hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const; + hb_font_t * + _create_font_for_instancing (const hb_subset_plan_t *plan) const; void _free_compiled_subset_glyphs (hb_vector_t<glyf_impl::SubsetGlyph> *glyphs) const { @@ -394,7 +404,11 @@ glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan, plan->pinned_at_default) subset_glyph.source_glyph = glyf_impl::Glyph (); else - subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true); + { + /* If plan has an accelerator, the preprocessing step already trimmed glyphs. + * Don't trim them again! */ + subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, !plan->accelerator); + } if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) subset_glyph.drop_hints_bytes (); @@ -403,17 +417,15 @@ glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan, } } -inline bool -glyf::_compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan, - hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const +inline hb_font_t * +glyf::_create_font_for_instancing (const hb_subset_plan_t *plan) const { - OT::glyf_accelerator_t glyf (plan->source); hb_font_t *font = hb_font_create (plan->source); - if (unlikely (!font)) return false; + if (unlikely (font == hb_font_get_empty ())) return nullptr; hb_vector_t<hb_variation_t> vars; if (unlikely (!vars.alloc (plan->user_axes_location->get_population ()))) - return false; + return nullptr; for (auto _ : *plan->user_axes_location) { @@ -423,18 +435,10 @@ glyf::_compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan, vars.push (var); } +#ifndef HB_NO_VAR hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location->get_population ()); - for (auto& subset_glyph : *glyphs) - { - if (!const_cast<glyf_impl::SubsetGlyph &> (subset_glyph).compile_bytes_with_deltas (plan, font, glyf)) - { - hb_font_destroy (font); - return false; - } - } - - hb_font_destroy (font); - return true; +#endif + return font; } diff --git a/thirdparty/harfbuzz/src/graph/classdef-graph.hh b/thirdparty/harfbuzz/src/graph/classdef-graph.hh index 0bda76ac2f..c2e24a7067 100644 --- a/thirdparty/harfbuzz/src/graph/classdef-graph.hh +++ b/thirdparty/harfbuzz/src/graph/classdef-graph.hh @@ -112,7 +112,7 @@ struct ClassDef : public OT::ClassDef { case 1: return ((ClassDefFormat1*)this)->sanitize (vertex); case 2: return ((ClassDefFormat2*)this)->sanitize (vertex); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K // Not currently supported case 3: case 4: diff --git a/thirdparty/harfbuzz/src/graph/coverage-graph.hh b/thirdparty/harfbuzz/src/graph/coverage-graph.hh index 3c1022f090..49d0936315 100644 --- a/thirdparty/harfbuzz/src/graph/coverage-graph.hh +++ b/thirdparty/harfbuzz/src/graph/coverage-graph.hh @@ -136,7 +136,7 @@ struct Coverage : public OT::Layout::Common::Coverage { case 1: return ((CoverageFormat1*)this)->sanitize (vertex); case 2: return ((CoverageFormat2*)this)->sanitize (vertex); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K // Not currently supported case 3: case 4: diff --git a/thirdparty/harfbuzz/src/graph/graph.hh b/thirdparty/harfbuzz/src/graph/graph.hh index 79c7e690a1..dc5b6a36fe 100644 --- a/thirdparty/harfbuzz/src/graph/graph.hh +++ b/thirdparty/harfbuzz/src/graph/graph.hh @@ -49,6 +49,50 @@ struct graph_t unsigned end = 0; unsigned priority = 0; + + bool link_positions_valid (unsigned num_objects, bool removed_nil) + { + hb_set_t assigned_bytes; + for (const auto& l : obj.real_links) + { + if (l.objidx >= num_objects + || (removed_nil && !l.objidx)) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + "Invalid graph. Invalid object index."); + return false; + } + + unsigned start = l.position; + unsigned end = start + l.width - 1; + + if (unlikely (l.width < 2 || l.width > 4)) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + "Invalid graph. Invalid link width."); + return false; + } + + if (unlikely (end >= table_size ())) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + "Invalid graph. Link position is out of bounds."); + return false; + } + + if (unlikely (assigned_bytes.intersects (start, end))) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + "Invalid graph. Found offsets whose positions overlap."); + return false; + } + + assigned_bytes.add_range (start, end); + } + + return !assigned_bytes.in_error (); + } + void normalize () { obj.real_links.qsort (); @@ -132,7 +176,7 @@ struct graph_t for (unsigned i = 0; i < parents.length; i++) { if (parents[i] != parent_index) continue; - parents.remove (i); + parents.remove_unordered (i); break; } } @@ -148,7 +192,7 @@ struct graph_t if ((obj.head + link.position) != offset) continue; - obj.real_links.remove (i); + obj.real_links.remove_unordered (i); return; } } @@ -286,8 +330,6 @@ struct graph_t vertices_scratch_.alloc (objects.length); for (unsigned i = 0; i < objects.length; i++) { - // TODO(grieger): check all links point to valid objects. - // If this graph came from a serialization buffer object 0 is the // nil object. We don't need it for our purposes here so drop it. if (i == 0 && !objects[i]) @@ -299,6 +341,9 @@ struct graph_t vertex_t* v = vertices_.push (); if (check_success (!vertices_.in_error ())) v->obj = *objects[i]; + + check_success (v->link_positions_valid (objects.length, removed_nil)); + if (!removed_nil) continue; // Fix indices to account for removed nil object. for (auto& l : v->obj.all_links_writer ()) { @@ -418,6 +463,13 @@ struct graph_t hb_swap (sorted_graph[new_id], vertices_[next_id]); const vertex_t& next = sorted_graph[new_id]; + if (unlikely (!check_success(new_id >= 0))) { + // We are out of ids. Which means we've visited a node more than once. + // This graph contains a cycle which is not allowed. + DEBUG_MSG (SUBSET_REPACK, nullptr, "Invalid graph. Contains cycle."); + return; + } + id_map[next_id] = new_id--; for (const auto& link : next.obj.all_links ()) { @@ -580,7 +632,7 @@ struct graph_t while (roots) { - unsigned next = HB_SET_VALUE_INVALID; + uint32_t next = HB_SET_VALUE_INVALID; if (unlikely (!check_success (!roots.in_error ()))) break; if (!roots.next (&next)) break; @@ -661,8 +713,8 @@ struct graph_t auto new_subgraph = + subgraph.keys () - | hb_map([&] (unsigned node_idx) { - const unsigned *v; + | hb_map([&] (uint32_t node_idx) { + const uint32_t *v; if (index_map.has (node_idx, &v)) return *v; return node_idx; }) @@ -672,10 +724,10 @@ struct graph_t remap_obj_indices (index_map, parents.iter (), true); // Update roots set with new indices as needed. - unsigned next = HB_SET_VALUE_INVALID; + uint32_t next = HB_SET_VALUE_INVALID; while (roots.next (&next)) { - const unsigned *v; + const uint32_t *v; if (index_map.has (next, &v)) { roots.del (next); @@ -690,7 +742,7 @@ struct graph_t { for (const auto& link : vertices_[node_idx].obj.all_links ()) { - const unsigned *v; + const uint32_t *v; if (subgraph.has (link.objidx, &v)) { subgraph.set (link.objidx, *v + 1); @@ -941,6 +993,72 @@ struct graph_t return made_change; } + bool is_fully_connected () + { + update_parents(); + + if (root().parents) + // Root cannot have parents. + return false; + + for (unsigned i = 0; i < root_idx (); i++) + { + if (!vertices_[i].parents) + return false; + } + return true; + } + +#if 0 + /* + * Saves the current graph to a packed binary format which the repacker fuzzer takes + * as a seed. + */ + void save_fuzzer_seed (hb_tag_t tag) const + { + FILE* f = fopen ("./repacker_fuzzer_seed", "w"); + fwrite ((void*) &tag, sizeof (tag), 1, f); + + uint16_t num_objects = vertices_.length; + fwrite ((void*) &num_objects, sizeof (num_objects), 1, f); + + for (const auto& v : vertices_) + { + uint16_t blob_size = v.table_size (); + fwrite ((void*) &blob_size, sizeof (blob_size), 1, f); + fwrite ((const void*) v.obj.head, blob_size, 1, f); + } + + uint16_t link_count = 0; + for (const auto& v : vertices_) + link_count += v.obj.real_links.length; + + fwrite ((void*) &link_count, sizeof (link_count), 1, f); + + typedef struct + { + uint16_t parent; + uint16_t child; + uint16_t position; + uint8_t width; + } link_t; + + for (unsigned i = 0; i < vertices_.length; i++) + { + for (const auto& l : vertices_[i].obj.real_links) + { + link_t link { + (uint16_t) i, (uint16_t) l.objidx, + (uint16_t) l.position, (uint8_t) l.width + }; + fwrite ((void*) &link, sizeof (link), 1, f); + } + } + + fclose (f); + } +#endif + void print_orphaned_nodes () { if (!DEBUG_ENABLED(SUBSET_REPACK)) return; @@ -949,6 +1067,10 @@ struct graph_t parents_invalid = true; update_parents(); + if (root().parents) { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Root node has incoming edges."); + } + for (unsigned i = 0; i < root_idx (); i++) { const auto& v = vertices_[i]; @@ -1065,6 +1187,11 @@ struct graph_t } } + for (unsigned i = 0; i < vertices_.length; i++) + // parents arrays must be accurate or downstream operations like cycle detection + // and sorting won't work correctly. + check_success (!vertices_[i].parents.in_error ()); + parents_invalid = false; } @@ -1183,7 +1310,7 @@ struct graph_t { for (auto& link : vertices_[i].obj.all_links_writer ()) { - const unsigned *v; + const uint32_t *v; if (!id_map.has (link.objidx, &v)) continue; if (only_wide && !(link.width == 4 && !link.is_signed)) continue; diff --git a/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh b/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh index e8d5bef9a8..c170638409 100644 --- a/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh +++ b/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh @@ -201,7 +201,7 @@ struct Lookup : public OT::Lookup + new_subtable_count * OT::Offset16::static_size; char* buffer = (char*) hb_calloc (1, new_size); c.add_buffer (buffer); - memcpy (buffer, v.obj.head, v.table_size()); + hb_memcpy (buffer, v.obj.head, v.table_size()); v.obj.head = buffer; v.obj.tail = buffer + new_size; @@ -355,7 +355,7 @@ struct GSTAR : public OT::GSUBGPOS { switch (u.version.major) { case 1: return u.version1.get_lookup_list_offset (); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 2: return u.version2.get_lookup_list_offset (); #endif default: return 0; @@ -374,7 +374,7 @@ struct GSTAR : public OT::GSUBGPOS { switch (u.version.major) { case 1: find_lookups<SmallTypes> (graph, lookups); break; -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 2: find_lookups<MediumTypes> (graph, lookups); break; #endif } diff --git a/thirdparty/harfbuzz/src/graph/markbasepos-graph.hh b/thirdparty/harfbuzz/src/graph/markbasepos-graph.hh index e42a6042cc..84ef5f71b9 100644 --- a/thirdparty/harfbuzz/src/graph/markbasepos-graph.hh +++ b/thirdparty/harfbuzz/src/graph/markbasepos-graph.hh @@ -112,7 +112,7 @@ struct AnchorMatrix : public OT::Layout::GPOS_impl::AnchorMatrix auto& child = c.graph.vertices_[child_idx]; child.remove_parent (this_index); - o.real_links.remove (i); + o.real_links.remove_unordered (i); num_links--; i--; } @@ -372,7 +372,7 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2<S if (!mark_coverage) return false; hb_set_t marks = sc.marks_for (0, count); auto new_coverage = - + hb_zip (hb_range (), mark_coverage.table->iter ()) + + hb_enumerate (mark_coverage.table->iter ()) | hb_filter (marks, hb_first) | hb_map_retains_sorting (hb_second) ; @@ -431,7 +431,7 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2<S if (!mark_coverage) return false; hb_set_t marks = sc.marks_for (start, end); auto new_coverage = - + hb_zip (hb_range (), mark_coverage.table->iter ()) + + hb_enumerate (mark_coverage.table->iter ()) | hb_filter (marks, hb_first) | hb_map_retains_sorting (hb_second) ; @@ -477,7 +477,7 @@ struct MarkBasePos : public OT::Layout::GPOS_impl::MarkBasePos switch (u.format) { case 1: return ((MarkBasePosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 2: HB_FALLTHROUGH; // Don't split 24bit PairPos's. #endif @@ -494,7 +494,7 @@ struct MarkBasePos : public OT::Layout::GPOS_impl::MarkBasePos switch (u.format) { case 1: return ((MarkBasePosFormat1*)(&u.format1))->sanitize (vertex); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 2: HB_FALLTHROUGH; #endif default: diff --git a/thirdparty/harfbuzz/src/graph/pairpos-graph.hh b/thirdparty/harfbuzz/src/graph/pairpos-graph.hh index 8040778ea3..1c13eb24f9 100644 --- a/thirdparty/harfbuzz/src/graph/pairpos-graph.hh +++ b/thirdparty/harfbuzz/src/graph/pairpos-graph.hh @@ -434,7 +434,7 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4<SmallType char* start_addr = ((char*)&values[0]) + start * split_context.class1_record_size; unsigned num_records = end - start; - memcpy (&pair_pos_prime->values[0], + hb_memcpy (&pair_pos_prime->values[0], start_addr, num_records * split_context.class1_record_size); @@ -611,7 +611,7 @@ struct PairPos : public OT::Layout::GPOS_impl::PairPos return ((PairPosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index); case 2: return ((PairPosFormat2*)(&u.format2))->split_subtables (c, parent_index, this_index); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 3: HB_FALLTHROUGH; case 4: HB_FALLTHROUGH; // Don't split 24bit PairPos's. @@ -631,7 +631,7 @@ struct PairPos : public OT::Layout::GPOS_impl::PairPos return ((PairPosFormat1*)(&u.format1))->sanitize (vertex); case 2: return ((PairPosFormat2*)(&u.format2))->sanitize (vertex); -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K case 3: HB_FALLTHROUGH; case 4: HB_FALLTHROUGH; #endif diff --git a/thirdparty/harfbuzz/src/graph/serialize.hh b/thirdparty/harfbuzz/src/graph/serialize.hh index ecc6cc5aea..d03a61bd19 100644 --- a/thirdparty/harfbuzz/src/graph/serialize.hh +++ b/thirdparty/harfbuzz/src/graph/serialize.hh @@ -33,6 +33,23 @@ struct overflow_record_t { unsigned parent; unsigned child; + + bool operator != (const overflow_record_t o) const + { return !(*this == o); } + + inline bool operator == (const overflow_record_t& o) const + { + return parent == o.parent && + child == o.child; + } + + inline uint32_t hash () const + { + uint32_t current = 0; + current = current * 31 + hb_hash (parent); + current = current * 31 + hb_hash (child); + return current; + } }; inline @@ -94,6 +111,7 @@ will_overflow (graph_t& graph, if (overflows) overflows->resize (0); graph.update_positions (); + hb_hashmap_t<overflow_record_t*, bool> record_set; const auto& vertices = graph.vertices_; for (int parent_idx = vertices.length - 1; parent_idx >= 0; parent_idx--) { @@ -109,7 +127,10 @@ will_overflow (graph_t& graph, overflow_record_t r; r.parent = parent_idx; r.child = link.objidx; + if (record_set.has(&r)) continue; // don't keep duplicate overflows. + overflows->push (r); + record_set.set(&r, true); } } @@ -223,7 +244,7 @@ inline hb_blob_t* serialize (const graph_t& graph) return nullptr; } - memcpy (start, vertices[i].obj.head, size); + hb_memcpy (start, vertices[i].obj.head, size); // Only real links needs to be serialized. for (const auto& link : vertices[i].obj.real_links) diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh index aa4ad4cf3c..8b9190d0be 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh @@ -131,14 +131,14 @@ struct RearrangementSubtable hb_glyph_info_t *info = buffer->info; hb_glyph_info_t buf[4]; - memcpy (buf, info + start, l * sizeof (buf[0])); - memcpy (buf + 2, info + end - r, r * sizeof (buf[0])); + hb_memcpy (buf, info + start, l * sizeof (buf[0])); + hb_memcpy (buf + 2, info + end - r, r * sizeof (buf[0])); if (l != r) memmove (info + start + r, info + start + l, (end - start - l - r) * sizeof (buf[0])); - memcpy (info + start, buf + 2, r * sizeof (buf[0])); - memcpy (info + end - l, buf, l * sizeof (buf[0])); + hb_memcpy (info + start, buf + 2, r * sizeof (buf[0])); + hb_memcpy (info + end - l, buf, l * sizeof (buf[0])); if (reverse_l) { buf[0] = info[end - 1]; diff --git a/thirdparty/harfbuzz/src/hb-aat-layout.cc b/thirdparty/harfbuzz/src/hb-aat-layout.cc index d60126fe19..78427b0d5a 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout.cc +++ b/thirdparty/harfbuzz/src/hb-aat-layout.cc @@ -289,7 +289,7 @@ is_deleted_glyph (const hb_glyph_info_t *info) void hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer) { - hb_ot_layout_delete_glyphs_inplace (buffer, is_deleted_glyph); + buffer->delete_glyphs_inplace (is_deleted_glyph); } /** diff --git a/thirdparty/harfbuzz/src/hb-aat-map.hh b/thirdparty/harfbuzz/src/hb-aat-map.hh index c914f58d70..d0ee7d672c 100644 --- a/thirdparty/harfbuzz/src/hb-aat-map.hh +++ b/thirdparty/harfbuzz/src/hb-aat-map.hh @@ -38,7 +38,7 @@ struct hb_aat_map_t void init () { - memset (this, 0, sizeof (*this)); + hb_memset (this, 0, sizeof (*this)); chain_flags.init (); } void fini () { chain_flags.fini (); } diff --git a/thirdparty/harfbuzz/src/hb-algs.hh b/thirdparty/harfbuzz/src/hb-algs.hh index cc37c073da..d85a4afe10 100644 --- a/thirdparty/harfbuzz/src/hb-algs.hh +++ b/thirdparty/harfbuzz/src/hb-algs.hh @@ -236,17 +236,6 @@ struct template <typename T> constexpr auto impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ()) - template <typename T> constexpr uint32_t - impl (const hb::shared_ptr<T>& v, hb_priority<1>) const - { - return v.get () ? v.get ()->hash () : 0; - } - template <typename T> constexpr uint32_t - impl (const hb::unique_ptr<T>& v, hb_priority<1>) const - { - return v.get () ? v.get ()->hash () : 0; - } - template <typename T> constexpr auto impl (const T& v, hb_priority<0>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v))>>{} (hb_deref (v))) @@ -495,6 +484,17 @@ struct } HB_FUNCOBJ (hb_equal); +struct +{ + template <typename T> void + operator () (T& a, T& b) const + { + using std::swap; // allow ADL + swap (a, b); + } +} +HB_FUNCOBJ (hb_swap); + template <typename T1, typename T2> struct hb_pair_t @@ -507,7 +507,7 @@ struct hb_pair_t hb_enable_if (std::is_default_constructible<U1>::value && std::is_default_constructible<U2>::value)> hb_pair_t () : first (), second () {} - hb_pair_t (T1 a, T2 b) : first (a), second (b) {} + hb_pair_t (T1 a, T2 b) : first (std::forward<T1> (a)), second (std::forward<T2> (b)) {} template <typename Q1, typename Q2, hb_enable_if (hb_is_convertible (T1, Q1) && @@ -524,6 +524,25 @@ struct hb_pair_t bool operator > (const pair_t& o) const { return first > o.first || (first == o.first && second > o.second); } bool operator <= (const pair_t& o) const { return !(*this > o); } + static int cmp (const void *pa, const void *pb) + { + pair_t *a = (pair_t *) pa; + pair_t *b = (pair_t *) pb; + + if (a->first < b->first) return -1; + if (a->first > b->first) return +1; + if (a->second < b->second) return -1; + if (a->second > b->second) return +1; + return 0; + } + + friend void swap (hb_pair_t& a, hb_pair_t& b) + { + hb_swap (a.first, b.first); + hb_swap (a.second, b.second); + } + + T1 first; T2 second; }; @@ -570,17 +589,6 @@ struct } HB_FUNCOBJ (hb_clamp); -struct -{ - template <typename T> void - operator () (T& a, T& b) const - { - using std::swap; // allow ADL - swap (a, b); - } -} -HB_FUNCOBJ (hb_swap); - /* * Bithacks. */ @@ -849,19 +857,14 @@ hb_in_range (T u, T lo, T hi) return (T)(u - lo) <= (T)(hi - lo); } template <typename T> static inline bool -hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2) +hb_in_ranges (T u, T lo1, T hi1) { - return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2); + return hb_in_range (u, lo1, hi1); } -template <typename T> static inline bool -hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) +template <typename T, typename ...Ts> static inline bool +hb_in_ranges (T u, T lo1, T hi1, Ts... ds) { - return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3); -} -template <typename T> static inline bool -hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3, T lo4, T hi4) -{ - return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3) || hb_in_range (u, lo4, hi4); + return hb_in_range<T> (u, lo1, hi1) || hb_in_ranges<T> (u, ds...); } @@ -869,10 +872,18 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3, T lo4, T hi4) * Overflow checking. */ -/* Consider __builtin_mul_overflow use here also */ static inline bool -hb_unsigned_mul_overflows (unsigned int count, unsigned int size) +hb_unsigned_mul_overflows (unsigned int count, unsigned int size, unsigned *result = nullptr) { +#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) + unsigned stack_result; + if (!result) + result = &stack_result; + return __builtin_mul_overflow (count, size, result); +#endif + + if (result) + *result = count * size; return (size > 0) && (count >= ((unsigned int) -1) / size); } @@ -1164,9 +1175,12 @@ hb_qsort (void *base, size_t nel, size_t width, } -template <typename T, typename T2, typename T3> static inline void -hb_stable_sort (T *array, unsigned int len, int(*compar)(const T2 *, const T2 *), T3 *array2) +template <typename T, typename T2, typename T3 = int> static inline void +hb_stable_sort (T *array, unsigned int len, int(*compar)(const T2 *, const T2 *), T3 *array2 = nullptr) { + static_assert (hb_is_trivially_copy_assignable (T), ""); + static_assert (hb_is_trivially_copy_assignable (T3), ""); + for (unsigned int i = 1; i < len; i++) { unsigned int j = i; @@ -1189,12 +1203,6 @@ hb_stable_sort (T *array, unsigned int len, int(*compar)(const T2 *, const T2 *) } } -template <typename T> static inline void -hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *)) -{ - hb_stable_sort (array, len, compar, (int *) nullptr); -} - static inline hb_bool_t hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out) { @@ -1322,47 +1330,4 @@ struct HB_FUNCOBJ (hb_dec); -/* Compiler-assisted vectorization. */ - -/* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))), - * basically a fixed-size bitset. */ -template <typename elt_t, unsigned int byte_size> -struct hb_vector_size_t -{ - elt_t& operator [] (unsigned int i) { return v[i]; } - const elt_t& operator [] (unsigned int i) const { return v[i]; } - - void clear (unsigned char v = 0) { memset (this, v, sizeof (*this)); } - - template <typename Op> - hb_vector_size_t process (const Op& op) const - { - hb_vector_size_t r; - for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) - r.v[i] = op (v[i]); - return r; - } - template <typename Op> - hb_vector_size_t process (const Op& op, const hb_vector_size_t &o) const - { - hb_vector_size_t r; - for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) - r.v[i] = op (v[i], o.v[i]); - return r; - } - hb_vector_size_t operator | (const hb_vector_size_t &o) const - { return process (hb_bitwise_or, o); } - hb_vector_size_t operator & (const hb_vector_size_t &o) const - { return process (hb_bitwise_and, o); } - hb_vector_size_t operator ^ (const hb_vector_size_t &o) const - { return process (hb_bitwise_xor, o); } - hb_vector_size_t operator ~ () const - { return process (hb_bitwise_neg); } - - private: - static_assert (0 == byte_size % sizeof (elt_t), ""); - elt_t v[byte_size / sizeof (elt_t)]; -}; - - #endif /* HB_ALGS_HH */ diff --git a/thirdparty/harfbuzz/src/hb-array.hh b/thirdparty/harfbuzz/src/hb-array.hh index 5884007c19..17562bc336 100644 --- a/thirdparty/harfbuzz/src/hb-array.hh +++ b/thirdparty/harfbuzz/src/hb-array.hh @@ -100,10 +100,18 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> /* Ouch. The operator== compares the contents of the array. For range-based for loops, * it's best if we can just compare arrayZ, though comparing contents is still fast, * but also would require that Type has operator==. As such, we optimize this operator - * for range-based for loop and just compare arrayZ and length. */ + * for range-based for loop and just compare arrayZ and length. + * + * The above comment is outdated now because we implemented separate begin/end to + * objects that were using hb_array_t for range-based loop before. */ bool operator != (const hb_array_t& o) const { return this->arrayZ != o.arrayZ || this->length != o.length; } + /* Faster range-based for loop without bounds-check. */ + Type *begin () const { return arrayZ; } + Type *end () const { return arrayZ + length; } + + /* Extra operators. */ Type * operator & () const { return arrayZ; } @@ -112,11 +120,11 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> HB_INTERNAL bool operator == (const hb_array_t &o) const; - uint32_t hash () const { + uint32_t hash () const + { uint32_t current = 0; - for (unsigned int i = 0; i < this->length; i++) { - current = current * 31 + hb_hash (this->arrayZ[i]); - } + for (auto &v : *this) + current = current * 31 + hb_hash (v); return current; } @@ -184,23 +192,18 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> hb_sorted_array_t<Type> qsort (int (*cmp_)(const void*, const void*)) { + //static_assert (hb_enable_if (hb_is_trivially_copy_assignable(Type)), ""); if (likely (length)) hb_qsort (arrayZ, length, this->get_item_size (), cmp_); return hb_sorted_array_t<Type> (*this); } hb_sorted_array_t<Type> qsort () { + //static_assert (hb_enable_if (hb_is_trivially_copy_assignable(Type)), ""); if (likely (length)) hb_qsort (arrayZ, length, this->get_item_size (), Type::cmp); return hb_sorted_array_t<Type> (*this); } - void qsort (unsigned int start, unsigned int end) - { - end = hb_min (end, length); - assert (start <= end); - if (likely (start < end)) - hb_qsort (arrayZ + start, end - start, this->get_item_size (), Type::cmp); - } /* * Other methods. @@ -262,17 +265,31 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> void fini () { hb_free ((void *) arrayZ); arrayZ = nullptr; length = 0; } - template <typename hb_serialize_context_t> + template <typename hb_serialize_context_t, + typename U = Type, + hb_enable_if (!(sizeof (U) < sizeof (long long) && hb_is_trivially_copy_assignable(hb_decay<Type>)))> hb_array_t copy (hb_serialize_context_t *c) const { TRACE_SERIALIZE (this); auto* out = c->start_embed (arrayZ); - if (unlikely (!c->extend_size (out, get_size ()))) return_trace (hb_array_t ()); + if (unlikely (!c->extend_size (out, get_size (), false))) return_trace (hb_array_t ()); for (unsigned i = 0; i < length; i++) out[i] = arrayZ[i]; /* TODO: add version that calls c->copy() */ return_trace (hb_array_t (out, length)); } + template <typename hb_serialize_context_t, + typename U = Type, + hb_enable_if (sizeof (U) < sizeof (long long) && hb_is_trivially_copy_assignable(hb_decay<Type>))> + hb_array_t copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + auto* out = c->start_embed (arrayZ); + if (unlikely (!c->extend_size (out, get_size (), false))) return_trace (hb_array_t ()); + hb_memcpy (out, arrayZ, get_size ()); + return_trace (hb_array_t (out, length)); + } + template <typename hb_sanitize_context_t> bool sanitize (hb_sanitize_context_t *c) const { return c->check_array (arrayZ, length); } @@ -295,8 +312,8 @@ hb_array (T (&array_)[length_]) template <typename Type> struct hb_sorted_array_t : - hb_iter_t<hb_sorted_array_t<Type>, Type&>, - hb_array_t<Type> + hb_array_t<Type>, + hb_iter_t<hb_sorted_array_t<Type>, Type&> { typedef hb_iter_t<hb_sorted_array_t, Type&> iter_base_t; HB_ITER_USING (iter_base_t); @@ -316,8 +333,8 @@ struct hb_sorted_array_t : template <typename U, hb_enable_if (hb_is_cr_convertible(U, Type))> constexpr hb_sorted_array_t (const hb_array_t<U> &o) : - hb_iter_t<hb_sorted_array_t, Type&> (), - hb_array_t<Type> (o) {} + hb_array_t<Type> (o), + hb_iter_t<hb_sorted_array_t, Type&> () {} template <typename U, hb_enable_if (hb_is_cr_convertible(U, Type))> hb_sorted_array_t& operator = (const hb_array_t<U> &o) @@ -329,6 +346,11 @@ struct hb_sorted_array_t : bool operator != (const hb_sorted_array_t& o) const { return this->arrayZ != o.arrayZ || this->length != o.length; } + /* Faster range-based for loop without bounds-check. */ + Type *begin () const { return this->arrayZ; } + Type *end () const { return this->arrayZ + this->length; } + + hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int *seg_count /* IN/OUT */) const { return hb_sorted_array_t (((const hb_array_t<Type> *) (this))->sub_array (start_offset, seg_count)); } hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const @@ -421,18 +443,42 @@ inline bool hb_array_t<const unsigned char>::operator == (const hb_array_t<const return 0 == hb_memcmp (arrayZ, o.arrayZ, length); } + +/* Specialize hash() for byte arrays. */ + template <> -inline uint32_t hb_array_t<const char>::hash () const { +inline uint32_t hb_array_t<const char>::hash () const +{ uint32_t current = 0; - for (unsigned int i = 0; i < this->length; i++) - current = current * 31 + (uint32_t) (this->arrayZ[i] * 2654435761u); + unsigned i = 0; + +#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \ + ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) + struct __attribute__((packed)) packed_uint32_t { uint32_t v; }; + for (; i + 4 <= this->length; i += 4) + current = current * 31 + hb_hash ((uint32_t) ((packed_uint32_t *) &this->arrayZ[i])->v); +#endif + + for (; i < this->length; i++) + current = current * 31 + hb_hash (this->arrayZ[i]); return current; } + template <> -inline uint32_t hb_array_t<const unsigned char>::hash () const { +inline uint32_t hb_array_t<const unsigned char>::hash () const +{ uint32_t current = 0; - for (unsigned int i = 0; i < this->length; i++) - current = current * 31 + (uint32_t) (this->arrayZ[i] * 2654435761u); + unsigned i = 0; + +#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \ + ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) + struct __attribute__((packed)) packed_uint32_t { uint32_t v; }; + for (; i + 4 <= this->length; i += 4) + current = current * 31 + hb_hash ((uint32_t) ((packed_uint32_t *) &this->arrayZ[i])->v); +#endif + + for (; i < this->length; i++) + current = current * 31 + hb_hash (this->arrayZ[i]); return current; } diff --git a/thirdparty/harfbuzz/src/hb-bit-page.hh b/thirdparty/harfbuzz/src/hb-bit-page.hh index 95ae1b7bf9..11987054f8 100644 --- a/thirdparty/harfbuzz/src/hb-bit-page.hh +++ b/thirdparty/harfbuzz/src/hb-bit-page.hh @@ -30,6 +30,53 @@ #include "hb.hh" + +/* Compiler-assisted vectorization. */ + +/* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))), + * basically a fixed-size bitset. */ +template <typename elt_t, unsigned int byte_size> +struct hb_vector_size_t +{ + elt_t& operator [] (unsigned int i) { return v[i]; } + const elt_t& operator [] (unsigned int i) const { return v[i]; } + + void clear (unsigned char v = 0) { hb_memset (this, v, sizeof (*this)); } + + template <typename Op> + hb_vector_size_t process (const Op& op) const + { + hb_vector_size_t r; + for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) + r.v[i] = op (v[i]); + return r; + } + template <typename Op> + hb_vector_size_t process (const Op& op, const hb_vector_size_t &o) const + { + hb_vector_size_t r; + for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) + r.v[i] = op (v[i], o.v[i]); + return r; + } + hb_vector_size_t operator | (const hb_vector_size_t &o) const + { return process (hb_bitwise_or, o); } + hb_vector_size_t operator & (const hb_vector_size_t &o) const + { return process (hb_bitwise_and, o); } + hb_vector_size_t operator ^ (const hb_vector_size_t &o) const + { return process (hb_bitwise_xor, o); } + hb_vector_size_t operator ~ () const + { return process (hb_bitwise_neg); } + + hb_array_t<const elt_t> iter () const + { return hb_array (v); } + + private: + static_assert (0 == byte_size % sizeof (elt_t), ""); + elt_t v[byte_size / sizeof (elt_t)]; +}; + + struct hb_bit_page_t { void init0 () { v.clear (); } @@ -40,17 +87,17 @@ struct hb_bit_page_t bool is_empty () const { - for (unsigned i = 0; i < len (); i++) - if (v[i]) - return false; - return true; + return + + hb_iter (v) + | hb_none + ; } uint32_t hash () const { - uint32_t h = 0; - for (unsigned i = 0; i < len (); i++) - h = h * 31 + hb_hash (v[i]); - return h; + return + + hb_iter (v) + | hb_reduce ([] (uint32_t h, const elt_t &_) { return h * 31 + hb_hash (_); }, (uint32_t) 0u) + ; } void add (hb_codepoint_t g) { elt (g) |= mask (g); } @@ -69,7 +116,7 @@ struct hb_bit_page_t *la |= ~(mask (a) - 1); la++; - memset (la, 0xff, (char *) lb - (char *) la); + hb_memset (la, 0xff, (char *) lb - (char *) la); *lb |= ((mask (b) << 1) - 1); } @@ -85,7 +132,7 @@ struct hb_bit_page_t *la &= mask (a) - 1; la++; - memset (la, 0, (char *) lb - (char *) la); + hb_memset (la, 0, (char *) lb - (char *) la); *lb &= ~((mask (b) << 1) - 1); } @@ -101,13 +148,13 @@ struct hb_bit_page_t hb_codepoint_t *p, unsigned int size) const { - unsigned int start_v = start_value >> ELT_BITS_LOG_2; + unsigned int start_v = start_value / ELT_BITS; unsigned int start_bit = start_value & ELT_MASK; unsigned int count = 0; for (unsigned i = start_v; i < len () && count < size; i++) { elt_t bits = v[i]; - uint32_t v_base = base | (i << ELT_BITS_LOG_2); + uint32_t v_base = base | (i * ELT_BITS); for (unsigned int j = start_bit; j < ELT_BITS && count < size; j++) { if ((elt_t(1) << j) & bits) { @@ -132,13 +179,13 @@ struct hb_bit_page_t unsigned int size, hb_codepoint_t *next_value) const { - unsigned int start_v = start_value >> ELT_BITS_LOG_2; + unsigned int start_v = start_value / ELT_BITS; unsigned int start_bit = start_value & ELT_MASK; unsigned int count = 0; for (unsigned i = start_v; i < len () && count < size; i++) { elt_t bits = v[i]; - uint32_t v_offset = i << ELT_BITS_LOG_2; + uint32_t v_offset = i * ELT_BITS; for (unsigned int j = start_bit; j < ELT_BITS && count < size; j++) { if ((elt_t(1) << j) & bits) @@ -161,7 +208,10 @@ struct hb_bit_page_t bool is_equal (const hb_bit_page_t &other) const { - return 0 == hb_memcmp (&v, &other.v, sizeof (v)); + for (unsigned i = 0; i < len (); i++) + if (v[i] != other.v[i]) + return false; + return true; } bool is_subset (const hb_bit_page_t &larger_page) const { @@ -173,10 +223,10 @@ struct hb_bit_page_t unsigned int get_population () const { - unsigned int pop = 0; - for (unsigned int i = 0; i < len (); i++) - pop += hb_popcount (v[i]); - return pop; + return + + hb_iter (v) + | hb_reduce ([] (unsigned pop, const elt_t &_) { return pop + hb_popcount (_); }, 0u) + ; } bool next (hb_codepoint_t *codepoint) const @@ -262,8 +312,6 @@ struct hb_bit_page_t typedef hb_vector_size_t<elt_t, PAGE_BITS / 8> vector_t; static constexpr unsigned ELT_BITS = sizeof (elt_t) * 8; - static constexpr unsigned ELT_BITS_LOG_2 = 6; - static_assert (1 << ELT_BITS_LOG_2 == ELT_BITS, ""); static constexpr unsigned ELT_MASK = ELT_BITS - 1; static constexpr unsigned BITS = sizeof (vector_t) * 8; diff --git a/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh b/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh index 27fb0732ea..ff8aecc60c 100644 --- a/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh +++ b/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh @@ -123,10 +123,8 @@ struct hb_bit_set_invertible_t bool get (hb_codepoint_t g) const { return s.get (g) ^ inverted; } /* Has interface. */ - static constexpr bool SENTINEL = false; - typedef bool value_t; - value_t operator [] (hb_codepoint_t k) const { return get (k); } - bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; } + bool operator [] (hb_codepoint_t k) const { return get (k); } + bool has (hb_codepoint_t k) const { return (*this)[k]; } /* Predicate. */ bool operator () (hb_codepoint_t k) const { return has (k); } diff --git a/thirdparty/harfbuzz/src/hb-bit-set.hh b/thirdparty/harfbuzz/src/hb-bit-set.hh index a63887efda..8de6e037fb 100644 --- a/thirdparty/harfbuzz/src/hb-bit-set.hh +++ b/thirdparty/harfbuzz/src/hb-bit-set.hh @@ -85,10 +85,10 @@ struct hb_bit_set_t void err () { if (successful) successful = false; } /* TODO Remove */ bool in_error () const { return !successful; } - bool resize (unsigned int count) + bool resize (unsigned int count, bool clear = true) { if (unlikely (!successful)) return false; - if (unlikely (!pages.resize (count) || !page_map.resize (count))) + if (unlikely (!pages.resize (count, clear) || !page_map.resize (count, clear))) { pages.resize (page_map.length); successful = false; @@ -330,10 +330,8 @@ struct hb_bit_set_t } /* Has interface. */ - static constexpr bool SENTINEL = false; - typedef bool value_t; - value_t operator [] (hb_codepoint_t k) const { return get (k); } - bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; } + bool operator [] (hb_codepoint_t k) const { return get (k); } + bool has (hb_codepoint_t k) const { return (*this)[k]; } /* Predicate. */ bool operator () (hb_codepoint_t k) const { return has (k); } @@ -352,7 +350,7 @@ struct hb_bit_set_t { if (unlikely (!successful)) return; unsigned int count = other.pages.length; - if (unlikely (!resize (count))) + if (unlikely (!resize (count, false))) return; population = other.population; @@ -391,7 +389,7 @@ struct hb_bit_set_t bool is_subset (const hb_bit_set_t &larger_set) const { if (has_population () && larger_set.has_population () && - population != larger_set.population) + population > larger_set.population) return false; uint32_t spi = 0; @@ -540,21 +538,21 @@ struct hb_bit_set_t b = nb; for (; a && b; ) { - if (page_map[a - 1].major == other.page_map[b - 1].major) + if (page_map.arrayZ[a - 1].major == other.page_map.arrayZ[b - 1].major) { a--; b--; count--; - page_map[count] = page_map[a]; + page_map.arrayZ[count] = page_map.arrayZ[a]; page_at (count).v = op (page_at (a).v, other.page_at (b).v); } - else if (page_map[a - 1].major > other.page_map[b - 1].major) + else if (page_map.arrayZ[a - 1].major > other.page_map.arrayZ[b - 1].major) { a--; if (passthru_left) { count--; - page_map[count] = page_map[a]; + page_map.arrayZ[count] = page_map.arrayZ[a]; } } else @@ -563,8 +561,8 @@ struct hb_bit_set_t if (passthru_right) { count--; - page_map[count].major = other.page_map[b].major; - page_map[count].index = next_page++; + page_map.arrayZ[count].major = other.page_map.arrayZ[b].major; + page_map.arrayZ[count].index = next_page++; page_at (count).v = other.page_at (b).v; } } @@ -574,15 +572,15 @@ struct hb_bit_set_t { a--; count--; - page_map[count] = page_map [a]; + page_map.arrayZ[count] = page_map.arrayZ[a]; } if (passthru_right) while (b) { b--; count--; - page_map[count].major = other.page_map[b].major; - page_map[count].index = next_page++; + page_map.arrayZ[count].major = other.page_map.arrayZ[b].major; + page_map.arrayZ[count].index = next_page++; page_at (count).v = other.page_at (b).v; } assert (!count); @@ -605,8 +603,6 @@ struct hb_bit_set_t bool next (hb_codepoint_t *codepoint) const { - // TODO: this should be merged with prev() as both implementations - // are very similar. if (unlikely (*codepoint == INVALID)) { *codepoint = get_min (); return *codepoint != INVALID; @@ -640,7 +636,7 @@ struct hb_bit_set_t for (; i < page_map.length; i++) { - const page_map_t ¤t = page_map.arrayZ[i]; + const page_map_t ¤t = page_map_array[i]; hb_codepoint_t m = pages_array[current.index].get_min (); if (m != INVALID) { @@ -663,21 +659,21 @@ struct hb_bit_set_t page_map_t map = {get_major (*codepoint), 0}; unsigned int i; page_map.bfind (map, &i, HB_NOT_FOUND_STORE_CLOSEST); - if (i < page_map.length && page_map[i].major == map.major) + if (i < page_map.length && page_map.arrayZ[i].major == map.major) { - if (pages[page_map[i].index].previous (codepoint)) + if (pages[page_map.arrayZ[i].index].previous (codepoint)) { - *codepoint += page_map[i].major * page_t::PAGE_BITS; + *codepoint += page_map.arrayZ[i].major * page_t::PAGE_BITS; return true; } } i--; for (; (int) i >= 0; i--) { - hb_codepoint_t m = pages[page_map[i].index].get_max (); + hb_codepoint_t m = pages.arrayZ[page_map.arrayZ[i].index].get_max (); if (m != INVALID) { - *codepoint = page_map[i].major * page_t::PAGE_BITS + m; + *codepoint = page_map.arrayZ[i].major * page_t::PAGE_BITS + m; return true; } } @@ -905,7 +901,7 @@ struct hb_bit_set_t { auto &cached_page = page_map.arrayZ[i]; if (cached_page.major == major) - return &pages[cached_page.index]; + return &pages.arrayZ[cached_page.index]; } page_map_t map = {major, pages.length}; @@ -917,15 +913,15 @@ struct hb_bit_set_t if (unlikely (!resize (pages.length + 1))) return nullptr; - pages[map.index].init0 (); - memmove (page_map + i + 1, - page_map + i, + pages.arrayZ[map.index].init0 (); + memmove (page_map.arrayZ + i + 1, + page_map.arrayZ + i, (page_map.length - 1 - i) * page_map.item_size); page_map[i] = map; } last_page_lookup = i; - return &pages[page_map[i].index]; + return &pages.arrayZ[page_map.arrayZ[i].index]; } const page_t *page_for (hb_codepoint_t g) const { @@ -939,7 +935,7 @@ struct hb_bit_set_t { auto &cached_page = page_map.arrayZ[i]; if (cached_page.major == major) - return &pages[cached_page.index]; + return &pages.arrayZ[cached_page.index]; } page_map_t key = {major}; @@ -947,10 +943,18 @@ struct hb_bit_set_t return nullptr; last_page_lookup = i; - return &pages[page_map[i].index]; + return &pages.arrayZ[page_map[i].index]; + } + page_t &page_at (unsigned int i) + { + assert (i < page_map.length); + return pages.arrayZ[page_map.arrayZ[i].index]; + } + const page_t &page_at (unsigned int i) const + { + assert (i < page_map.length); + return pages.arrayZ[page_map.arrayZ[i].index]; } - page_t &page_at (unsigned int i) { return pages[page_map[i].index]; } - const page_t &page_at (unsigned int i) const { return pages[page_map[i].index]; } unsigned int get_major (hb_codepoint_t g) const { return g >> page_t::PAGE_BITS_LOG_2; } unsigned int page_remainder (hb_codepoint_t g) const { return g & page_t::PAGE_BITMASK; } hb_codepoint_t major_start (unsigned int major) const { return major << page_t::PAGE_BITS_LOG_2; } diff --git a/thirdparty/harfbuzz/src/hb-blob.cc b/thirdparty/harfbuzz/src/hb-blob.cc index 9bc12ea3fa..f0fda1fa4d 100644 --- a/thirdparty/harfbuzz/src/hb-blob.cc +++ b/thirdparty/harfbuzz/src/hb-blob.cc @@ -495,7 +495,7 @@ hb_blob_t::try_make_writable () DEBUG_MSG_FUNC (BLOB, this, "dupped successfully -> %p\n", this->data); - memcpy (new_data, this->data, this->length); + hb_memcpy (new_data, this->data, this->length); this->destroy_user_data (); this->mode = HB_MEMORY_MODE_WRITABLE; this->data = new_data; diff --git a/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh b/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh index 87095855d6..993bb1f698 100644 --- a/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh +++ b/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh @@ -32,7 +32,7 @@ #include "hb.hh" -#line 36 "hb-buffer-deserialize-json.hh" +#line 33 "hb-buffer-deserialize-json.hh" static const unsigned char _deserialize_json_trans_keys[] = { 0u, 0u, 9u, 123u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, @@ -557,12 +557,12 @@ _hb_buffer_deserialize_json (hb_buffer_t *buffer, hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; -#line 561 "hb-buffer-deserialize-json.hh" +#line 554 "hb-buffer-deserialize-json.hh" { cs = deserialize_json_start; } -#line 566 "hb-buffer-deserialize-json.hh" +#line 557 "hb-buffer-deserialize-json.hh" { int _slen; int _trans; @@ -590,8 +590,8 @@ _resume: case 1: #line 38 "hb-buffer-deserialize-json.rl" { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); + hb_memset (&info, 0, sizeof (info)); + hb_memset (&pos , 0, sizeof (pos )); } break; case 5: @@ -774,7 +774,7 @@ _resume: *end_ptr = p; } break; -#line 778 "hb-buffer-deserialize-json.hh" +#line 735 "hb-buffer-deserialize-json.hh" } _again: diff --git a/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh b/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh index 9062610de2..6b9b4282fc 100644 --- a/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh +++ b/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh @@ -32,32 +32,30 @@ #include "hb.hh" -#line 36 "hb-buffer-deserialize-text.hh" +#line 33 "hb-buffer-deserialize-text.hh" static const unsigned char _deserialize_text_trans_keys[] = { - 0u, 0u, 9u, 91u, 85u, 85u, 43u, 43u, 48u, 102u, 9u, 85u, 48u, 57u, 45u, 57u, - 48u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, - 44u, 57u, 43u, 124u, 45u, 57u, 48u, 57u, 9u, 124u, 9u, 124u, 0u, 0u, 9u, 85u, + 0u, 0u, 9u, 91u, 85u, 85u, 43u, 43u, 48u, 102u, 9u, 85u, 48u, 57u, 48u, 57u, + 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 44u, 44u, + 45u, 57u, 48u, 57u, 44u, 57u, 43u, 124u, 9u, 124u, 9u, 124u, 0u, 0u, 9u, 85u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, - 9u, 124u, 9u, 124u, 9u, 124u, 0 + 0 }; static const char _deserialize_text_key_spans[] = { - 0, 83, 1, 1, 55, 77, 10, 13, - 10, 10, 10, 13, 10, 1, 13, 10, - 14, 82, 13, 10, 116, 116, 0, 77, - 116, 116, 116, 116, 116, 116, 116, 116, + 0, 83, 1, 1, 55, 77, 10, 10, + 13, 10, 13, 10, 10, 13, 10, 1, + 13, 10, 14, 82, 116, 116, 0, 77, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116 + 116, 116, 116, 116, 116, 116, 116, 116 }; static const short _deserialize_text_index_offsets[] = { 0, 0, 84, 86, 88, 144, 222, 233, - 247, 258, 269, 280, 294, 305, 307, 321, - 332, 347, 430, 444, 455, 572, 689, 690, + 244, 258, 269, 283, 294, 305, 319, 330, + 332, 346, 357, 372, 455, 572, 689, 690, 768, 885, 1002, 1119, 1236, 1353, 1470, 1587, - 1704, 1821, 1938, 2055, 2172, 2289, 2406, 2523, - 2640, 2757, 2874 + 1704, 1821, 1938, 2055, 2172, 2289, 2406, 2523 }; static const char _deserialize_text_indicies[] = { @@ -90,34 +88,34 @@ static const char _deserialize_text_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 8, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 1, 10, 1, 1, 11, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 1, + 9, 1, 10, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 1, 12, 1, 1, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 1, 15, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 1, 17, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 1, 19, 1, 1, 20, 21, 21, 21, + 16, 16, 16, 16, 16, 1, 17, 1, + 1, 18, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 1, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 22, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 1, 24, 1, 25, 1, 1, 26, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 1, 28, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 1, 24, 1, 1, - 1, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 1, 30, 30, 1, 1, + 23, 1, 24, 1, 1, 25, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 1, + 27, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 1, 29, 1, 30, 1, 1, + 31, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 1, 33, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 1, 29, 1, + 1, 1, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 1, 35, 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 30, 1, - 1, 30, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 35, + 1, 1, 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 30, 30, 1, + 1, 1, 1, 1, 1, 1, 35, 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 30, 1, 31, - 1, 1, 32, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 1, 34, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 1, + 1, 1, 1, 1, 1, 1, 35, 1, 36, 36, 36, 36, 36, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 36, @@ -201,282 +199,235 @@ static const char _deserialize_text_indicies[] = { 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 56, 48, - 57, 57, 57, 57, 57, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 57, - 30, 30, 58, 30, 30, 30, 30, 30, - 30, 30, 59, 1, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 60, 30, 30, 61, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 62, 63, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 64, 30, 57, 57, 57, - 57, 57, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 57, 30, 30, 58, - 30, 30, 30, 30, 30, 30, 30, 59, - 1, 30, 30, 30, 65, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 30, 30, - 30, 60, 30, 30, 61, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 62, 63, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 64, 30, 67, 67, 67, 67, 67, 1, + 57, 57, 57, 57, 57, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 57, + 35, 35, 58, 35, 35, 35, 35, 35, + 35, 35, 59, 1, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 60, 35, 35, 61, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 62, 63, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 64, 35, 65, 65, 65, + 65, 65, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 67, 1, 1, 68, 1, 1, 1, - 1, 1, 1, 1, 1, 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 70, 1, + 1, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 71, 1, 72, - 72, 72, 72, 72, 1, 1, 1, 1, + 67, 1, 68, 68, 68, 68, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 42, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 42, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 73, 1, 74, 74, 74, 74, - 74, 48, 48, 48, 48, 48, 48, 48, + 1, 1, 1, 1, 1, 69, 1, 70, + 70, 70, 70, 70, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 74, 48, 48, 50, 48, - 48, 48, 48, 48, 48, 48, 51, 1, + 48, 48, 48, 48, 48, 48, 70, 48, + 48, 50, 48, 48, 48, 48, 48, 48, + 48, 51, 1, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 52, 48, 48, 53, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 52, 48, 48, 53, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 54, - 55, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 54, 55, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 56, - 48, 75, 75, 75, 75, 75, 1, 1, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 56, 48, 71, 71, 71, 71, + 71, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 71, 1, 1, 72, 1, + 1, 1, 1, 1, 1, 1, 1, 73, 1, 1, 1, 1, 1, 1, 1, 1, - 75, 1, 1, 76, 1, 1, 1, 1, - 1, 1, 1, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 78, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 79, 1, 80, 80, - 80, 80, 80, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 75, + 1, 76, 76, 76, 76, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 76, 1, 1, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 81, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 78, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 82, 1, 80, 80, 80, 80, 80, + 1, 1, 1, 1, 79, 1, 76, 76, + 76, 76, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 76, 1, 1, + 77, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 78, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 79, 1, 71, 71, 71, 71, 71, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 82, 1, - 84, 84, 84, 84, 84, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 84, - 1, 1, 85, 1, 1, 1, 1, 1, - 1, 1, 86, 1, 1, 1, 1, 1, + 1, 1, 71, 1, 1, 72, 1, 1, + 1, 1, 1, 1, 1, 1, 73, 1, + 1, 1, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 87, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 75, 1, + 80, 80, 80, 80, 80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 88, 1, 84, 84, 84, - 84, 84, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 80, + 1, 1, 81, 1, 1, 1, 1, 1, + 1, 1, 82, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 84, 1, 1, 85, - 1, 1, 1, 1, 1, 1, 1, 86, - 1, 1, 1, 1, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 83, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 84, 1, 85, 85, 85, + 85, 85, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 88, 1, 75, 75, 75, 75, 75, 1, + 1, 1, 1, 1, 85, 1, 1, 86, + 1, 1, 1, 1, 1, 1, 1, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 75, 1, 1, 76, 1, 1, 1, - 1, 1, 1, 1, 77, 1, 1, 1, - 1, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 1, 1, 1, 1, 1, - 1, 78, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 88, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 79, 1, 90, - 90, 90, 90, 90, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 90, 1, - 1, 91, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 89, 1, 85, 85, 85, 85, 85, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 85, 1, 1, 86, 1, 1, 1, + 1, 1, 1, 1, 87, 1, 1, 1, + 1, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 88, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 93, 1, 90, 90, 90, 90, - 90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 90, 1, 1, 91, 1, + 1, 1, 1, 1, 1, 89, 1, 80, + 80, 80, 80, 80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 80, 1, + 1, 81, 1, 1, 1, 1, 1, 1, + 1, 82, 1, 1, 1, 1, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + 1, 1, 1, 1, 1, 1, 83, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 93, - 1, 67, 67, 67, 67, 67, 1, 1, + 1, 1, 84, 1, 65, 65, 65, 65, + 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 67, 1, 1, 68, 1, 1, 1, 1, - 1, 1, 1, 1, 69, 1, 1, 1, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 71, 1, 94, 94, - 94, 94, 94, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 94, 30, 30, - 58, 30, 30, 30, 30, 30, 30, 30, - 59, 1, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 60, 30, 30, 61, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 62, 95, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 96, 30, 94, 94, 94, 94, 94, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 94, 30, 30, 58, 30, 30, - 30, 30, 30, 30, 30, 59, 1, 30, - 30, 30, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 97, 30, 30, 30, 60, - 30, 30, 61, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 62, 95, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 96, 30, - 0 + 1, 1, 1, 1, 1, 1, 1, 67, + 1, 0 }; static const char _deserialize_text_trans_targs[] = { 1, 0, 2, 26, 3, 4, 20, 5, - 24, 25, 8, 29, 40, 29, 40, 32, - 37, 33, 34, 12, 13, 16, 13, 16, - 14, 15, 35, 36, 35, 36, 27, 19, - 38, 39, 38, 39, 21, 20, 6, 22, + 24, 25, 28, 39, 9, 31, 34, 31, + 34, 11, 32, 33, 32, 33, 35, 38, + 14, 15, 18, 15, 18, 16, 17, 36, + 37, 36, 37, 27, 21, 20, 6, 22, 23, 21, 22, 23, 21, 22, 23, 25, - 27, 27, 28, 7, 9, 11, 17, 22, - 31, 27, 28, 7, 9, 11, 17, 22, - 31, 41, 42, 30, 10, 18, 22, 31, - 30, 31, 31, 30, 10, 7, 11, 31, - 30, 22, 31, 34, 30, 10, 7, 22, - 31, 37, 30, 10, 22, 31, 27, 22, - 31, 42 + 27, 27, 7, 8, 12, 13, 19, 22, + 30, 27, 7, 8, 12, 13, 19, 22, + 30, 29, 22, 30, 29, 30, 30, 29, + 7, 10, 22, 30, 29, 7, 22, 30, + 29, 7, 8, 13, 30, 29, 7, 8, + 22, 30, 38, 39 }; static const char _deserialize_text_trans_actions[] = { 0, 0, 0, 0, 1, 0, 2, 0, - 2, 2, 3, 4, 4, 5, 5, 4, - 4, 4, 4, 3, 3, 3, 0, 0, - 6, 3, 4, 4, 5, 5, 5, 3, - 4, 4, 5, 5, 7, 8, 9, 7, + 2, 2, 3, 3, 4, 3, 3, 5, + 5, 4, 3, 3, 5, 5, 3, 3, + 4, 4, 4, 0, 0, 6, 4, 3, + 3, 5, 5, 5, 7, 8, 9, 7, 7, 0, 0, 0, 10, 10, 10, 8, - 12, 13, 14, 15, 15, 15, 16, 11, - 11, 18, 19, 20, 20, 20, 0, 17, - 17, 4, 4, 21, 22, 22, 21, 21, - 0, 0, 13, 10, 23, 23, 23, 10, - 24, 24, 24, 5, 25, 26, 26, 25, - 25, 5, 27, 28, 27, 27, 30, 29, - 29, 5 + 12, 13, 14, 14, 14, 14, 15, 11, + 11, 17, 18, 18, 18, 18, 0, 16, + 16, 19, 19, 19, 0, 0, 13, 20, + 21, 21, 20, 20, 22, 23, 22, 22, + 10, 24, 24, 24, 10, 25, 26, 26, + 25, 25, 5, 5 }; static const char _deserialize_text_eof_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, - 10, 10, 11, 17, 17, 21, 0, 11, - 10, 24, 24, 25, 25, 10, 27, 27, - 21, 29, 29 + 10, 10, 11, 16, 19, 0, 11, 20, + 22, 22, 20, 10, 25, 25, 10, 19 }; static const int deserialize_text_start = 1; @@ -509,12 +460,12 @@ _hb_buffer_deserialize_text (hb_buffer_t *buffer, hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; -#line 513 "hb-buffer-deserialize-text.hh" +#line 457 "hb-buffer-deserialize-text.hh" { cs = deserialize_text_start; } -#line 518 "hb-buffer-deserialize-text.hh" +#line 460 "hb-buffer-deserialize-text.hh" { int _slen; int _trans; @@ -542,11 +493,11 @@ _resume: case 1: #line 38 "hb-buffer-deserialize-text.rl" { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); + hb_memset (&info, 0, sizeof (info)); + hb_memset (&pos , 0, sizeof (pos )); } break; - case 3: + case 4: #line 51 "hb-buffer-deserialize-text.rl" { tok = p; @@ -560,7 +511,7 @@ _resume: #line 56 "hb-buffer-deserialize-text.rl" { if (unlikely (!buffer->ensure_unicode ())) return false; } break; - case 20: + case 18: #line 58 "hb-buffer-deserialize-text.rl" { /* TODO Unescape delimiters. */ @@ -574,7 +525,7 @@ _resume: #line 66 "hb-buffer-deserialize-text.rl" {if (!parse_hex (tok, p, &info.codepoint )) return false; } break; - case 23: + case 24: #line 68 "hb-buffer-deserialize-text.rl" { if (!parse_uint (tok, p, &info.cluster )) return false; } break; @@ -586,26 +537,26 @@ _resume: #line 70 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.y_offset )) return false; } break; - case 22: + case 21: #line 71 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.x_advance)) return false; } break; - case 28: + case 23: #line 72 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.y_advance)) return false; } break; - case 16: + case 15: #line 38 "hb-buffer-deserialize-text.rl" { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); + hb_memset (&info, 0, sizeof (info)); + hb_memset (&pos , 0, sizeof (pos )); } #line 51 "hb-buffer-deserialize-text.rl" { tok = p; } break; - case 4: + case 3: #line 51 "hb-buffer-deserialize-text.rl" { tok = p; @@ -621,7 +572,7 @@ _resume: #line 56 "hb-buffer-deserialize-text.rl" { if (unlikely (!buffer->ensure_unicode ())) return false; } break; - case 17: + case 16: #line 58 "hb-buffer-deserialize-text.rl" { /* TODO Unescape delimiters. */ @@ -639,18 +590,6 @@ _resume: *end_ptr = p; } break; - case 19: -#line 58 "hb-buffer-deserialize-text.rl" - { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} -#line 55 "hb-buffer-deserialize-text.rl" - { if (unlikely (!buffer->ensure_glyphs ())) return false; } - break; case 7: #line 66 "hb-buffer-deserialize-text.rl" {if (!parse_hex (tok, p, &info.codepoint )) return false; } @@ -687,7 +626,7 @@ _resume: *end_ptr = p; } break; - case 21: + case 20: #line 71 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.x_advance)) return false; } #line 43 "hb-buffer-deserialize-text.rl" @@ -699,7 +638,7 @@ _resume: *end_ptr = p; } break; - case 27: + case 22: #line 72 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.y_advance)) return false; } #line 43 "hb-buffer-deserialize-text.rl" @@ -711,7 +650,7 @@ _resume: *end_ptr = p; } break; - case 24: + case 19: #line 73 "hb-buffer-deserialize-text.rl" { if (!parse_uint (tok, p, &info.mask )) return false; } #line 43 "hb-buffer-deserialize-text.rl" @@ -726,8 +665,8 @@ _resume: case 12: #line 38 "hb-buffer-deserialize-text.rl" { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); + hb_memset (&info, 0, sizeof (info)); + hb_memset (&pos , 0, sizeof (pos )); } #line 51 "hb-buffer-deserialize-text.rl" { @@ -736,11 +675,11 @@ _resume: #line 55 "hb-buffer-deserialize-text.rl" { if (unlikely (!buffer->ensure_glyphs ())) return false; } break; - case 15: + case 14: #line 38 "hb-buffer-deserialize-text.rl" { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); + hb_memset (&info, 0, sizeof (info)); + hb_memset (&pos , 0, sizeof (pos )); } #line 51 "hb-buffer-deserialize-text.rl" { @@ -755,7 +694,7 @@ _resume: return false; } break; - case 18: + case 17: #line 58 "hb-buffer-deserialize-text.rl" { /* TODO Unescape delimiters. */ @@ -775,31 +714,11 @@ _resume: *end_ptr = p; } break; - case 29: -#line 58 "hb-buffer-deserialize-text.rl" - { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} -#line 73 "hb-buffer-deserialize-text.rl" - { if (!parse_uint (tok, p, &info.mask )) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; case 11: #line 38 "hb-buffer-deserialize-text.rl" { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); + hb_memset (&info, 0, sizeof (info)); + hb_memset (&pos , 0, sizeof (pos )); } #line 51 "hb-buffer-deserialize-text.rl" { @@ -822,54 +741,11 @@ _resume: *end_ptr = p; } break; - case 14: -#line 38 "hb-buffer-deserialize-text.rl" - { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); -} -#line 51 "hb-buffer-deserialize-text.rl" - { - tok = p; -} -#line 58 "hb-buffer-deserialize-text.rl" - { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} -#line 55 "hb-buffer-deserialize-text.rl" - { if (unlikely (!buffer->ensure_glyphs ())) return false; } - break; - case 30: -#line 58 "hb-buffer-deserialize-text.rl" - { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} -#line 73 "hb-buffer-deserialize-text.rl" - { if (!parse_uint (tok, p, &info.mask )) return false; } -#line 55 "hb-buffer-deserialize-text.rl" - { if (unlikely (!buffer->ensure_glyphs ())) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; case 13: #line 38 "hb-buffer-deserialize-text.rl" { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); + hb_memset (&info, 0, sizeof (info)); + hb_memset (&pos , 0, sizeof (pos )); } #line 51 "hb-buffer-deserialize-text.rl" { @@ -894,7 +770,7 @@ _resume: *end_ptr = p; } break; -#line 898 "hb-buffer-deserialize-text.hh" +#line 715 "hb-buffer-deserialize-text.hh" } _again: @@ -906,7 +782,7 @@ _again: if ( p == eof ) { switch ( _deserialize_text_eof_actions[cs] ) { - case 17: + case 16: #line 58 "hb-buffer-deserialize-text.rl" { /* TODO Unescape delimiters. */ @@ -960,7 +836,7 @@ _again: *end_ptr = p; } break; - case 21: + case 20: #line 71 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.x_advance)) return false; } #line 43 "hb-buffer-deserialize-text.rl" @@ -972,7 +848,7 @@ _again: *end_ptr = p; } break; - case 27: + case 22: #line 72 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.y_advance)) return false; } #line 43 "hb-buffer-deserialize-text.rl" @@ -984,27 +860,7 @@ _again: *end_ptr = p; } break; - case 24: -#line 73 "hb-buffer-deserialize-text.rl" - { if (!parse_uint (tok, p, &info.mask )) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 29: -#line 58 "hb-buffer-deserialize-text.rl" - { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} + case 19: #line 73 "hb-buffer-deserialize-text.rl" { if (!parse_uint (tok, p, &info.mask )) return false; } #line 43 "hb-buffer-deserialize-text.rl" @@ -1019,8 +875,8 @@ _again: case 11: #line 38 "hb-buffer-deserialize-text.rl" { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); + hb_memset (&info, 0, sizeof (info)); + hb_memset (&pos , 0, sizeof (pos )); } #line 51 "hb-buffer-deserialize-text.rl" { @@ -1043,7 +899,7 @@ _again: *end_ptr = p; } break; -#line 1047 "hb-buffer-deserialize-text.hh" +#line 825 "hb-buffer-deserialize-text.hh" } } diff --git a/thirdparty/harfbuzz/src/hb-buffer-serialize.cc b/thirdparty/harfbuzz/src/hb-buffer-serialize.cc index d1e1775430..a458f2318f 100644 --- a/thirdparty/harfbuzz/src/hb-buffer-serialize.cc +++ b/thirdparty/harfbuzz/src/hb-buffer-serialize.cc @@ -183,7 +183,7 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, unsigned int l = p - b; if (buf_size > l) { - memcpy (buf, b, l); + hb_memcpy (buf, b, l); buf += l; buf_size -= l; *buf_consumed += l; @@ -241,7 +241,7 @@ _hb_buffer_serialize_unicode_json (hb_buffer_t *buffer, unsigned int l = p - b; if (buf_size > l) { - memcpy (buf, b, l); + hb_memcpy (buf, b, l); buf += l; buf_size -= l; *buf_consumed += l; @@ -329,7 +329,7 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, unsigned int l = p - b; if (buf_size > l) { - memcpy (buf, b, l); + hb_memcpy (buf, b, l); buf += l; buf_size -= l; *buf_consumed += l; @@ -381,7 +381,7 @@ _hb_buffer_serialize_unicode_text (hb_buffer_t *buffer, unsigned int l = p - b; if (buf_size > l) { - memcpy (buf, b, l); + hb_memcpy (buf, b, l); buf += l; buf_size -= l; *buf_consumed += l; diff --git a/thirdparty/harfbuzz/src/hb-buffer-verify.cc b/thirdparty/harfbuzz/src/hb-buffer-verify.cc index 5453e1ca94..1cd52b39b1 100644 --- a/thirdparty/harfbuzz/src/hb-buffer-verify.cc +++ b/thirdparty/harfbuzz/src/hb-buffer-verify.cc @@ -186,7 +186,7 @@ buffer_verify_unsafe_to_break (hb_buffer_t *buffer, bool ret = true; hb_buffer_diff_flags_t diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0); - if (diff) + if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH) { buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-break test failed."); ret = false; @@ -313,7 +313,6 @@ buffer_verify_unsafe_to_concat (hb_buffer_t *buffer, bool ret = true; hb_buffer_diff_flags_t diff; - /* * Shape the two fragment streams. */ @@ -382,7 +381,7 @@ buffer_verify_unsafe_to_concat (hb_buffer_t *buffer, * Diff results. */ diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0); - if (diff) + if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH) { buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-concat test failed."); ret = false; diff --git a/thirdparty/harfbuzz/src/hb-buffer.cc b/thirdparty/harfbuzz/src/hb-buffer.cc index 57a5ae03ed..4b6c2d9eaa 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.cc +++ b/thirdparty/harfbuzz/src/hb-buffer.cc @@ -172,12 +172,13 @@ hb_buffer_t::enlarge (unsigned int size) while (size >= new_allocated) new_allocated += (new_allocated >> 1) + 32; - static_assert ((sizeof (info[0]) == sizeof (pos[0])), ""); - if (unlikely (hb_unsigned_mul_overflows (new_allocated, sizeof (info[0])))) + unsigned new_bytes; + if (unlikely (hb_unsigned_mul_overflows (new_allocated, sizeof (info[0]), &new_bytes))) goto done; - new_pos = (hb_glyph_position_t *) hb_realloc (pos, new_allocated * sizeof (pos[0])); - new_info = (hb_glyph_info_t *) hb_realloc (info, new_allocated * sizeof (info[0])); + static_assert (sizeof (info[0]) == sizeof (pos[0]), ""); + new_pos = (hb_glyph_position_t *) hb_realloc (pos, new_bytes); + new_info = (hb_glyph_info_t *) hb_realloc (info, new_bytes); done: if (unlikely (!new_pos || !new_info)) @@ -208,7 +209,7 @@ hb_buffer_t::make_room_for (unsigned int num_in, assert (have_output); out_info = (hb_glyph_info_t *) pos; - memcpy (out_info, info, out_len * sizeof (out_info[0])); + hb_memcpy (out_info, info, out_len * sizeof (out_info[0])); } return true; @@ -229,7 +230,7 @@ hb_buffer_t::shift_forward (unsigned int count) * Ideally, we should at least set Default_Ignorable bits on * these, as well as consistent cluster values. But the former * is layering violation... */ - memset (info + len, 0, (idx + count - len) * sizeof (info[0])); + hb_memset (info + len, 0, (idx + count - len) * sizeof (info[0])); } len += count; idx += count; @@ -298,8 +299,8 @@ hb_buffer_t::clear () out_len = 0; out_info = info; - memset (context, 0, sizeof context); - memset (context_len, 0, sizeof context_len); + hb_memset (context, 0, sizeof context); + hb_memset (context_len, 0, sizeof context_len); deallocate_var_all (); serial = 0; @@ -313,15 +314,14 @@ hb_buffer_t::enter () serial = 0; shaping_failed = false; scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; - if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR))) + unsigned mul; + if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR, &mul))) { - max_len = hb_max (len * HB_BUFFER_MAX_LEN_FACTOR, - (unsigned) HB_BUFFER_MAX_LEN_MIN); + max_len = hb_max (mul, (unsigned) HB_BUFFER_MAX_LEN_MIN); } - if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_OPS_FACTOR))) + if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_OPS_FACTOR, &mul))) { - max_ops = hb_max (len * HB_BUFFER_MAX_OPS_FACTOR, - (unsigned) HB_BUFFER_MAX_OPS_MIN); + max_ops = hb_max (mul, (unsigned) HB_BUFFER_MAX_OPS_MIN); } } void @@ -345,7 +345,7 @@ hb_buffer_t::add (hb_codepoint_t codepoint, glyph = &info[len]; - memset (glyph, 0, sizeof (*glyph)); + hb_memset (glyph, 0, sizeof (*glyph)); glyph->codepoint = codepoint; glyph->mask = 0; glyph->cluster = cluster; @@ -606,6 +606,53 @@ done: } void +hb_buffer_t::delete_glyphs_inplace (bool (*filter) (const hb_glyph_info_t *info)) +{ + /* Merge clusters and delete filtered glyphs. + * NOTE! We can't use out-buffer as we have positioning data. */ + unsigned int j = 0; + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + { + if (filter (&info[i])) + { + /* Merge clusters. + * Same logic as delete_glyph(), but for in-place removal. */ + + unsigned int cluster = info[i].cluster; + if (i + 1 < count && cluster == info[i + 1].cluster) + continue; /* Cluster survives; do nothing. */ + + if (j) + { + /* Merge cluster backward. */ + if (cluster < info[j - 1].cluster) + { + unsigned int mask = info[i].mask; + unsigned int old_cluster = info[j - 1].cluster; + for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--) + set_cluster (info[k - 1], cluster, mask); + } + continue; + } + + if (i + 1 < count) + merge_clusters (i, i + 2); /* Merge cluster forward. */ + + continue; + } + + if (j != i) + { + info[j] = info[i]; + pos[j] = pos[i]; + } + j++; + } + len = j; +} + +void hb_buffer_t::guess_segment_properties () { assert_unicode (); @@ -933,7 +980,6 @@ hb_buffer_get_unicode_funcs (const hb_buffer_t *buffer) void hb_buffer_set_direction (hb_buffer_t *buffer, hb_direction_t direction) - { if (unlikely (hb_object_is_immutable (buffer))) return; @@ -1385,9 +1431,9 @@ hb_buffer_set_length (hb_buffer_t *buffer, /* Wipe the new space */ if (length > buffer->len) { - memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len)); + hb_memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len)); if (buffer->have_positions) - memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len)); + hb_memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len)); } buffer->len = length; @@ -1795,7 +1841,9 @@ hb_buffer_add_latin1 (hb_buffer_t *buffer, * marks at stat of run. * * This function does not check the validity of @text, it is up to the caller - * to ensure it contains a valid Unicode code points. + * to ensure it contains a valid Unicode scalar values. In contrast, + * hb_buffer_add_utf32() can be used that takes similar input but performs + * sanity-check on the input. * * Since: 0.9.31 **/ @@ -1858,9 +1906,9 @@ hb_buffer_append (hb_buffer_t *buffer, hb_segment_properties_overlay (&buffer->props, &source->props); - memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0])); + hb_memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0])); if (buffer->have_positions) - memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0])); + hb_memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0])); if (source->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) { @@ -2048,7 +2096,7 @@ hb_buffer_diff (hb_buffer_t *buffer, result |= HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH; if (buf_info->cluster != ref_info->cluster) result |= HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH; - if ((buf_info->mask & ~ref_info->mask & HB_GLYPH_FLAG_DEFINED)) + if ((buf_info->mask ^ ref_info->mask) & HB_GLYPH_FLAG_DEFINED) result |= HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH; if (contains && ref_info->codepoint == dottedcircle_glyph) result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT; @@ -2103,6 +2151,13 @@ hb_buffer_set_message_func (hb_buffer_t *buffer, hb_buffer_message_func_t func, void *user_data, hb_destroy_func_t destroy) { + if (unlikely (hb_object_is_immutable (buffer))) + { + if (destroy) + destroy (user_data); + return; + } + if (buffer->message_destroy) buffer->message_destroy (buffer->message_data); diff --git a/thirdparty/harfbuzz/src/hb-buffer.hh b/thirdparty/harfbuzz/src/hb-buffer.hh index 26c3f0fac8..bb1efe9dd3 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.hh +++ b/thirdparty/harfbuzz/src/hb-buffer.hh @@ -32,6 +32,7 @@ #include "hb.hh" #include "hb-unicode.hh" +#include "hb-set-digest.hh" #ifndef HB_BUFFER_MAX_LEN_FACTOR @@ -207,6 +208,14 @@ struct hb_buffer_t hb_glyph_info_t &prev () { return out_info[out_len ? out_len - 1 : 0]; } hb_glyph_info_t prev () const { return out_info[out_len ? out_len - 1 : 0]; } + hb_set_digest_t digest () const + { + hb_set_digest_t d; + d.init (); + d.add_array (&info[0].codepoint, len, sizeof (info[0])); + return d; + } + HB_INTERNAL void similar (const hb_buffer_t &src); HB_INTERNAL void reset (); HB_INTERNAL void clear (); @@ -402,6 +411,8 @@ struct hb_buffer_t HB_INTERNAL void merge_out_clusters (unsigned int start, unsigned int end); /* Merge clusters for deleting current glyph, and skip it. */ HB_INTERNAL void delete_glyph (); + HB_INTERNAL void delete_glyphs_inplace (bool (*filter) (const hb_glyph_info_t *info)); + /* Adds glyph flags in mask to infos with clusters between start and end. diff --git a/thirdparty/harfbuzz/src/hb-cache.hh b/thirdparty/harfbuzz/src/hb-cache.hh index 897f313fbd..f8c8108f1f 100644 --- a/thirdparty/harfbuzz/src/hb-cache.hh +++ b/thirdparty/harfbuzz/src/hb-cache.hh @@ -46,7 +46,7 @@ struct hb_cache_t >::type; static_assert ((key_bits >= cache_bits), ""); - static_assert ((key_bits + value_bits - cache_bits <= 8 * sizeof (item_t)), ""); + static_assert ((key_bits + value_bits <= cache_bits + 8 * sizeof (item_t)), ""); void init () { clear (); } void fini () {} diff --git a/thirdparty/harfbuzz/src/hb-cff-interp-common.hh b/thirdparty/harfbuzz/src/hb-cff-interp-common.hh index 5c2cb060a4..49805a89c5 100644 --- a/thirdparty/harfbuzz/src/hb-cff-interp-common.hh +++ b/thirdparty/harfbuzz/src/hb-cff-interp-common.hh @@ -284,65 +284,56 @@ struct UnsizedByteStr : UnsizedArrayOf <HBUINT8> /* A byte string associated with the current offset and an error condition */ struct byte_str_ref_t { - byte_str_ref_t () { init (); } - - void init () - { - str = hb_ubytes_t (); - offset = 0; - error = false; - } - - void fini () {} + byte_str_ref_t () + : str () {} byte_str_ref_t (const hb_ubytes_t &str_, unsigned int offset_ = 0) - : str (str_), offset (offset_), error (false) {} + : str (str_) { set_offset (offset_); } void reset (const hb_ubytes_t &str_, unsigned int offset_ = 0) { str = str_; - offset = offset_; - error = false; + set_offset (offset_); } const unsigned char& operator [] (int i) { - if (unlikely ((unsigned int) (offset + i) >= str.length)) + if (unlikely ((unsigned int) (get_offset () + i) >= str.length)) { set_error (); return Null (unsigned char); } - return str[offset + i]; + return str.arrayZ[get_offset () + i]; } + unsigned char head_unchecked () const { return str.arrayZ[get_offset ()]; } + /* Conversion to hb_ubytes_t */ - operator hb_ubytes_t () const { return str.sub_array (offset, str.length - offset); } + operator hb_ubytes_t () const { return str.sub_array (get_offset ()); } hb_ubytes_t sub_array (unsigned int offset_, unsigned int len_) const { return str.sub_array (offset_, len_); } bool avail (unsigned int count=1) const - { return (!in_error () && offset + count <= str.length); } + { return get_offset () + count <= str.length; } void inc (unsigned int count=1) { - if (likely (!in_error () && (offset <= str.length) && (offset + count <= str.length))) - { - offset += count; - } - else - { - offset = str.length; - set_error (); - } + /* Automatically puts us in error if count is out-of-range. */ + set_offset (get_offset () + count); } - void set_error () { error = true; } - bool in_error () const { return error; } + /* We (ab)use ubytes backwards_length as a cursor (called offset), + * as well as to store error condition. */ - hb_ubytes_t str; - unsigned int offset; /* beginning of the sub-string within str */ + unsigned get_offset () const { return str.backwards_length; } + void set_offset (unsigned offset) { str.backwards_length = offset; } + + void set_error () { str.backwards_length = str.length + 1; } + bool in_error () const { return str.backwards_length > str.length; } + + unsigned total_size () const { return str.length; } protected: - bool error; + hb_ubytes_t str; }; using byte_str_array_t = hb_vector_t<hb_ubytes_t>; @@ -491,8 +482,15 @@ struct arg_stack_t : cff_stack_t<ARG, 513> /* an operator prefixed by its operands in a byte string */ struct op_str_t { - hb_ubytes_t str; + /* This used to have a hb_ubytes_t. Using a pointer and length + * in a particular order, saves 8 bytes in this struct and more + * in our parsed_cs_op_t subclass. */ + + const unsigned char *ptr = nullptr; + op_code_t op; + + uint8_t length = 0; }; /* base of OP_SERIALIZER */ @@ -503,9 +501,11 @@ struct op_serializer_t { TRACE_SERIALIZE (this); - HBUINT8 *d = c->allocate_size<HBUINT8> (opstr.str.length); + unsigned char *d = c->allocate_size<unsigned char> (opstr.length); if (unlikely (!d)) return_trace (false); - memcpy (d, &opstr.str[0], opstr.str.length); + /* Faster than hb_memcpy for small strings. */ + for (unsigned i = 0; i < opstr.length; i++) + d[i] = opstr.ptr[i]; return_trace (true); } }; @@ -529,16 +529,20 @@ struct parsed_values_t { VAL *val = values.push (); val->op = op; - val->str = str_ref.str.sub_array (opStart, str_ref.offset - opStart); - opStart = str_ref.offset; + auto arr = str_ref.sub_array (opStart, str_ref.get_offset () - opStart); + val->ptr = arr.arrayZ; + val->length = arr.length; + opStart = str_ref.get_offset (); } void add_op (op_code_t op, const byte_str_ref_t& str_ref, const VAL &v) { VAL *val = values.push (v); val->op = op; - val->str = str_ref.sub_array ( opStart, str_ref.offset - opStart); - opStart = str_ref.offset; + auto arr = str_ref.sub_array (opStart, str_ref.get_offset () - opStart); + val->ptr = arr.arrayZ; + val->length = arr.length; + opStart = str_ref.get_offset (); } bool has_op (op_code_t op) const @@ -549,8 +553,7 @@ struct parsed_values_t } unsigned get_count () const { return values.length; } - const VAL &get_value (unsigned int i) const { return values[i]; } - const VAL &operator [] (unsigned int i) const { return get_value (i); } + const VAL &operator [] (unsigned int i) const { return values[i]; } unsigned int opStart; hb_vector_t<VAL> values; @@ -565,23 +568,23 @@ struct interp_env_t str_ref.reset (str_); } bool in_error () const - { return error || str_ref.in_error () || argStack.in_error (); } + { return str_ref.in_error () || argStack.in_error (); } - void set_error () { error = true; } + void set_error () { str_ref.set_error (); } op_code_t fetch_op () { op_code_t op = OpCode_Invalid; if (unlikely (!str_ref.avail ())) return OpCode_Invalid; - op = (op_code_t)(unsigned char)str_ref[0]; + op = (op_code_t) str_ref.head_unchecked (); + str_ref.inc (); if (op == OpCode_escape) { if (unlikely (!str_ref.avail ())) return OpCode_Invalid; - op = Make_OpCode_ESC(str_ref[1]); + op = Make_OpCode_ESC (str_ref.head_unchecked ()); str_ref.inc (); } - str_ref.inc (); return op; } @@ -596,8 +599,6 @@ struct interp_env_t str_ref; arg_stack_t<ARG> argStack; - protected: - bool error = false; }; using num_interp_env_t = interp_env_t<>; diff --git a/thirdparty/harfbuzz/src/hb-cff2-interp-cs.hh b/thirdparty/harfbuzz/src/hb-cff2-interp-cs.hh index d0b9e7b086..00c25800e6 100644 --- a/thirdparty/harfbuzz/src/hb-cff2-interp-cs.hh +++ b/thirdparty/harfbuzz/src/hb-cff2-interp-cs.hh @@ -40,13 +40,15 @@ struct blend_arg_t : number_t void set_real (double v) { reset_blends (); number_t::set_real (v); } void set_blends (unsigned int numValues_, unsigned int valueIndex_, - unsigned int numBlends, hb_array_t<const blend_arg_t> blends_) + hb_array_t<const blend_arg_t> blends_) { numValues = numValues_; valueIndex = valueIndex_; - deltas.resize (numBlends); + unsigned numBlends = blends_.length; + if (unlikely (!deltas.resize (numBlends))) + return; for (unsigned int i = 0; i < numBlends; i++) - deltas[i] = blends_[i]; + deltas.arrayZ[i] = blends_.arrayZ[i]; } bool blending () const { return deltas.length > 0; } @@ -61,7 +63,6 @@ struct blend_arg_t : number_t hb_vector_t<number_t> deltas; }; -typedef interp_env_t<blend_arg_t> BlendInterpEnv; typedef biased_subrs_t<CFF2Subrs> cff2_biased_subrs_t; template <typename ELEM> @@ -154,8 +155,9 @@ struct cff2_cs_interp_env_t : cs_interp_env_t<ELEM, CFF2Subrs> { if (likely (scalars.length == deltas.length)) { - for (unsigned int i = 0; i < scalars.length; i++) - v += (double) scalars[i] * deltas[i].to_real (); + unsigned count = scalars.length; + for (unsigned i = 0; i < count; i++) + v += (double) scalars.arrayZ[i] * deltas.arrayZ[i].to_real (); } } return v; @@ -220,7 +222,7 @@ struct cff2_cs_opset_t : cs_opset_t<ELEM, OPSET, cff2_cs_interp_env_t<ELEM>, PAR const hb_array_t<const ELEM> blends, unsigned n, unsigned i) { - arg.set_blends (n, i, blends.length, blends); + arg.set_blends (n, i, blends); } template <typename T = ELEM, hb_enable_if (!hb_is_same (T, blend_arg_t))> diff --git a/thirdparty/harfbuzz/src/hb-common.cc b/thirdparty/harfbuzz/src/hb-common.cc index bbb6cd552b..e9f9cfeb5f 100644 --- a/thirdparty/harfbuzz/src/hb-common.cc +++ b/thirdparty/harfbuzz/src/hb-common.cc @@ -285,7 +285,7 @@ struct hb_language_item_t { lang = (hb_language_t) hb_malloc(len); if (likely (lang)) { - memcpy((unsigned char *) lang, s, len); + hb_memcpy((unsigned char *) lang, s, len); for (unsigned char *p = (unsigned char *) lang; *p; p++) *p = canon_map[*p]; } @@ -379,7 +379,7 @@ hb_language_from_string (const char *str, int len) /* NUL-terminate it. */ char strbuf[64]; len = hb_min (len, (int) sizeof (strbuf) - 1); - memcpy (strbuf, str, len); + hb_memcpy (strbuf, str, len); strbuf[len] = '\0'; item = lang_find_or_insert (strbuf); } @@ -976,7 +976,7 @@ hb_feature_from_string (const char *str, int len, } if (feature) - memset (feature, 0, sizeof (*feature)); + hb_memset (feature, 0, sizeof (*feature)); return false; } @@ -1025,7 +1025,7 @@ hb_feature_to_string (hb_feature_t *feature, } assert (len < ARRAY_LENGTH (s)); len = hb_min (len, size - 1); - memcpy (buf, s, len); + hb_memcpy (buf, s, len); buf[len] = '\0'; } @@ -1088,7 +1088,7 @@ hb_variation_from_string (const char *str, int len, } if (variation) - memset (variation, 0, sizeof (*variation)); + hb_memset (variation, 0, sizeof (*variation)); return false; } @@ -1136,7 +1136,7 @@ get_C_locale () /** * hb_variation_to_string: * @variation: an #hb_variation_t to convert - * @buf: (array length=size) (out): output string + * @buf: (array length=size) (out caller-allocates): output string * @size: the allocated size of @buf * * Converts an #hb_variation_t into a `NULL`-terminated string in the format @@ -1166,7 +1166,7 @@ hb_variation_to_string (hb_variation_t *variation, assert (len < ARRAY_LENGTH (s)); len = hb_min (len, size - 1); - memcpy (buf, s, len); + hb_memcpy (buf, s, len); buf[len] = '\0'; } diff --git a/thirdparty/harfbuzz/src/hb-config.hh b/thirdparty/harfbuzz/src/hb-config.hh index d56617f6a9..98b1e9d0cf 100644 --- a/thirdparty/harfbuzz/src/hb-config.hh +++ b/thirdparty/harfbuzz/src/hb-config.hh @@ -35,8 +35,9 @@ #include "config.h" #endif -#ifndef HB_BORING_EXPANSION -#define HB_NO_BORING_EXPANSION +#ifndef HB_EXPERIMENTAL_API +#define HB_NO_BEYOND_64K +#define HB_NO_VAR_COMPOSITES #endif #ifdef HB_TINY @@ -84,6 +85,7 @@ #define HB_NO_OT_SHAPE_FRACTIONS #define HB_NO_STYLE #define HB_NO_SUBSET_LAYOUT +#define HB_NO_VERTICAL #define HB_NO_VAR #endif @@ -104,7 +106,7 @@ #ifdef HB_NO_BORING_EXPANSION #define HB_NO_BEYOND_64K -#define HB_NO_VARIATIONS2 +#define HB_NO_AVAR2 #endif #ifdef HB_DISABLE_DEPRECATED @@ -113,6 +115,11 @@ #define HB_IF_NOT_DEPRECATED(x) x #endif +#ifdef HB_NO_SHAPER +#define HB_NO_OT_SHAPE +#define HB_NO_AAT_SHAPE +#endif + #ifdef HB_NO_AAT #define HB_NO_OT_NAME_LANGUAGE_AAT #define HB_NO_AAT_SHAPE @@ -159,6 +166,7 @@ #define HB_NO_OT_SHAPER_HEBREW_FALLBACK #define HB_NO_OT_SHAPER_THAI_FALLBACK #define HB_NO_OT_SHAPER_VOWEL_CONSTRAINTS +#define HB_NO_OT_SHAPER_MYANMAR_ZAWGYI #endif #ifdef NDEBUG diff --git a/thirdparty/harfbuzz/src/hb-coretext.cc b/thirdparty/harfbuzz/src/hb-coretext.cc index 99b33c001e..4267e0e13e 100644 --- a/thirdparty/harfbuzz/src/hb-coretext.cc +++ b/thirdparty/harfbuzz/src/hb-coretext.cc @@ -347,10 +347,13 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) hb_ot_var_axis_info_t info; unsigned int c = 1; hb_ot_var_get_axis_infos (font->face, i, &c, &info); - CFDictionarySetValue (variations, - CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &info.tag), - CFNumberCreate (kCFAllocatorDefault, kCFNumberFloatType, &font->design_coords[i]) - ); + float v = hb_clamp (font->design_coords[i], info.min_value, info.max_value); + + CFNumberRef tag_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &info.tag); + CFNumberRef value_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberFloatType, &v); + CFDictionarySetValue (variations, tag_number, value_number); + CFRelease (tag_number); + CFRelease (value_number); } CFDictionaryRef attributes = @@ -648,7 +651,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, } else { active_feature_t *feature = active_features.lsearch (event->feature); if (feature) - active_features.remove (feature - active_features.arrayZ); + active_features.remove_ordered (feature - active_features.arrayZ); } } } diff --git a/thirdparty/harfbuzz/src/hb-draw.cc b/thirdparty/harfbuzz/src/hb-draw.cc index 46797e64e6..72c203f24f 100644 --- a/thirdparty/harfbuzz/src/hb-draw.cc +++ b/thirdparty/harfbuzz/src/hb-draw.cc @@ -80,6 +80,56 @@ hb_draw_close_path_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UN void *user_data HB_UNUSED) {} +static bool +_hb_draw_funcs_set_preamble (hb_draw_funcs_t *dfuncs, + bool func_is_null, + void **user_data, + hb_destroy_func_t *destroy) +{ + if (hb_object_is_immutable (dfuncs)) + { + if (*destroy) + (*destroy) (*user_data); + return false; + } + + if (func_is_null) + { + if (*destroy) + (*destroy) (*user_data); + *destroy = nullptr; + *user_data = nullptr; + } + + return true; +} + +static bool +_hb_draw_funcs_set_middle (hb_draw_funcs_t *dfuncs, + void *user_data, + hb_destroy_func_t destroy) +{ + if (user_data && !dfuncs->user_data) + { + dfuncs->user_data = (decltype (dfuncs->user_data)) hb_calloc (1, sizeof (*dfuncs->user_data)); + if (unlikely (!dfuncs->user_data)) + goto fail; + } + if (destroy && !dfuncs->destroy) + { + dfuncs->destroy = (decltype (dfuncs->destroy)) hb_calloc (1, sizeof (*dfuncs->destroy)); + if (unlikely (!dfuncs->destroy)) + goto fail; + } + + return true; + +fail: + if (destroy) + (destroy) (user_data); + return false; +} + #define HB_DRAW_FUNC_IMPLEMENT(name) \ \ void \ @@ -88,43 +138,24 @@ hb_draw_funcs_set_##name##_func (hb_draw_funcs_t *dfuncs, \ void *user_data, \ hb_destroy_func_t destroy) \ { \ - if (hb_object_is_immutable (dfuncs)) \ - return; \ + if (!_hb_draw_funcs_set_preamble (dfuncs, !func, &user_data, &destroy))\ + return; \ \ if (dfuncs->destroy && dfuncs->destroy->name) \ dfuncs->destroy->name (!dfuncs->user_data ? nullptr : dfuncs->user_data->name); \ \ - if (user_data && !dfuncs->user_data) \ - { \ - dfuncs->user_data = (decltype (dfuncs->user_data)) hb_calloc (1, sizeof (*dfuncs->user_data)); \ - if (unlikely (!dfuncs->user_data)) \ - goto fail; \ - } \ - if (destroy && !dfuncs->destroy) \ - { \ - dfuncs->destroy = (decltype (dfuncs->destroy)) hb_calloc (1, sizeof (*dfuncs->destroy)); \ - if (unlikely (!dfuncs->destroy)) \ - goto fail; \ - } \ + if (!_hb_draw_funcs_set_middle (dfuncs, user_data, destroy)) \ + return; \ \ - if (func) { \ + if (func) \ dfuncs->func.name = func; \ - if (dfuncs->user_data) \ - dfuncs->user_data->name = user_data; \ - if (dfuncs->destroy) \ - dfuncs->destroy->name = destroy; \ - } else { \ + else \ dfuncs->func.name = hb_draw_##name##_nil; \ - if (dfuncs->user_data) \ - dfuncs->user_data->name = nullptr; \ - if (dfuncs->destroy) \ - dfuncs->destroy->name = nullptr; \ - } \ - return; \ - \ -fail: \ - if (destroy) \ - destroy (user_data); \ + \ + if (dfuncs->user_data) \ + dfuncs->user_data->name = user_data; \ + if (dfuncs->destroy) \ + dfuncs->destroy->name = destroy; \ } HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS diff --git a/thirdparty/harfbuzz/src/hb-face.cc b/thirdparty/harfbuzz/src/hb-face.cc index e7deb31dd8..8b4b635c7a 100644 --- a/thirdparty/harfbuzz/src/hb-face.cc +++ b/thirdparty/harfbuzz/src/hb-face.cc @@ -288,6 +288,7 @@ hb_face_destroy (hb_face_t *face) { if (!hb_object_destroy (face)) return; +#ifndef HB_NO_SHAPER for (hb_face_t::plan_node_t *node = face->shape_plans; node; ) { hb_face_t::plan_node_t *next = node->next; @@ -295,6 +296,7 @@ hb_face_destroy (hb_face_t *face) hb_free (node); node = next; } +#endif face->data.fini (); face->table.fini (); @@ -636,7 +638,7 @@ hb_face_collect_variation_unicodes (hb_face_t *face, struct face_table_info_t { hb_blob_t* data; - unsigned order; + signed order; }; struct hb_face_builder_data_t @@ -784,16 +786,16 @@ hb_face_builder_create () hb_bool_t hb_face_builder_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob) { - if (tag == HB_MAP_VALUE_INVALID) + if (unlikely (face->destroy != (hb_destroy_func_t) _hb_face_builder_data_destroy)) return false; - if (unlikely (face->destroy != (hb_destroy_func_t) _hb_face_builder_data_destroy)) + if (tag == HB_MAP_VALUE_INVALID) return false; hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data; hb_blob_t* previous = data->tables.get (tag).data; - if (!data->tables.set (tag, face_table_info_t {hb_blob_reference (blob), 0})) + if (!data->tables.set (tag, face_table_info_t {hb_blob_reference (blob), -1})) { hb_blob_destroy (blob); return false; @@ -819,13 +821,16 @@ void hb_face_builder_sort_tables (hb_face_t *face, const hb_tag_t *tags) { + if (unlikely (face->destroy != (hb_destroy_func_t) _hb_face_builder_data_destroy)) + return; + hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data; // Sort all unspecified tables after any specified tables. for (auto& info : data->tables.values_ref()) - info.order = -1; + info.order = (unsigned) -1; - unsigned order = 0; + signed order = 0; for (const hb_tag_t* tag = tags; *tag; tag++) diff --git a/thirdparty/harfbuzz/src/hb-face.hh b/thirdparty/harfbuzz/src/hb-face.hh index 12e10d01e0..1bf0606e52 100644 --- a/thirdparty/harfbuzz/src/hb-face.hh +++ b/thirdparty/harfbuzz/src/hb-face.hh @@ -65,7 +65,9 @@ struct hb_face_t hb_shape_plan_t *shape_plan; plan_node_t *next; }; +#ifndef HB_NO_SHAPER hb_atomic_ptr_t<plan_node_t> shape_plans; +#endif hb_blob_t *reference_table (hb_tag_t tag) const { diff --git a/thirdparty/harfbuzz/src/hb-fallback-shape.cc b/thirdparty/harfbuzz/src/hb-fallback-shape.cc index f8524ecc8e..c54ad8764b 100644 --- a/thirdparty/harfbuzz/src/hb-fallback-shape.cc +++ b/thirdparty/harfbuzz/src/hb-fallback-shape.cc @@ -75,16 +75,6 @@ _hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED, const hb_feature_t *features HB_UNUSED, unsigned int num_features HB_UNUSED) { - /* TODO - * - * - Apply fallback kern. - * - Handle Variation Selectors? - * - Apply normalization? - * - * This will make the fallback shaper into a dumb "TrueType" - * shaper which many people unfortunately still request. - */ - hb_codepoint_t space; bool has_space = (bool) font->get_nominal_glyph (' ', &space); diff --git a/thirdparty/harfbuzz/src/hb-font.cc b/thirdparty/harfbuzz/src/hb-font.cc index 856bbdda32..0ce3e2608a 100644 --- a/thirdparty/harfbuzz/src/hb-font.cc +++ b/thirdparty/harfbuzz/src/hb-font.cc @@ -71,7 +71,7 @@ hb_font_get_font_h_extents_nil (hb_font_t *font HB_UNUSED, hb_font_extents_t *extents, void *user_data HB_UNUSED) { - memset (extents, 0, sizeof (*extents)); + hb_memset (extents, 0, sizeof (*extents)); return false; } @@ -96,7 +96,7 @@ hb_font_get_font_v_extents_nil (hb_font_t *font HB_UNUSED, hb_font_extents_t *extents, void *user_data HB_UNUSED) { - memset (extents, 0, sizeof (*extents)); + hb_memset (extents, 0, sizeof (*extents)); return false; } @@ -409,7 +409,7 @@ hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED, hb_glyph_extents_t *extents, void *user_data HB_UNUSED) { - memset (extents, 0, sizeof (*extents)); + hb_memset (extents, 0, sizeof (*extents)); return false; } @@ -518,6 +518,7 @@ typedef struct hb_font_get_glyph_shape_default_adaptor_t { void *draw_data; float x_scale; float y_scale; + float slant; } hb_font_get_glyph_shape_default_adaptor_t; static void @@ -530,9 +531,10 @@ hb_draw_move_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; + float slant = adaptor->slant; adaptor->draw_funcs->emit_move_to (adaptor->draw_data, *st, - x_scale * to_x, y_scale * to_y); + x_scale * to_x + slant * to_y, y_scale * to_y); } static void @@ -544,12 +546,13 @@ hb_draw_line_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data, hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; + float slant = adaptor->slant; - st->current_x *= x_scale; - st->current_y *= y_scale; + st->current_x = st->current_x * x_scale + st->current_y * slant; + st->current_y = st->current_y * y_scale; adaptor->draw_funcs->emit_line_to (adaptor->draw_data, *st, - x_scale * to_x, y_scale * to_y); + x_scale * to_x + slant * to_y, y_scale * to_y); } static void @@ -562,13 +565,14 @@ hb_draw_quadratic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; + float slant = adaptor->slant; - st->current_x *= x_scale; - st->current_y *= y_scale; + st->current_x = st->current_x * x_scale + st->current_y * slant; + st->current_y = st->current_y * y_scale; adaptor->draw_funcs->emit_quadratic_to (adaptor->draw_data, *st, - x_scale * control_x, y_scale * control_y, - x_scale * to_x, y_scale * to_y); + x_scale * control_x + slant * control_y, y_scale * control_y, + x_scale * to_x + slant * to_y, y_scale * to_y); } static void @@ -582,14 +586,15 @@ hb_draw_cubic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data, hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; + float slant = adaptor->slant; - st->current_x *= x_scale; - st->current_y *= y_scale; + st->current_x = st->current_x * x_scale + st->current_y * slant; + st->current_y = st->current_y * y_scale; adaptor->draw_funcs->emit_cubic_to (adaptor->draw_data, *st, - x_scale * control1_x, y_scale * control1_y, - x_scale * control2_x, y_scale * control2_y, - x_scale * to_x, y_scale * to_y); + x_scale * control1_x + slant * control1_y, y_scale * control1_y, + x_scale * control2_x + slant * control2_y, y_scale * control2_y, + x_scale * to_x + slant * to_y, y_scale * to_y); } static void @@ -623,8 +628,10 @@ hb_font_get_glyph_shape_default (hb_font_t *font, hb_font_get_glyph_shape_default_adaptor_t adaptor = { draw_funcs, draw_data, - (float) font->x_scale / (float) font->parent->x_scale, - (float) font->y_scale / (float) font->parent->y_scale + font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f, + font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f, + font->parent->y_scale ? (font->slant - font->parent->slant) * + (float) font->x_scale / (float) font->parent->y_scale : 0.f }; font->parent->get_glyph_shape (glyph, @@ -822,6 +829,56 @@ hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs) } +static bool +_hb_font_funcs_set_preamble (hb_font_funcs_t *ffuncs, + bool func_is_null, + void **user_data, + hb_destroy_func_t *destroy) +{ + if (hb_object_is_immutable (ffuncs)) + { + if (*destroy) + (*destroy) (*user_data); + return false; + } + + if (func_is_null) + { + if (*destroy) + (*destroy) (*user_data); + *destroy = nullptr; + *user_data = nullptr; + } + + return true; +} + +static bool +_hb_font_funcs_set_middle (hb_font_funcs_t *ffuncs, + void *user_data, + hb_destroy_func_t destroy) +{ + if (user_data && !ffuncs->user_data) + { + ffuncs->user_data = (decltype (ffuncs->user_data)) hb_calloc (1, sizeof (*ffuncs->user_data)); + if (unlikely (!ffuncs->user_data)) + goto fail; + } + if (destroy && !ffuncs->destroy) + { + ffuncs->destroy = (decltype (ffuncs->destroy)) hb_calloc (1, sizeof (*ffuncs->destroy)); + if (unlikely (!ffuncs->destroy)) + goto fail; + } + + return true; + +fail: + if (destroy) + (destroy) (user_data); + return false; +} + #define HB_FONT_FUNC_IMPLEMENT(name) \ \ void \ @@ -830,51 +887,24 @@ hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \ void *user_data, \ hb_destroy_func_t destroy) \ { \ - if (hb_object_is_immutable (ffuncs)) \ - goto fail; \ - \ - if (!func) \ - { \ - if (destroy) \ - destroy (user_data); \ - destroy = nullptr; \ - user_data = nullptr; \ - } \ + if (!_hb_font_funcs_set_preamble (ffuncs, !func, &user_data, &destroy))\ + return; \ \ if (ffuncs->destroy && ffuncs->destroy->name) \ ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name); \ \ - if (user_data && !ffuncs->user_data) \ - { \ - ffuncs->user_data = (decltype (ffuncs->user_data)) hb_calloc (1, sizeof (*ffuncs->user_data)); \ - if (unlikely (!ffuncs->user_data)) \ - goto fail; \ - } \ - if (destroy && !ffuncs->destroy) \ - { \ - ffuncs->destroy = (decltype (ffuncs->destroy)) hb_calloc (1, sizeof (*ffuncs->destroy)); \ - if (unlikely (!ffuncs->destroy)) \ - goto fail; \ - } \ + if (!_hb_font_funcs_set_middle (ffuncs, user_data, destroy)) \ + return; \ \ - if (func) { \ + if (func) \ ffuncs->get.f.name = func; \ - if (ffuncs->user_data) \ - ffuncs->user_data->name = user_data; \ - if (ffuncs->destroy) \ - ffuncs->destroy->name = destroy; \ - } else { \ + else \ ffuncs->get.f.name = hb_font_get_##name##_default; \ - if (ffuncs->user_data) \ - ffuncs->user_data->name = nullptr; \ - if (ffuncs->destroy) \ - ffuncs->destroy->name = nullptr; \ - } \ - return; \ - \ -fail: \ - if (destroy) \ - destroy (user_data); \ + \ + if (ffuncs->user_data) \ + ffuncs->user_data->name = user_data; \ + if (ffuncs->destroy) \ + ffuncs->destroy->name = destroy; \ } HB_FONT_FUNCS_IMPLEMENT_CALLBACKS @@ -1323,7 +1353,7 @@ hb_font_get_glyph_from_name (hb_font_t *font, * @draw_data: User data to pass to draw callbacks * * Fetches the glyph shape that corresponds to a glyph in the specified @font. - * The shape is returned by way of calls to the callsbacks of the @dfuncs + * The shape is returned by way of calls to the callbacks of the @dfuncs * objects, with @draw_data passed to them. * * Since: 4.0.0 @@ -1780,8 +1810,8 @@ hb_font_create_sub_font (hb_font_t *parent) float *design_coords = (float *) hb_calloc (num_coords, sizeof (parent->design_coords[0])); if (likely (coords && design_coords)) { - memcpy (coords, parent->coords, num_coords * sizeof (parent->coords[0])); - memcpy (design_coords, parent->design_coords, num_coords * sizeof (parent->design_coords[0])); + hb_memcpy (coords, parent->coords, num_coords * sizeof (parent->coords[0])); + hb_memcpy (design_coords, parent->design_coords, num_coords * sizeof (parent->design_coords[0])); _hb_font_adopt_var_coords (font, coords, design_coords, num_coords); } else @@ -2443,7 +2473,7 @@ hb_font_set_var_coords_design (hb_font_t *font, } if (coords_length) - memcpy (design_coords, coords, coords_length * sizeof (font->design_coords[0])); + hb_memcpy (design_coords, coords, coords_length * sizeof (font->design_coords[0])); hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized); _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length); @@ -2519,8 +2549,8 @@ hb_font_set_var_coords_normalized (hb_font_t *font, if (coords_length) { - memcpy (copy, coords, coords_length * sizeof (coords[0])); - memcpy (unmapped, coords, coords_length * sizeof (coords[0])); + hb_memcpy (copy, coords, coords_length * sizeof (coords[0])); + hb_memcpy (unmapped, coords, coords_length * sizeof (coords[0])); } /* Best effort design coords simulation */ diff --git a/thirdparty/harfbuzz/src/hb-font.hh b/thirdparty/harfbuzz/src/hb-font.hh index bb402e23eb..6942d99c70 100644 --- a/thirdparty/harfbuzz/src/hb-font.hh +++ b/thirdparty/harfbuzz/src/hb-font.hh @@ -206,14 +206,14 @@ struct hb_font_t hb_bool_t get_font_h_extents (hb_font_extents_t *extents) { - memset (extents, 0, sizeof (*extents)); + hb_memset (extents, 0, sizeof (*extents)); return klass->get.f.font_h_extents (this, user_data, extents, !klass->user_data ? nullptr : klass->user_data->font_h_extents); } hb_bool_t get_font_v_extents (hb_font_extents_t *extents) { - memset (extents, 0, sizeof (*extents)); + hb_memset (extents, 0, sizeof (*extents)); return klass->get.f.font_v_extents (this, user_data, extents, !klass->user_data ? nullptr : klass->user_data->font_v_extents); @@ -342,7 +342,7 @@ struct hb_font_t hb_bool_t get_glyph_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) { - memset (extents, 0, sizeof (*extents)); + hb_memset (extents, 0, sizeof (*extents)); return klass->get.f.glyph_extents (this, user_data, glyph, extents, diff --git a/thirdparty/harfbuzz/src/hb-ft.cc b/thirdparty/harfbuzz/src/hb-ft.cc index bcc1dd080f..3892dedc13 100644 --- a/thirdparty/harfbuzz/src/hb-ft.cc +++ b/thirdparty/harfbuzz/src/hb-ft.cc @@ -89,7 +89,7 @@ struct hb_ft_font_t bool unref; /* Whether to destroy ft_face when done. */ bool transform; /* Whether to apply FT_Face's transform. */ - mutable hb_mutex_t lock; + mutable hb_mutex_t lock; /* Protects members below. */ FT_Face ft_face; mutable unsigned cached_serial; mutable hb_ft_advance_cache_t advance_cache; @@ -732,16 +732,18 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED, static int _hb_ft_move_to (const FT_Vector *to, - hb_draw_session_t *drawing) + void *arg) { + hb_draw_session_t *drawing = (hb_draw_session_t *) arg; drawing->move_to (to->x, to->y); return FT_Err_Ok; } static int _hb_ft_line_to (const FT_Vector *to, - hb_draw_session_t *drawing) + void *arg) { + hb_draw_session_t *drawing = (hb_draw_session_t *) arg; drawing->line_to (to->x, to->y); return FT_Err_Ok; } @@ -749,8 +751,9 @@ _hb_ft_line_to (const FT_Vector *to, static int _hb_ft_conic_to (const FT_Vector *control, const FT_Vector *to, - hb_draw_session_t *drawing) + void *arg) { + hb_draw_session_t *drawing = (hb_draw_session_t *) arg; drawing->quadratic_to (control->x, control->y, to->x, to->y); return FT_Err_Ok; @@ -760,8 +763,9 @@ static int _hb_ft_cubic_to (const FT_Vector *control1, const FT_Vector *control2, const FT_Vector *to, - hb_draw_session_t *drawing) + void *arg) { + hb_draw_session_t *drawing = (hb_draw_session_t *) arg; drawing->cubic_to (control1->x, control1->y, control2->x, control2->y, to->x, to->y); @@ -787,10 +791,10 @@ hb_ft_get_glyph_shape (hb_font_t *font HB_UNUSED, return; const FT_Outline_Funcs outline_funcs = { - (FT_Outline_MoveToFunc) _hb_ft_move_to, - (FT_Outline_LineToFunc) _hb_ft_line_to, - (FT_Outline_ConicToFunc) _hb_ft_conic_to, - (FT_Outline_CubicToFunc) _hb_ft_cubic_to, + _hb_ft_move_to, + _hb_ft_line_to, + _hb_ft_conic_to, + _hb_ft_cubic_to, 0, /* shift */ 0, /* delta */ }; @@ -975,8 +979,9 @@ hb_ft_face_create_referenced (FT_Face ft_face) } static void -hb_ft_face_finalize (FT_Face ft_face) +hb_ft_face_finalize (void *arg) { + FT_Face ft_face = (FT_Face) arg; hb_face_destroy ((hb_face_t *) ft_face->generic.data); } @@ -1008,7 +1013,7 @@ hb_ft_face_create_cached (FT_Face ft_face) ft_face->generic.finalizer (ft_face); ft_face->generic.data = hb_ft_face_create (ft_face, nullptr); - ft_face->generic.finalizer = (FT_Generic_Finalizer) hb_ft_face_finalize; + ft_face->generic.finalizer = hb_ft_face_finalize; } return hb_face_reference ((hb_face_t *) ft_face->generic.data); @@ -1217,8 +1222,9 @@ get_ft_library () } static void -_release_blob (FT_Face ft_face) +_release_blob (void *arg) { + FT_Face ft_face = (FT_Face) arg; hb_blob_destroy ((hb_blob_t *) ft_face->generic.data); } @@ -1271,7 +1277,7 @@ hb_ft_font_set_funcs (hb_font_t *font) ft_face->generic.data = blob; - ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob; + ft_face->generic.finalizer = _release_blob; _hb_ft_font_set_funcs (font, ft_face, true); hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING); diff --git a/thirdparty/harfbuzz/src/hb-glib.cc b/thirdparty/harfbuzz/src/hb-glib.cc index 8ddc7ebad8..1da81696e7 100644 --- a/thirdparty/harfbuzz/src/hb-glib.cc +++ b/thirdparty/harfbuzz/src/hb-glib.cc @@ -129,32 +129,9 @@ hb_glib_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED, { #if GLIB_CHECK_VERSION(2,29,12) return g_unichar_compose (a, b, ab); +#else + return false; #endif - - /* We don't ifdef-out the fallback code such that compiler always - * sees it and makes sure it's compilable. */ - - gchar utf8[12]; - gchar *normalized; - int len; - hb_bool_t ret; - - len = g_unichar_to_utf8 (a, utf8); - len += g_unichar_to_utf8 (b, utf8 + len); - normalized = g_utf8_normalize (utf8, len, G_NORMALIZE_NFC); - len = g_utf8_strlen (normalized, -1); - if (unlikely (!len)) - return false; - - if (len == 1) { - *ab = g_utf8_get_char (normalized); - ret = true; - } else { - ret = false; - } - - g_free (normalized); - return ret; } static hb_bool_t @@ -166,55 +143,9 @@ hb_glib_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, { #if GLIB_CHECK_VERSION(2,29,12) return g_unichar_decompose (ab, a, b); +#else + return false; #endif - - /* We don't ifdef-out the fallback code such that compiler always - * sees it and makes sure it's compilable. */ - - gchar utf8[6]; - gchar *normalized; - int len; - hb_bool_t ret; - - len = g_unichar_to_utf8 (ab, utf8); - normalized = g_utf8_normalize (utf8, len, G_NORMALIZE_NFD); - len = g_utf8_strlen (normalized, -1); - if (unlikely (!len)) - return false; - - if (len == 1) { - *a = g_utf8_get_char (normalized); - *b = 0; - ret = *a != ab; - } else if (len == 2) { - *a = g_utf8_get_char (normalized); - *b = g_utf8_get_char (g_utf8_next_char (normalized)); - /* Here's the ugly part: if ab decomposes to a single character and - * that character decomposes again, we have to detect that and undo - * the second part :-(. */ - gchar *recomposed = g_utf8_normalize (normalized, -1, G_NORMALIZE_NFC); - hb_codepoint_t c = g_utf8_get_char (recomposed); - if (c != ab && c != *a) { - *a = c; - *b = 0; - } - g_free (recomposed); - ret = true; - } else { - /* If decomposed to more than two characters, take the last one, - * and recompose the rest to get the first component. */ - gchar *end = g_utf8_offset_to_pointer (normalized, len - 1); - gchar *recomposed; - *b = g_utf8_get_char (end); - recomposed = g_utf8_normalize (normalized, end - normalized, G_NORMALIZE_NFC); - /* We expect that recomposed has exactly one character now. */ - *a = g_utf8_get_char (recomposed); - g_free (recomposed); - ret = true; - } - - g_free (normalized); - return ret; } diff --git a/thirdparty/harfbuzz/src/hb-graphite2.cc b/thirdparty/harfbuzz/src/hb-graphite2.cc index 4d0e687c75..9e068f8d84 100644 --- a/thirdparty/harfbuzz/src/hb-graphite2.cc +++ b/thirdparty/harfbuzz/src/hb-graphite2.cc @@ -318,7 +318,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED, #undef ALLOCATE_ARRAY - memset (clusters, 0, sizeof (clusters[0]) * buffer->len); + hb_memset (clusters, 0, sizeof (clusters[0]) * buffer->len); hb_codepoint_t *pg = gids; clusters[0].cluster = buffer->info[0].cluster; diff --git a/thirdparty/harfbuzz/src/hb-iter.hh b/thirdparty/harfbuzz/src/hb-iter.hh index 1a3ab43de0..b57f37b132 100644 --- a/thirdparty/harfbuzz/src/hb-iter.hh +++ b/thirdparty/harfbuzz/src/hb-iter.hh @@ -73,8 +73,10 @@ struct hb_iter_t /* Operators. */ iter_t iter () const { return *thiz(); } iter_t operator + () const { return *thiz(); } - iter_t begin () const { return *thiz(); } - iter_t end () const { return thiz()->__end__ (); } + iter_t _begin () const { return *thiz(); } + iter_t begin () const { return _begin (); } + iter_t _end () const { return thiz()->__end__ (); } + iter_t end () const { return _end (); } explicit operator bool () const { return thiz()->__more__ (); } unsigned len () const { return thiz()->__len__ (); } /* The following can only be enabled if item_t is reference type. Otherwise @@ -118,7 +120,9 @@ struct hb_iter_t #define HB_ITER_USING(Name) \ using item_t = typename Name::item_t; \ + using Name::_begin; \ using Name::begin; \ + using Name::_end; \ using Name::end; \ using Name::get_item_size; \ using Name::is_iterator; \ @@ -377,7 +381,7 @@ struct hb_map_iter_t : void __forward__ (unsigned n) { it += n; } void __prev__ () { --it; } void __rewind__ (unsigned n) { it -= n; } - hb_map_iter_t __end__ () const { return hb_map_iter_t (it.end (), f); } + hb_map_iter_t __end__ () const { return hb_map_iter_t (it._end (), f); } bool operator != (const hb_map_iter_t& o) const { return it != o.it; } @@ -440,7 +444,7 @@ struct hb_filter_iter_t : bool __more__ () const { return bool (it); } void __next__ () { do ++it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); } void __prev__ () { do --it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); } - hb_filter_iter_t __end__ () const { return hb_filter_iter_t (it.end (), p, f); } + hb_filter_iter_t __end__ () const { return hb_filter_iter_t (it._end (), p, f); } bool operator != (const hb_filter_iter_t& o) const { return it != o.it; } @@ -553,7 +557,7 @@ struct hb_zip_iter_t : void __forward__ (unsigned n) { a += n; b += n; } void __prev__ () { --a; --b; } void __rewind__ (unsigned n) { a -= n; b -= n; } - hb_zip_iter_t __end__ () const { return hb_zip_iter_t (a.end (), b.end ()); } + hb_zip_iter_t __end__ () const { return hb_zip_iter_t (a._end (), b._end ()); } /* Note, we should stop if ANY of the iters reaches end. As such two compare * unequal if both items are unequal, NOT if either is unequal. */ bool operator != (const hb_zip_iter_t& o) const @@ -637,7 +641,7 @@ struct hb_concat_iter_t : } } - hb_concat_iter_t __end__ () const { return hb_concat_iter_t (a.end (), b.end ()); } + hb_concat_iter_t __end__ () const { return hb_concat_iter_t (a._end (), b._end ()); } bool operator != (const hb_concat_iter_t& o) const { return a != o.a diff --git a/thirdparty/harfbuzz/src/hb-machinery.hh b/thirdparty/harfbuzz/src/hb-machinery.hh index 2571f22e15..b555739cfb 100644 --- a/thirdparty/harfbuzz/src/hb-machinery.hh +++ b/thirdparty/harfbuzz/src/hb-machinery.hh @@ -136,6 +136,13 @@ static inline Type& StructAfter(TObject &X) /* * Lazy loaders. + * + * The lazy-loaders are thread-safe pointer-like objects that create their + * instead on-demand. They also support access to a "data" object that is + * necessary for creating their instance. The data object, if specified, + * is accessed via pointer math, located at a location before the position + * of the loader itself. This avoids having to store a pointer to data + * for every lazy-loader. Multiple lazy-loaders can access the same data. */ template <typename Data, unsigned int WheresData> @@ -228,7 +235,8 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> bool cmpexch (Stored *current, Stored *value) const { - /* This *must* be called when there are no other threads accessing. */ + /* This function can only be safely called directly if no + * other thread is accessing. */ return this->instance.cmpexch (current, value); } @@ -261,7 +269,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> hb_free (p); } -// private: + private: /* Must only have one pointer. */ hb_atomic_ptr_t<Stored *> instance; }; @@ -283,7 +291,7 @@ struct hb_table_lazy_loader_t : hb_lazy_loader_t<T, { auto c = hb_sanitize_context_t (); if (core) - c.set_num_glyphs (0); // So we don't recurse ad infinitum... + c.set_num_glyphs (0); // So we don't recurse ad infinitum, or doesn't need num_glyphs return c.reference_table<T> (face); } static void destroy (hb_blob_t *p) { hb_blob_destroy (p); } diff --git a/thirdparty/harfbuzz/src/hb-map.hh b/thirdparty/harfbuzz/src/hb-map.hh index 8302e3f8c7..bfb1b3f768 100644 --- a/thirdparty/harfbuzz/src/hb-map.hh +++ b/thirdparty/harfbuzz/src/hb-map.hh @@ -43,9 +43,9 @@ struct hb_hashmap_t hb_hashmap_t () { init (); } ~hb_hashmap_t () { fini (); } - hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { resize (population); hb_copy (o, *this); } + hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { resize (o.population); hb_copy (o, *this); } hb_hashmap_t (hb_hashmap_t&& o) : hb_hashmap_t () { hb_swap (*this, o); } - hb_hashmap_t& operator= (const hb_hashmap_t& o) { resize (population); hb_copy (o, *this); return *this; } + hb_hashmap_t& operator= (const hb_hashmap_t& o) { reset (); resize (o.population); hb_copy (o, *this); return *this; } hb_hashmap_t& operator= (hb_hashmap_t&& o) { hb_swap (*this, o); return *this; } hb_hashmap_t (std::initializer_list<hb_pair_t<K, V>> lst) : hb_hashmap_t () @@ -71,6 +71,11 @@ struct hb_hashmap_t uint32_t is_tombstone_ : 1; V value; + item_t () : key (), + hash (0), + is_used_ (false), is_tombstone_ (false), + value () {} + bool is_used () const { return is_used_; } void set_used (bool is_used) { is_used_ = is_used; } bool is_tombstone () const { return is_tombstone_; } @@ -88,17 +93,8 @@ struct hb_hashmap_t return minus_1; }; - void clear () - { - new (std::addressof (key)) K (); - new (std::addressof (value)) V (); - hash = 0; - is_used_ = false; - is_tombstone_ = false; - } - - bool operator == (const K &o) { return hb_deref (key) == hb_deref (o); } - bool operator == (const item_t &o) { return *this == o.key; } + bool operator == (const K &o) const { return hb_deref (key) == hb_deref (o); } + bool operator == (const item_t &o) const { return *this == o.key; } hb_pair_t<K, V> get_pair() const { return hb_pair_t<K, V> (key, value); } hb_pair_t<const K &, const V &> get_pair_ref() const { return hb_pair_t<const K &, const V &> (key, value); } @@ -107,8 +103,8 @@ struct hb_hashmap_t }; hb_object_header_t header; - bool successful; /* Allocations successful */ - unsigned int population; /* Not including tombstones. */ + unsigned int successful : 1; /* Allocations successful */ + unsigned int population : 31; /* Not including tombstones. */ unsigned int occupancy; /* Including tombstones. */ unsigned int mask; unsigned int prime; @@ -118,7 +114,10 @@ struct hb_hashmap_t { if (unlikely (!a.successful || !b.successful)) return; - hb_swap (a.population, b.population); + unsigned tmp = a.population; + a.population = b.population; + b.population = tmp; + //hb_swap (a.population, b.population); hb_swap (a.occupancy, b.occupancy); hb_swap (a.mask, b.mask); hb_swap (a.prime, b.prime); @@ -160,7 +159,9 @@ struct hb_hashmap_t { if (unlikely (!successful)) return false; - unsigned int power = hb_bit_storage (hb_max (population, new_population) * 2 + 8); + if (new_population != 0 && (new_population + new_population / 2) < mask) return true; + + unsigned int power = hb_bit_storage (hb_max ((unsigned) population, new_population) * 2 + 8); unsigned int new_size = 1u << power; item_t *new_items = (item_t *) hb_malloc ((size_t) new_size * sizeof (item_t)); if (unlikely (!new_items)) @@ -169,9 +170,9 @@ struct hb_hashmap_t return false; } for (auto &_ : hb_iter (new_items, new_size)) - _.clear (); + new (&_) item_t (); - unsigned int old_size = mask + 1; + unsigned int old_size = size (); item_t *old_items = items; /* Switch to new, empty, array. */ @@ -181,47 +182,82 @@ struct hb_hashmap_t items = new_items; /* Insert back old items. */ - if (old_items) - for (unsigned int i = 0; i < old_size; i++) + for (unsigned int i = 0; i < old_size; i++) + { + if (old_items[i].is_real ()) { - if (old_items[i].is_real ()) - { - set_with_hash (old_items[i].key, - old_items[i].hash, - std::move (old_items[i].value)); - } - old_items[i].~item_t (); + set_with_hash (std::move (old_items[i].key), + old_items[i].hash, + std::move (old_items[i].value)); } + old_items[i].~item_t (); + } hb_free (old_items); return true; } + template <typename KK, typename VV> + bool set_with_hash (KK&& key, uint32_t hash, VV&& value, bool is_delete=false) + { + if (unlikely (!successful)) return false; + if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false; + item_t &item = item_for_hash (key, hash); + + if (is_delete && !(item == key)) + return true; /* Trying to delete non-existent key. */ + + if (item.is_used ()) + { + occupancy--; + if (!item.is_tombstone ()) + population--; + } + + item.key = std::forward<KK> (key); + item.value = std::forward<VV> (value); + item.hash = hash; + item.set_used (true); + item.set_tombstone (is_delete); + + occupancy++; + if (!is_delete) + population++; + + return true; + } + + template <typename VV> + bool set (const K &key, VV&& value) { return set_with_hash (key, hb_hash (key), std::forward<VV> (value)); } template <typename VV> - bool set (K key, VV&& value) { return set_with_hash (key, hb_hash (key), std::forward<VV> (value)); } + bool set (K &&key, VV&& value) { return set_with_hash (std::move (key), hb_hash (key), std::forward<VV> (value)); } - const V& get (K key) const + const V& get_with_hash (const K &key, uint32_t hash) const + { + if (unlikely (!items)) return item_t::default_value (); + auto &item = item_for_hash (key, hash); + return item.is_real () && item == key ? item.value : item_t::default_value (); + } + const V& get (const K &key) const { if (unlikely (!items)) return item_t::default_value (); - unsigned int i = bucket_for (key); - return items[i].is_real () && items[i] == key ? items[i].value : item_t::default_value (); + return get_with_hash (key, hb_hash (key)); } - void del (K key) { set_with_hash (key, hb_hash (key), item_t::default_value (), true); } + void del (const K &key) { set_with_hash (key, hb_hash (key), item_t::default_value (), true); } /* Has interface. */ - typedef const V& value_t; - value_t operator [] (K k) const { return get (k); } + const V& operator [] (K k) const { return get (k); } template <typename VV=V> bool has (K key, VV **vp = nullptr) const { if (unlikely (!items)) return false; - unsigned int i = bucket_for (key); - if (items[i].is_real () && items[i] == key) + auto &item = item_for_hash (key, hb_hash (key)); + if (item.is_real () && item == key) { - if (vp) *vp = &items[i].value; + if (vp) *vp = std::addressof (item.value); return true; } else @@ -230,13 +266,18 @@ struct hb_hashmap_t /* Projection. */ V operator () (K k) const { return get (k); } + unsigned size () const { return mask ? mask + 1 : 0; } + void clear () { if (unlikely (!successful)) return; - if (items) - for (auto &_ : hb_iter (items, mask + 1)) - _.clear (); + for (auto &_ : hb_iter (items, size ())) + { + /* Reconstruct items. */ + _.~item_t (); + new (&_) item_t (); + } population = occupancy = 0; } @@ -246,11 +287,10 @@ struct hb_hashmap_t uint32_t hash () const { - uint32_t h = 0; - for (const auto &item : + hb_array (items, mask ? mask + 1 : 0) - | hb_filter (&item_t::is_real)) - h ^= item.total_hash (); - return h; + return + + iter_items () + | hb_reduce ([] (uint32_t h, const item_t &_) { return h ^ _.total_hash (); }, (uint32_t) 0u) + ; } bool is_equal (const hb_hashmap_t &other) const @@ -258,7 +298,7 @@ struct hb_hashmap_t if (population != other.population) return false; for (auto pair : iter ()) - if (get (pair.first) != pair.second) + if (other.get (pair.first) != pair.second) return false; return true; @@ -271,87 +311,54 @@ struct hb_hashmap_t /* * Iterator */ - auto iter () const HB_AUTO_RETURN + + auto iter_items () const HB_AUTO_RETURN ( - + hb_array (items, mask ? mask + 1 : 0) + + hb_iter (items, size ()) | hb_filter (&item_t::is_real) - | hb_map (&item_t::get_pair) ) auto iter_ref () const HB_AUTO_RETURN ( - + hb_array (items, mask ? mask + 1 : 0) - | hb_filter (&item_t::is_real) + + iter_items () | hb_map (&item_t::get_pair_ref) ) - auto keys () const HB_AUTO_RETURN + auto iter () const HB_AUTO_RETURN ( - + hb_array (items, mask ? mask + 1 : 0) - | hb_filter (&item_t::is_real) - | hb_map (&item_t::key) - | hb_map (hb_ridentity) + + iter_items () + | hb_map (&item_t::get_pair) ) auto keys_ref () const HB_AUTO_RETURN ( - + hb_array (items, mask ? mask + 1 : 0) - | hb_filter (&item_t::is_real) + + iter_items () | hb_map (&item_t::key) ) - auto values () const HB_AUTO_RETURN + auto keys () const HB_AUTO_RETURN ( - + hb_array (items, mask ? mask + 1 : 0) - | hb_filter (&item_t::is_real) - | hb_map (&item_t::value) + + keys_ref () | hb_map (hb_ridentity) ) auto values_ref () const HB_AUTO_RETURN ( - + hb_array (items, mask ? mask + 1 : 0) - | hb_filter (&item_t::is_real) + + iter_items () | hb_map (&item_t::value) ) + auto values () const HB_AUTO_RETURN + ( + + values_ref () + | hb_map (hb_ridentity) + ) /* Sink interface. */ hb_hashmap_t& operator << (const hb_pair_t<K, V>& v) { set (v.first, v.second); return *this; } - - protected: - - template <typename VV> - bool set_with_hash (K key, uint32_t hash, VV&& value, bool is_delete=false) - { - if (unlikely (!successful)) return false; - if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false; - unsigned int i = bucket_for_hash (key, hash); - - if (is_delete && items[i].key != key) - return true; /* Trying to delete non-existent key. */ - - if (items[i].is_used ()) - { - occupancy--; - if (!items[i].is_tombstone ()) - population--; - } - - items[i].key = key; - items[i].value = std::forward<VV> (value); - items[i].hash = hash; - items[i].set_used (true); - items[i].set_tombstone (is_delete); - - occupancy++; - if (!is_delete) - population++; - - return true; - } - - unsigned int bucket_for (const K &key) const - { - return bucket_for_hash (key, hb_hash (key)); - } - - unsigned int bucket_for_hash (const K &key, uint32_t hash) const + hb_hashmap_t& operator << (const hb_pair_t<K, V&&>& v) + { set (v.first, std::move (v.second)); return *this; } + hb_hashmap_t& operator << (const hb_pair_t<K&&, V>& v) + { set (std::move (v.first), v.second); return *this; } + hb_hashmap_t& operator << (const hb_pair_t<K&&, V&&>& v) + { set (std::move (v.first), std::move (v.second)); return *this; } + + item_t& item_for_hash (const K &key, uint32_t hash) const { hash &= 0x3FFFFFFF; // We only store lower 30bit of hash unsigned int i = hash % prime; @@ -360,12 +367,12 @@ struct hb_hashmap_t while (items[i].is_used ()) { if (items[i].hash == hash && items[i] == key) - return i; + return items[i]; if (tombstone == (unsigned) -1 && items[i].is_tombstone ()) tombstone = i; i = (i + ++step) & mask; } - return tombstone == (unsigned) -1 ? i : tombstone; + return items[tombstone == (unsigned) -1 ? i : tombstone]; } static unsigned int prime_for (unsigned int shift) diff --git a/thirdparty/harfbuzz/src/hb-meta.hh b/thirdparty/harfbuzz/src/hb-meta.hh index 52a6791e31..31aa7fa6f1 100644 --- a/thirdparty/harfbuzz/src/hb-meta.hh +++ b/thirdparty/harfbuzz/src/hb-meta.hh @@ -112,8 +112,7 @@ template <typename T> auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_ident template <typename T> using hb_add_pointer = decltype (_hb_try_add_pointer<T> (hb_prioritize)); -/* TODO Add feature-parity to std::decay. */ -template <typename T> using hb_decay = hb_remove_const<hb_remove_reference<T>>; +template <typename T> using hb_decay = typename std::decay<T>::type; #define hb_is_convertible(From,To) std::is_convertible<From, To>::value diff --git a/thirdparty/harfbuzz/src/hb-ms-feature-ranges.hh b/thirdparty/harfbuzz/src/hb-ms-feature-ranges.hh index d40fdeaa82..46a20c91ea 100644 --- a/thirdparty/harfbuzz/src/hb-ms-feature-ranges.hh +++ b/thirdparty/harfbuzz/src/hb-ms-feature-ranges.hh @@ -166,7 +166,7 @@ hb_ms_setup_features (const hb_feature_t *features, { auto *feature = active_features.lsearch (event->feature); if (feature) - active_features.remove (feature - active_features.arrayZ); + active_features.remove_ordered (feature - active_features.arrayZ); } } diff --git a/thirdparty/harfbuzz/src/hb-multimap.hh b/thirdparty/harfbuzz/src/hb-multimap.hh new file mode 100644 index 0000000000..f0f95917aa --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-multimap.hh @@ -0,0 +1,92 @@ +/* + * Copyright © 2022 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_MULTIMAP_HH +#define HB_MULTIMAP_HH + +#include "hb.hh" +#include "hb-map.hh" +#include "hb-vector.hh" + + +/* + * hb_multimap_t + */ + +struct hb_multimap_t +{ + void add (hb_codepoint_t k, hb_codepoint_t v) + { + hb_codepoint_t *i; + if (multiples_indices.has (k, &i)) + { + multiples_values[*i].push (v); + return; + } + + hb_codepoint_t *old_v; + if (singulars.has (k, &old_v)) + { + hb_codepoint_t old = *old_v; + singulars.del (k); + + multiples_indices.set (k, multiples_values.length); + auto *vec = multiples_values.push (); + + vec->push (old); + vec->push (v); + + return; + } + + singulars.set (k, v); + } + + hb_array_t<const hb_codepoint_t> get (hb_codepoint_t k) const + { + hb_codepoint_t *v; + if (singulars.has (k, &v)) + return hb_array (v, 1); + + hb_codepoint_t *i; + if (multiples_indices.has (k, &i)) + return multiples_values[*i].as_array (); + + return hb_array_t<hb_codepoint_t> (); + } + + bool in_error () const + { + return singulars.in_error () || multiples_indices.in_error () || multiples_values.in_error (); + } + + protected: + hb_map_t singulars; + hb_map_t multiples_indices; + hb_vector_t<hb_vector_t<hb_codepoint_t>> multiples_values; +}; + + + +#endif /* HB_MULTIMAP_HH */ diff --git a/thirdparty/harfbuzz/src/hb-mutex.hh b/thirdparty/harfbuzz/src/hb-mutex.hh index 6914b22450..053f9ddcc4 100644 --- a/thirdparty/harfbuzz/src/hb-mutex.hh +++ b/thirdparty/harfbuzz/src/hb-mutex.hh @@ -108,10 +108,11 @@ struct hb_mutex_t struct hb_lock_t { - hb_lock_t (hb_mutex_t &mutex_) : mutex (mutex_) { mutex.lock (); } - ~hb_lock_t () { mutex.unlock (); } + hb_lock_t (hb_mutex_t &mutex_) : mutex (&mutex_) { mutex->lock (); } + hb_lock_t (hb_mutex_t *mutex_) : mutex (mutex_) { if (mutex) mutex->lock (); } + ~hb_lock_t () { if (mutex) mutex->unlock (); } private: - hb_mutex_t &mutex; + hb_mutex_t *mutex; }; diff --git a/thirdparty/harfbuzz/src/hb-number-parser.hh b/thirdparty/harfbuzz/src/hb-number-parser.hh index 1a9dbba6dd..ec68c3a728 100644 --- a/thirdparty/harfbuzz/src/hb-number-parser.hh +++ b/thirdparty/harfbuzz/src/hb-number-parser.hh @@ -31,7 +31,7 @@ #include "hb.hh" -#line 35 "hb-number-parser.hh" +#line 32 "hb-number-parser.hh" static const unsigned char _double_parser_trans_keys[] = { 0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u, 46u, 101u, 0 @@ -135,12 +135,12 @@ strtod_rl (const char *p, const char **end_ptr /* IN/OUT */) int cs; -#line 139 "hb-number-parser.hh" +#line 132 "hb-number-parser.hh" { cs = double_parser_start; } -#line 144 "hb-number-parser.hh" +#line 135 "hb-number-parser.hh" { int _slen; int _trans; @@ -198,7 +198,7 @@ _resume: exp_overflow = true; } break; -#line 202 "hb-number-parser.hh" +#line 187 "hb-number-parser.hh" } _again: diff --git a/thirdparty/harfbuzz/src/hb-object.hh b/thirdparty/harfbuzz/src/hb-object.hh index 9876c2923c..a23c25f7ca 100644 --- a/thirdparty/harfbuzz/src/hb-object.hh +++ b/thirdparty/harfbuzz/src/hb-object.hh @@ -80,7 +80,7 @@ struct hb_lockable_set_t if (item) { item_t old = *item; - *item = items[items.length - 1]; + *item = std::move (items.tail ()); items.pop (); l.unlock (); old.fini (); @@ -123,7 +123,7 @@ struct hb_lockable_set_t l.lock (); while (items.length) { - item_t old = items[items.length - 1]; + item_t old = items.tail (); items.pop (); l.unlock (); old.fini (); diff --git a/thirdparty/harfbuzz/src/hb-open-file.hh b/thirdparty/harfbuzz/src/hb-open-file.hh index 6eee5827c1..13570a46e0 100644 --- a/thirdparty/harfbuzz/src/hb-open-file.hh +++ b/thirdparty/harfbuzz/src/hb-open-file.hh @@ -90,7 +90,7 @@ typedef struct OpenTypeOffsetTable { if (table_count) { - + tables.sub_array (start_offset, table_count) + + tables.as_array ().sub_array (start_offset, table_count) | hb_map (&TableRecord::tag) | hb_sink (hb_array (table_tags, *table_count)) ; @@ -158,7 +158,7 @@ typedef struct OpenTypeOffsetTable return_trace (false); if (likely (len)) - memcpy (start, blob->data, len); + hb_memcpy (start, blob->data, len); /* 4-byte alignment. */ c->align (4); diff --git a/thirdparty/harfbuzz/src/hb-open-type.hh b/thirdparty/harfbuzz/src/hb-open-type.hh index e66f451820..290799127a 100644 --- a/thirdparty/harfbuzz/src/hb-open-type.hh +++ b/thirdparty/harfbuzz/src/hb-open-type.hh @@ -148,7 +148,7 @@ struct HBFixed : Type static_assert (Type::static_size * 8 > fraction_bits, ""); HBFixed& operator = (typename Type::type i ) { Type::operator= (i); return *this; } - float to_float () const { return ((int32_t) Type::v) / shift; } + float to_float (float offset = 0) const { return ((int32_t) Type::v + offset) / shift; } void set_float (float f) { Type::v = roundf (f * shift); } public: DEFINE_SIZE_STATIC (Type::static_size); @@ -157,6 +157,9 @@ struct HBFixed : Type /* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */ using F2DOT14 = HBFixed<HBINT16, 14>; +/* 16-bit signed fixed number with the low 12 bits of fraction (4.12). */ +using F4DOT12 = HBFixed<HBINT16, 12>; + /* 32-bit signed fixed-point number (16.16). */ using F16DOT16 = HBFixed<HBINT32, 16>; @@ -209,6 +212,12 @@ typedef Index NameID; struct VarIdx : HBUINT32 { static constexpr unsigned NO_VARIATION = 0xFFFFFFFFu; + static_assert (NO_VARIATION == HB_OT_LAYOUT_NO_VARIATIONS_INDEX, ""); + static uint32_t add (uint32_t i, unsigned short v) + { + if (i == NO_VARIATION) return i; + return i + v; + } VarIdx& operator = (uint32_t i) { HBUINT32::operator= (i); return *this; } }; DECLARE_NULL_NAMESPACE_BYTES (OT, VarIdx); @@ -493,10 +502,10 @@ struct UnsizedArrayOf void qsort (unsigned int len, unsigned int start = 0, unsigned int end = (unsigned int) -1) { as_array (len).qsort (start, end); } - bool serialize (hb_serialize_context_t *c, unsigned int items_len) + bool serialize (hb_serialize_context_t *c, unsigned int items_len, bool clear = true) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend (this, items_len))) return_trace (false); + if (unlikely (!c->extend_size (this, get_size (items_len), clear))) return_trace (false); return_trace (true); } template <typename Iterator, @@ -504,8 +513,8 @@ struct UnsizedArrayOf bool serialize (hb_serialize_context_t *c, Iterator items) { TRACE_SERIALIZE (this); - unsigned count = items.len (); - if (unlikely (!serialize (c, count))) return_trace (false); + unsigned count = hb_len (items); + if (unlikely (!serialize (c, count, false))) return_trace (false); /* TODO Umm. Just exhaust the iterator instead? Being extra * cautious right now.. */ for (unsigned i = 0; i < count; i++, ++items) @@ -646,14 +655,9 @@ struct ArrayOf operator iter_t () const { return iter (); } operator writer_t () { return writer (); } - hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const - { return as_array ().sub_array (start_offset, count); } - hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const - { return as_array ().sub_array (start_offset, count); } - hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int count) - { return as_array ().sub_array (start_offset, count); } - hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) - { return as_array ().sub_array (start_offset, count); } + /* Faster range-based for loop. */ + const Type *begin () const { return arrayZ; } + const Type *end () const { return arrayZ + len; } template <typename T> Type &lsearch (const T &x, Type ¬_found = Crap (Type)) @@ -667,15 +671,15 @@ struct ArrayOf unsigned int to_store = (unsigned int) -1) const { return as_array ().lfind (x, i, not_found, to_store); } - void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1) - { as_array ().qsort (start, end); } + void qsort () + { as_array ().qsort (); } - HB_NODISCARD bool serialize (hb_serialize_context_t *c, unsigned items_len) + HB_NODISCARD bool serialize (hb_serialize_context_t *c, unsigned items_len, bool clear = true) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (this))) return_trace (false); c->check_assign (len, items_len, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW); - if (unlikely (!c->extend (this))) return_trace (false); + if (unlikely (!c->extend_size (this, get_size (), clear))) return_trace (false); return_trace (true); } template <typename Iterator, @@ -683,8 +687,8 @@ struct ArrayOf HB_NODISCARD bool serialize (hb_serialize_context_t *c, Iterator items) { TRACE_SERIALIZE (this); - unsigned count = items.len (); - if (unlikely (!serialize (c, count))) return_trace (false); + unsigned count = hb_len (items); + if (unlikely (!serialize (c, count, false))) return_trace (false); /* TODO Umm. Just exhaust the iterator instead? Being extra * cautious right now.. */ for (unsigned i = 0; i < count; i++, ++items) @@ -828,21 +832,25 @@ struct HeadlessArrayOf operator iter_t () const { return iter (); } operator writer_t () { return writer (); } - bool serialize (hb_serialize_context_t *c, unsigned int items_len) + /* Faster range-based for loop. */ + const Type *begin () const { return arrayZ; } + const Type *end () const { return arrayZ + get_length (); } + + HB_NODISCARD bool serialize (hb_serialize_context_t *c, unsigned int items_len, bool clear = true) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (this))) return_trace (false); c->check_assign (lenP1, items_len + 1, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW); - if (unlikely (!c->extend (this))) return_trace (false); + if (unlikely (!c->extend_size (this, get_size (), clear))) return_trace (false); return_trace (true); } template <typename Iterator, hb_requires (hb_is_source_of (Iterator, Type))> - bool serialize (hb_serialize_context_t *c, Iterator items) + HB_NODISCARD bool serialize (hb_serialize_context_t *c, Iterator items) { TRACE_SERIALIZE (this); - unsigned count = items.len (); - if (unlikely (!serialize (c, count))) return_trace (false); + unsigned count = hb_len (items); + if (unlikely (!serialize (c, count, false))) return_trace (false); /* TODO Umm. Just exhaust the iterator instead? Being extra * cautious right now.. */ for (unsigned i = 0; i < count; i++, ++items) @@ -944,14 +952,9 @@ struct SortedArrayOf : ArrayOf<Type, LenType> operator iter_t () const { return iter (); } operator writer_t () { return writer (); } - hb_sorted_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const - { return as_array ().sub_array (start_offset, count); } - hb_sorted_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const - { return as_array ().sub_array (start_offset, count); } - hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int count) - { return as_array ().sub_array (start_offset, count); } - hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) - { return as_array ().sub_array (start_offset, count); } + /* Faster range-based for loop. */ + const Type *begin () const { return this->arrayZ; } + const Type *end () const { return this->arrayZ + this->len; } bool serialize (hb_serialize_context_t *c, unsigned int items_len) { diff --git a/thirdparty/harfbuzz/src/hb-ot-cff-common.hh b/thirdparty/harfbuzz/src/hb-ot-cff-common.hh index ae3b83a256..f22824fc69 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cff-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cff-common.hh @@ -66,95 +66,25 @@ struct CFFIndex { TRACE_SERIALIZE (this); unsigned int size = get_size (); - CFFIndex *out = c->allocate_size<CFFIndex> (size); + CFFIndex *out = c->allocate_size<CFFIndex> (size, false); if (likely (out)) - memcpy (out, this, size); + hb_memcpy (out, this, size); return_trace (out); } + template <typename Iterable, + hb_requires (hb_is_iterable (Iterable))> bool serialize (hb_serialize_context_t *c, - unsigned int offSize_, - const byte_str_array_t &byteArray) + const Iterable &iterable) { TRACE_SERIALIZE (this); - - if (byteArray.length == 0) - { - COUNT *dest = c->allocate_min<COUNT> (); - if (unlikely (!dest)) return_trace (false); - *dest = 0; - return_trace (true); - } - - /* serialize CFFIndex header */ - if (unlikely (!c->extend_min (this))) return_trace (false); - this->count = byteArray.length; - this->offSize = offSize_; - if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (byteArray.length + 1)))) - return_trace (false); - - /* serialize indices */ - unsigned int offset = 1; - unsigned int i = 0; - for (; i < byteArray.length; i++) - { - set_offset_at (i, offset); - offset += byteArray[i].get_size (); - } - set_offset_at (i, offset); - - /* serialize data */ - for (unsigned int i = 0; i < byteArray.length; i++) - { - const hb_ubytes_t &bs = byteArray[i]; - unsigned char *dest = c->allocate_size<unsigned char> (bs.length); - if (unlikely (!dest)) return_trace (false); - memcpy (dest, &bs[0], bs.length); - } - - return_trace (true); - } - - bool serialize (hb_serialize_context_t *c, - unsigned int offSize_, - const str_buff_vec_t &buffArray) - { - byte_str_array_t byteArray; - byteArray.init (); - byteArray.resize (buffArray.length); - for (unsigned int i = 0; i < byteArray.length; i++) - byteArray[i] = hb_ubytes_t (buffArray[i].arrayZ, buffArray[i].length); - bool result = this->serialize (c, offSize_, byteArray); - byteArray.fini (); - return result; - } - - template <typename Iterator, - hb_requires (hb_is_iterator (Iterator))> - bool serialize (hb_serialize_context_t *c, - Iterator it) - { - TRACE_SERIALIZE (this); - serialize_header(c, + it | hb_map ([] (const hb_ubytes_t &_) { return _.length; })); + auto it = hb_iter (iterable); + serialize_header(c, + it | hb_map (hb_iter) | hb_map (hb_len)); for (const auto &_ : +it) - _.copy (c); + hb_iter (_).copy (c); return_trace (true); } - bool serialize (hb_serialize_context_t *c, - const byte_str_array_t &byteArray) - { return serialize (c, + hb_iter (byteArray)); } - - bool serialize (hb_serialize_context_t *c, - const str_buff_vec_t &buffArray) - { - auto it = - + hb_iter (buffArray) - | hb_map ([] (const str_buff_t &_) { return hb_ubytes_t (_.arrayZ, _.length); }) - ; - return serialize (c, it); - } - template <typename Iterator, hb_requires (hb_is_iterator (Iterator))> bool serialize_header (hb_serialize_context_t *c, @@ -171,7 +101,7 @@ struct CFFIndex if (!this->count) return_trace (true); if (unlikely (!c->extend (this->offSize))) return_trace (false); this->offSize = off_size; - if (unlikely (!c->allocate_size<HBUINT8> (off_size * (this->count + 1)))) + if (unlikely (!c->allocate_size<HBUINT8> (off_size * (this->count + 1), false))) return_trace (false); /* serialize indices */ @@ -179,14 +109,27 @@ struct CFFIndex unsigned int i = 0; for (unsigned _ : +it) { - CFFIndex<COUNT>::set_offset_at (i++, offset); + set_offset_at (i++, offset); offset += _; } - CFFIndex<COUNT>::set_offset_at (i, offset); + set_offset_at (i, offset); return_trace (true); } + template <typename Iterable, + hb_requires (hb_is_iterable (Iterable))> + static unsigned total_size (const Iterable &iterable) + { + auto it = + hb_iter (iterable) | hb_map (hb_iter) | hb_map (hb_len); + if (!it) return 0; + + unsigned total = + it | hb_reduce (hb_add, 0); + unsigned off_size = (hb_bit_storage (total + 1) + 7) / 8; + + return min_size + HBUINT8::static_size + (hb_len (it) + 1) * off_size + total; + } + void set_offset_at (unsigned int index, unsigned int offset) { assert (index <= count); @@ -207,10 +150,14 @@ struct CFFIndex unsigned int size = offSize; const HBUINT8 *p = offsets + size * index; - unsigned int offset = 0; - for (; size; size--) - offset = (offset << 8) + *p++; - return offset; + switch (size) + { + case 1: return * (HBUINT8 *) p; + case 2: return * (HBUINT16 *) p; + case 3: return * (HBUINT24 *) p; + case 4: return * (HBUINT32 *) p; + default: return 0; + } } unsigned int length_at (unsigned int index) const @@ -229,6 +176,7 @@ struct CFFIndex hb_ubytes_t operator [] (unsigned int index) const { if (unlikely (index >= count)) return hb_ubytes_t (); + _hb_compiler_memory_r_barrier (); unsigned length = length_at (index); if (unlikely (!length)) return hb_ubytes_t (); return hb_ubytes_t (data_base () + offset_at (index) - 1, length); @@ -280,7 +228,7 @@ struct CFFIndexOf : CFFIndex<COUNT> if (unlikely (!c->extend_min (this))) return_trace (false); this->count = dataArrayLen; this->offSize = offSize_; - if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (dataArrayLen + 1)))) + if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (dataArrayLen + 1), false))) return_trace (false); /* serialize indices */ @@ -288,10 +236,10 @@ struct CFFIndexOf : CFFIndex<COUNT> unsigned int i = 0; for (; i < dataArrayLen; i++) { - CFFIndex<COUNT>::set_offset_at (i, offset); + this->set_offset_at (i, offset); offset += dataSizeArray[i]; } - CFFIndex<COUNT>::set_offset_at (i, offset); + this->set_offset_at (i, offset); /* serialize data */ for (unsigned int i = 0; i < dataArrayLen; i++) @@ -324,13 +272,12 @@ struct Dict : UnsizedByteStr template <typename T, typename V> static bool serialize_int_op (hb_serialize_context_t *c, op_code_t op, V value, op_code_t intOp) { - // XXX: not sure why but LLVM fails to compile the following 'unlikely' macro invocation - if (/*unlikely*/ (!serialize_int<T, V> (c, intOp, value))) + if (unlikely ((!serialize_int<T, V> (c, intOp, value)))) return false; TRACE_SERIALIZE (this); /* serialize the opcode */ - HBUINT8 *p = c->allocate_size<HBUINT8> (OpCode_Size (op)); + HBUINT8 *p = c->allocate_size<HBUINT8> (OpCode_Size (op), false); if (unlikely (!p)) return_trace (false); if (Is_OpCode_ESC (op)) { @@ -415,9 +362,8 @@ struct FDSelect0 { TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this)))) return_trace (false); - for (unsigned int i = 0; i < c->get_num_glyphs (); i++) - if (unlikely (!fds[i].sanitize (c))) - return_trace (false); + if (unlikely (!c->check_array (fds, c->get_num_glyphs ()))) + return_trace (false); return_trace (true); } @@ -471,14 +417,20 @@ struct FDSelect3_4 return_trace (true); } - hb_codepoint_t get_fd (hb_codepoint_t glyph) const + static int _cmp_range (const void *_key, const void *_item) { - unsigned int i; - for (i = 1; i < nRanges (); i++) - if (glyph < ranges[i].first) - break; + hb_codepoint_t glyph = * (hb_codepoint_t *) _key; + FDSelect3_4_Range<GID_TYPE, FD_TYPE> *range = (FDSelect3_4_Range<GID_TYPE, FD_TYPE> *) _item; - return (hb_codepoint_t) ranges[i - 1].fd; + if (glyph < range[0].first) return -1; + if (glyph < range[1].first) return 0; + return +1; + } + + hb_codepoint_t get_fd (hb_codepoint_t glyph) const + { + auto *range = hb_bsearch (glyph, &ranges[0], nRanges () - 1, sizeof (ranges[0]), _cmp_range); + return range ? range->fd : ranges[nRanges () - 1].fd; } GID_TYPE &nRanges () { return ranges.len; } @@ -501,9 +453,9 @@ struct FDSelect { TRACE_SERIALIZE (this); unsigned int size = src.get_size (num_glyphs); - FDSelect *dest = c->allocate_size<FDSelect> (size); + FDSelect *dest = c->allocate_size<FDSelect> (size, false); if (unlikely (!dest)) return_trace (false); - memcpy (dest, &src, size); + hb_memcpy (dest, &src, size); return_trace (true); } diff --git a/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh b/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh index 17b0296616..bb856c9ddb 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh @@ -175,7 +175,7 @@ struct Encoding unsigned int size = src.get_size (); Encoding *dest = c->allocate_size<Encoding> (size); if (unlikely (!dest)) return_trace (false); - memcpy (dest, &src, size); + hb_memcpy (dest, &src, size); return_trace (true); } @@ -471,7 +471,7 @@ struct Charset unsigned int size = src.get_size (num_glyphs); Charset *dest = c->allocate_size<Charset> (size); if (unlikely (!dest)) return_trace (false); - memcpy (dest, &src, size); + hb_memcpy (dest, &src, size); return_trace (true); } @@ -617,7 +617,6 @@ struct CFF1StringIndex : CFF1Index } byte_str_array_t bytesArray; - bytesArray.init (); if (!bytesArray.resize (sidmap.get_population ())) return_trace (false); for (unsigned int i = 0; i < strings.count; i++) @@ -628,7 +627,6 @@ struct CFF1StringIndex : CFF1Index } bool result = CFF1Index::serialize (c, bytesArray); - bytesArray.fini (); return_trace (result); } }; @@ -813,7 +811,7 @@ struct cff1_top_dict_opset_t : top_dict_opset_t<cff1_top_dict_val_t> break; default: - env.last_offset = env.str_ref.offset; + env.last_offset = env.str_ref.get_offset (); top_dict_opset_t<cff1_top_dict_val_t>::process_op (op, env, dictval); /* Record this operand below if stack is empty, otherwise done */ if (!env.argStack.is_empty ()) return; @@ -1295,10 +1293,10 @@ struct cff1 } protected: - hb_blob_t *blob = nullptr; hb_sanitize_context_t sc; public: + hb_blob_t *blob = nullptr; const Encoding *encoding = nullptr; const Charset *charset = nullptr; const CFF1NameIndex *nameIndex = nullptr; diff --git a/thirdparty/harfbuzz/src/hb-ot-cff2-table.hh b/thirdparty/harfbuzz/src/hb-ot-cff2-table.hh index 746160dc8e..9081930bbe 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cff2-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cff2-table.hh @@ -56,7 +56,7 @@ struct CFF2FDSelect unsigned int size = src.get_size (num_glyphs); CFF2FDSelect *dest = c->allocate_size<CFF2FDSelect> (size); if (unlikely (!dest)) return_trace (false); - memcpy (dest, &src, size); + hb_memcpy (dest, &src, size); return_trace (true); } @@ -124,7 +124,7 @@ struct CFF2VariationStore unsigned int size_ = varStore->get_size (); CFF2VariationStore *dest = c->allocate_size<CFF2VariationStore> (size_); if (unlikely (!dest)) return_trace (false); - memcpy (dest, varStore, size_); + hb_memcpy (dest, varStore, size_); return_trace (true); } @@ -483,13 +483,18 @@ struct cff2 blob = nullptr; } + hb_map_t *create_glyph_to_sid_map () const + { + return nullptr; + } + bool is_valid () const { return blob; } protected: - hb_blob_t *blob = nullptr; hb_sanitize_context_t sc; public: + hb_blob_t *blob = nullptr; cff2_top_dict_values_t topDict; const CFF2Subrs *globalSubrs = nullptr; const CFF2VariationStore *varStore = nullptr; diff --git a/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh b/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh index 09c9fe93f3..523196fa79 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh @@ -909,7 +909,7 @@ struct DefaultUVS : SortedArray32Of<UnicodeValueRange> hb_codepoint_t first = arrayZ[i].startUnicodeValue; hb_codepoint_t last = hb_min ((hb_codepoint_t) (first + arrayZ[i].additionalCount), (hb_codepoint_t) HB_UNICODE_MAX); - out->add_range (first, hb_min (last, 0x10FFFFu)); + out->add_range (first, last); } } @@ -925,37 +925,75 @@ struct DefaultUVS : SortedArray32Of<UnicodeValueRange> if (unlikely (!c->copy<HBUINT32> (len))) return nullptr; unsigned init_len = c->length (); - hb_codepoint_t lastCode = HB_MAP_VALUE_INVALID; - int count = -1; - - for (const UnicodeValueRange& _ : as_array ()) + if (this->len > unicodes->get_population () * hb_bit_storage ((unsigned) this->len)) { - for (const unsigned addcnt : hb_range ((unsigned) _.additionalCount + 1)) + hb_codepoint_t start = HB_SET_VALUE_INVALID; + hb_codepoint_t end = HB_SET_VALUE_INVALID; + + for (hb_codepoint_t u = HB_SET_VALUE_INVALID; + unicodes->next (&u);) { - unsigned curEntry = (unsigned) _.startUnicodeValue + addcnt; - if (!unicodes->has (curEntry)) continue; - count += 1; - if (lastCode == HB_MAP_VALUE_INVALID) - lastCode = curEntry; - else if (lastCode + count != curEntry) + if (!as_array ().bsearch (u)) + continue; + if (start == HB_SET_VALUE_INVALID) { + start = u; + end = start - 1; + } + if (end + 1 != u || end - start == 255) + { UnicodeValueRange rec; - rec.startUnicodeValue = lastCode; - rec.additionalCount = count - 1; + rec.startUnicodeValue = start; + rec.additionalCount = end - start; c->copy<UnicodeValueRange> (rec); - - lastCode = curEntry; - count = 0; + start = u; } + end = u; + } + if (start != HB_SET_VALUE_INVALID) + { + UnicodeValueRange rec; + rec.startUnicodeValue = start; + rec.additionalCount = end - start; + c->copy<UnicodeValueRange> (rec); } - } - if (lastCode != HB_MAP_VALUE_INVALID) + } + else { - UnicodeValueRange rec; - rec.startUnicodeValue = lastCode; - rec.additionalCount = count; - c->copy<UnicodeValueRange> (rec); + hb_codepoint_t lastCode = HB_SET_VALUE_INVALID; + int count = -1; + + for (const UnicodeValueRange& _ : *this) + { + hb_codepoint_t curEntry = (hb_codepoint_t) (_.startUnicodeValue - 1); + hb_codepoint_t end = curEntry + _.additionalCount + 2; + + for (; unicodes->next (&curEntry) && curEntry < end;) + { + count += 1; + if (lastCode == HB_SET_VALUE_INVALID) + lastCode = curEntry; + else if (lastCode + count != curEntry) + { + UnicodeValueRange rec; + rec.startUnicodeValue = lastCode; + rec.additionalCount = count - 1; + c->copy<UnicodeValueRange> (rec); + + lastCode = curEntry; + count = 0; + } + } + } + + if (lastCode != HB_MAP_VALUE_INVALID) + { + UnicodeValueRange rec; + rec.startUnicodeValue = lastCode; + rec.additionalCount = count; + c->copy<UnicodeValueRange> (rec); + } } if (c->length () - init_len == 0) @@ -1474,32 +1512,80 @@ struct EncodingRecord DEFINE_SIZE_STATIC (8); }; +struct cmap; + struct SubtableUnicodesCache { private: - const void* base; - hb_hashmap_t<intptr_t, hb::unique_ptr<hb_set_t>> cached_unicodes; + hb_blob_ptr_t<cmap> base_blob; + const char* base; + hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> cached_unicodes; public: + + static SubtableUnicodesCache* create (hb_blob_ptr_t<cmap> source_table) + { + SubtableUnicodesCache* cache = + (SubtableUnicodesCache*) hb_malloc (sizeof(SubtableUnicodesCache)); + new (cache) SubtableUnicodesCache (source_table); + return cache; + } + + static void destroy (void* value) { + if (!value) return; + + SubtableUnicodesCache* cache = (SubtableUnicodesCache*) value; + cache->~SubtableUnicodesCache (); + hb_free (cache); + } + SubtableUnicodesCache(const void* cmap_base) - : base(cmap_base), cached_unicodes() {} + : base_blob(), + base ((const char*) cmap_base), + cached_unicodes () + {} + + SubtableUnicodesCache(hb_blob_ptr_t<cmap> base_blob_) + : base_blob(base_blob_), + base ((const char *) base_blob.get()), + cached_unicodes () + {} + + ~SubtableUnicodesCache() + { + base_blob.destroy (); + } + + bool same_base(const void* other) const + { + return other == (const void*) base; + } - hb_set_t* set_for (const EncodingRecord* record) + const hb_set_t* set_for (const EncodingRecord* record, + SubtableUnicodesCache& mutable_cache) const { - if (!cached_unicodes.has ((intptr_t) record)) + if (cached_unicodes.has ((unsigned) ((const char *) record - base))) + return cached_unicodes.get ((unsigned) ((const char *) record - base)); + + return mutable_cache.set_for (record); + } + + const hb_set_t* set_for (const EncodingRecord* record) + { + if (!cached_unicodes.has ((unsigned) ((const char *) record - base))) { hb_set_t *s = hb_set_create (); if (unlikely (s->in_error ())) return hb_set_get_empty (); - + (base+record->subtable).collect_unicodes (s); - if (unlikely (!cached_unicodes.set ((intptr_t) record, hb::unique_ptr<hb_set_t> {s}))) + if (unlikely (!cached_unicodes.set ((unsigned) ((const char *) record - base), hb::unique_ptr<hb_set_t> {s}))) return hb_set_get_empty (); return s; } - return cached_unicodes.get ((intptr_t) record); + return cached_unicodes.get ((unsigned) ((const char *) record - base)); } }; @@ -1523,13 +1609,30 @@ struct cmap { static constexpr hb_tag_t tableTag = HB_OT_TAG_cmap; + + static SubtableUnicodesCache* create_filled_cache(hb_blob_ptr_t<cmap> source_table) { + const cmap* cmap = source_table.get(); + auto it = + + hb_iter (cmap->encodingRecord) + | hb_filter ([&](const EncodingRecord& _) { + return cmap::filter_encoding_records_for_subset (cmap, _); + }) + ; + + SubtableUnicodesCache* cache = SubtableUnicodesCache::create(source_table); + for (const EncodingRecord& _ : it) + cache->set_for(&_); // populate the cache for this encoding record. + + return cache; + } + template<typename Iterator, typename EncodingRecIter, hb_requires (hb_is_iterator (EncodingRecIter))> bool serialize (hb_serialize_context_t *c, Iterator it, EncodingRecIter encodingrec_iter, const void *base, - const hb_subset_plan_t *plan, + hb_subset_plan_t *plan, bool drop_format_4 = false) { if (unlikely (!c->extend_min ((*this)))) return false; @@ -1538,7 +1641,14 @@ struct cmap unsigned format4objidx = 0, format12objidx = 0, format14objidx = 0; auto snap = c->snapshot (); - SubtableUnicodesCache unicodes_cache (base); + SubtableUnicodesCache local_unicodes_cache (base); + const SubtableUnicodesCache* unicodes_cache = &local_unicodes_cache; + + if (plan->accelerator && + plan->accelerator->cmap_cache && + plan->accelerator->cmap_cache->same_base (base)) + unicodes_cache = plan->accelerator->cmap_cache; + for (const EncodingRecord& _ : encodingrec_iter) { if (c->in_error ()) @@ -1547,7 +1657,7 @@ struct cmap unsigned format = (base+_.subtable).u.format; if (format != 4 && format != 12 && format != 14) continue; - hb_set_t* unicodes_set = unicodes_cache.set_for (&_); + const hb_set_t* unicodes_set = unicodes_cache->set_for (&_, local_unicodes_cache); if (!drop_format_4 && format == 4) { @@ -1566,7 +1676,13 @@ struct cmap else if (format == 12) { - if (_can_drop (_, *unicodes_set, base, unicodes_cache, + it | hb_map (hb_first), encodingrec_iter)) continue; + if (_can_drop (_, + *unicodes_set, + base, + *unicodes_cache, + local_unicodes_cache, + + it | hb_map (hb_first), encodingrec_iter)) + continue; c->copy (_, + it | hb_filter (*unicodes_set, hb_first), 12u, base, plan, &format12objidx); } else if (format == 14) c->copy (_, it, 14u, base, plan, &format14objidx); @@ -1585,7 +1701,8 @@ struct cmap bool _can_drop (const EncodingRecord& cmap12, const hb_set_t& cmap12_unicodes, const void* base, - SubtableUnicodesCache& unicodes_cache, + const SubtableUnicodesCache& unicodes_cache, + SubtableUnicodesCache& local_unicodes_cache, Iterator subset_unicodes, EncodingRecordIterator encoding_records) { @@ -1616,7 +1733,7 @@ struct cmap || (base+_.subtable).get_language() != target_language) continue; - hb_set_t* sibling_unicodes = unicodes_cache.set_for (&_); + const hb_set_t* sibling_unicodes = unicodes_cache.set_for (&_, local_unicodes_cache); auto cmap12 = + subset_unicodes | hb_filter (cmap12_unicodes); auto sibling = + subset_unicodes | hb_filter (*sibling_unicodes); @@ -1653,17 +1770,9 @@ struct cmap auto encodingrec_iter = + hb_iter (encodingRecord) - | hb_filter ([&] (const EncodingRecord& _) - { - if ((_.platformID == 0 && _.encodingID == 3) || - (_.platformID == 0 && _.encodingID == 4) || - (_.platformID == 3 && _.encodingID == 1) || - (_.platformID == 3 && _.encodingID == 10) || - (this + _.subtable).u.format == 14) - return true; - - return false; - }) + | hb_filter ([&](const EncodingRecord& _) { + return cmap::filter_encoding_records_for_subset (this, _); + }) ; if (unlikely (!encodingrec_iter.len ())) return_trace (false); @@ -1692,7 +1801,11 @@ struct cmap { return (_.second != HB_MAP_VALUE_INVALID); }) ; - return_trace (cmap_prime->serialize (c->serializer, it, encodingrec_iter, this, c->plan)); + return_trace (cmap_prime->serialize (c->serializer, + it, + encodingrec_iter, + this, + c->plan)); } const CmapSubtable *find_best_subtable (bool *symbol = nullptr) const @@ -1928,6 +2041,19 @@ struct cmap encodingRecord.sanitize (c, this)); } + private: + + static bool filter_encoding_records_for_subset(const cmap* cmap, + const EncodingRecord& _) + { + return + (_.platformID == 0 && _.encodingID == 3) || + (_.platformID == 0 && _.encodingID == 4) || + (_.platformID == 3 && _.encodingID == 1) || + (_.platformID == 3 && _.encodingID == 10) || + (cmap + _.subtable).u.format == 14; + } + protected: HBUINT16 version; /* Table version number (0). */ SortedArray16Of<EncodingRecord> diff --git a/thirdparty/harfbuzz/src/hb-ot-color-cbdt-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-cbdt-table.hh index 23fa56c4f6..3246894d39 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color-cbdt-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-color-cbdt-table.hh @@ -67,7 +67,7 @@ _copy_data_to_cbdt (hb_vector_t<char> *cbdt_prime, { unsigned int new_len = cbdt_prime->length + length; if (unlikely (!cbdt_prime->alloc (new_len))) return false; - memcpy (cbdt_prime->arrayZ + cbdt_prime->length, data, length); + hb_memcpy (cbdt_prime->arrayZ + cbdt_prime->length, data, length); cbdt_prime->length = new_len; return true; } @@ -468,13 +468,13 @@ struct IndexSubtableRecord if (unlikely (!c->serializer->check_success (records->resize (records->length + 1)))) return_trace (false); - (*records)[records->length - 1].firstGlyphIndex = 1; - (*records)[records->length - 1].lastGlyphIndex = 0; + records->tail ().firstGlyphIndex = 1; + records->tail ().lastGlyphIndex = 0; bitmap_size_context->size += IndexSubtableRecord::min_size; c->serializer->push (); - if (unlikely (!add_new_subtable (c, bitmap_size_context, &((*records)[records->length - 1]), lookup, base, start))) + if (unlikely (!add_new_subtable (c, bitmap_size_context, &(records->tail ()), lookup, base, start))) { c->serializer->pop_discard (); c->serializer->revert (snap); diff --git a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh index 908bf550f0..1af9d30937 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh @@ -39,11 +39,7 @@ #define HB_OT_TAG_COLR HB_TAG('C','O','L','R') #ifndef HB_COLRV1_MAX_NESTING_LEVEL -#define HB_COLRV1_MAX_NESTING_LEVEL 100 -#endif - -#ifndef COLRV1_ENABLE_SUBSETTING -#define COLRV1_ENABLE_SUBSETTING 1 +#define HB_COLRV1_MAX_NESTING_LEVEL 16 #endif namespace OT { @@ -188,6 +184,7 @@ struct Variable protected: T value; + public: VarIdx varIdxBase; public: DEFINE_SIZE_STATIC (4 + T::static_size); @@ -196,6 +193,8 @@ struct Variable template <typename T> struct NoVariable { + static constexpr uint32_t varIdxBase = VarIdx::NO_VARIATION; + NoVariable<T>* copy (hb_serialize_context_t *c) const { TRACE_SERIALIZE (this); @@ -888,6 +887,11 @@ struct PaintComposite DEFINE_SIZE_STATIC (8); }; +struct ClipBoxData +{ + int xMin, yMin, xMax, yMax; +}; + struct ClipBoxFormat1 { bool sanitize (hb_sanitize_context_t *c) const @@ -896,6 +900,14 @@ struct ClipBoxFormat1 return_trace (c->check_struct (this)); } + void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer HB_UNUSED) const + { + clip_box.xMin = xMin; + clip_box.yMin = yMin; + clip_box.xMax = xMax; + clip_box.yMax = yMax; + } + public: HBUINT8 format; /* format = 1(noVar) or 2(Var)*/ FWORD xMin; @@ -906,7 +918,20 @@ struct ClipBoxFormat1 DEFINE_SIZE_STATIC (1 + 4 * FWORD::static_size); }; -struct ClipBoxFormat2 : Variable<ClipBoxFormat1> {}; +struct ClipBoxFormat2 : Variable<ClipBoxFormat1> +{ + void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer) const + { + value.get_clip_box(clip_box, instancer); + if (instancer) + { + clip_box.xMin += _hb_roundf (instancer (varIdxBase, 0)); + clip_box.yMin += _hb_roundf (instancer (varIdxBase, 1)); + clip_box.xMax += _hb_roundf (instancer (varIdxBase, 2)); + clip_box.yMax += _hb_roundf (instancer (varIdxBase, 3)); + } + } +}; struct ClipBox { @@ -932,6 +957,28 @@ struct ClipBox } } + bool get_extents (hb_glyph_extents_t *extents, + const VarStoreInstancer &instancer) const + { + ClipBoxData clip_box; + switch (u.format) { + case 1: + u.format1.get_clip_box (clip_box, instancer); + break; + case 2: + u.format2.get_clip_box (clip_box, instancer); + break; + default: + return false; + } + + extents->x_bearing = clip_box.xMin; + extents->y_bearing = clip_box.yMax; + extents->width = clip_box.xMax - clip_box.xMin; + extents->height = clip_box.yMin - clip_box.yMax; + return true; + } + protected: union { HBUINT8 format; /* Format identifier */ @@ -942,6 +989,9 @@ struct ClipBox struct ClipRecord { + int cmp (hb_codepoint_t g) const + { return g < startGlyphID ? -1 : g <= endGlyphID ? 0 : +1; } + ClipRecord* copy (hb_serialize_context_t *c, const void *base) const { TRACE_SERIALIZE (this); @@ -957,6 +1007,13 @@ struct ClipRecord return_trace (c->check_struct (this) && clipBox.sanitize (c, base)); } + bool get_extents (hb_glyph_extents_t *extents, + const void *base, + const VarStoreInstancer &instancer) const + { + return (base+clipBox).get_extents (extents, instancer); + } + public: HBUINT16 startGlyphID; // first gid clip applies to HBUINT16 endGlyphID; // last gid clip applies to, inclusive @@ -964,6 +1021,7 @@ struct ClipRecord public: DEFINE_SIZE_STATIC (7); }; +DECLARE_NULL_NAMESPACE_BYTES (OT, ClipRecord); struct ClipList { @@ -1052,11 +1110,26 @@ struct ClipList bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); + // TODO Make a formatted struct! return_trace (c->check_struct (this) && clips.sanitize (c, this)); } + bool + get_extents (hb_codepoint_t gid, + hb_glyph_extents_t *extents, + const VarStoreInstancer &instancer) const + { + auto *rec = clips.as_array ().bsearch (gid); + if (rec) + { + rec->get_extents (extents, this, instancer); + return true; + } + return false; + } + HBUINT8 format; // Set to 1. - Array32Of<ClipRecord> clips; // Clip records, sorted by startGlyphID + SortedArray32Of<ClipRecord> clips; // Clip records, sorted by startGlyphID public: DEFINE_SIZE_ARRAY_SIZED (5, clips); }; @@ -1359,7 +1432,7 @@ struct COLR (this+baseGlyphsZ).sanitize (c, numBaseGlyphs) && (this+layersZ).sanitize (c, numLayers) && (version == 0 || - (COLRV1_ENABLE_SUBSETTING && version == 1 && + (version == 1 && baseGlyphList.sanitize (c, this) && layerList.sanitize (c, this) && clipList.sanitize (c, this) && @@ -1516,6 +1589,30 @@ struct COLR return_trace (true); } + bool + get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const + { + if (version != 1) + return false; + + VarStoreInstancer instancer (this+varStore, + this+varIdxMap, + hb_array (font->coords, font->num_coords)); + + if ((this+clipList).get_extents (glyph, + extents, + instancer)) + { + extents->x_bearing = font->em_scale_x (extents->x_bearing); + extents->y_bearing = font->em_scale_x (extents->y_bearing); + extents->width = font->em_scale_x (extents->width); + extents->height = font->em_scale_x (extents->height); + return true; + } + + return false; + } + protected: HBUINT16 version; /* Table version number (starts at 0). */ HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records. */ diff --git a/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh b/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh index c05034b3bb..c9da36c1bb 100644 --- a/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh +++ b/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh @@ -56,9 +56,9 @@ HB_OT_CORE_TABLE (OT, maxp) #if !defined(HB_NO_FACE_COLLECT_UNICODES) || !defined(HB_NO_OT_FONT) HB_OT_ACCELERATOR (OT, cmap) #endif -HB_OT_TABLE (OT, hhea) +HB_OT_CORE_TABLE (OT, hhea) HB_OT_ACCELERATOR (OT, hmtx) -HB_OT_TABLE (OT, OS2) +HB_OT_CORE_TABLE (OT, OS2) #if !defined(HB_NO_OT_FONT_GLYPH_NAMES) || !defined(HB_NO_METRICS) || !defined(HB_NO_STYLE) HB_OT_ACCELERATOR (OT, post) #endif @@ -66,7 +66,7 @@ HB_OT_ACCELERATOR (OT, post) HB_OT_ACCELERATOR (OT, name) #endif #ifndef HB_NO_STYLE -HB_OT_TABLE (OT, STAT) +HB_OT_CORE_TABLE (OT, STAT) #endif #ifndef HB_NO_META HB_OT_ACCELERATOR (OT, meta) @@ -74,9 +74,9 @@ HB_OT_ACCELERATOR (OT, meta) /* Vertical layout. */ #ifndef HB_NO_VERTICAL -HB_OT_TABLE (OT, vhea) +HB_OT_CORE_TABLE (OT, vhea) HB_OT_ACCELERATOR (OT, vmtx) -HB_OT_TABLE (OT, VORG) +HB_OT_CORE_TABLE (OT, VORG) #endif /* TrueType outlines. */ @@ -91,15 +91,15 @@ HB_OT_ACCELERATOR (OT, cff2) /* OpenType variations. */ #ifndef HB_NO_VAR -HB_OT_TABLE (OT, fvar) -HB_OT_TABLE (OT, avar) +HB_OT_CORE_TABLE (OT, fvar) +HB_OT_CORE_TABLE (OT, avar) HB_OT_ACCELERATOR (OT, gvar) -HB_OT_TABLE (OT, MVAR) +HB_OT_CORE_TABLE (OT, MVAR) #endif /* Legacy kern. */ #ifndef HB_NO_OT_KERN -HB_OT_TABLE (OT, kern) +HB_OT_CORE_TABLE (OT, kern) #endif /* OpenType shaping. */ @@ -107,12 +107,12 @@ HB_OT_TABLE (OT, kern) HB_OT_ACCELERATOR (OT, GDEF) HB_OT_ACCELERATOR (OT, GSUB) HB_OT_ACCELERATOR (OT, GPOS) -//HB_OT_TABLE (OT, JSTF) +//HB_OT_CORE_TABLE (OT, JSTF) #endif /* OpenType baseline. */ #ifndef HB_NO_BASE -HB_OT_TABLE (OT, BASE) +HB_OT_CORE_TABLE (OT, BASE) #endif /* AAT shaping. */ @@ -129,8 +129,8 @@ HB_OT_TABLE (AAT, feat) /* OpenType color fonts. */ #ifndef HB_NO_COLOR -HB_OT_TABLE (OT, COLR) -HB_OT_TABLE (OT, CPAL) +HB_OT_CORE_TABLE (OT, COLR) +HB_OT_CORE_TABLE (OT, CPAL) HB_OT_ACCELERATOR (OT, CBDT) HB_OT_ACCELERATOR (OT, sbix) HB_OT_ACCELERATOR (OT, SVG) @@ -138,7 +138,7 @@ HB_OT_ACCELERATOR (OT, SVG) /* OpenType math. */ #ifndef HB_NO_MATH -HB_OT_TABLE (OT, MATH) +HB_OT_CORE_TABLE (OT, MATH) #endif diff --git a/thirdparty/harfbuzz/src/hb-ot-font.cc b/thirdparty/harfbuzz/src/hb-ot-font.cc index 825b30853c..8405103423 100644 --- a/thirdparty/harfbuzz/src/hb-ot-font.cc +++ b/thirdparty/harfbuzz/src/hb-ot-font.cc @@ -45,6 +45,7 @@ #include "hb-ot-vorg-table.hh" #include "hb-ot-color-cbdt-table.hh" #include "hb-ot-color-sbix-table.hh" +#include "hb-ot-color-colr-table.hh" /** @@ -350,13 +351,15 @@ hb_ot_get_glyph_extents (hb_font_t *font, if (ot_face->sbix->get_extents (font, glyph, extents)) return true; if (ot_face->CBDT->get_extents (font, glyph, extents)) return true; #endif +#if !defined(HB_NO_COLOR) + if (ot_face->COLR->get_extents (font, glyph, extents)) return true; +#endif if (ot_face->glyf->get_extents (font, glyph, extents)) return true; #ifndef HB_NO_OT_FONT_CFF if (ot_face->cff1->get_extents (font, glyph, extents)) return true; if (ot_face->cff2->get_extents (font, glyph, extents)) return true; #endif - // TODO Hook up side-bearings variations. return false; } diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh index 579abf011a..0f424f5aa6 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh @@ -478,7 +478,7 @@ struct IndexArray : Array16Of<Index> { if (_count) { - + this->sub_array (start_offset, _count) + + this->as_array ().sub_array (start_offset, _count) | hb_sink (hb_array (_indexes, *_count)) ; } @@ -658,7 +658,7 @@ struct FeatureParamsCharacterVariants { if (char_count) { - + characters.sub_array (start_offset, char_count) + + characters.as_array ().sub_array (start_offset, char_count) | hb_sink (hb_array (chars, *char_count)) ; } @@ -932,7 +932,7 @@ struct RecordArrayOf : SortedArray16Of<Record<Type>> { if (record_count) { - + this->sub_array (start_offset, record_count) + + this->as_array ().sub_array (start_offset, record_count) | hb_map (&Record<Type>::tag) | hb_sink (hb_array (record_tags, *record_count)) ; @@ -980,18 +980,16 @@ struct RecordListOfFeature : RecordListOf<Feature> auto *out = c->serializer->start_embed (*this); if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); - unsigned count = this->len; - - + hb_zip (*this, hb_range (count)) - | hb_filter (l->feature_index_map, hb_second) - | hb_apply ([l, out, this] (const hb_pair_t<const Record<Feature>&, unsigned>& _) + + hb_enumerate (*this) + | hb_filter (l->feature_index_map, hb_first) + | hb_apply ([l, out, this] (const hb_pair_t<unsigned, const Record<Feature>&>& _) { const Feature *f_sub = nullptr; const Feature **f = nullptr; - if (l->feature_substitutes_map->has (_.second, &f)) + if (l->feature_substitutes_map->has (_.first, &f)) f_sub = *f; - subset_record_array (l, out, this, f_sub) (_.first); + subset_record_array (l, out, this, f_sub) (_.second); }) ; @@ -1079,7 +1077,7 @@ struct LangSys auto *out = c->serializer->start_embed (*this); if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); - const unsigned *v; + const uint32_t *v; out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? *v : 0xFFFFu; if (!l->visitFeatureIndex (featureIndex.len)) @@ -1147,7 +1145,6 @@ struct Script return; } - unsigned langsys_count = get_lang_sys_count (); if (has_default_lang_sys ()) { //only collect features from non-redundant langsys @@ -1156,24 +1153,24 @@ struct Script d.collect_features (c); } - for (auto _ : + hb_zip (langSys, hb_range (langsys_count))) + for (auto _ : + hb_enumerate (langSys)) { - const LangSys& l = this+_.first.offset; + const LangSys& l = this+_.second.offset; if (!c->visitLangsys (l.get_feature_count ())) continue; if (l.compare (d, c->duplicate_feature_map)) continue; l.collect_features (c); - c->script_langsys_map->get (script_index)->add (_.second); + c->script_langsys_map->get (script_index)->add (_.first); } } else { - for (auto _ : + hb_zip (langSys, hb_range (langsys_count))) + for (auto _ : + hb_enumerate (langSys)) { - const LangSys& l = this+_.first.offset; + const LangSys& l = this+_.second.offset; if (!c->visitLangsys (l.get_feature_count ())) continue; l.collect_features (c); - c->script_langsys_map->get (script_index)->add (_.second); + c->script_langsys_map->get (script_index)->add (_.first); } } } @@ -1211,10 +1208,9 @@ struct Script const hb_set_t *active_langsys = l->script_langsys_map->get (l->cur_script_index); if (active_langsys) { - unsigned count = langSys.len; - + hb_zip (langSys, hb_range (count)) - | hb_filter (active_langsys, hb_second) - | hb_map (hb_first) + + hb_enumerate (langSys) + | hb_filter (active_langsys, hb_first) + | hb_map (hb_second) | hb_filter ([=] (const Record<LangSys>& record) {return l->visitLangSys (); }) | hb_apply (subset_record_array (l, &(out->langSys), this)) ; @@ -1250,12 +1246,11 @@ struct RecordListOfScript : RecordListOf<Script> auto *out = c->serializer->start_embed (*this); if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); - unsigned count = this->len; - for (auto _ : + hb_zip (*this, hb_range (count))) + for (auto _ : + hb_enumerate (*this)) { auto snap = c->serializer->snapshot (); - l->cur_script_index = _.second; - bool ret = _.first.subset (l, this); + l->cur_script_index = _.first; + bool ret = _.second.subset (l, this); if (!ret) c->serializer->revert (snap); else out->len++; } @@ -1388,7 +1383,13 @@ struct Lookup outMarkFilteringSet = markFilteringSet; } - return_trace (out->subTable.len); + // Always keep the lookup even if it's empty. The rest of layout subsetting depends on lookup + // indices being consistent with those computed during planning. So if an empty lookup is + // discarded during the subset phase it will invalidate all subsequent lookup indices. + // Generally we shouldn't end up with an empty lookup as we pre-prune them during the planning + // phase, but it can happen in rare cases such as when during closure subtable is considered + // degenerate (see: https://github.com/harfbuzz/harfbuzz/issues/3853) + return true; } template <typename TSubTable> @@ -1454,10 +1455,9 @@ struct LookupOffsetList : List16OfOffsetTo<TLookup, OffsetType> auto *out = c->serializer->start_embed (this); if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); - unsigned count = this->len; - + hb_zip (*this, hb_range (count)) - | hb_filter (l->lookup_index_map, hb_second) - | hb_map (hb_first) + + hb_enumerate (*this) + | hb_filter (l->lookup_index_map, hb_first) + | hb_map (hb_second) | hb_apply (subset_offset_array (c, *out, this)) ; return_trace (true); @@ -1491,7 +1491,7 @@ static bool ClassDef_remap_and_serialize (hb_serialize_context_t *c, klass_map->set (0, 0); unsigned idx = klass_map->has (0) ? 1 : 0; - for (const unsigned k: klasses.iter ()) + for (const unsigned k: klasses) { if (klass_map->has (k)) continue; klass_map->set (k, idx); @@ -1524,6 +1524,11 @@ struct ClassDefFormat1_3 return classValue[(unsigned int) (glyph_id - startGlyph)]; } + unsigned get_population () const + { + return classValue.len; + } + template<typename Iterator, hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> bool serialize (hb_serialize_context_t *c, @@ -1548,7 +1553,7 @@ struct ClassDefFormat1_3 startGlyph = glyph_min; if (unlikely (!classValue.serialize (c, glyph_count))) return_trace (false); - for (const hb_pair_t<hb_codepoint_t, unsigned> gid_klass_pair : + it) + for (const hb_pair_t<hb_codepoint_t, uint32_t> gid_klass_pair : + it) { unsigned idx = gid_klass_pair.first - glyph_min; classValue[idx] = gid_klass_pair.second; @@ -1639,11 +1644,10 @@ struct ClassDefFormat1_3 bool intersects (const hb_set_t *glyphs) const { - /* TODO Speed up, using hb_set_next()? */ hb_codepoint_t start = startGlyph; hb_codepoint_t end = startGlyph + classValue.len; for (hb_codepoint_t iter = startGlyph - 1; - hb_set_next (glyphs, &iter) && iter < end;) + glyphs->next (&iter) && iter < end;) if (classValue[iter - start]) return true; return false; } @@ -1654,10 +1658,10 @@ struct ClassDefFormat1_3 { /* Match if there's any glyph that is not listed! */ hb_codepoint_t g = HB_SET_VALUE_INVALID; - if (!hb_set_next (glyphs, &g)) return false; + if (!glyphs->next (&g)) return false; if (g < startGlyph) return true; g = startGlyph + count - 1; - if (hb_set_next (glyphs, &g)) return true; + if (glyphs->next (&g)) return true; /* Fall through. */ } /* TODO Speed up, using set overlap first? */ @@ -1675,12 +1679,12 @@ struct ClassDefFormat1_3 if (klass == 0) { unsigned start_glyph = startGlyph; - for (unsigned g = HB_SET_VALUE_INVALID; - hb_set_next (glyphs, &g) && g < start_glyph;) + for (uint32_t g = HB_SET_VALUE_INVALID; + glyphs->next (&g) && g < start_glyph;) intersect_glyphs->add (g); - for (unsigned g = startGlyph + count - 1; - hb_set_next (glyphs, &g);) + for (uint32_t g = startGlyph + count - 1; + glyphs-> next (&g);) intersect_glyphs->add (g); return; @@ -1696,7 +1700,7 @@ struct ClassDefFormat1_3 unsigned start_glyph = startGlyph; unsigned end_glyph = start_glyph + count; for (unsigned g = startGlyph - 1; - hb_set_next (glyphs, &g) && g < end_glyph;) + glyphs->next (&g) && g < end_glyph;) if (classValue.arrayZ[g - start_glyph] == klass) intersect_glyphs->add (g); #endif @@ -1739,6 +1743,14 @@ struct ClassDefFormat2_4 return rangeRecord.bsearch (glyph_id).value; } + unsigned get_population () const + { + typename Types::large_int ret = 0; + for (const auto &r : rangeRecord) + ret += r.get_population (); + return ret > UINT_MAX ? UINT_MAX : (unsigned) ret; + } + template<typename Iterator, hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> bool serialize (hb_serialize_context_t *c, @@ -1802,28 +1814,45 @@ struct ClassDefFormat2_4 { TRACE_SUBSET (this); const hb_map_t &glyph_map = *c->plan->glyph_map_gsub; + const hb_set_t &glyph_set = *c->plan->glyphset_gsub (); hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> glyph_and_klass; hb_set_t orig_klasses; - unsigned num_source_glyphs = c->plan->source->get_num_glyphs (); - unsigned count = rangeRecord.len; - for (unsigned i = 0; i < count; i++) + if (glyph_set.get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2 + < get_population ()) { - unsigned klass = rangeRecord[i].value; - if (!klass) continue; - hb_codepoint_t start = rangeRecord[i].first; - hb_codepoint_t end = hb_min (rangeRecord[i].last + 1, num_source_glyphs); - for (hb_codepoint_t g = start; g < end; g++) + for (hb_codepoint_t g : glyph_set) { - hb_codepoint_t new_gid = glyph_map[g]; + unsigned klass = get_class (g); + if (!klass) continue; + hb_codepoint_t new_gid = glyph_map[g]; if (new_gid == HB_MAP_VALUE_INVALID) continue; - if (glyph_filter && !glyph_filter->has (g)) continue; - + if (glyph_filter && !glyph_filter->has (g)) continue; glyph_and_klass.push (hb_pair (new_gid, klass)); orig_klasses.add (klass); } } + else + { + unsigned num_source_glyphs = c->plan->source->get_num_glyphs (); + for (auto &range : rangeRecord) + { + unsigned klass = range.value; + if (!klass) continue; + hb_codepoint_t start = range.first; + hb_codepoint_t end = hb_min (range.last + 1, num_source_glyphs); + for (hb_codepoint_t g = start; g < end; g++) + { + hb_codepoint_t new_gid = glyph_map[g]; + if (new_gid == HB_MAP_VALUE_INVALID) continue; + if (glyph_filter && !glyph_filter->has (g)) continue; + + glyph_and_klass.push (hb_pair (new_gid, klass)); + orig_klasses.add (klass); + } + } + } const hb_set_t& glyphset = *c->plan->glyphset_gsub (); unsigned glyph_count = glyph_filter @@ -1850,10 +1879,9 @@ struct ClassDefFormat2_4 template <typename set_t> bool collect_coverage (set_t *glyphs) const { - unsigned int count = rangeRecord.len; - for (unsigned int i = 0; i < count; i++) - if (rangeRecord[i].value) - if (unlikely (!rangeRecord[i].collect_coverage (glyphs))) + for (auto &range : rangeRecord) + if (range.value) + if (unlikely (!range.collect_coverage (glyphs))) return false; return true; } @@ -1861,11 +1889,10 @@ struct ClassDefFormat2_4 template <typename set_t> bool collect_class (set_t *glyphs, unsigned int klass) const { - unsigned int count = rangeRecord.len; - for (unsigned int i = 0; i < count; i++) + for (auto &range : rangeRecord) { - if (rangeRecord[i].value == klass) - if (unlikely (!rangeRecord[i].collect_coverage (glyphs))) + if (range.value == klass) + if (unlikely (!range.collect_coverage (glyphs))) return false; } return true; @@ -1873,32 +1900,32 @@ struct ClassDefFormat2_4 bool intersects (const hb_set_t *glyphs) const { - /* TODO Speed up, using hb_set_next() and bsearch()? */ - unsigned int count = rangeRecord.len; - for (unsigned int i = 0; i < count; i++) + if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2) { - const auto& range = rangeRecord[i]; - if (range.intersects (*glyphs) && range.value) - return true; + for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);) + if (get_class (g)) + return true; + return false; } - return false; + + return hb_any (+ hb_iter (rangeRecord) + | hb_map ([glyphs] (const RangeRecord<Types> &range) { return range.intersects (*glyphs) && range.value; })); } bool intersects_class (const hb_set_t *glyphs, uint16_t klass) const { - unsigned int count = rangeRecord.len; if (klass == 0) { /* Match if there's any glyph that is not listed! */ hb_codepoint_t g = HB_SET_VALUE_INVALID; - for (unsigned int i = 0; i < count; i++) + for (auto &range : rangeRecord) { - if (!hb_set_next (glyphs, &g)) + if (!glyphs->next (&g)) break; - if (g < rangeRecord[i].first) + if (g < range.first) return true; - g = rangeRecord[i].last; + g = range.last; } - if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g)) + if (g != HB_SET_VALUE_INVALID && glyphs->next (&g)) return true; /* Fall through. */ } @@ -1910,49 +1937,49 @@ struct ClassDefFormat2_4 void intersected_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) const { - unsigned count = rangeRecord.len; if (klass == 0) { hb_codepoint_t g = HB_SET_VALUE_INVALID; - for (unsigned int i = 0; i < count; i++) + for (auto &range : rangeRecord) { - if (!hb_set_next (glyphs, &g)) + if (!glyphs->next (&g)) goto done; - while (g < rangeRecord[i].first) + while (g < range.first) { intersect_glyphs->add (g); - if (!hb_set_next (glyphs, &g)) + if (!glyphs->next (&g)) goto done; } - g = rangeRecord[i].last; + g = range.last; } - while (hb_set_next (glyphs, &g)) + while (glyphs->next (&g)) intersect_glyphs->add (g); done: return; } -#if 0 - /* The following implementation is faster asymptotically, but slower - * in practice. */ - if ((count >> 3) > glyphs->get_population ()) + unsigned count = rangeRecord.len; + if (count > glyphs->get_population () * hb_bit_storage (count) * 8) { for (hb_codepoint_t g = HB_SET_VALUE_INVALID; - hb_set_next (glyphs, &g);) - if (rangeRecord.as_array ().bfind (g)) + glyphs->next (&g);) + { + unsigned i; + if (rangeRecord.as_array ().bfind (g, &i) && + rangeRecord.arrayZ[i].value == klass) intersect_glyphs->add (g); + } return; } -#endif - for (unsigned int i = 0; i < count; i++) + for (auto &range : rangeRecord) { - if (rangeRecord[i].value != klass) continue; + if (range.value != klass) continue; - unsigned end = rangeRecord[i].last + 1; - for (hb_codepoint_t g = rangeRecord[i].first - 1; - hb_set_next (glyphs, &g) && g < end;) + unsigned end = range.last + 1; + for (hb_codepoint_t g = range.first - 1; + glyphs->next (&g) && g < end;) intersect_glyphs->add (g); } } @@ -1961,25 +1988,24 @@ struct ClassDefFormat2_4 { if (glyphs->is_empty ()) return; - unsigned count = rangeRecord.len; hb_codepoint_t g = HB_SET_VALUE_INVALID; - for (unsigned int i = 0; i < count; i++) + for (auto &range : rangeRecord) { - if (!hb_set_next (glyphs, &g)) + if (!glyphs->next (&g)) break; - if (g < rangeRecord[i].first) + if (g < range.first) { intersect_classes->add (0); break; } - g = rangeRecord[i].last; + g = range.last; } - if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g)) + if (g != HB_SET_VALUE_INVALID && glyphs->next (&g)) intersect_classes->add (0); - for (const auto& record : rangeRecord.iter ()) - if (record.intersects (*glyphs)) - intersect_classes->add (record.value); + for (const auto& range : rangeRecord) + if (range.intersects (*glyphs)) + intersect_classes->add (range.value); } protected: @@ -1994,10 +2020,8 @@ struct ClassDefFormat2_4 struct ClassDef { /* Has interface. */ - static constexpr unsigned SENTINEL = 0; - typedef unsigned int value_t; - value_t operator [] (hb_codepoint_t k) const { return get (k); } - bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; } + unsigned operator [] (hb_codepoint_t k) const { return get (k); } + bool has (hb_codepoint_t k) const { return (*this)[k]; } /* Projection. */ hb_codepoint_t operator () (hb_codepoint_t k) const { return get (k); } @@ -2015,6 +2039,19 @@ struct ClassDef } } + unsigned get_population () const + { + switch (u.format) { + case 1: return u.format1.get_population (); + case 2: return u.format2.get_population (); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.get_population (); + case 4: return u.format4.get_population (); +#endif + default:return NOT_COVERED; + } + } + template<typename Iterator, hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> bool serialize (hb_serialize_context_t *c, Iterator it_with_class_zero) @@ -2332,7 +2369,7 @@ struct VarRegionList { unsigned int backward = region_map.backward (r); if (backward >= region_count) return_trace (false); - memcpy (&axesZ[axisCount * r], &src->axesZ[axisCount * backward], VarRegionAxis::static_size * axisCount); + hb_memcpy (&axesZ[axisCount * r], &src->axesZ[axisCount * backward], VarRegionAxis::static_size * axisCount); } return_trace (true); @@ -2442,21 +2479,26 @@ struct VarData unsigned ri_count = src->regionIndices.len; enum delta_size_t { kZero=0, kNonWord, kWord }; hb_vector_t<delta_size_t> delta_sz; - hb_vector_t<unsigned int> ri_map; /* maps old index to new index */ + hb_vector_t<unsigned int> ri_map; /* maps new index to old index */ delta_sz.resize (ri_count); ri_map.resize (ri_count); unsigned int new_word_count = 0; unsigned int r; + const HBUINT8 *src_delta_bytes = src->get_delta_bytes (); + unsigned src_row_size = src->get_row_size (); + unsigned src_word_count = src->wordCount (); + bool src_long_words = src->longWords (); + bool has_long = false; - if (src->longWords ()) + if (src_long_words) { - for (r = 0; r < ri_count; r++) + for (r = 0; r < src_word_count; r++) { for (unsigned int i = 0; i < inner_map.get_next_value (); i++) { unsigned int old = inner_map.backward (i); - int32_t delta = src->get_item_delta (old, r); + int32_t delta = src->get_item_delta_fast (old, r, src_delta_bytes, src_row_size); if (delta < -65536 || 65535 < delta) { has_long = true; @@ -2470,11 +2512,13 @@ struct VarData signed max_threshold = has_long ? +65535 : +127; for (r = 0; r < ri_count; r++) { + bool short_circuit = src_long_words == has_long && src_word_count <= r; + delta_sz[r] = kZero; for (unsigned int i = 0; i < inner_map.get_next_value (); i++) { unsigned int old = inner_map.backward (i); - int32_t delta = src->get_item_delta (old, r); + int32_t delta = src->get_item_delta_fast (old, r, src_delta_bytes, src_row_size); if (delta < min_threshold || max_threshold < delta) { delta_sz[r] = kWord; @@ -2482,7 +2526,11 @@ struct VarData break; } else if (delta != 0) + { delta_sz[r] = kNonWord; + if (short_circuit) + break; + } } } @@ -2492,7 +2540,8 @@ struct VarData for (r = 0; r < ri_count; r++) if (delta_sz[r]) { - ri_map[r] = (delta_sz[r] == kWord)? word_index++ : non_word_index++; + unsigned new_r = (delta_sz[r] == kWord)? word_index++ : non_word_index++; + ri_map[new_r] = r; new_ri_count++; } @@ -2502,14 +2551,20 @@ struct VarData if (unlikely (!c->extend (this))) return_trace (false); - for (r = 0; r < ri_count; r++) - if (delta_sz[r]) regionIndices[ri_map[r]] = region_map[src->regionIndices[r]]; + for (r = 0; r < new_ri_count; r++) + regionIndices[r] = region_map[src->regionIndices[ri_map[r]]]; - for (unsigned int i = 0; i < itemCount; i++) + HBUINT8 *delta_bytes = get_delta_bytes (); + unsigned row_size = get_row_size (); + unsigned count = itemCount; + for (unsigned int i = 0; i < count; i++) { - unsigned int old = inner_map.backward (i); - for (unsigned int r = 0; r < ri_count; r++) - if (delta_sz[r]) set_item_delta (i, ri_map[r], src->get_item_delta (old, r)); + unsigned int old = inner_map.backward (i); + for (unsigned int r = 0; r < new_ri_count; r++) + set_item_delta_fast (i, r, + src->get_item_delta_fast (old, ri_map[r], + src_delta_bytes, src_row_size), + delta_bytes, row_size); } return_trace (true); @@ -2517,12 +2572,15 @@ struct VarData void collect_region_refs (hb_set_t ®ion_indices, const hb_inc_bimap_t &inner_map) const { + const HBUINT8 *delta_bytes = get_delta_bytes (); + unsigned row_size = get_row_size (); + for (unsigned int r = 0; r < regionIndices.len; r++) { - unsigned int region = regionIndices[r]; + unsigned int region = regionIndices.arrayZ[r]; if (region_indices.has (region)) continue; for (unsigned int i = 0; i < inner_map.get_next_value (); i++) - if (get_item_delta (inner_map.backward (i), r) != 0) + if (get_item_delta_fast (inner_map.backward (i), r, delta_bytes, row_size) != 0) { region_indices.add (region); break; @@ -2537,10 +2595,12 @@ struct VarData HBUINT8 *get_delta_bytes () { return &StructAfter<HBUINT8> (regionIndices); } - int32_t get_item_delta (unsigned int item, unsigned int region) const + int32_t get_item_delta_fast (unsigned int item, unsigned int region, + const HBUINT8 *delta_bytes, unsigned row_size) const { - if ( item >= itemCount || unlikely (region >= regionIndices.len)) return 0; - const HBINT8 *p = (const HBINT8 *) get_delta_bytes () + item * get_row_size (); + if (unlikely (item >= itemCount || region >= regionIndices.len)) return 0; + + const HBINT8 *p = (const HBINT8 *) delta_bytes + item * row_size; unsigned word_count = wordCount (); bool is_long = longWords (); if (is_long) @@ -2558,10 +2618,17 @@ struct VarData return (p + HBINT16::static_size * word_count)[region - word_count]; } } + int32_t get_item_delta (unsigned int item, unsigned int region) const + { + return get_item_delta_fast (item, region, + get_delta_bytes (), + get_row_size ()); + } - void set_item_delta (unsigned int item, unsigned int region, int32_t delta) + void set_item_delta_fast (unsigned int item, unsigned int region, int32_t delta, + HBUINT8 *delta_bytes, unsigned row_size) { - HBINT8 *p = (HBINT8 *)get_delta_bytes () + item * get_row_size (); + HBINT8 *p = (HBINT8 *) delta_bytes + item * row_size; unsigned word_count = wordCount (); bool is_long = longWords (); if (is_long) @@ -2579,6 +2646,12 @@ struct VarData (p + HBINT16::static_size * word_count)[region - word_count] = delta; } } + void set_item_delta (unsigned int item, unsigned int region, int32_t delta) + { + set_item_delta_fast (item, region, delta, + get_delta_bytes (), + get_row_size ()); + } bool longWords () const { return wordSizeCount & 0x8000u /* LONG_WORDS */; } unsigned wordCount () const { return wordSizeCount & 0x7FFFu /* WORD_DELTA_COUNT_MASK */; } @@ -2642,6 +2715,14 @@ struct VariationStore unsigned int inner = index & 0xFFFF; return get_delta (outer, inner, coords, coord_count, cache); } + float get_delta (unsigned int index, + hb_array_t<int> coords, + VarRegionList::cache_t *cache = nullptr) const + { + return get_delta (index, + coords.arrayZ, coords.length, + cache); + } bool sanitize (hb_sanitize_context_t *c) const { @@ -2948,7 +3029,7 @@ struct ConditionSet // all conditions met if (num_kept_cond == 0) return DROP_COND_WITH_VAR; - + //check if condition_set is unique with variations if (c->conditionset_map->has (p)) //duplicate found, drop the entire record @@ -3420,17 +3501,16 @@ struct VariationDevice { TRACE_SERIALIZE (this); if (!layout_variation_idx_delta_map) return_trace (nullptr); - auto snap = c->snapshot (); + + hb_pair_t<unsigned, int> *v; + if (!layout_variation_idx_delta_map->has (varIdx, &v)) + return_trace (nullptr); + + c->start_zerocopy (this->static_size); auto *out = c->embed (this); if (unlikely (!out)) return_trace (nullptr); - /* TODO Just get() and bail if NO_VARIATION. Needs to setup the map to return that. */ - if (!layout_variation_idx_delta_map->has (varIdx)) - { - c->revert (snap); - return_trace (nullptr); - } - unsigned new_idx = hb_first (layout_variation_idx_delta_map->get (varIdx)); + unsigned new_idx = hb_first (*v); out->varIdx = new_idx; return_trace (out); } diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh index 22925fdfa9..a84edef162 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh @@ -73,7 +73,7 @@ struct AttachList if (point_count) { - + points.sub_array (start_offset, point_count) + + points.as_array ().sub_array (start_offset, point_count) | hb_sink (hb_array (point_array, *point_count)) ; } @@ -322,7 +322,7 @@ struct LigGlyph { if (caret_count) { - + carets.sub_array (start_offset, caret_count) + + carets.as_array ().sub_array (start_offset, caret_count) | hb_map (hb_add (this)) | hb_map ([&] (const CaretValue &value) { return value.get_caret_value (font, direction, glyph_id, var_store); }) | hb_sink (hb_array (caret_array, *caret_count)) diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh index d1d94255f4..04ccefd108 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh @@ -100,8 +100,8 @@ struct hb_closure_context_t : bool is_lookup_done (unsigned int lookup_index) { - if (done_lookups_glyph_count->in_error () || - done_lookups_glyph_set->in_error ()) + if (unlikely (done_lookups_glyph_count->in_error () || + done_lookups_glyph_set->in_error ())) return true; /* Have we visited this lookup with the current set of glyphs? */ @@ -535,7 +535,12 @@ struct hb_ot_apply_context_t : bool next (unsigned *unsafe_to = nullptr) { assert (num_items > 0); - while (idx + num_items < end) + /* The alternate condition below is faster at string boundaries, + * but produces subpar "unsafe-to-concat" values. */ + signed stop = (signed) end - (signed) num_items; + if (c->buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) + stop = (signed) end - 1; + while ((signed) idx < stop) { idx++; hb_glyph_info_t &info = c->buffer->info[idx]; @@ -568,7 +573,12 @@ struct hb_ot_apply_context_t : bool prev (unsigned *unsafe_from = nullptr) { assert (num_items > 0); - while (idx > num_items - 1) + /* The alternate condition below is faster at string boundaries, + * but produces subpar "unsafe-to-concat" values. */ + unsigned stop = num_items - 1; + if (c->buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) + stop = 1 - 1; + while (idx > stop) { idx--; hb_glyph_info_t &info = c->buffer->out_info[idx]; @@ -672,6 +682,7 @@ struct hb_ot_apply_context_t : const GDEF &gdef; const VariationStore &var_store; VariationStore::cache_t *var_store_cache; + hb_set_digest_t digest; hb_direction_t direction; hb_mask_t lookup_mask = 1; @@ -707,6 +718,7 @@ struct hb_ot_apply_context_t : nullptr #endif ), + digest (buffer_->digest ()), direction (buffer_->props.direction), has_glyph_classes (gdef.has_glyph_classes ()) { init_iters (); } @@ -781,8 +793,10 @@ struct hb_ot_apply_context_t : void _set_glyph_class (hb_codepoint_t glyph_index, unsigned int class_guess = 0, bool ligature = false, - bool component = false) const + bool component = false) { + digest.add (glyph_index); + if (new_syllables != (unsigned) -1) buffer->cur().syllable() = new_syllables; @@ -815,24 +829,24 @@ struct hb_ot_apply_context_t : _hb_glyph_info_set_glyph_props (&buffer->cur(), props); } - void replace_glyph (hb_codepoint_t glyph_index) const + void replace_glyph (hb_codepoint_t glyph_index) { _set_glyph_class (glyph_index); (void) buffer->replace_glyph (glyph_index); } - void replace_glyph_inplace (hb_codepoint_t glyph_index) const + void replace_glyph_inplace (hb_codepoint_t glyph_index) { _set_glyph_class (glyph_index); buffer->cur().codepoint = glyph_index; } void replace_glyph_with_ligature (hb_codepoint_t glyph_index, - unsigned int class_guess) const + unsigned int class_guess) { _set_glyph_class (glyph_index, class_guess, true); (void) buffer->replace_glyph (glyph_index); } void output_glyph_for_component (hb_codepoint_t glyph_index, - unsigned int class_guess) const + unsigned int class_guess) { _set_glyph_class (glyph_index, class_guess, false, true); (void) buffer->output_glyph (glyph_index); @@ -844,7 +858,7 @@ struct hb_accelerate_subtables_context_t : hb_dispatch_context_t<hb_accelerate_subtables_context_t> { template <typename Type> - static inline bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c) + static inline bool apply_to (const void *obj, hb_ot_apply_context_t *c) { const Type *typed_obj = (const Type *) obj; return typed_obj->apply (c); @@ -852,30 +866,30 @@ struct hb_accelerate_subtables_context_t : #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE template <typename T> - static inline auto apply_cached_ (const T *obj, OT::hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply (c, true) ) + static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply (c, true) ) template <typename T> - static inline auto apply_cached_ (const T *obj, OT::hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (bool, obj->apply (c) ) + static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (bool, obj->apply (c) ) template <typename Type> - static inline bool apply_cached_to (const void *obj, OT::hb_ot_apply_context_t *c) + static inline bool apply_cached_to (const void *obj, hb_ot_apply_context_t *c) { const Type *typed_obj = (const Type *) obj; return apply_cached_ (typed_obj, c, hb_prioritize); } template <typename T> - static inline auto cache_func_ (const T *obj, OT::hb_ot_apply_context_t *c, bool enter, hb_priority<1>) HB_RETURN (bool, obj->cache_func (c, enter) ) + static inline auto cache_func_ (const T *obj, hb_ot_apply_context_t *c, bool enter, hb_priority<1>) HB_RETURN (bool, obj->cache_func (c, enter) ) template <typename T> - static inline bool cache_func_ (const T *obj, OT::hb_ot_apply_context_t *c, bool enter, hb_priority<0>) { return false; } + static inline bool cache_func_ (const T *obj, hb_ot_apply_context_t *c, bool enter, hb_priority<0>) { return false; } template <typename Type> - static inline bool cache_func_to (const void *obj, OT::hb_ot_apply_context_t *c, bool enter) + static inline bool cache_func_to (const void *obj, hb_ot_apply_context_t *c, bool enter) { const Type *typed_obj = (const Type *) obj; return cache_func_ (typed_obj, c, enter, hb_prioritize); } #endif - typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_ot_apply_context_t *c); - typedef bool (*hb_cache_func_t) (const void *obj, OT::hb_ot_apply_context_t *c, bool enter); + typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c); + typedef bool (*hb_cache_func_t) (const void *obj, hb_ot_apply_context_t *c, bool enter); struct hb_applicable_t { @@ -901,20 +915,20 @@ struct hb_accelerate_subtables_context_t : obj_.get_coverage ().collect_coverage (&digest); } - bool apply (OT::hb_ot_apply_context_t *c) const + bool apply (hb_ot_apply_context_t *c) const { return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c); } #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - bool apply_cached (OT::hb_ot_apply_context_t *c) const + bool apply_cached (hb_ot_apply_context_t *c) const { return digest.may_have (c->buffer->cur().codepoint) && apply_cached_func (obj, c); } - bool cache_enter (OT::hb_ot_apply_context_t *c) const + bool cache_enter (hb_ot_apply_context_t *c) const { return cache_func (obj, c, true); } - void cache_leave (OT::hb_ot_apply_context_t *c) const + void cache_leave (hb_ot_apply_context_t *c) const { cache_func (obj, c, false); } @@ -988,8 +1002,8 @@ struct hb_accelerate_subtables_context_t : }; -typedef bool (*intersects_func_t) (const hb_set_t *glyphs, unsigned value, const void *data); -typedef void (*intersected_glyphs_func_t) (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs); +typedef bool (*intersects_func_t) (const hb_set_t *glyphs, unsigned value, const void *data, void *cache); +typedef void (*intersected_glyphs_func_t) (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs, void *cache); typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, unsigned value, const void *data); typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data); @@ -1012,16 +1026,25 @@ struct ChainContextApplyFuncs }; -static inline bool intersects_glyph (const hb_set_t *glyphs, unsigned value, const void *data HB_UNUSED) +static inline bool intersects_glyph (const hb_set_t *glyphs, unsigned value, const void *data HB_UNUSED, void *cache HB_UNUSED) { return glyphs->has (value); } -static inline bool intersects_class (const hb_set_t *glyphs, unsigned value, const void *data) +static inline bool intersects_class (const hb_set_t *glyphs, unsigned value, const void *data, void *cache) { const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); - return class_def.intersects_class (glyphs, value); + hb_map_t *map = (hb_map_t *) cache; + + hb_codepoint_t *cached_v; + if (map->has (value, &cached_v)) + return *cached_v; + + bool v = class_def.intersects_class (glyphs, value); + map->set (value, v); + + return v; } -static inline bool intersects_coverage (const hb_set_t *glyphs, unsigned value, const void *data) +static inline bool intersects_coverage (const hb_set_t *glyphs, unsigned value, const void *data, void *cache HB_UNUSED) { Offset16To<Coverage> coverage; coverage = value; @@ -1029,17 +1052,36 @@ static inline bool intersects_coverage (const hb_set_t *glyphs, unsigned value, } -static inline void intersected_glyph (const hb_set_t *glyphs HB_UNUSED, const void *data, unsigned value, hb_set_t *intersected_glyphs) +static inline void intersected_glyph (const hb_set_t *glyphs HB_UNUSED, const void *data, unsigned value, hb_set_t *intersected_glyphs, HB_UNUSED void *cache) { unsigned g = reinterpret_cast<const HBUINT16 *>(data)[value]; intersected_glyphs->add (g); } -static inline void intersected_class_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs) + +using intersected_class_cache_t = hb_hashmap_t<unsigned, hb_set_t>; + +static inline void intersected_class_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs, void *cache) { const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); - class_def.intersected_class_glyphs (glyphs, value, intersected_glyphs); + + intersected_class_cache_t *map = (intersected_class_cache_t *) cache; + + hb_set_t *cached_v; + if (map->has (value, &cached_v)) + { + intersected_glyphs->union_ (*cached_v); + return; + } + + hb_set_t v; + class_def.intersected_class_glyphs (glyphs, value, &v); + + intersected_glyphs->union_ (v); + + map->set (value, std::move (v)); } -static inline void intersected_coverage_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs) + +static inline void intersected_coverage_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs, HB_UNUSED void *cache) { Offset16To<Coverage> coverage; coverage = value; @@ -1052,10 +1094,11 @@ static inline bool array_is_subset_of (const hb_set_t *glyphs, unsigned int count, const HBUINT values[], intersects_func_t intersects_func, - const void *intersects_data) + const void *intersects_data, + void *cache) { for (const auto &_ : + hb_iter (values, count)) - if (!intersects_func (glyphs, _, intersects_data)) return false; + if (!intersects_func (glyphs, _, intersects_data, cache)) return false; return true; } @@ -1492,7 +1535,8 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c, unsigned value, ContextFormat context_format, const void *data, - intersected_glyphs_func_t intersected_glyphs_func) + intersected_glyphs_func_t intersected_glyphs_func, + void *cache) { hb_set_t *covered_seq_indicies = hb_set_create (); for (unsigned int i = 0; i < lookupCount; i++) @@ -1513,7 +1557,7 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c, pos_glyphs.add (value); break; case ContextFormat::ClassBasedContext: - intersected_glyphs_func (&c->parent_active_glyphs (), data, value, &pos_glyphs); + intersected_glyphs_func (&c->parent_active_glyphs (), data, value, &pos_glyphs, cache); break; case ContextFormat::CoverageBasedContext: pos_glyphs.set (c->parent_active_glyphs ()); @@ -1530,7 +1574,7 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c, input_value = input[seqIndex - 1]; } - intersected_glyphs_func (c->glyphs, input_data, input_value, &pos_glyphs); + intersected_glyphs_func (c->glyphs, input_data, input_value, &pos_glyphs, cache); } } @@ -1710,6 +1754,8 @@ struct ContextClosureLookupContext ContextClosureFuncs funcs; ContextFormat context_format; const void *intersects_data; + void *intersects_cache; + void *intersected_glyphs_cache; }; struct ContextCollectGlyphsLookupContext @@ -1732,7 +1778,9 @@ static inline bool context_intersects (const hb_set_t *glyphs, { return array_is_subset_of (glyphs, inputCount ? inputCount - 1 : 0, input, - lookup_context.funcs.intersects, lookup_context.intersects_data); + lookup_context.funcs.intersects, + lookup_context.intersects_data, + lookup_context.intersects_cache); } template <typename HBUINT> @@ -1753,7 +1801,8 @@ static inline void context_closure_lookup (hb_closure_context_t *c, value, lookup_context.context_format, lookup_context.intersects_data, - lookup_context.funcs.intersected_glyphs); + lookup_context.funcs.intersected_glyphs, + lookup_context.intersected_glyphs_cache); } template <typename HBUINT> @@ -1777,7 +1826,7 @@ static inline bool context_would_apply_lookup (hb_would_apply_context_t *c, const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookupCount HB_UNUSED, const LookupRecord lookupRecord[] HB_UNUSED, - ContextApplyLookupContext &lookup_context) + const ContextApplyLookupContext &lookup_context) { return would_match_input (c, inputCount, input, @@ -1790,7 +1839,7 @@ static inline bool context_apply_lookup (hb_ot_apply_context_t *c, const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], - ContextApplyLookupContext &lookup_context) + const ContextApplyLookupContext &lookup_context) { unsigned match_end = 0; unsigned match_positions[HB_MAX_CONTEXT_LENGTH]; @@ -1858,7 +1907,7 @@ struct Rule } bool would_apply (hb_would_apply_context_t *c, - ContextApplyLookupContext &lookup_context) const + const ContextApplyLookupContext &lookup_context) const { const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> (inputZ.as_array (inputCount ? inputCount - 1 : 0)); @@ -1869,7 +1918,7 @@ struct Rule } bool apply (hb_ot_apply_context_t *c, - ContextApplyLookupContext &lookup_context) const + const ContextApplyLookupContext &lookup_context) const { TRACE_APPLY (this); const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> @@ -1989,7 +2038,7 @@ struct RuleSet } bool would_apply (hb_would_apply_context_t *c, - ContextApplyLookupContext &lookup_context) const + const ContextApplyLookupContext &lookup_context) const { return + hb_iter (rule) @@ -2000,7 +2049,7 @@ struct RuleSet } bool apply (hb_ot_apply_context_t *c, - ContextApplyLookupContext &lookup_context) const + const ContextApplyLookupContext &lookup_context) const { TRACE_APPLY (this); return_trace ( @@ -2108,7 +2157,7 @@ struct ContextFormat1_4 void closure_lookups (hb_closure_lookups_context_t *c) const { struct ContextClosureLookupContext lookup_context = { - {intersects_glyph, intersected_glyph}, + {intersects_glyph, nullptr}, ContextFormat::SimpleContext, nullptr }; @@ -2220,10 +2269,12 @@ struct ContextFormat2_5 const ClassDef &class_def = this+classDef; + hb_map_t cache; struct ContextClosureLookupContext lookup_context = { - {intersects_class, intersected_class_glyphs}, + {intersects_class, nullptr}, ContextFormat::ClassBasedContext, - &class_def + &class_def, + &cache }; hb_set_t retained_coverage_glyphs; @@ -2259,10 +2310,14 @@ struct ContextFormat2_5 const ClassDef &class_def = this+classDef; + hb_map_t cache; + intersected_class_cache_t intersected_cache; struct ContextClosureLookupContext lookup_context = { {intersects_class, intersected_class_glyphs}, ContextFormat::ClassBasedContext, - &class_def + &class_def, + &cache, + &intersected_cache }; + hb_enumerate (ruleSet) @@ -2286,10 +2341,12 @@ struct ContextFormat2_5 const ClassDef &class_def = this+classDef; + hb_map_t cache; struct ContextClosureLookupContext lookup_context = { - {intersects_class, intersected_class_glyphs}, + {intersects_class, nullptr}, ContextFormat::ClassBasedContext, - &class_def + &class_def, + &cache }; + hb_iter (ruleSet) @@ -2407,6 +2464,7 @@ struct ContextFormat2_5 const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups; bool ret = true; int non_zero_index = -1, index = 0; + auto snapshot = c->serializer->snapshot(); for (const auto& _ : + hb_enumerate (ruleSet) | hb_filter (klass_map, hb_first)) { @@ -2418,8 +2476,10 @@ struct ContextFormat2_5 } if (coverage_glyph_classes.has (_.first) && - o->serialize_subset (c, _.second, this, lookup_map, &klass_map)) + o->serialize_subset (c, _.second, this, lookup_map, &klass_map)) { non_zero_index = index; + snapshot = c->serializer->snapshot(); + } index++; } @@ -2433,6 +2493,7 @@ struct ContextFormat2_5 out->ruleSet.pop (); index--; } + c->serializer->revert (snapshot); return_trace (bool (out->ruleSet)); } @@ -2469,7 +2530,7 @@ struct ContextFormat3 return false; struct ContextClosureLookupContext lookup_context = { - {intersects_coverage, intersected_coverage_glyphs}, + {intersects_coverage, nullptr}, ContextFormat::CoverageBasedContext, this }; @@ -2655,6 +2716,8 @@ struct ChainContextClosureLookupContext ContextClosureFuncs funcs; ContextFormat context_format; const void *intersects_data[3]; + void *intersects_cache[3]; + void *intersected_glyphs_cache; }; struct ChainContextCollectGlyphsLookupContext @@ -2681,13 +2744,19 @@ static inline bool chain_context_intersects (const hb_set_t *glyphs, { return array_is_subset_of (glyphs, backtrackCount, backtrack, - lookup_context.funcs.intersects, lookup_context.intersects_data[0]) + lookup_context.funcs.intersects, + lookup_context.intersects_data[0], + lookup_context.intersects_cache[0]) && array_is_subset_of (glyphs, inputCount ? inputCount - 1 : 0, input, - lookup_context.funcs.intersects, lookup_context.intersects_data[1]) + lookup_context.funcs.intersects, + lookup_context.intersects_data[1], + lookup_context.intersects_cache[1]) && array_is_subset_of (glyphs, lookaheadCount, lookahead, - lookup_context.funcs.intersects, lookup_context.intersects_data[2]); + lookup_context.funcs.intersects, + lookup_context.intersects_data[2], + lookup_context.intersects_cache[2]); } template <typename HBUINT> @@ -2714,7 +2783,8 @@ static inline void chain_context_closure_lookup (hb_closure_context_t *c, value, lookup_context.context_format, lookup_context.intersects_data[1], - lookup_context.funcs.intersected_glyphs); + lookup_context.funcs.intersected_glyphs, + lookup_context.intersected_glyphs_cache); } template <typename HBUINT> @@ -2752,7 +2822,7 @@ static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c const HBUINT lookahead[] HB_UNUSED, unsigned int lookupCount HB_UNUSED, const LookupRecord lookupRecord[] HB_UNUSED, - ChainContextApplyLookupContext &lookup_context) + const ChainContextApplyLookupContext &lookup_context) { return (c->zero_context ? !backtrackCount && !lookaheadCount : true) && would_match_input (c, @@ -2770,7 +2840,7 @@ static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c, const HBUINT lookahead[], unsigned int lookupCount, const LookupRecord lookupRecord[], - ChainContextApplyLookupContext &lookup_context) + const ChainContextApplyLookupContext &lookup_context) { unsigned end_index = c->buffer->idx; unsigned match_end = 0; @@ -2864,7 +2934,7 @@ struct ChainRule } bool would_apply (hb_would_apply_context_t *c, - ChainContextApplyLookupContext &lookup_context) const + const ChainContextApplyLookupContext &lookup_context) const { const auto &input = StructAfter<decltype (inputX)> (backtrack); const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); @@ -2876,7 +2946,8 @@ struct ChainRule lookup.arrayZ, lookup_context); } - bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const + bool apply (hb_ot_apply_context_t *c, + const ChainContextApplyLookupContext &lookup_context) const { TRACE_APPLY (this); const auto &input = StructAfter<decltype (inputX)> (backtrack); @@ -3042,7 +3113,8 @@ struct ChainRuleSet ; } - bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const + bool would_apply (hb_would_apply_context_t *c, + const ChainContextApplyLookupContext &lookup_context) const { return + hb_iter (rule) @@ -3052,7 +3124,8 @@ struct ChainRuleSet ; } - bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const + bool apply (hb_ot_apply_context_t *c, + const ChainContextApplyLookupContext &lookup_context) const { TRACE_APPLY (this); return_trace ( @@ -3166,7 +3239,7 @@ struct ChainContextFormat1_4 void closure_lookups (hb_closure_lookups_context_t *c) const { struct ChainContextClosureLookupContext lookup_context = { - {intersects_glyph, intersected_glyph}, + {intersects_glyph, nullptr}, ContextFormat::SimpleContext, {nullptr, nullptr, nullptr} }; @@ -3278,12 +3351,14 @@ struct ChainContextFormat2_5 const ClassDef &input_class_def = this+inputClassDef; const ClassDef &lookahead_class_def = this+lookaheadClassDef; + hb_map_t caches[3] = {}; struct ChainContextClosureLookupContext lookup_context = { - {intersects_class, intersected_class_glyphs}, + {intersects_class, nullptr}, ContextFormat::ClassBasedContext, {&backtrack_class_def, &input_class_def, - &lookahead_class_def} + &lookahead_class_def}, + {&caches[0], &caches[1], &caches[2]} }; hb_set_t retained_coverage_glyphs; @@ -3321,12 +3396,16 @@ struct ChainContextFormat2_5 const ClassDef &input_class_def = this+inputClassDef; const ClassDef &lookahead_class_def = this+lookaheadClassDef; + hb_map_t caches[3] = {}; + intersected_class_cache_t intersected_cache; struct ChainContextClosureLookupContext lookup_context = { {intersects_class, intersected_class_glyphs}, ContextFormat::ClassBasedContext, {&backtrack_class_def, &input_class_def, - &lookahead_class_def} + &lookahead_class_def}, + {&caches[0], &caches[1], &caches[2]}, + &intersected_cache }; + hb_enumerate (ruleSet) @@ -3352,12 +3431,14 @@ struct ChainContextFormat2_5 const ClassDef &input_class_def = this+inputClassDef; const ClassDef &lookahead_class_def = this+lookaheadClassDef; + hb_map_t caches[3] = {}; struct ChainContextClosureLookupContext lookup_context = { - {intersects_class, intersected_class_glyphs}, + {intersects_class, nullptr}, ContextFormat::ClassBasedContext, {&backtrack_class_def, &input_class_def, - &lookahead_class_def} + &lookahead_class_def}, + {&caches[0], &caches[1], &caches[2]} }; + hb_iter (ruleSet) @@ -3587,7 +3668,7 @@ struct ChainContextFormat3 const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); struct ChainContextClosureLookupContext lookup_context = { - {intersects_coverage, intersected_coverage_glyphs}, + {intersects_coverage, nullptr}, ContextFormat::CoverageBasedContext, {this, this, this} }; @@ -3938,13 +4019,14 @@ struct hb_ot_layout_lookup_accelerator_t template <typename TLookup> void init (const TLookup &lookup) { - digest.init (); - lookup.collect_coverage (&digest); - subtables.init (); - OT::hb_accelerate_subtables_context_t c_accelerate_subtables (subtables); + hb_accelerate_subtables_context_t c_accelerate_subtables (subtables); lookup.dispatch (&c_accelerate_subtables); + digest.init (); + for (auto& subtable : hb_iter (subtables)) + digest.add (subtable.digest); + #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE cache_user_idx = c_accelerate_subtables.cache_user_idx; for (unsigned i = 0; i < subtables.length; i++) @@ -3962,21 +4044,25 @@ struct hb_ot_layout_lookup_accelerator_t #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE if (use_cache) { - for (unsigned int i = 0; i < subtables.length; i++) - if (subtables[i].apply_cached (c)) - return true; + return + + hb_iter (subtables) + | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply_cached (c); }) + | hb_any + ; } else #endif { - for (unsigned int i = 0; i < subtables.length; i++) - if (subtables[i].apply (c)) - return true; + return + + hb_iter (subtables) + | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply (c); }) + | hb_any + ; } return false; } - bool cache_enter (OT::hb_ot_apply_context_t *c) const + bool cache_enter (hb_ot_apply_context_t *c) const { #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE return cache_user_idx != (unsigned) -1 && @@ -3985,7 +4071,7 @@ struct hb_ot_layout_lookup_accelerator_t return false; #endif } - void cache_leave (OT::hb_ot_apply_context_t *c) const + void cache_leave (hb_ot_apply_context_t *c) const { #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE subtables[cache_user_idx].cache_leave (c); @@ -3993,8 +4079,8 @@ struct hb_ot_layout_lookup_accelerator_t } - private: hb_set_digest_t digest; + private: hb_accelerate_subtables_context_t::array_t subtables; #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE unsigned cache_user_idx = (unsigned) -1; @@ -4255,11 +4341,11 @@ struct GSUBGPOS hb_set_t *lookup_indexes /* IN/OUT */) const { hb_set_t visited_lookups, inactive_lookups; - OT::hb_closure_lookups_context_t c (face, glyphs, &visited_lookups, &inactive_lookups); + hb_closure_lookups_context_t c (face, glyphs, &visited_lookups, &inactive_lookups); c.set_recurse_func (TLookup::template dispatch_recurse_func<hb_closure_lookups_context_t>); - for (unsigned lookup_index : + hb_iter (lookup_indexes)) + for (unsigned lookup_index : *lookup_indexes) reinterpret_cast<const TLookup &> (get_lookup (lookup_index)).closure_lookups (&c, lookup_index); hb_set_union (lookup_indexes, &visited_lookups); @@ -4301,7 +4387,7 @@ struct GSUBGPOS } #endif - for (unsigned i : feature_indices->iter()) + for (unsigned i : hb_iter (feature_indices)) { hb_tag_t tag = get_feature_tag (i); if (tag == HB_TAG ('p', 'r', 'e', 'f')) diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.cc b/thirdparty/harfbuzz/src/hb-ot-layout.cc index dbb30076a2..e8091ec3e0 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.cc +++ b/thirdparty/harfbuzz/src/hb-ot-layout.cc @@ -1465,56 +1465,6 @@ hb_ot_layout_substitute_start (hb_font_t *font, _hb_ot_layout_set_glyph_props (font, buffer); } -void -hb_ot_layout_delete_glyphs_inplace (hb_buffer_t *buffer, - bool (*filter) (const hb_glyph_info_t *info)) -{ - /* Merge clusters and delete filtered glyphs. - * NOTE! We can't use out-buffer as we have positioning data. */ - unsigned int j = 0; - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - hb_glyph_position_t *pos = buffer->pos; - for (unsigned int i = 0; i < count; i++) - { - if (filter (&info[i])) - { - /* Merge clusters. - * Same logic as buffer->delete_glyph(), but for in-place removal. */ - - unsigned int cluster = info[i].cluster; - if (i + 1 < count && cluster == info[i + 1].cluster) - continue; /* Cluster survives; do nothing. */ - - if (j) - { - /* Merge cluster backward. */ - if (cluster < info[j - 1].cluster) - { - unsigned int mask = info[i].mask; - unsigned int old_cluster = info[j - 1].cluster; - for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--) - buffer->set_cluster (info[k - 1], cluster, mask); - } - continue; - } - - if (i + 1 < count) - buffer->merge_clusters (i, i + 2); /* Merge cluster forward. */ - - continue; - } - - if (j != i) - { - info[j] = info[i]; - pos[j] = pos[i]; - } - j++; - } - buffer->len = j; -} - /** * hb_ot_layout_lookup_substitute_closure: * @face: #hb_face_t to work upon @@ -1867,7 +1817,7 @@ apply_forward (OT::hb_ot_apply_context_t *c, while (buffer->idx < buffer->len && buffer->successful) { bool applied = false; - if (accel.may_have (buffer->cur().codepoint) && + if (accel.digest.may_have (buffer->cur().codepoint) && (buffer->cur().mask & c->lookup_mask) && c->check_glyph_property (&buffer->cur(), c->lookup_props)) { @@ -1894,7 +1844,7 @@ apply_backward (OT::hb_ot_apply_context_t *c, hb_buffer_t *buffer = c->buffer; do { - if (accel.may_have (buffer->cur().codepoint) && + if (accel.digest.may_have (buffer->cur().codepoint) && (buffer->cur().mask & c->lookup_mask) && c->check_glyph_property (&buffer->cur(), c->lookup_props)) ret |= accel.apply (c, false); @@ -1908,15 +1858,16 @@ apply_backward (OT::hb_ot_apply_context_t *c, } template <typename Proxy> -static inline void +static inline bool apply_string (OT::hb_ot_apply_context_t *c, const typename Proxy::Lookup &lookup, const OT::hb_ot_layout_lookup_accelerator_t &accel) { + bool ret = false; hb_buffer_t *buffer = c->buffer; if (unlikely (!buffer->len || !c->lookup_mask)) - return; + return ret; c->set_lookup_props (lookup.get_props ()); @@ -1927,7 +1878,7 @@ apply_string (OT::hb_ot_apply_context_t *c, buffer->clear_output (); buffer->idx = 0; - apply_forward (c, accel); + ret = apply_forward (c, accel); if (!Proxy::always_inplace) buffer->sync (); @@ -1937,8 +1888,10 @@ apply_string (OT::hb_ot_apply_context_t *c, /* in-place backward substitution/positioning */ assert (!buffer->have_output); buffer->idx = buffer->len - 1; - apply_backward (c, accel); + ret = apply_backward (c, accel); } + + return ret; } template <typename Proxy> @@ -1957,23 +1910,42 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, const stage_map_t *stage = &stages[table_index][stage_index]; for (; i < stage->last_lookup; i++) { - unsigned int lookup_index = lookups[table_index][i].index; - if (!buffer->message (font, "start lookup %d", lookup_index)) continue; - c.set_lookup_index (lookup_index); - c.set_lookup_mask (lookups[table_index][i].mask); - c.set_auto_zwj (lookups[table_index][i].auto_zwj); - c.set_auto_zwnj (lookups[table_index][i].auto_zwnj); - c.set_random (lookups[table_index][i].random); - c.set_per_syllable (lookups[table_index][i].per_syllable); - - apply_string<Proxy> (&c, - proxy.table.get_lookup (lookup_index), - proxy.accels[lookup_index]); - (void) buffer->message (font, "end lookup %d", lookup_index); + auto &lookup = lookups[table_index][i]; + + unsigned int lookup_index = lookup.index; + if (!buffer->message (font, "start lookup %d feature '%c%c%c%c'", lookup_index, HB_UNTAG (lookup.feature_tag))) continue; + + /* c.digest is a digest of all the current glyphs in the buffer + * (plus some past glyphs). + * + * Only try applying the lookup if there is any overlap. */ + if (proxy.accels[lookup_index].digest.may_have (c.digest)) + { + c.set_lookup_index (lookup_index); + c.set_lookup_mask (lookup.mask); + c.set_auto_zwj (lookup.auto_zwj); + c.set_auto_zwnj (lookup.auto_zwnj); + c.set_random (lookup.random); + c.set_per_syllable (lookup.per_syllable); + + apply_string<Proxy> (&c, + proxy.table.get_lookup (lookup_index), + proxy.accels[lookup_index]); + } + else + (void) buffer->message (font, "skipped lookup %d feature '%c%c%c%c' because no glyph matches", lookup_index, HB_UNTAG (lookup.feature_tag)); + + (void) buffer->message (font, "end lookup %d feature '%c%c%c%c'", lookup_index, HB_UNTAG (lookup.feature_tag)); } if (stage->pause_func) - stage->pause_func (plan, font, buffer); + { + if (stage->pause_func (plan, font, buffer)) + { + /* Refresh working buffer digest since buffer changed. */ + c.digest = buffer->digest (); + } + } } } diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.hh b/thirdparty/harfbuzz/src/hb-ot-layout.hh index de06610cb5..9505d5f147 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout.hh @@ -102,10 +102,6 @@ HB_INTERNAL void hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer); -HB_INTERNAL void -hb_ot_layout_delete_glyphs_inplace (hb_buffer_t *buffer, - bool (*filter) (const hb_glyph_info_t *info)); - namespace OT { struct hb_ot_apply_context_t; struct hb_ot_layout_lookup_accelerator_t; @@ -552,7 +548,7 @@ _hb_glyph_info_clear_substituted (hb_glyph_info_t *info) info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED); } -static inline void +static inline bool _hb_clear_substitution_flags (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) @@ -561,6 +557,7 @@ _hb_clear_substitution_flags (const hb_ot_shape_plan_t *plan HB_UNUSED, unsigned int count = buffer->len; for (unsigned int i = 0; i < count; i++) _hb_glyph_info_clear_substituted (&info[i]); + return false; } diff --git a/thirdparty/harfbuzz/src/hb-ot-map.cc b/thirdparty/harfbuzz/src/hb-ot-map.cc index 39215b335f..8882dbaccb 100644 --- a/thirdparty/harfbuzz/src/hb-ot-map.cc +++ b/thirdparty/harfbuzz/src/hb-ot-map.cc @@ -45,7 +45,7 @@ void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_o hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_, const hb_segment_properties_t &props_) { - memset (this, 0, sizeof (*this)); + hb_memset (this, 0, sizeof (*this)); feature_infos.init (); for (unsigned int table_index = 0; table_index < 2; table_index++) @@ -133,7 +133,8 @@ hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m, bool auto_zwnj, bool auto_zwj, bool random, - bool per_syllable) + bool per_syllable, + hb_tag_t feature_tag) { unsigned int lookup_indices[32]; unsigned int offset, len; @@ -162,6 +163,7 @@ hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m, lookup->auto_zwj = auto_zwj; lookup->random = random; lookup->per_syllable = per_syllable; + lookup->feature_tag = feature_tag; } offset += len; @@ -212,24 +214,26 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, if (feature_infos.length) { feature_infos.qsort (); + auto *f = feature_infos.arrayZ; unsigned int j = 0; - for (unsigned int i = 1; i < feature_infos.length; i++) - if (feature_infos[i].tag != feature_infos[j].tag) - feature_infos[++j] = feature_infos[i]; + unsigned count = feature_infos.length; + for (unsigned int i = 1; i < count; i++) + if (f[i].tag != f[j].tag) + f[++j] = f[i]; else { - if (feature_infos[i].flags & F_GLOBAL) { - feature_infos[j].flags |= F_GLOBAL; - feature_infos[j].max_value = feature_infos[i].max_value; - feature_infos[j].default_value = feature_infos[i].default_value; + if (f[i].flags & F_GLOBAL) { + f[j].flags |= F_GLOBAL; + f[j].max_value = f[i].max_value; + f[j].default_value = f[i].default_value; } else { - if (feature_infos[j].flags & F_GLOBAL) - feature_infos[j].flags ^= F_GLOBAL; - feature_infos[j].max_value = hb_max (feature_infos[j].max_value, feature_infos[i].max_value); + if (f[j].flags & F_GLOBAL) + f[j].flags ^= F_GLOBAL; + f[j].max_value = hb_max (f[j].max_value, f[i].max_value); /* Inherit default_value from j */ } - feature_infos[j].flags |= (feature_infos[i].flags & F_HAS_FALLBACK); - feature_infos[j].stage[0] = hb_min (feature_infos[j].stage[0], feature_infos[i].stage[0]); - feature_infos[j].stage[1] = hb_min (feature_infos[j].stage[1], feature_infos[i].stage[1]); + f[j].flags |= (f[i].flags & F_HAS_FALLBACK); + f[j].stage[0] = hb_min (f[j].stage[0], f[i].stage[0]); + f[j].stage[1] = hb_min (f[j].stage[1], f[i].stage[1]); } feature_infos.shrink (j + 1); } @@ -239,7 +243,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, static_assert ((!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))), ""); unsigned int next_bit = hb_popcount (HB_GLYPH_FLAG_DEFINED) + 1; - for (unsigned int i = 0; i < feature_infos.length; i++) + unsigned count = feature_infos.length; + for (unsigned int i = 0; i < count; i++) { const feature_info_t *info = &feature_infos[i]; @@ -308,7 +313,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, map->_1_mask = (1u << map->shift) & map->mask; map->needs_fallback = !found; } - feature_infos.shrink (0); /* Done with these */ + //feature_infos.shrink (0); /* Done with these */ add_gsub_pause (nullptr); @@ -317,6 +322,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, for (unsigned int table_index = 0; table_index < 2; table_index++) { /* Collect lookup indices for features */ + auto &lookups = m.lookups[table_index]; unsigned int stage_index = 0; unsigned int last_num_lookups = 0; @@ -329,36 +335,39 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, key.variations_index[table_index], global_bit_mask); - for (unsigned i = 0; i < m.features.length; i++) - if (m.features[i].stage[table_index] == stage) + for (auto &feature : m.features) + { + if (feature.stage[table_index] == stage) add_lookups (m, table_index, - m.features[i].index[table_index], + feature.index[table_index], key.variations_index[table_index], - m.features[i].mask, - m.features[i].auto_zwnj, - m.features[i].auto_zwj, - m.features[i].random, - m.features[i].per_syllable); + feature.mask, + feature.auto_zwnj, + feature.auto_zwj, + feature.random, + feature.per_syllable, + feature.tag); + } /* Sort lookups and merge duplicates */ - if (last_num_lookups < m.lookups[table_index].length) + if (last_num_lookups < lookups.length) { - m.lookups[table_index].qsort (last_num_lookups, m.lookups[table_index].length); + lookups.as_array ().sub_array (last_num_lookups, lookups.length - last_num_lookups).qsort (); unsigned int j = last_num_lookups; - for (unsigned int i = j + 1; i < m.lookups[table_index].length; i++) - if (m.lookups[table_index][i].index != m.lookups[table_index][j].index) - m.lookups[table_index][++j] = m.lookups[table_index][i]; + for (unsigned int i = j + 1; i < lookups.length; i++) + if (lookups.arrayZ[i].index != lookups.arrayZ[j].index) + lookups.arrayZ[++j] = lookups.arrayZ[i]; else { - m.lookups[table_index][j].mask |= m.lookups[table_index][i].mask; - m.lookups[table_index][j].auto_zwnj &= m.lookups[table_index][i].auto_zwnj; - m.lookups[table_index][j].auto_zwj &= m.lookups[table_index][i].auto_zwj; + lookups.arrayZ[j].mask |= lookups.arrayZ[i].mask; + lookups.arrayZ[j].auto_zwnj &= lookups.arrayZ[i].auto_zwnj; + lookups.arrayZ[j].auto_zwj &= lookups.arrayZ[i].auto_zwj; } - m.lookups[table_index].shrink (j + 1); + lookups.shrink (j + 1); } - last_num_lookups = m.lookups[table_index].length; + last_num_lookups = lookups.length; if (stage_index < stages[table_index].length && stages[table_index][stage_index].index == stage) { hb_ot_map_t::stage_map_t *stage_map = m.stages[table_index].push (); diff --git a/thirdparty/harfbuzz/src/hb-ot-map.hh b/thirdparty/harfbuzz/src/hb-ot-map.hh index a7b5eec30d..efc8cae96a 100644 --- a/thirdparty/harfbuzz/src/hb-ot-map.hh +++ b/thirdparty/harfbuzz/src/hb-ot-map.hh @@ -69,6 +69,7 @@ struct hb_ot_map_t unsigned short random : 1; unsigned short per_syllable : 1; hb_mask_t mask; + hb_tag_t feature_tag; HB_INTERNAL static int cmp (const void *pa, const void *pb) { @@ -78,7 +79,9 @@ struct hb_ot_map_t } }; - typedef void (*pause_func_t) (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); + /* Pause functions return true if new glyph indices might have been + * added to the buffer. This is used to update buffer digest. */ + typedef bool (*pause_func_t) (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); struct stage_map_t { unsigned int last_lookup; /* Cumulative */ @@ -87,13 +90,13 @@ struct hb_ot_map_t void init () { - memset (this, 0, sizeof (*this)); + hb_memset (this, 0, sizeof (*this)); - features.init (); + features.init0 (); for (unsigned int table_index = 0; table_index < 2; table_index++) { - lookups[table_index].init (); - stages[table_index].init (); + lookups[table_index].init0 (); + stages[table_index].init0 (); } } void fini () @@ -239,7 +242,8 @@ struct hb_ot_map_builder_t bool auto_zwnj = true, bool auto_zwj = true, bool random = false, - bool per_syllable = false); + bool per_syllable = false, + hb_tag_t feature_tag = HB_TAG(' ',' ',' ',' ')); struct feature_info_t { hb_tag_t tag; diff --git a/thirdparty/harfbuzz/src/hb-ot-math-table.hh b/thirdparty/harfbuzz/src/hb-ot-math-table.hh index d834d94371..93953370e2 100644 --- a/thirdparty/harfbuzz/src/hb-ot-math-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-math-table.hh @@ -77,11 +77,11 @@ struct MathConstants HBINT16 *p = c->allocate_size<HBINT16> (HBINT16::static_size * 2); if (unlikely (!p)) return_trace (nullptr); - memcpy (p, percentScaleDown, HBINT16::static_size * 2); + hb_memcpy (p, percentScaleDown, HBINT16::static_size * 2); HBUINT16 *m = c->allocate_size<HBUINT16> (HBUINT16::static_size * 2); if (unlikely (!m)) return_trace (nullptr); - memcpy (m, minHeight, HBUINT16::static_size * 2); + hb_memcpy (m, minHeight, HBUINT16::static_size * 2); unsigned count = ARRAY_LENGTH (mathValueRecords); for (unsigned i = 0; i < count; i++) @@ -786,7 +786,7 @@ struct MathGlyphAssembly if (parts_count) { int64_t mult = font->dir_mult (direction); - for (auto _ : hb_zip (partRecords.sub_array (start_offset, parts_count), + for (auto _ : hb_zip (partRecords.as_array ().sub_array (start_offset, parts_count), hb_array (parts, *parts_count))) _.first.extract (_.second, mult, font); } @@ -855,7 +855,7 @@ struct MathGlyphConstruction if (variants_count) { int64_t mult = font->dir_mult (direction); - for (auto _ : hb_zip (mathGlyphVariantRecord.sub_array (start_offset, variants_count), + for (auto _ : hb_zip (mathGlyphVariantRecord.as_array ().sub_array (start_offset, variants_count), hb_array (variants, *variants_count))) _.second = {_.first.variantGlyph, font->em_mult (_.first.advanceMeasurement, mult)}; } diff --git a/thirdparty/harfbuzz/src/hb-ot-meta-table.hh b/thirdparty/harfbuzz/src/hb-ot-meta-table.hh index 93e64c5327..e1b68bcf91 100644 --- a/thirdparty/harfbuzz/src/hb-ot-meta-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-meta-table.hh @@ -84,7 +84,7 @@ struct meta { if (count) { - + table->dataMaps.sub_array (start_offset, count) + + table->dataMaps.as_array ().sub_array (start_offset, count) | hb_map (&DataMap::get_tag) | hb_map ([](hb_tag_t tag) { return (hb_ot_meta_tag_t) tag; }) | hb_sink (hb_array (entries, *count)) diff --git a/thirdparty/harfbuzz/src/hb-ot-name-table.hh b/thirdparty/harfbuzz/src/hb-ot-name-table.hh index 1f2131ffcc..6f4461cc15 100644 --- a/thirdparty/harfbuzz/src/hb-ot-name-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-name-table.hh @@ -30,10 +30,55 @@ #include "hb-open-type.hh" #include "hb-ot-name-language.hh" #include "hb-aat-layout.hh" +#include "hb-utf.hh" namespace OT { +template <typename in_utf_t, typename out_utf_t> +inline unsigned int +hb_ot_name_convert_utf (hb_bytes_t bytes, + unsigned int *text_size /* IN/OUT */, + typename out_utf_t::codepoint_t *text /* OUT */) +{ + unsigned int src_len = bytes.length / sizeof (typename in_utf_t::codepoint_t); + const typename in_utf_t::codepoint_t *src = (const typename in_utf_t::codepoint_t *) bytes.arrayZ; + const typename in_utf_t::codepoint_t *src_end = src + src_len; + + typename out_utf_t::codepoint_t *dst = text; + + hb_codepoint_t unicode; + const hb_codepoint_t replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT; + + if (text_size && *text_size) + { + (*text_size)--; /* Save room for NUL-termination. */ + const typename out_utf_t::codepoint_t *dst_end = text + *text_size; + + while (src < src_end && dst < dst_end) + { + const typename in_utf_t::codepoint_t *src_next = in_utf_t::next (src, src_end, &unicode, replacement); + typename out_utf_t::codepoint_t *dst_next = out_utf_t::encode (dst, dst_end, unicode); + if (dst_next == dst) + break; /* Out-of-room. */ + + dst = dst_next; + src = src_next; + } + + *text_size = dst - text; + *dst = 0; /* NUL-terminate. */ + } + + /* Accumulate length of rest. */ + unsigned int dst_len = dst - text; + while (src < src_end) + { + src = in_utf_t::next (src, src_end, &unicode, replacement); + dst_len += out_utf_t::encode_len (unicode); + } + return dst_len; +} #define entry_score var.u16[0] #define entry_index var.u16[1] @@ -97,12 +142,68 @@ struct NameRecord return UNSUPPORTED; } - NameRecord* copy (hb_serialize_context_t *c, const void *base) const + NameRecord* copy (hb_serialize_context_t *c, const void *base +#ifdef HB_EXPERIMENTAL_API + , const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides +#endif + ) const { TRACE_SERIALIZE (this); + HB_UNUSED auto snap = c->snapshot (); auto *out = c->embed (this); if (unlikely (!out)) return_trace (nullptr); - out->offset.serialize_copy (c, offset, base, 0, hb_serialize_context_t::Tail, length); +#ifdef HB_EXPERIMENTAL_API + hb_ot_name_record_ids_t record_ids (platformID, encodingID, languageID, nameID); + hb_bytes_t* name_bytes; + + if (name_table_overrides->has (record_ids, &name_bytes)) { + hb_bytes_t encoded_bytes = *name_bytes; + char *name_str_utf16_be = nullptr; + + if (platformID != 1) + { + unsigned text_size = hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (*name_bytes, nullptr, nullptr); + + text_size++; // needs to consider NULL terminator for use in hb_ot_name_convert_utf() + unsigned byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size; + name_str_utf16_be = (char *) hb_calloc (byte_len, 1); + if (!name_str_utf16_be) + { + c->revert (snap); + return_trace (nullptr); + } + hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (*name_bytes, &text_size, + (hb_utf16_be_t::codepoint_t *) name_str_utf16_be); + + unsigned encoded_byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size; + if (!encoded_byte_len || !c->check_assign (out->length, encoded_byte_len, HB_SERIALIZE_ERROR_INT_OVERFLOW)) { + c->revert (snap); + hb_free (name_str_utf16_be); + return_trace (nullptr); + } + + encoded_bytes = hb_bytes_t (name_str_utf16_be, encoded_byte_len); + } + else + { + // mac platform, copy the UTF-8 string(all ascii characters) as is + if (!c->check_assign (out->length, encoded_bytes.length, HB_SERIALIZE_ERROR_INT_OVERFLOW)) { + c->revert (snap); + return_trace (nullptr); + } + } + + out->offset = 0; + c->push (); + encoded_bytes.copy (c); + c->add_link (out->offset, c->pop_pack (), hb_serialize_context_t::Tail, 0); + hb_free (name_str_utf16_be); + } + else +#endif + { + out->offset.serialize_copy (c, offset, base, 0, hb_serialize_context_t::Tail, length); + } return_trace (out); } @@ -216,29 +317,61 @@ struct name hb_requires (hb_is_source_of (Iterator, const NameRecord &))> bool serialize (hb_serialize_context_t *c, Iterator it, - const void *src_string_pool) + const void *src_string_pool +#ifdef HB_EXPERIMENTAL_API + , const hb_vector_t<hb_ot_name_record_ids_t>& insert_name_records + , const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides +#endif + ) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min ((*this)))) return_trace (false); + unsigned total_count = it.len () +#ifdef HB_EXPERIMENTAL_API + + insert_name_records.length +#endif + ; this->format = 0; - this->count = it.len (); + if (!c->check_assign (this->count, total_count, HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return false; - NameRecord *name_records = (NameRecord *) hb_calloc (it.len (), NameRecord::static_size); + NameRecord *name_records = (NameRecord *) hb_calloc (total_count, NameRecord::static_size); if (unlikely (!name_records)) return_trace (false); - hb_array_t<NameRecord> records (name_records, it.len ()); + hb_array_t<NameRecord> records (name_records, total_count); for (const NameRecord& record : it) { + hb_memcpy (name_records, &record, NameRecord::static_size); + name_records++; + } + +#ifdef HB_EXPERIMENTAL_API + for (unsigned i = 0; i < insert_name_records.length; i++) + { + const hb_ot_name_record_ids_t& ids = insert_name_records[i]; + NameRecord record; + record.platformID = ids.platform_id; + record.encodingID = ids.encoding_id; + record.languageID = ids.language_id; + record.nameID = ids.name_id; + record.length = 0; // handled in NameRecord copy() + record.offset = 0; memcpy (name_records, &record, NameRecord::static_size); name_records++; } +#endif records.qsort (); - c->copy_all (records, src_string_pool); + c->copy_all (records, + src_string_pool +#ifdef HB_EXPERIMENTAL_API + , name_table_overrides +#endif + ); hb_free (records.arrayZ); @@ -256,6 +389,11 @@ struct name name *name_prime = c->serializer->start_embed<name> (); if (unlikely (!name_prime)) return_trace (false); +#ifdef HB_EXPERIMENTAL_API + const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides = + c->plan->name_table_overrides; +#endif + auto it = + nameRecordZ.as_array (count) | hb_filter (c->plan->name_ids, &NameRecord::nameID) @@ -265,10 +403,48 @@ struct name (c->plan->flags & HB_SUBSET_FLAGS_NAME_LEGACY) || namerecord.isUnicode (); }) +#ifdef HB_EXPERIMENTAL_API + | hb_filter ([&] (const NameRecord& namerecord) { + if (name_table_overrides->is_empty ()) + return true; + hb_ot_name_record_ids_t rec_ids (namerecord.platformID, + namerecord.encodingID, + namerecord.languageID, + namerecord.nameID); + + hb_bytes_t *p; + if (name_table_overrides->has (rec_ids, &p) && + (*p).length == 0) + return false; + return true; + }) +#endif ; - name_prime->serialize (c->serializer, it, std::addressof (this + stringOffset)); - return_trace (name_prime->count); +#ifdef HB_EXPERIMENTAL_API + hb_vector_t<hb_ot_name_record_ids_t> insert_name_records; + if (!name_table_overrides->is_empty ()) + { + if (unlikely (!insert_name_records.alloc (name_table_overrides->get_population ()))) + return_trace (false); + for (const auto& record_ids : name_table_overrides->keys ()) + { + if (name_table_overrides->get (record_ids).length == 0) + continue; + if (has_name_record_with_ids (record_ids)) + continue; + insert_name_records.push (record_ids); + } + } +#endif + + return (name_prime->serialize (c->serializer, it, + std::addressof (this + stringOffset) +#ifdef HB_EXPERIMENTAL_API + , insert_name_records + , name_table_overrides +#endif + )); } bool sanitize_records (hb_sanitize_context_t *c) const @@ -378,6 +554,23 @@ struct name hb_vector_t<hb_ot_name_entry_t> names; }; + private: + // sometimes NameRecords are not sorted in the font file, so use linear search + // here + bool has_name_record_with_ids (const hb_ot_name_record_ids_t& record_ids) const + { + for (const auto& record : nameRecordZ.as_array (count)) + { + if (record.platformID == record_ids.platform_id && + record.encodingID == record_ids.encoding_id && + record.languageID == record_ids.language_id && + record.nameID == record_ids.name_id) + return true; + } + return false; + } + + public: /* We only implement format 0 for now. */ HBUINT16 format; /* Format selector (=0/1). */ HBUINT16 count; /* Number of name records. */ diff --git a/thirdparty/harfbuzz/src/hb-ot-name.cc b/thirdparty/harfbuzz/src/hb-ot-name.cc index c35ac5b3dc..6adf1e8fbe 100644 --- a/thirdparty/harfbuzz/src/hb-ot-name.cc +++ b/thirdparty/harfbuzz/src/hb-ot-name.cc @@ -64,52 +64,6 @@ hb_ot_name_list_names (hb_face_t *face, return (const hb_ot_name_entry_t *) name.names; } - -template <typename in_utf_t, typename out_utf_t> -static inline unsigned int -hb_ot_name_convert_utf (hb_bytes_t bytes, - unsigned int *text_size /* IN/OUT */, - typename out_utf_t::codepoint_t *text /* OUT */) -{ - unsigned int src_len = bytes.length / sizeof (typename in_utf_t::codepoint_t); - const typename in_utf_t::codepoint_t *src = (const typename in_utf_t::codepoint_t *) bytes.arrayZ; - const typename in_utf_t::codepoint_t *src_end = src + src_len; - - typename out_utf_t::codepoint_t *dst = text; - - hb_codepoint_t unicode; - const hb_codepoint_t replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT; - - if (text_size && *text_size) - { - (*text_size)--; /* Same room for NUL-termination. */ - const typename out_utf_t::codepoint_t *dst_end = text + *text_size; - - while (src < src_end && dst < dst_end) - { - const typename in_utf_t::codepoint_t *src_next = in_utf_t::next (src, src_end, &unicode, replacement); - typename out_utf_t::codepoint_t *dst_next = out_utf_t::encode (dst, dst_end, unicode); - if (dst_next == dst) - break; /* Out-of-room. */ - - dst = dst_next; - src = src_next; - } - - *text_size = dst - text; - *dst = 0; /* NUL-terminate. */ - } - - /* Accumulate length of rest. */ - unsigned int dst_len = dst - text; - while (src < src_end) - { - src = in_utf_t::next (src, src_end, &unicode, replacement); - dst_len += out_utf_t::encode_len (unicode); - } - return dst_len; -} - template <typename utf_t> static inline unsigned int hb_ot_name_get_utf (hb_face_t *face, @@ -130,10 +84,10 @@ hb_ot_name_get_utf (hb_face_t *face, hb_bytes_t bytes = name.get_name (idx); if (width == 2) /* UTF16-BE */ - return hb_ot_name_convert_utf<hb_utf16_be_t, utf_t> (bytes, text_size, text); + return OT::hb_ot_name_convert_utf<hb_utf16_be_t, utf_t> (bytes, text_size, text); if (width == 1) /* ASCII */ - return hb_ot_name_convert_utf<hb_ascii_t, utf_t> (bytes, text_size, text); + return OT::hb_ot_name_convert_utf<hb_ascii_t, utf_t> (bytes, text_size, text); } if (text_size) @@ -227,5 +181,4 @@ hb_ot_name_get_utf32 (hb_face_t *face, return hb_ot_name_get_utf<hb_utf32_t> (face, name_id, language, text_size, text); } - #endif diff --git a/thirdparty/harfbuzz/src/hb-ot-os2-table.hh b/thirdparty/harfbuzz/src/hb-ot-os2-table.hh index c6e8fad6fc..5b017d56a6 100644 --- a/thirdparty/harfbuzz/src/hb-ot-os2-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-os2-table.hh @@ -212,17 +212,6 @@ struct OS2 TRACE_SUBSET (this); OS2 *os2_prime = c->serializer->embed (this); if (unlikely (!os2_prime)) return_trace (false); - if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES) - return_trace (true); - - /* when --gids option is not used, no need to do collect_mapping that is - * iterating all codepoints in each subtable, which is not efficient */ - uint16_t min_cp, max_cp; - find_min_and_max_codepoint (c->plan->unicodes, &min_cp, &max_cp); - os2_prime->usFirstCharIndex = min_cp; - os2_prime->usLastCharIndex = max_cp; - - _update_unicode_ranges (c->plan->unicodes, os2_prime->ulUnicodeRange); if (c->plan->user_axes_location->has (HB_TAG ('w','g','h','t')) && !c->plan->pinned_at_default) @@ -244,6 +233,18 @@ struct OS2 return_trace (false); } + if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES) + return_trace (true); + + /* when --gids option is not used, no need to do collect_mapping that is + * iterating all codepoints in each subtable, which is not efficient */ + uint16_t min_cp, max_cp; + find_min_and_max_codepoint (c->plan->unicodes, &min_cp, &max_cp); + os2_prime->usFirstCharIndex = min_cp; + os2_prime->usLastCharIndex = max_cp; + + _update_unicode_ranges (c->plan->unicodes, os2_prime->ulUnicodeRange); + return_trace (true); } diff --git a/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh b/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh index 4d427e5431..951e6395d6 100644 --- a/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh +++ b/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh @@ -78,14 +78,14 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const post::accelerator_t _post (c->plan->source); - hb_hashmap_t<hb_bytes_t, unsigned, true> glyph_name_to_new_index; + hb_hashmap_t<hb_bytes_t, uint32_t, true> glyph_name_to_new_index; for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++) { hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid); unsigned old_index = glyphNameIndex[old_gid]; unsigned new_index; - const unsigned *new_index2; + const uint32_t *new_index2; if (old_index <= 257) new_index = old_index; else if (old_new_index_map.has (old_index, &new_index2)) { diff --git a/thirdparty/harfbuzz/src/hb-ot-post-table.hh b/thirdparty/harfbuzz/src/hb-ot-post-table.hh index 59c1de3784..a04b80357b 100644 --- a/thirdparty/harfbuzz/src/hb-ot-post-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-post-table.hh @@ -84,7 +84,7 @@ struct post post *post_prime = c->allocate_min<post> (); if (unlikely (!post_prime)) return_trace (false); - memcpy (post_prime, this, post::min_size); + hb_memcpy (post_prime, this, post::min_size); if (!glyph_names) return_trace (c->check_assign (post_prime->version.major, 3, HB_SERIALIZE_ERROR_INT_OVERFLOW)); // Version 3 does not have any glyph names. diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc b/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc index 7db0b25b73..897377aa15 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc @@ -341,7 +341,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, { unsigned int end; for (end = buffer->idx + 1; end < count; end++) - if (unlikely (_hb_glyph_info_is_unicode_mark (&buffer->info[end]))) + if (_hb_glyph_info_is_unicode_mark (&buffer->info[end])) break; if (end < count) diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.cc b/thirdparty/harfbuzz/src/hb-ot-shape.cc index 249b5a864c..bbdfc214a1 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape.cc @@ -91,9 +91,11 @@ hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *fac script_zero_marks = shaper->zero_width_marks != HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE; script_fallback_mark_positioning = shaper->fallback_position; +#ifndef HB_NO_AAT_SHAPE /* https://github.com/harfbuzz/harfbuzz/issues/1528 */ if (apply_morx && shaper != &_hb_ot_shaper_default) shaper = &_hb_ot_shaper_dumber; +#endif } void @@ -864,7 +866,7 @@ hb_ot_hide_default_ignorables (hb_buffer_t *buffer, } } else - hb_ot_layout_delete_glyphs_inplace (buffer, _hb_glyph_info_is_default_ignorable); + buffer->delete_glyphs_inplace (_hb_glyph_info_is_default_ignorable); } diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.hh b/thirdparty/harfbuzz/src/hb-ot-shape.hh index cd6f15cbe2..ace28602f6 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape.hh @@ -51,7 +51,7 @@ struct hb_ot_shape_plan_key_t bool equal (const hb_ot_shape_plan_key_t *other) { - return 0 == memcmp (this, other, sizeof (*this)); + return 0 == hb_memcmp (this, other, sizeof (*this)); } }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc index ed2748b828..2332ae3697 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc @@ -161,22 +161,23 @@ static const struct arabic_state_table_entry { }; -static void +static bool arabic_fallback_shape (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); -static void +static bool record_stch (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); -static void +static bool deallocate_buffer_var (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); + return false; } static void @@ -412,19 +413,19 @@ setup_masks_arabic (const hb_ot_shape_plan_t *plan, setup_masks_arabic_plan (arabic_plan, buffer, plan->props.script); } -static void +static bool arabic_fallback_shape (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { #ifdef HB_NO_OT_SHAPER_ARABIC_FALLBACK - return; + return false; #endif const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data; if (!arabic_plan->do_fallback) - return; + return false; retry: arabic_fallback_plan_t *fallback_plan = arabic_plan->fallback_plan; @@ -440,6 +441,7 @@ retry: } arabic_fallback_plan_shape (fallback_plan, font, buffer); + return true; } /* @@ -450,14 +452,14 @@ retry: * marks can use it as well. */ -static void +static bool record_stch (const hb_ot_shape_plan_t *plan, hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data; if (!arabic_plan->has_stch) - return; + return false; /* 'stch' feature was just applied. Look for anything that multiplied, * and record it for stch treatment later. Note that rtlm, frac, etc @@ -473,6 +475,7 @@ record_stch (const hb_ot_shape_plan_t *plan, info[i].arabic_shaping_action() = comp % 2 ? STCH_REPEATING : STCH_FIXED; buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH; } + return false; } static void diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-default.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-default.cc index 2f6f499eec..f0404a4d2c 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-default.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-default.cc @@ -49,6 +49,7 @@ const hb_ot_shaper_t _hb_ot_shaper_default = true, /* fallback_position */ }; +#ifndef HB_NO_AAT_SHAPE /* Same as default but no mark advance zeroing / fallback positioning. * Dumbest shaper ever, basically. */ const hb_ot_shaper_t _hb_ot_shaper_dumber = @@ -68,6 +69,7 @@ const hb_ot_shaper_t _hb_ot_shaper_dumber = HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ }; +#endif #endif diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh index d52b13f616..d6c67b81bd 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh @@ -53,7 +53,7 @@ enum indic_syllable_type_t { }; -#line 57 "hb-ot-shaper-indic-machine.hh" +#line 54 "hb-ot-shaper-indic-machine.hh" #define indic_syllable_machine_ex_A 9u #define indic_syllable_machine_ex_C 1u #define indic_syllable_machine_ex_CM 16u @@ -61,6 +61,7 @@ enum indic_syllable_type_t { #define indic_syllable_machine_ex_DOTTEDCIRCLE 11u #define indic_syllable_machine_ex_H 4u #define indic_syllable_machine_ex_M 7u +#define indic_syllable_machine_ex_MPst 13u #define indic_syllable_machine_ex_N 3u #define indic_syllable_machine_ex_PLACEHOLDER 10u #define indic_syllable_machine_ex_RS 12u @@ -75,268 +76,302 @@ enum indic_syllable_type_t { #define indic_syllable_machine_ex_ZWNJ 5u -#line 79 "hb-ot-shaper-indic-machine.hh" +#line 75 "hb-ot-shaper-indic-machine.hh" static const unsigned char _indic_syllable_machine_trans_keys[] = { - 8u, 8u, 4u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 4u, 12u, 4u, 8u, 8u, 8u, - 5u, 7u, 5u, 8u, 4u, 8u, 4u, 12u, 4u, 12u, 4u, 12u, 8u, 8u, 5u, 7u, - 5u, 8u, 4u, 8u, 4u, 8u, 4u, 12u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, - 4u, 8u, 5u, 8u, 8u, 8u, 1u, 18u, 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, - 5u, 9u, 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u, 1u, 15u, 1u, 15u, 3u, 9u, - 4u, 9u, 5u, 9u, 4u, 9u, 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, - 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, - 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u, 1u, 15u, 3u, 9u, 4u, 9u, 5u, 9u, - 4u, 9u, 5u, 9u, 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 4u, 8u, - 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, - 5u, 9u, 1u, 15u, 1u, 15u, 3u, 9u, 4u, 9u, 5u, 9u, 3u, 16u, 4u, 9u, - 5u, 9u, 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 4u, 12u, 4u, 8u, 3u, 16u, - 3u, 16u, 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, - 1u, 15u, 1u, 15u, 3u, 9u, 4u, 9u, 5u, 9u, 3u, 16u, 4u, 9u, 5u, 9u, - 5u, 9u, 3u, 9u, 5u, 9u, 1u, 16u, 3u, 16u, 1u, 16u, 4u, 12u, 5u, 9u, - 9u, 9u, 5u, 9u, 1u, 15u, 3u, 9u, 5u, 9u, 5u, 9u, 9u, 9u, 5u, 9u, - 1u, 15u, 0 + 8u, 8u, 4u, 13u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, + 8u, 8u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, + 8u, 8u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 8u, 8u, + 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 5u, 13u, 8u, 8u, 1u, 18u, + 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 5u, 9u, 5u, 9u, 9u, 9u, 5u, 9u, + 1u, 15u, 1u, 15u, 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 4u, 13u, + 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 3u, 16u, 3u, 16u, 4u, 16u, + 1u, 15u, 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, + 1u, 15u, 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 4u, 13u, 5u, 9u, + 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 4u, 13u, 3u, 16u, 3u, 16u, + 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u, + 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 3u, 16u, 4u, 13u, 5u, 9u, + 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 4u, 13u, 4u, 13u, 3u, 16u, 3u, 16u, + 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u, + 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 3u, 16u, 4u, 13u, 5u, 9u, + 5u, 9u, 3u, 9u, 5u, 9u, 1u, 16u, 3u, 16u, 1u, 16u, 4u, 13u, 5u, 13u, + 5u, 13u, 9u, 9u, 5u, 9u, 1u, 15u, 3u, 9u, 5u, 9u, 5u, 9u, 9u, 9u, + 5u, 9u, 1u, 15u, 0 }; static const char _indic_syllable_machine_key_spans[] = { - 1, 5, 3, 4, 5, 9, 5, 1, - 3, 4, 5, 9, 9, 9, 1, 3, - 4, 5, 5, 9, 1, 3, 4, 5, - 5, 4, 1, 18, 14, 14, 13, 15, - 5, 5, 1, 5, 15, 15, 15, 7, - 6, 5, 6, 5, 7, 5, 14, 14, - 14, 14, 13, 15, 14, 14, 13, 15, - 5, 1, 5, 15, 15, 7, 6, 5, - 6, 5, 5, 7, 5, 14, 14, 5, - 14, 14, 13, 15, 14, 15, 5, 1, - 5, 15, 15, 7, 6, 5, 14, 6, - 5, 5, 7, 5, 14, 9, 5, 14, - 14, 13, 15, 14, 15, 5, 1, 5, - 15, 15, 7, 6, 5, 14, 6, 5, - 5, 7, 5, 16, 14, 16, 9, 5, - 1, 5, 15, 7, 5, 5, 1, 5, - 15 + 1, 10, 9, 9, 1, 10, 10, 10, + 1, 9, 9, 1, 10, 10, 10, 10, + 1, 9, 9, 1, 10, 10, 10, 1, + 9, 9, 1, 10, 10, 9, 1, 18, + 14, 14, 13, 15, 5, 5, 1, 5, + 15, 15, 15, 11, 10, 9, 9, 10, + 5, 7, 5, 14, 14, 14, 14, 13, + 15, 14, 14, 13, 15, 5, 1, 5, + 15, 15, 11, 10, 9, 9, 10, 5, + 5, 7, 5, 14, 14, 10, 14, 14, + 13, 15, 14, 15, 5, 1, 5, 15, + 15, 11, 10, 9, 9, 14, 10, 5, + 5, 7, 5, 14, 10, 10, 14, 14, + 13, 15, 14, 15, 5, 1, 5, 15, + 15, 11, 10, 9, 9, 14, 10, 5, + 5, 7, 5, 16, 14, 16, 10, 9, + 9, 1, 5, 15, 7, 5, 5, 1, + 5, 15 }; static const short _indic_syllable_machine_index_offsets[] = { - 0, 2, 8, 12, 17, 23, 33, 39, - 41, 45, 50, 56, 66, 76, 86, 88, - 92, 97, 103, 109, 119, 121, 125, 130, - 136, 142, 147, 149, 168, 183, 198, 212, - 228, 234, 240, 242, 248, 264, 280, 296, - 304, 311, 317, 324, 330, 338, 344, 359, - 374, 389, 404, 418, 434, 449, 464, 478, - 494, 500, 502, 508, 524, 540, 548, 555, - 561, 568, 574, 580, 588, 594, 609, 624, - 630, 645, 660, 674, 690, 705, 721, 727, - 729, 735, 751, 767, 775, 782, 788, 803, - 810, 816, 822, 830, 836, 851, 861, 867, - 882, 897, 911, 927, 942, 958, 964, 966, - 972, 988, 1004, 1012, 1019, 1025, 1040, 1047, - 1053, 1059, 1067, 1073, 1090, 1105, 1122, 1132, - 1138, 1140, 1146, 1162, 1170, 1176, 1182, 1184, - 1190 + 0, 2, 13, 23, 33, 35, 46, 57, + 68, 70, 80, 90, 92, 103, 114, 125, + 136, 138, 148, 158, 160, 171, 182, 193, + 195, 205, 215, 217, 228, 239, 249, 251, + 270, 285, 300, 314, 330, 336, 342, 344, + 350, 366, 382, 398, 410, 421, 431, 441, + 452, 458, 466, 472, 487, 502, 517, 532, + 546, 562, 577, 592, 606, 622, 628, 630, + 636, 652, 668, 680, 691, 701, 711, 722, + 728, 734, 742, 748, 763, 778, 789, 804, + 819, 833, 849, 864, 880, 886, 888, 894, + 910, 926, 938, 949, 959, 969, 984, 995, + 1001, 1007, 1015, 1021, 1036, 1047, 1058, 1073, + 1088, 1102, 1118, 1133, 1149, 1155, 1157, 1163, + 1179, 1195, 1207, 1218, 1228, 1238, 1253, 1264, + 1270, 1276, 1284, 1290, 1307, 1322, 1339, 1350, + 1360, 1370, 1372, 1378, 1394, 1402, 1408, 1414, + 1416, 1422 }; static const unsigned char _indic_syllable_machine_indicies[] = { - 1, 0, 2, 3, 3, 4, 1, 0, - 3, 3, 4, 0, 3, 3, 4, 1, - 0, 5, 3, 3, 4, 1, 0, 2, - 3, 3, 4, 1, 0, 0, 0, 6, - 0, 8, 9, 9, 10, 11, 7, 11, - 7, 9, 9, 10, 7, 9, 9, 10, - 11, 7, 12, 9, 9, 10, 11, 7, - 8, 9, 9, 10, 11, 7, 7, 7, - 13, 7, 8, 9, 9, 10, 11, 7, - 7, 7, 14, 7, 16, 17, 17, 18, - 19, 15, 15, 15, 20, 15, 19, 15, - 17, 17, 18, 21, 17, 17, 18, 19, - 15, 16, 17, 17, 18, 19, 15, 22, - 17, 17, 18, 19, 15, 24, 25, 25, - 26, 27, 23, 23, 23, 28, 23, 27, - 23, 25, 25, 26, 23, 25, 25, 26, - 27, 23, 24, 25, 25, 26, 27, 23, - 29, 25, 25, 26, 27, 23, 17, 17, - 18, 1, 0, 31, 30, 33, 34, 35, - 36, 37, 38, 18, 19, 39, 40, 40, - 20, 32, 41, 42, 43, 44, 45, 32, - 47, 48, 49, 50, 4, 1, 51, 46, - 46, 6, 46, 46, 46, 52, 46, 53, - 48, 54, 54, 4, 1, 51, 46, 46, - 46, 46, 46, 46, 52, 46, 48, 54, - 54, 4, 1, 51, 46, 46, 46, 46, - 46, 46, 52, 46, 33, 46, 46, 46, - 55, 56, 46, 1, 51, 46, 46, 46, - 46, 46, 33, 46, 57, 57, 46, 1, - 51, 46, 51, 46, 46, 58, 51, 46, - 51, 46, 51, 46, 46, 46, 51, 46, - 33, 46, 59, 46, 57, 57, 46, 1, - 51, 46, 46, 46, 46, 46, 33, 46, - 33, 46, 46, 46, 57, 57, 46, 1, - 51, 46, 46, 46, 46, 46, 33, 46, - 33, 46, 46, 46, 57, 56, 46, 1, - 51, 46, 46, 46, 46, 46, 33, 46, - 60, 61, 62, 62, 4, 1, 51, 46, - 61, 62, 62, 4, 1, 51, 46, 62, - 62, 4, 1, 51, 46, 63, 64, 64, - 4, 1, 51, 46, 55, 65, 46, 1, - 51, 46, 55, 46, 57, 57, 46, 1, - 51, 46, 57, 65, 46, 1, 51, 46, - 47, 48, 54, 54, 4, 1, 51, 46, - 46, 46, 46, 46, 46, 52, 46, 47, - 48, 49, 54, 4, 1, 51, 46, 46, - 6, 46, 46, 46, 52, 46, 67, 68, - 69, 70, 10, 11, 71, 66, 66, 14, - 66, 66, 66, 72, 66, 73, 68, 74, - 70, 10, 11, 71, 66, 66, 66, 66, - 66, 66, 72, 66, 68, 74, 70, 10, - 11, 71, 66, 66, 66, 66, 66, 66, - 72, 66, 75, 66, 66, 66, 76, 77, - 66, 11, 71, 66, 66, 66, 66, 66, - 75, 66, 78, 68, 79, 80, 10, 11, - 71, 66, 66, 13, 66, 66, 66, 72, - 66, 81, 68, 74, 74, 10, 11, 71, - 66, 66, 66, 66, 66, 66, 72, 66, - 68, 74, 74, 10, 11, 71, 66, 66, - 66, 66, 66, 66, 72, 66, 75, 66, - 66, 66, 82, 77, 66, 11, 71, 66, - 66, 66, 66, 66, 75, 66, 71, 66, - 66, 83, 71, 66, 71, 66, 71, 66, - 66, 66, 71, 66, 75, 66, 84, 66, - 82, 82, 66, 11, 71, 66, 66, 66, - 66, 66, 75, 66, 75, 66, 66, 66, - 82, 82, 66, 11, 71, 66, 66, 66, - 66, 66, 75, 66, 85, 86, 87, 87, - 10, 11, 71, 66, 86, 87, 87, 10, - 11, 71, 66, 87, 87, 10, 11, 71, - 66, 88, 89, 89, 10, 11, 71, 66, - 76, 90, 66, 11, 71, 66, 82, 82, - 66, 11, 71, 66, 76, 66, 82, 82, - 66, 11, 71, 66, 82, 90, 66, 11, - 71, 66, 78, 68, 74, 74, 10, 11, - 71, 66, 66, 66, 66, 66, 66, 72, - 66, 78, 68, 79, 74, 10, 11, 71, - 66, 66, 13, 66, 66, 66, 72, 66, - 8, 9, 9, 10, 11, 66, 67, 68, - 74, 70, 10, 11, 71, 66, 66, 66, - 66, 66, 66, 72, 66, 92, 36, 93, - 93, 18, 19, 39, 91, 91, 91, 91, - 91, 91, 43, 91, 36, 93, 93, 18, - 19, 39, 91, 91, 91, 91, 91, 91, - 43, 91, 94, 91, 91, 91, 95, 96, - 91, 19, 39, 91, 91, 91, 91, 91, - 94, 91, 35, 36, 97, 98, 18, 19, - 39, 91, 91, 20, 91, 91, 91, 43, - 91, 94, 91, 91, 91, 99, 96, 91, - 19, 39, 91, 91, 91, 91, 91, 94, - 91, 39, 91, 91, 100, 39, 91, 39, - 91, 39, 91, 91, 91, 39, 91, 94, - 91, 101, 91, 99, 99, 91, 19, 39, - 91, 91, 91, 91, 91, 94, 91, 94, - 91, 91, 91, 99, 99, 91, 19, 39, - 91, 91, 91, 91, 91, 94, 91, 102, - 103, 104, 104, 18, 19, 39, 91, 103, - 104, 104, 18, 19, 39, 91, 104, 104, - 18, 19, 39, 91, 35, 36, 93, 93, - 18, 19, 39, 91, 91, 91, 91, 91, - 91, 43, 91, 105, 106, 106, 18, 19, - 39, 91, 95, 107, 91, 19, 39, 91, - 99, 99, 91, 19, 39, 91, 95, 91, - 99, 99, 91, 19, 39, 91, 99, 107, - 91, 19, 39, 91, 35, 36, 97, 93, - 18, 19, 39, 91, 91, 20, 91, 91, - 91, 43, 91, 16, 17, 17, 18, 19, - 108, 108, 108, 20, 108, 16, 17, 17, - 18, 19, 108, 110, 111, 112, 113, 26, - 27, 114, 109, 109, 28, 109, 109, 109, - 115, 109, 116, 111, 113, 113, 26, 27, - 114, 109, 109, 109, 109, 109, 109, 115, - 109, 111, 113, 113, 26, 27, 114, 109, - 109, 109, 109, 109, 109, 115, 109, 117, - 109, 109, 109, 118, 119, 109, 27, 114, - 109, 109, 109, 109, 109, 117, 109, 110, - 111, 112, 40, 26, 27, 114, 109, 109, - 28, 109, 109, 109, 115, 109, 117, 109, - 109, 109, 120, 119, 109, 27, 114, 109, - 109, 109, 109, 109, 117, 109, 114, 109, - 109, 121, 114, 109, 114, 109, 114, 109, - 109, 109, 114, 109, 117, 109, 122, 109, - 120, 120, 109, 27, 114, 109, 109, 109, - 109, 109, 117, 109, 117, 109, 109, 109, - 120, 120, 109, 27, 114, 109, 109, 109, - 109, 109, 117, 109, 123, 124, 125, 125, - 26, 27, 114, 109, 124, 125, 125, 26, - 27, 114, 109, 125, 125, 26, 27, 114, - 109, 110, 111, 113, 113, 26, 27, 114, - 109, 109, 109, 109, 109, 109, 115, 109, - 126, 127, 127, 26, 27, 114, 109, 118, - 128, 109, 27, 114, 109, 120, 120, 109, - 27, 114, 109, 118, 109, 120, 120, 109, - 27, 114, 109, 120, 128, 109, 27, 114, - 109, 33, 34, 35, 36, 97, 93, 18, - 19, 39, 40, 40, 20, 91, 91, 33, - 43, 91, 47, 129, 49, 50, 4, 1, - 51, 46, 46, 6, 46, 46, 46, 52, - 46, 33, 34, 35, 36, 130, 131, 18, - 132, 133, 46, 40, 20, 46, 46, 33, - 43, 46, 16, 134, 134, 18, 132, 51, - 46, 46, 20, 46, 133, 46, 46, 135, - 133, 46, 133, 46, 133, 46, 46, 46, - 133, 46, 33, 46, 59, 16, 134, 134, - 18, 132, 51, 46, 46, 46, 46, 46, - 33, 46, 137, 136, 138, 138, 136, 31, - 139, 136, 138, 138, 136, 31, 139, 136, - 139, 136, 136, 140, 139, 136, 139, 136, - 139, 136, 136, 136, 139, 136, 33, 108, - 108, 108, 108, 108, 108, 108, 108, 40, - 108, 108, 108, 108, 33, 108, 0 + 1, 0, 2, 3, 3, 4, 5, 0, + 0, 0, 0, 4, 0, 3, 3, 4, + 6, 0, 0, 0, 0, 4, 0, 3, + 3, 4, 5, 0, 0, 0, 0, 4, + 0, 4, 0, 7, 3, 3, 4, 5, + 0, 0, 0, 0, 4, 0, 2, 3, + 3, 4, 5, 0, 0, 0, 8, 4, + 0, 10, 11, 11, 12, 13, 9, 9, + 9, 9, 12, 9, 14, 9, 11, 11, + 12, 15, 9, 9, 9, 9, 12, 9, + 11, 11, 12, 13, 9, 9, 9, 9, + 12, 9, 12, 9, 16, 11, 11, 12, + 13, 9, 9, 9, 9, 12, 9, 10, + 11, 11, 12, 13, 9, 9, 9, 17, + 12, 9, 10, 11, 11, 12, 13, 9, + 9, 9, 18, 12, 9, 20, 21, 21, + 22, 23, 19, 19, 19, 24, 22, 19, + 25, 19, 21, 21, 22, 27, 26, 26, + 26, 26, 22, 26, 21, 21, 22, 23, + 19, 19, 19, 19, 22, 19, 22, 26, + 20, 21, 21, 22, 23, 19, 19, 19, + 19, 22, 19, 28, 21, 21, 22, 23, + 19, 19, 19, 19, 22, 19, 30, 31, + 31, 32, 33, 29, 29, 29, 34, 32, + 29, 35, 29, 31, 31, 32, 36, 29, + 29, 29, 29, 32, 29, 31, 31, 32, + 33, 29, 29, 29, 29, 32, 29, 32, + 29, 30, 31, 31, 32, 33, 29, 29, + 29, 29, 32, 29, 37, 31, 31, 32, + 33, 29, 29, 29, 29, 32, 29, 21, + 21, 22, 38, 0, 0, 0, 0, 22, + 0, 40, 39, 42, 43, 44, 45, 46, + 47, 22, 23, 48, 49, 49, 24, 22, + 50, 51, 52, 53, 54, 41, 56, 57, + 58, 59, 4, 5, 60, 55, 55, 8, + 4, 55, 55, 61, 55, 62, 57, 63, + 63, 4, 5, 60, 55, 55, 55, 4, + 55, 55, 61, 55, 57, 63, 63, 4, + 5, 60, 55, 55, 55, 4, 55, 55, + 61, 55, 42, 55, 55, 55, 64, 65, + 55, 1, 60, 55, 55, 55, 55, 55, + 42, 55, 66, 66, 55, 1, 60, 55, + 60, 55, 55, 67, 60, 55, 60, 55, + 60, 55, 55, 55, 60, 55, 42, 55, + 68, 55, 66, 66, 55, 1, 60, 55, + 55, 55, 55, 55, 42, 55, 42, 55, + 55, 55, 66, 66, 55, 1, 60, 55, + 55, 55, 55, 55, 42, 55, 42, 55, + 55, 55, 66, 65, 55, 1, 60, 55, + 55, 55, 55, 55, 42, 55, 69, 70, + 71, 71, 4, 5, 60, 55, 55, 55, + 4, 55, 70, 71, 71, 4, 5, 60, + 55, 55, 55, 4, 55, 71, 71, 4, + 5, 60, 55, 55, 55, 4, 55, 60, + 55, 55, 67, 60, 55, 55, 55, 4, + 55, 72, 73, 73, 4, 5, 60, 55, + 55, 55, 4, 55, 64, 74, 55, 1, + 60, 55, 64, 55, 66, 66, 55, 1, + 60, 55, 66, 74, 55, 1, 60, 55, + 56, 57, 63, 63, 4, 5, 60, 55, + 55, 55, 4, 55, 55, 61, 55, 56, + 57, 58, 63, 4, 5, 60, 55, 55, + 8, 4, 55, 55, 61, 55, 76, 77, + 78, 79, 12, 13, 80, 75, 75, 18, + 12, 75, 75, 81, 75, 82, 77, 83, + 79, 12, 13, 80, 75, 75, 75, 12, + 75, 75, 81, 75, 77, 83, 79, 12, + 13, 80, 75, 75, 75, 12, 75, 75, + 81, 75, 84, 75, 75, 75, 85, 86, + 75, 14, 80, 75, 75, 75, 75, 75, + 84, 75, 87, 77, 88, 89, 12, 13, + 80, 75, 75, 17, 12, 75, 75, 81, + 75, 90, 77, 83, 83, 12, 13, 80, + 75, 75, 75, 12, 75, 75, 81, 75, + 77, 83, 83, 12, 13, 80, 75, 75, + 75, 12, 75, 75, 81, 75, 84, 75, + 75, 75, 91, 86, 75, 14, 80, 75, + 75, 75, 75, 75, 84, 75, 80, 75, + 75, 92, 80, 75, 80, 75, 80, 75, + 75, 75, 80, 75, 84, 75, 93, 75, + 91, 91, 75, 14, 80, 75, 75, 75, + 75, 75, 84, 75, 84, 75, 75, 75, + 91, 91, 75, 14, 80, 75, 75, 75, + 75, 75, 84, 75, 94, 95, 96, 96, + 12, 13, 80, 75, 75, 75, 12, 75, + 95, 96, 96, 12, 13, 80, 75, 75, + 75, 12, 75, 96, 96, 12, 13, 80, + 75, 75, 75, 12, 75, 80, 75, 75, + 92, 80, 75, 75, 75, 12, 75, 97, + 98, 98, 12, 13, 80, 75, 75, 75, + 12, 75, 85, 99, 75, 14, 80, 75, + 91, 91, 75, 14, 80, 75, 85, 75, + 91, 91, 75, 14, 80, 75, 91, 99, + 75, 14, 80, 75, 87, 77, 83, 83, + 12, 13, 80, 75, 75, 75, 12, 75, + 75, 81, 75, 87, 77, 88, 83, 12, + 13, 80, 75, 75, 17, 12, 75, 75, + 81, 75, 10, 11, 11, 12, 13, 75, + 75, 75, 75, 12, 75, 76, 77, 83, + 79, 12, 13, 80, 75, 75, 75, 12, + 75, 75, 81, 75, 101, 45, 102, 102, + 22, 23, 48, 100, 100, 100, 22, 100, + 100, 52, 100, 45, 102, 102, 22, 23, + 48, 100, 100, 100, 22, 100, 100, 52, + 100, 103, 100, 100, 100, 104, 105, 100, + 25, 48, 100, 100, 100, 100, 100, 103, + 100, 44, 45, 106, 107, 22, 23, 48, + 100, 100, 24, 22, 100, 100, 52, 100, + 103, 100, 100, 100, 108, 105, 100, 25, + 48, 100, 100, 100, 100, 100, 103, 100, + 48, 100, 100, 109, 48, 100, 48, 100, + 48, 100, 100, 100, 48, 100, 103, 100, + 110, 100, 108, 108, 100, 25, 48, 100, + 100, 100, 100, 100, 103, 100, 103, 100, + 100, 100, 108, 108, 100, 25, 48, 100, + 100, 100, 100, 100, 103, 100, 111, 112, + 113, 113, 22, 23, 48, 100, 100, 100, + 22, 100, 112, 113, 113, 22, 23, 48, + 100, 100, 100, 22, 100, 113, 113, 22, + 23, 48, 100, 100, 100, 22, 100, 48, + 100, 100, 109, 48, 100, 100, 100, 22, + 100, 44, 45, 102, 102, 22, 23, 48, + 100, 100, 100, 22, 100, 100, 52, 100, + 114, 115, 115, 22, 23, 48, 100, 100, + 100, 22, 100, 104, 116, 100, 25, 48, + 100, 108, 108, 100, 25, 48, 100, 104, + 100, 108, 108, 100, 25, 48, 100, 108, + 116, 100, 25, 48, 100, 44, 45, 106, + 102, 22, 23, 48, 100, 100, 24, 22, + 100, 100, 52, 100, 20, 21, 21, 22, + 23, 117, 117, 117, 24, 22, 117, 20, + 21, 21, 22, 23, 117, 117, 117, 117, + 22, 117, 119, 120, 121, 122, 32, 33, + 123, 118, 118, 34, 32, 118, 118, 124, + 118, 125, 120, 122, 122, 32, 33, 123, + 118, 118, 118, 32, 118, 118, 124, 118, + 120, 122, 122, 32, 33, 123, 118, 118, + 118, 32, 118, 118, 124, 118, 126, 118, + 118, 118, 127, 128, 118, 35, 123, 118, + 118, 118, 118, 118, 126, 118, 119, 120, + 121, 49, 32, 33, 123, 118, 118, 34, + 32, 118, 118, 124, 118, 126, 118, 118, + 118, 129, 128, 118, 35, 123, 118, 118, + 118, 118, 118, 126, 118, 123, 118, 118, + 130, 123, 118, 123, 118, 123, 118, 118, + 118, 123, 118, 126, 118, 131, 118, 129, + 129, 118, 35, 123, 118, 118, 118, 118, + 118, 126, 118, 126, 118, 118, 118, 129, + 129, 118, 35, 123, 118, 118, 118, 118, + 118, 126, 118, 132, 133, 134, 134, 32, + 33, 123, 118, 118, 118, 32, 118, 133, + 134, 134, 32, 33, 123, 118, 118, 118, + 32, 118, 134, 134, 32, 33, 123, 118, + 118, 118, 32, 118, 123, 118, 118, 130, + 123, 118, 118, 118, 32, 118, 119, 120, + 122, 122, 32, 33, 123, 118, 118, 118, + 32, 118, 118, 124, 118, 135, 136, 136, + 32, 33, 123, 118, 118, 118, 32, 118, + 127, 137, 118, 35, 123, 118, 129, 129, + 118, 35, 123, 118, 127, 118, 129, 129, + 118, 35, 123, 118, 129, 137, 118, 35, + 123, 118, 42, 43, 44, 45, 106, 102, + 22, 23, 48, 49, 49, 24, 22, 100, + 42, 52, 100, 56, 138, 58, 59, 4, + 5, 60, 55, 55, 8, 4, 55, 55, + 61, 55, 42, 43, 44, 45, 139, 140, + 22, 141, 142, 55, 49, 24, 22, 55, + 42, 52, 55, 20, 143, 143, 22, 141, + 60, 55, 55, 24, 22, 55, 60, 55, + 55, 67, 60, 55, 55, 55, 22, 55, + 142, 55, 55, 144, 142, 55, 55, 55, + 22, 55, 142, 55, 142, 55, 55, 55, + 142, 55, 42, 55, 68, 20, 143, 143, + 22, 141, 60, 55, 55, 55, 22, 55, + 42, 55, 146, 145, 147, 147, 145, 40, + 148, 145, 147, 147, 145, 40, 148, 145, + 148, 145, 145, 149, 148, 145, 148, 145, + 148, 145, 145, 145, 148, 145, 42, 117, + 117, 117, 117, 117, 117, 117, 117, 49, + 117, 117, 117, 117, 42, 117, 0 }; static const unsigned char _indic_syllable_machine_trans_targs[] = { - 27, 33, 38, 2, 39, 45, 46, 27, - 55, 8, 61, 56, 68, 69, 72, 27, - 77, 15, 83, 78, 86, 27, 91, 27, - 100, 21, 106, 101, 109, 114, 27, 125, - 27, 28, 48, 73, 75, 93, 94, 79, - 95, 115, 116, 87, 123, 128, 27, 29, - 31, 5, 47, 34, 42, 30, 1, 32, - 36, 0, 35, 37, 40, 41, 3, 43, - 4, 44, 27, 49, 51, 12, 71, 57, - 64, 50, 6, 52, 66, 59, 53, 11, - 70, 54, 7, 58, 60, 62, 63, 9, - 65, 10, 67, 27, 74, 17, 76, 89, - 81, 13, 92, 14, 80, 82, 84, 85, - 16, 88, 18, 90, 27, 27, 96, 98, - 19, 23, 102, 110, 97, 99, 112, 104, - 20, 103, 105, 107, 108, 22, 111, 24, - 113, 117, 118, 122, 119, 120, 25, 121, - 27, 124, 26, 126, 127 + 31, 37, 42, 2, 43, 46, 4, 50, + 51, 31, 60, 9, 66, 69, 61, 11, + 74, 75, 78, 31, 83, 17, 89, 92, + 93, 84, 31, 19, 98, 31, 107, 24, + 113, 116, 117, 108, 26, 122, 127, 31, + 134, 31, 32, 53, 79, 81, 100, 101, + 85, 102, 123, 124, 94, 132, 137, 31, + 33, 35, 6, 52, 38, 47, 34, 1, + 36, 40, 0, 39, 41, 44, 45, 3, + 48, 5, 49, 31, 54, 56, 14, 77, + 62, 70, 55, 7, 57, 72, 64, 58, + 13, 76, 59, 8, 63, 65, 67, 68, + 10, 71, 12, 73, 31, 80, 20, 82, + 96, 87, 15, 99, 16, 86, 88, 90, + 91, 18, 95, 21, 97, 31, 31, 103, + 105, 22, 27, 109, 118, 104, 106, 120, + 111, 23, 110, 112, 114, 115, 25, 119, + 28, 121, 125, 126, 131, 128, 129, 29, + 130, 31, 133, 30, 135, 136 }; static const char _indic_syllable_machine_trans_actions[] = { - 1, 0, 2, 0, 2, 2, 2, 3, - 2, 0, 2, 0, 2, 2, 2, 4, - 2, 0, 5, 0, 5, 6, 2, 7, - 2, 0, 2, 0, 2, 2, 8, 0, - 11, 2, 2, 5, 0, 12, 12, 0, - 2, 5, 2, 5, 2, 0, 13, 2, - 0, 0, 2, 0, 2, 2, 0, 2, - 2, 0, 0, 2, 2, 2, 0, 0, - 0, 2, 14, 2, 0, 0, 2, 0, - 2, 2, 0, 2, 2, 2, 2, 0, + 1, 0, 2, 0, 2, 0, 0, 2, + 2, 3, 2, 0, 2, 0, 0, 0, + 2, 2, 2, 4, 2, 0, 5, 0, + 5, 0, 6, 0, 2, 7, 2, 0, + 2, 0, 2, 0, 0, 2, 0, 8, + 0, 11, 2, 2, 5, 0, 12, 12, + 0, 2, 5, 2, 5, 2, 0, 13, + 2, 0, 0, 2, 0, 2, 2, 0, 2, 2, 0, 0, 2, 2, 2, 0, - 0, 0, 2, 15, 5, 0, 5, 2, - 2, 0, 5, 0, 0, 2, 5, 5, - 0, 0, 0, 2, 16, 17, 2, 0, - 0, 0, 0, 2, 2, 2, 2, 2, - 0, 0, 2, 2, 2, 0, 0, 0, - 2, 0, 18, 18, 0, 0, 0, 0, - 19, 2, 0, 0, 0 + 0, 0, 2, 14, 2, 0, 0, 2, + 0, 2, 2, 0, 2, 2, 2, 2, + 0, 2, 2, 0, 0, 2, 2, 2, + 0, 0, 0, 2, 15, 5, 0, 5, + 2, 2, 0, 5, 0, 0, 2, 5, + 5, 0, 0, 0, 2, 16, 17, 2, + 0, 0, 0, 0, 2, 2, 2, 2, + 2, 0, 0, 2, 2, 2, 0, 0, + 0, 2, 0, 18, 18, 0, 0, 0, + 0, 19, 2, 0, 0, 0 }; static const char _indic_syllable_machine_to_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -349,14 +384,16 @@ static const char _indic_syllable_machine_to_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 }; static const char _indic_syllable_machine_from_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 10, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -369,41 +406,42 @@ static const char _indic_syllable_machine_from_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0 + 0, 0 }; static const short _indic_syllable_machine_eof_trans[] = { - 1, 1, 1, 1, 1, 1, 8, 8, - 8, 8, 8, 8, 8, 16, 16, 22, - 16, 16, 16, 24, 24, 24, 24, 24, - 24, 1, 31, 0, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 109, 109, 110, - 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 92, 47, 47, 47, 47, - 47, 47, 47, 137, 137, 137, 137, 137, - 109 + 1, 1, 1, 1, 1, 1, 1, 10, + 10, 10, 10, 10, 10, 10, 10, 20, + 20, 27, 20, 27, 20, 20, 30, 30, + 30, 30, 30, 30, 30, 1, 40, 0, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 118, 118, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 101, 56, 56, 56, 56, + 56, 56, 56, 56, 146, 146, 146, 146, + 146, 118 }; -static const int indic_syllable_machine_start = 27; -static const int indic_syllable_machine_first_final = 27; +static const int indic_syllable_machine_start = 31; +static const int indic_syllable_machine_first_final = 31; static const int indic_syllable_machine_error = -1; -static const int indic_syllable_machine_en_main = 27; +static const int indic_syllable_machine_en_main = 31; #line 58 "hb-ot-shaper-indic-machine.rl" -#line 117 "hb-ot-shaper-indic-machine.rl" +#line 118 "hb-ot-shaper-indic-machine.rl" #define found_syllable(syllable_type) \ @@ -412,7 +450,7 @@ static const int indic_syllable_machine_en_main = 27; for (unsigned int i = ts; i < te; i++) \ info[i].syllable() = (syllable_serial << 4) | syllable_type; \ syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ + if (syllable_serial == 16) syllable_serial = 1; \ } HB_STMT_END inline void @@ -422,7 +460,7 @@ find_syllables_indic (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 426 "hb-ot-shaper-indic-machine.hh" +#line 453 "hb-ot-shaper-indic-machine.hh" { cs = indic_syllable_machine_start; ts = 0; @@ -430,7 +468,7 @@ find_syllables_indic (hb_buffer_t *buffer) act = 0; } -#line 137 "hb-ot-shaper-indic-machine.rl" +#line 138 "hb-ot-shaper-indic-machine.rl" p = 0; @@ -438,7 +476,7 @@ find_syllables_indic (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 442 "hb-ot-shaper-indic-machine.hh" +#line 465 "hb-ot-shaper-indic-machine.hh" { int _slen; int _trans; @@ -452,7 +490,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 456 "hb-ot-shaper-indic-machine.hh" +#line 477 "hb-ot-shaper-indic-machine.hh" } _keys = _indic_syllable_machine_trans_keys + (cs<<1); @@ -475,51 +513,51 @@ _eof_trans: {te = p+1;} break; case 11: -#line 113 "hb-ot-shaper-indic-machine.rl" +#line 114 "hb-ot-shaper-indic-machine.rl" {te = p+1;{ found_syllable (indic_non_indic_cluster); }} break; case 13: -#line 108 "hb-ot-shaper-indic-machine.rl" +#line 109 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_consonant_syllable); }} break; case 14: -#line 109 "hb-ot-shaper-indic-machine.rl" +#line 110 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_vowel_syllable); }} break; case 17: -#line 110 "hb-ot-shaper-indic-machine.rl" +#line 111 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_standalone_cluster); }} break; case 19: -#line 111 "hb-ot-shaper-indic-machine.rl" +#line 112 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_symbol_cluster); }} break; case 15: -#line 112 "hb-ot-shaper-indic-machine.rl" +#line 113 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} break; case 16: -#line 113 "hb-ot-shaper-indic-machine.rl" +#line 114 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_non_indic_cluster); }} break; case 1: -#line 108 "hb-ot-shaper-indic-machine.rl" +#line 109 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_consonant_syllable); }} break; case 3: -#line 109 "hb-ot-shaper-indic-machine.rl" +#line 110 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_vowel_syllable); }} break; case 7: -#line 110 "hb-ot-shaper-indic-machine.rl" +#line 111 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_standalone_cluster); }} break; case 8: -#line 111 "hb-ot-shaper-indic-machine.rl" +#line 112 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_symbol_cluster); }} break; case 4: -#line 112 "hb-ot-shaper-indic-machine.rl" +#line 113 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} break; case 6: @@ -540,19 +578,19 @@ _eof_trans: case 18: #line 1 "NONE" {te = p+1;} -#line 108 "hb-ot-shaper-indic-machine.rl" +#line 109 "hb-ot-shaper-indic-machine.rl" {act = 1;} break; case 5: #line 1 "NONE" {te = p+1;} -#line 112 "hb-ot-shaper-indic-machine.rl" +#line 113 "hb-ot-shaper-indic-machine.rl" {act = 5;} break; case 12: #line 1 "NONE" {te = p+1;} -#line 113 "hb-ot-shaper-indic-machine.rl" +#line 114 "hb-ot-shaper-indic-machine.rl" {act = 6;} break; #line 559 "hb-ot-shaper-indic-machine.hh" @@ -564,7 +602,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 568 "hb-ot-shaper-indic-machine.hh" +#line 566 "hb-ot-shaper-indic-machine.hh" } if ( ++p != pe ) @@ -580,7 +618,7 @@ _again: } -#line 145 "hb-ot-shaper-indic-machine.rl" +#line 146 "hb-ot-shaper-indic-machine.rl" } diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-indic-table.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-table.cc index bf6a2757bb..d9fb0510e4 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-indic-table.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-table.cc @@ -42,6 +42,7 @@ #define OT_PLACEHOLDER I_Cat(PLACEHOLDER) #define OT_DOTTEDCIRCLE I_Cat(DOTTEDCIRCLE) #define OT_RS I_Cat(RS) +#define OT_MPst I_Cat(MPst) #define OT_Repha I_Cat(Repha) #define OT_Ra I_Cat(Ra) #define OT_CM I_Cat(CM) @@ -80,9 +81,10 @@ static_assert (OT_VPst == M_Cat(VPst), ""); #define _OT_CS OT_CS /* 2 chars; CS */ #define _OT_DC OT_DOTTEDCIRCLE /* 1 chars; DOTTEDCIRCLE */ #define _OT_H OT_H /* 11 chars; H */ -#define _OT_M OT_M /* 143 chars; M */ +#define _OT_M OT_M /* 142 chars; M */ #define _OT_MH OT_MH /* 1 chars; MH */ #define _OT_ML OT_ML /* 1 chars; ML */ +#define _OT_MP OT_MPst /* 1 chars; MPst */ #define _OT_MR OT_MR /* 1 chars; MR */ #define _OT_MW OT_MW /* 2 chars; MW */ #define _OT_MY OT_MY /* 3 chars; MY */ @@ -200,7 +202,7 @@ static const uint16_t indic_table[] = { /* 0A28 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), /* 0A30 */ _(R,C), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), _(C,C), _(X,X), /* 0A38 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(X,X), _(M,AP), _(M,LM), - /* 0A40 */ _(M,AP), _(M,AP), _(M,AP), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP), + /* 0A40 */_(MP,AP), _(M,AP), _(M,AP), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP), /* 0A48 */ _(M,AP), _(X,X), _(X,X), _(M,AP), _(M,AP), _(H,B), _(X,X), _(X,X), /* 0A50 */ _(X,X), _(M,B), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), /* 0A58 */ _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(X,X), _(C,C), _(X,X), @@ -451,15 +453,12 @@ static const uint16_t indic_table[] = { /* Grantha */ /* 11300 */ _(X,X),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(X,X), _(X,X), _(X,X), - /* 11308 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 11310 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 11318 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 11320 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 11328 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 11330 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + +#define indic_offset_0x11338u 1720 + /* 11338 */ _(X,X), _(X,X), _(X,X), _(N,X), _(N,X), _(X,X), _(X,X), _(X,X), -}; /* Table items: 1776; occupancy: 69% */ +}; /* Table items: 1728; occupancy: 71% */ uint16_t hb_indic_get_categories (hb_codepoint_t u) @@ -497,7 +496,8 @@ hb_indic_get_categories (hb_codepoint_t u) break; case 0x11u: - if (hb_in_range<hb_codepoint_t> (u, 0x11300u, 0x1133Fu)) return indic_table[u - 0x11300u + indic_offset_0x11300u]; + if (hb_in_range<hb_codepoint_t> (u, 0x11300u, 0x11307u)) return indic_table[u - 0x11300u + indic_offset_0x11300u]; + if (hb_in_range<hb_codepoint_t> (u, 0x11338u, 0x1133Fu)) return indic_table[u - 0x11338u + indic_offset_0x11338u]; break; default: @@ -519,6 +519,7 @@ hb_indic_get_categories (hb_codepoint_t u) #undef _OT_M #undef _OT_MH #undef _OT_ML +#undef _OT_MP #undef _OT_MR #undef _OT_MW #undef _OT_MY diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-indic.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-indic.cc index 55509c1101..7652210d9d 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-indic.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-indic.cc @@ -223,15 +223,15 @@ enum { INDIC_BASIC_FEATURES = INDIC_INIT, /* Don't forget to update this! */ }; -static void +static bool setup_syllables_indic (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); -static void +static bool initial_reordering_indic (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); -static void +static bool final_reordering_indic (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); @@ -413,7 +413,7 @@ setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED, set_indic_properties (info[i]); } -static void +static bool setup_syllables_indic (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) @@ -422,6 +422,7 @@ setup_syllables_indic (const hb_ot_shape_plan_t *plan HB_UNUSED, find_syllables_indic (buffer); foreach_syllable (buffer, start, end) buffer->unsafe_to_break (start, end); + return false; } static int @@ -714,6 +715,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, } } } else if (info[i].indic_position() != POS_SMVD) { + if (info[i].indic_category() == I_Cat(MPst) && + i > start && info[i - 1].indic_category() == I_Cat(SM)) + info[i - 1].indic_position() = info[i].indic_position(); last_pos = (indic_position_t) info[i].indic_position(); } } @@ -729,7 +733,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, if (info[j].indic_position() < POS_SMVD) info[j].indic_position() = info[i].indic_position(); last = i; - } else if (info[i].indic_category() == I_Cat(M)) + } else if (FLAG_UNSAFE (info[i].indic_category()) & (FLAG (I_Cat(M)) | FLAG (I_Cat(MPst)))) last = i; } @@ -742,14 +746,40 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, /* Sit tight, rock 'n roll! */ hb_stable_sort (info + start, end - start, compare_indic_order); - /* Find base again */ + + /* Find base again; also flip left-matra sequence. */ + unsigned first_left_matra = end; + unsigned last_left_matra = end; base = end; for (unsigned int i = start; i < end; i++) + { if (info[i].indic_position() == POS_BASE_C) { base = i; break; } + else if (info[i].indic_position() == POS_PRE_M) + { + if (first_left_matra == end) + first_left_matra = i; + last_left_matra = i; + } + } + /* https://github.com/harfbuzz/harfbuzz/issues/3863 */ + if (first_left_matra < last_left_matra) + { + /* No need to merge clusters, handled later. */ + buffer->reverse_range (first_left_matra, last_left_matra + 1); + /* Reverse back nuktas, etc. */ + unsigned i = first_left_matra; + for (unsigned j = i; j <= last_left_matra; j++) + if (FLAG_UNSAFE (info[j].indic_category()) & (FLAG (I_Cat(M)) | FLAG (I_Cat(MPst)))) + { + buffer->reverse_range (i, j + 1); + i = j + 1; + } + } + /* Things are out-of-control for post base positions, they may shuffle * around like crazy. In old-spec mode, we move halants around, so in * that case merge all clusters after base. Otherwise, check the sort @@ -955,25 +985,29 @@ initial_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, } } -static void +static bool initial_reordering_indic (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { + bool ret = false; if (!buffer->message (font, "start reordering indic initial")) - return; + return ret; update_consonant_positions_indic (plan, font, buffer); - hb_syllabic_insert_dotted_circles (font, buffer, - indic_broken_cluster, - I_Cat(DOTTEDCIRCLE), - I_Cat(Repha), - POS_END); + if (hb_syllabic_insert_dotted_circles (font, buffer, + indic_broken_cluster, + I_Cat(DOTTEDCIRCLE), + I_Cat(Repha), + POS_END)) + ret = true; foreach_syllable (buffer, start, end) initial_reordering_syllable_indic (plan, font->face, buffer, start, end); (void) buffer->message (font, "end reordering indic initial"); + + return ret; } static void @@ -1116,7 +1150,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, { search: while (new_pos > start && - !(is_one_of (info[new_pos], (FLAG (I_Cat(M)) | FLAG (I_Cat(H)))))) + !(is_one_of (info[new_pos], (FLAG (I_Cat(M)) | FLAG (I_Cat(MPst)) | FLAG (I_Cat(H)))))) new_pos--; /* If we found no Halant we are done. @@ -1316,7 +1350,8 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, unlikely (is_halant (info[new_reph_pos]))) { for (unsigned int i = base + 1; i < new_reph_pos; i++) - if (info[i].indic_category() == I_Cat(M)) { + if (FLAG_UNSAFE (info[i].indic_category()) & (FLAG (I_Cat(M)) | FLAG (I_Cat(MPst)))) + { /* Ok, got it. */ new_reph_pos--; } @@ -1376,7 +1411,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL) { while (new_pos > start && - !(is_one_of (info[new_pos - 1], FLAG(I_Cat(M)) | FLAG (I_Cat(H))))) + !(is_one_of (info[new_pos - 1], FLAG (I_Cat(M)) | FLAG (I_Cat(MPst)) | FLAG (I_Cat(H))))) new_pos--; } @@ -1439,13 +1474,13 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, } -static void +static bool final_reordering_indic (const hb_ot_shape_plan_t *plan, hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { unsigned int count = buffer->len; - if (unlikely (!count)) return; + if (unlikely (!count)) return false; if (buffer->message (font, "start reordering indic final")) { foreach_syllable (buffer, start, end) @@ -1455,6 +1490,8 @@ final_reordering_indic (const hb_ot_shape_plan_t *plan, HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category); HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position); + + return false; } diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh index e18bd75ef1..fd91ee0caf 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh @@ -48,7 +48,7 @@ enum khmer_syllable_type_t { }; -#line 52 "hb-ot-shaper-khmer-machine.hh" +#line 49 "hb-ot-shaper-khmer-machine.hh" #define khmer_syllable_machine_ex_C 1u #define khmer_syllable_machine_ex_DOTTEDCIRCLE 11u #define khmer_syllable_machine_ex_H 4u @@ -66,7 +66,7 @@ enum khmer_syllable_type_t { #define khmer_syllable_machine_ex_ZWNJ 5u -#line 70 "hb-ot-shaper-khmer-machine.hh" +#line 65 "hb-ot-shaper-khmer-machine.hh" static const unsigned char _khmer_syllable_machine_trans_keys[] = { 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, @@ -284,7 +284,7 @@ static const int khmer_syllable_machine_en_main = 21; for (unsigned int i = ts; i < te; i++) \ info[i].syllable() = (syllable_serial << 4) | syllable_type; \ syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ + if (syllable_serial == 16) syllable_serial = 1; \ } HB_STMT_END inline void @@ -294,7 +294,7 @@ find_syllables_khmer (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 298 "hb-ot-shaper-khmer-machine.hh" +#line 287 "hb-ot-shaper-khmer-machine.hh" { cs = khmer_syllable_machine_start; ts = 0; @@ -310,7 +310,7 @@ find_syllables_khmer (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 314 "hb-ot-shaper-khmer-machine.hh" +#line 299 "hb-ot-shaper-khmer-machine.hh" { int _slen; int _trans; @@ -324,7 +324,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 328 "hb-ot-shaper-khmer-machine.hh" +#line 311 "hb-ot-shaper-khmer-machine.hh" } _keys = _khmer_syllable_machine_trans_keys + (cs<<1); @@ -394,7 +394,7 @@ _eof_trans: #line 98 "hb-ot-shaper-khmer-machine.rl" {act = 3;} break; -#line 398 "hb-ot-shaper-khmer-machine.hh" +#line 368 "hb-ot-shaper-khmer-machine.hh" } _again: @@ -403,7 +403,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 407 "hb-ot-shaper-khmer-machine.hh" +#line 375 "hb-ot-shaper-khmer-machine.hh" } if ( ++p != pe ) diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-khmer.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-khmer.cc index d9795589fa..019a285102 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-khmer.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-khmer.cc @@ -89,11 +89,11 @@ set_khmer_properties (hb_glyph_info_t &info) info.khmer_category() = (khmer_category_t) (type & 0xFFu); } -static void +static bool setup_syllables_khmer (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); -static void +static bool reorder_khmer (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); @@ -192,7 +192,7 @@ setup_masks_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED, set_khmer_properties (info[i]); } -static void +static bool setup_syllables_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) @@ -201,6 +201,7 @@ setup_syllables_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED, find_syllables_khmer (buffer); foreach_syllable (buffer, start, end) buffer->unsafe_to_break (start, end); + return false; } @@ -303,23 +304,27 @@ reorder_syllable_khmer (const hb_ot_shape_plan_t *plan, } } -static void +static bool reorder_khmer (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { + bool ret = false; if (buffer->message (font, "start reordering khmer")) { - hb_syllabic_insert_dotted_circles (font, buffer, - khmer_broken_cluster, - K_Cat(DOTTEDCIRCLE), - (unsigned) -1); + if (hb_syllabic_insert_dotted_circles (font, buffer, + khmer_broken_cluster, + K_Cat(DOTTEDCIRCLE), + (unsigned) -1)) + ret = true; foreach_syllable (buffer, start, end) reorder_syllable_khmer (plan, font->face, buffer, start, end); (void) buffer->message (font, "end reordering khmer"); } HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_category); + + return ret; } diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh index b109708937..87cded4ed8 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh @@ -50,7 +50,7 @@ enum myanmar_syllable_type_t { }; -#line 54 "hb-ot-shaper-myanmar-machine.hh" +#line 51 "hb-ot-shaper-myanmar-machine.hh" #define myanmar_syllable_machine_ex_A 9u #define myanmar_syllable_machine_ex_As 32u #define myanmar_syllable_machine_ex_C 1u @@ -77,7 +77,7 @@ enum myanmar_syllable_type_t { #define myanmar_syllable_machine_ex_ZWNJ 5u -#line 81 "hb-ot-shaper-myanmar-machine.hh" +#line 76 "hb-ot-shaper-myanmar-machine.hh" static const unsigned char _myanmar_syllable_machine_trans_keys[] = { 1u, 41u, 3u, 41u, 5u, 39u, 5u, 8u, 3u, 41u, 3u, 39u, 3u, 39u, 5u, 39u, 5u, 39u, 3u, 39u, 3u, 39u, 3u, 41u, 5u, 39u, 1u, 15u, 3u, 39u, 3u, 39u, @@ -433,7 +433,7 @@ static const int myanmar_syllable_machine_en_main = 0; for (unsigned int i = ts; i < te; i++) \ info[i].syllable() = (syllable_serial << 4) | syllable_type; \ syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ + if (syllable_serial == 16) syllable_serial = 1; \ } HB_STMT_END inline void @@ -443,7 +443,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 447 "hb-ot-shaper-myanmar-machine.hh" +#line 436 "hb-ot-shaper-myanmar-machine.hh" { cs = myanmar_syllable_machine_start; ts = 0; @@ -459,7 +459,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 463 "hb-ot-shaper-myanmar-machine.hh" +#line 448 "hb-ot-shaper-myanmar-machine.hh" { int _slen; int _trans; @@ -473,7 +473,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 477 "hb-ot-shaper-myanmar-machine.hh" +#line 460 "hb-ot-shaper-myanmar-machine.hh" } _keys = _myanmar_syllable_machine_trans_keys + (cs<<1); @@ -519,7 +519,7 @@ _eof_trans: #line 113 "hb-ot-shaper-myanmar-machine.rl" {te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }} break; -#line 523 "hb-ot-shaper-myanmar-machine.hh" +#line 498 "hb-ot-shaper-myanmar-machine.hh" } _again: @@ -528,7 +528,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 532 "hb-ot-shaper-myanmar-machine.hh" +#line 505 "hb-ot-shaper-myanmar-machine.hh" } if ( ++p != pe ) diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar.cc index 78bd8de524..1b2a085a8d 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar.cc @@ -98,11 +98,11 @@ is_consonant_myanmar (const hb_glyph_info_t &info) } -static void +static bool setup_syllables_myanmar (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); -static void +static bool reorder_myanmar (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); @@ -150,7 +150,7 @@ setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED, set_myanmar_properties (info[i]); } -static void +static bool setup_syllables_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) @@ -159,6 +159,7 @@ setup_syllables_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED, find_syllables_myanmar (buffer); foreach_syllable (buffer, start, end) buffer->unsafe_to_break (start, end); + return false; } static int @@ -270,6 +271,33 @@ initial_reordering_consonant_syllable (hb_buffer_t *buffer, /* Sit tight, rock 'n roll! */ buffer->sort (start, end, compare_myanmar_order); + + /* Flip left-matra sequence. */ + unsigned first_left_matra = end; + unsigned last_left_matra = end; + for (unsigned int i = start; i < end; i++) + { + if (info[i].myanmar_position() == POS_PRE_M) + { + if (first_left_matra == end) + first_left_matra = i; + last_left_matra = i; + } + } + /* https://github.com/harfbuzz/harfbuzz/issues/3863 */ + if (first_left_matra < last_left_matra) + { + /* No need to merge clusters, done already? */ + buffer->reverse_range (first_left_matra, last_left_matra + 1); + /* Reverse back VS, etc. */ + unsigned i = first_left_matra; + for (unsigned j = i; j <= last_left_matra; j++) + if (info[j].myanmar_category() == M_Cat(VPre)) + { + buffer->reverse_range (i, j + 1); + i = j + 1; + } + } } static void @@ -291,16 +319,18 @@ reorder_syllable_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED, } } -static void +static bool reorder_myanmar (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { + bool ret = false; if (buffer->message (font, "start reordering myanmar")) { - hb_syllabic_insert_dotted_circles (font, buffer, - myanmar_broken_cluster, - M_Cat(DOTTEDCIRCLE)); + if (hb_syllabic_insert_dotted_circles (font, buffer, + myanmar_broken_cluster, + M_Cat(DOTTEDCIRCLE))) + ret = true; foreach_syllable (buffer, start, end) reorder_syllable_myanmar (plan, font->face, buffer, start, end); @@ -309,6 +339,8 @@ reorder_myanmar (const hb_ot_shape_plan_t *plan, HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_category); HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_position); + + return ret; } @@ -331,6 +363,7 @@ const hb_ot_shaper_t _hb_ot_shaper_myanmar = }; +#ifndef HB_NO_OT_SHAPER_MYANMAR_ZAWGYI /* Ugly Zawgyi encoding. * Disable all auto processing. * https://github.com/harfbuzz/harfbuzz/issues/1162 */ @@ -351,6 +384,7 @@ const hb_ot_shaper_t _hb_ot_shaper_myanmar_zawgyi = HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ }; +#endif #endif diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-syllabic.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-syllabic.cc index a8e0d8e8c1..89226ae4a1 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-syllabic.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-syllabic.cc @@ -29,7 +29,7 @@ #include "hb-ot-shaper-syllabic.hh" -void +bool hb_syllabic_insert_dotted_circles (hb_font_t *font, hb_buffer_t *buffer, unsigned int broken_syllable_type, @@ -38,13 +38,13 @@ hb_syllabic_insert_dotted_circles (hb_font_t *font, int dottedcircle_position) { if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)) - return; + return false; if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE))) - return; + return false; hb_codepoint_t dottedcircle_glyph; if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph)) - return; + return false; hb_glyph_info_t dottedcircle = {0}; dottedcircle.codepoint = 0x25CCu; @@ -84,14 +84,16 @@ hb_syllabic_insert_dotted_circles (hb_font_t *font, (void) buffer->next_glyph (); } buffer->sync (); + return true; } -HB_INTERNAL void +HB_INTERNAL bool hb_syllabic_clear_var (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { HB_BUFFER_DEALLOCATE_VAR (buffer, syllable); + return false; } diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-syllabic.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-syllabic.hh index e8a15bb48a..f240ad1c26 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-syllabic.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-syllabic.hh @@ -30,7 +30,7 @@ #include "hb-ot-shaper.hh" -HB_INTERNAL void +HB_INTERNAL bool hb_syllabic_insert_dotted_circles (hb_font_t *font, hb_buffer_t *buffer, unsigned int broken_syllable_type, @@ -38,7 +38,7 @@ hb_syllabic_insert_dotted_circles (hb_font_t *font, int repha_category = -1, int dottedcircle_position = -1); -HB_INTERNAL void +HB_INTERNAL bool hb_syllabic_clear_var (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc index 15349b1e64..6cd67cde35 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc @@ -98,9 +98,9 @@ static hb_codepoint_t thai_pua_shape (hb_codepoint_t u, thai_action_t action, hb_font_t *font) { struct thai_pua_mapping_t { - hb_codepoint_t u; - hb_codepoint_t win_pua; - hb_codepoint_t mac_pua; + uint16_t u; + uint16_t win_pua; + uint16_t mac_pua; } const *pua_mappings = nullptr; static const thai_pua_mapping_t SD_mappings[] = { {0x0E48u, 0xF70Au, 0xF88Bu}, /* MAI EK */ diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh index 41e8a34f3b..f2fbdb725b 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh @@ -53,7 +53,7 @@ enum use_syllable_type_t { }; -#line 57 "hb-ot-shaper-use-machine.hh" +#line 54 "hb-ot-shaper-use-machine.hh" #define use_syllable_machine_ex_B 1u #define use_syllable_machine_ex_CGJ 6u #define use_syllable_machine_ex_CMAbv 31u @@ -97,7 +97,7 @@ enum use_syllable_type_t { #define use_syllable_machine_ex_ZWNJ 14u -#line 101 "hb-ot-shaper-use-machine.hh" +#line 96 "hb-ot-shaper-use-machine.hh" static const unsigned char _use_syllable_machine_trans_keys[] = { 0u, 53u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, @@ -839,7 +839,7 @@ static const int use_syllable_machine_en_main = 0; for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \ info[i].syllable() = (syllable_serial << 4) | syllable_type; \ syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ + if (syllable_serial == 16) syllable_serial = 1; \ } HB_STMT_END @@ -929,7 +929,7 @@ find_syllables_use (hb_buffer_t *buffer) unsigned int act HB_UNUSED; int cs; -#line 933 "hb-ot-shaper-use-machine.hh" +#line 922 "hb-ot-shaper-use-machine.hh" { cs = use_syllable_machine_start; ts = 0; @@ -942,7 +942,7 @@ find_syllables_use (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 946 "hb-ot-shaper-use-machine.hh" +#line 931 "hb-ot-shaper-use-machine.hh" { int _slen; int _trans; @@ -956,7 +956,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 960 "hb-ot-shaper-use-machine.hh" +#line 943 "hb-ot-shaper-use-machine.hh" } _keys = _use_syllable_machine_trans_keys + (cs<<1); @@ -1046,7 +1046,7 @@ _eof_trans: #line 178 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_non_cluster); }} break; -#line 1050 "hb-ot-shaper-use-machine.hh" +#line 1014 "hb-ot-shaper-use-machine.hh" } _again: @@ -1055,7 +1055,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 1059 "hb-ot-shaper-use-machine.hh" +#line 1021 "hb-ot-shaper-use-machine.hh" } if ( ++p != pe ) diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh index 9833fb55de..6b6b552ee5 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh @@ -91,6 +91,9 @@ #define VMPre USE(VMPre) #pragma GCC diagnostic pop + +#ifndef HB_OPTIMIZE_SIZE + static const uint8_t hb_use_u8[3141] = { @@ -357,6 +360,273 @@ hb_use_get_category (unsigned u) return u<921600u?hb_use_u8[2777+(((hb_use_u8[593+(((hb_use_u16[((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O; } + +#else + +static const uint8_t +hb_use_u8[3413] = +{ + 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 51, 57, 58, 179, 195, 61, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 14, 0, 1, 1, 2, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 1, + 11, 12, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 17, 18, 19, 1, + 1, 20, 1, 1, 1, 1, 21, 1, 1, 1, 1, 1, 1, 1, 22, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 24, 25, 26, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, + 28, 1, 1, 1, 1, 1, 29, 1, 1, 1, 1, 30, 31, 1, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 1, 46, 47, 48, + 49, 50, 50, 50, 50, 51, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 52, 53, 1, 1, 1, + 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 50, 55, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 56, 1, 1, + 1, 1, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 58, 59, 1, 60, 1, 1, 1, 1, 61, 1, 1, 1, 1, 1, + 1, 62, 63, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, 8, 0, 0, 0, 0, + 0, 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, 36, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 0, 55, 56, 57, 58, 59, 0, 0, 0, 60, 61, 62, 63, 55, 64, 65, + 66, 67, 55, 55, 68, 69, 70, 0, 0, 71, 72, 73, 74, 55, 75, 76, + 0, 77, 55, 78, 79, 80, 0, 0, 0, 81, 82, 83, 84, 85, 86, 55, + 87, 55, 88, 89, 0, 0, 0, 90, 91, 0, 0, 0, 0, 0, 0, 0, + 92, 93, 94, 0, 95, 96, 0, 0, 97, 0, 0, 0, 0, 0, 0, 98, + 0, 0, 99, 55, 100, 0, 0, 0, 0, 101, 102, 55, 103, 104, 105, 106, + 107, 55, 108, 109, 0, 110, 111, 112, 113, 55, 114, 115, 116, 55, 117, 118, + 119, 0, 0, 0, 0, 0, 0, 55, 120, 121, 0, 0, 0, 0, 0, 0, + 122, 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, 124, 125, 126, 0, + 0, 127, 128, 129, 0, 0, 0, 50, 130, 0, 0, 0, 0, 131, 132, 0, + 0, 55, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 134, 0, + 0, 0, 99, 135, 99, 136, 137, 138, 0, 139, 140, 141, 142, 143, 144, 145, + 0, 146, 147, 148, 149, 143, 150, 151, 152, 153, 154, 155, 0, 156, 157, 158, + 159, 160, 161, 162, 163, 0, 0, 0, 0, 55, 164, 165, 166, 167, 168, 169, + 0, 0, 0, 0, 0, 55, 170, 171, 0, 55, 172, 173, 0, 55, 174, 66, + 0, 175, 176, 177, 0, 0, 0, 0, 0, 55, 178, 0, 0, 0, 0, 0, + 0, 179, 180, 181, 0, 0, 182, 183, 184, 185, 186, 187, 55, 188, 0, 0, + 0, 189, 190, 191, 192, 193, 194, 0, 0, 195, 196, 197, 198, 199, 66, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 200, 201, 202, 203, 0, 0, 0, 0, + 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 204, 205, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 66, 0, 55, 206, 0, 0, 0, 0, 0, + 0, 55, 55, 207, 208, 209, 0, 0, 210, 55, 55, 55, 55, 55, 55, 211, + 0, 55, 55, 55, 212, 213, 0, 0, 0, 0, 0, 0, 214, 0, 0, 0, + 0, 55, 215, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 217, 55, + 218, 0, 0, 0, 0, 0, 0, 99, 219, 55, 55, 220, 0, 0, 0, 0, + 0, 221, 221, 221, 221, 221, 221, 221, 221, 222, 222, 222, 222, 222, 222, 222, + 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 2, 2, 2, 2, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, + 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 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, 8, 9, 9, 9, 9, 0, 0, 0, 7, 10, + 0, 2, 2, 2, 2, 11, 12, 0, 0, 9, 13, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 14, 15, 16, 17, 18, 19, 20, 14, 21, 22, + 23, 10, 24, 25, 18, 2, 2, 2, 2, 2, 18, 0, 2, 2, 2, 2, + 2, 0, 2, 2, 2, 2, 2, 2, 2, 26, 27, 28, 2, 2, 2, 7, + 28, 7, 28, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 2, 2, + 2, 7, 7, 0, 2, 2, 0, 15, 16, 17, 18, 29, 30, 31, 30, 32, + 0, 0, 0, 0, 33, 0, 0, 2, 28, 2, 0, 0, 0, 0, 0, 7, + 34, 10, 13, 28, 2, 2, 7, 0, 28, 7, 2, 28, 7, 2, 0, 35, + 16, 17, 29, 0, 25, 36, 25, 37, 0, 38, 0, 0, 0, 28, 2, 7, + 7, 0, 0, 0, 2, 2, 2, 2, 2, 39, 40, 41, 0, 0, 0, 0, + 0, 10, 13, 28, 2, 2, 2, 2, 28, 2, 28, 2, 2, 2, 2, 2, + 2, 7, 2, 28, 2, 2, 0, 15, 16, 17, 18, 19, 25, 20, 33, 22, + 0, 0, 0, 0, 0, 28, 39, 39, 42, 10, 27, 28, 2, 2, 2, 7, + 28, 7, 2, 28, 2, 2, 0, 15, 43, 0, 0, 25, 20, 0, 0, 2, + 28, 28, 0, 0, 0, 0, 0, 0, 0, 0, 44, 28, 2, 2, 7, 0, + 2, 7, 2, 2, 0, 28, 7, 7, 2, 0, 28, 7, 0, 2, 7, 0, + 2, 2, 2, 2, 2, 2, 0, 0, 21, 14, 45, 0, 46, 31, 46, 32, + 0, 0, 0, 0, 33, 0, 0, 0, 0, 13, 27, 47, 2, 2, 2, 7, + 2, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 15, + 20, 14, 21, 45, 20, 36, 20, 37, 0, 0, 0, 25, 29, 2, 7, 0, + 0, 8, 27, 28, 2, 2, 2, 7, 2, 2, 2, 28, 2, 2, 0, 15, + 43, 0, 0, 33, 45, 0, 0, 0, 7, 48, 49, 0, 0, 0, 0, 0, + 0, 9, 27, 2, 2, 2, 2, 7, 2, 2, 2, 2, 2, 2, 50, 51, + 21, 21, 17, 29, 46, 31, 46, 32, 52, 0, 0, 0, 33, 0, 0, 0, + 28, 10, 27, 28, 2, 2, 2, 2, 2, 2, 2, 2, 7, 0, 2, 2, + 2, 2, 28, 2, 2, 2, 2, 28, 0, 2, 2, 2, 7, 0, 53, 0, + 33, 21, 20, 29, 29, 16, 46, 46, 23, 0, 21, 0, 0, 0, 0, 0, + 0, 2, 0, 2, 7, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, + 0, 2, 2, 54, 54, 55, 0, 0, 16, 2, 2, 2, 2, 28, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 7, 0, 56, 19, 57, 20, 20, 18, 18, + 44, 19, 9, 29, 9, 2, 2, 58, 59, 59, 59, 59, 59, 60, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, + 0, 0, 0, 0, 62, 0, 0, 0, 0, 2, 2, 2, 2, 2, 63, 43, + 57, 64, 20, 20, 65, 66, 67, 68, 69, 2, 2, 2, 2, 2, 1, 0, + 3, 2, 2, 2, 21, 18, 2, 2, 70, 69, 71, 72, 63, 71, 27, 27, + 2, 50, 20, 51, 2, 2, 2, 2, 2, 2, 73, 74, 75, 27, 27, 76, + 77, 2, 2, 2, 2, 2, 27, 43, 0, 2, 57, 78, 0, 0, 0, 0, + 28, 2, 57, 45, 0, 0, 0, 0, 0, 2, 57, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 7, 2, 7, 57, 0, 0, 0, 0, 0, + 0, 2, 2, 79, 43, 20, 57, 18, 46, 46, 46, 46, 13, 80, 81, 82, + 83, 84, 85, 0, 0, 0, 0, 86, 0, 7, 0, 0, 28, 0, 87, 79, + 88, 2, 2, 2, 2, 7, 0, 0, 0, 40, 40, 89, 90, 2, 2, 2, + 2, 2, 2, 2, 2, 11, 7, 0, 0, 91, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 7, 20, 78, 43, 20, 92, 59, 0, + 0, 93, 94, 93, 93, 95, 96, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 0, 2, 2, 7, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, + 0, 2, 2, 2, 2, 27, 0, 0, 0, 2, 2, 2, 2, 2, 7, 0, + 0, 2, 2, 2, 50, 97, 43, 0, 0, 2, 2, 98, 99, 100, 101, 59, + 61, 102, 14, 43, 20, 57, 19, 78, 46, 46, 74, 9, 9, 9, 103, 44, + 38, 9, 104, 72, 2, 2, 2, 2, 2, 2, 2, 105, 20, 18, 18, 20, + 46, 46, 20, 106, 2, 2, 2, 7, 0, 0, 0, 0, 0, 0, 107, 108, + 109, 109, 109, 0, 0, 0, 0, 0, 0, 104, 72, 2, 2, 2, 2, 2, + 2, 58, 59, 57, 23, 20, 110, 59, 2, 2, 2, 2, 105, 20, 21, 43, + 43, 100, 12, 0, 0, 0, 0, 0, 0, 2, 2, 59, 16, 46, 21, 111, + 100, 100, 100, 112, 113, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 28, + 2, 9, 44, 114, 114, 114, 9, 114, 114, 13, 114, 114, 114, 24, 0, 38, + 0, 0, 0, 115, 49, 9, 3, 0, 0, 0, 0, 0, 0, 0, 116, 0, + 0, 0, 0, 0, 0, 0, 4, 117, 118, 40, 40, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 118, 118, 119, 118, 118, 118, 118, 118, 118, 118, + 118, 0, 0, 120, 0, 0, 0, 0, 0, 0, 5, 120, 0, 0, 0, 0, + 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, + 0, 2, 2, 2, 2, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, + 121, 2, 51, 2, 106, 2, 8, 2, 2, 2, 63, 17, 14, 0, 0, 29, + 0, 2, 2, 0, 0, 0, 0, 0, 0, 27, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 122, 21, 21, 21, 21, 21, 21, 21, 123, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 0, + 50, 2, 2, 2, 20, 20, 124, 114, 0, 2, 2, 2, 125, 18, 57, 18, + 111, 100, 126, 0, 0, 0, 0, 0, 0, 9, 127, 2, 2, 2, 2, 2, + 2, 2, 128, 21, 20, 18, 46, 129, 130, 131, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 50, 28, 2, 2, 2, 2, 2, 2, 2, 2, 8, 20, 57, + 97, 74, 132, 133, 134, 0, 0, 0, 0, 2, 135, 2, 2, 2, 2, 136, + 0, 28, 2, 40, 3, 0, 77, 13, 2, 51, 20, 137, 50, 51, 2, 2, + 103, 8, 7, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 138, 19, + 23, 0, 0, 139, 140, 0, 0, 0, 0, 2, 63, 43, 21, 78, 45, 141, + 0, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, 0, 0, 0, 0, 0, + 4, 118, 118, 118, 118, 119, 0, 0, 0, 2, 2, 2, 2, 2, 7, 2, + 2, 2, 7, 2, 28, 2, 2, 2, 2, 2, 28, 2, 2, 2, 28, 7, + 0, 125, 18, 25, 29, 0, 0, 142, 143, 2, 2, 28, 2, 28, 2, 2, + 2, 2, 2, 2, 0, 12, 35, 0, 144, 2, 2, 11, 35, 0, 28, 2, + 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 2, 2, + 7, 2, 2, 9, 39, 0, 0, 0, 0, 2, 2, 2, 2, 2, 25, 36, + 0, 2, 2, 2, 114, 114, 114, 114, 114, 145, 2, 7, 0, 0, 0, 0, + 0, 2, 12, 12, 0, 0, 0, 0, 0, 7, 2, 2, 7, 2, 2, 2, + 2, 28, 2, 7, 0, 28, 2, 0, 0, 146, 147, 148, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 20, 20, 18, 18, 18, 20, 20, 131, 0, 0, 0, + 0, 0, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 2, 2, 2, 2, + 2, 51, 50, 51, 0, 0, 0, 0, 150, 9, 72, 2, 2, 2, 2, 2, + 2, 16, 17, 19, 14, 22, 35, 0, 0, 0, 29, 0, 0, 0, 0, 0, + 0, 9, 47, 2, 2, 2, 2, 2, 2, 2, 2, 2, 125, 18, 20, 151, + 20, 19, 152, 153, 2, 2, 2, 2, 2, 0, 0, 63, 154, 0, 0, 0, + 0, 2, 11, 0, 0, 0, 0, 0, 0, 2, 63, 23, 18, 18, 18, 20, + 20, 106, 155, 0, 0, 54, 156, 29, 157, 28, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 21, 17, 20, 20, 158, 42, 0, 0, 0, + 47, 125, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 7, 7, 2, 2, + 28, 2, 2, 2, 2, 2, 2, 2, 28, 2, 2, 2, 2, 2, 2, 2, + 8, 16, 17, 19, 20, 159, 29, 0, 0, 9, 9, 28, 2, 2, 2, 7, + 28, 7, 2, 28, 2, 2, 56, 15, 21, 14, 21, 45, 30, 31, 30, 32, + 0, 0, 0, 0, 33, 0, 0, 0, 2, 2, 21, 0, 9, 9, 9, 44, + 0, 9, 9, 44, 0, 0, 0, 0, 0, 2, 2, 63, 23, 18, 18, 18, + 20, 21, 123, 13, 15, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, + 160, 161, 0, 0, 0, 0, 0, 0, 0, 16, 17, 18, 18, 64, 97, 23, + 157, 9, 162, 7, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 63, 23, 18, 18, 0, 46, 46, 9, 163, 35, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 2, 18, 0, 21, 17, 18, 18, 19, 14, 80, + 163, 36, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 8, 164, + 23, 18, 20, 20, 162, 7, 0, 0, 0, 2, 2, 2, 2, 2, 7, 41, + 133, 21, 20, 18, 74, 19, 20, 0, 0, 2, 2, 2, 7, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 16, 17, 18, 19, 20, 103, 163, 35, 0, + 0, 2, 2, 2, 7, 28, 0, 2, 2, 2, 2, 28, 7, 2, 2, 2, + 2, 21, 21, 16, 30, 31, 10, 165, 166, 167, 168, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 0, 2, 2, 2, 63, 23, 18, 18, 0, 20, 21, + 27, 106, 0, 31, 0, 0, 0, 0, 0, 50, 18, 20, 20, 20, 137, 2, + 2, 2, 169, 170, 9, 13, 171, 70, 172, 0, 0, 1, 144, 0, 0, 0, + 0, 50, 18, 20, 14, 17, 18, 2, 2, 2, 2, 155, 155, 155, 173, 173, + 173, 173, 173, 173, 13, 174, 0, 28, 0, 20, 18, 18, 29, 20, 20, 9, + 163, 0, 59, 59, 59, 59, 59, 59, 59, 64, 19, 80, 44, 0, 0, 0, + 0, 2, 2, 2, 7, 2, 28, 2, 2, 50, 20, 20, 29, 0, 36, 20, + 25, 9, 156, 175, 171, 0, 0, 0, 0, 2, 2, 2, 28, 7, 2, 2, + 2, 2, 2, 2, 2, 2, 21, 21, 45, 20, 33, 80, 66, 0, 0, 0, + 0, 2, 176, 64, 45, 0, 0, 0, 0, 9, 177, 2, 2, 2, 2, 2, + 2, 2, 2, 21, 20, 18, 29, 0, 46, 14, 140, 0, 0, 0, 0, 0, + 0, 178, 178, 178, 106, 179, 178, 0, 0, 145, 2, 2, 180, 114, 114, 114, + 114, 114, 114, 114, 0, 0, 0, 0, 0, 9, 9, 9, 44, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 7, 0, 56, 181, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, + 38, 114, 24, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, + 0, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 56, + 35, 0, 4, 118, 118, 118, 119, 0, 0, 9, 9, 9, 47, 2, 2, 2, + 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, + 44, 2, 2, 2, 2, 2, 2, 9, 9, 2, 2, 2, 2, 2, 2, 20, + 20, 2, 2, 42, 42, 42, 90, 0, 0, O, O, O, GB, B, B, GB, + O, O, WJ,FMPst,FMPst, O, CGJ, B, O, B,VMAbv,VMAbv,VMAbv, O,VMAbv, B, + CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, + VAbv, VAbv, VAbv, VPst, VPst, VPst, H, VPre, VPst,VMBlw, O, O, VAbv, GB,VMAbv,VMPst, + VMPst, O, B, VBlw, O, O, VPre, VPre, O, VPre, H, O, VPst,FMAbv, O,CMBlw, + O, VAbv, O, VAbv, H, O,VMBlw,VMAbv,CMAbv, GB, GB, O, MBlw,CMAbv,CMAbv, VPst, + VAbv,VMAbv, O, VPst, O, VPre, VPre,VMAbv, B, O, CS, CS,VMPst, B, VAbv, VAbv, + B, R, O, HVM, O, O,FMBlw, O,CMAbv, O,CMBlw, VAbv, VBlw, B, SUB, SUB, + SUB, O, SUB, SUB, O,FMBlw, O, B, VPst, VBlw, VPre,VMAbv,VMBlw,VMPst, IS, VAbv, + MPst, MPre, MBlw, MBlw, B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, VPst, VPre, VAbv, VAbv, + VMPst,VMPst,VMBlw, B,VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv, + VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB,CMAbv,CMAbv, B, GB, + B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, MPre, MBlw, + SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, B, O, + SMAbv,SMBlw,SMAbv,SMAbv,SMAbv, VPst, IS, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv, + CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, O, H, MPst, VPst, H, + VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, MBlw, MPst, MBlw, H, + O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, B, B, VPre, O, + VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst, + CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, IS,CMAbv, O, VPst, B, R, + R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,FMAbv, B, CS, CS, H,CMBlw,VMPst, + H,VMPst, VAbv,VMAbv, VPst, IS, R, MPst, R, MPst,CMBlw, B,FMBlw, VBlw,VMAbv, R, + MBlw, MBlw, GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, GB, VAbv, R,VMPst, H, H, B, + H, B,VMBlw, O, VBlw, +}; +static const uint16_t +hb_use_u16[448] = +{ + 0, 0, 1, 2, 3, 4, 0, 5, 6, 0, 7, 0, 8, 9, 10, 11, + 9, 12, 13, 9, 9, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 17, 25, 26, 20, 21, 27, 28, 29, 30, 31, 32, 33, 21, 34, 35, 0, + 17, 36, 37, 20, 21, 38, 23, 39, 17, 40, 41, 42, 43, 44, 45, 46, + 30, 0, 47, 48, 21, 49, 50, 51, 17, 0, 52, 48, 21, 53, 50, 54, + 17, 55, 56, 48, 9, 57, 58, 59, 60, 61, 9, 62, 63, 64, 30, 65, + 66, 67, 9, 68, 69, 9, 70, 71, 72, 73, 74, 75, 76, 0, 9, 9, + 77, 78, 79, 80, 81, 82, 83, 84, 9, 85, 9, 86, 9, 87, 88, 89, + 9, 90, 91, 92, 2, 0, 93, 0, 9, 94, 95, 9, 96, 0, 97, 98, + 99,100, 30, 9,101,102,103, 9,104,105, 9,106, 9,107,108,109, + 2, 2,110, 9, 9,111,112, 2,113,114,115, 9,116, 9,117,118, + 119,120,121, 0, 0,122,123,124, 0,125,126,127,128, 0,129,130, + 131, 0, 0,132,133, 0, 0, 9,134,135,136, 9,137, 0, 9,138, + 139, 9, 9,140,141, 2,142,143,144, 9,145,146,147, 9, 9,148, + 149, 2,150, 98,151,152,153, 2, 9,154, 9,155,156, 0,157,158, + 159, 2,160, 0, 0,161, 0,162, 0,163,163,164, 33,165,166,167, + 9,168, 94, 0,169, 0, 9,170,171, 0,172, 2,173,170,174,175, + 176, 0, 0,177,178, 0,179, 9, 9,180,181,182,183,184,185, 9, + 9,186,187, 0,188, 9,189,190,191, 9, 9,192, 9,193,194,105, + 195,102, 9, 33,196,197,198, 0,199,200, 94, 9, 9,201,202, 2, + 203, 20, 21,204,205,206,207,208, 9,209,210,211,212, 0,195, 9, + 9,213,214, 2,215,216,217,218, 9,219,220, 2,221,222, 9,223, + 224,103,225, 0,226,227,228,229, 9,230,231, 2,232, 9, 9,233, + 234, 0,235, 9, 9,236,237,238,239,240, 21, 9,215,241, 7, 9, + 70, 18, 9,242, 73,243,244, 9, 9,245,246, 2,247, 9,248,249, + 9,250,251, 48, 9,252,253, 2, 9,254,255,256, 9,257,258,259, + 260,260,261,262,263, 0, 9,264,105, 70, 94,265, 0,266, 70,267, + 268, 0,269, 0,270, 2,271, 2,272, 2,129,129,160,160,160,129, +}; + +static inline unsigned +hb_use_b4 (const uint8_t* a, unsigned i) +{ + return (a[i>>1]>>((i&1u)<<2))&15u; +} +static inline uint_fast8_t +hb_use_get_category (unsigned u) +{ + return u<921600u?hb_use_u8[3049+(((hb_use_u8[865+(((hb_use_u16[((hb_use_u8[353+(((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>1>>3>>4))<<4)+((u>>1>>3>>1>>3)&15u))])<<3)+((u>>1>>3>>1)&7u))])<<1)+((u>>1>>3)&1u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O; +} + +#endif + #undef B #undef CGJ #undef CS diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-use.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-use.cc index c40ec52f9c..342aba1235 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-use.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use.cc @@ -89,19 +89,19 @@ use_other_features[] = HB_TAG('p','s','t','s'), }; -static void +static bool setup_syllables_use (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); -static void +static bool record_rphf_use (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); -static void +static bool record_pref_use (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); -static void +static bool reorder_use (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); @@ -293,7 +293,7 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan, } } -static void +static bool setup_syllables_use (const hb_ot_shape_plan_t *plan, hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) @@ -304,9 +304,10 @@ setup_syllables_use (const hb_ot_shape_plan_t *plan, buffer->unsafe_to_break (start, end); setup_rphf_mask (plan, buffer); setup_topographical_masks (plan, buffer); + return false; } -static void +static bool record_rphf_use (const hb_ot_shape_plan_t *plan, hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) @@ -314,7 +315,7 @@ record_rphf_use (const hb_ot_shape_plan_t *plan, const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; hb_mask_t mask = use_plan->rphf_mask; - if (!mask) return; + if (!mask) return false; hb_glyph_info_t *info = buffer->info; foreach_syllable (buffer, start, end) @@ -327,9 +328,10 @@ record_rphf_use (const hb_ot_shape_plan_t *plan, break; } } + return false; } -static void +static bool record_pref_use (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) @@ -346,6 +348,7 @@ record_pref_use (const hb_ot_shape_plan_t *plan HB_UNUSED, break; } } + return false; } static inline bool @@ -438,17 +441,19 @@ reorder_syllable_use (hb_buffer_t *buffer, unsigned int start, unsigned int end) } } -static void +static bool reorder_use (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { + bool ret = false; if (buffer->message (font, "start reordering USE")) { - hb_syllabic_insert_dotted_circles (font, buffer, - use_broken_cluster, - USE(B), - USE(R)); + if (hb_syllabic_insert_dotted_circles (font, buffer, + use_broken_cluster, + USE(B), + USE(R))) + ret = true; foreach_syllable (buffer, start, end) reorder_syllable_use (buffer, start, end); @@ -457,6 +462,8 @@ reorder_use (const hb_ot_shape_plan_t *plan, } HB_BUFFER_DEALLOCATE_VAR (buffer, use_category); + + return ret; } diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper.hh b/thirdparty/harfbuzz/src/hb-ot-shaper.hh index b2d1acb39b..0207b2bbe3 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper.hh @@ -262,11 +262,13 @@ hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner) return &_hb_ot_shaper_myanmar; +#ifndef HB_NO_OT_SHAPER_MYANMAR_ZAWGYI #define HB_SCRIPT_MYANMAR_ZAWGYI ((hb_script_t) HB_TAG ('Q','a','a','g')) case HB_SCRIPT_MYANMAR_ZAWGYI: /* https://github.com/harfbuzz/harfbuzz/issues/1162 */ return &_hb_ot_shaper_myanmar_zawgyi; +#endif /* Unicode-2.0 additions */ diff --git a/thirdparty/harfbuzz/src/hb-ot-stat-table.hh b/thirdparty/harfbuzz/src/hb-ot-stat-table.hh index af6d550c0e..59bb2daccd 100644 --- a/thirdparty/harfbuzz/src/hb-ot-stat-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-stat-table.hh @@ -320,7 +320,7 @@ struct AxisValueFormat4 unsigned total_size = min_size + axisCount * AxisValueRecord::static_size; auto *out = c->serializer->allocate_size<AxisValueFormat4> (total_size); if (unlikely (!out)) return_trace (false); - memcpy (out, this, total_size); + hb_memcpy (out, this, total_size); return_trace (true); } diff --git a/thirdparty/harfbuzz/src/hb-ot-tag.cc b/thirdparty/harfbuzz/src/hb-ot-tag.cc index 1b18270cca..f6ba3b0d47 100644 --- a/thirdparty/harfbuzz/src/hb-ot-tag.cc +++ b/thirdparty/harfbuzz/src/hb-ot-tag.cc @@ -577,7 +577,7 @@ hb_ot_tags_to_script_and_language (hb_tag_t script_tag, else { int shift; - memcpy (buf, lang_str, len); + hb_memcpy (buf, lang_str, len); if (lang_str[0] != 'x' || lang_str[1] != '-') { buf[len++] = '-'; buf[len++] = 'x'; diff --git a/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh index f60bc4a3ce..cc5c5c0068 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh @@ -143,7 +143,7 @@ struct avar TRACE_SANITIZE (this); if (!(version.sanitize (c) && (version.major == 1 -#ifndef HB_NO_VARIATIONS2 +#ifndef HB_NO_AVAR2 || version.major == 2 #endif ) && @@ -159,7 +159,7 @@ struct avar map = &StructAfter<SegmentMaps> (*map); } -#ifndef HB_NO_VARIATIONS2 +#ifndef HB_NO_AVAR2 if (version.major < 2) return_trace (true); @@ -182,7 +182,7 @@ struct avar map = &StructAfter<SegmentMaps> (*map); } -#ifndef HB_NO_VARIATIONS2 +#ifndef HB_NO_AVAR2 if (version.major < 2) return; diff --git a/thirdparty/harfbuzz/src/hb-ot-var-common.hh b/thirdparty/harfbuzz/src/hb-ot-var-common.hh index 1d29e3e4f9..4997c2e2e8 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-common.hh @@ -47,7 +47,7 @@ struct DeltaSetIndexMapFormat01 HBUINT8 *p = c->allocate_size<HBUINT8> (total_size); if (unlikely (!p)) return_trace (nullptr); - memcpy (p, this, HBUINT8::static_size * total_size); + hb_memcpy (p, this, HBUINT8::static_size * total_size); return_trace (out); } @@ -219,6 +219,25 @@ struct DeltaSetIndexMap DEFINE_SIZE_UNION (1, format); }; + +struct VarStoreInstancer +{ + VarStoreInstancer (const VariationStore &varStore, + const DeltaSetIndexMap &varIdxMap, + hb_array_t<int> coords) : + varStore (varStore), varIdxMap (varIdxMap), coords (coords) {} + + operator bool () const { return bool (coords); } + + float operator() (uint32_t varIdx, unsigned short offset = 0) const + { return varStore.get_delta (varIdxMap.map (VarIdx::add (varIdx, offset)), coords); } + + const VariationStore &varStore; + const DeltaSetIndexMap &varIdxMap; + hb_array_t<int> coords; +}; + + } /* namespace OT */ diff --git a/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh index af23862870..c1d57a002a 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh @@ -59,7 +59,7 @@ struct InstanceRecord const hb_hashmap_t<hb_tag_t, float> *axes_location = c->plan->user_axes_location; for (unsigned i = 0 ; i < axis_count; i++) { - unsigned *axis_tag; + uint32_t *axis_tag; // only keep instances whose coordinates == pinned axis location if (!c->plan->axes_old_index_tag_map->has (i, &axis_tag)) continue; @@ -337,13 +337,13 @@ struct fvar { const InstanceRecord *instance = get_instance (i); - if (hb_any (+ hb_zip (instance->get_coordinates (axisCount), hb_range ((unsigned)axisCount)) - | hb_filter (pinned_axes, hb_second) - | hb_map ([&] (const hb_pair_t<const F16DOT16&, unsigned>& _) + if (hb_any (+ hb_enumerate (instance->get_coordinates (axisCount)) + | hb_filter (pinned_axes, hb_first) + | hb_map ([&] (const hb_pair_t<unsigned, const F16DOT16&>& _) { - hb_tag_t axis_tag = pinned_axes.get (_.second); + hb_tag_t axis_tag = pinned_axes.get (_.first); float location = user_axes_location->get (axis_tag); - if (fabs ((double)location - (double)_.first.to_float ()) > 0.001) return true; + if (fabs ((double)location - (double)_.second.to_float ()) > 0.001) return true; return false; }) )) diff --git a/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh index bf1039d1d6..e02063ca43 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh @@ -56,12 +56,11 @@ struct contour_point_vector_t : hb_vector_t<contour_point_t> void extend (const hb_array_t<contour_point_t> &a) { unsigned int old_len = length; - if (unlikely (!resize (old_len + a.length))) + if (unlikely (!resize (old_len + a.length, false))) return; auto arrayZ = this->arrayZ + old_len; unsigned count = a.length; - for (unsigned int i = 0; i < count; i++) - arrayZ[i] = a.arrayZ[i]; + hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0])); } void transform (const float (&matrix)[4]) @@ -231,8 +230,8 @@ struct GlyphVariationData { return (index < var_data->tupleVarCount.get_count ()) && var_data_bytes.check_range (current_tuple, TupleVariationHeader::min_size) && - var_data_bytes.check_range (current_tuple, hb_max (current_tuple->get_data_size (), current_tuple->get_size (axis_count))) && - current_tuple->get_size (axis_count); + var_data_bytes.check_range (current_tuple, hb_max (current_tuple->get_data_size (), + current_tuple->get_size (axis_count))); } bool move_to_next () @@ -281,42 +280,42 @@ struct GlyphVariationData if (unlikely (p + 1 > end)) return false; - uint16_t count = *p++; + unsigned count = *p++; if (count & POINTS_ARE_WORDS) { if (unlikely (p + 1 > end)) return false; count = ((count & POINT_RUN_COUNT_MASK) << 8) | *p++; } - if (unlikely (!points.resize (count))) return false; + if (unlikely (!points.resize (count, false))) return false; - unsigned int n = 0; - uint16_t i = 0; + unsigned n = 0; + unsigned i = 0; while (i < count) { if (unlikely (p + 1 > end)) return false; - uint16_t j; - uint8_t control = *p++; - uint16_t run_count = (control & POINT_RUN_COUNT_MASK) + 1; + unsigned control = *p++; + unsigned run_count = (control & POINT_RUN_COUNT_MASK) + 1; + if (unlikely (i + run_count > count)) return false; + unsigned j; if (control & POINTS_ARE_WORDS) { - for (j = 0; j < run_count && i < count; j++, i++) + if (unlikely (p + run_count * HBUINT16::static_size > end)) return false; + for (j = 0; j < run_count; j++, i++) { - if (unlikely (p + HBUINT16::static_size > end)) return false; n += *(const HBUINT16 *)p; - points[i] = n; + points.arrayZ[i] = n; p += HBUINT16::static_size; } } else { - for (j = 0; j < run_count && i < count; j++, i++) + if (unlikely (p + run_count > end)) return false; + for (j = 0; j < run_count; j++, i++) { - if (unlikely (p + 1 > end)) return false; n += *p++; - points[i] = n; + points.arrayZ[i] = n; } } - if (j < run_count) return false; } return true; } @@ -332,32 +331,37 @@ struct GlyphVariationData DELTA_RUN_COUNT_MASK = 0x3F }; - unsigned int i = 0; - unsigned int count = deltas.length; + unsigned i = 0; + unsigned count = deltas.length; while (i < count) { if (unlikely (p + 1 > end)) return false; - uint8_t control = *p++; - unsigned int run_count = (control & DELTA_RUN_COUNT_MASK) + 1; - unsigned int j; + unsigned control = *p++; + unsigned run_count = (control & DELTA_RUN_COUNT_MASK) + 1; + if (unlikely (i + run_count > count)) return false; + unsigned j; if (control & DELTAS_ARE_ZERO) - for (j = 0; j < run_count && i < count; j++, i++) - deltas[i] = 0; + { + for (j = 0; j < run_count; j++, i++) + deltas.arrayZ[i] = 0; + } else if (control & DELTAS_ARE_WORDS) - for (j = 0; j < run_count && i < count; j++, i++) + { + if (unlikely (p + run_count * HBUINT16::static_size > end)) return false; + for (j = 0; j < run_count; j++, i++) { - if (unlikely (p + HBUINT16::static_size > end)) return false; - deltas[i] = *(const HBINT16 *) p; + deltas.arrayZ[i] = * (const HBINT16 *) p; p += HBUINT16::static_size; } + } else - for (j = 0; j < run_count && i < count; j++, i++) + { + if (unlikely (p + run_count > end)) return false; + for (j = 0; j < run_count; j++, i++) { - if (unlikely (p + 1 > end)) return false; - deltas[i] = *(const HBINT8 *) p++; + deltas.arrayZ[i] = * (const HBINT8 *) p++; } - if (j < run_count) - return false; + } } return true; } @@ -450,7 +454,7 @@ struct gvar F2DOT14 *tuples = c->serializer->allocate_size<F2DOT14> (shared_tuple_size); if (!tuples) return_trace (false); out->sharedTuples = (char *) tuples - (char *) out; - memcpy (tuples, this+sharedTuples, shared_tuple_size); + hb_memcpy (tuples, this+sharedTuples, shared_tuple_size); } char *subset_data = c->serializer->allocate_size<char> (subset_data_size); @@ -473,7 +477,7 @@ struct gvar ((HBUINT16 *) subset_offsets)[gid] = glyph_offset / 2; if (var_data_bytes.length > 0) - memcpy (subset_data, var_data_bytes.arrayZ, var_data_bytes.length); + hb_memcpy (subset_data, var_data_bytes.arrayZ, var_data_bytes.length); subset_data += var_data_bytes.length; glyph_offset += var_data_bytes.length; } @@ -501,6 +505,7 @@ struct gvar unsigned get_offset (unsigned i) const { if (unlikely (i > glyphCount)) return 0; + _hb_compiler_memory_r_barrier (); return is_long_offset () ? get_long_offset_array ()[i] : get_short_offset_array ()[i] * 2; } @@ -521,11 +526,11 @@ struct gvar unsigned int target, unsigned int prev, unsigned int next, float contour_point_t::*m) { - float target_val = points[target].*m; - float prev_val = points[prev].*m; - float next_val = points[next].*m; - float prev_delta = deltas[prev].*m; - float next_delta = deltas[next].*m; + float target_val = points.arrayZ[target].*m; + float prev_val = points.arrayZ[prev].*m; + float next_val = points.arrayZ[next].*m; + float prev_delta = deltas.arrayZ[prev].*m; + float next_delta = deltas.arrayZ[next].*m; if (prev_val == next_val) return (prev_delta == next_delta) ? prev_delta : 0.f; @@ -543,10 +548,11 @@ struct gvar { return (i >= end) ? start : (i + 1); } public: - bool apply_deltas_to_points (hb_codepoint_t glyph, hb_font_t *font, + bool apply_deltas_to_points (hb_codepoint_t glyph, + hb_array_t<int> coords, const hb_array_t<contour_point_t> points) const { - if (!font->num_coords) return true; + if (!coords) return true; if (unlikely (glyph >= table->glyphCount)) return true; @@ -559,20 +565,20 @@ struct gvar return true; /* so isn't applied at all */ /* Save original points for inferred delta calculation */ - contour_point_vector_t orig_points; - if (unlikely (!orig_points.resize (points.length))) return false; - for (unsigned int i = 0; i < orig_points.length; i++) - orig_points.arrayZ[i] = points.arrayZ[i]; + contour_point_vector_t orig_points_vec; + orig_points_vec.extend (points); + if (unlikely (orig_points_vec.in_error ())) return false; + auto orig_points = orig_points_vec.as_array (); - contour_point_vector_t deltas; /* flag is used to indicate referenced point */ - if (unlikely (!deltas.resize (points.length))) return false; + contour_point_vector_t deltas_vec; /* flag is used to indicate referenced point */ + if (unlikely (!deltas_vec.resize (points.length, false))) return false; + auto deltas = deltas_vec.as_array (); hb_vector_t<unsigned> end_points; for (unsigned i = 0; i < points.length; ++i) - if (points[i].is_end_point) + if (points.arrayZ[i].is_end_point) end_points.push (i); - auto coords = hb_array (font->coords, font->num_coords); unsigned num_coords = table->axisCount; hb_array_t<const F2DOT14> shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount); @@ -598,70 +604,89 @@ struct gvar bool apply_to_all = (indices.length == 0); unsigned int num_deltas = apply_to_all ? points.length : indices.length; - if (unlikely (!x_deltas.resize (num_deltas))) return false; + if (unlikely (!x_deltas.resize (num_deltas, false))) return false; if (unlikely (!GlyphVariationData::unpack_deltas (p, x_deltas, end))) return false; - if (unlikely (!y_deltas.resize (num_deltas))) return false; + if (unlikely (!y_deltas.resize (num_deltas, false))) return false; if (unlikely (!GlyphVariationData::unpack_deltas (p, y_deltas, end))) return false; - for (unsigned int i = 0; i < deltas.length; i++) - deltas[i].init (); - for (unsigned int i = 0; i < num_deltas; i++) - { - unsigned int pt_index = apply_to_all ? i : indices[i]; - if (unlikely (pt_index >= deltas.length)) continue; - deltas.arrayZ[pt_index].flag = 1; /* this point is referenced, i.e., explicit deltas specified */ - deltas.arrayZ[pt_index].x += x_deltas.arrayZ[i] * scalar; - deltas.arrayZ[pt_index].y += y_deltas.arrayZ[i] * scalar; - } + hb_memset (deltas.arrayZ, 0, deltas.get_size ()); + + unsigned ref_points = 0; + if (scalar != 1.0f) + for (unsigned int i = 0; i < num_deltas; i++) + { + unsigned int pt_index = apply_to_all ? i : indices[i]; + if (unlikely (pt_index >= deltas.length)) continue; + auto &delta = deltas.arrayZ[pt_index]; + ref_points += !delta.flag; + delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */ + delta.x += x_deltas.arrayZ[i] * scalar; + delta.y += y_deltas.arrayZ[i] * scalar; + } + else + for (unsigned int i = 0; i < num_deltas; i++) + { + unsigned int pt_index = apply_to_all ? i : indices[i]; + if (unlikely (pt_index >= deltas.length)) continue; + auto &delta = deltas.arrayZ[pt_index]; + ref_points += !delta.flag; + delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */ + delta.x += x_deltas.arrayZ[i]; + delta.y += y_deltas.arrayZ[i]; + } /* infer deltas for unreferenced points */ - unsigned start_point = 0; - for (unsigned c = 0; c < end_points.length; c++) + if (ref_points && ref_points < orig_points.length) { - unsigned end_point = end_points[c]; + unsigned start_point = 0; + for (unsigned c = 0; c < end_points.length; c++) + { + unsigned end_point = end_points.arrayZ[c]; - /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */ - unsigned unref_count = 0; - for (unsigned i = start_point; i <= end_point; i++) - if (!deltas[i].flag) unref_count++; + /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */ + unsigned unref_count = 0; + for (unsigned i = start_point; i < end_point + 1; i++) + unref_count += deltas.arrayZ[i].flag; + unref_count = (end_point - start_point + 1) - unref_count; - unsigned j = start_point; - if (unref_count == 0 || unref_count > end_point - start_point) - goto no_more_gaps; + unsigned j = start_point; + if (unref_count == 0 || unref_count > end_point - start_point) + goto no_more_gaps; - for (;;) - { - /* Locate the next gap of unreferenced points between two referenced points prev and next. - * Note that a gap may wrap around at left (start_point) and/or at right (end_point). - */ - unsigned int prev, next, i; - for (;;) - { - i = j; - j = next_index (i, start_point, end_point); - if (deltas[i].flag && !deltas[j].flag) break; - } - prev = j = i; - for (;;) - { - i = j; - j = next_index (i, start_point, end_point); - if (!deltas[i].flag && deltas[j].flag) break; - } - next = j; - /* Infer deltas for all unref points in the gap between prev and next */ - i = prev; for (;;) { - i = next_index (i, start_point, end_point); - if (i == next) break; - deltas[i].x = infer_delta (orig_points.as_array (), deltas.as_array (), i, prev, next, &contour_point_t::x); - deltas[i].y = infer_delta (orig_points.as_array (), deltas.as_array (), i, prev, next, &contour_point_t::y); - if (--unref_count == 0) goto no_more_gaps; + /* Locate the next gap of unreferenced points between two referenced points prev and next. + * Note that a gap may wrap around at left (start_point) and/or at right (end_point). + */ + unsigned int prev, next, i; + for (;;) + { + i = j; + j = next_index (i, start_point, end_point); + if (deltas.arrayZ[i].flag && !deltas.arrayZ[j].flag) break; + } + prev = j = i; + for (;;) + { + i = j; + j = next_index (i, start_point, end_point); + if (!deltas.arrayZ[i].flag && deltas.arrayZ[j].flag) break; + } + next = j; + /* Infer deltas for all unref points in the gap between prev and next */ + i = prev; + for (;;) + { + i = next_index (i, start_point, end_point); + if (i == next) break; + deltas.arrayZ[i].x = infer_delta (orig_points, deltas, i, prev, next, &contour_point_t::x); + deltas.arrayZ[i].y = infer_delta (orig_points, deltas, i, prev, next, &contour_point_t::y); + if (--unref_count == 0) goto no_more_gaps; + } } + no_more_gaps: + start_point = end_point + 1; } - no_more_gaps: - start_point = end_point + 1; } /* apply specified / inferred deltas to points */ diff --git a/thirdparty/harfbuzz/src/hb-pool.hh b/thirdparty/harfbuzz/src/hb-pool.hh index dcf8f6627d..e4bb64f627 100644 --- a/thirdparty/harfbuzz/src/hb-pool.hh +++ b/thirdparty/harfbuzz/src/hb-pool.hh @@ -35,15 +35,13 @@ template <typename T, unsigned ChunkLen = 16> struct hb_pool_t { hb_pool_t () : next (nullptr) {} - ~hb_pool_t () { fini (); } - - void fini () + ~hb_pool_t () { next = nullptr; - for (chunk_t *_ : chunks) hb_free (_); - - chunks.fini (); + + hb_iter (chunks) + | hb_apply (hb_free) + ; } T* alloc () @@ -60,7 +58,7 @@ struct hb_pool_t T* obj = next; next = * ((T**) next); - memset (obj, 0, sizeof (T)); + hb_memset (obj, 0, sizeof (T)); return obj; } diff --git a/thirdparty/harfbuzz/src/hb-priority-queue.hh b/thirdparty/harfbuzz/src/hb-priority-queue.hh index ffb86e30ae..ac76b7d955 100644 --- a/thirdparty/harfbuzz/src/hb-priority-queue.hh +++ b/thirdparty/harfbuzz/src/hb-priority-queue.hh @@ -63,7 +63,9 @@ struct hb_priority_queue_t heap.arrayZ[0] = heap.arrayZ[heap.length - 1]; heap.shrink (heap.length - 1); - bubble_down (0); + + if (!is_empty ()) + bubble_down (0); return result; } @@ -100,7 +102,7 @@ struct hb_priority_queue_t void bubble_down (unsigned index) { - assert (index <= heap.length); + assert (index < heap.length); unsigned left = left_child (index); unsigned right = right_child (index); @@ -112,7 +114,7 @@ struct hb_priority_queue_t bool has_right = right < heap.length; if (heap.arrayZ[index].first <= heap.arrayZ[left].first - && (!has_right || heap[index].first <= heap.arrayZ[right].first)) + && (!has_right || heap.arrayZ[index].first <= heap.arrayZ[right].first)) return; if (!has_right || heap.arrayZ[left].first < heap.arrayZ[right].first) @@ -128,7 +130,7 @@ struct hb_priority_queue_t void bubble_up (unsigned index) { - assert (index <= heap.length); + assert (index < heap.length); if (index == 0) return; @@ -142,8 +144,8 @@ struct hb_priority_queue_t void swap (unsigned a, unsigned b) { - assert (a <= heap.length); - assert (b <= heap.length); + assert (a < heap.length); + assert (b < heap.length); hb_swap (heap.arrayZ[a], heap.arrayZ[b]); } }; diff --git a/thirdparty/harfbuzz/src/hb-repacker.hh b/thirdparty/harfbuzz/src/hb-repacker.hh index c97ce6cc2c..7a3143cec3 100644 --- a/thirdparty/harfbuzz/src/hb-repacker.hh +++ b/thirdparty/harfbuzz/src/hb-repacker.hh @@ -209,7 +209,7 @@ bool _try_isolating_subgraphs (const hb_vector_t<graph::overflow_record_t>& over // Only move at most half of the roots in a space at a time. unsigned extra = roots_to_isolate.get_population () - maximum_to_move; while (extra--) { - unsigned root = HB_SET_VALUE_INVALID; + uint32_t root = HB_SET_VALUE_INVALID; roots_to_isolate.previous (&root); roots_to_isolate.del (root); } @@ -283,6 +283,11 @@ hb_resolve_graph_overflows (hb_tag_t table_tag, graph_t& sorted_graph /* IN/OUT */) { sorted_graph.sort_shortest_distance (); + if (sorted_graph.in_error ()) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Sorted graph in error state after initial sort."); + return false; + } bool will_overflow = graph::will_overflow (sorted_graph); if (!will_overflow) @@ -376,6 +381,26 @@ hb_resolve_overflows (const T& packed, unsigned max_rounds = 20, bool recalculate_extensions = false) { graph_t sorted_graph (packed); + if (sorted_graph.in_error ()) + { + // Invalid graph definition. + return nullptr; + } + + if (!sorted_graph.is_fully_connected ()) + { + sorted_graph.print_orphaned_nodes (); + return nullptr; + } + + if (sorted_graph.in_error ()) + { + // Allocations failed somewhere + DEBUG_MSG (SUBSET_REPACK, nullptr, + "Graph is in error, likely due to a memory allocation error."); + return nullptr; + } + if (!hb_resolve_graph_overflows (table_tag, max_rounds, recalculate_extensions, sorted_graph)) return nullptr; diff --git a/thirdparty/harfbuzz/src/hb-sanitize.hh b/thirdparty/harfbuzz/src/hb-sanitize.hh index 65c2772201..bd3250e580 100644 --- a/thirdparty/harfbuzz/src/hb-sanitize.hh +++ b/thirdparty/harfbuzz/src/hb-sanitize.hh @@ -198,10 +198,11 @@ struct hb_sanitize_context_t : void start_processing () { reset_object (); - if (unlikely (hb_unsigned_mul_overflows (this->end - this->start, HB_SANITIZE_MAX_OPS_FACTOR))) + unsigned m; + if (unlikely (hb_unsigned_mul_overflows (this->end - this->start, HB_SANITIZE_MAX_OPS_FACTOR, &m))) this->max_ops = HB_SANITIZE_MAX_OPS_MAX; else - this->max_ops = hb_clamp ((unsigned) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR, + this->max_ops = hb_clamp (m, (unsigned) HB_SANITIZE_MAX_OPS_MIN, (unsigned) HB_SANITIZE_MAX_OPS_MAX); this->edit_count = 0; @@ -252,8 +253,9 @@ struct hb_sanitize_context_t : unsigned int a, unsigned int b) const { - return !hb_unsigned_mul_overflows (a, b) && - this->check_range (base, a * b); + unsigned m; + return !hb_unsigned_mul_overflows (a, b, &m) && + this->check_range (base, m); } template <typename T> @@ -262,8 +264,9 @@ struct hb_sanitize_context_t : unsigned int b, unsigned int c) const { - return !hb_unsigned_mul_overflows (a, b) && - this->check_range (base, a * b, c); + unsigned m; + return !hb_unsigned_mul_overflows (a, b, &m) && + this->check_range (base, m, c); } template <typename T> diff --git a/thirdparty/harfbuzz/src/hb-serialize.hh b/thirdparty/harfbuzz/src/hb-serialize.hh index f47cde5eb5..d5573281f1 100644 --- a/thirdparty/harfbuzz/src/hb-serialize.hh +++ b/thirdparty/harfbuzz/src/hb-serialize.hh @@ -194,7 +194,6 @@ struct hb_serialize_context_t current = current->next; _->fini (); } - object_pool.fini (); } bool in_error () const { return bool (errors); } @@ -224,6 +223,7 @@ struct hb_serialize_context_t this->errors = HB_SERIALIZE_ERROR_NONE; this->head = this->start; this->tail = this->end; + this->zerocopy = nullptr; this->debug_depth = 0; fini (); @@ -326,7 +326,8 @@ struct hb_serialize_context_t if (unlikely (in_error() && !only_overflow ())) return; current = current->next; - revert (obj->head, obj->tail); + revert (zerocopy ? zerocopy : obj->head, obj->tail); + zerocopy = nullptr; obj->fini (); object_pool.release (obj); } @@ -344,8 +345,11 @@ struct hb_serialize_context_t current = current->next; obj->tail = head; obj->next = nullptr; + assert (obj->head <= obj->tail); unsigned len = obj->tail - obj->head; - head = obj->head; /* Rewind head. */ + head = zerocopy ? zerocopy : obj->head; /* Rewind head. */ + bool was_zerocopy = zerocopy; + zerocopy = nullptr; if (!len) { @@ -355,9 +359,11 @@ struct hb_serialize_context_t } objidx_t objidx; + uint32_t hash = 0; if (share) { - objidx = packed_map.get (obj); + hash = hb_hash (obj); + objidx = packed_map.get_with_hash (obj, hash); if (objidx) { merge_virtual_links (obj, objidx); @@ -367,7 +373,10 @@ struct hb_serialize_context_t } tail -= len; - memmove (tail, obj->head, len); + if (was_zerocopy) + assert (tail == obj->head); + else + memmove (tail, obj->head, len); obj->head = tail; obj->tail = tail + len; @@ -385,7 +394,7 @@ struct hb_serialize_context_t objidx = packed.length - 1; - if (share) packed_map.set (obj, objidx); + if (share) packed_map.set_with_hash (obj, hash, objidx); propagate_error (packed_map); return objidx; @@ -569,8 +578,26 @@ struct hb_serialize_context_t return !bool ((errors = (errors | err_type))); } + bool start_zerocopy (size_t size) + { + if (unlikely (in_error ())) return false; + + if (unlikely (size > INT_MAX || this->tail - this->head < ptrdiff_t (size))) + { + err (HB_SERIALIZE_ERROR_OUT_OF_ROOM); + return false; + } + + assert (!this->zerocopy); + this->zerocopy = this->head; + + assert (this->current->head == this->head); + this->current->head = this->current->tail = this->head = this->tail - size; + return true; + } + template <typename Type> - Type *allocate_size (size_t size) + Type *allocate_size (size_t size, bool clear = true) { if (unlikely (in_error ())) return nullptr; @@ -579,7 +606,8 @@ struct hb_serialize_context_t err (HB_SERIALIZE_ERROR_OUT_OF_ROOM); return nullptr; } - hb_memset (this->head, 0, size); + if (clear) + hb_memset (this->head, 0, size); char *ret = this->head; this->head += size; return reinterpret_cast<Type *> (ret); @@ -593,9 +621,9 @@ struct hb_serialize_context_t Type *embed (const Type *obj) { unsigned int size = obj->get_size (); - Type *ret = this->allocate_size<Type> (size); + Type *ret = this->allocate_size<Type> (size, false); if (unlikely (!ret)) return nullptr; - memcpy (ret, obj, size); + hb_memcpy (ret, obj, size); return ret; } template <typename Type> @@ -616,7 +644,7 @@ struct hb_serialize_context_t } /* Like embed, but active: calls obj.operator=() or obj.copy() to transfer data - * instead of memcpy(). */ + * instead of hb_memcpy(). */ template <typename Type, typename ...Ts> Type *copy (const Type &src, Ts&&... ds) { return _copy (src, hb_prioritize, std::forward<Ts> (ds)...); } @@ -634,7 +662,7 @@ struct hb_serialize_context_t hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; } template <typename Type> - Type *extend_size (Type *obj, size_t size) + Type *extend_size (Type *obj, size_t size, bool clear = true) { if (unlikely (in_error ())) return nullptr; @@ -642,12 +670,12 @@ struct hb_serialize_context_t assert ((char *) obj <= this->head); assert ((size_t) (this->head - (char *) obj) <= size); if (unlikely (((char *) obj + size < (char *) obj) || - !this->allocate_size<Type> (((char *) obj) + size - this->head))) return nullptr; + !this->allocate_size<Type> (((char *) obj) + size - this->head, clear))) return nullptr; return reinterpret_cast<Type *> (obj); } template <typename Type> - Type *extend_size (Type &obj, size_t size) - { return extend_size (std::addressof (obj), size); } + Type *extend_size (Type &obj, size_t size, bool clear = true) + { return extend_size (std::addressof (obj), size, clear); } template <typename Type> Type *extend_min (Type *obj) { return extend_size (obj, obj->min_size); } @@ -676,8 +704,8 @@ struct hb_serialize_context_t char *p = (char *) hb_malloc (len); if (unlikely (!p)) return hb_bytes_t (); - memcpy (p, this->start, this->head - this->start); - memcpy (p + (this->head - this->start), this->tail, this->end - this->tail); + hb_memcpy (p, this->start, this->head - this->start); + hb_memcpy (p + (this->head - this->start), this->tail, this->end - this->tail); return hb_bytes_t (p, len); } template <typename Type> @@ -704,7 +732,7 @@ struct hb_serialize_context_t } public: - char *start, *head, *tail, *end; + char *start, *head, *tail, *end, *zerocopy; unsigned int debug_depth; hb_serialize_error_t errors; diff --git a/thirdparty/harfbuzz/src/hb-set-digest.hh b/thirdparty/harfbuzz/src/hb-set-digest.hh index fab36216e4..e8409111f2 100644 --- a/thirdparty/harfbuzz/src/hb-set-digest.hh +++ b/thirdparty/harfbuzz/src/hb-set-digest.hh @@ -28,6 +28,7 @@ #define HB_SET_DIGEST_HH #include "hb.hh" +#include "hb-machinery.hh" /* * The set-digests here implement various "filters" that support @@ -75,6 +76,8 @@ struct hb_set_digest_bits_pattern_t void init () { mask = 0; } + void add (const hb_set_digest_bits_pattern_t &o) { mask |= o.mask; } + void add (hb_codepoint_t g) { mask |= mask_for (g); } bool add_range (hb_codepoint_t a, hb_codepoint_t b) @@ -95,7 +98,7 @@ struct hb_set_digest_bits_pattern_t for (unsigned int i = 0; i < count; i++) { add (*array); - array = (const T *) (stride + (const char *) array); + array = &StructAtOffsetUnaligned<T> ((const void *) array, stride); } } template <typename T> @@ -103,16 +106,15 @@ struct hb_set_digest_bits_pattern_t template <typename T> bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) { - for (unsigned int i = 0; i < count; i++) - { - add (*array); - array = (const T *) (stride + (const char *) array); - } + add_array (array, count, stride); return true; } template <typename T> bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); } + bool may_have (const hb_set_digest_bits_pattern_t &o) const + { return mask & o.mask; } + bool may_have (hb_codepoint_t g) const { return mask & mask_for (g); } @@ -132,6 +134,12 @@ struct hb_set_digest_combiner_t tail.init (); } + void add (const hb_set_digest_combiner_t &o) + { + head.add (o.head); + tail.add (o.tail); + } + void add (hb_codepoint_t g) { head.add (g); @@ -140,9 +148,8 @@ struct hb_set_digest_combiner_t bool add_range (hb_codepoint_t a, hb_codepoint_t b) { - head.add_range (a, b); - tail.add_range (a, b); - return true; + return head.add_range (a, b) && + tail.add_range (a, b); } template <typename T> void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) @@ -155,13 +162,17 @@ struct hb_set_digest_combiner_t template <typename T> bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) { - head.add_sorted_array (array, count, stride); - tail.add_sorted_array (array, count, stride); - return true; + return head.add_sorted_array (array, count, stride) && + tail.add_sorted_array (array, count, stride); } template <typename T> bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); } + bool may_have (const hb_set_digest_combiner_t &o) const + { + return head.may_have (o.head) && tail.may_have (o.tail); + } + bool may_have (hb_codepoint_t g) const { return head.may_have (g) && tail.may_have (g); diff --git a/thirdparty/harfbuzz/src/hb-set.hh b/thirdparty/harfbuzz/src/hb-set.hh index 5d5576cb9e..f958a081fb 100644 --- a/thirdparty/harfbuzz/src/hb-set.hh +++ b/thirdparty/harfbuzz/src/hb-set.hh @@ -105,10 +105,8 @@ struct hb_sparseset_t bool get (hb_codepoint_t g) const { return s.get (g); } /* Has interface. */ - static constexpr bool SENTINEL = false; - typedef bool value_t; - value_t operator [] (hb_codepoint_t k) const { return get (k); } - bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; } + bool operator [] (hb_codepoint_t k) const { return get (k); } + bool has (hb_codepoint_t k) const { return (*this)[k]; } /* Predicate. */ bool operator () (hb_codepoint_t k) const { return has (k); } diff --git a/thirdparty/harfbuzz/src/hb-shape-plan.cc b/thirdparty/harfbuzz/src/hb-shape-plan.cc index 9e513c0458..cabcbd4e72 100644 --- a/thirdparty/harfbuzz/src/hb-shape-plan.cc +++ b/thirdparty/harfbuzz/src/hb-shape-plan.cc @@ -31,6 +31,8 @@ #include "hb-buffer.hh" +#ifndef HB_NO_SHAPER + /** * SECTION:hb-shape-plan * @title: hb-shape-plan @@ -74,7 +76,7 @@ hb_shape_plan_key_t::init (bool copy, this->user_features = copy ? features : user_features; if (copy && num_user_features) { - memcpy (features, user_features, num_user_features * sizeof (hb_feature_t)); + hb_memcpy (features, user_features, num_user_features * sizeof (hb_feature_t)); /* Make start/end uniform to easier catch bugs. */ for (unsigned int i = 0; i < num_user_features; i++) { @@ -574,3 +576,6 @@ retry: return hb_shape_plan_reference (shape_plan); } + + +#endif diff --git a/thirdparty/harfbuzz/src/hb-shape.cc b/thirdparty/harfbuzz/src/hb-shape.cc index 547d0afc47..7b5bf2c5ef 100644 --- a/thirdparty/harfbuzz/src/hb-shape.cc +++ b/thirdparty/harfbuzz/src/hb-shape.cc @@ -35,6 +35,8 @@ #include "hb-machinery.hh" +#ifndef HB_NO_SHAPER + /** * SECTION:hb-shape * @title: hb-shape @@ -192,3 +194,6 @@ hb_shape (hb_font_t *font, { hb_shape_full (font, buffer, features, num_features, nullptr); } + + +#endif diff --git a/thirdparty/harfbuzz/src/hb-shaper.cc b/thirdparty/harfbuzz/src/hb-shaper.cc index a900ac6991..c4885cda94 100644 --- a/thirdparty/harfbuzz/src/hb-shaper.cc +++ b/thirdparty/harfbuzz/src/hb-shaper.cc @@ -53,7 +53,7 @@ static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<hb_shaper_entry_t, if (unlikely (!shapers)) return nullptr; - memcpy (shapers, _hb_all_shapers, sizeof (_hb_all_shapers)); + hb_memcpy (shapers, _hb_all_shapers, sizeof (_hb_all_shapers)); /* Reorder shaper list to prefer requested shapers. */ unsigned int i = 0; diff --git a/thirdparty/harfbuzz/src/hb-static.cc b/thirdparty/harfbuzz/src/hb-static.cc index 5d4c7cda1b..eac50754c2 100644 --- a/thirdparty/harfbuzz/src/hb-static.cc +++ b/thirdparty/harfbuzz/src/hb-static.cc @@ -33,6 +33,7 @@ #include "hb-aat-layout-feat-table.hh" #include "hb-ot-layout-common.hh" #include "hb-ot-cmap-table.hh" +#include "hb-ot-color-colr-table.hh" #include "hb-ot-glyf-table.hh" #include "hb-ot-head-table.hh" #include "hb-ot-maxp-table.hh" @@ -47,6 +48,7 @@ DEFINE_NULL_NAMESPACE_BYTES (OT, Index) = {0xFF,0xFF}; DEFINE_NULL_NAMESPACE_BYTES (OT, VarIdx) = {0xFF,0xFF,0xFF,0xFF}; DEFINE_NULL_NAMESPACE_BYTES (OT, LangSys) = {0x00,0x00, 0xFF,0xFF, 0x00,0x00}; DEFINE_NULL_NAMESPACE_BYTES (OT, RangeRecord) = {0x01}; +DEFINE_NULL_NAMESPACE_BYTES (OT, ClipRecord) = {0x01}; DEFINE_NULL_NAMESPACE_BYTES (OT, CmapSubtableLongGroup) = {0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00}; DEFINE_NULL_NAMESPACE_BYTES (AAT, SettingName) = {0xFF,0xFF, 0xFF,0xFF}; DEFINE_NULL_NAMESPACE_BYTES (AAT, Lookup) = {0xFF,0xFF}; diff --git a/thirdparty/harfbuzz/src/hb-subset-accelerator.hh b/thirdparty/harfbuzz/src/hb-subset-accelerator.hh index 34bd0534fb..63ae6d77e2 100644 --- a/thirdparty/harfbuzz/src/hb-subset-accelerator.hh +++ b/thirdparty/harfbuzz/src/hb-subset-accelerator.hh @@ -31,21 +31,34 @@ #include "hb.hh" #include "hb-map.hh" +#include "hb-multimap.hh" #include "hb-set.hh" +extern HB_INTERNAL hb_user_data_key_t _hb_subset_accelerator_user_data_key; + +namespace CFF { +struct cff_subset_accelerator_t; +} + +namespace OT { +struct SubtableUnicodesCache; +}; + struct hb_subset_accelerator_t { static hb_user_data_key_t* user_data_key() { - static hb_user_data_key_t key; - return &key; + return &_hb_subset_accelerator_user_data_key; } static hb_subset_accelerator_t* create(const hb_map_t& unicode_to_gid_, - const hb_set_t& unicodes_) { + const hb_multimap_t gid_to_unicodes_, + const hb_set_t& unicodes_, + bool has_seac_) { hb_subset_accelerator_t* accel = (hb_subset_accelerator_t*) hb_malloc (sizeof(hb_subset_accelerator_t)); - new (accel) hb_subset_accelerator_t (unicode_to_gid_, unicodes_); + new (accel) hb_subset_accelerator_t (unicode_to_gid_, gid_to_unicodes_, unicodes_); + accel->has_seac = has_seac_; return accel; } @@ -53,22 +66,54 @@ struct hb_subset_accelerator_t if (!value) return; hb_subset_accelerator_t* accel = (hb_subset_accelerator_t*) value; + + if (accel->cff_accelerator && accel->destroy_cff_accelerator) + accel->destroy_cff_accelerator ((void*) accel->cff_accelerator); + + if (accel->cmap_cache && accel->destroy_cmap_cache) + accel->destroy_cmap_cache ((void*) accel->cmap_cache); + accel->~hb_subset_accelerator_t (); hb_free (accel); } - hb_subset_accelerator_t(const hb_map_t& unicode_to_gid_, + hb_subset_accelerator_t (const hb_map_t& unicode_to_gid_, + const hb_multimap_t& gid_to_unicodes_, const hb_set_t& unicodes_) - : unicode_to_gid(unicode_to_gid_), unicodes(unicodes_) {} + : unicode_to_gid(unicode_to_gid_), gid_to_unicodes (gid_to_unicodes_), unicodes(unicodes_), + cmap_cache(nullptr), destroy_cmap_cache(nullptr), + has_seac(false), cff_accelerator(nullptr), destroy_cff_accelerator(nullptr) + { sanitized_table_cache_lock.init (); } + + ~hb_subset_accelerator_t () + { sanitized_table_cache_lock.fini (); } + + // Generic + + mutable hb_mutex_t sanitized_table_cache_lock; + mutable hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_blob_t>> sanitized_table_cache; const hb_map_t unicode_to_gid; + const hb_multimap_t gid_to_unicodes; const hb_set_t unicodes; + + // cmap + const OT::SubtableUnicodesCache* cmap_cache; + hb_destroy_func_t destroy_cmap_cache; + + // CFF + bool has_seac; + const CFF::cff_subset_accelerator_t* cff_accelerator; + hb_destroy_func_t destroy_cff_accelerator; + // TODO(garretrieger): cumulative glyf checksum map - // TODO(garretrieger): sanitized table cache. bool in_error () const { - return unicode_to_gid.in_error() || unicodes.in_error (); + return unicode_to_gid.in_error () || + gid_to_unicodes.in_error () || + unicodes.in_error () || + sanitized_table_cache.in_error (); } }; diff --git a/thirdparty/harfbuzz/src/hb-subset-cff-common.cc b/thirdparty/harfbuzz/src/hb-subset-cff-common.cc index 711b2236d6..6e1b6f713d 100644 --- a/thirdparty/harfbuzz/src/hb-subset-cff-common.cc +++ b/thirdparty/harfbuzz/src/hb-subset-cff-common.cc @@ -66,8 +66,7 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan, { /* use hb_set to determine the subset of font dicts */ - hb_set_t *set = hb_set_create (); - if (unlikely (set == &Null (hb_set_t))) return false; + hb_set_t set; hb_codepoint_t prev_fd = CFF_UNDEF_CODE; for (hb_codepoint_t i = 0; i < subset_num_glyphs; i++) { @@ -79,7 +78,7 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan, glyph = i; } fd = src.get_fd (glyph); - set->add (fd); + set.add (fd); if (fd != prev_fd) { @@ -90,12 +89,11 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan, } } - subset_fd_count = set->get_population (); + subset_fd_count = set.get_population (); if (subset_fd_count == fdCount) { /* all font dicts belong to the subset. no need to subset FDSelect & FDArray */ fdmap.identity (fdCount); - hb_set_destroy (set); } else { @@ -103,9 +101,8 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan, fdmap.reset (); hb_codepoint_t fd = CFF_UNDEF_CODE; - while (set->next (&fd)) + while (set.next (&fd)) fdmap.add (fd); - hb_set_destroy (set); if (unlikely (fdmap.get_population () != subset_fd_count)) return false; } diff --git a/thirdparty/harfbuzz/src/hb-subset-cff-common.hh b/thirdparty/harfbuzz/src/hb-subset-cff-common.hh index bb9f27eec1..8bbc017656 100644 --- a/thirdparty/harfbuzz/src/hb-subset-cff-common.hh +++ b/thirdparty/harfbuzz/src/hb-subset-cff-common.hh @@ -38,15 +38,16 @@ namespace CFF { struct str_encoder_t { str_encoder_t (str_buff_t &buff_) - : buff (buff_), error (false) {} + : buff (buff_) {} void reset () { buff.reset (); } void encode_byte (unsigned char b) { - buff.push (b); - if (unlikely (buff.in_error ())) - set_error (); + if (likely ((signed) buff.length < buff.allocated)) + buff.arrayZ[buff.length++] = b; + else + buff.push (b); } void encode_int (int v) @@ -108,27 +109,18 @@ struct str_encoder_t encode_byte (op); } - void copy_str (const hb_ubytes_t &str) + void copy_str (const unsigned char *str, unsigned length) { - unsigned int offset = buff.length; - /* Manually resize buffer since faster. */ - if ((signed) (buff.length + str.length) <= buff.allocated) - buff.length += str.length; - else if (unlikely (!buff.resize (offset + str.length))) - { - set_error (); - return; - } - memcpy (buff.arrayZ + offset, &str[0], str.length); + assert ((signed) (buff.length + length) <= buff.allocated); + hb_memcpy (buff.arrayZ + buff.length, str, length); + buff.length += length; } - bool is_error () const { return error; } + bool in_error () const { return buff.in_error (); } protected: - void set_error () { error = true; } str_buff_t &buff; - bool error; }; struct cff_sub_table_info_t { @@ -187,9 +179,12 @@ struct cff_font_dict_op_serializer_t : op_serializer_t } else { - HBUINT8 *d = c->allocate_size<HBUINT8> (opstr.str.length); + unsigned char *d = c->allocate_size<unsigned char> (opstr.length); if (unlikely (!d)) return_trace (false); - memcpy (d, &opstr.str[0], opstr.str.length); + /* Faster than hb_memcpy for small strings. */ + for (unsigned i = 0; i < opstr.length; i++) + d[i] = opstr.ptr[i]; + //hb_memcpy (d, opstr.ptr, opstr.length); } return_trace (true); } @@ -239,11 +234,10 @@ struct subr_flattener_t bool flatten (str_buff_vec_t &flat_charstrings) { - if (!flat_charstrings.resize (plan->num_output_glyphs ())) + unsigned count = plan->num_output_glyphs (); + if (!flat_charstrings.resize (count)) return false; - for (unsigned int i = 0; i < plan->num_output_glyphs (); i++) - flat_charstrings[i].init (); - for (unsigned int i = 0; i < plan->num_output_glyphs (); i++) + for (unsigned int i = 0; i < count; i++) { hb_codepoint_t glyph; if (!plan->old_gid_for_new_gid (i, &glyph)) @@ -259,7 +253,7 @@ struct subr_flattener_t ENV env (str, acc, fd); cs_interpreter_t<ENV, OPSET, flatten_param_t> interp (env); flatten_param_t param = { - flat_charstrings[i], + flat_charstrings.arrayZ[i], (bool) (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) }; if (unlikely (!interp.interpret (param))) @@ -274,11 +268,9 @@ struct subr_flattener_t struct subr_closures_t { - subr_closures_t (unsigned int fd_count) : valid (false), global_closure (), local_closures () + subr_closures_t (unsigned int fd_count) : global_closure (), local_closures () { - valid = true; - if (!local_closures.resize (fd_count)) - valid = false; + local_closures.resize (fd_count); } void reset () @@ -288,47 +280,38 @@ struct subr_closures_t local_closures[i].clear(); } - bool is_valid () const { return valid; } - bool valid; + bool in_error () const { return local_closures.in_error (); } hb_set_t global_closure; hb_vector_t<hb_set_t> local_closures; }; struct parsed_cs_op_t : op_str_t { - void init (unsigned int subr_num_ = 0) - { - subr_num = subr_num_; - drop_flag = false; - keep_flag = false; - skip_flag = false; - } - - bool for_drop () const { return drop_flag; } - void set_drop () { if (!for_keep ()) drop_flag = true; } + parsed_cs_op_t (unsigned int subr_num_ = 0) : + subr_num (subr_num_) {} - bool for_keep () const { return keep_flag; } - void set_keep () { keep_flag = true; } + bool is_hinting () const { return hinting_flag; } + void set_hinting () { hinting_flag = true; } - bool for_skip () const { return skip_flag; } - void set_skip () { skip_flag = true; } - - unsigned int subr_num; + /* The layout of this struct is designed to fit within the + * padding of op_str_t! */ protected: - bool drop_flag; - bool keep_flag; - bool skip_flag; + bool hinting_flag = false; + + public: + uint16_t subr_num; }; struct parsed_cs_str_t : parsed_values_t<parsed_cs_op_t> { - void init () + parsed_cs_str_t () : + parsed (false), + hint_dropped (false), + has_prefix_ (false), + has_calls_ (false) { SUPER::init (); - parsed = false; - hint_dropped = false; - has_prefix_ = false; } void add_op (op_code_t op, const byte_str_ref_t& str_ref) @@ -341,13 +324,12 @@ struct parsed_cs_str_t : parsed_values_t<parsed_cs_op_t> { if (!is_parsed ()) { - unsigned int parsed_len = get_count (); - if (likely (parsed_len > 0)) - values[parsed_len-1].set_skip (); + has_calls_ = true; - parsed_cs_op_t val; - val.init (subr_num); - SUPER::add_op (op, str_ref, val); + /* Pop the subroutine number. */ + values.pop (); + + SUPER::add_op (op, str_ref, {subr_num}); } } @@ -377,11 +359,14 @@ struct parsed_cs_str_t : parsed_values_t<parsed_cs_op_t> op_code_t prefix_op () const { return prefix_op_; } const number_t &prefix_num () const { return prefix_num_; } + bool has_calls () const { return has_calls_; } + protected: - bool parsed; - bool hint_dropped; - bool vsindex_dropped; - bool has_prefix_; + bool parsed : 1; + bool hint_dropped : 1; + bool vsindex_dropped : 1; + bool has_prefix_ : 1; + bool has_calls_ : 1; op_code_t prefix_op_; number_t prefix_num_; @@ -395,6 +380,59 @@ struct parsed_cs_str_vec_t : hb_vector_t<parsed_cs_str_t> typedef hb_vector_t<parsed_cs_str_t> SUPER; }; +struct cff_subset_accelerator_t +{ + static cff_subset_accelerator_t* create ( + hb_blob_t* original_blob, + const parsed_cs_str_vec_t& parsed_charstrings, + const parsed_cs_str_vec_t& parsed_global_subrs, + const hb_vector_t<parsed_cs_str_vec_t>& parsed_local_subrs) { + cff_subset_accelerator_t* accel = + (cff_subset_accelerator_t*) hb_malloc (sizeof(cff_subset_accelerator_t)); + new (accel) cff_subset_accelerator_t (original_blob, + parsed_charstrings, + parsed_global_subrs, + parsed_local_subrs); + return accel; + } + + static void destroy (void* value) { + if (!value) return; + + cff_subset_accelerator_t* accel = (cff_subset_accelerator_t*) value; + accel->~cff_subset_accelerator_t (); + hb_free (accel); + } + + cff_subset_accelerator_t( + hb_blob_t* original_blob_, + const parsed_cs_str_vec_t& parsed_charstrings_, + const parsed_cs_str_vec_t& parsed_global_subrs_, + const hb_vector_t<parsed_cs_str_vec_t>& parsed_local_subrs_) + { + parsed_charstrings = parsed_charstrings_; + parsed_global_subrs = parsed_global_subrs_; + parsed_local_subrs = parsed_local_subrs_; + + // the parsed charstrings point to memory in the original CFF table so we must hold a reference + // to it to keep the memory valid. + original_blob = hb_blob_reference (original_blob_); + } + + ~cff_subset_accelerator_t() { + hb_blob_destroy (original_blob); + hb_map_destroy (glyph_to_sid_map.get_relaxed ()); + } + + parsed_cs_str_vec_t parsed_charstrings; + parsed_cs_str_vec_t parsed_global_subrs; + hb_vector_t<parsed_cs_str_vec_t> parsed_local_subrs; + mutable hb_atomic_ptr_t<hb_map_t> glyph_to_sid_map = nullptr; + + private: + hb_blob_t* original_blob; +}; + struct subr_subset_param_t { subr_subset_param_t (parsed_cs_str_t *parsed_charstring_, @@ -446,7 +484,11 @@ struct subr_subset_param_t if (unlikely (calling && !parsed_str->is_parsed () && (parsed_str->values.length > 0))) env.set_error (); else + { + if (!parsed_str->is_parsed ()) + parsed_str->alloc (env.str_ref.total_size () / 2); current_parsed_str = parsed_str; + } } parsed_cs_str_t *current_parsed_str; @@ -506,7 +548,7 @@ struct subr_remaps_t { global_remap.create (&closures.global_closure); for (unsigned int i = 0; i < local_remaps.length; i++) - local_remaps[i].create (&closures.local_closures[i]); + local_remaps.arrayZ[i].create (&closures.local_closures[i]); } subr_remap_t global_remap; @@ -517,7 +559,8 @@ template <typename SUBSETTER, typename SUBRS, typename ACC, typename ENV, typena struct subr_subsetter_t { subr_subsetter_t (ACC &acc_, const hb_subset_plan_t *plan_) - : acc (acc_), plan (plan_), closures(acc_.fdCount), remaps(acc_.fdCount) + : acc (acc_), plan (plan_), closures(acc_.fdCount), + remaps(acc_.fdCount) {} /* Subroutine subsetting with --no-desubroutinize runs in phases: @@ -536,55 +579,96 @@ struct subr_subsetter_t */ bool subset (void) { - parsed_charstrings.resize (plan->num_output_glyphs ()); - parsed_global_subrs.resize (acc.globalSubrs->count); - - if (unlikely (remaps.in_error() - || parsed_charstrings.in_error () - || parsed_global_subrs.in_error ())) { - return false; + unsigned fd_count = acc.fdCount; + const cff_subset_accelerator_t* cff_accelerator = nullptr; + if (plan->accelerator && plan->accelerator->cff_accelerator) { + cff_accelerator = plan->accelerator->cff_accelerator; + fd_count = cff_accelerator->parsed_local_subrs.length; } - if (unlikely (!parsed_local_subrs.resize (acc.fdCount))) return false; + if (cff_accelerator) { + // If we are not dropping hinting then charstrings are not modified so we can + // just use a reference to the cached copies. + cached_charstrings.resize (plan->num_output_glyphs ()); + parsed_global_subrs = &cff_accelerator->parsed_global_subrs; + parsed_local_subrs = &cff_accelerator->parsed_local_subrs; + } else { + parsed_charstrings.resize (plan->num_output_glyphs ()); + parsed_global_subrs_storage.resize (acc.globalSubrs->count); - for (unsigned int i = 0; i < acc.fdCount; i++) - { - parsed_local_subrs[i].resize (acc.privateDicts[i].localSubrs->count); - if (unlikely (parsed_local_subrs[i].in_error ())) return false; + if (unlikely (!parsed_local_subrs_storage.resize (fd_count))) return false; + + for (unsigned int i = 0; i < acc.fdCount; i++) + { + unsigned count = acc.privateDicts[i].localSubrs->count; + parsed_local_subrs_storage[i].resize (count); + if (unlikely (parsed_local_subrs_storage[i].in_error ())) return false; + } + + parsed_global_subrs = &parsed_global_subrs_storage; + parsed_local_subrs = &parsed_local_subrs_storage; } - if (unlikely (!closures.valid)) + + if (unlikely (remaps.in_error() + || cached_charstrings.in_error () + || parsed_charstrings.in_error () + || parsed_global_subrs->in_error () + || closures.in_error ())) { return false; + } /* phase 1 & 2 */ for (unsigned int i = 0; i < plan->num_output_glyphs (); i++) { hb_codepoint_t glyph; if (!plan->old_gid_for_new_gid (i, &glyph)) - continue; + continue; + const hb_ubytes_t str = (*acc.charStrings)[glyph]; unsigned int fd = acc.fdSelect->get_fd (glyph); if (unlikely (fd >= acc.fdCount)) - return false; + return false; + + if (cff_accelerator) + { + // parsed string already exists in accelerator, copy it and move + // on. + if (cached_charstrings) + cached_charstrings[i] = &cff_accelerator->parsed_charstrings[glyph]; + else + parsed_charstrings[i] = cff_accelerator->parsed_charstrings[glyph]; + + continue; + } ENV env (str, acc, fd); cs_interpreter_t<ENV, OPSET, subr_subset_param_t> interp (env); - parsed_charstrings[i].alloc (str.length); + parsed_charstrings[i].alloc (str.length / 2); subr_subset_param_t param (&parsed_charstrings[i], - &parsed_global_subrs, - &parsed_local_subrs[fd], - &closures.global_closure, - &closures.local_closures[fd], - plan->flags & HB_SUBSET_FLAGS_NO_HINTING); + &parsed_global_subrs_storage, + &parsed_local_subrs_storage[fd], + &closures.global_closure, + &closures.local_closures[fd], + plan->flags & HB_SUBSET_FLAGS_NO_HINTING); if (unlikely (!interp.interpret (param))) - return false; + return false; /* complete parsed string esp. copy CFF1 width or CFF2 vsindex to the parsed charstring for encoding */ SUBSETTER::complete_parsed_str (interp.env, param, parsed_charstrings[i]); } - if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + // Since parsed strings were loaded from accelerator, we still need + // to compute the subroutine closures which would have normally happened during + // parsing. + if (cff_accelerator && + !closure_subroutines(*parsed_global_subrs, + *parsed_local_subrs)) + return false; + + if ((plan->flags & HB_SUBSET_FLAGS_NO_HINTING && !cff_accelerator) || + plan->inprogress_accelerator) { /* mark hint ops and arguments for drop */ for (unsigned int i = 0; i < plan->num_output_glyphs (); i++) @@ -596,8 +680,8 @@ struct subr_subsetter_t if (unlikely (fd >= acc.fdCount)) return false; subr_subset_param_t param (&parsed_charstrings[i], - &parsed_global_subrs, - &parsed_local_subrs[fd], + &parsed_global_subrs_storage, + &parsed_local_subrs_storage[fd], &closures.global_closure, &closures.local_closures[fd], plan->flags & HB_SUBSET_FLAGS_NO_HINTING); @@ -612,27 +696,14 @@ struct subr_subsetter_t } /* after dropping hints recreate closures of actually used subrs */ - closures.reset (); - for (unsigned int i = 0; i < plan->num_output_glyphs (); i++) - { - hb_codepoint_t glyph; - if (!plan->old_gid_for_new_gid (i, &glyph)) - continue; - unsigned int fd = acc.fdSelect->get_fd (glyph); - if (unlikely (fd >= acc.fdCount)) - return false; - subr_subset_param_t param (&parsed_charstrings[i], - &parsed_global_subrs, - &parsed_local_subrs[fd], - &closures.global_closure, - &closures.local_closures[fd], - plan->flags & HB_SUBSET_FLAGS_NO_HINTING); - collect_subr_refs_in_str (parsed_charstrings[i], param); - } + if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING && + !cff_accelerator && + !closure_subroutines(*parsed_global_subrs, *parsed_local_subrs)) return false; } remaps.create (closures); + populate_subset_accelerator (); return true; } @@ -646,13 +717,13 @@ struct subr_subsetter_t if (!plan->old_gid_for_new_gid (i, &glyph)) { /* add an endchar only charstring for a missing glyph if CFF1 */ - if (endchar_op != OpCode_Invalid) buffArray[i].push (endchar_op); + if (endchar_op != OpCode_Invalid) buffArray.arrayZ[i].push (endchar_op); continue; } unsigned int fd = acc.fdSelect->get_fd (glyph); if (unlikely (fd >= acc.fdCount)) return false; - if (unlikely (!encode_str (parsed_charstrings[i], fd, buffArray[i]))) + if (unlikely (!encode_str (get_parsed_charstring (i), fd, buffArray.arrayZ[i]))) return false; } return true; @@ -664,26 +735,25 @@ struct subr_subsetter_t if (unlikely (!buffArray.resize (count))) return false; - for (unsigned int old_num = 0; old_num < subrs.length; old_num++) + for (unsigned int new_num = 0; new_num < count; new_num++) { - hb_codepoint_t new_num = remap[old_num]; - if (new_num != CFF_UNDEF_CODE) - { - if (unlikely (!encode_str (subrs[old_num], fd, buffArray[new_num]))) - return false; - } + hb_codepoint_t old_num = remap.backward (new_num); + assert (old_num != CFF_UNDEF_CODE); + + if (unlikely (!encode_str (subrs[old_num], fd, buffArray[new_num]))) + return false; } return true; } bool encode_globalsubrs (str_buff_vec_t &buffArray) { - return encode_subrs (parsed_global_subrs, remaps.global_remap, 0, buffArray); + return encode_subrs (*parsed_global_subrs, remaps.global_remap, 0, buffArray); } bool encode_localsubrs (unsigned int fd, str_buff_vec_t &buffArray) const { - return encode_subrs (parsed_local_subrs[fd], remaps.local_remaps[fd], fd, buffArray); + return encode_subrs ((*parsed_local_subrs)[fd], remaps.local_remaps[fd], fd, buffArray); } protected: @@ -712,7 +782,7 @@ struct subr_subsetter_t * then this entire subroutine must be a hint. drop its call. */ if (drop.ends_in_hint) { - str.values[pos].set_drop (); + str.values[pos].set_hinting (); /* if this subr call is at the end of the parent subr, propagate the flag * otherwise reset the flag */ if (!str.at_end (pos)) @@ -720,7 +790,7 @@ struct subr_subsetter_t } else if (drop.all_dropped) { - str.values[pos].set_drop (); + str.values[pos].set_hinting (); } return has_hint; @@ -731,20 +801,22 @@ struct subr_subsetter_t { bool seen_hint = false; - for (unsigned int pos = 0; pos < str.values.length; pos++) + unsigned count = str.values.length; + auto *values = str.values.arrayZ; + for (unsigned int pos = 0; pos < count; pos++) { bool has_hint = false; - switch (str.values[pos].op) + switch (values[pos].op) { case OpCode_callsubr: has_hint = drop_hints_in_subr (str, pos, - *param.parsed_local_subrs, str.values[pos].subr_num, + *param.parsed_local_subrs, values[pos].subr_num, param, drop); break; case OpCode_callgsubr: has_hint = drop_hints_in_subr (str, pos, - *param.parsed_global_subrs, str.values[pos].subr_num, + *param.parsed_global_subrs, values[pos].subr_num, param, drop); break; @@ -758,7 +830,7 @@ struct subr_subsetter_t case OpCode_cntrmask: if (drop.seen_moveto) { - str.values[pos].set_drop (); + values[pos].set_hinting (); break; } HB_FALLTHROUGH; @@ -768,13 +840,13 @@ struct subr_subsetter_t case OpCode_hstem: case OpCode_vstem: has_hint = true; - str.values[pos].set_drop (); + values[pos].set_hinting (); if (str.at_end (pos)) drop.ends_in_hint = true; break; case OpCode_dotsection: - str.values[pos].set_drop (); + values[pos].set_hinting (); break; default: @@ -785,10 +857,10 @@ struct subr_subsetter_t { for (int i = pos - 1; i >= 0; i--) { - parsed_cs_op_t &csop = str.values[(unsigned)i]; - if (csop.for_drop ()) + parsed_cs_op_t &csop = values[(unsigned)i]; + if (csop.is_hinting ()) break; - csop.set_drop (); + csop.set_hinting (); if (csop.op == OpCode_vsindexcs) drop.vsindex_dropped = true; } @@ -801,12 +873,12 @@ struct subr_subsetter_t * only (usually one) hintmask operator, then calls to this subr can be dropped. */ drop.all_dropped = true; - for (unsigned int pos = 0; pos < str.values.length; pos++) + for (unsigned int pos = 0; pos < count; pos++) { - parsed_cs_op_t &csop = str.values[pos]; + parsed_cs_op_t &csop = values[pos]; if (csop.op == OpCode_return) break; - if (!csop.for_drop ()) + if (!csop.is_hinting ()) { drop.all_dropped = false; break; @@ -816,32 +888,62 @@ struct subr_subsetter_t return seen_hint; } - void collect_subr_refs_in_subr (parsed_cs_str_t &str, unsigned int pos, - unsigned int subr_num, parsed_cs_str_vec_t &subrs, + bool closure_subroutines (const parsed_cs_str_vec_t& global_subrs, + const hb_vector_t<parsed_cs_str_vec_t>& local_subrs) + { + closures.reset (); + for (unsigned int i = 0; i < plan->num_output_glyphs (); i++) + { + hb_codepoint_t glyph; + if (!plan->old_gid_for_new_gid (i, &glyph)) + continue; + unsigned int fd = acc.fdSelect->get_fd (glyph); + if (unlikely (fd >= acc.fdCount)) + return false; + + // Note: const cast is safe here because the collect_subr_refs_in_str only performs a + // closure and does not modify any of the charstrings. + subr_subset_param_t param (const_cast<parsed_cs_str_t*> (&get_parsed_charstring (i)), + const_cast<parsed_cs_str_vec_t*> (&global_subrs), + const_cast<parsed_cs_str_vec_t*> (&local_subrs[fd]), + &closures.global_closure, + &closures.local_closures[fd], + plan->flags & HB_SUBSET_FLAGS_NO_HINTING); + collect_subr_refs_in_str (get_parsed_charstring (i), param); + } + + return true; + } + + void collect_subr_refs_in_subr (unsigned int subr_num, parsed_cs_str_vec_t &subrs, hb_set_t *closure, const subr_subset_param_t ¶m) { + if (closure->has (subr_num)) + return; closure->add (subr_num); collect_subr_refs_in_str (subrs[subr_num], param); } - void collect_subr_refs_in_str (parsed_cs_str_t &str, const subr_subset_param_t ¶m) + void collect_subr_refs_in_str (const parsed_cs_str_t &str, + const subr_subset_param_t ¶m) { - for (unsigned int pos = 0; pos < str.values.length; pos++) + if (!str.has_calls ()) + return; + + for (auto &opstr : str.values) { - if (!str.values[pos].for_drop ()) + if (!param.drop_hints || !opstr.is_hinting ()) { - switch (str.values[pos].op) + switch (opstr.op) { case OpCode_callsubr: - collect_subr_refs_in_subr (str, pos, - str.values[pos].subr_num, *param.parsed_local_subrs, + collect_subr_refs_in_subr (opstr.subr_num, *param.parsed_local_subrs, param.local_closure, param); break; case OpCode_callgsubr: - collect_subr_refs_in_subr (str, pos, - str.values[pos].subr_num, *param.parsed_global_subrs, + collect_subr_refs_in_subr (opstr.subr_num, *param.parsed_global_subrs, param.global_closure, param); break; @@ -853,42 +955,113 @@ struct subr_subsetter_t bool encode_str (const parsed_cs_str_t &str, const unsigned int fd, str_buff_t &buff) const { - unsigned count = str.get_count (); str_encoder_t encoder (buff); encoder.reset (); - buff.alloc (count * 3); + bool hinting = !(plan->flags & HB_SUBSET_FLAGS_NO_HINTING); /* if a prefix (CFF1 width or CFF2 vsindex) has been removed along with hints, * re-insert it at the beginning of charstreing */ - if (str.has_prefix () && str.is_hint_dropped ()) + if (str.has_prefix () && !hinting && str.is_hint_dropped ()) { encoder.encode_num (str.prefix_num ()); if (str.prefix_op () != OpCode_Invalid) encoder.encode_op (str.prefix_op ()); } - for (unsigned int i = 0; i < count; i++) + + unsigned size = 0; + for (auto &opstr : str.values) { - const parsed_cs_op_t &opstr = str.values[i]; - if (!opstr.for_drop () && !opstr.for_skip ()) + size += opstr.length; + if (opstr.op == OpCode_callsubr || opstr.op == OpCode_callgsubr) + size += 3; + } + if (!buff.alloc (buff.length + size)) + return false; + + for (auto &opstr : str.values) + { + if (hinting || !opstr.is_hinting ()) { switch (opstr.op) { case OpCode_callsubr: encoder.encode_int (remaps.local_remaps[fd].biased_num (opstr.subr_num)); - encoder.encode_op (OpCode_callsubr); + encoder.copy_str (opstr.ptr, opstr.length); break; case OpCode_callgsubr: encoder.encode_int (remaps.global_remap.biased_num (opstr.subr_num)); - encoder.encode_op (OpCode_callgsubr); + encoder.copy_str (opstr.ptr, opstr.length); break; default: - encoder.copy_str (opstr.str); + encoder.copy_str (opstr.ptr, opstr.length); break; } } } - return !encoder.is_error (); + return !encoder.in_error (); + } + + void compact_parsed_strings () const + { + for (auto &cs : parsed_charstrings) + compact_string (cs); + for (auto &cs : parsed_global_subrs_storage) + compact_string (cs); + for (auto &vec : parsed_local_subrs_storage) + for (auto &cs : vec) + compact_string (cs); + } + + static void compact_string (parsed_cs_str_t &str) + { + unsigned count = str.values.length; + if (unlikely (!count)) return; + auto &opstr = str.values.arrayZ; + unsigned j = 0; + for (unsigned i = 1; i < count; i++) + { + /* See if we can combine op j and op i. */ + bool combine = + (opstr[j].op != OpCode_callsubr && opstr[j].op != OpCode_callgsubr) && + (opstr[i].op != OpCode_callsubr && opstr[i].op != OpCode_callgsubr) && + (opstr[j].is_hinting () == opstr[i].is_hinting ()) && + (opstr[j].ptr + opstr[j].length == opstr[i].ptr) && + (opstr[j].length + opstr[i].length <= 255); + + if (combine) + { + opstr[j].length += opstr[i].length; + opstr[j].op = OpCode_Invalid; + } + else + { + opstr[++j] = opstr[i]; + } + } + str.values.shrink (j + 1); + } + + void populate_subset_accelerator () const + { + if (!plan->inprogress_accelerator) return; + + compact_parsed_strings (); + + plan->inprogress_accelerator->cff_accelerator = + cff_subset_accelerator_t::create(acc.blob, + parsed_charstrings, + parsed_global_subrs_storage, + parsed_local_subrs_storage); + plan->inprogress_accelerator->destroy_cff_accelerator = + cff_subset_accelerator_t::destroy; + + } + + const parsed_cs_str_t& get_parsed_charstring (unsigned i) const + { + if (cached_charstrings) return *(cached_charstrings[i]); + return parsed_charstrings[i]; } protected: @@ -897,13 +1070,17 @@ struct subr_subsetter_t subr_closures_t closures; - parsed_cs_str_vec_t parsed_charstrings; - parsed_cs_str_vec_t parsed_global_subrs; - hb_vector_t<parsed_cs_str_vec_t> parsed_local_subrs; + hb_vector_t<const parsed_cs_str_t*> cached_charstrings; + const parsed_cs_str_vec_t* parsed_global_subrs; + const hb_vector_t<parsed_cs_str_vec_t>* parsed_local_subrs; subr_remaps_t remaps; private: + + parsed_cs_str_vec_t parsed_charstrings; + parsed_cs_str_vec_t parsed_global_subrs_storage; + hb_vector_t<parsed_cs_str_vec_t> parsed_local_subrs_storage; typedef typename SUBRS::count_type subr_count_type; }; diff --git a/thirdparty/harfbuzz/src/hb-subset-cff1.cc b/thirdparty/harfbuzz/src/hb-subset-cff1.cc index 52bb13d320..538f28f5aa 100644 --- a/thirdparty/harfbuzz/src/hb-subset-cff1.cc +++ b/thirdparty/harfbuzz/src/hb-subset-cff1.cc @@ -167,9 +167,10 @@ struct cff1_top_dict_op_serializer_t : cff_top_dict_op_serializer_t<cff1_top_dic * for supplement, the original byte string is copied along with the op code */ op_str_t supp_op; supp_op.op = op; - if ( unlikely (!(opstr.str.length >= opstr.last_arg_offset + 3))) + if ( unlikely (!(opstr.length >= opstr.last_arg_offset + 3))) return_trace (false); - supp_op.str = hb_ubytes_t (&opstr.str + opstr.last_arg_offset, opstr.str.length - opstr.last_arg_offset); + supp_op.ptr = opstr.ptr + opstr.last_arg_offset; + supp_op.length = opstr.length - opstr.last_arg_offset; return_trace (UnsizedByteStr::serialize_int2 (c, mod.nameSIDs[name_dict_values_t::registry]) && UnsizedByteStr::serialize_int2 (c, mod.nameSIDs[name_dict_values_t::ordering]) && copy_opstr (c, supp_op)); @@ -442,8 +443,17 @@ struct cff_subset_plan { return; } - bool use_glyph_to_sid_map = plan->num_output_glyphs () > plan->source->get_num_glyphs () / 8.; - hb_map_t *glyph_to_sid_map = use_glyph_to_sid_map ? acc.create_glyph_to_sid_map () : nullptr; + hb_map_t *glyph_to_sid_map = (plan->accelerator && plan->accelerator->cff_accelerator) ? + plan->accelerator->cff_accelerator->glyph_to_sid_map : + nullptr; + bool created_map = false; + if (!glyph_to_sid_map && + ((plan->accelerator && plan->accelerator->cff_accelerator) || + plan->num_output_glyphs () > plan->source->get_num_glyphs () / 8.)) + { + created_map = true; + glyph_to_sid_map = acc.create_glyph_to_sid_map (); + } unsigned int glyph; for (glyph = 1; glyph < plan->num_output_glyphs (); glyph++) @@ -467,8 +477,12 @@ struct cff_subset_plan { last_sid = sid; } - if (glyph_to_sid_map) - hb_map_destroy (glyph_to_sid_map); + if (created_map) + { + if (!(plan->accelerator && plan->accelerator->cff_accelerator) || + !plan->accelerator->cff_accelerator->glyph_to_sid_map.cmpexch (nullptr, glyph_to_sid_map)) + hb_map_destroy (glyph_to_sid_map); + } bool two_byte = subset_charset_ranges.complete (glyph); @@ -728,11 +742,17 @@ static bool _serialize_cff1 (hb_serialize_context_t *c, /* CharStrings */ { + c->push<CFF1CharStrings> (); + + unsigned total_size = CFF1CharStrings::total_size (plan.subset_charstrings); + if (unlikely (!c->start_zerocopy (total_size))) + return false; + CFF1CharStrings *cs = c->start_embed<CFF1CharStrings> (); if (unlikely (!cs)) return false; - c->push (); + if (likely (cs->serialize (c, plan.subset_charstrings))) - plan.info.char_strings_link = c->pop_pack (); + plan.info.char_strings_link = c->pop_pack (false); else { c->pop_discard (); @@ -815,7 +835,7 @@ static bool _serialize_cff1 (hb_serialize_context_t *c, CFF1Subrs *dest = c->start_embed <CFF1Subrs> (); if (unlikely (!dest)) return false; if (likely (dest->serialize (c, plan.subset_globalsubrs))) - c->pop_pack (); + c->pop_pack (false); else { c->pop_discard (); diff --git a/thirdparty/harfbuzz/src/hb-subset-cff2.cc b/thirdparty/harfbuzz/src/hb-subset-cff2.cc index 08e820efcf..60946b0281 100644 --- a/thirdparty/harfbuzz/src/hb-subset-cff2.cc +++ b/thirdparty/harfbuzz/src/hb-subset-cff2.cc @@ -334,7 +334,7 @@ static bool _serialize_cff2 (hb_serialize_context_t *c, if (unlikely (!dest)) return false; c->push (); if (likely (dest->serialize (c, plan.subset_localsubrs[i]))) - subrs_link = c->pop_pack (); + subrs_link = c->pop_pack (false); else { c->pop_discard (); @@ -361,11 +361,17 @@ static bool _serialize_cff2 (hb_serialize_context_t *c, /* CharStrings */ { + c->push (); + + unsigned total_size = CFF2CharStrings::total_size (plan.subset_charstrings); + if (unlikely (!c->start_zerocopy (total_size))) + return false; + CFF2CharStrings *cs = c->start_embed<CFF2CharStrings> (); if (unlikely (!cs)) return false; - c->push (); + if (likely (cs->serialize (c, plan.subset_charstrings))) - plan.info.char_strings_link = c->pop_pack (); + plan.info.char_strings_link = c->pop_pack (false); else { c->pop_discard (); @@ -377,9 +383,10 @@ static bool _serialize_cff2 (hb_serialize_context_t *c, if (acc.fdSelect != &Null (CFF2FDSelect)) { c->push (); - if (likely (hb_serialize_cff_fdselect (c, num_glyphs, *(const FDSelect *)acc.fdSelect, plan.orig_fdcount, - plan.subset_fdselect_format, plan.subset_fdselect_size, - plan.subset_fdselect_ranges))) + if (likely (hb_serialize_cff_fdselect (c, num_glyphs, *(const FDSelect *)acc.fdSelect, + plan.orig_fdcount, + plan.subset_fdselect_format, plan.subset_fdselect_size, + plan.subset_fdselect_ranges))) plan.info.fd_select.link = c->pop_pack (); else { @@ -401,7 +408,7 @@ static bool _serialize_cff2 (hb_serialize_context_t *c, hb_iter (private_dict_infos)) ; if (unlikely (!fda->serialize (c, it, fontSzr))) return false; - plan.info.fd_array_link = c->pop_pack (); + plan.info.fd_array_link = c->pop_pack (false); } /* variation store */ @@ -410,7 +417,7 @@ static bool _serialize_cff2 (hb_serialize_context_t *c, c->push (); CFF2VariationStore *dest = c->start_embed<CFF2VariationStore> (); if (unlikely (!dest || !dest->serialize (c, acc.varStore))) return false; - plan.info.var_store_link = c->pop_pack (); + plan.info.var_store_link = c->pop_pack (false); } OT::cff2 *cff2 = c->allocate_min<OT::cff2> (); diff --git a/thirdparty/harfbuzz/src/hb-subset-input.cc b/thirdparty/harfbuzz/src/hb-subset-input.cc index fd250104bb..42434ae0ef 100644 --- a/thirdparty/harfbuzz/src/hb-subset-input.cc +++ b/thirdparty/harfbuzz/src/hb-subset-input.cc @@ -26,7 +26,7 @@ #include "hb-subset.hh" #include "hb-set.hh" - +#include "hb-utf.hh" /** * hb_subset_input_create_or_fail: * @@ -49,8 +49,15 @@ hb_subset_input_create_or_fail (void) set = hb_set_create (); input->axes_location = hb_hashmap_create<hb_tag_t, float> (); +#ifdef HB_EXPERIMENTAL_API + input->name_table_overrides = hb_hashmap_create<hb_ot_name_record_ids_t, hb_bytes_t> (); +#endif - if (!input->axes_location || input->in_error ()) + if (!input->axes_location || +#ifdef HB_EXPERIMENTAL_API + !input->name_table_overrides || +#endif + input->in_error ()) { hb_subset_input_destroy (input); return nullptr; @@ -248,6 +255,15 @@ hb_subset_input_destroy (hb_subset_input_t *input) hb_hashmap_destroy (input->axes_location); +#ifdef HB_EXPERIMENTAL_API + if (input->name_table_overrides) + { + for (auto _ : *input->name_table_overrides) + _.second.fini (); + } + hb_hashmap_destroy (input->name_table_overrides); +#endif + hb_free (input); } @@ -379,7 +395,6 @@ hb_subset_input_get_user_data (const hb_subset_input_t *input, return hb_object_get_user_data (input, key); } -#ifdef HB_EXPERIMENTAL_API #ifndef HB_NO_VAR /** * hb_subset_input_pin_axis_to_default: (skip) @@ -388,9 +403,12 @@ hb_subset_input_get_user_data (const hb_subset_input_t *input, * * Pin an axis to its default location in the given subset input object. * + * Currently only works for fonts with 'glyf' tables. CFF and CFF2 is not + * yet supported. Additionally all axes in a font must be pinned. + * * Return value: `true` if success, `false` otherwise * - * Since: EXPERIMENTAL + * Since: 6.0.0 **/ HB_EXTERN hb_bool_t hb_subset_input_pin_axis_to_default (hb_subset_input_t *input, @@ -412,9 +430,12 @@ hb_subset_input_pin_axis_to_default (hb_subset_input_t *input, * * Pin an axis to a fixed location in the given subset input object. * + * Currently only works for fonts with 'glyf' tables. CFF and CFF2 is not + * yet supported. Additionally all axes in a font must be pinned. + * * Return value: `true` if success, `false` otherwise * - * Since: EXPERIMENTAL + * Since: 6.0.0 **/ HB_EXTERN hb_bool_t hb_subset_input_pin_axis_location (hb_subset_input_t *input, @@ -430,28 +451,41 @@ hb_subset_input_pin_axis_location (hb_subset_input_t *input, return input->axes_location->set (axis_tag, val); } #endif -#endif -#ifdef HB_EXPERIMENTAL_API /** - * hb_subset_preprocess - * @input: a #hb_face_t object. + * hb_subset_preprocess: + * @source: a #hb_face_t object. * * Preprocesses the face and attaches data that will be needed by the * subsetter. Future subsetting operations can then use the precomputed data * to speed up the subsetting operation. * - * Since: EXPERIMENTAL + * See [subset-preprocessing](https://github.com/harfbuzz/harfbuzz/blob/main/docs/subset-preprocessing.md) + * for more information. + * + * Note: the preprocessed face may contain sub-blobs that reference the memory + * backing the source #hb_face_t. Therefore in the case that this memory is not + * owned by the source face you will need to ensure that memory lives + * as long as the returned #hb_face_t. + * + * Returns: a new #hb_face_t. + * + * Since: 6.0.0 **/ HB_EXTERN hb_face_t * hb_subset_preprocess (hb_face_t *source) { hb_subset_input_t* input = hb_subset_input_create_or_fail (); + if (!input) + return source; hb_set_clear (hb_subset_input_set(input, HB_SUBSET_SETS_UNICODE)); hb_set_invert (hb_subset_input_set(input, HB_SUBSET_SETS_UNICODE)); + hb_set_clear (hb_subset_input_set(input, HB_SUBSET_SETS_GLYPH_INDEX)); + hb_set_invert (hb_subset_input_set(input, HB_SUBSET_SETS_GLYPH_INDEX)); + hb_set_clear (hb_subset_input_set(input, HB_SUBSET_SETS_LAYOUT_FEATURE_TAG)); hb_set_invert (hb_subset_input_set(input, @@ -467,15 +501,100 @@ hb_subset_preprocess (hb_face_t *source) hb_set_invert (hb_subset_input_set(input, HB_SUBSET_SETS_NAME_ID)); + hb_set_clear (hb_subset_input_set(input, + HB_SUBSET_SETS_NAME_LANG_ID)); + hb_set_invert (hb_subset_input_set(input, + HB_SUBSET_SETS_NAME_LANG_ID)); + hb_subset_input_set_flags(input, HB_SUBSET_FLAGS_NOTDEF_OUTLINE | HB_SUBSET_FLAGS_GLYPH_NAMES | - HB_SUBSET_FLAGS_RETAIN_GIDS); + HB_SUBSET_FLAGS_RETAIN_GIDS | + HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES); input->attach_accelerator_data = true; + // Always use long loca in the preprocessed version. This allows + // us to store the glyph bytes unpadded which allows the future subset + // operation to run faster by skipping the trim padding step. + input->force_long_loca = true; + hb_face_t* new_source = hb_subset_or_fail (source, input); hb_subset_input_destroy (input); + if (!new_source) { + DEBUG_MSG (SUBSET, nullptr, "Preprocessing failed due to subset failure."); + return source; + } + return new_source; } + +#ifdef HB_EXPERIMENTAL_API +/** + * hb_subset_input_override_name_table: + * @input: a #hb_subset_input_t object. + * @name_id: name_id of a nameRecord + * @platform_id: platform ID of a nameRecord + * @encoding_id: encoding ID of a nameRecord + * @language_id: language ID of a nameRecord + * @name_str: pointer to name string new value or null to indicate should remove + * @str_len: the size of @name_str, or -1 if it is `NULL`-terminated + * + * Override the name string of the NameRecord identified by name_id, + * platform_id, encoding_id and language_id. If a record with that name_id + * doesn't exist, create it and insert to the name table. + * + * Note: for mac platform, we only support name_str with all ascii characters, + * name_str with non-ascii characters will be ignored. + * + * Since: EXPERIMENTAL + **/ +HB_EXTERN hb_bool_t +hb_subset_input_override_name_table (hb_subset_input_t *input, + hb_ot_name_id_t name_id, + unsigned platform_id, + unsigned encoding_id, + unsigned language_id, + const char *name_str, + int str_len /* -1 means nul-terminated */) +{ + if (!name_str) + { + str_len = 0; + } + else if (str_len == -1) + { + str_len = strlen (name_str); + } + + hb_bytes_t name_bytes (nullptr, 0); + if (str_len) + { + if (platform_id == 1) + { + const uint8_t *src = reinterpret_cast<const uint8_t*> (name_str); + const uint8_t *src_end = src + str_len; + + hb_codepoint_t unicode; + const hb_codepoint_t replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT; + while (src < src_end) + { + src = hb_utf8_t::next (src, src_end, &unicode, replacement); + if (unicode >= 0x0080u) + { + printf ("Non-ascii character detected, ignored...This API supports acsii characters only for mac platform\n"); + return false; + } + } + } + char *override_name = (char *) hb_malloc (str_len); + if (unlikely (!override_name)) return false; + + hb_memcpy (override_name, name_str, str_len); + name_bytes = hb_bytes_t (override_name, str_len); + } + input->name_table_overrides->set (hb_ot_name_record_ids_t (platform_id, encoding_id, language_id, name_id), name_bytes); + return true; +} + #endif diff --git a/thirdparty/harfbuzz/src/hb-subset-input.hh b/thirdparty/harfbuzz/src/hb-subset-input.hh index dabb4918fe..ecd47b7abf 100644 --- a/thirdparty/harfbuzz/src/hb-subset-input.hh +++ b/thirdparty/harfbuzz/src/hb-subset-input.hh @@ -36,6 +36,48 @@ #include "hb-font.hh" +struct hb_ot_name_record_ids_t +{ + hb_ot_name_record_ids_t () = default; + hb_ot_name_record_ids_t (unsigned platform_id_, + unsigned encoding_id_, + unsigned language_id_, + unsigned name_id_) + :platform_id (platform_id_), + encoding_id (encoding_id_), + language_id (language_id_), + name_id (name_id_) {} + + bool operator != (const hb_ot_name_record_ids_t o) const + { return !(*this == o); } + + inline bool operator == (const hb_ot_name_record_ids_t& o) const + { + return platform_id == o.platform_id && + encoding_id == o.encoding_id && + language_id == o.language_id && + name_id == o.name_id; + } + + inline uint32_t hash () const + { + uint32_t current = 0; + current = current * 31 + hb_hash (platform_id); + current = current * 31 + hb_hash (encoding_id); + current = current * 31 + hb_hash (language_id); + current = current * 31 + hb_hash (name_id); + return current; + } + + unsigned platform_id; + unsigned encoding_id; + unsigned language_id; + unsigned name_id; +}; + +typedef struct hb_ot_name_record_ids_t hb_ot_name_record_ids_t; + + HB_MARK_AS_FLAG_T (hb_subset_flags_t); struct hb_subset_input_t @@ -60,7 +102,14 @@ struct hb_subset_input_t unsigned flags; bool attach_accelerator_data = false; + + // If set loca format will always be the long version. + bool force_long_loca = false; + hb_hashmap_t<hb_tag_t, float> *axes_location; +#ifdef HB_EXPERIMENTAL_API + hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides; +#endif inline unsigned num_sets () const { @@ -80,7 +129,11 @@ struct hb_subset_input_t return true; } - return axes_location->in_error (); + return axes_location->in_error () +#ifdef HB_EXPERIMENTAL_API + || name_table_overrides->in_error () +#endif + ; } }; diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.cc b/thirdparty/harfbuzz/src/hb-subset-plan.cc index 9cf7c9e431..71bc908ffb 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.cc +++ b/thirdparty/harfbuzz/src/hb-subset-plan.cc @@ -27,6 +27,7 @@ #include "hb-subset-plan.hh" #include "hb-subset-accelerator.hh" #include "hb-map.hh" +#include "hb-multimap.hh" #include "hb-set.hh" #include "hb-ot-cmap-table.hh" @@ -47,7 +48,7 @@ using OT::Layout::GPOS; typedef hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> script_langsys_map; #ifndef HB_NO_SUBSET_CFF -static inline void +static inline bool _add_cff_seac_components (const OT::cff1::accelerator_t &cff, hb_codepoint_t gid, hb_set_t *gids_to_retain) @@ -57,7 +58,9 @@ _add_cff_seac_components (const OT::cff1::accelerator_t &cff, { gids_to_retain->add (base_gid); gids_to_retain->add (accent_gid); + return true; } + return false; } #endif @@ -82,10 +85,8 @@ static void _remap_indexes (const hb_set_t *indexes, hb_map_t *mapping /* OUT */) { - unsigned count = indexes->get_population (); - - for (auto _ : + hb_zip (indexes->iter (), hb_range (count))) - mapping->set (_.first, _.second); + for (auto _ : + hb_enumerate (indexes->iter ())) + mapping->set (_.second, _.first); } @@ -344,7 +345,9 @@ _get_hb_font_with_variations (const hb_subset_plan_t *plan) vars.push (var); } +#ifndef HB_NO_VAR hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location->get_population ()); +#endif return font; } @@ -521,14 +524,44 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, cmap_unicodes = &plan->accelerator->unicodes; } - for (hb_codepoint_t cp : *cmap_unicodes) + if (plan->accelerator && + unicodes->get_population () < cmap_unicodes->get_population () && + glyphs->get_population () < cmap_unicodes->get_population ()) + { + auto &gid_to_unicodes = plan->accelerator->gid_to_unicodes; + for (hb_codepoint_t gid : *glyphs) + { + auto unicodes = gid_to_unicodes.get (gid); + + for (hb_codepoint_t cp : unicodes) + { + plan->codepoint_to_glyph->set (cp, gid); + plan->unicode_to_new_gid_list.push (hb_pair (cp, gid)); + } + } + for (hb_codepoint_t cp : *unicodes) + { + /* Don't double-add entry. */ + if (plan->codepoint_to_glyph->has (cp)) + continue; + + hb_codepoint_t gid = (*unicode_glyphid_map)[cp]; + plan->codepoint_to_glyph->set (cp, gid); + plan->unicode_to_new_gid_list.push (hb_pair (cp, gid)); + } + plan->unicode_to_new_gid_list.qsort (); + } + else { - hb_codepoint_t gid = (*unicode_glyphid_map)[cp]; - if (!unicodes->has (cp) && !glyphs->has (gid)) - continue; + for (hb_codepoint_t cp : *cmap_unicodes) + { + hb_codepoint_t gid = (*unicode_glyphid_map)[cp]; + if (!unicodes->has (cp) && !glyphs->has (gid)) + continue; - plan->codepoint_to_glyph->set (cp, gid); - plan->unicode_to_new_gid_list.push (hb_pair (cp, gid)); + plan->codepoint_to_glyph->set (cp, gid); + plan->unicode_to_new_gid_list.push (hb_pair (cp, gid)); + } } /* Add gids which where requested, but not mapped in cmap */ @@ -639,9 +672,15 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, else plan->_glyphset->union_ (cur_glyphset); #ifndef HB_NO_SUBSET_CFF - if (cff.is_valid ()) - for (hb_codepoint_t gid : cur_glyphset) - _add_cff_seac_components (cff, gid, plan->_glyphset); + if (!plan->accelerator || plan->accelerator->has_seac) + { + bool has_seac = false; + if (cff.is_valid ()) + for (hb_codepoint_t gid : cur_glyphset) + if (_add_cff_seac_components (cff, gid, plan->_glyphset)) + has_seac = true; + plan->has_seac = has_seac; + } #endif _remove_invalid_gids (plan->_glyphset, plan->source->get_num_glyphs ()); @@ -848,9 +887,28 @@ hb_subset_plan_create_or_fail (hb_face_t *face, plan->check_success (plan->vmtx_map = hb_hashmap_create<unsigned, hb_pair_t<unsigned, int>> ()); plan->check_success (plan->hmtx_map = hb_hashmap_create<unsigned, hb_pair_t<unsigned, int>> ()); +#ifdef HB_EXPERIMENTAL_API + plan->check_success (plan->name_table_overrides = hb_hashmap_create<hb_ot_name_record_ids_t, hb_bytes_t> ()); + if (plan->name_table_overrides && input->name_table_overrides) + { + for (auto _ : *input->name_table_overrides) + { + hb_bytes_t name_bytes = _.second; + unsigned len = name_bytes.length; + char *name_str = (char *) hb_malloc (len); + if (unlikely (!plan->check_success (name_str))) + break; + + hb_memcpy (name_str, name_bytes.arrayZ, len); + plan->name_table_overrides->set (_.first, hb_bytes_t (name_str, len)); + } + } +#endif + void* accel = hb_face_get_user_data(face, hb_subset_accelerator_t::user_data_key()); plan->attach_accelerator_data = input->attach_accelerator_data; + plan->force_long_loca = input->force_long_loca; if (accel) plan->accelerator = (hb_subset_accelerator_t*) accel; @@ -893,6 +951,28 @@ hb_subset_plan_create_or_fail (hb_face_t *face, hb_subset_plan_destroy (plan); return nullptr; } + + + if (plan->attach_accelerator_data) + { + hb_multimap_t gid_to_unicodes; + + hb_map_t &unicode_to_gid = *plan->codepoint_to_glyph; + + for (auto unicode : *plan->unicodes) + { + auto gid = unicode_to_gid[unicode]; + gid_to_unicodes.add (gid, unicode); + } + + plan->inprogress_accelerator = + hb_subset_accelerator_t::create (*plan->codepoint_to_glyph, + gid_to_unicodes, + *plan->unicodes, + plan->has_seac); + } + + return plan; } diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.hh b/thirdparty/harfbuzz/src/hb-subset-plan.hh index 15fabba9c3..1b2aee7825 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.hh +++ b/thirdparty/harfbuzz/src/hb-subset-plan.hh @@ -87,6 +87,18 @@ struct hb_subset_plan_t hb_hashmap_destroy (vmtx_map); hb_hashmap_destroy (layout_variation_idx_delta_map); +#ifdef HB_EXPERIMENTAL_API + if (name_table_overrides) + { + for (auto _ : *name_table_overrides) + _.second.fini (); + } + hb_hashmap_destroy (name_table_overrides); +#endif + + if (inprogress_accelerator) + hb_subset_accelerator_t::destroy ((void*) inprogress_accelerator); + if (user_axes_location) { hb_object_destroy (user_axes_location); @@ -99,10 +111,11 @@ struct hb_subset_plan_t bool successful; unsigned flags; bool attach_accelerator_data = false; + bool force_long_loca = false; // For each cp that we'd like to retain maps to the corresponding gid. hb_set_t *unicodes; - hb_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> unicode_to_new_gid_list; + hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> unicode_to_new_gid_list; // name_ids we would like to retain hb_set_t *name_ids; @@ -185,31 +198,41 @@ struct hb_subset_plan_t hb_map_t *axes_old_index_tag_map; bool all_axes_pinned; bool pinned_at_default; + bool has_seac; //hmtx metrics map: new gid->(advance, lsb) hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *hmtx_map; //vmtx metrics map: new gid->(advance, lsb) hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *vmtx_map; +#ifdef HB_EXPERIMENTAL_API + // name table overrides map: hb_ot_name_record_ids_t-> name string new value or + // None to indicate should remove + hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides; +#endif + const hb_subset_accelerator_t* accelerator; + hb_subset_accelerator_t* inprogress_accelerator; public: template<typename T> hb_blob_ptr_t<T> source_table() { - if (sanitized_table_cache - && !sanitized_table_cache->in_error () - && sanitized_table_cache->has (T::tableTag)) { - return hb_blob_reference (sanitized_table_cache->get (T::tableTag).get ()); + hb_lock_t (accelerator ? &accelerator->sanitized_table_cache_lock : nullptr); + + auto *cache = accelerator ? &accelerator->sanitized_table_cache : sanitized_table_cache; + if (cache + && !cache->in_error () + && cache->has (+T::tableTag)) { + return hb_blob_reference (cache->get (+T::tableTag).get ()); } hb::unique_ptr<hb_blob_t> table_blob {hb_sanitize_context_t ().reference_table<T> (source)}; hb_blob_t* ret = hb_blob_reference (table_blob.get ()); - if (likely (sanitized_table_cache)) - sanitized_table_cache->set (T::tableTag, - std::move (table_blob)); + if (likely (cache)) + cache->set (+T::tableTag, std::move (table_blob)); return ret; } diff --git a/thirdparty/harfbuzz/src/hb-subset.cc b/thirdparty/harfbuzz/src/hb-subset.cc index 6026aa6eff..186b12dbb8 100644 --- a/thirdparty/harfbuzz/src/hb-subset.cc +++ b/thirdparty/harfbuzz/src/hb-subset.cc @@ -82,6 +82,10 @@ using OT::Layout::GPOS; * retain glyph ids option and configure the subset to pass through the layout tables untouched. */ + +hb_user_data_key_t _hb_subset_accelerator_user_data_key = {}; + + /* * The list of tables in the open type spec. Used to check for tables that may need handling * if we are unable to list the tables in a face. @@ -409,20 +413,14 @@ _passthrough (hb_subset_plan_t *plan, hb_tag_t tag) static bool _dependencies_satisfied (hb_subset_plan_t *plan, hb_tag_t tag, - hb_set_t &visited_set, hb_set_t &revisit_set) + const hb_set_t &subsetted_tags, + const hb_set_t &pending_subset_tags) { switch (tag) { case HB_OT_TAG_hmtx: case HB_OT_TAG_vmtx: - if (!plan->pinned_at_default && - !visited_set.has (HB_OT_TAG_glyf)) - { - revisit_set.add (tag); - return false; - } - return true; - + return plan->pinned_at_default || !pending_subset_tags.has (HB_OT_TAG_glyf); default: return true; } @@ -495,12 +493,14 @@ _subset_table (hb_subset_plan_t *plan, } } -static void _attach_accelerator_data (const hb_subset_plan_t* plan, +static void _attach_accelerator_data (hb_subset_plan_t* plan, hb_face_t* face /* IN/OUT */) { - hb_subset_accelerator_t* accel = - hb_subset_accelerator_t::create (*plan->codepoint_to_glyph, - *plan->unicodes); + if (!plan->inprogress_accelerator) return; + + // Transfer the accelerator from the plan to us. + hb_subset_accelerator_t* accel = plan->inprogress_accelerator; + plan->inprogress_accelerator = nullptr; if (accel->in_error ()) { @@ -508,6 +508,11 @@ static void _attach_accelerator_data (const hb_subset_plan_t* plan, return; } + // Populate caches that need access to the final tables. + hb_blob_ptr_t<OT::cmap> cmap_ptr (hb_sanitize_context_t ().reference_table<OT::cmap> (face)); + accel->cmap_cache = OT::cmap::create_filled_cache (cmap_ptr); + accel->destroy_cmap_cache = OT::SubtableUnicodesCache::destroy; + if (!hb_face_set_user_data(face, hb_subset_accelerator_t::user_data_key(), accel, @@ -561,41 +566,63 @@ hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan) return nullptr; } - hb_set_t tags_set, revisit_set; - bool success = true; hb_tag_t table_tags[32]; unsigned offset = 0, num_tables = ARRAY_LENGTH (table_tags); - hb_vector_t<char> buf; - buf.alloc (4096 - 16); + hb_set_t subsetted_tags, pending_subset_tags; while (((void) _get_table_tags (plan, offset, &num_tables, table_tags), num_tables)) { for (unsigned i = 0; i < num_tables; ++i) { hb_tag_t tag = table_tags[i]; - if (_should_drop_table (plan, tag) && !tags_set.has (tag)) continue; - if (!_dependencies_satisfied (plan, tag, tags_set, revisit_set)) continue; - tags_set.add (tag); - success = _subset_table (plan, buf, tag); - if (unlikely (!success)) goto end; + if (_should_drop_table (plan, tag)) continue; + pending_subset_tags.add (tag); + } + + offset += num_tables; + } + + hb_vector_t<char> buf; + buf.alloc (4096 - 16); + + + bool success = true; + + while (!pending_subset_tags.is_empty ()) + { + if (subsetted_tags.in_error () + || pending_subset_tags.in_error ()) { + success = false; + goto end; } - /*delayed subsetting for some tables since they might have dependency on other tables in some cases: - e.g: during instantiating glyf tables, hmetrics/vmetrics are updated and saved in subset plan, - hmtx/vmtx subsetting need to use these updated metrics values*/ - while (!revisit_set.is_empty ()) + bool made_changes = false; + for (hb_tag_t tag : pending_subset_tags) { - hb_set_t revisit_temp; - for (hb_tag_t tag : revisit_set) + if (!_dependencies_satisfied (plan, tag, + subsetted_tags, + pending_subset_tags)) { - if (!_dependencies_satisfied (plan, tag, tags_set, revisit_temp)) continue; - tags_set.add (tag); - success = _subset_table (plan, buf, tag); - if (unlikely (!success)) goto end; + // delayed subsetting for some tables since they might have dependency on other tables + // in some cases: e.g: during instantiating glyf tables, hmetrics/vmetrics are updated + // and saved in subset plan, hmtx/vmtx subsetting need to use these updated metrics values + continue; } - revisit_set = revisit_temp; + + pending_subset_tags.del (tag); + subsetted_tags.add (tag); + made_changes = true; + + success = _subset_table (plan, buf, tag); + if (unlikely (!success)) goto end; + } + + if (!made_changes) + { + DEBUG_MSG (SUBSET, nullptr, "Table dependencies unable to be satisfied. Subset failed."); + success = false; + goto end; } - offset += num_tables; } if (success && plan->attach_accelerator_data) { diff --git a/thirdparty/harfbuzz/src/hb-subset.h b/thirdparty/harfbuzz/src/hb-subset.h index 6a2c5f6114..b83264ea5e 100644 --- a/thirdparty/harfbuzz/src/hb-subset.h +++ b/thirdparty/harfbuzz/src/hb-subset.h @@ -28,6 +28,7 @@ #define HB_SUBSET_H #include "hb.h" +#include "hb-ot.h" HB_BEGIN_DECLS @@ -164,8 +165,6 @@ HB_EXTERN void hb_subset_input_set_flags (hb_subset_input_t *input, unsigned value); -#ifdef HB_EXPERIMENTAL_API -#ifndef HB_NO_VAR HB_EXTERN hb_bool_t hb_subset_input_pin_axis_to_default (hb_subset_input_t *input, hb_face_t *face, @@ -176,16 +175,22 @@ hb_subset_input_pin_axis_location (hb_subset_input_t *input, hb_face_t *face, hb_tag_t axis_tag, float axis_value); -#endif -#endif #ifdef HB_EXPERIMENTAL_API +HB_EXTERN hb_bool_t +hb_subset_input_override_name_table (hb_subset_input_t *input, + hb_ot_name_id_t name_id, + unsigned platform_id, + unsigned encoding_id, + unsigned language_id, + const char *name_str, + int str_len); + +#endif HB_EXTERN hb_face_t * hb_subset_preprocess (hb_face_t *source); -#endif - HB_EXTERN hb_face_t * hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input); diff --git a/thirdparty/harfbuzz/src/hb-ucd-table.hh b/thirdparty/harfbuzz/src/hb-ucd-table.hh index a372a4afce..f7d76eee18 100644 --- a/thirdparty/harfbuzz/src/hb-ucd-table.hh +++ b/thirdparty/harfbuzz/src/hb-ucd-table.hh @@ -1069,7 +1069,7 @@ _hb_ucd_dm2_u64_map[388] = #ifndef HB_OPTIMIZE_SIZE static const uint8_t -_hb_ucd_u8[18260] = +_hb_ucd_u8[17868] = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 11, 12, 13, 13, 13, 14, @@ -1535,191 +1535,166 @@ _hb_ucd_u8[18260] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, 0, 0, 40, 41, 42, 0, 43, 0, - 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, 2, 3, 4, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 0, - 9, 0, 10, 11, 0, 0, 12, 13, 14, 15, 16, 0, 0, 0, 0, 17, - 18, 19, 20, 0, 21, 0, 22, 23, 0, 24, 25, 0, 0, 24, 26, 27, - 0, 24, 26, 0, 0, 24, 26, 0, 0, 24, 26, 0, 0, 0, 26, 0, - 0, 24, 28, 0, 0, 24, 26, 0, 0, 29, 26, 0, 0, 0, 30, 0, - 0, 31, 32, 0, 0, 33, 34, 0, 35, 36, 0, 37, 38, 0, 39, 0, - 0, 40, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 0, 0, 0, 45, 0, - 0, 0, 0, 0, 0, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, - 48, 0, 0, 49, 0, 50, 51, 0, 0, 52, 53, 54, 0, 55, 0, 56, - 0, 57, 0, 0, 0, 0, 58, 59, 0, 0, 0, 0, 0, 0, 60, 61, - 0, 0, 0, 0, 0, 0, 62, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, 66, - 0, 67, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 69, 70, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, - 72, 73, 0, 0, 0, 0, 53, 74, 0, 75, 76, 0, 0, 77, 78, 0, - 0, 0, 0, 0, 0, 79, 80, 81, 0, 0, 0, 0, 0, 0, 0, 26, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, - 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, - 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 0, 86, 0, 0, 0, 0, - 87, 88, 0, 0, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 91, 0, 92, 0, 0, 93, 0, 94, 0, 0, 0, - 0, 0, 72, 95, 0, 96, 0, 0, 97, 98, 0, 77, 0, 0, 99, 0, - 0,100, 0, 0, 0, 0, 0,101, 0,102, 26,103, 0, 0, 0, 0, - 0, 0,104, 0, 0, 0,105, 0, 0, 0, 0, 0, 0, 65,106, 0, - 0, 65, 0, 0, 0,107, 0, 0, 0,108, 0, 0, 0, 0, 0, 0, - 0, 96, 0, 0, 0, 0, 0, 0, 0,109,110, 0, 0, 0, 0, 78, - 0, 44,111, 0,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 65, 0, 0, 0, 0, 0, 0, 0, 0,113, 0,114, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,115, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,116, 0,117, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118, - 0, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120,121,122, 0, 0, - 0, 0,123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 124,125, 0, 0,126, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,127, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,129, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,130, 0, 0, 0,131, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, - 5, 6, 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, - 18, 1, 1, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, - 29, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 31, 0, - 0, 0, 32, 33, 34, 35, 1, 36, 0, 0, 0, 0, 37, 0, 0, 0, - 0, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 0, 0, 0, 0, - 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 43, 36, 44, 45, - 21, 45, 46, 0, 0, 0, 0, 0, 0, 0, 19, 1, 21, 0, 0, 47, - 0, 0, 0, 0, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 52, 1, - 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, - 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, - 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, - 0, 0, 0, 56, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 61, 62, - 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, - 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, - 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, - 0, 0, 0, 0, 0, 69, 70, 0, 0, 0, 0, 0, 71, 72, 73, 74, - 75, 76, 0, 0, 0, 0, 0, 0, 0, 77, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 80, 0, 0, - 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 63, 0, 0, 81, - 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, - 0, 0, 0, 0, 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, - 0, 0, 0, 0, 1, 52, 15, 86, 36, 10, 21, 87, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, - 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 0, - 0, 89, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 0, 78, 0, 0, - 0, 0, 0, 0, 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, - 21, 1, 21, 92, 93, 1, 1, 1, 1, 1, 1, 1, 1, 94, 95, 96, - 0, 0, 0, 0, 97, 1, 98, 58, 81, 99,100, 4, 58, 0, 0, 0, - 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,101,102, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 19, 0, 1, 1, 50, - 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 50, 0, 0, 0, - 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, - 1, 1, 1, 1, 50, 0, 0, 0, 0, 0,104, 68, 0, 0, 0, 0, - 0, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 78, 0, 0, 0, - 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105,106, 58, 38, - 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, - 0, 0, 0, 0, 0, 0, 0,107, 1, 14, 4, 12, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 47, 84, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,109, 61, 0,110, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 19, 58, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 51, 0,111, 14, 52, 84, 0, 0, 0, - 112, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 61, - 0, 0, 0, 0, 0, 0,113, 0, 87, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 78, 55, 0, 38, 1, 58, 1, 58, 0, 0, - 63, 89, 0, 0, 0, 0, 0, 59,115, 0, 0, 0, 0, 0, 0, 0, - 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,115, 0, 0, - 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, - 78, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 61, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 8, 91, 0, 0, 0, 0, 0, 0, 1, 87, 0, 0, - 0, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, - 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, 0, 0, 0, 0, - 0, 0, 38, 50, 0, 0, 0, 0, 38, 58, 0, 0, 0, 0, 0, 0, - 1, 87, 1, 1, 1, 1, 39, 1, 48,105, 87, 0, 0, 0, 0, 0, - 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,123, 0, 0, 0, 0, - 0, 0, 0, 0, 4,122, 0, 0, 0, 1,124, 0, 0, 0, 0, 0, - 0, 0, 0, 0,230,230,230,230,230,232,220,220,220,220,232,216, - 220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220, - 1, 1, 1, 1, 1,220,220,220,220,230,230,230,230,240,230,220, - 220,220,230,230,230,220,220, 0,230,230,230,220,220,220,220,230, - 232,220,220,230,233,234,234,233,234,234,233,230, 0, 0, 0,230, - 0,220,230,230,230,230,220,230,230,230,222,220,230,230,220,220, - 230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, - 21, 22, 0, 23, 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0, - 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230, - 220,230,230,220, 35, 0, 0, 0, 0, 0,230,230,230, 0, 0,230, - 230, 0,220,230,230,220, 0, 0, 0, 36, 0, 0,230,220,230,230, - 220,220,230,220,220,230,220,230,220,230,230, 0, 0,220, 0, 0, - 230,230, 0,230, 0,230,230,230,230,230, 0, 0, 0,220,220,220, - 230,220,220,220,230,230, 0,220, 27, 28, 29,230, 7, 0, 0, 0, - 0, 9, 0, 0, 0,230,220,230,230, 0, 0, 0, 0, 0,230, 0, - 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 9, 0, - 103,103, 9, 0,107,107,107,107,118,118, 9, 0,122,122,122,122, - 220,220, 0, 0, 0,220, 0,220, 0,216, 0, 0, 0,129,130, 0, - 132, 0, 0, 0, 0, 0,130,130,130,130, 0, 0,130, 0,230,230, - 9, 0,230,230, 0, 0,220, 0, 0, 0, 0, 7, 0, 9, 9, 0, - 9, 9, 0, 0, 0,230, 0, 0, 0,228, 0, 0, 0,222,230,220, - 220, 0, 0, 0,230, 0, 0,220,230,220, 0,220,230,230,230, 0, - 0, 0, 9, 9, 0, 0, 7, 0,230, 0, 1, 1, 1, 0, 0, 0, - 230,234,214,220,202,230,230,230,230,230,232,228,228,220,218,230, - 233,220,230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230, - 220,230, 1, 1, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0, - 0, 0, 0,220,230, 0,230,230,220, 0, 0,230, 0, 0, 26, 0, - 0,220, 0,230,230, 1,220, 0, 0,230,220, 0, 0, 0,220,220, - 0, 0,230,220, 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 9, 7, - 6, 6, 0, 0, 0, 0, 1, 0, 0,216,216, 1, 1, 1, 0, 0, - 0,226,216,216,216,216,216, 0,220,220,220, 0,232,232,220,230, - 230,230, 7, 0, 16, 17, 17, 17, 17, 17, 17, 33, 17, 17, 17, 19, - 17, 17, 17, 17, 20,101, 17,113,129,169, 17, 27, 28, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, + 0, 0, 3, 0, 0, 0, 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, + 12, 13, 14, 15, 16, 17, 16, 18, 16, 19, 16, 19, 16, 19, 0, 19, + 16, 20, 16, 19, 21, 19, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, + 0, 0, 0, 0, 34, 0, 0, 35, 0, 0, 36, 0, 37, 0, 0, 0, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 0, 0, 47, 0, 0, 0, 48, + 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 52, + 53, 0, 54, 0, 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, 0, 0, + 58, 0, 0, 59, 60, 61, 62, 63, 0, 0, 64, 65, 0, 0, 0, 66, + 0, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 70, 0, 71, 0, 0, + 72, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, + 0, 0, 75, 76, 0, 77, 78, 0, 0, 79, 80, 0, 81, 62, 0, 82, + 83, 0, 0, 84, 85, 86, 0, 0, 0, 87, 0, 88, 0, 0, 51, 89, + 51, 0, 90, 0, 91, 0, 0, 0, 80, 0, 0, 0, 92, 93, 0, 94, + 95, 96, 97, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 98, 99, 0, + 0, 0, 0, 0, 0,100, 0, 0, 0, 0, 0,101,102, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,103, 0, 0,104, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,105,106, 0, 0,107, 0, 0, 0, 0, 0, 0, + 108, 0,109, 0,102, 0, 0, 0, 0, 0,110,111, 0, 0, 0, 0, + 0, 0, 0,112, 0, 0, 0, 0, 0, 0, 0,113, 0,114, 0, 0, + 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 8, 0, 0, 0, + 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, 14, 15, 0, 16, + 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, 0, 0, 22, 23, + 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, 28, 29, 30, 31, + 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, 33, 0, 0, 0, + 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, 0, 0, 39, + 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 43, 0, 44, + 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 48, + 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, 0, 53, 0, 0, + 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, 0, 0, 57, 58, + 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, 52, 0, 62, 63, + 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, 0, 68, 69, 70, + 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, 0, 0, 0, 79, + 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, 0, 0, 77, 82, + 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, 52, 0, 1, 78, + 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, 57, 0, 0, 0, + 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, 0, 91, 0, 0, + 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, 0, 0, 0, 94, + 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99, 0, + 0, 0, 0,100,101, 93, 0, 0,102, 0, 0, 0, 84, 0, 0,103, + 0, 0, 0,104,105, 0, 0,106,107, 0, 0, 0, 0, 0, 0,108, + 0, 0,109, 0, 0, 0, 0,110, 33, 0,111,112,113, 35, 0, 0, + 114, 0, 0, 0,115, 0, 0, 0, 0, 0, 0,116, 0, 0,117, 0, + 0, 0, 0,118, 88, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 52, + 119, 0, 0, 0, 0,120, 0, 0,121, 0, 0, 0, 0,119, 0, 0, + 122, 0, 0, 0, 0, 0, 0,123, 0, 0, 0,124, 0, 0, 0,125, + 0,126, 0, 0, 0, 0,127,128,129, 0,130, 0,131, 0, 0, 0, + 132,133,134, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,135, 0, + 0, 0,136, 0, 0,137, 0, 0,138, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, 4, 8, 9, 10, + 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, 19, 1, 0, 0, + 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, 29, 30, 0, 0, + 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, 37, 0, 0, 0, + 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, 43, 36, 44, 45, + 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, 0, 38, 48, 1, + 1, 49, 49, 50, 0, 0, 51, 0, 0, 0, 52, 1, 0, 0, 38, 14, + 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, 0, 0, 0, 55, + 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, 0, 60, 0, 0, + 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, 0, 0, 65, 0, + 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 69, 70, 0, + 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, 0, 78, 79, 0, + 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, 0, 62, 0, 0, + 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, 0, 19, 84, 0, + 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, 36, 10, 21, 87, + 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, 88, 0, + 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, 87, 9, 12, 4, + 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, 93, 1, 1, 1, + 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, 58, 0, 0, 0, + 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, 0, 0,101,102, + 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, 0, 63, 0, 0, + 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, 78, 0, 0, 0, + 105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, 1, 14, 4, 12, + 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, 0, 0,109, 61, + 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 19, 58, 0, 0, 0, 51, + 0,111, 14, 52,112, 41, 0, 0, 62, 0, 0, 61, 0, 0,113, 0, + 87, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, 0,113, 0, 0, + 0, 0,114, 0, 0, 0, 78, 55, 0, 38, 1, 58, 1, 58, 0, 0, + 63, 89, 0, 0,115, 0, 0, 0, 55, 0, 0, 0, 0,115, 0, 0, + 0, 0, 61, 0, 0, 0, 0, 79, 0, 61, 0, 0, 0, 0, 56, 0, + 89, 80, 0, 0, 79, 0, 0, 0, 8, 91, 0, 0, 1, 87, 0, 0, + 116, 0, 0, 0, 0, 0, 0,117, 0,118,119,120,121, 0,104, 4, + 122, 49, 23, 0, 0, 0, 38, 50, 38, 58, 0, 0, 1, 87, 1, 1, + 1, 1, 39, 1, 48,105, 87, 0, 0, 0, 0, 1, 0, 0, 0,123, + 4,122, 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230, + 230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220, + 220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220, + 220,230,230,230,230,240,230,220,220,220,230,230,230,220,220, 0, + 230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233, + 234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230, + 230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0, + 230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, + 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0, + 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0, + 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230,220,230, + 220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230, + 230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220, + 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230, + 230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, + 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107, + 118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220, + 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130, + 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, + 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, + 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220, + 230,220, 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0, + 230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230, + 230,230,232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, + 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228, + 232,222,224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230, + 220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, + 0,230,220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, + 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, + 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0, + 220,220,220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 17, + 17, 17, 17, 33, 17, 17, 17, 19, 17, 17, 17, 17, 20,101, 17,113, + 129,169, 17, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17,237, 0, 1, 2, 2, 0, 3, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 0, 0, 0, 0, 6, 7, 8, 9, 0, 0, 0, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, - 0, 0, 21, 22, 0, 0, 0, 0, 23, 24, 25, 26, 0, 27, 0, 28, - 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 33, 34, 35, 36, 0, - 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, - 0, 0, 0, 0, 1, 2, 40, 41, 0, 1, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, - 0, 0, 3, 4, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, - 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, - 0, 0, 10, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 11, 12, - 0, 13, 0, 14, 15, 16, 0, 0, 0, 0, 0, 1, 17, 18, 0, 19, - 7, 1, 0, 0, 0, 20, 20, 7, 20, 20, 20, 20, 20, 20, 20, 8, - 21, 0, 22, 0, 7, 23, 24, 0, 20, 20, 25, 0, 0, 0, 26, 27, - 1, 7, 20, 20, 20, 20, 20, 1, 28, 29, 30, 31, 0, 0, 20, 0, - 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 20, 20, - 20, 1, 0, 0, 8, 21, 32, 4, 0, 10, 0, 33, 7, 20, 20, 20, - 0, 0, 0, 0, 8, 34, 34, 35, 36, 34, 37, 0, 38, 1, 20, 20, - 0, 0, 39, 0, 1, 1, 0, 8, 21, 1, 20, 0, 0, 0, 1, 0, - 0, 40, 1, 1, 0, 0, 8, 21, 0, 1, 0, 1, 0, 1, 0, 0, - 0, 0, 26, 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 7, 20, 41, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 0, 42, 43, 44, 0, 45, - 0, 8, 21, 0, 0, 0, 0, 0, 0, 0, 0, 46, 7, 1, 10, 1, - 0, 0, 0, 1, 20, 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 26, 34, 9, 0, 0, 20, 20, 1, 20, 20, 0, 0, 0, 0, 0, - 0, 0, 26, 21, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, - 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 9, 10, 11, 11, 11, 11, 12, 13, 13, 13, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 13, 22, 13, 13, 13, 13, 23, 24, 24, 25, 26, 13, 13, - 13, 27, 28, 29, 13, 30, 31, 32, 33, 34, 35, 36, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 13, 42, 7, 7, 43, 7, - 44, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,237, 0, 1, 2, 2, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 6, 7, 8, + 9, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 21, 22, 0, 0, 0, 0, + 23, 24, 25, 26, 0, 27, 0, 28, 29, 30, 31, 32, 0, 0, 0, 0, + 0, 0, 0, 33, 34, 35, 36, 0, 0, 0, 0, 0, 37, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, 1, 2, 40, 41, + 0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 5, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, + 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 0, 0, 0, 11, 12, 0, 13, 0, 14, 15, 16, 0, 0, + 0, 0, 0, 1, 17, 18, 0, 19, 7, 1, 0, 0, 0, 20, 20, 7, + 20, 20, 20, 20, 20, 20, 20, 8, 21, 0, 22, 0, 7, 23, 24, 0, + 20, 20, 25, 0, 0, 0, 26, 27, 1, 7, 20, 20, 20, 20, 20, 1, + 28, 29, 30, 31, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 10, 0, + 0, 0, 0, 0, 0, 0, 20, 20, 20, 1, 0, 0, 8, 21, 32, 4, + 0, 10, 0, 33, 7, 20, 20, 20, 0, 0, 0, 0, 8, 34, 34, 35, + 36, 34, 37, 0, 38, 1, 20, 20, 0, 0, 39, 0, 1, 1, 0, 8, + 21, 1, 20, 0, 0, 0, 1, 0, 0, 40, 1, 1, 0, 0, 8, 21, + 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 26, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 21, 7, 20, 41, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 21, 0, 42, 43, 44, 0, 45, 0, 8, 21, 0, 0, 0, 0, 0, + 0, 0, 0, 46, 7, 1, 10, 1, 0, 0, 0, 1, 20, 20, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 34, 9, 0, 0, 20, 20, + 1, 20, 20, 0, 0, 0, 0, 0, 0, 0, 26, 21, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 47, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 11, 11, 11, 11, 12, 13, + 13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 13, 22, 13, 13, 13, + 13, 23, 24, 24, 25, 26, 13, 13, 13, 27, 28, 29, 13, 30, 31, 32, + 33, 34, 35, 36, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 37, 7, 38, 39, 7, 40, 7, 7, + 7, 41, 13, 42, 7, 7, 43, 7, 44, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, @@ -1740,420 +1715,420 @@ _hb_ucd_u8[18260] = 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 45, 0, 0, 1, - 2, 2, 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, 32, 33, 34, 35, 36, 37, 37, 37, 37, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 2, 2, 53, 54, 55, 56, - 57, 58, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 61, 61, - 59, 59, 59, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 59, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 45, 0, 0, 1, 2, 2, 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, 32, 33, 34, 35, 36, 37, 37, + 37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 2, 2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59, + 59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 59, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 79, 70, 70, 70, 70, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 81, 82, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 79, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, + 82, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 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, 95, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 70, 70, 97, 98, 99,100,101,101,102,103,104,105,106,107,108,109, - 110,111, 96,112,113,114,115,116,117,118,119,119,120,121,122,123, - 124,125,126,127,128,129,130,131,132, 96,133,134,135,136,137,138, - 139,140,141,142,143, 96,144,145, 96,146,147,148,149, 96,150,151, - 152,153,154,155,156, 96,157,158,159,160, 96,161,162,163,164,164, - 164,164,164,164,164,165,166,164,167, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,168,169,169, - 169,169,169,169,169,169,170, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96,171,171,171,171,172, 96, 96, 96,173,173, - 173,173,174,175,176,177, 96, 96, 96, 96,178,179,180,181,182,182, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, 97, 98, 99,100,101,101, + 102,103,104,105,106,107,108,109,110,111, 96,112,113,114,115,116, + 117,118,119,119,120,121,122,123,124,125,126,127,128,129,130,131, + 132, 96,133,134,135,136,137,138,139,140,141,142,143, 96,144,145, + 96,146,147,148,149, 96,150,151,152,153,154,155,156, 96,157,158, + 159,160, 96,161,162,163,164,164,164,164,164,164,164,165,166,164, + 167, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96,168,169,169,169,169,169,169,169,169,170, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,171,171, + 171,171,172, 96, 96, 96,173,173,173,173,174,175,176,177, 96, 96, + 96, 96,178,179,180,181,182,182,182,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, - 182,182,182,182,182,182,182,182,182,182,182,182,182,183,182,182, - 182,182,182,182,184,184,184,185,186, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,187,188,189, - 190,191,191,192, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96,193,194, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,195,196, 59,197, - 198,199,200,201,202, 96,203,204,205, 59, 59,206, 59,207,208,208, - 208,208,208,209, 96, 96, 96, 96, 96, 96, 96, 96,210, 96,211,212, - 213, 96, 96,214, 96, 96, 96,215, 96, 96, 96, 96, 96,216,217,218, - 219, 96, 96, 96, 96, 96,220,221,222, 96,223,224, 96, 96,225,226, - 59,227,228, 96, 59, 59, 59, 59, 59, 59, 59,229,230,231,232,233, - 59, 59,234,235, 59,236, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,237, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,238, 70,239, 70, + 182,182,182,182,182,183,182,182,182,182,182,182,184,184,184,185, + 186, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96,187,188,189,190,191,191,192, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,193,194, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96,195,196, 59,197,198,199,200,201,202, 96,203,204, + 205, 59, 59,206, 59,207,208,208,208,208,208,209, 96, 96, 96, 96, + 96, 96, 96, 96,210, 96,211,212,213, 96, 96,214, 96, 96, 96,215, + 96, 96, 96, 96, 96,216,217,218,219, 96, 96, 96, 96, 96,220,221, + 222, 96,223,224, 96, 96,225,226, 59,227,228, 96, 59, 59, 59, 59, + 59, 59, 59,229,230,231,232,233, 59, 59,234,235, 59,236, 96, 96, + 96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70,237, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70,238, 70,239, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,240, 70, 70, 70, 70, - 70, 70, 70, 70, 70,241, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, - 70, 70,242, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, - 70, 70, 70, 70,243, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70,244, 96, 96, 96, 96, 96, 96, 96, 96,245, 96, - 246,247, 0, 1, 2, 2, 0, 1, 2, 2, 2, 3, 4, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, - 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, 0, - 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, - 26, 26, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, - 9, 9, 0, 9, 9, 9, 2, 2, 9, 9, 9, 9, 0, 9, 2, 2, - 2, 2, 9, 0, 9, 0, 9, 9, 9, 2, 9, 2, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 6, 2, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 2, 4, 4, 4, 2, 2, 4, 4, 4, 2, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2, - 2, 2, 2, 2, 2, 2, 14, 14, 14, 2, 2, 2, 2, 14, 14, 14, - 14, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, - 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 0, 3, 3, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, - 3, 3, 3, 3, 3, 3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 2, 37, 37, 37, 37, 2, 2, 37, 37, 37, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 2, 2, 2, 2, 2, 2, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90, - 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 2, 2, 95, 2, 37, 37, 37, 2, 2, 2, 2, 2, 3, 3, - 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 2, 2, 2, 2, 3, 3, - 0, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, - 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 5, 5, - 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2, - 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, - 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5, - 2, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 2, 2, 2, - 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 5, 5, 2, 5, 5, 5, - 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 11, - 11, 11, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, - 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, - 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, - 2, 2, 11, 2, 11, 11, 11, 2, 2, 11, 11, 11, 2, 2, 2, 11, - 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, 2, 11, 2, 2, 2, - 2, 2, 2, 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 2, 10, - 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, - 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, - 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, 10, - 2, 2, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 2, 2, 10, 2, - 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, - 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 2, 21, - 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, - 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, - 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 2, 21, 21, 21, 21, 21, - 2, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 2, 2, 2, 2, - 2, 2, 2, 21, 21, 21, 2, 2, 2, 2, 21, 21, 2, 21, 21, 21, - 21, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, - 22, 2, 2, 2, 22, 22, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, - 22, 2, 22, 2, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 2, 2, 2, 2, 22, 22, 22, 2, - 2, 2, 2, 2, 2, 22, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, - 22, 2, 2, 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23, - 2, 2, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 2, - 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 23, 2, 2, 23, 23, - 23, 23, 2, 2, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 2, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 16, - 2, 2, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 2, 2, - 2, 2, 2, 16, 16, 2, 16, 16, 16, 16, 2, 2, 16, 16, 2, 16, - 16, 16, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 2, 20, 20, 20, 2, 20, 20, 20, 20, 20, 20, 2, 2, - 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 2, 2, 20, 20, 2, 36, - 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36, 36, - 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, 2, - 36, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, - 2, 2, 2, 2, 36, 36, 2, 2, 36, 36, 36, 2, 2, 2, 2, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 2, 2, 2, 2, 0, 24, 24, 24, 24, 2, 2, 2, 2, 2, 18, - 18, 2, 18, 2, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, - 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, - 18, 18, 18, 18, 18, 2, 18, 18, 2, 2, 18, 18, 18, 18, 25, 25, - 25, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 2, 2, 2, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, - 25, 25, 25, 0, 0, 0, 0, 25, 25, 2, 2, 2, 2, 2, 33, 33, - 33, 33, 33, 33, 33, 33, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 2, 8, 2, 2, 2, 2, 2, 8, 2, 2, 8, 8, - 8, 0, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, - 30, 30, 30, 30, 30, 2, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, - 30, 30, 30, 2, 2, 2, 30, 30, 2, 2, 2, 2, 2, 2, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 2, 2, 28, 28, - 28, 28, 28, 28, 28, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 2, 2, 2, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 0, 0, 0, 35, 35, 35, 2, 2, 2, 2, 2, 2, 2, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 0, 0, 2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 2, 2, 2, 2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 2, 46, 46, 46, 2, 46, 46, 2, 2, 2, 2, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 2, 2, 31, 31, - 2, 2, 2, 2, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 2, 2, 2, 2, 2, 2, 32, 2, - 2, 2, 2, 2, 2, 2, 32, 32, 32, 2, 2, 2, 2, 2, 28, 28, - 28, 28, 28, 28, 2, 2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 2, 48, 48, 48, 48, 2, 2, 2, 2, 48, 2, - 2, 2, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 2, 2, 52, 52, 52, 52, 52, 2, 2, 2, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 2, 2, 2, 2, 58, 58, - 2, 2, 2, 2, 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 2, 2, 54, 54, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 2, 91, 91, - 91, 91, 91, 2, 2, 91, 91, 91, 2, 2, 2, 2, 2, 2, 91, 91, - 91, 91, 91, 91, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 2, 2, 2, 62, 62, - 62, 62, 62, 62, 62, 2, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 2, 2, 2, 2, 2, 2, - 2, 2, 93, 93, 93, 93, 70, 70, 70, 70, 70, 70, 70, 70, 2, 2, - 2, 70, 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 73, 73, - 73, 73, 73, 73, 73, 73, 6, 2, 2, 2, 2, 2, 2, 2, 8, 8, - 8, 2, 2, 8, 8, 8, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 1, 1, 0, 2, 2, 2, 2, 2, 19, 19, - 19, 19, 19, 19, 9, 9, 9, 9, 9, 6, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 9, 9, 9, 9, - 9, 19, 19, 19, 19, 19, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, 9, 9, 2, 2, 2, 9, - 2, 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, - 9, 9, 2, 2, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 2, 2, - 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 19, - 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, - 0, 0, 0, 0, 0, 2, 19, 19, 19, 19, 19, 2, 2, 2, 0, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 19, 19, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 19, 0, 19, 0, 0, 0, 2, 2, 2, 2, 0, 0, - 0, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, - 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 56, 56, - 56, 56, 56, 56, 56, 56, 55, 55, 55, 55, 2, 2, 2, 2, 2, 55, - 55, 55, 55, 55, 55, 55, 61, 61, 61, 61, 61, 61, 61, 61, 2, 2, - 2, 2, 2, 2, 2, 61, 61, 2, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 0, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 13, 13, - 13, 13, 13, 13, 2, 2, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 13, 0, 13, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 1, 1, 1, 1, 12, 12, 13, 13, 13, 13, 0, 0, 0, 0, 2, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 2, 2, 1, 1, 0, 0, 15, 15, 15, 0, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 0, 0, 17, 17, 17, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 2, 12, 12, 12, 12, 12, 12, 12, 0, 17, 17, - 17, 17, 17, 17, 17, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 2, 86, 86, - 86, 86, 86, 86, 86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, - 77, 77, 2, 2, 2, 2, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, - 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, - 19, 2, 2, 2, 2, 2, 19, 19, 2, 19, 2, 19, 19, 19, 19, 19, - 2, 2, 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 2, 2, 2, 0, 0, - 2, 2, 2, 2, 2, 2, 65, 65, 65, 65, 65, 65, 65, 65, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, - 2, 2, 2, 2, 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 0, 69, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 74, 12, 12, 12, 12, 12, 2, 2, 2, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 2, 0, 84, 84, - 2, 2, 2, 2, 84, 84, 33, 33, 33, 33, 33, 33, 33, 2, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 68, 68, - 68, 68, 68, 68, 2, 2, 68, 68, 2, 2, 68, 68, 68, 68, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 2, 2, 2, 2, 2, 2, 2, - 2, 92, 92, 92, 92, 92, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 2, 2, 30, 30, 30, 30, 30, 30, 2, 19, 19, - 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 19, 19, 19, 19, - 0, 0, 2, 2, 2, 2, 87, 87, 87, 87, 87, 87, 2, 2, 87, 87, - 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, - 2, 12, 12, 12, 12, 12, 13, 13, 2, 2, 2, 2, 2, 2, 19, 19, - 19, 19, 19, 19, 19, 2, 2, 2, 2, 4, 4, 4, 4, 4, 2, 2, - 2, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 14, 14, - 14, 14, 14, 2, 14, 2, 14, 14, 2, 14, 14, 2, 14, 14, 3, 3, - 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 0, 0, 2, 2, 3, 3, 3, 3, 3, 3, 2, 2, - 2, 2, 2, 2, 2, 3, 1, 1, 1, 1, 1, 1, 6, 6, 0, 0, - 0, 2, 0, 0, 0, 0, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, - 3, 3, 3, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 2, 2, - 12, 12, 12, 12, 12, 12, 2, 2, 12, 12, 12, 2, 2, 2, 2, 0, - 0, 0, 0, 0, 2, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, - 49, 2, 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 2, 2, 49, 49, - 49, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, - 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 1, 2, 2, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 2, 2, 2, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 2, 2, 2, 2, 2, 2, 2, 1, 0, - 0, 0, 0, 0, 0, 0, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 2, 2, 2, 2, 2, 2, 2, 2, 2, 42, 42, 42, 41, 41, - 41, 41, 41, 41, 41, 41, 41, 41, 41, 2, 2, 2, 2, 2,118,118, - 118,118,118,118,118,118,118,118,118, 2, 2, 2, 2, 2, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 2, 53, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2, 2, 2, 2, 59, 59, - 59, 59, 59, 59, 2, 2, 40, 40, 40, 40, 40, 40, 40, 40, 51, 51, - 51, 51, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 2, 2, 50, 50, 2, 2, 2, 2, 2, 2,135,135, - 135,135,135,135,135,135,135,135,135,135, 2, 2, 2, 2,106,106, - 106,106,106,106,106,106,104,104,104,104,104,104,104,104,104,104, - 104,104, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,104,161,161, - 161,161,161,161,161,161,161,161,161, 2,161,161,161,161,161,161, - 161, 2,161,161, 2,161,161,161, 2,161,161,161,161,161,161,161, - 2,161,161, 2, 2, 2,110,110,110,110,110,110,110,110,110,110, - 110,110,110,110,110, 2,110,110,110,110,110,110, 2, 2, 19, 19, - 19, 19, 19, 19, 2, 19, 19, 2, 19, 19, 19, 19, 19, 19, 47, 47, - 47, 47, 47, 47, 2, 2, 47, 2, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 2, 47, 47, 2, - 2, 2, 47, 2, 2, 47, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 2, 81,120,120,120,120,120,120,120,120,116,116, - 116,116,116,116,116,116,116,116,116,116,116,116,116, 2, 2, 2, - 2, 2, 2, 2, 2,116,128,128,128,128,128,128,128,128,128,128, - 128, 2,128,128, 2, 2, 2, 2, 2,128,128,128,128,128, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 2, 2, 2, 66, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 2, 2, 2, 2, 2, 72, 98, 98, - 98, 98, 98, 98, 98, 98, 97, 97, 97, 97, 97, 97, 97, 97, 2, 2, - 2, 2, 97, 97, 97, 97, 2, 2, 97, 97, 97, 97, 97, 97, 57, 57, - 57, 57, 2, 57, 57, 2, 2, 2, 2, 2, 57, 57, 57, 57, 57, 57, - 57, 57, 2, 57, 57, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 57, 57, - 57, 2, 2, 2, 2, 57, 57, 2, 2, 2, 2, 2, 2, 2, 88, 88, - 88, 88, 88, 88, 88, 88,117,117,117,117,117,117,117,117,112,112, - 112,112,112,112,112,112,112,112,112,112,112,112,112, 2, 2, 2, - 2,112,112,112,112,112, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 2, 2, 2, 78, 78, 78, 78, 78, 78, 78, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 2, 2, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 2, 2, 2, 2, 2,122,122, - 122,122,122,122,122,122,122,122, 2, 2, 2, 2, 2, 2, 2,122, - 122,122,122, 2, 2, 2, 2,122,122,122,122,122,122,122, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 2, 2, 2, 2, 2, 2, 2,130,130, - 130,130,130,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, - 130,130,130,130,130,130,144,144,144,144,144,144,144,144,144,144, - 2, 2, 2, 2, 2, 2,156,156,156,156,156,156,156,156,156,156, - 2,156,156,156, 2, 2,156,156, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 3, 3, 3,147,147,147,147,147,147,147,147,148,148, - 148,148,148,148,148,148,148,148, 2, 2, 2, 2, 2, 2,158,158, - 158,158,158,158,158,158,158,158, 2, 2, 2, 2, 2, 2,153,153, - 153,153,153,153,153,153,153,153,153,153, 2, 2, 2, 2,149,149, - 149,149,149,149,149,149,149,149,149,149,149,149,149, 2, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, - 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, 2, 2, 2, 94, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 85, 2, 2,101,101,101,101,101,101,101,101,101, 2, - 2, 2, 2, 2, 2, 2,101,101, 2, 2, 2, 2, 2, 2, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 2, 96, 96,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111, 2,100,100, - 100,100,100,100,100,100, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 2, 2, 2,108,108,108,108,108,108,108,108,108,108, - 2,108,108,108,108,108,108,108, 2, 2, 2, 2, 2, 2,129,129, - 129,129,129,129,129, 2,129, 2,129,129,129,129, 2,129,129,129, - 129,129,129,129,129,129,129,129,129,129,129,129, 2,129,129,129, - 2, 2, 2, 2, 2, 2,109,109,109,109,109,109,109,109,109,109, - 109, 2, 2, 2, 2, 2,109,109, 2, 2, 2, 2, 2, 2,107,107, - 107,107, 2,107,107,107,107,107,107,107,107, 2, 2,107,107, 2, - 2,107,107,107,107,107,107,107,107,107,107,107,107,107,107, 2, - 107,107,107,107,107,107,107, 2,107,107, 2,107,107,107,107,107, - 2, 1,107,107,107,107,107, 2, 2,107,107,107, 2, 2,107, 2, - 2, 2, 2, 2, 2,107, 2, 2, 2, 2, 2,107,107,107,107,107, - 107,107, 2, 2,107,107,107,107,107,107,107, 2, 2, 2,137,137, - 137,137,137,137,137,137,137,137,137,137, 2,137,137,137,137,137, - 2, 2, 2, 2, 2, 2,124,124,124,124,124,124,124,124,124,124, - 2, 2, 2, 2, 2, 2,123,123,123,123,123,123,123,123,123,123, - 123,123,123,123, 2, 2,114,114,114,114,114,114,114,114,114,114, - 114,114,114, 2, 2, 2,114,114, 2, 2, 2, 2, 2, 2, 32, 32, - 32, 32, 32, 2, 2, 2,102,102,102,102,102,102,102,102,102,102, - 2, 2, 2, 2, 2, 2,126,126,126,126,126,126,126,126,126,126, - 126, 2, 2,126,126,126,126,126,126,126, 2, 2, 2, 2,126,126, - 126,126,126,126,126, 2,142,142,142,142,142,142,142,142,142,142, - 142,142, 2, 2, 2, 2,125,125,125,125,125,125,125,125,125,125, - 125, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,125,154,154, - 154,154,154,154,154, 2, 2,154, 2, 2,154,154,154,154,154,154, - 154,154, 2,154,154, 2,154,154,154,154,154,154,154,154,154,154, - 154,154,154,154, 2,154,154, 2, 2,154,154,154,154,154,154,154, - 2, 2, 2, 2, 2, 2,150,150,150,150,150,150,150,150, 2, 2, - 150,150,150,150,150,150,150,150,150,150,150, 2, 2, 2,141,141, - 141,141,141,141,141,141,140,140,140,140,140,140,140,140,140,140, - 140, 2, 2, 2, 2, 2,121,121,121,121,121,121,121,121,121, 2, - 2, 2, 2, 2, 2, 2, 7, 7, 2, 2, 2, 2, 2, 2,133,133, - 133,133,133,133,133,133,133, 2,133,133,133,133,133,133,133,133, - 133,133,133,133,133, 2,133,133,133,133,133,133, 2, 2,133,133, - 133,133,133, 2, 2, 2,134,134,134,134,134,134,134,134, 2, 2, - 134,134,134,134,134,134, 2,134,134,134,134,134,134,134,134,134, - 134,134,134,134,134, 2,138,138,138,138,138,138,138, 2,138,138, - 2,138,138,138,138,138,138,138,138,138,138,138,138,138, 2, 2, - 138, 2,138,138, 2,138,138,138, 2, 2, 2, 2, 2, 2,143,143, - 143,143,143,143, 2,143,143, 2,143,143,143,143,143,143,143,143, - 143,143,143,143,143,143,143,143,143,143,143,143,143, 2,143,143, - 2,143,143,143,143,143,143, 2, 2, 2, 2, 2, 2, 2,143,143, - 2, 2, 2, 2, 2, 2,145,145,145,145,145,145,145,145,145, 2, - 2, 2, 2, 2, 2, 2,163,163,163,163,163,163,163,163,163, 2, - 163,163,163,163,163,163,163,163,163, 2, 2, 2,163,163,163,163, - 2, 2, 2, 2, 2, 2, 86, 2, 2, 2, 2, 2, 2, 2, 22, 22, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 2, 2, 2, 2, 2, 2, 63, 63, - 63, 63, 63, 63, 63, 2, 63, 63, 63, 63, 63, 2, 2, 2, 63, 63, - 63, 63, 2, 2, 2, 2,157,157,157,157,157,157,157,157,157,157, - 157, 2, 2, 2, 2, 2, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 2, 2,127,127,127,127,127,127,127,127,127,127, - 127,127,127,127,127, 2, 79, 2, 2, 2, 2, 2, 2, 2,115,115, - 115,115,115,115,115,115,115,115,115,115,115,115,115, 2,115,115, - 2, 2, 2, 2,115,115,159,159,159,159,159,159,159,159,159,159, - 159,159,159,159,159, 2,159,159, 2, 2, 2, 2, 2, 2,103,103, - 103,103,103,103,103,103,103,103,103,103,103,103, 2, 2,119,119, - 119,119,119,119,119,119,119,119,119,119,119,119, 2, 2,119,119, - 2,119,119,119,119,119, 2, 2, 2, 2, 2,119,119,119,146,146, - 146,146,146,146,146,146,146,146,146, 2, 2, 2, 2, 2, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 99, 2, 2, - 2, 2, 2, 2, 2, 99,136,139, 13, 13,155, 2, 2, 2,136,136, - 136,136,136,136,136,136,155,155,155,155,155,155,155,155,155,155, - 155,155,155,155, 2, 2,136, 2, 2, 2, 2, 2, 2, 2, 17, 17, - 17, 17, 2, 17, 17, 17, 17, 17, 17, 17, 2, 17, 17, 2, 17, 15, - 15, 15, 15, 15, 15, 15, 17, 17, 17, 2, 2, 2, 2, 2, 2, 2, - 15, 2, 2, 2, 2, 2, 15, 15, 15, 2, 2, 17, 2, 2, 2, 2, - 2, 2, 17, 17, 17, 17,139,139,139,139,139,139,139,139,139,139, - 139,139, 2, 2, 2, 2,105,105,105,105,105,105,105,105,105,105, - 105, 2, 2, 2, 2, 2,105,105,105,105,105, 2, 2, 2,105, 2, - 2, 2, 2, 2, 2, 2,105,105, 2, 2,105,105,105,105, 1, 1, - 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 2, 2, 0, 2, 2, 0, 0, 2, 2, 0, - 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, - 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, - 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 2, 2, 2, - 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,131,131, - 131,131,131,131,131,131,131,131,131,131, 2, 2, 2, 2, 2, 2, - 2,131,131,131,131,131, 2,131,131,131,131,131,131,131, 2, 2, - 2, 2, 2, 19, 19, 19, 56, 56, 56, 56, 56, 56, 56, 2, 56, 2, - 2, 56, 56, 56, 56, 56, 56, 56, 2, 56, 56, 2, 56, 56, 56, 56, - 56, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 6,151,151,151,151,151,151,151,151,151,151, - 151,151,151, 2, 2, 2,151,151,151,151,151,151, 2, 2,151,151, - 2, 2, 2, 2,151,151,160,160,160,160,160,160,160,160,160,160, - 160,160,160,160,160, 2,152,152,152,152,152,152,152,152,152,152, - 2, 2, 2, 2, 2,152,164,164,164,164,164,164,164,164,164,164, - 2, 2, 2, 2, 2, 2, 30, 30, 30, 30, 2, 30, 30, 2,113,113, - 113,113,113,113,113,113,113,113,113,113,113, 2, 2,113,113,113, - 113,113,113,113,113, 2,132,132,132,132,132,132,132,132,132,132, - 132,132, 2, 2, 2, 2,132,132, 2, 2, 2, 2,132,132, 3, 3, - 3, 3, 2, 3, 3, 3, 2, 3, 3, 2, 3, 2, 2, 3, 2, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, - 2, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 2, 3, - 2, 3, 2, 3, 3, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, - 3, 3, 3, 2, 3, 2, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 2, - 2, 2, 2, 2, 0, 0, 15, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 13, 2, - 2, 2, 2, 2, 2, 2, 13, 13, 13, 2, 2, 2, 2, 2, 2, 0, - 2, 2, 2, 2, 2, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 9, 9, 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 70, 70, 70,240, 70, 70, 70, 70, 70, 70, 70, 70, 70,241, 96, 96, + 96, 96, 96, 96, 96, 96, 70, 70, 70, 70,242, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70,243, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,244, 96, 96, + 96, 96, 96, 96, 96, 96,245, 96,246,247, 0, 1, 2, 2, 0, 1, + 2, 2, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 19, 19, + 19, 19, 19, 19, 19, 0, 19, 0, 0, 0, 0, 0, 0, 0, 19, 19, + 19, 19, 19, 0, 0, 0, 0, 0, 26, 26, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 2, 2, + 9, 9, 9, 9, 0, 9, 2, 2, 2, 2, 9, 0, 9, 0, 9, 9, + 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 2, 9, 9, 9, 9, 9, 9, 9, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 1, 1, 6, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, + 4, 2, 2, 4, 4, 4, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 2, 2, 2, 2, 2, 2, 2, 2, 14, 14, + 14, 2, 2, 2, 2, 14, 14, 14, 14, 14, 14, 2, 2, 2, 3, 3, + 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 0, 0, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 2, 37, 37, 37, + 37, 2, 2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 2, 2, 2, 2, 2, 2, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 2, 2, 90, 90, 90, 90, 90, 90, 90, 2, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 2, 2, 95, 2, 37, 37, + 37, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, + 2, 2, 2, 2, 2, 2, 3, 3, 0, 3, 3, 3, 3, 3, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 7, 7, + 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, + 5, 5, 5, 2, 2, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 2, + 5, 2, 2, 2, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 2, + 2, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, + 2, 2, 5, 5, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 2, 2, 11, 11, 11, 2, 11, 11, 11, 11, 11, + 11, 2, 2, 2, 2, 11, 11, 2, 2, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 11, 11, 11, 11, 11, 2, + 11, 11, 2, 11, 11, 2, 11, 11, 2, 2, 11, 2, 11, 11, 11, 2, + 2, 11, 11, 11, 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, + 11, 11, 11, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 2, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 2, + 10, 10, 2, 10, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, 10, 10, + 2, 10, 10, 10, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 10, 10, + 10, 10, 2, 2, 10, 10, 10, 10, 2, 2, 2, 2, 2, 2, 2, 10, + 10, 10, 10, 10, 10, 10, 2, 21, 21, 21, 2, 21, 21, 21, 21, 21, + 21, 21, 21, 2, 2, 21, 21, 2, 2, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 2, + 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 21, 21, 2, + 2, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 2, 2, + 2, 2, 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, 2, + 22, 22, 2, 22, 22, 22, 22, 22, 22, 2, 2, 2, 22, 22, 22, 2, + 22, 22, 22, 22, 2, 2, 2, 22, 22, 2, 22, 2, 22, 22, 2, 2, + 2, 22, 22, 2, 2, 2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 2, 2, 2, 2, 22, 22, 22, 2, 2, 2, 2, 2, 2, 22, 2, 2, + 2, 2, 2, 2, 22, 22, 22, 22, 22, 2, 2, 2, 2, 2, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 2, 23, 23, 23, 2, + 23, 23, 23, 23, 23, 23, 23, 23, 2, 2, 23, 23, 23, 23, 23, 2, + 23, 23, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 23, 2, 23, 23, + 23, 2, 2, 23, 2, 2, 23, 23, 23, 23, 2, 2, 23, 23, 2, 2, + 2, 2, 2, 2, 2, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 2, 16, 16, 16, 2, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 2, 16, 16, 16, 16, 16, 2, 2, 16, 16, 16, 16, 16, 2, + 16, 16, 16, 16, 2, 2, 2, 2, 2, 2, 2, 16, 16, 2, 16, 16, + 16, 16, 2, 2, 16, 16, 2, 16, 16, 16, 2, 2, 2, 2, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 2, 20, 20, 20, 2, + 20, 20, 20, 20, 20, 20, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, + 20, 20, 2, 2, 20, 20, 2, 36, 36, 36, 2, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, + 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 2, 36, 2, 2, 2, 2, 36, 2, 2, 2, 2, 36, 36, 36, + 36, 36, 36, 2, 36, 2, 2, 2, 2, 2, 2, 2, 36, 36, 2, 2, + 36, 36, 36, 2, 2, 2, 2, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 2, 2, 2, 2, 0, 24, 24, + 24, 24, 2, 2, 2, 2, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18, + 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 18, 18, 2, 2, 18, 18, + 18, 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 18, 18, 2, 18, 18, + 2, 2, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 2, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 2, 2, 2, 25, 25, + 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 25, + 25, 2, 2, 2, 2, 2, 33, 33, 33, 33, 33, 33, 33, 33, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 8, 2, 2, + 2, 2, 2, 8, 2, 2, 8, 8, 8, 0, 8, 8, 8, 8, 12, 12, + 12, 12, 12, 12, 12, 12, 30, 30, 30, 30, 30, 30, 30, 30, 30, 2, + 30, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, + 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 30, 2, 2, 2, 30, 30, + 2, 2, 2, 2, 2, 2, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 2, 2, 28, 28, 28, 28, 28, 28, 28, 28, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 2, 2, 2, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 2, + 2, 2, 2, 2, 2, 2, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 2, 2, 2, 2, 2, 2, 2, 2, 2, 45, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 2, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 2, 2, 2, 2, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 2, 46, 46, 46, 2, + 46, 46, 2, 2, 2, 2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 2, 2, 31, 31, 2, 2, 2, 2, 2, 2, 32, 32, + 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 2, 2, 2, 2, 2, 2, 32, 2, 2, 2, 2, 2, 2, 2, 32, 32, + 32, 2, 2, 2, 2, 2, 28, 28, 28, 28, 28, 28, 2, 2, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 2, 48, 48, + 48, 48, 2, 2, 2, 2, 48, 2, 2, 2, 48, 48, 48, 48, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 2, 2, 52, 52, + 52, 52, 52, 2, 2, 2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 2, 2, 2, 2, 58, 58, 2, 2, 2, 2, 2, 2, 58, 58, + 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 2, 91, 91, 91, 91, 91, 2, 2, 91, 91, 91, + 2, 2, 2, 2, 2, 2, 91, 91, 91, 91, 91, 91, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 2, 2, 2, 62, 62, 62, 62, 62, 62, 62, 2, 76, 76, + 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, 93, 93, 70, 70, + 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 70, 70, 70, 70, + 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73, 6, 2, + 2, 2, 2, 2, 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, + 0, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, + 9, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, + 19, 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 19, 6, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, + 9, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, 2, 9, 9, 9, + 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, + 9, 9, 2, 9, 9, 9, 2, 2, 9, 9, 9, 2, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 2, 19, 19, + 19, 19, 19, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, 0, + 0, 0, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 27, 27, + 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 56, 56, 56, 56, 56, 56, 56, 56, 55, 55, + 55, 55, 2, 2, 2, 2, 2, 55, 55, 55, 55, 55, 55, 55, 61, 61, + 61, 61, 61, 61, 61, 61, 2, 2, 2, 2, 2, 2, 2, 61, 61, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 2, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 2, 0, 0, + 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 13, 0, 13, 0, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 13, 13, + 13, 13, 0, 0, 0, 0, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, + 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 17, 2, 2, + 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 12, 12, + 12, 12, 12, 12, 12, 0, 17, 17, 17, 17, 17, 17, 17, 0, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39, + 39, 39, 39, 39, 39, 2, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 2, 2, 2, 2, 79, 79, + 79, 79, 79, 79, 79, 79, 0, 0, 19, 19, 19, 19, 19, 19, 0, 0, + 0, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, 2, 2, 19, 19, + 2, 19, 2, 19, 19, 19, 19, 19, 2, 2, 2, 2, 2, 2, 2, 2, + 19, 19, 19, 19, 19, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 65, 65, + 65, 65, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 2, 2, 75, 75, 75, 75, + 2, 2, 2, 2, 2, 2, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 74, 12, 12, + 12, 12, 12, 2, 2, 2, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 2, 0, 84, 84, 2, 2, 2, 2, 84, 84, 33, 33, + 33, 33, 33, 33, 33, 2, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 2, 68, 68, 68, 68, 68, 68, 2, 2, 68, 68, + 2, 2, 68, 68, 68, 68, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 2, 2, 2, 2, 2, 2, 2, 2, 92, 92, 92, 92, 92, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 2, 2, 30, + 30, 30, 30, 30, 30, 2, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 9, 19, 19, 19, 19, 0, 0, 2, 2, 2, 2, 87, 87, + 87, 87, 87, 87, 2, 2, 87, 87, 2, 2, 2, 2, 2, 2, 12, 12, + 12, 12, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 13, 13, + 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, + 2, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 2, 14, 14, 14, 14, 14, 2, 14, 2, 14, 14, + 2, 14, 14, 2, 14, 14, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 2, 2, + 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 1, 1, + 1, 1, 1, 1, 6, 6, 0, 0, 0, 2, 0, 0, 0, 0, 3, 3, + 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, + 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 12, 12, 12, 12, 2, 2, + 12, 12, 12, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 2, 49, 49, 49, 2, 49, 49, 2, 49, 49, 49, + 49, 49, 49, 49, 2, 2, 49, 49, 49, 2, 2, 2, 2, 2, 0, 0, + 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, + 0, 0, 0, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 0, 0, + 0, 0, 0, 1, 2, 2, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 67, 67, 67, 67, 2, + 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 42, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 2, 2, 2, 2, 2,118,118,118,118,118,118,118,118,118,118, + 118, 2, 2, 2, 2, 2, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 2, 2, 2, 2, 59, 59, 59, 59, 59, 59, 2, 2, 40, 40, + 40, 40, 40, 40, 40, 40, 51, 51, 51, 51, 51, 51, 51, 51, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 2, 2, 50, 50, + 2, 2, 2, 2, 2, 2,135,135,135,135,135,135,135,135,135,135, + 135,135, 2, 2, 2, 2,106,106,106,106,106,106,106,106,104,104, + 104,104,104,104,104,104,104,104,104,104, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2,104,161,161,161,161,161,161,161,161,161,161, + 161, 2,161,161,161,161,161,161,161, 2,161,161, 2,161,161,161, + 2,161,161,161,161,161,161,161, 2,161,161, 2, 2, 2,110,110, + 110,110,110,110,110,110,110,110,110,110,110,110,110, 2,110,110, + 110,110,110,110, 2, 2, 19, 19, 19, 19, 19, 19, 2, 19, 19, 2, + 19, 19, 19, 19, 19, 19, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2, 81,120,120, + 120,120,120,120,120,120,116,116,116,116,116,116,116,116,116,116, + 116,116,116,116,116, 2, 2, 2, 2, 2, 2, 2, 2,116,128,128, + 128,128,128,128,128,128,128,128,128, 2,128,128, 2, 2, 2, 2, + 2,128,128,128,128,128, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 2, 2, 2, 66, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 2, 2, 2, 2, 2, 72, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97, + 97, 97, 97, 97, 97, 97, 2, 2, 2, 2, 97, 97, 97, 97, 2, 2, + 97, 97, 97, 97, 97, 97, 57, 57, 57, 57, 2, 57, 57, 2, 2, 2, + 2, 2, 57, 57, 57, 57, 57, 57, 57, 57, 2, 57, 57, 57, 2, 57, + 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 2, 2, 57, 57, 57, 2, 2, 2, 2, 57, 57, 2, + 2, 2, 2, 2, 2, 2, 88, 88, 88, 88, 88, 88, 88, 88,117,117, + 117,117,117,117,117,117,112,112,112,112,112,112,112,112,112,112, + 112,112,112,112,112, 2, 2, 2, 2,112,112,112,112,112, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 2, 2, 2, 78, + 78, 78, 78, 78, 78, 78, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 2, 2, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 2, 2, 2, 2, 2,122,122,122,122,122,122,122,122,122,122, + 2, 2, 2, 2, 2, 2, 2,122,122,122,122, 2, 2, 2, 2,122, + 122,122,122,122,122,122, 89, 89, 89, 89, 89, 89, 89, 89, 89, 2, + 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,130,130,130,130, + 130, 2, 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,144,144, + 144,144,144,144,144,144,144,144, 2, 2, 2, 2, 2, 2,156,156, + 156,156,156,156,156,156,156,156, 2,156,156,156, 2, 2,156,156, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3,147,147, + 147,147,147,147,147,147,148,148,148,148,148,148,148,148,148,148, + 2, 2, 2, 2, 2, 2,158,158,158,158,158,158,158,158,158,158, + 2, 2, 2, 2, 2, 2,153,153,153,153,153,153,153,153,153,153, + 153,153, 2, 2, 2, 2,149,149,149,149,149,149,149,149,149,149, + 149,149,149,149,149, 2, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 94, 94, 94, 94, 2, 2, + 2, 2, 2, 2, 2, 94, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 85, 2, 2,101,101, + 101,101,101,101,101,101,101, 2, 2, 2, 2, 2, 2, 2,101,101, + 2, 2, 2, 2, 2, 2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 2, 96, 96,111,111,111,111,111,111,111,111,111,111, + 111,111,111,111,111, 2,100,100,100,100,100,100,100,100, 2, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2,108,108, + 108,108,108,108,108,108,108,108, 2,108,108,108,108,108,108,108, + 2, 2, 2, 2, 2, 2,129,129,129,129,129,129,129, 2,129, 2, + 129,129,129,129, 2,129,129,129,129,129,129,129,129,129,129,129, + 129,129,129,129, 2,129,129,129, 2, 2, 2, 2, 2, 2,109,109, + 109,109,109,109,109,109,109,109,109, 2, 2, 2, 2, 2,109,109, + 2, 2, 2, 2, 2, 2,107,107,107,107, 2,107,107,107,107,107, + 107,107,107, 2, 2,107,107, 2, 2,107,107,107,107,107,107,107, + 107,107,107,107,107,107,107, 2,107,107,107,107,107,107,107, 2, + 107,107, 2,107,107,107,107,107, 2, 1,107,107,107,107,107, 2, + 2,107,107,107, 2, 2,107, 2, 2, 2, 2, 2, 2,107, 2, 2, + 2, 2, 2,107,107,107,107,107,107,107, 2, 2,107,107,107,107, + 107,107,107, 2, 2, 2,137,137,137,137,137,137,137,137,137,137, + 137,137, 2,137,137,137,137,137, 2, 2, 2, 2, 2, 2,124,124, + 124,124,124,124,124,124,124,124, 2, 2, 2, 2, 2, 2,123,123, + 123,123,123,123,123,123,123,123,123,123,123,123, 2, 2,114,114, + 114,114,114,114,114,114,114,114,114,114,114, 2, 2, 2,114,114, + 2, 2, 2, 2, 2, 2, 32, 32, 32, 32, 32, 2, 2, 2,102,102, + 102,102,102,102,102,102,102,102, 2, 2, 2, 2, 2, 2,126,126, + 126,126,126,126,126,126,126,126,126, 2, 2,126,126,126,126,126, + 126,126, 2, 2, 2, 2,126,126,126,126,126,126,126, 2,142,142, + 142,142,142,142,142,142,142,142,142,142, 2, 2, 2, 2,125,125, + 125,125,125,125,125,125,125,125,125, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2,125,154,154,154,154,154,154,154, 2, 2,154, + 2, 2,154,154,154,154,154,154,154,154, 2,154,154, 2,154,154, + 154,154,154,154,154,154,154,154,154,154,154,154, 2,154,154, 2, + 2,154,154,154,154,154,154,154, 2, 2, 2, 2, 2, 2,150,150, + 150,150,150,150,150,150, 2, 2,150,150,150,150,150,150,150,150, + 150,150,150, 2, 2, 2,141,141,141,141,141,141,141,141,140,140, + 140,140,140,140,140,140,140,140,140, 2, 2, 2, 2, 2,121,121, + 121,121,121,121,121,121,121, 2, 2, 2, 2, 2, 2, 2, 7, 7, + 2, 2, 2, 2, 2, 2,133,133,133,133,133,133,133,133,133, 2, + 133,133,133,133,133,133,133,133,133,133,133,133,133, 2,133,133, + 133,133,133,133, 2, 2,133,133,133,133,133, 2, 2, 2,134,134, + 134,134,134,134,134,134, 2, 2,134,134,134,134,134,134, 2,134, + 134,134,134,134,134,134,134,134,134,134,134,134,134, 2,138,138, + 138,138,138,138,138, 2,138,138, 2,138,138,138,138,138,138,138, + 138,138,138,138,138,138, 2, 2,138, 2,138,138, 2,138,138,138, + 2, 2, 2, 2, 2, 2,143,143,143,143,143,143, 2,143,143, 2, + 143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, + 143,143,143,143,143, 2,143,143, 2,143,143,143,143,143,143, 2, + 2, 2, 2, 2, 2, 2,143,143, 2, 2, 2, 2, 2, 2,145,145, + 145,145,145,145,145,145,145, 2, 2, 2, 2, 2, 2, 2,163,163, + 163,163,163,163,163,163,163, 2,163,163,163,163,163,163,163,163, + 163, 2, 2, 2,163,163,163,163, 2, 2, 2, 2, 2, 2, 86, 2, + 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 22, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 63, 63, 63, 2, 63, 63, + 63, 63, 63, 2, 2, 2, 63, 63, 63, 63, 2, 2, 2, 2,157,157, + 157,157,157,157,157,157,157,157,157, 2, 2, 2, 2, 2, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 2, 2,127,127, + 127,127,127,127,127,127,127,127,127,127,127,127,127, 2, 79, 2, + 2, 2, 2, 2, 2, 2,115,115,115,115,115,115,115,115,115,115, + 115,115,115,115,115, 2,115,115, 2, 2, 2, 2,115,115,159,159, + 159,159,159,159,159,159,159,159,159,159,159,159,159, 2,159,159, + 2, 2, 2, 2, 2, 2,103,103,103,103,103,103,103,103,103,103, + 103,103,103,103, 2, 2,119,119,119,119,119,119,119,119,119,119, + 119,119,119,119, 2, 2,119,119, 2,119,119,119,119,119, 2, 2, + 2, 2, 2,119,119,119,146,146,146,146,146,146,146,146,146,146, + 146, 2, 2, 2, 2, 2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 2, 2, 2, 2, 99, 2, 2, 2, 2, 2, 2, 2, 99,136,139, + 13, 13,155, 2, 2, 2,136,136,136,136,136,136,136,136,155,155, + 155,155,155,155,155,155,155,155,155,155,155,155, 2, 2,136, 2, + 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 2, 17, 17, 17, 17, 17, + 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 15, 15, 15, 15, 17, 17, + 17, 2, 2, 2, 2, 2, 2, 2, 15, 2, 2, 2, 2, 2, 15, 15, + 15, 2, 2, 17, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17,139,139, + 139,139,139,139,139,139,139,139,139,139, 2, 2, 2, 2,105,105, + 105,105,105,105,105,105,105,105,105, 2, 2, 2, 2, 2,105,105, + 105,105,105, 2, 2, 2,105, 2, 2, 2, 2, 2, 2, 2,105,105, + 2, 2,105,105,105,105, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 2, + 0, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0,131,131,131,131,131,131,131,131,131,131, + 131,131, 2, 2, 2, 2, 2, 2, 2,131,131,131,131,131, 2,131, + 131,131,131,131,131,131, 2, 2, 2, 2, 2, 19, 19, 19, 56, 56, + 56, 56, 56, 56, 56, 2, 56, 2, 2, 56, 56, 56, 56, 56, 56, 56, + 2, 56, 56, 2, 56, 56, 56, 56, 56, 2, 2, 2, 2, 2, 6, 6, + 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6,151,151, + 151,151,151,151,151,151,151,151,151,151,151, 2, 2, 2,151,151, + 151,151,151,151, 2, 2,151,151, 2, 2, 2, 2,151,151,160,160, + 160,160,160,160,160,160,160,160,160,160,160,160,160, 2,152,152, + 152,152,152,152,152,152,152,152, 2, 2, 2, 2, 2,152,164,164, + 164,164,164,164,164,164,164,164, 2, 2, 2, 2, 2, 2, 30, 30, + 30, 30, 2, 30, 30, 2,113,113,113,113,113,113,113,113,113,113, + 113,113,113, 2, 2,113,113,113,113,113,113,113,113, 2,132,132, + 132,132,132,132,132,132,132,132,132,132, 2, 2, 2, 2,132,132, + 2, 2, 2, 2,132,132, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, + 3, 2, 3, 2, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, 2, + 3, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 3, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, + 3, 3, 2, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 0, 15, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 2, 2, + 2, 0, 0, 0, 0, 0, 13, 2, 2, 2, 2, 2, 2, 2, 13, 13, + 13, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, 9, 11, 12, 13, + 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 16, 17, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 19, - 20, 9, 21, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, 17, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 18, 19, 20, 9, 21, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -2162,57 +2137,57 @@ _hb_ucd_u8[18260] = 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, - 29, 30, 0, 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, - 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 23, 24, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, 0, 0, 31, 32, 0, 33, + 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, 38, 39, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, - 46, 47, 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, - 53, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, - 55, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, - 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, - 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, + 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, 0, 0, 0, 48, + 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, + 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99,100,101,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0, - 107, 0, 0, 0,108, 0,109, 0,110, 0,111,112,113, 0,114, 0, - 0, 0,115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124, - 125,126, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 68, 0, 69, + 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 0, + 0, 0, 0, 0, 0,105,106, 0,107, 0, 0, 0,108, 0,109, 0, + 110, 0,111,112,113, 0,114, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,128,129,130,131,132,133,134,135,136,137,138,139, - 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155, - 156,157, 0, 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162,163, 0, - 0, 0, 0, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,165, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,166, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,167, + 118,119,120,121, 0,122,123,124,125,126, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,168, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,129,130,131, + 132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147, + 148,149,150,151,152,153,154,155,156,157, 0, 0, 0,158,159,160, + 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,162,163, 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,169,170, 0, 0, 0, 0,171, - 172, 0, 0, 0,173,174,175,176,177,178,179,180,181,182,183,184, - 185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200, - 201,202,203,204,205,206, 0, 0, 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, 2, 3, 4, + 165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,169,170, 0, 0, 0, 0,171,172, 0, 0, 0,173,174,175,176, + 177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192, + 193,194,195,196,197,198,199,200,201,202,203,204,205,206, 0, 0, + 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, 2, 3, 4, }; static const uint16_t _hb_ucd_u16[9320] = @@ -2827,7 +2802,7 @@ _hb_ucd_gc (unsigned u) static inline uint_fast8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[9184+(((_hb_ucd_u8[8128+(((_hb_ucd_u8[7424+(((_hb_ucd_u8[7178+(u>>2>>3>>4)])<<4)+((u>>2>>3)&15u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u))]:0; + return u<125259u?_hb_ucd_u8[8792+(((_hb_ucd_u8[8236+(((_hb_ucd_u8[7776+(((_hb_ucd_u8[7424+(((_hb_ucd_u8[7178+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; } static inline unsigned _hb_ucd_b4 (const uint8_t* a, unsigned i) @@ -2837,24 +2812,24 @@ _hb_ucd_b4 (const uint8_t* a, unsigned i) static inline int_fast16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9932+(((_hb_ucd_u8[9812+(((_hb_ucd_b4(9684+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0; + return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9540+(((_hb_ucd_u8[9420+(((_hb_ucd_b4(9292+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0; } static inline uint_fast8_t _hb_ucd_sc (unsigned u) { - return u<918000u?_hb_ucd_u8[11454+(((_hb_ucd_u16[2040+(((_hb_ucd_u8[10718+(((_hb_ucd_u8[10268+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2; + return u<918000u?_hb_ucd_u8[11062+(((_hb_ucd_u16[2040+(((_hb_ucd_u8[10326+(((_hb_ucd_u8[9876+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2; } static inline uint_fast16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[6008+(((_hb_ucd_u8[17460+(((_hb_ucd_u8[17078+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + return u<195102u?_hb_ucd_u16[6008+(((_hb_ucd_u8[17068+(((_hb_ucd_u8[16686+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; } #elif !defined(HB_NO_UCD_UNASSIGNED) static const uint8_t -_hb_ucd_u8[17868] = +_hb_ucd_u8[14744] = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 11, 12, 13, 13, 13, 14, @@ -3436,51 +3411,54 @@ _hb_ucd_u8[17868] = 0,230,220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0, - 220,220,220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 17, - 17, 17, 17, 33, 17, 17, 17, 19, 17, 17, 17, 17, 20,101, 17,113, - 129,169, 17, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 220,220,220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 33, + 17, 49, 17, 17, 84, 97,135,145, 26, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,237, 0, 1, 2, 2, - 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 6, 7, 8, - 9, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 21, 22, 0, 0, 0, 0, - 23, 24, 25, 26, 0, 27, 0, 28, 29, 30, 31, 32, 0, 0, 0, 0, - 0, 0, 0, 33, 34, 35, 36, 0, 0, 0, 0, 0, 37, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, 1, 2, 40, 41, - 0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 5, 0, - 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, - 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, - 0, 0, 0, 0, 0, 0, 11, 12, 0, 13, 0, 14, 15, 16, 0, 0, - 0, 0, 0, 1, 17, 18, 0, 19, 7, 1, 0, 0, 0, 20, 20, 7, - 20, 20, 20, 20, 20, 20, 20, 8, 21, 0, 22, 0, 7, 23, 24, 0, - 20, 20, 25, 0, 0, 0, 26, 27, 1, 7, 20, 20, 20, 20, 20, 1, - 28, 29, 30, 31, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 10, 0, - 0, 0, 0, 0, 0, 0, 20, 20, 20, 1, 0, 0, 8, 21, 32, 4, - 0, 10, 0, 33, 7, 20, 20, 20, 0, 0, 0, 0, 8, 34, 34, 35, - 36, 34, 37, 0, 38, 1, 20, 20, 0, 0, 39, 0, 1, 1, 0, 8, - 21, 1, 20, 0, 0, 0, 1, 0, 0, 40, 1, 1, 0, 0, 8, 21, - 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 26, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 21, 7, 20, 41, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 21, 0, 42, 43, 44, 0, 45, 0, 8, 21, 0, 0, 0, 0, 0, - 0, 0, 0, 46, 7, 1, 10, 1, 0, 0, 0, 1, 20, 20, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 34, 9, 0, 0, 20, 20, - 1, 20, 20, 0, 0, 0, 0, 0, 0, 0, 26, 21, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 47, 48, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 11, 11, 11, 11, 12, 13, - 13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 13, 22, 13, 13, 13, - 13, 23, 24, 24, 25, 26, 13, 13, 13, 27, 28, 29, 13, 30, 31, 32, - 33, 34, 35, 36, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 37, 7, 38, 39, 7, 40, 7, 7, - 7, 41, 13, 42, 7, 7, 43, 7, 44, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,177, 0, 1, 2, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 6, 7, 8, 3, + 3, 3, 3, 3, 9, 10, 11, 12, 13, 3, 3, 3, 3, 3, 3, 3, + 3, 14, 3, 15, 3, 3, 3, 3, 3, 3, 16, 17, 18, 19, 20, 21, + 3, 3, 3, 22, 23, 24, 3, 3, 3, 3, 3, 3, 25, 3, 3, 3, + 3, 3, 3, 3, 3, 26, 3, 3, 27, 28, 0, 1, 0, 0, 0, 0, + 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 4, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 10, 11, 12, 13, 0, 0, 14, 15, 16, 6, 0, + 17, 18, 19, 19, 19, 20, 21, 22, 23, 24, 19, 25, 0, 26, 27, 19, + 19, 28, 29, 30, 0, 31, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 19, 28, 0, 32, 33, 9, 34, 35, 19, 0, 0, 36, 37, 38, 39, + 40, 19, 0, 41, 42, 43, 44, 31, 0, 1, 45, 42, 0, 0, 0, 0, + 0, 32, 14, 14, 0, 0, 0, 0, 14, 0, 0, 46, 47, 47, 47, 47, + 48, 49, 47, 47, 47, 47, 50, 51, 52, 53, 43, 21, 0, 0, 0, 0, + 0, 0, 0, 54, 6, 55, 0, 14, 19, 1, 0, 0, 0, 0, 56, 57, + 0, 0, 0, 0, 0, 19, 58, 31, 0, 0, 0, 0, 0, 0, 0, 59, + 14, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, + 61, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3, + 0, 4, 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 1, 1, 0, + 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, + 0, 0, 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 1, 0, + 0, 18, 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, 1, 1, 0, 1, + 1, 1, 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, 22, 0, 0, 0, + 0, 1, 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, 8, 21, 27, 0, + 1, 0, 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, 0, 31, 32, 20, + 1, 1, 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, 0, 0, 33, 9, + 0, 1, 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, 35, 21, 21, 21, + 9, 36, 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, 1, 0, 1, 0, + 0, 0, 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, 8, 21, 21, 21, + 21, 21, 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, 21, 21, 21, 9, + 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, 0, 0, 0, 45, + 8, 9, 1, 0, 0, 0, 8, 21, 21, 21, 9, 0, 1, 0, 1, 1, + 8, 21, 21, 9, 0, 4, 5, 8, 9, 1, 0, 0, 0, 1, 2, 3, + 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 9, 10, 11, 11, 11, 11, 12, 13, 13, 13, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 13, 22, 13, 13, 13, 13, 23, 24, 24, 25, 26, 13, 13, + 13, 27, 28, 29, 13, 30, 31, 32, 33, 34, 35, 36, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 13, 42, 7, 7, 43, 7, + 44, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, @@ -3501,419 +3479,221 @@ _hb_ucd_u8[17868] = 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 45, 0, 0, 1, 2, 2, 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, 32, 33, 34, 35, 36, 37, 37, - 37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 2, 2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59, - 59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 59, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 45, 0, 0, 1, + 2, 2, 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, 32, 33, 34, 35, 36, 37, 37, 37, 37, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 2, 2, 53, 54, 55, 56, + 57, 58, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 61, 61, + 59, 59, 59, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 59, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 79, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, - 82, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 79, 70, 70, 70, 70, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 81, 82, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 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, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, 97, 98, 99,100,101,101, - 102,103,104,105,106,107,108,109,110,111, 96,112,113,114,115,116, - 117,118,119,119,120,121,122,123,124,125,126,127,128,129,130,131, - 132, 96,133,134,135,136,137,138,139,140,141,142,143, 96,144,145, - 96,146,147,148,149, 96,150,151,152,153,154,155,156, 96,157,158, - 159,160, 96,161,162,163,164,164,164,164,164,164,164,165,166,164, - 167, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96,168,169,169,169,169,169,169,169,169,170, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,171,171, - 171,171,172, 96, 96, 96,173,173,173,173,174,175,176,177, 96, 96, - 96, 96,178,179,180,181,182,182,182,182,182,182,182,182,182,182, - 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, - 182,182,182,182,182,183,182,182,182,182,182,182,184,184,184,185, - 186, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96,187,188,189,190,191,191,192, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,193,194, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96,195,196, 59,197,198,199,200,201,202, 96,203,204, - 205, 59, 59,206, 59,207,208,208,208,208,208,209, 96, 96, 96, 96, - 96, 96, 96, 96,210, 96,211,212,213, 96, 96,214, 96, 96, 96,215, - 96, 96, 96, 96, 96,216,217,218,219, 96, 96, 96, 96, 96,220,221, - 222, 96,223,224, 96, 96,225,226, 59,227,228, 96, 59, 59, 59, 59, - 59, 59, 59,229,230,231,232,233, 59, 59,234,235, 59,236, 96, 96, - 96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70,237, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70,238, 70,239, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 97, 98, 99,100,101,101,102,103,104,105,106,107,108,109, + 110,111, 96,112,113,114,115,116,117,118,119,119,120,121,122,123, + 124,125,126,127,128,129,130,131,132, 96,133,134,135,136,137,138, + 139,140,141,142,143, 96,144,145, 96,146,147,148,149, 96,150,151, + 152,153,154,155,156, 96,157,158,159,160, 96,161,162,163,164,164, + 164,164,164,164,164,165,166,164,167, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,168,169,169, + 169,169,169,169,169,169,170, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96,171,171,171,171,172, 96, 96, 96,173,173, + 173,173,174,175,176,177, 96, 96, 96, 96,178,179,180,181,182,182, + 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, + 182,182,182,182,182,182,182,182,182,182,182,182,182,183,182,182, + 182,182,182,182,184,184,184,185,186, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,187,188,189, + 190,191,191,192, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96,193,194, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,195,196, 59,197, + 198,199,200,201,202, 96,203,204,205, 59, 59,206, 59,207,208,208, + 208,208,208,209, 96, 96, 96, 96, 96, 96, 96, 96,210, 96,211,212, + 213, 96, 96,214, 96, 96, 96,215, 96, 96, 96, 96, 96,216,217,218, + 219, 96, 96, 96, 96, 96,220,221,222, 96,223,224, 96, 96,225,226, + 59,227,228, 96, 59, 59, 59, 59, 59, 59, 59,229,230,231,232,233, + 59, 59,234,235, 59,236, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,237, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,238, 70,239, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70,240, 70, 70, 70, 70, 70, 70, 70, 70, 70,241, 96, 96, - 96, 96, 96, 96, 96, 96, 70, 70, 70, 70,242, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70,243, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,244, 96, 96, - 96, 96, 96, 96, 96, 96,245, 96,246,247, 0, 1, 2, 2, 0, 1, - 2, 2, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 19, 19, - 19, 19, 19, 19, 19, 0, 19, 0, 0, 0, 0, 0, 0, 0, 19, 19, - 19, 19, 19, 0, 0, 0, 0, 0, 26, 26, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 2, 2, - 9, 9, 9, 9, 0, 9, 2, 2, 2, 2, 9, 0, 9, 0, 9, 9, - 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 2, 9, 9, 9, 9, 9, 9, 9, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 1, 1, 6, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, - 4, 2, 2, 4, 4, 4, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 2, 2, 2, 2, 2, 2, 2, 2, 14, 14, - 14, 2, 2, 2, 2, 14, 14, 14, 14, 14, 14, 2, 2, 2, 3, 3, - 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 0, 0, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 2, 37, 37, 37, - 37, 2, 2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 2, 2, 2, 2, 2, 2, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 2, 2, 90, 90, 90, 90, 90, 90, 90, 2, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 2, 2, 95, 2, 37, 37, - 37, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, - 2, 2, 2, 2, 2, 2, 3, 3, 0, 3, 3, 3, 3, 3, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 7, 7, - 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, - 5, 5, 5, 2, 2, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 2, - 5, 2, 2, 2, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 2, - 2, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, - 2, 2, 5, 5, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 2, 2, 11, 11, 11, 2, 11, 11, 11, 11, 11, - 11, 2, 2, 2, 2, 11, 11, 2, 2, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 11, 11, 11, 11, 11, 2, - 11, 11, 2, 11, 11, 2, 11, 11, 2, 2, 11, 2, 11, 11, 11, 2, - 2, 11, 11, 11, 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, - 11, 11, 11, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 2, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 2, - 10, 10, 2, 10, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, 10, 10, - 2, 10, 10, 10, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 10, 10, - 10, 10, 2, 2, 10, 10, 10, 10, 2, 2, 2, 2, 2, 2, 2, 10, - 10, 10, 10, 10, 10, 10, 2, 21, 21, 21, 2, 21, 21, 21, 21, 21, - 21, 21, 21, 2, 2, 21, 21, 2, 2, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 2, - 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 21, 21, 2, - 2, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 2, 2, - 2, 2, 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, 2, - 22, 22, 2, 22, 22, 22, 22, 22, 22, 2, 2, 2, 22, 22, 22, 2, - 22, 22, 22, 22, 2, 2, 2, 22, 22, 2, 22, 2, 22, 22, 2, 2, - 2, 22, 22, 2, 2, 2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 2, 2, 2, 2, 22, 22, 22, 2, 2, 2, 2, 2, 2, 22, 2, 2, - 2, 2, 2, 2, 22, 22, 22, 22, 22, 2, 2, 2, 2, 2, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 2, 23, 23, 23, 2, - 23, 23, 23, 23, 23, 23, 23, 23, 2, 2, 23, 23, 23, 23, 23, 2, - 23, 23, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 23, 2, 23, 23, - 23, 2, 2, 23, 2, 2, 23, 23, 23, 23, 2, 2, 23, 23, 2, 2, - 2, 2, 2, 2, 2, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 2, 16, 16, 16, 2, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 2, 16, 16, 16, 16, 16, 2, 2, 16, 16, 16, 16, 16, 2, - 16, 16, 16, 16, 2, 2, 2, 2, 2, 2, 2, 16, 16, 2, 16, 16, - 16, 16, 2, 2, 16, 16, 2, 16, 16, 16, 2, 2, 2, 2, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 2, 20, 20, 20, 2, - 20, 20, 20, 20, 20, 20, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, - 20, 20, 2, 2, 20, 20, 2, 36, 36, 36, 2, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, - 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 2, 36, 2, 2, 2, 2, 36, 2, 2, 2, 2, 36, 36, 36, - 36, 36, 36, 2, 36, 2, 2, 2, 2, 2, 2, 2, 36, 36, 2, 2, - 36, 36, 36, 2, 2, 2, 2, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 2, 2, 2, 2, 0, 24, 24, - 24, 24, 2, 2, 2, 2, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18, - 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 18, 18, 2, 2, 18, 18, - 18, 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 18, 18, 2, 18, 18, - 2, 2, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 2, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 2, 2, 2, 25, 25, - 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 25, - 25, 2, 2, 2, 2, 2, 33, 33, 33, 33, 33, 33, 33, 33, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 8, 2, 2, - 2, 2, 2, 8, 2, 2, 8, 8, 8, 0, 8, 8, 8, 8, 12, 12, - 12, 12, 12, 12, 12, 12, 30, 30, 30, 30, 30, 30, 30, 30, 30, 2, - 30, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, - 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 30, 2, 2, 2, 30, 30, - 2, 2, 2, 2, 2, 2, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 2, 2, 28, 28, 28, 28, 28, 28, 28, 28, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 2, 2, 2, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 2, - 2, 2, 2, 2, 2, 2, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 2, 2, 2, 2, 2, 2, 2, 2, 2, 45, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 2, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 2, 2, 2, 2, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 2, 46, 46, 46, 2, - 46, 46, 2, 2, 2, 2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 2, 2, 31, 31, 2, 2, 2, 2, 2, 2, 32, 32, - 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 2, 2, 2, 2, 2, 2, 32, 2, 2, 2, 2, 2, 2, 2, 32, 32, - 32, 2, 2, 2, 2, 2, 28, 28, 28, 28, 28, 28, 2, 2, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 2, 48, 48, - 48, 48, 2, 2, 2, 2, 48, 2, 2, 2, 48, 48, 48, 48, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 2, 2, 52, 52, - 52, 52, 52, 2, 2, 2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 2, 2, 2, 2, 58, 58, 2, 2, 2, 2, 2, 2, 58, 58, - 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 2, 91, 91, 91, 91, 91, 2, 2, 91, 91, 91, - 2, 2, 2, 2, 2, 2, 91, 91, 91, 91, 91, 91, 2, 2, 1, 1, - 1, 1, 1, 1, 1, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 2, 2, 2, 62, 62, 62, 62, 62, 62, 62, 2, 76, 76, - 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, 93, 93, 70, 70, - 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 70, 70, 70, 70, - 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73, 6, 2, - 2, 2, 2, 2, 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, - 0, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, - 9, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, - 19, 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 19, 6, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, - 9, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, 2, 9, 9, 9, - 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, - 9, 9, 2, 9, 9, 9, 2, 2, 9, 9, 9, 2, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 2, 19, 19, - 19, 19, 19, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, - 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, 0, - 0, 0, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 27, 27, - 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 0, 56, 56, 56, 56, 56, 56, 56, 56, 55, 55, - 55, 55, 2, 2, 2, 2, 2, 55, 55, 55, 55, 55, 55, 55, 61, 61, - 61, 61, 61, 61, 61, 61, 2, 2, 2, 2, 2, 2, 2, 61, 61, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 2, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 2, 0, 0, - 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 13, 0, 13, 0, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 13, 13, - 13, 13, 0, 0, 0, 0, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, - 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 17, 2, 2, - 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 12, 12, - 12, 12, 12, 12, 12, 0, 17, 17, 17, 17, 17, 17, 17, 0, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39, - 39, 39, 39, 39, 39, 2, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77, - 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 2, 2, 2, 2, 79, 79, - 79, 79, 79, 79, 79, 79, 0, 0, 19, 19, 19, 19, 19, 19, 0, 0, - 0, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, 2, 2, 19, 19, - 2, 19, 2, 19, 19, 19, 19, 19, 2, 2, 2, 2, 2, 2, 2, 2, - 19, 19, 19, 19, 19, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 65, 65, - 65, 65, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 2, 2, 75, 75, 75, 75, - 2, 2, 2, 2, 2, 2, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 74, 12, 12, - 12, 12, 12, 2, 2, 2, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 2, 0, 84, 84, 2, 2, 2, 2, 84, 84, 33, 33, - 33, 33, 33, 33, 33, 2, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 2, 68, 68, 68, 68, 68, 68, 2, 2, 68, 68, - 2, 2, 68, 68, 68, 68, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 2, 2, 2, 2, 2, 2, 2, 2, 92, 92, 92, 92, 92, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 2, 2, 30, - 30, 30, 30, 30, 30, 2, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 9, 19, 19, 19, 19, 0, 0, 2, 2, 2, 2, 87, 87, - 87, 87, 87, 87, 2, 2, 87, 87, 2, 2, 2, 2, 2, 2, 12, 12, - 12, 12, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 13, 13, - 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, - 2, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 2, 14, 14, 14, 14, 14, 2, 14, 2, 14, 14, - 2, 14, 14, 2, 14, 14, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, - 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 2, 2, - 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 1, 1, - 1, 1, 1, 1, 6, 6, 0, 0, 0, 2, 0, 0, 0, 0, 3, 3, - 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 0, 2, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 12, 12, 12, 12, 2, 2, - 12, 12, 12, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 2, 49, 49, 49, 2, 49, 49, 2, 49, 49, 49, - 49, 49, 49, 49, 2, 2, 49, 49, 49, 2, 2, 2, 2, 2, 0, 0, - 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, - 0, 0, 0, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 1, 2, 2, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 67, 67, 67, 67, 2, - 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 42, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 41, 2, 2, 2, 2, 2,118,118,118,118,118,118,118,118,118,118, - 118, 2, 2, 2, 2, 2, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 2, 2, 2, 2, 59, 59, 59, 59, 59, 59, 2, 2, 40, 40, - 40, 40, 40, 40, 40, 40, 51, 51, 51, 51, 51, 51, 51, 51, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 2, 2, 50, 50, - 2, 2, 2, 2, 2, 2,135,135,135,135,135,135,135,135,135,135, - 135,135, 2, 2, 2, 2,106,106,106,106,106,106,106,106,104,104, - 104,104,104,104,104,104,104,104,104,104, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2,104,161,161,161,161,161,161,161,161,161,161, - 161, 2,161,161,161,161,161,161,161, 2,161,161, 2,161,161,161, - 2,161,161,161,161,161,161,161, 2,161,161, 2, 2, 2,110,110, - 110,110,110,110,110,110,110,110,110,110,110,110,110, 2,110,110, - 110,110,110,110, 2, 2, 19, 19, 19, 19, 19, 19, 2, 19, 19, 2, - 19, 19, 19, 19, 19, 19, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2, 81,120,120, - 120,120,120,120,120,120,116,116,116,116,116,116,116,116,116,116, - 116,116,116,116,116, 2, 2, 2, 2, 2, 2, 2, 2,116,128,128, - 128,128,128,128,128,128,128,128,128, 2,128,128, 2, 2, 2, 2, - 2,128,128,128,128,128, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 2, 2, 2, 66, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 2, 2, 2, 2, 2, 72, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97, - 97, 97, 97, 97, 97, 97, 2, 2, 2, 2, 97, 97, 97, 97, 2, 2, - 97, 97, 97, 97, 97, 97, 57, 57, 57, 57, 2, 57, 57, 2, 2, 2, - 2, 2, 57, 57, 57, 57, 57, 57, 57, 57, 2, 57, 57, 57, 2, 57, - 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 2, 2, 57, 57, 57, 2, 2, 2, 2, 57, 57, 2, - 2, 2, 2, 2, 2, 2, 88, 88, 88, 88, 88, 88, 88, 88,117,117, - 117,117,117,117,117,117,112,112,112,112,112,112,112,112,112,112, - 112,112,112,112,112, 2, 2, 2, 2,112,112,112,112,112, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 2, 2, 2, 78, - 78, 78, 78, 78, 78, 78, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 2, 2, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 2, 2, 2, 2, 2,122,122,122,122,122,122,122,122,122,122, - 2, 2, 2, 2, 2, 2, 2,122,122,122,122, 2, 2, 2, 2,122, - 122,122,122,122,122,122, 89, 89, 89, 89, 89, 89, 89, 89, 89, 2, - 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,130,130,130,130, - 130, 2, 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,144,144, - 144,144,144,144,144,144,144,144, 2, 2, 2, 2, 2, 2,156,156, - 156,156,156,156,156,156,156,156, 2,156,156,156, 2, 2,156,156, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3,147,147, - 147,147,147,147,147,147,148,148,148,148,148,148,148,148,148,148, - 2, 2, 2, 2, 2, 2,158,158,158,158,158,158,158,158,158,158, - 2, 2, 2, 2, 2, 2,153,153,153,153,153,153,153,153,153,153, - 153,153, 2, 2, 2, 2,149,149,149,149,149,149,149,149,149,149, - 149,149,149,149,149, 2, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 94, 94, 94, 94, 2, 2, - 2, 2, 2, 2, 2, 94, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 85, 2, 2,101,101, - 101,101,101,101,101,101,101, 2, 2, 2, 2, 2, 2, 2,101,101, - 2, 2, 2, 2, 2, 2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 2, 96, 96,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111, 2,100,100,100,100,100,100,100,100, 2, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2,108,108, - 108,108,108,108,108,108,108,108, 2,108,108,108,108,108,108,108, - 2, 2, 2, 2, 2, 2,129,129,129,129,129,129,129, 2,129, 2, - 129,129,129,129, 2,129,129,129,129,129,129,129,129,129,129,129, - 129,129,129,129, 2,129,129,129, 2, 2, 2, 2, 2, 2,109,109, - 109,109,109,109,109,109,109,109,109, 2, 2, 2, 2, 2,109,109, - 2, 2, 2, 2, 2, 2,107,107,107,107, 2,107,107,107,107,107, - 107,107,107, 2, 2,107,107, 2, 2,107,107,107,107,107,107,107, - 107,107,107,107,107,107,107, 2,107,107,107,107,107,107,107, 2, - 107,107, 2,107,107,107,107,107, 2, 1,107,107,107,107,107, 2, - 2,107,107,107, 2, 2,107, 2, 2, 2, 2, 2, 2,107, 2, 2, - 2, 2, 2,107,107,107,107,107,107,107, 2, 2,107,107,107,107, - 107,107,107, 2, 2, 2,137,137,137,137,137,137,137,137,137,137, - 137,137, 2,137,137,137,137,137, 2, 2, 2, 2, 2, 2,124,124, - 124,124,124,124,124,124,124,124, 2, 2, 2, 2, 2, 2,123,123, - 123,123,123,123,123,123,123,123,123,123,123,123, 2, 2,114,114, - 114,114,114,114,114,114,114,114,114,114,114, 2, 2, 2,114,114, - 2, 2, 2, 2, 2, 2, 32, 32, 32, 32, 32, 2, 2, 2,102,102, - 102,102,102,102,102,102,102,102, 2, 2, 2, 2, 2, 2,126,126, - 126,126,126,126,126,126,126,126,126, 2, 2,126,126,126,126,126, - 126,126, 2, 2, 2, 2,126,126,126,126,126,126,126, 2,142,142, - 142,142,142,142,142,142,142,142,142,142, 2, 2, 2, 2,125,125, - 125,125,125,125,125,125,125,125,125, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2,125,154,154,154,154,154,154,154, 2, 2,154, - 2, 2,154,154,154,154,154,154,154,154, 2,154,154, 2,154,154, - 154,154,154,154,154,154,154,154,154,154,154,154, 2,154,154, 2, - 2,154,154,154,154,154,154,154, 2, 2, 2, 2, 2, 2,150,150, - 150,150,150,150,150,150, 2, 2,150,150,150,150,150,150,150,150, - 150,150,150, 2, 2, 2,141,141,141,141,141,141,141,141,140,140, - 140,140,140,140,140,140,140,140,140, 2, 2, 2, 2, 2,121,121, - 121,121,121,121,121,121,121, 2, 2, 2, 2, 2, 2, 2, 7, 7, - 2, 2, 2, 2, 2, 2,133,133,133,133,133,133,133,133,133, 2, - 133,133,133,133,133,133,133,133,133,133,133,133,133, 2,133,133, - 133,133,133,133, 2, 2,133,133,133,133,133, 2, 2, 2,134,134, - 134,134,134,134,134,134, 2, 2,134,134,134,134,134,134, 2,134, - 134,134,134,134,134,134,134,134,134,134,134,134,134, 2,138,138, - 138,138,138,138,138, 2,138,138, 2,138,138,138,138,138,138,138, - 138,138,138,138,138,138, 2, 2,138, 2,138,138, 2,138,138,138, - 2, 2, 2, 2, 2, 2,143,143,143,143,143,143, 2,143,143, 2, - 143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, - 143,143,143,143,143, 2,143,143, 2,143,143,143,143,143,143, 2, - 2, 2, 2, 2, 2, 2,143,143, 2, 2, 2, 2, 2, 2,145,145, - 145,145,145,145,145,145,145, 2, 2, 2, 2, 2, 2, 2,163,163, - 163,163,163,163,163,163,163, 2,163,163,163,163,163,163,163,163, - 163, 2, 2, 2,163,163,163,163, 2, 2, 2, 2, 2, 2, 86, 2, - 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 22, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 63, 63, 63, 2, 63, 63, - 63, 63, 63, 2, 2, 2, 63, 63, 63, 63, 2, 2, 2, 2,157,157, - 157,157,157,157,157,157,157,157,157, 2, 2, 2, 2, 2, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 2, 2,127,127, - 127,127,127,127,127,127,127,127,127,127,127,127,127, 2, 79, 2, - 2, 2, 2, 2, 2, 2,115,115,115,115,115,115,115,115,115,115, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,240, 70, 70, 70, 70, + 70, 70, 70, 70, 70,241, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, + 70, 70,242, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, + 70, 70, 70, 70,243, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70,244, 96, 96, 96, 96, 96, 96, 96, 96,245, 96, + 246,247, 0, 1, 2, 2, 0, 1, 2, 2, 2, 3, 4, 5, 0, 0, + 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, + 19, 0, 19, 0, 0, 0, 0, 0, 26, 26, 1, 1, 1, 1, 9, 9, + 9, 9, 0, 9, 9, 9, 2, 2, 9, 9, 9, 9, 0, 9, 2, 2, + 2, 2, 9, 0, 9, 0, 9, 9, 9, 2, 9, 2, 9, 9, 9, 9, + 2, 9, 9, 9, 55, 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 1, + 1, 6, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2, 2, 2, 14, 14, 2, + 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3, 3, 3, 3, 3, + 3, 0, 3, 3, 3, 1, 1, 1, 3, 3, 1, 3, 3, 3, 37, 37, + 37, 37, 37, 37, 2, 37, 37, 37, 37, 2, 2, 37, 37, 37, 38, 38, + 38, 38, 38, 38, 2, 2, 64, 64, 64, 64, 64, 64, 64, 2, 2, 64, + 64, 64, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90, 90, 2, 95, 95, + 95, 95, 2, 2, 95, 2, 3, 3, 3, 2, 3, 3, 2, 2, 3, 3, + 0, 3, 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 0, 0, + 7, 7, 5, 5, 5, 5, 2, 5, 5, 5, 5, 2, 2, 5, 5, 2, + 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5, 2, 2, 5, 5, + 5, 2, 2, 2, 2, 5, 5, 5, 2, 5, 2, 11, 11, 11, 11, 11, + 11, 2, 2, 2, 2, 11, 11, 2, 2, 11, 11, 11, 11, 11, 11, 2, + 11, 11, 2, 11, 11, 2, 11, 11, 2, 2, 2, 11, 2, 2, 11, 2, + 11, 2, 2, 2, 11, 11, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 2, 10, 10, 2, 10, 10, 10, 10, 2, 2, 10, 2, 2, 2, 2, 2, + 10, 10, 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, + 21, 21, 21, 21, 2, 2, 21, 21, 2, 21, 2, 2, 21, 21, 2, 2, + 22, 22, 2, 22, 22, 22, 22, 22, 22, 2, 22, 2, 22, 22, 22, 22, + 2, 2, 2, 22, 22, 2, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22, + 22, 22, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 23, + 23, 2, 23, 23, 23, 2, 2, 23, 2, 2, 2, 2, 23, 23, 2, 2, + 2, 23, 16, 16, 16, 16, 16, 2, 16, 16, 2, 16, 16, 16, 16, 16, + 2, 2, 2, 16, 16, 2, 2, 2, 16, 16, 20, 20, 20, 20, 20, 2, + 20, 20, 2, 2, 20, 20, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 2, 2, 2, 36, 36, 36, 36, 2, 36, 2, 36, 2, 2, 2, 2, + 36, 2, 2, 2, 2, 36, 36, 2, 36, 2, 36, 2, 2, 2, 2, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 2, 2, 2, 2, 0, 2, 18, + 18, 2, 18, 2, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 2, 18, + 2, 18, 18, 18, 2, 2, 18, 2, 18, 2, 25, 25, 25, 25, 2, 25, + 25, 25, 25, 2, 2, 2, 25, 2, 25, 25, 25, 0, 0, 0, 0, 25, + 25, 2, 33, 33, 33, 33, 8, 8, 8, 8, 8, 8, 2, 8, 2, 8, + 2, 2, 8, 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, 30, 2, + 30, 30, 30, 30, 2, 2, 30, 30, 30, 2, 2, 30, 30, 30, 30, 2, + 2, 2, 29, 29, 29, 29, 29, 29, 2, 2, 28, 28, 28, 28, 34, 34, + 34, 34, 34, 2, 2, 2, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, + 35, 35, 35, 2, 2, 2, 45, 45, 45, 45, 45, 45, 2, 2, 2, 2, + 2, 45, 44, 44, 44, 44, 44, 0, 0, 2, 43, 43, 43, 43, 46, 46, + 46, 46, 46, 2, 46, 46, 31, 31, 31, 31, 31, 31, 2, 2, 32, 32, + 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 32, 32, 2, 2, 32, 2, + 2, 2, 32, 32, 32, 2, 28, 28, 2, 2, 48, 48, 48, 48, 48, 48, + 48, 2, 48, 2, 2, 2, 52, 52, 52, 52, 52, 52, 2, 2, 52, 2, + 2, 2, 58, 58, 58, 58, 58, 58, 2, 2, 58, 58, 58, 2, 2, 2, + 58, 58, 54, 54, 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91, + 91, 2, 91, 2, 2, 91, 91, 91, 2, 2, 1, 1, 1, 2, 62, 62, + 62, 62, 62, 2, 2, 2, 62, 62, 62, 2, 76, 76, 76, 76, 93, 93, + 93, 93, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 2, 2, 2, 70, + 70, 70, 73, 73, 73, 73, 6, 2, 2, 2, 8, 8, 8, 2, 2, 8, + 8, 8, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, + 0, 0, 1, 1, 0, 2, 19, 19, 9, 9, 9, 9, 9, 6, 19, 9, + 9, 9, 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, 19, 19, + 19, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, 9, 9, 1, 1, + 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, 0, 19, 0, 0, + 0, 2, 19, 2, 2, 2, 0, 2, 2, 2, 1, 2, 2, 2, 0, 0, + 9, 0, 0, 0, 19, 19, 27, 27, 27, 27, 2, 2, 0, 0, 0, 0, + 2, 0, 56, 56, 56, 56, 2, 55, 55, 55, 61, 61, 61, 61, 2, 2, + 2, 61, 61, 2, 2, 2, 0, 0, 2, 2, 13, 13, 13, 13, 13, 13, + 2, 13, 13, 13, 2, 2, 0, 13, 0, 13, 0, 13, 13, 13, 13, 13, + 1, 1, 1, 1, 12, 12, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 2, 2, 1, 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 0, 2, 26, 26, 26, 26, 26, 26, 26, 2, 12, + 12, 12, 12, 12, 12, 2, 12, 12, 12, 0, 39, 39, 39, 39, 39, 2, + 2, 2, 39, 39, 39, 2, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79, + 79, 79, 19, 19, 19, 2, 19, 19, 2, 19, 2, 19, 19, 19, 19, 19, + 2, 2, 2, 2, 19, 19, 60, 60, 60, 60, 60, 2, 2, 2, 65, 65, + 65, 65, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, 75, 75, 69, 69, + 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 2, 2, 2, 74, 12, 2, + 2, 2, 84, 84, 84, 84, 84, 84, 2, 0, 84, 84, 2, 2, 2, 2, + 84, 84, 33, 33, 33, 2, 68, 68, 68, 68, 68, 68, 68, 2, 68, 68, + 2, 2, 92, 92, 92, 92, 92, 92, 92, 2, 2, 2, 2, 92, 87, 87, + 87, 87, 87, 87, 87, 2, 19, 9, 19, 19, 19, 19, 0, 0, 87, 87, + 2, 2, 2, 2, 2, 12, 2, 2, 2, 4, 14, 2, 14, 2, 14, 14, + 2, 14, 14, 2, 14, 14, 2, 2, 2, 3, 3, 3, 0, 0, 2, 2, + 3, 3, 1, 1, 6, 6, 3, 2, 3, 3, 3, 2, 2, 0, 2, 0, + 0, 0, 0, 0, 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 49, 49, + 49, 49, 2, 49, 49, 49, 49, 49, 49, 2, 49, 49, 2, 49, 49, 49, + 2, 2, 9, 2, 2, 2, 0, 1, 2, 2, 71, 71, 71, 71, 71, 2, + 2, 2, 67, 67, 67, 67, 67, 2, 2, 2, 42, 42, 42, 42, 2, 42, + 42, 42, 41, 41, 41, 41, 41, 41, 41, 2,118,118,118,118,118,118, + 118, 2, 53, 53, 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, + 2, 2, 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50, + 2, 2,135,135,135,135,106,106,106,106,104,104,104,104, 2, 2, + 2,104,161,161,161,161,161,161,161, 2,161,161, 2,161,161, 2, + 2, 2,110,110,110,110,110,110,110, 2,110,110, 2, 2, 19, 2, + 19, 19, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, 47, 47, 47, 47, + 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, 81, 81, 81, 81, 81, + 2, 81,120,120,120,120,116,116,116,116,116,116,116, 2, 2, 2, + 2,116,128,128,128,128,128,128,128, 2,128,128, 2, 2, 2, 2, + 2,128, 66, 66, 66, 66, 2, 2, 2, 66, 72, 72, 72, 72, 72, 72, + 2, 2, 2, 2, 2, 72, 98, 98, 98, 98, 97, 97, 97, 97, 2, 2, + 97, 97, 57, 57, 57, 57, 2, 57, 57, 2, 2, 57, 57, 57, 57, 57, + 2, 2, 57, 57, 57, 2, 2, 2, 2, 57, 57, 2, 2, 2, 88, 88, + 88, 88,117,117,117,117,112,112,112,112,112,112,112, 2, 2, 2, + 2,112, 78, 78, 78, 78, 78, 78, 2, 2, 2, 78, 78, 78, 83, 83, + 83, 83, 83, 83, 2, 2, 82, 82, 82, 82, 82, 82, 82, 2,122,122, + 122,122,122,122, 2, 2, 2,122,122,122,122, 2, 2, 2, 89, 89, + 89, 89, 89, 2, 2, 2,130,130,130,130,130,130,130, 2, 2, 2, + 130,130,144,144,144,144,144,144, 2, 2,156,156,156,156,156,156, + 2,156,156,156, 2, 2, 2, 3, 3, 3,147,147,147,147,148,148, + 148,148,148,148, 2, 2,158,158,158,158,158,158, 2, 2,153,153, + 153,153,149,149,149,149,149,149,149, 2, 94, 94, 94, 94, 94, 94, + 2, 2, 2, 2, 94, 94, 2, 2, 2, 94, 85, 85, 85, 85, 85, 85, + 85, 2, 2, 85, 2, 2,101,101,101,101,101, 2, 2, 2,101,101, + 2, 2, 96, 96, 96, 96, 96, 2, 96, 96,111,111,111,111,111,111, + 111, 2,100,100,100,100,108,108,108,108,108,108, 2,108,108,108, + 2, 2,129,129,129,129,129,129,129, 2,129, 2,129,129,129,129, + 2,129,129,129, 2, 2,109,109,109,109,109,109,109, 2,109,109, + 2, 2,107,107,107,107, 2,107,107,107,107, 2, 2,107,107, 2, + 107,107,107,107, 2, 1,107,107, 2, 2,107, 2, 2, 2, 2, 2, + 2,107, 2, 2,107,107,137,137,137,137, 2,137,137,137,137,137, + 2, 2,124,124,124,124,124,124, 2, 2,123,123,123,123,123,123, + 2, 2,114,114,114,114,114, 2, 2, 2,114,114, 2, 2,102,102, + 102,102,102,102, 2, 2,126,126,126,126,126,126,126, 2, 2,126, + 126,126,142,142,142,142,125,125,125,125,125,125,125, 2, 2, 2, + 2,125,154,154,154,154,154,154,154, 2, 2,154, 2, 2, 2,154, + 154, 2,154,154, 2,154,154, 2, 2,154,154,154, 2, 2,150,150, + 150,150, 2, 2,150,150,150, 2, 2, 2,141,141,141,141,140,140, + 140,140,140,140,140, 2,121,121,121,121,121, 2, 2, 2, 7, 7, + 2, 2,133,133,133,133,133, 2,133,133,133,133,133, 2,133,133, + 2, 2,133, 2, 2, 2,134,134,134,134, 2, 2,134,134, 2,134, + 134,134,134,134,134, 2,138,138,138,138,138,138,138, 2,138,138, + 2,138, 2, 2,138, 2,138,138, 2, 2,143,143,143,143,143,143, + 2,143,143, 2,143,143,143,143,143, 2,143, 2, 2, 2,143,143, + 2, 2,145,145,145,145,145, 2, 2, 2,163,163,163,163,163, 2, + 163,163,163,163,163, 2, 2, 2,163,163,163,163, 2, 2, 86, 2, + 2, 2, 63, 63, 63, 63, 63, 63, 2, 2, 63, 63, 63, 2, 63, 2, + 2, 2,157,157,157,157,157,157,157, 2, 80, 80, 80, 80, 80, 80, + 2, 2,127,127,127,127,127,127,127, 2, 79, 2, 2, 2,115,115, 115,115,115,115,115, 2,115,115, 2, 2, 2, 2,115,115,159,159, - 159,159,159,159,159,159,159,159,159,159,159,159,159, 2,159,159, - 2, 2, 2, 2, 2, 2,103,103,103,103,103,103,103,103,103,103, - 103,103,103,103, 2, 2,119,119,119,119,119,119,119,119,119,119, - 119,119,119,119, 2, 2,119,119, 2,119,119,119,119,119, 2, 2, - 2, 2, 2,119,119,119,146,146,146,146,146,146,146,146,146,146, - 146, 2, 2, 2, 2, 2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 2, 2, 2, 2, 99, 2, 2, 2, 2, 2, 2, 2, 99,136,139, - 13, 13,155, 2, 2, 2,136,136,136,136,136,136,136,136,155,155, - 155,155,155,155,155,155,155,155,155,155,155,155, 2, 2,136, 2, - 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 2, 17, 17, 17, 17, 17, - 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 15, 15, 15, 15, 17, 17, - 17, 2, 2, 2, 2, 2, 2, 2, 15, 2, 2, 2, 2, 2, 15, 15, - 15, 2, 2, 17, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17,139,139, - 139,139,139,139,139,139,139,139,139,139, 2, 2, 2, 2,105,105, - 105,105,105,105,105,105,105,105,105, 2, 2, 2, 2, 2,105,105, - 105,105,105, 2, 2, 2,105, 2, 2, 2, 2, 2, 2, 2,105,105, - 2, 2,105,105,105,105, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 2, - 0, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, - 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, - 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, - 0, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, - 0, 0, 0, 0, 0, 0,131,131,131,131,131,131,131,131,131,131, - 131,131, 2, 2, 2, 2, 2, 2, 2,131,131,131,131,131, 2,131, - 131,131,131,131,131,131, 2, 2, 2, 2, 2, 19, 19, 19, 56, 56, - 56, 56, 56, 56, 56, 2, 56, 2, 2, 56, 56, 56, 56, 56, 56, 56, - 2, 56, 56, 2, 56, 56, 56, 56, 56, 2, 2, 2, 2, 2, 6, 6, - 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6,151,151, - 151,151,151,151,151,151,151,151,151,151,151, 2, 2, 2,151,151, - 151,151,151,151, 2, 2,151,151, 2, 2, 2, 2,151,151,160,160, - 160,160,160,160,160,160,160,160,160,160,160,160,160, 2,152,152, - 152,152,152,152,152,152,152,152, 2, 2, 2, 2, 2,152,164,164, - 164,164,164,164,164,164,164,164, 2, 2, 2, 2, 2, 2, 30, 30, - 30, 30, 2, 30, 30, 2,113,113,113,113,113,113,113,113,113,113, - 113,113,113, 2, 2,113,113,113,113,113,113,113,113, 2,132,132, - 132,132,132,132,132,132,132,132,132,132, 2, 2, 2, 2,132,132, - 2, 2, 2, 2,132,132, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, - 3, 2, 3, 2, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, 2, - 3, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 2, 3, - 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 3, - 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, - 3, 3, 2, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 0, 15, 0, - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 2, 2, - 2, 0, 0, 0, 0, 0, 13, 2, 2, 2, 2, 2, 2, 2, 13, 13, - 13, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 0, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, 9, 11, 12, 13, - 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 159,159,159,159,159, 2,159,159, 2, 2,103,103,103,103,103,103, + 2, 2,119,119,119,119,119,119, 2, 2,119,119, 2,119, 2,119, + 119,119,146,146,146,146,146,146,146, 2, 99, 99, 99, 99, 99, 99, + 99, 2, 2, 2, 2, 99,136,139, 13, 13,155, 2, 2, 2,136,136, + 136,136,155,155,155,155,155,155, 2, 2,136, 2, 2, 2, 2, 17, + 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 17, 17, 17, 2, 2, 2, + 15, 2, 2, 17, 2, 2,139,139,139,139,105,105,105,105,105,105, + 105, 2,105, 2, 2, 2,105,105, 2, 2, 1, 1, 2, 2, 0, 0, + 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 2, 2, 0, 2, 2, 0, + 0, 2, 0, 2, 0, 2,131,131,131,131, 2, 2, 2,131, 2,131, + 131,131, 56, 56, 56, 2, 56, 2, 2, 56, 56, 56, 2, 56, 56, 2, + 56, 56, 6, 6, 2, 2, 2, 2, 2, 6,151,151,151,151,151, 2, + 2, 2,151,151, 2, 2, 2, 2,151,151,160,160,160,160,160,160, + 160, 2,152,152,152,152,152,152, 2, 2, 2, 2, 2,152,164,164, + 164,164,164,164, 2, 2, 2, 30, 30, 2,113,113,113,113,113, 2, + 2,113,113,113,113, 2,132,132,132,132,132,132, 2, 2, 2, 2, + 132,132, 2, 3, 3, 2, 3, 2, 2, 3, 2, 3, 2, 3, 2, 2, + 3, 2, 3, 2, 3, 2, 3, 3, 2, 3, 15, 0, 0, 2, 13, 2, + 2, 2, 13, 13, 13, 2, 2, 0, 2, 2, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 9, 9, 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, + 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, 17, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 18, 19, 20, 9, 21, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 16, 17, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 18, 19, 20, 9, 21, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -3922,60 +3702,60 @@ _hb_ucd_u8[17868] = 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 23, 24, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, 0, 0, 31, 32, 0, 33, - 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, 38, 39, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, - 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, 0, 0, 0, 48, - 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, - 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, - 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, 0, 0, 0, 0, 66, 0, + 9, 9, 9, 9, 9, 9, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 24, + 25, 26, 27, 28, 29, 30, 0, 0, 31, 32, 0, 33, 0, 34, 0, 35, + 0, 0, 0, 0, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 45, 0, 0, + 0, 0, 0, 0, 46, 47, 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, + 0, 52, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, + 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 60, 61, + 62, 63, 64, 65, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 68, 0, 69, - 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 0, - 0, 0, 0, 0, 0,105,106, 0,107, 0, 0, 0,108, 0,109, 0, - 110, 0,111,112,113, 0,114, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99,100,101,102,103, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0, + 0,105,106, 0,107, 0, 0, 0,108, 0,109, 0,110, 0,111,112, + 113, 0,114, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 118,119,120,121, 0,122,123,124,125,126, 0,127, 0, 0, 0, 0, + 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118,119,120,121, + 0,122,123,124,125,126, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,129,130,131, - 132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147, - 148,149,150,151,152,153,154,155,156,157, 0, 0, 0,158,159,160, - 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,162,163, 0, 0, 0, 0, 0, 0, 0,164, 0, + 0, 0, 0, 0, 0, 0, 0, 0,128,129,130,131,132,133,134,135, + 136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151, + 152,153,154,155,156,157, 0, 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,162,163, 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,169,170, 0, 0, 0, 0,171,172, 0, 0, 0,173,174,175,176, - 177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192, - 193,194,195,196,197,198,199,200,201,202,203,204,205,206, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,169,170, 0, + 0, 0, 0,171,172, 0, 0, 0,173,174,175,176,177,178,179,180, + 181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196, + 197,198,199,200,201,202,203,204,205,206, 0, 0, 0, 0, 0, 0, 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, 2, 3, 4, + 0, 0, 0, 0, 1, 2, 3, 4, }; static const uint16_t -_hb_ucd_u16[9320] = +_hb_ucd_u16[10040] = { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, @@ -4104,255 +3884,300 @@ _hb_ucd_u16[9320] = 48, 48, 48, 48, 71, 48, 48, 48, 48, 48, 48, 140, 140, 140, 140, 140, 683, 140, 570, 570, 570, 570, 570, 570, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 140, 391, 391, 391, 391, 391, 391, 391, 684, - 391, 391, 391, 391, 391, 391, 391, 685, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 2, 3, 1, 2, 2, 3, 0, 0, 0, 0, 0, 4, 0, 4, - 2, 2, 5, 2, 2, 2, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, - 0, 0, 0, 0, 7, 8, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 10, 11, 12, 13, 14, 14, 15, 14, 14, 14, - 14, 14, 14, 14, 16, 17, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 19, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 20, 21, - 21, 21, 22, 20, 21, 21, 21, 21, 21, 23, 24, 25, 25, 25, 25, 25, - 25, 26, 25, 25, 25, 27, 28, 26, 29, 30, 31, 32, 31, 31, 31, 31, - 33, 34, 35, 31, 31, 31, 36, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 29, 31, 31, 31, 31, 37, 38, 37, 37, 37, 37, 37, 37, - 37, 39, 31, 31, 31, 31, 31, 31, 40, 40, 40, 40, 40, 40, 41, 26, - 42, 42, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 45, 44, 46, - 47, 47, 47, 48, 37, 49, 31, 31, 31, 50, 51, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 52, 31, 31, 31, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 54, 53, 55, 53, 53, 53, 56, 57, 58, 59, 59, 60, 61, 62, - 57, 63, 64, 65, 66, 59, 59, 67, 68, 69, 70, 71, 71, 72, 73, 74, - 69, 75, 76, 77, 78, 71, 79, 26, 80, 81, 82, 83, 83, 84, 85, 86, - 81, 87, 88, 26, 89, 83, 90, 91, 92, 93, 94, 95, 95, 96, 97, 98, - 93, 99, 100, 101, 102, 95, 95, 26, 103, 104, 105, 106, 107, 104, 108, 109, - 104, 105, 110, 26, 111, 108, 108, 112, 113, 114, 115, 113, 113, 115, 113, 116, - 114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, 122, 124, 125, 126, - 123, 127, 128, 128, 129, 122, 130, 26, 131, 132, 133, 131, 131, 131, 131, 131, - 132, 133, 134, 131, 135, 131, 131, 131, 136, 137, 138, 139, 137, 137, 140, 141, - 138, 142, 143, 137, 144, 137, 145, 26, 146, 147, 147, 147, 147, 147, 147, 148, - 147, 147, 147, 149, 26, 26, 26, 26, 150, 151, 152, 152, 153, 152, 152, 154, - 155, 156, 152, 157, 26, 26, 26, 26, 158, 158, 158, 158, 158, 158, 158, 158, - 158, 159, 158, 158, 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161, - 158, 161, 162, 163, 26, 26, 26, 26, 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 165, 165, 165, 165, - 166, 167, 165, 165, 165, 165, 165, 168, 169, 169, 169, 169, 169, 169, 169, 169, - 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 171, 172, 171, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 171, 172, - 171, 170, 172, 170, 170, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 170, - 170, 170, 170, 173, 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 177, 177, 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, 179, 179, 179, 180, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 182, 181, 183, 184, 184, 185, 186, 187, 187, 188, 26, - 189, 189, 190, 26, 191, 192, 193, 26, 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 195, 194, 196, 194, 196, 197, 198, 198, 199, 198, 198, 198, 198, - 198, 198, 198, 198, 198, 198, 198, 200, 198, 198, 198, 198, 198, 201, 178, 178, - 178, 178, 178, 178, 178, 178, 202, 26, 203, 203, 203, 204, 203, 205, 203, 205, - 206, 203, 207, 207, 207, 208, 209, 26, 210, 210, 210, 210, 210, 211, 210, 210, - 210, 212, 210, 213, 194, 194, 194, 194, 214, 214, 214, 215, 216, 216, 216, 216, - 216, 216, 216, 217, 216, 216, 216, 218, 216, 219, 216, 219, 216, 220, 9, 9, - 9, 221, 26, 26, 26, 26, 26, 26, 222, 222, 222, 222, 222, 222, 222, 222, - 222, 223, 222, 222, 222, 222, 222, 224, 225, 225, 225, 225, 225, 225, 225, 225, - 226, 226, 226, 226, 226, 226, 227, 228, 229, 229, 229, 229, 229, 229, 229, 230, - 229, 231, 232, 232, 232, 232, 232, 232, 18, 233, 165, 165, 165, 165, 165, 234, - 225, 26, 235, 9, 236, 237, 238, 239, 2, 2, 2, 2, 240, 241, 2, 2, - 2, 2, 2, 242, 243, 244, 2, 245, 2, 2, 2, 2, 2, 2, 2, 246, - 9, 9, 9, 9, 9, 9, 9, 9, 14, 14, 247, 247, 14, 14, 14, 14, - 247, 247, 14, 248, 14, 14, 14, 247, 14, 14, 14, 14, 14, 14, 249, 14, - 249, 14, 250, 251, 14, 14, 252, 253, 0, 254, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 255, 0, 256, 257, 0, 258, 2, 259, 0, 0, 0, 0, - 260, 26, 9, 9, 9, 9, 261, 26, 0, 0, 0, 0, 262, 263, 4, 0, - 0, 264, 0, 0, 2, 2, 2, 2, 2, 265, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 258, 26, 26, 26, - 0, 266, 26, 26, 0, 0, 0, 0, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 268, 0, 0, 0, 269, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 2, 2, 2, 2, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 271, 272, 165, 165, 165, 165, 166, 167, 273, 273, - 273, 273, 273, 273, 273, 274, 275, 274, 170, 170, 172, 26, 172, 172, 172, 172, - 172, 172, 172, 172, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 276, 26, 26, 26, 26, 277, 277, 277, 278, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 279, 26, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 280, 26, 26, 26, 0, 281, 282, 0, 0, 0, 283, 284, 0, 285, - 286, 287, 287, 287, 287, 287, 287, 287, 287, 287, 288, 289, 290, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 291, 292, 293, 294, 294, 294, 294, 294, 295, 169, - 169, 169, 169, 169, 169, 169, 169, 169, 169, 296, 0, 0, 294, 294, 294, 294, - 0, 0, 0, 0, 281, 26, 291, 291, 169, 169, 169, 296, 0, 0, 0, 0, - 0, 0, 0, 0, 169, 169, 169, 297, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 291, 291, 291, 291, 291, 298, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 0, 0, 0, 0, 0, 277, 277, 277, 277, 277, 277, 277, 277, - 0, 0, 0, 0, 0, 0, 0, 0, 299, 299, 299, 299, 299, 299, 299, 299, - 299, 299, 299, 299, 299, 299, 299, 299, 299, 300, 299, 299, 299, 299, 299, 299, - 301, 26, 302, 302, 302, 302, 302, 302, 303, 303, 303, 303, 303, 303, 303, 303, - 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 304, 26, 26, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 305, 305, 305, 305, - 305, 305, 305, 305, 305, 305, 305, 26, 0, 0, 0, 0, 306, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 307, 2, 2, 2, 2, 2, 2, - 2, 308, 309, 310, 26, 26, 311, 2, 312, 312, 312, 312, 312, 313, 0, 314, - 315, 315, 315, 315, 315, 315, 315, 26, 316, 316, 316, 316, 316, 316, 316, 316, - 317, 318, 316, 319, 53, 53, 53, 53, 320, 320, 320, 320, 320, 321, 322, 322, - 322, 322, 323, 324, 169, 169, 169, 325, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 327, 326, 328, 164, 164, 164, 329, 330, 330, 330, 330, 330, 330, 331, 26, - 330, 332, 330, 333, 164, 164, 164, 164, 334, 334, 334, 334, 334, 334, 334, 334, - 335, 26, 26, 336, 337, 337, 338, 26, 339, 339, 339, 26, 172, 172, 2, 2, - 2, 2, 2, 340, 341, 342, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, - 337, 337, 337, 337, 337, 343, 337, 344, 169, 169, 169, 169, 345, 26, 169, 169, - 296, 346, 169, 169, 169, 169, 169, 345, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 347, 26, 26, 26, 26, 348, 26, 349, 350, 25, 25, 351, 352, - 353, 25, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 354, 26, 355, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 356, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 357, 31, 31, 31, 31, 31, - 31, 358, 26, 26, 26, 26, 31, 31, 9, 9, 0, 314, 9, 359, 0, 0, - 0, 0, 360, 0, 258, 281, 361, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 362, 363, 0, 0, 0, 1, 2, 2, 3, - 1, 2, 2, 3, 364, 291, 290, 291, 291, 291, 291, 365, 169, 169, 169, 296, - 366, 366, 366, 367, 258, 258, 26, 368, 369, 370, 369, 369, 371, 369, 369, 372, - 369, 373, 369, 373, 26, 26, 26, 26, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369, 374, 375, 0, 0, 0, 0, 0, 376, 0, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 253, 0, 377, 378, 26, 26, 26, - 26, 26, 0, 0, 0, 0, 0, 379, 380, 380, 380, 381, 382, 382, 382, 382, - 382, 382, 383, 26, 384, 0, 0, 281, 385, 385, 385, 385, 386, 387, 388, 388, - 388, 389, 390, 390, 390, 390, 390, 391, 392, 392, 392, 393, 394, 394, 394, 394, - 395, 394, 396, 26, 26, 26, 26, 26, 397, 397, 397, 397, 397, 397, 397, 397, - 397, 397, 398, 398, 398, 398, 398, 398, 399, 399, 399, 400, 399, 401, 402, 402, - 402, 402, 403, 402, 402, 402, 402, 403, 404, 404, 404, 404, 404, 26, 405, 405, - 405, 405, 405, 405, 406, 407, 408, 409, 408, 409, 410, 408, 411, 408, 411, 412, - 26, 26, 26, 26, 26, 26, 26, 26, 413, 413, 413, 413, 413, 413, 413, 413, - 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 414, 26, - 413, 413, 415, 26, 413, 26, 26, 26, 416, 2, 2, 2, 2, 2, 417, 308, - 26, 26, 26, 26, 26, 26, 26, 26, 418, 419, 420, 420, 420, 420, 421, 422, - 423, 423, 424, 423, 425, 425, 425, 425, 426, 426, 426, 427, 428, 426, 26, 26, - 26, 26, 26, 26, 429, 429, 430, 431, 432, 432, 432, 433, 434, 434, 434, 435, - 26, 26, 26, 26, 26, 26, 26, 26, 436, 436, 436, 436, 437, 437, 437, 438, - 437, 437, 439, 437, 437, 437, 437, 437, 440, 441, 442, 443, 444, 444, 445, 446, - 444, 447, 444, 447, 448, 448, 448, 448, 449, 449, 449, 449, 26, 26, 26, 26, - 450, 450, 450, 450, 451, 452, 451, 26, 453, 453, 453, 453, 453, 453, 454, 455, - 456, 456, 457, 456, 458, 458, 459, 458, 460, 460, 461, 462, 26, 463, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 464, 464, 464, 464, 464, 464, 464, 464, - 464, 465, 26, 26, 26, 26, 26, 26, 466, 466, 466, 466, 466, 466, 467, 26, - 466, 466, 466, 466, 466, 466, 467, 468, 469, 469, 469, 469, 469, 26, 469, 470, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 31, 31, 31, 50, 471, 471, 471, 471, 471, 472, 473, 26, - 26, 26, 26, 26, 26, 26, 26, 474, 475, 475, 475, 475, 475, 26, 476, 476, - 476, 476, 476, 477, 26, 26, 478, 478, 478, 479, 26, 26, 26, 26, 480, 480, - 480, 481, 26, 26, 482, 482, 483, 26, 484, 484, 484, 484, 484, 484, 484, 484, - 484, 485, 486, 484, 484, 484, 485, 487, 488, 488, 488, 488, 488, 488, 488, 488, - 489, 490, 491, 491, 491, 492, 491, 493, 494, 494, 494, 494, 494, 494, 495, 494, - 494, 26, 496, 496, 496, 496, 497, 26, 498, 498, 498, 498, 498, 498, 498, 498, - 498, 498, 498, 498, 499, 137, 500, 26, 501, 501, 502, 501, 501, 501, 501, 501, - 503, 26, 26, 26, 26, 26, 26, 26, 504, 505, 506, 507, 506, 508, 509, 509, - 509, 509, 509, 509, 509, 510, 509, 511, 512, 513, 514, 515, 515, 516, 517, 518, - 513, 519, 520, 521, 522, 523, 523, 26, 524, 524, 524, 524, 524, 524, 524, 524, - 524, 524, 524, 525, 526, 26, 26, 26, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 26, 527, 528, 26, 26, 26, 26, 529, 529, 529, 529, 529, 529, 530, 529, - 529, 529, 529, 530, 26, 26, 26, 26, 531, 531, 531, 531, 531, 531, 531, 531, - 532, 26, 531, 533, 198, 534, 26, 26, 535, 535, 535, 535, 535, 535, 535, 536, - 535, 536, 26, 26, 26, 26, 26, 26, 537, 537, 537, 538, 537, 539, 537, 537, - 540, 26, 26, 26, 26, 26, 26, 26, 541, 541, 541, 541, 541, 541, 541, 542, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 543, 543, 543, 543, - 543, 543, 543, 543, 543, 543, 544, 545, 546, 547, 548, 549, 549, 549, 550, 551, - 546, 26, 549, 552, 26, 26, 26, 26, 26, 26, 26, 26, 553, 554, 553, 553, - 553, 553, 553, 554, 555, 26, 26, 26, 556, 556, 556, 556, 556, 556, 556, 556, - 556, 26, 557, 557, 557, 557, 557, 557, 557, 557, 557, 557, 558, 26, 178, 178, - 559, 559, 559, 559, 559, 559, 559, 560, 53, 561, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 562, 563, 562, 562, 562, 562, 564, 562, - 565, 26, 562, 562, 562, 566, 567, 567, 567, 567, 568, 567, 567, 569, 570, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 571, 572, 573, 573, 573, 573, 571, 574, - 573, 26, 573, 575, 576, 577, 578, 578, 578, 579, 580, 581, 578, 582, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 583, 583, 583, 584, 585, 585, 586, 585, 585, 585, 585, 587, - 585, 585, 585, 588, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 589, 26, - 108, 108, 108, 108, 108, 108, 590, 591, 592, 592, 592, 592, 592, 592, 592, 592, - 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 593, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 592, 592, 592, 592, 592, 592, 592, 592, - 592, 592, 592, 592, 592, 594, 595, 26, 592, 592, 592, 592, 592, 592, 592, 592, - 596, 26, 26, 26, 26, 26, 26, 26, 26, 26, 597, 597, 597, 597, 597, 597, - 597, 597, 597, 597, 597, 597, 598, 26, 599, 599, 599, 599, 599, 599, 599, 599, - 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, - 599, 599, 600, 26, 26, 26, 26, 26, 601, 601, 601, 601, 601, 601, 601, 601, - 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, - 602, 26, 26, 26, 26, 26, 26, 26, 305, 305, 305, 305, 305, 305, 305, 305, - 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 603, - 604, 604, 604, 605, 604, 606, 607, 607, 607, 607, 607, 607, 607, 607, 607, 608, - 607, 609, 610, 610, 610, 611, 611, 26, 612, 612, 612, 612, 612, 612, 612, 612, - 613, 26, 612, 614, 614, 612, 612, 615, 612, 612, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 617, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 618, 618, 618, 618, 618, 618, 618, 618, - 618, 619, 618, 618, 618, 618, 618, 618, 618, 620, 618, 618, 26, 26, 26, 26, - 26, 26, 26, 26, 621, 26, 347, 26, 622, 622, 622, 622, 622, 622, 622, 622, - 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, - 622, 622, 622, 622, 622, 622, 622, 26, 623, 623, 623, 623, 623, 623, 623, 623, - 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, - 623, 623, 624, 26, 26, 26, 26, 26, 622, 625, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 626, 627, 628, 287, 287, 287, 287, 287, 287, 287, - 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, - 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 629, 26, 630, 26, - 26, 26, 631, 26, 632, 26, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, - 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, - 633, 633, 633, 633, 633, 633, 633, 634, 635, 635, 635, 635, 635, 635, 635, 635, - 635, 635, 635, 635, 635, 636, 635, 637, 635, 638, 635, 639, 281, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 9, 9, 9, 9, 9, 640, 9, 9, - 221, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 281, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 276, 26, 0, 0, 0, 0, 258, 363, 0, 0, - 0, 0, 0, 0, 641, 642, 0, 643, 644, 645, 0, 0, 0, 646, 0, 0, - 0, 0, 0, 0, 0, 266, 26, 26, 14, 14, 14, 14, 14, 14, 14, 14, - 247, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 0, 0, 281, 26, 0, 0, 281, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 258, 26, 0, 0, 0, 260, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 647, 648, 0, 649, - 650, 0, 0, 0, 0, 0, 0, 0, 269, 651, 255, 255, 0, 0, 0, 652, - 653, 654, 655, 0, 0, 0, 0, 0, 0, 0, 0, 0, 276, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 268, 0, 0, 0, 0, 0, 0, 656, 656, 656, 656, 656, 656, 656, 656, - 656, 656, 656, 656, 656, 656, 656, 656, 656, 657, 26, 658, 659, 656, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 348, 660, 308, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 661, 270, 270, 662, 663, 664, 18, 18, - 18, 18, 18, 18, 18, 665, 26, 26, 26, 666, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 667, 667, 667, 667, 667, 668, 667, 669, - 667, 670, 26, 26, 26, 26, 26, 26, 26, 26, 671, 671, 671, 672, 26, 26, - 673, 673, 673, 673, 673, 673, 673, 674, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 675, 675, 675, 675, 675, 676, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 172, 677, 170, 172, 678, 678, 678, 678, 678, 678, 678, 678, - 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, - 679, 678, 680, 26, 26, 26, 26, 26, 681, 681, 681, 681, 681, 681, 681, 681, - 681, 682, 681, 683, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 363, 0, 0, 0, 0, 0, 0, 0, 377, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 363, 0, 0, 0, 0, 0, 0, 276, - 26, 26, 26, 26, 26, 26, 26, 26, 684, 31, 31, 31, 685, 686, 687, 688, - 689, 690, 685, 691, 685, 687, 687, 692, 31, 693, 31, 694, 695, 693, 31, 694, - 26, 26, 26, 26, 26, 26, 51, 26, 0, 0, 0, 0, 0, 281, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 281, 26, 0, 258, 363, 0, - 363, 0, 363, 0, 0, 0, 276, 26, 0, 0, 0, 0, 0, 276, 26, 26, - 26, 26, 26, 26, 696, 0, 0, 0, 697, 26, 0, 0, 0, 0, 0, 281, - 0, 260, 314, 26, 276, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 698, 0, 377, 0, 377, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 258, 699, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 314, 0, 281, 260, 26, 0, 281, 0, 0, 0, 0, 0, 0, - 0, 26, 0, 314, 0, 0, 0, 0, 0, 26, 0, 0, 0, 276, 314, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 281, 26, 0, 276, 0, 377, 0, 260, 0, 0, 0, 0, 0, 269, - 276, 696, 0, 281, 0, 260, 0, 260, 0, 0, 360, 0, 0, 0, 0, 0, - 0, 266, 26, 26, 26, 26, 0, 314, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 347, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 347, 26, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 700, 26, 26, 26, 277, 277, 277, 280, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 701, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 702, 26, 26, 26, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 391, 391, 391, 391, 391, 391, 391, 685, 0, 0, 0, 0, 1, 2, 1, 2, + 0, 0, 3, 3, 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 6, 0, 0, 7, 0, 8, 8, 8, 8, 8, 8, 8, 9, + 10, 11, 12, 11, 11, 11, 13, 11, 14, 14, 14, 14, 14, 14, 14, 14, + 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 16, 17, 18, 17, 17, + 19, 20, 21, 21, 22, 21, 23, 24, 25, 26, 27, 27, 28, 29, 27, 30, + 27, 27, 27, 27, 27, 31, 27, 27, 32, 33, 33, 33, 34, 27, 27, 27, + 35, 35, 35, 36, 37, 37, 37, 38, 39, 39, 40, 41, 42, 43, 44, 27, + 45, 46, 27, 27, 27, 27, 47, 27, 48, 48, 48, 48, 48, 49, 50, 48, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 109, 110, 111, 112, 109, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 122, 123, 122, 124, 125, 125, + 126, 127, 128, 129, 130, 131, 125, 125, 132, 132, 132, 132, 133, 132, 134, 135, + 132, 133, 132, 136, 136, 137, 125, 125, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 139, 139, 140, 139, 139, 141, 142, 142, 142, 142, 142, 142, 142, 142, + 143, 143, 143, 143, 144, 145, 143, 143, 144, 143, 143, 146, 147, 148, 143, 143, + 143, 147, 143, 143, 143, 149, 143, 150, 143, 151, 152, 152, 152, 152, 152, 153, + 154, 154, 154, 154, 154, 154, 154, 154, 155, 156, 157, 157, 157, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 168, 168, 168, 168, 169, 170, 170, + 171, 172, 173, 173, 173, 173, 173, 174, 173, 173, 175, 154, 154, 154, 154, 176, + 177, 178, 179, 179, 180, 181, 182, 183, 184, 184, 185, 184, 186, 187, 168, 168, + 188, 189, 190, 190, 190, 191, 190, 192, 193, 193, 194, 8, 195, 125, 125, 125, + 196, 196, 196, 196, 197, 196, 196, 198, 199, 199, 199, 199, 200, 200, 200, 201, + 202, 202, 202, 203, 204, 205, 205, 205, 206, 139, 139, 207, 208, 209, 210, 211, + 4, 4, 212, 4, 4, 213, 214, 215, 4, 4, 4, 216, 8, 8, 8, 8, + 11, 217, 11, 11, 217, 218, 11, 219, 11, 11, 11, 220, 220, 221, 11, 222, + 223, 0, 0, 0, 0, 0, 224, 225, 226, 227, 0, 0, 228, 8, 8, 229, + 0, 0, 230, 231, 232, 0, 4, 4, 233, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 125, 235, 125, 0, 0, + 236, 236, 236, 236, 236, 236, 236, 236, 0, 0, 0, 0, 0, 0, 0, 237, + 0, 238, 0, 0, 0, 0, 0, 0, 239, 239, 239, 239, 239, 239, 4, 4, + 240, 240, 240, 240, 240, 240, 240, 241, 139, 139, 140, 242, 242, 242, 243, 244, + 143, 245, 246, 246, 246, 246, 14, 14, 0, 0, 0, 0, 0, 247, 125, 125, + 248, 249, 248, 248, 248, 248, 248, 250, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 251, 125, 252, 253, 0, 254, 255, 256, 257, 257, 257, + 257, 258, 259, 260, 260, 260, 260, 261, 262, 263, 263, 264, 142, 142, 142, 142, + 265, 0, 263, 263, 0, 0, 266, 260, 142, 265, 0, 0, 0, 0, 142, 267, + 0, 0, 0, 0, 0, 260, 260, 268, 260, 260, 260, 260, 260, 269, 0, 0, + 248, 248, 248, 248, 0, 0, 0, 0, 270, 270, 270, 270, 270, 270, 270, 270, + 271, 270, 270, 270, 272, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 275, 125, 14, 14, 14, 14, 14, 14, 276, 276, 276, 276, 276, 277, + 0, 0, 278, 4, 4, 4, 4, 4, 279, 4, 4, 4, 280, 281, 125, 282, + 283, 283, 284, 285, 286, 286, 286, 287, 288, 288, 288, 288, 289, 290, 48, 48, + 291, 291, 292, 293, 293, 294, 142, 295, 296, 296, 296, 296, 297, 298, 138, 299, + 300, 300, 300, 301, 302, 303, 138, 138, 304, 304, 304, 304, 305, 306, 307, 308, + 309, 310, 246, 4, 4, 311, 312, 152, 152, 152, 152, 152, 307, 307, 313, 314, + 142, 142, 315, 142, 316, 142, 142, 317, 125, 125, 125, 125, 125, 125, 125, 125, + 248, 248, 248, 248, 248, 248, 318, 248, 248, 248, 248, 248, 248, 319, 125, 125, + 320, 321, 21, 322, 323, 27, 27, 27, 27, 27, 27, 27, 324, 325, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 326, 27, 27, 27, 27, + 27, 327, 27, 27, 328, 125, 125, 27, 8, 285, 329, 0, 0, 330, 331, 332, + 27, 27, 27, 27, 27, 27, 27, 333, 334, 0, 1, 2, 1, 2, 335, 259, + 260, 336, 142, 265, 337, 338, 339, 340, 341, 342, 343, 344, 345, 345, 125, 125, + 342, 342, 342, 342, 342, 342, 342, 346, 347, 0, 0, 348, 11, 11, 11, 11, + 349, 350, 351, 125, 125, 0, 0, 352, 353, 354, 355, 355, 355, 356, 357, 252, + 358, 358, 359, 360, 361, 362, 362, 363, 364, 365, 366, 366, 367, 368, 125, 125, + 369, 369, 369, 369, 369, 370, 370, 370, 371, 372, 373, 374, 374, 375, 374, 376, + 377, 377, 378, 379, 379, 379, 380, 381, 381, 382, 383, 384, 125, 125, 125, 125, + 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 386, 385, 387, 388, 125, + 389, 4, 4, 390, 125, 125, 125, 125, 391, 392, 392, 393, 394, 395, 396, 396, + 397, 398, 399, 125, 125, 125, 400, 401, 402, 403, 404, 405, 125, 125, 125, 125, + 406, 406, 407, 408, 407, 409, 407, 407, 410, 411, 412, 413, 414, 414, 415, 415, + 416, 416, 125, 125, 417, 417, 418, 419, 420, 420, 420, 421, 422, 423, 424, 425, + 426, 427, 428, 125, 125, 125, 125, 125, 429, 429, 429, 429, 430, 125, 125, 125, + 431, 431, 431, 432, 431, 431, 431, 433, 434, 434, 435, 436, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 27, 45, 437, 437, 438, 439, 125, 125, 125, 440, + 441, 441, 442, 443, 443, 444, 125, 445, 446, 125, 125, 447, 448, 125, 449, 450, + 451, 451, 451, 451, 452, 453, 451, 454, 455, 455, 455, 455, 456, 457, 458, 459, + 460, 460, 460, 461, 462, 463, 463, 464, 465, 465, 465, 465, 465, 465, 466, 467, + 468, 469, 468, 468, 470, 125, 125, 125, 471, 472, 473, 474, 474, 474, 475, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 485, 485, 485, 485, 485, 486, 487, 125, + 488, 488, 488, 488, 489, 490, 125, 125, 491, 491, 491, 492, 491, 493, 125, 125, + 494, 494, 494, 494, 495, 496, 497, 125, 498, 498, 498, 499, 499, 125, 125, 125, + 500, 501, 502, 500, 503, 125, 125, 125, 504, 504, 504, 505, 125, 125, 125, 125, + 125, 125, 506, 506, 506, 506, 506, 507, 508, 509, 510, 511, 512, 513, 125, 125, + 125, 125, 514, 515, 515, 514, 516, 125, 517, 517, 517, 517, 518, 519, 519, 519, + 519, 519, 520, 154, 521, 521, 521, 522, 523, 125, 125, 125, 125, 125, 125, 125, + 524, 525, 525, 526, 527, 525, 528, 529, 529, 530, 531, 532, 125, 125, 125, 125, + 533, 534, 534, 535, 536, 537, 538, 539, 540, 541, 542, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 543, 544, 545, 546, 545, 547, 545, 548, 125, 125, + 125, 125, 125, 549, 550, 550, 550, 551, 552, 552, 552, 552, 552, 552, 552, 552, + 552, 553, 125, 125, 125, 125, 125, 125, 552, 552, 552, 552, 552, 552, 554, 555, + 552, 552, 552, 552, 556, 125, 125, 125, 125, 557, 557, 557, 557, 557, 557, 558, + 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 560, 125, 125, + 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 562, 125, 125, 125, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 563, 564, 565, 566, 567, + 567, 567, 567, 568, 569, 570, 571, 572, 573, 573, 573, 573, 574, 575, 576, 577, + 573, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 578, 578, 578, 578, + 578, 579, 125, 125, 125, 125, 125, 125, 580, 580, 580, 580, 581, 580, 580, 580, + 582, 580, 125, 125, 125, 125, 583, 584, 585, 585, 585, 585, 585, 585, 585, 585, + 585, 585, 585, 585, 585, 585, 585, 586, 587, 587, 587, 587, 587, 587, 587, 587, + 587, 587, 587, 587, 587, 588, 125, 125, 589, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 590, 591, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 592, 593, 125, 594, 595, 596, + 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 597, + 598, 598, 598, 598, 598, 598, 599, 600, 601, 602, 266, 125, 125, 125, 125, 125, + 8, 8, 603, 8, 604, 0, 0, 0, 0, 0, 0, 0, 266, 125, 125, 125, + 0, 0, 0, 0, 0, 0, 0, 605, 0, 0, 606, 0, 0, 0, 607, 608, + 609, 0, 610, 0, 0, 0, 235, 125, 11, 11, 11, 11, 611, 125, 125, 125, + 125, 125, 125, 125, 0, 266, 0, 266, 0, 0, 0, 0, 0, 234, 0, 612, + 0, 0, 0, 0, 0, 224, 0, 0, 0, 613, 614, 615, 616, 0, 0, 0, + 617, 618, 0, 619, 620, 621, 0, 0, 0, 0, 622, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 623, 0, 0, 0, 624, 624, 624, 624, 624, 624, 624, 624, + 625, 626, 627, 125, 125, 125, 125, 125, 4, 628, 629, 125, 125, 125, 125, 125, + 630, 631, 632, 14, 14, 14, 633, 125, 634, 125, 125, 125, 125, 125, 125, 125, + 635, 635, 636, 637, 638, 125, 125, 125, 125, 639, 640, 125, 641, 641, 641, 642, + 125, 125, 125, 125, 125, 643, 643, 644, 125, 125, 125, 125, 125, 125, 645, 646, + 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 648, 649, 125, 125, + 650, 650, 650, 650, 651, 652, 125, 125, 125, 125, 125, 125, 125, 125, 125, 334, + 0, 0, 0, 653, 125, 125, 125, 125, 334, 0, 0, 247, 125, 125, 125, 125, + 654, 27, 655, 656, 657, 658, 659, 660, 661, 662, 663, 662, 125, 125, 125, 664, + 0, 0, 252, 0, 0, 0, 0, 0, 0, 266, 226, 334, 334, 334, 0, 605, + 0, 0, 247, 125, 125, 125, 665, 0, 666, 0, 0, 252, 612, 667, 605, 125, + 0, 0, 0, 0, 0, 668, 350, 350, 0, 0, 0, 0, 0, 0, 0, 669, + 0, 0, 0, 0, 0, 285, 252, 228, 252, 0, 0, 0, 670, 285, 0, 0, + 670, 0, 247, 667, 125, 125, 125, 125, 0, 0, 0, 0, 0, 266, 247, 350, + 612, 0, 0, 671, 672, 252, 612, 612, 0, 330, 0, 0, 235, 125, 125, 285, + 248, 248, 248, 248, 248, 248, 125, 125, 248, 248, 248, 319, 248, 248, 248, 248, + 248, 318, 248, 248, 248, 248, 248, 248, 248, 248, 584, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 673, 125, 248, 318, 125, 125, 125, 125, 125, 125, + 248, 248, 248, 248, 674, 248, 248, 248, 248, 248, 248, 125, 125, 125, 125, 125, + 675, 125, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 1, 2, 2, 2, + 2, 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2, + 2, 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 8, 8, 8, 8, 16, 8, 8, 8, 17, 18, 18, 18, + 19, 19, 19, 19, 19, 20, 19, 19, 21, 22, 22, 22, 22, 22, 22, 22, + 22, 23, 21, 22, 22, 22, 23, 21, 24, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 12, 12, 25, 25, 26, 27, 25, 28, 12, 12, 29, 30, 29, 31, + 29, 29, 32, 32, 29, 29, 29, 29, 31, 29, 33, 7, 7, 34, 29, 29, + 35, 29, 29, 29, 29, 29, 29, 30, 36, 36, 36, 37, 36, 36, 36, 36, + 36, 36, 38, 39, 40, 40, 40, 40, 41, 12, 12, 12, 42, 42, 42, 42, + 42, 42, 43, 44, 45, 45, 45, 45, 45, 45, 45, 46, 45, 45, 45, 47, + 48, 48, 48, 48, 48, 48, 48, 49, 36, 36, 38, 12, 29, 29, 29, 50, + 51, 12, 29, 29, 52, 29, 29, 29, 53, 53, 53, 53, 54, 55, 53, 53, + 53, 56, 53, 53, 57, 58, 57, 59, 59, 57, 57, 57, 57, 57, 60, 57, + 61, 62, 63, 57, 57, 59, 59, 64, 12, 65, 12, 66, 57, 62, 57, 57, + 57, 57, 57, 64, 67, 67, 68, 69, 70, 71, 71, 71, 71, 71, 72, 71, + 72, 73, 74, 72, 68, 69, 70, 74, 75, 12, 67, 76, 12, 77, 71, 71, + 71, 68, 12, 12, 78, 78, 79, 80, 80, 79, 79, 79, 79, 79, 81, 79, + 81, 78, 82, 79, 79, 80, 80, 82, 83, 12, 12, 12, 79, 84, 79, 79, + 82, 12, 78, 79, 85, 85, 86, 87, 87, 86, 86, 86, 86, 86, 88, 86, + 88, 85, 89, 86, 86, 87, 87, 89, 12, 85, 12, 90, 86, 91, 86, 86, + 86, 86, 12, 12, 92, 93, 94, 92, 95, 96, 97, 95, 98, 99, 94, 92, + 100, 100, 96, 92, 94, 92, 95, 96, 99, 98, 12, 12, 12, 92, 100, 100, + 100, 100, 94, 12, 101, 101, 101, 102, 102, 101, 101, 101, 101, 101, 102, 101, + 101, 101, 103, 101, 101, 102, 102, 103, 12, 104, 105, 106, 101, 107, 101, 101, + 12, 108, 101, 101, 109, 109, 109, 110, 110, 109, 109, 109, 109, 109, 110, 109, + 109, 111, 112, 109, 109, 110, 110, 112, 12, 113, 12, 113, 109, 114, 109, 109, + 111, 12, 12, 12, 115, 115, 115, 116, 116, 115, 115, 115, 115, 115, 115, 115, + 115, 116, 116, 115, 12, 115, 115, 115, 115, 117, 115, 115, 118, 118, 119, 119, + 119, 120, 121, 119, 119, 119, 119, 119, 122, 119, 119, 123, 119, 120, 124, 125, + 119, 126, 119, 119, 12, 121, 119, 119, 121, 127, 12, 12, 128, 129, 129, 129, + 129, 129, 129, 129, 129, 129, 130, 131, 129, 129, 129, 12, 12, 12, 12, 12, + 132, 133, 134, 135, 135, 135, 135, 135, 135, 136, 135, 135, 135, 135, 135, 137, + 135, 138, 135, 134, 135, 135, 137, 135, 139, 139, 139, 139, 139, 139, 140, 139, + 139, 139, 139, 141, 140, 139, 139, 139, 139, 139, 139, 142, 139, 143, 144, 12, + 145, 145, 145, 145, 146, 146, 146, 146, 146, 147, 12, 148, 146, 146, 149, 146, + 150, 150, 150, 150, 151, 151, 151, 151, 151, 151, 152, 153, 151, 154, 152, 153, + 152, 153, 151, 154, 152, 153, 151, 151, 151, 154, 151, 151, 151, 151, 154, 155, + 151, 151, 151, 156, 151, 151, 153, 12, 157, 157, 157, 157, 157, 158, 157, 158, + 159, 159, 159, 159, 160, 160, 160, 160, 160, 160, 160, 161, 162, 162, 162, 162, + 162, 162, 163, 164, 162, 162, 165, 12, 166, 166, 166, 166, 166, 167, 12, 168, + 169, 169, 169, 169, 169, 170, 12, 12, 171, 171, 171, 171, 171, 12, 12, 12, + 172, 172, 172, 173, 173, 12, 12, 12, 174, 174, 174, 174, 174, 174, 174, 175, + 174, 174, 175, 12, 176, 177, 178, 178, 178, 178, 179, 12, 178, 178, 178, 178, + 178, 178, 180, 12, 178, 178, 181, 12, 159, 182, 12, 12, 183, 183, 183, 183, + 183, 183, 183, 184, 183, 183, 183, 12, 185, 183, 183, 183, 186, 186, 186, 186, + 186, 186, 186, 187, 186, 188, 12, 12, 189, 189, 189, 189, 189, 189, 189, 12, + 189, 189, 190, 12, 189, 189, 191, 192, 193, 193, 193, 193, 193, 193, 193, 194, + 195, 195, 195, 195, 195, 195, 195, 196, 195, 195, 195, 197, 195, 195, 198, 12, + 195, 195, 195, 198, 7, 7, 7, 199, 200, 200, 200, 200, 200, 200, 200, 201, + 200, 200, 200, 202, 203, 203, 203, 203, 204, 204, 204, 204, 204, 12, 12, 204, + 205, 205, 205, 205, 205, 205, 206, 205, 205, 205, 207, 208, 209, 209, 209, 209, + 19, 19, 210, 12, 146, 146, 211, 212, 203, 203, 12, 12, 213, 7, 7, 7, + 214, 7, 215, 216, 0, 215, 217, 12, 2, 218, 219, 2, 2, 2, 2, 220, + 221, 218, 222, 2, 2, 2, 223, 2, 2, 2, 2, 224, 8, 225, 8, 225, + 8, 8, 226, 226, 8, 8, 8, 225, 8, 15, 8, 8, 8, 10, 8, 227, + 10, 15, 8, 14, 0, 0, 0, 228, 0, 229, 0, 0, 230, 0, 0, 231, + 0, 0, 0, 232, 2, 2, 2, 233, 234, 12, 12, 12, 235, 12, 12, 12, + 0, 236, 237, 0, 4, 0, 0, 0, 0, 0, 0, 4, 2, 2, 5, 12, + 0, 232, 12, 12, 0, 0, 232, 12, 238, 238, 238, 238, 0, 239, 0, 0, + 0, 240, 0, 0, 241, 241, 241, 241, 18, 18, 18, 18, 18, 12, 242, 18, + 243, 243, 243, 243, 243, 243, 12, 244, 245, 12, 12, 244, 151, 154, 12, 12, + 151, 154, 151, 154, 0, 0, 0, 246, 247, 247, 247, 247, 247, 247, 248, 247, + 247, 12, 12, 12, 247, 249, 12, 12, 0, 0, 0, 12, 0, 250, 0, 0, + 251, 247, 252, 253, 0, 0, 247, 0, 254, 255, 255, 255, 255, 255, 255, 255, + 255, 256, 257, 258, 259, 260, 260, 260, 260, 260, 260, 260, 260, 260, 261, 259, + 12, 262, 263, 263, 263, 263, 263, 263, 264, 150, 150, 150, 150, 150, 150, 265, + 0, 12, 12, 12, 150, 150, 150, 266, 260, 260, 260, 261, 260, 260, 0, 0, + 267, 267, 267, 267, 267, 267, 267, 268, 267, 269, 12, 12, 270, 270, 270, 270, + 271, 271, 271, 271, 271, 271, 271, 12, 272, 272, 272, 272, 272, 272, 12, 12, + 237, 2, 2, 2, 2, 2, 231, 2, 2, 2, 273, 12, 274, 275, 276, 12, + 277, 2, 2, 2, 278, 278, 278, 278, 278, 278, 278, 279, 0, 0, 246, 12, + 280, 280, 280, 280, 280, 280, 12, 12, 281, 281, 281, 281, 281, 282, 12, 283, + 281, 281, 282, 12, 284, 284, 284, 284, 284, 284, 284, 285, 286, 286, 286, 286, + 286, 12, 12, 287, 150, 150, 150, 288, 289, 289, 289, 289, 289, 289, 289, 290, + 289, 289, 291, 292, 145, 145, 145, 293, 294, 294, 294, 294, 294, 295, 12, 12, + 294, 294, 294, 296, 294, 294, 296, 294, 297, 297, 297, 297, 298, 12, 12, 12, + 12, 12, 299, 297, 300, 300, 300, 300, 300, 301, 12, 12, 155, 154, 155, 154, + 155, 154, 12, 12, 2, 2, 3, 2, 2, 302, 303, 12, 300, 300, 300, 304, + 300, 300, 304, 12, 150, 12, 12, 12, 150, 265, 305, 150, 150, 150, 150, 12, + 247, 247, 247, 249, 247, 247, 249, 12, 2, 273, 12, 12, 306, 22, 12, 24, + 25, 26, 25, 307, 308, 309, 25, 25, 50, 12, 12, 12, 310, 29, 29, 29, + 29, 29, 29, 311, 312, 29, 29, 29, 29, 29, 12, 310, 7, 7, 7, 313, + 232, 0, 0, 0, 0, 232, 0, 12, 29, 314, 29, 29, 29, 29, 29, 315, + 316, 0, 0, 0, 0, 317, 260, 260, 260, 260, 260, 318, 319, 150, 319, 150, + 319, 150, 319, 288, 0, 232, 0, 232, 12, 12, 316, 246, 320, 320, 320, 321, + 320, 320, 320, 320, 320, 322, 320, 320, 320, 320, 322, 323, 320, 320, 320, 324, + 320, 320, 322, 12, 232, 131, 0, 0, 0, 131, 0, 0, 8, 8, 8, 14, + 0, 0, 0, 234, 325, 12, 12, 12, 0, 0, 0, 326, 327, 327, 327, 327, + 327, 327, 327, 328, 329, 329, 329, 329, 330, 12, 12, 12, 215, 0, 0, 0, + 331, 331, 331, 331, 331, 12, 12, 332, 333, 333, 333, 333, 333, 333, 334, 12, + 335, 335, 335, 335, 335, 335, 336, 12, 337, 337, 337, 337, 337, 337, 337, 338, + 339, 339, 339, 339, 339, 12, 339, 339, 339, 340, 12, 12, 341, 341, 341, 341, + 342, 342, 342, 342, 343, 343, 343, 343, 343, 343, 343, 344, 343, 343, 344, 12, + 345, 345, 345, 345, 345, 12, 345, 345, 345, 345, 345, 12, 346, 346, 346, 346, + 346, 346, 12, 12, 347, 347, 347, 347, 347, 12, 12, 348, 349, 349, 350, 349, + 350, 351, 349, 349, 351, 349, 349, 349, 351, 349, 351, 352, 353, 353, 353, 353, + 353, 354, 12, 12, 353, 355, 12, 12, 353, 353, 12, 12, 2, 274, 2, 2, + 356, 2, 273, 12, 357, 358, 359, 357, 357, 357, 357, 357, 357, 360, 361, 362, + 363, 363, 363, 363, 363, 364, 363, 363, 365, 365, 365, 365, 366, 366, 366, 366, + 366, 366, 366, 367, 12, 368, 366, 366, 369, 369, 369, 369, 370, 371, 372, 369, + 373, 373, 373, 373, 373, 373, 373, 374, 375, 375, 375, 375, 375, 375, 376, 377, + 378, 378, 378, 378, 379, 379, 379, 379, 379, 379, 12, 379, 380, 379, 379, 379, + 381, 382, 12, 381, 381, 383, 383, 381, 381, 381, 381, 381, 381, 384, 385, 386, + 381, 381, 387, 12, 388, 388, 388, 388, 389, 389, 389, 389, 390, 390, 390, 390, + 390, 391, 392, 390, 390, 391, 12, 12, 393, 393, 393, 393, 393, 394, 395, 393, + 396, 396, 396, 396, 396, 397, 396, 396, 398, 398, 398, 398, 399, 12, 398, 398, + 400, 400, 400, 400, 401, 12, 402, 403, 12, 12, 402, 400, 404, 404, 404, 404, + 404, 404, 405, 12, 406, 406, 406, 406, 407, 12, 12, 12, 407, 12, 408, 406, + 409, 409, 409, 409, 409, 409, 12, 12, 409, 409, 410, 12, 411, 411, 411, 411, + 411, 411, 412, 413, 413, 12, 12, 12, 12, 12, 12, 414, 415, 415, 415, 415, + 415, 415, 12, 12, 416, 416, 416, 416, 416, 416, 417, 12, 418, 418, 418, 418, + 418, 418, 419, 12, 420, 420, 420, 420, 420, 420, 420, 12, 421, 421, 421, 421, + 421, 422, 12, 12, 423, 423, 423, 423, 423, 423, 423, 424, 425, 423, 423, 423, + 423, 424, 12, 426, 427, 427, 427, 427, 428, 12, 12, 429, 430, 430, 430, 430, + 430, 430, 431, 12, 430, 430, 432, 12, 433, 433, 433, 433, 433, 434, 433, 433, + 433, 433, 12, 12, 435, 435, 435, 435, 435, 436, 12, 12, 437, 437, 437, 437, + 118, 119, 119, 119, 119, 127, 12, 12, 438, 438, 438, 438, 439, 438, 438, 438, + 440, 12, 12, 12, 441, 442, 443, 444, 441, 441, 441, 444, 441, 441, 445, 12, + 446, 446, 446, 446, 446, 446, 447, 12, 446, 446, 448, 12, 449, 450, 449, 451, + 451, 449, 449, 449, 449, 449, 452, 449, 452, 450, 453, 449, 449, 451, 451, 454, + 455, 456, 12, 450, 449, 457, 449, 455, 449, 455, 12, 12, 458, 458, 458, 458, + 458, 458, 458, 459, 460, 12, 12, 12, 461, 461, 461, 461, 461, 461, 12, 12, + 461, 461, 462, 12, 463, 463, 463, 463, 463, 464, 463, 463, 463, 463, 463, 464, + 465, 465, 465, 465, 465, 466, 12, 12, 465, 465, 467, 12, 178, 178, 178, 180, + 468, 468, 468, 468, 468, 468, 469, 12, 470, 470, 470, 470, 470, 470, 471, 472, + 470, 470, 470, 12, 470, 471, 12, 12, 473, 473, 473, 473, 473, 473, 473, 12, + 474, 474, 474, 474, 475, 12, 12, 476, 477, 478, 479, 477, 477, 480, 477, 477, + 477, 477, 477, 477, 477, 481, 482, 477, 477, 478, 12, 12, 477, 477, 483, 12, + 484, 484, 485, 484, 484, 484, 484, 484, 484, 486, 12, 12, 487, 487, 487, 487, + 487, 487, 12, 12, 488, 488, 488, 488, 489, 12, 12, 12, 490, 490, 490, 490, + 490, 490, 491, 12, 53, 53, 492, 12, 493, 493, 494, 493, 493, 493, 493, 493, + 493, 495, 493, 493, 493, 496, 12, 12, 493, 493, 493, 497, 498, 498, 498, 498, + 499, 498, 498, 498, 498, 498, 500, 498, 498, 501, 12, 12, 502, 503, 504, 502, + 502, 502, 502, 502, 502, 503, 505, 504, 502, 502, 12, 12, 502, 502, 506, 12, + 507, 508, 509, 507, 507, 507, 507, 507, 507, 507, 507, 510, 508, 507, 511, 12, + 507, 507, 512, 12, 513, 513, 513, 513, 513, 513, 514, 12, 515, 515, 515, 515, + 516, 515, 515, 515, 515, 515, 517, 518, 515, 515, 519, 12, 520, 12, 12, 12, + 100, 100, 100, 100, 96, 12, 12, 98, 521, 521, 521, 521, 521, 521, 522, 12, + 521, 521, 521, 523, 521, 524, 12, 12, 521, 12, 12, 12, 525, 525, 525, 525, + 526, 12, 12, 12, 527, 527, 527, 527, 527, 528, 12, 12, 529, 529, 529, 529, + 529, 530, 12, 12, 272, 272, 531, 12, 532, 532, 532, 532, 532, 532, 532, 533, + 532, 532, 534, 535, 536, 536, 536, 536, 536, 536, 536, 537, 536, 536, 538, 12, + 539, 539, 539, 539, 539, 539, 539, 540, 539, 540, 12, 12, 541, 541, 541, 541, + 541, 542, 12, 12, 541, 541, 543, 541, 543, 541, 541, 541, 541, 541, 12, 544, + 545, 545, 545, 545, 545, 545, 546, 12, 547, 547, 547, 547, 547, 547, 548, 549, + 547, 547, 12, 549, 550, 551, 12, 12, 249, 12, 12, 12, 552, 552, 552, 552, + 552, 552, 12, 12, 553, 553, 553, 553, 553, 554, 12, 12, 552, 552, 555, 12, + 260, 556, 260, 557, 558, 255, 255, 255, 559, 12, 12, 12, 560, 12, 12, 12, + 256, 561, 12, 12, 12, 260, 12, 12, 562, 562, 562, 562, 562, 562, 562, 12, + 563, 563, 563, 563, 563, 563, 564, 12, 563, 563, 563, 565, 563, 563, 565, 12, + 563, 563, 566, 563, 7, 7, 7, 567, 7, 199, 12, 12, 0, 246, 12, 12, + 0, 232, 316, 0, 0, 568, 228, 0, 0, 0, 568, 7, 213, 569, 7, 0, + 0, 0, 570, 228, 8, 225, 12, 12, 0, 0, 234, 12, 0, 0, 0, 229, + 571, 572, 316, 229, 0, 0, 240, 316, 0, 316, 0, 0, 0, 240, 232, 316, + 0, 229, 0, 229, 0, 0, 240, 232, 0, 573, 239, 0, 229, 0, 0, 0, + 0, 246, 0, 0, 0, 0, 0, 239, 574, 574, 574, 574, 574, 574, 574, 12, + 12, 12, 575, 574, 576, 574, 574, 574, 2, 2, 2, 273, 12, 275, 273, 12, + 241, 577, 241, 241, 241, 241, 578, 241, 579, 580, 577, 12, 19, 19, 19, 581, + 12, 12, 12, 582, 583, 583, 583, 583, 583, 583, 583, 584, 583, 583, 583, 585, + 583, 583, 585, 586, 587, 587, 587, 587, 587, 587, 587, 588, 589, 589, 589, 589, + 589, 589, 590, 591, 592, 592, 592, 592, 592, 592, 593, 12, 151, 154, 151, 594, + 151, 151, 151, 154, 595, 595, 595, 595, 595, 596, 595, 595, 595, 597, 12, 12, + 598, 598, 598, 598, 598, 598, 598, 12, 598, 598, 599, 600, 0, 234, 12, 12, + 29, 414, 29, 29, 601, 602, 414, 29, 50, 29, 603, 12, 604, 310, 603, 414, + 601, 602, 603, 603, 601, 602, 50, 29, 50, 29, 414, 605, 29, 29, 606, 29, + 29, 29, 29, 12, 414, 414, 606, 29, 51, 12, 12, 12, 12, 239, 0, 0, + 607, 12, 12, 12, 246, 12, 12, 12, 0, 0, 12, 0, 0, 232, 131, 0, + 0, 0, 12, 12, 0, 0, 0, 240, 0, 246, 12, 239, 608, 12, 12, 12, + 247, 247, 609, 12, 610, 12, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147, @@ -4562,21 +4387,14 @@ _hb_ucd_u16[9320] = 817, 818, 819, 820, 821, 935, 0, 0, }; static const int16_t -_hb_ucd_i16[196] = +_hb_ucd_i16[92] = { - 0, 0, 0, 0, 1, -1, 0, 0, 2, 0, -2, 0, 0, 0, 0, 2, - 0, -2, 0, 0, 0, 0, 0, 16, 0, 0, 0, -16, 0, 0, 1, -1, - 0, 0, 0, 1, -1, 0, 0, 0, 0, 1, -1, 0, 3, 3, 3, -3, - -3, -3, 0, 0, 0, 2016, 0, 0, 0, 0, 0, 2527, 1923, 1914, 1918, 0, - 2250, 0, 0, 0, 0, 0, 0, 138, 0, 7, 0, 0, -7, 0, 0, 0, - 1, -1, 1, -1, -1, 1, -1, 0, 1824, 0, 0, 0, 0, 0, 2104, 0, - 2108, 2106, 0, 2106, 1316, 0, 0, 0, 0, 1, -1, 1, -1, -138, 0, 0, - 1, -1, 8, 8, 8, 0, 7, 7, 0, 0, -8, -8, -8, -7, -7, 0, - 1, -1, 0, 2,-1316, 1, -1, 0, -1, 1, -1, 1, -1, 3, 1, -1, - -3, 1, -1, 1, -1, 0, 0,-1914,-1918, 0, 0,-1923,-1824, 0, 0, 0, - 0,-2016, 0, 0, 1, -1, 0, 1, 0, 0,-2104, 0, 0, 0, 0,-2106, - -2108,-2106, 0, 0, 1, -1,-2250, 0, 0, 0,-2527, 0, 0, -2, 0, 1, - -1, 0, 1, -1, + 0, 0, 1, -1, 2, 0, -2, 0, 0, 2, 0, -2, 0, 16, 0, -16, + 0, 1, -1, 0, 3, 3, 3, -3, -3, -3, 0, 2016, 0, 2527, 1923, 1914, + 1918, 0, 2250, 0, 0, 138, 0, 7, -7, 0, -1, 1, 1824, 0, 2104, 0, + 2108, 2106, 0, 2106, 1316, 0, -1, -138, 8, 8, 8, 0, 7, 7, -8, -8, + -8, -7,-1316, 1, -1, 3, -3, 1, 0,-1914,-1918, 0, 0,-1923,-1824, 0, + 0,-2016,-2104, 0, 0,-2106,-2108,-2106,-2250, 0,-2527, 0, }; static inline uint_fast8_t @@ -4597,17 +4415,17 @@ _hb_ucd_b4 (const uint8_t* a, unsigned i) static inline int_fast16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9540+(((_hb_ucd_u8[9420+(((_hb_ucd_b4(9292+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0; + return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9684+(((_hb_ucd_u8[9452+(((_hb_ucd_u8[9356+(((_hb_ucd_b4(9292+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; } static inline uint_fast8_t _hb_ucd_sc (unsigned u) { - return u<918000u?_hb_ucd_u8[11062+(((_hb_ucd_u16[2040+(((_hb_ucd_u8[10326+(((_hb_ucd_u8[9876+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2; + return u<918000u?_hb_ucd_u8[11118+(((_hb_ucd_u16[4024+(((_hb_ucd_u16[2040+(((_hb_ucd_u8[10382+(((_hb_ucd_u8[9932+(u>>2>>2>>3>>4)])<<4)+((u>>2>>2>>3)&15u))])<<3)+((u>>2>>2)&7u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2; } static inline uint_fast16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[6008+(((_hb_ucd_u8[17068+(((_hb_ucd_u8[16686+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + return u<195102u?_hb_ucd_u16[6728+(((_hb_ucd_u8[13944+(((_hb_ucd_u8[13562+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; } diff --git a/thirdparty/harfbuzz/src/hb-ucd.cc b/thirdparty/harfbuzz/src/hb-ucd.cc index baea224a25..4c8b1ee5e6 100644 --- a/thirdparty/harfbuzz/src/hb-ucd.cc +++ b/thirdparty/harfbuzz/src/hb-ucd.cc @@ -129,12 +129,16 @@ hb_ucd_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED, hb_codepoint_t a, hb_codepoint_t b, hb_codepoint_t *ab, void *user_data HB_UNUSED) { + // Hangul is handled algorithmically. if (_hb_ucd_compose_hangul (a, b, ab)) return true; hb_codepoint_t u = 0; if ((a & 0xFFFFF800u) == 0x0000u && (b & 0xFFFFFF80) == 0x0300u) { + /* If "a" is small enough and "b" is in the U+0300 range, + * the composition data is encoded in a 32bit array sorted + * by "a,b" pair. */ uint32_t k = HB_CODEPOINT_ENCODE3_11_7_14 (a, b, 0); const uint32_t *v = hb_bsearch (k, _hb_ucd_dm2_u32_map, @@ -146,6 +150,8 @@ hb_ucd_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED, } else { + /* Otherwise it is stored in a 64bit array sorted by + * "a,b" pair. */ uint64_t k = HB_CODEPOINT_ENCODE3 (a, b, 0); const uint64_t *v = hb_bsearch (k, _hb_ucd_dm2_u64_map, @@ -170,15 +176,22 @@ hb_ucd_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, unsigned i = _hb_ucd_dm (ab); + /* If no data, there's no decomposition. */ if (likely (!i)) return false; i--; + /* Check if it's a single-character decomposition. */ if (i < ARRAY_LENGTH (_hb_ucd_dm1_p0_map) + ARRAY_LENGTH (_hb_ucd_dm1_p2_map)) { + /* Single-character decompositions currently are only in plane 0 or plane 2. */ if (i < ARRAY_LENGTH (_hb_ucd_dm1_p0_map)) + { + /* Plane 0. */ *a = _hb_ucd_dm1_p0_map[i]; + } else { + /* Plane 2. */ i -= ARRAY_LENGTH (_hb_ucd_dm1_p0_map); *a = 0x20000 | _hb_ucd_dm1_p2_map[i]; } @@ -187,8 +200,10 @@ hb_ucd_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, } i -= ARRAY_LENGTH (_hb_ucd_dm1_p0_map) + ARRAY_LENGTH (_hb_ucd_dm1_p2_map); + /* Otherwise they are encoded either in a 32bit array or a 64bit array. */ if (i < ARRAY_LENGTH (_hb_ucd_dm2_u32_map)) { + /* 32bit array. */ uint32_t v = _hb_ucd_dm2_u32_map[i]; *a = HB_CODEPOINT_DECODE3_11_7_14_1 (v); *b = HB_CODEPOINT_DECODE3_11_7_14_2 (v); @@ -196,6 +211,7 @@ hb_ucd_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, } i -= ARRAY_LENGTH (_hb_ucd_dm2_u32_map); + /* 64bit array. */ uint64_t v = _hb_ucd_dm2_u64_map[i]; *a = HB_CODEPOINT_DECODE3_1 (v); *b = HB_CODEPOINT_DECODE3_2 (v); diff --git a/thirdparty/harfbuzz/src/hb-unicode.cc b/thirdparty/harfbuzz/src/hb-unicode.cc index c1795dc7f2..9a6471e52c 100644 --- a/thirdparty/harfbuzz/src/hb-unicode.cc +++ b/thirdparty/harfbuzz/src/hb-unicode.cc @@ -377,20 +377,30 @@ hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t *ufuncs, \ hb_destroy_func_t destroy) \ { \ if (hb_object_is_immutable (ufuncs)) \ - return; \ + goto fail; \ + \ + if (!func) \ + { \ + if (destroy) \ + destroy (user_data); \ + destroy = nullptr; \ + user_data = ufuncs->parent->user_data.name; \ + } \ \ if (ufuncs->destroy.name) \ ufuncs->destroy.name (ufuncs->user_data.name); \ \ - if (func) { \ + if (func) \ ufuncs->func.name = func; \ - ufuncs->user_data.name = user_data; \ - ufuncs->destroy.name = destroy; \ - } else { \ + else \ ufuncs->func.name = ufuncs->parent->func.name; \ - ufuncs->user_data.name = ufuncs->parent->user_data.name; \ - ufuncs->destroy.name = nullptr; \ - } \ + ufuncs->user_data.name = user_data; \ + ufuncs->destroy.name = destroy; \ + return; \ + \ +fail: \ + if (destroy) \ + destroy (user_data); \ } HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS diff --git a/thirdparty/harfbuzz/src/hb-uniscribe.cc b/thirdparty/harfbuzz/src/hb-uniscribe.cc index 50f71ce9ce..9648e02663 100644 --- a/thirdparty/harfbuzz/src/hb-uniscribe.cc +++ b/thirdparty/harfbuzz/src/hb-uniscribe.cc @@ -355,7 +355,7 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name) return nullptr; } - memcpy(new_sfnt_data, orig_sfnt_data, length); + hb_memcpy(new_sfnt_data, orig_sfnt_data, length); OT::name &name = StructAtOffset<OT::name> (new_sfnt_data, name_table_offset); name.format = 0; @@ -478,11 +478,11 @@ populate_log_font (LOGFONTW *lf, hb_font_t *font, unsigned int font_size) { - memset (lf, 0, sizeof (*lf)); + hb_memset (lf, 0, sizeof (*lf)); lf->lfHeight = - (int) font_size; lf->lfCharSet = DEFAULT_CHARSET; - memcpy (lf->lfFaceName, font->face->data.uniscribe->face_name, sizeof (lf->lfFaceName)); + hb_memcpy (lf->lfFaceName, font->face->data.uniscribe->face_name, sizeof (lf->lfFaceName)); return true; } diff --git a/thirdparty/harfbuzz/src/hb-vector.hh b/thirdparty/harfbuzz/src/hb-vector.hh index a6d9f6b3fb..9b52f5ca95 100644 --- a/thirdparty/harfbuzz/src/hb-vector.hh +++ b/thirdparty/harfbuzz/src/hb-vector.hh @@ -35,7 +35,7 @@ template <typename Type, bool sorted=false> -struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty_t>::type +struct hb_vector_t { typedef Type item_t; static constexpr unsigned item_size = hb_static_size (Type); @@ -53,9 +53,10 @@ struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty hb_requires (hb_is_iterable (Iterable))> hb_vector_t (const Iterable &o) : hb_vector_t () { - if (hb_iter (o).is_random_access_iterator) - alloc (hb_len (hb_iter (o))); - hb_copy (o, *this); + auto iter = hb_iter (o); + if (iter.is_random_access_iterator) + alloc (hb_len (iter)); + hb_copy (iter, *this); } hb_vector_t (const hb_vector_t &o) : hb_vector_t () { @@ -83,6 +84,9 @@ struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty allocated = length = 0; arrayZ = nullptr; } + void init0 () + { + } void fini () { @@ -94,7 +98,11 @@ struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty void reset () { if (unlikely (in_error ())) - allocated = length; // Big hack! + /* Big Hack! We don't know the true allocated size before + * an allocation failure happened. But we know it was at + * least as big as length. Restore it to that and continue + * as if error did not happen. */ + allocated = length; resize (0); } @@ -122,7 +130,7 @@ struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty } hb_bytes_t as_bytes () const - { return hb_bytes_t ((const char *) arrayZ, length * item_size); } + { return hb_bytes_t ((const char *) arrayZ, get_size ()); } bool operator == (const hb_vector_t &o) const { return as_array () == o.as_array (); } bool operator != (const hb_vector_t &o) const { return !(*this == o); } @@ -164,14 +172,10 @@ struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty operator iter_t () const { return iter (); } operator writer_t () { return writer (); } - c_array_t sub_array (unsigned int start_offset, unsigned int count) const - { return as_array ().sub_array (start_offset, count); } - c_array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const - { return as_array ().sub_array (start_offset, count); } - array_t sub_array (unsigned int start_offset, unsigned int count) - { return as_array ().sub_array (start_offset, count); } - array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) - { return as_array ().sub_array (start_offset, count); } + /* Faster range-based for loop. */ + Type *begin () const { return arrayZ; } + Type *end () const { return arrayZ + length; } + hb_sorted_array_t<Type> as_sorted_array () { return hb_sorted_array (arrayZ, length); } @@ -240,12 +244,11 @@ struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty if (likely (new_array)) { for (unsigned i = 0; i < length; i++) + { new (std::addressof (new_array[i])) Type (); - for (unsigned i = 0; i < (unsigned) length; i++) new_array[i] = std::move (arrayZ[i]); - unsigned old_length = length; - shrink_vector (0); - length = old_length; + arrayZ[i].~Type (); + } hb_free (arrayZ); } return new_array; @@ -277,7 +280,14 @@ struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty copy_vector (const hb_vector_t &other) { length = other.length; - hb_memcpy ((void *) arrayZ, (const void *) other.arrayZ, length * item_size); +#ifndef HB_OPTIMIZE_SIZE + if (sizeof (T) >= sizeof (long long)) + /* This runs faster because of alignment. */ + for (unsigned i = 0; i < length; i++) + arrayZ[i] = other.arrayZ[i]; + else +#endif + hb_memcpy ((void *) arrayZ, (const void *) other.arrayZ, length * item_size); } template <typename T = Type, hb_enable_if (!hb_is_trivially_copyable (T) && @@ -309,15 +319,6 @@ struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty } } - template <typename T = Type, - hb_enable_if (hb_is_trivially_destructible(T))> - void - shrink_vector (unsigned size) - { - length = size; - } - template <typename T = Type, - hb_enable_if (!hb_is_trivially_destructible(T))> void shrink_vector (unsigned size) { @@ -328,17 +329,6 @@ struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty } } - template <typename T = Type, - hb_enable_if (hb_is_trivially_copy_assignable(T))> - void - shift_down_vector (unsigned i) - { - memmove (static_cast<void *> (&arrayZ[i - 1]), - static_cast<void *> (&arrayZ[i]), - (length - i) * sizeof (Type)); - } - template <typename T = Type, - hb_enable_if (!hb_is_trivially_copy_assignable(T))> void shift_down_vector (unsigned i) { @@ -381,16 +371,22 @@ struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty return true; } - bool resize (int size_) + bool resize (int size_, bool initialize = true) { unsigned int size = size_ < 0 ? 0u : (unsigned int) size_; if (!alloc (size)) return false; if (size > length) - grow_vector (size); + { + if (initialize) + grow_vector (size); + } else if (size < length) - shrink_vector (size); + { + if (initialize) + shrink_vector (size); + } length = size; return true; @@ -399,13 +395,13 @@ struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty Type pop () { if (!length) return Null (Type); - Type v = arrayZ[length - 1]; + Type v {std::move (arrayZ[length - 1])}; arrayZ[length - 1].~Type (); length--; return v; } - void remove (unsigned int i) + void remove_ordered (unsigned int i) { if (unlikely (i >= length)) return; @@ -414,6 +410,18 @@ struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty length--; } + template <bool Sorted = sorted, + hb_enable_if (!Sorted)> + void remove_unordered (unsigned int i) + { + if (unlikely (i >= length)) + return; + if (i != length - 1) + arrayZ[i] = std::move (arrayZ[length - 1]); + arrayZ[length - 1].~Type (); + length--; + } + void shrink (int size_) { unsigned int size = size_ < 0 ? 0u : (unsigned int) size_; @@ -425,10 +433,8 @@ struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty /* Sorting API. */ - void qsort (int (*cmp)(const void*, const void*)) + void qsort (int (*cmp)(const void*, const void*) = Type::cmp) { as_array ().qsort (cmp); } - void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1) - { as_array ().qsort (start, end); } /* Unsorted search API. */ template <typename T> diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h index 8d6ec66e13..1070262a3b 100644 --- a/thirdparty/harfbuzz/src/hb-version.h +++ b/thirdparty/harfbuzz/src/hb-version.h @@ -41,26 +41,26 @@ HB_BEGIN_DECLS * * The major component of the library version available at compile-time. */ -#define HB_VERSION_MAJOR 5 +#define HB_VERSION_MAJOR 6 /** * HB_VERSION_MINOR: * * The minor component of the library version available at compile-time. */ -#define HB_VERSION_MINOR 3 +#define HB_VERSION_MINOR 0 /** * HB_VERSION_MICRO: * * The micro component of the library version available at compile-time. */ -#define HB_VERSION_MICRO 1 +#define HB_VERSION_MICRO 0 /** * HB_VERSION_STRING: * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "5.3.1" +#define HB_VERSION_STRING "6.0.0" /** * HB_VERSION_ATLEAST: diff --git a/thirdparty/harfbuzz/src/hb.hh b/thirdparty/harfbuzz/src/hb.hh index 8ec638a2b4..410d090d36 100644 --- a/thirdparty/harfbuzz/src/hb.hh +++ b/thirdparty/harfbuzz/src/hb.hh @@ -126,6 +126,7 @@ /* Ignored intentionally. */ #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_IGNORED #pragma GCC diagnostic ignored "-Wclass-memaccess" +#pragma GCC diagnostic ignored "-Wcast-function-type-strict" // https://github.com/harfbuzz/harfbuzz/pull/3859#issuecomment-1295409126 #pragma GCC diagnostic ignored "-Wformat-nonliteral" #pragma GCC diagnostic ignored "-Wformat-zero-length" #pragma GCC diagnostic ignored "-Wmissing-field-initializers" diff --git a/thirdparty/libpng/arm/arm_init.c b/thirdparty/libpng/arm/arm_init.c index ab22525b38..84d05556f8 100644 --- a/thirdparty/libpng/arm/arm_init.c +++ b/thirdparty/libpng/arm/arm_init.c @@ -36,7 +36,10 @@ #ifndef PNG_ARM_NEON_FILE # if defined(__aarch64__) || defined(_M_ARM64) /* ARM Neon is expected to be unconditionally available on ARM64. */ -# error "PNG_ARM_NEON_CHECK_SUPPORTED must not be defined on this platform" +# error "PNG_ARM_NEON_CHECK_SUPPORTED must not be defined on ARM64" +# elif defined(__ARM_NEON__) || defined(__ARM_NEON) + /* ARM Neon is expected to be available on the target CPU architecture. */ +# error "PNG_ARM_NEON_CHECK_SUPPORTED must not be defined on this CPU arch" # elif defined(__linux__) # define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c" # else diff --git a/thirdparty/libpng/png.c b/thirdparty/libpng/png.c index fc09564262..4f3e8bbd31 100644 --- a/thirdparty/libpng/png.c +++ b/thirdparty/libpng/png.c @@ -14,7 +14,7 @@ #include "pngpriv.h" /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_38 Your_png_h_is_not_version_1_6_38; +typedef png_libpng_version_1_6_39 Your_png_h_is_not_version_1_6_39; #ifdef __GNUC__ /* The version tests may need to be added to, but the problem warning has @@ -815,7 +815,7 @@ png_get_copyright(png_const_structrp png_ptr) return PNG_STRING_COPYRIGHT #else return PNG_STRING_NEWLINE \ - "libpng version 1.6.38" PNG_STRING_NEWLINE \ + "libpng version 1.6.39" PNG_STRING_NEWLINE \ "Copyright (c) 2018-2022 Cosmin Truta" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \ PNG_STRING_NEWLINE \ @@ -2710,7 +2710,7 @@ png_check_IHDR(png_const_structrp png_ptr, int /* PRIVATE */ png_check_fp_number(png_const_charp string, size_t size, int *statep, - png_size_tp whereami) + size_t *whereami) { int state = *statep; size_t i = *whereami; diff --git a/thirdparty/libpng/png.h b/thirdparty/libpng/png.h index 5fb494fb1a..f109cdf336 100644 --- a/thirdparty/libpng/png.h +++ b/thirdparty/libpng/png.h @@ -1,7 +1,7 @@ /* png.h - header file for PNG reference library * - * libpng version 1.6.38 - September 14, 2022 + * libpng version 1.6.39 - November 20, 2022 * * Copyright (c) 2018-2022 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson @@ -15,7 +15,7 @@ * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger * libpng versions 0.97, January 1998, through 1.6.35, July 2018: * Glenn Randers-Pehrson - * libpng versions 1.6.36, December 2018, through 1.6.38, September 2022: + * libpng versions 1.6.36, December 2018, through 1.6.39, November 2022: * Cosmin Truta * See also "Contributing Authors", below. */ @@ -239,7 +239,7 @@ * ... * 1.5.30 15 10530 15.so.15.30[.0] * ... - * 1.6.38 16 10638 16.so.16.38[.0] + * 1.6.39 16 10639 16.so.16.39[.0] * * Henceforth the source version will match the shared-library major and * minor numbers; the shared-library major version number will be used for @@ -278,8 +278,8 @@ */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.6.38" -#define PNG_HEADER_VERSION_STRING " libpng version 1.6.38 - September 14, 2022\n" +#define PNG_LIBPNG_VER_STRING "1.6.39" +#define PNG_HEADER_VERSION_STRING " libpng version 1.6.39 - November 20, 2022\n" #define PNG_LIBPNG_VER_SONUM 16 #define PNG_LIBPNG_VER_DLLNUM 16 @@ -287,7 +287,7 @@ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ #define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MINOR 6 -#define PNG_LIBPNG_VER_RELEASE 38 +#define PNG_LIBPNG_VER_RELEASE 39 /* This should be zero for a public release, or non-zero for a * development version. [Deprecated] @@ -318,7 +318,7 @@ * From version 1.0.1 it is: * XXYYZZ, where XX=major, YY=minor, ZZ=release */ -#define PNG_LIBPNG_VER 10638 /* 1.6.38 */ +#define PNG_LIBPNG_VER 10639 /* 1.6.39 */ /* Library configuration: these options cannot be changed after * the library has been built. @@ -428,7 +428,7 @@ extern "C" { /* This triggers a compiler error in png.c, if png.c and png.h * do not agree upon the version number. */ -typedef char* png_libpng_version_1_6_38; +typedef char* png_libpng_version_1_6_39; /* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. * diff --git a/thirdparty/libpng/pngconf.h b/thirdparty/libpng/pngconf.h index 89d28f83a0..fcb4b43069 100644 --- a/thirdparty/libpng/pngconf.h +++ b/thirdparty/libpng/pngconf.h @@ -1,7 +1,7 @@ /* pngconf.h - machine-configurable file for libpng * - * libpng version 1.6.38 + * libpng version 1.6.39 * * Copyright (c) 2018-2022 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson diff --git a/thirdparty/libpng/pnglibconf.h b/thirdparty/libpng/pnglibconf.h index 89d5b4c8ad..e5948c8ce1 100644 --- a/thirdparty/libpng/pnglibconf.h +++ b/thirdparty/libpng/pnglibconf.h @@ -1,6 +1,6 @@ /* pnglibconf.h - library build configuration */ -/* libpng version 1.6.38 */ +/* libpng version 1.6.39 */ /* Copyright (c) 2018-2022 Cosmin Truta */ /* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */ diff --git a/thirdparty/libpng/pngpriv.h b/thirdparty/libpng/pngpriv.h index 2e426cf47d..b8a73b685d 100644 --- a/thirdparty/libpng/pngpriv.h +++ b/thirdparty/libpng/pngpriv.h @@ -1946,7 +1946,7 @@ PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr, * the problem character.) This has not been tested within libpng. */ PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string, - size_t size, int *statep, png_size_tp whereami),PNG_EMPTY); + size_t size, int *statep, size_t *whereami),PNG_EMPTY); /* This is the same but it checks a complete string and returns true * only if it just contains a floating point number. As of 1.5.4 this diff --git a/thirdparty/libpng/pngread.c b/thirdparty/libpng/pngread.c index 5ab9224038..96996ced5b 100644 --- a/thirdparty/libpng/pngread.c +++ b/thirdparty/libpng/pngread.c @@ -3762,13 +3762,13 @@ png_image_read_direct(png_voidp argument) mode = PNG_ALPHA_PNG; output_gamma = PNG_DEFAULT_sRGB; } - + if ((change & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) { mode = PNG_ALPHA_OPTIMIZED; change &= ~PNG_FORMAT_FLAG_ASSOCIATED_ALPHA; } - + /* If 'do_local_background' is set check for the presence of gamma * correction; this is part of the work-round for the libpng bug * described above. diff --git a/thirdparty/libpng/pngrutil.c b/thirdparty/libpng/pngrutil.c index ca060dd15f..068ab193a3 100644 --- a/thirdparty/libpng/pngrutil.c +++ b/thirdparty/libpng/pngrutil.c @@ -3186,7 +3186,7 @@ png_check_chunk_length(png_const_structrp png_ptr, png_uint_32 length) { png_debug2(0," length = %lu, limit = %lu", (unsigned long)length,(unsigned long)limit); - png_chunk_error(png_ptr, "chunk data is too large"); + png_benign_error(png_ptr, "chunk data is too large"); } } diff --git a/thirdparty/libpng/pngwrite.c b/thirdparty/libpng/pngwrite.c index 06c45d16ab..4e58d776a9 100644 --- a/thirdparty/libpng/pngwrite.c +++ b/thirdparty/libpng/pngwrite.c @@ -75,10 +75,10 @@ write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr, * library. If you have a new chunk to add, make a function to write it, * and put it in the correct location here. If you want the chunk written * after the image data, put it in png_write_end(). I strongly encourage - * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing - * the chunk, as that will keep the code from breaking if you want to just - * write a plain PNG file. If you have long comments, I suggest writing - * them in png_write_end(), and compressing them. + * you to supply a PNG_INFO_<chunk> flag, and check info_ptr->valid before + * writing the chunk, as that will keep the code from breaking if you want + * to just write a plain PNG file. If you have long comments, I suggest + * writing them in png_write_end(), and compressing them. */ void PNGAPI png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr) diff --git a/thirdparty/libpng/pngwutil.c b/thirdparty/libpng/pngwutil.c index 16345e4c0b..01f0607c70 100644 --- a/thirdparty/libpng/pngwutil.c +++ b/thirdparty/libpng/pngwutil.c @@ -1,7 +1,7 @@ /* pngwutil.c - utilities to write a PNG file * - * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2018-2022 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -1747,7 +1747,7 @@ png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0, { png_uint_32 purpose_len; size_t units_len, total_len; - png_size_tp params_len; + size_t *params_len; png_byte buf[10]; png_byte new_purpose[80]; int i; @@ -1769,7 +1769,7 @@ png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0, png_debug1(3, "pCAL units length = %d", (int)units_len); total_len = purpose_len + units_len + 10; - params_len = (png_size_tp)png_malloc(png_ptr, + params_len = (size_t *)png_malloc(png_ptr, (png_alloc_size_t)((png_alloc_size_t)nparams * (sizeof (size_t)))); /* Find the length of each parameter, making sure we don't count the diff --git a/thirdparty/libtheora/LICENSE b/thirdparty/libtheora/LICENSE index 5e5ec08469..97e8431790 100644 --- a/thirdparty/libtheora/LICENSE +++ b/thirdparty/libtheora/LICENSE @@ -4,13 +4,13 @@ In addition to and irrespective of the copyright license associated with this software, On2 Technologies, Inc. makes the following statement regarding technology used in this software: - On2 represents and warrants that it shall not assert any rights + On2 represents and warrants that it shall not assert any rights relating to infringement of On2's registered patents, nor initiate any litigation asserting such rights, against any person who, or - entity which utilizes the On2 VP3 Codec Software, including any - use, distribution, and sale of said Software; which make changes, + entity which utilizes the On2 VP3 Codec Software, including any + use, distribution, and sale of said Software; which make changes, modifications, and improvements in said Software; and to use, - distribute, and sell said changes as well as applications for other + distribute, and sell said changes as well as applications for other fields of use. This reference implementation is originally derived from the On2 VP3 diff --git a/thirdparty/libtheora/analyze.c b/thirdparty/libtheora/analyze.c index af01b60dff..19d7612d23 100644 --- a/thirdparty/libtheora/analyze.c +++ b/thirdparty/libtheora/analyze.c @@ -18,12 +18,12 @@ #include <string.h> #include "encint.h" #include "modedec.h" +#if defined(OC_COLLECT_METRICS) +# include "collect.c" +#endif -typedef struct oc_fr_state oc_fr_state; -typedef struct oc_qii_state oc_qii_state; -typedef struct oc_enc_pipeline_state oc_enc_pipeline_state; typedef struct oc_rd_metric oc_rd_metric; typedef struct oc_mode_choice oc_mode_choice; @@ -42,7 +42,7 @@ typedef struct oc_mode_choice oc_mode_choice; This is the inverse of the equivalent table OC_MODE_ALPHABETS in the decoder.*/ static const unsigned char OC_MODE_RANKS[7][OC_NMODES]={ - /*Last MV dominates.*/ + /*Last MV dominates.*/ /*L P M N I G GM 4*/ {3,4,2,0,1,5,6,7}, /*L P N M I G GM 4*/ @@ -87,6 +87,29 @@ static void oc_mode_scheme_chooser_reset(oc_mode_scheme_chooser *_chooser){ } } +/*Return the cost of coding _mb_mode in the specified scheme.*/ +static int oc_mode_scheme_chooser_scheme_mb_cost( + const oc_mode_scheme_chooser *_chooser,int _scheme,int _mb_mode){ + int codebook; + int ri; + codebook=_scheme+1>>3; + /*For any scheme except 0, we can just use the bit cost of the mode's rank + in that scheme.*/ + ri=_chooser->mode_ranks[_scheme][_mb_mode]; + if(_scheme==0){ + int mc; + /*For scheme 0, incrementing the mode count could potentially change the + mode's rank. + Find the index where the mode would be moved to in the optimal list, + and use its bit cost instead of the one for the mode's current + position in the list.*/ + /*We don't actually reorder the list; this is for computing opportunity + cost, not an update.*/ + mc=_chooser->mode_counts[_mb_mode]; + while(ri>0&&mc>=_chooser->mode_counts[_chooser->scheme0_list[ri-1]])ri--; + } + return OC_MODE_BITS[codebook][ri]; +} /*This is the real purpose of this data structure: not actually selecting a mode scheme, but estimating the cost of coding a given mode given all the @@ -108,46 +131,32 @@ static int oc_mode_scheme_chooser_cost(oc_mode_scheme_chooser *_chooser, int best_bits; int mode_bits; int si; - int scheme_bits; + int scheme0_bits; + int scheme1_bits; scheme0=_chooser->scheme_list[0]; scheme1=_chooser->scheme_list[1]; - best_bits=_chooser->scheme_bits[scheme0]; - mode_bits=OC_MODE_BITS[scheme0+1>>3][_chooser->mode_ranks[scheme0][_mb_mode]]; + scheme0_bits=_chooser->scheme_bits[scheme0]; + scheme1_bits=_chooser->scheme_bits[scheme1]; + mode_bits=oc_mode_scheme_chooser_scheme_mb_cost(_chooser,scheme0,_mb_mode); /*Typical case: If the difference between the best scheme and the next best is greater than 6 bits, then adding just one mode cannot change which scheme we use.*/ - if(_chooser->scheme_bits[scheme1]-best_bits>6)return mode_bits; + if(scheme1_bits-scheme0_bits>6)return mode_bits; /*Otherwise, check to see if adding this mode selects a different scheme as the best.*/ si=1; - best_bits+=mode_bits; + best_bits=scheme0_bits+mode_bits; do{ - /*For any scheme except 0, we can just use the bit cost of the mode's rank - in that scheme.*/ - if(scheme1!=0){ - scheme_bits=_chooser->scheme_bits[scheme1]+ - OC_MODE_BITS[scheme1+1>>3][_chooser->mode_ranks[scheme1][_mb_mode]]; - } - else{ - int ri; - /*For scheme 0, incrementing the mode count could potentially change the - mode's rank. - Find the index where the mode would be moved to in the optimal list, - and use its bit cost instead of the one for the mode's current - position in the list.*/ - /*We don't recompute scheme bits; this is computing opportunity cost, not - an update.*/ - for(ri=_chooser->scheme0_ranks[_mb_mode];ri>0&& - _chooser->mode_counts[_mb_mode]>= - _chooser->mode_counts[_chooser->scheme0_list[ri-1]];ri--); - scheme_bits=_chooser->scheme_bits[0]+OC_MODE_BITS[0][ri]; - } - if(scheme_bits<best_bits)best_bits=scheme_bits; + int cur_bits; + cur_bits=scheme1_bits+ + oc_mode_scheme_chooser_scheme_mb_cost(_chooser,scheme1,_mb_mode); + if(cur_bits<best_bits)best_bits=cur_bits; if(++si>=8)break; scheme1=_chooser->scheme_list[si]; + scheme1_bits=_chooser->scheme_bits[scheme1]; } - while(_chooser->scheme_bits[scheme1]-_chooser->scheme_bits[scheme0]<=6); - return best_bits-_chooser->scheme_bits[scheme0]; + while(scheme1_bits-scheme0_bits<=6); + return best_bits-scheme0_bits; } /*Incrementally update the mode counts and per-scheme bit counts and re-order @@ -211,22 +220,6 @@ static int oc_block_run_bits(int _run_count){ -/*State to track coded block flags and their bit cost.*/ -struct oc_fr_state{ - ptrdiff_t bits; - unsigned sb_partial_count:16; - unsigned sb_full_count:16; - unsigned b_coded_count_prev:8; - unsigned b_coded_count:8; - unsigned b_count:8; - signed int sb_partial:2; - signed int sb_full:2; - signed int b_coded_prev:2; - signed int b_coded:2; -}; - - - static void oc_fr_state_init(oc_fr_state *_fr){ _fr->bits=0; _fr->sb_partial_count=0; @@ -234,6 +227,8 @@ static void oc_fr_state_init(oc_fr_state *_fr){ _fr->b_coded_count_prev=0; _fr->b_coded_count=0; _fr->b_count=0; + _fr->sb_prefer_partial=0; + _fr->sb_bits=0; _fr->sb_partial=-1; _fr->sb_full=-1; _fr->b_coded_prev=-1; @@ -241,14 +236,14 @@ static void oc_fr_state_init(oc_fr_state *_fr){ } -static void oc_fr_state_advance_sb(oc_fr_state *_fr, +static int oc_fr_state_sb_cost(const oc_fr_state *_fr, int _sb_partial,int _sb_full){ - ptrdiff_t bits; - int sb_partial_count; - int sb_full_count; - bits=_fr->bits; + int bits; + int sb_partial_count; + int sb_full_count; + bits=0; + sb_partial_count=_fr->sb_partial_count; /*Extend the sb_partial run, or start a new one.*/ - sb_partial_count=_fr->sb_partial; if(_fr->sb_partial==_sb_partial){ if(sb_partial_count>=4129){ bits++; @@ -257,8 +252,7 @@ static void oc_fr_state_advance_sb(oc_fr_state *_fr, else bits-=oc_sb_run_bits(sb_partial_count); } else sb_partial_count=0; - sb_partial_count++; - bits+=oc_sb_run_bits(sb_partial_count); + bits+=oc_sb_run_bits(++sb_partial_count); if(!_sb_partial){ /*Extend the sb_full run, or start a new one.*/ sb_full_count=_fr->sb_full_count; @@ -270,98 +264,161 @@ static void oc_fr_state_advance_sb(oc_fr_state *_fr, else bits-=oc_sb_run_bits(sb_full_count); } else sb_full_count=0; + bits+=oc_sb_run_bits(++sb_full_count); + } + return bits; +} + +static void oc_fr_state_advance_sb(oc_fr_state *_fr, + int _sb_partial,int _sb_full){ + int sb_partial_count; + int sb_full_count; + sb_partial_count=_fr->sb_partial_count; + if(_fr->sb_partial!=_sb_partial||sb_partial_count>=4129)sb_partial_count=0; + sb_partial_count++; + if(!_sb_partial){ + sb_full_count=_fr->sb_full_count; + if(_fr->sb_full!=_sb_full||sb_full_count>=4129)sb_full_count=0; sb_full_count++; - bits+=oc_sb_run_bits(sb_full_count); - _fr->sb_full=_sb_full; _fr->sb_full_count=sb_full_count; + _fr->sb_full=_sb_full; + /*Roll back the partial block state.*/ + _fr->b_coded=_fr->b_coded_prev; + _fr->b_coded_count=_fr->b_coded_count_prev; + } + else{ + /*Commit back the partial block state.*/ + _fr->b_coded_prev=_fr->b_coded; + _fr->b_coded_count_prev=_fr->b_coded_count; } - _fr->bits=bits; - _fr->sb_partial=_sb_partial; _fr->sb_partial_count=sb_partial_count; + _fr->sb_partial=_sb_partial; + _fr->b_count=0; + _fr->sb_prefer_partial=0; + _fr->sb_bits=0; } -/*Flush any outstanding block flags for a SB (e.g., one with fewer than 16 - blocks).*/ +/*Commit the state of the current super block and advance to the next.*/ static void oc_fr_state_flush_sb(oc_fr_state *_fr){ - ptrdiff_t bits; - int sb_partial; - int sb_full=sb_full; - int b_coded_count; - int b_coded; - int b_count; + int sb_partial; + int sb_full; + int b_coded_count; + int b_count; b_count=_fr->b_count; - if(b_count>0){ - bits=_fr->bits; - b_coded=_fr->b_coded; - b_coded_count=_fr->b_coded_count; - if(b_coded_count>=b_count){ - /*This SB was fully coded/uncoded; roll back the partial block flags.*/ - bits-=oc_block_run_bits(b_coded_count); - if(b_coded_count>b_count)bits+=oc_block_run_bits(b_coded_count-b_count); - sb_partial=0; - sb_full=b_coded; - b_coded=_fr->b_coded_prev; - b_coded_count=_fr->b_coded_count_prev; - } - else{ - /*It was partially coded.*/ - sb_partial=1; - /*sb_full is unused.*/ + b_coded_count=_fr->b_coded_count; + sb_full=_fr->b_coded; + sb_partial=b_coded_count<b_count; + if(!sb_partial){ + /*If the super block is fully coded/uncoded...*/ + if(_fr->sb_prefer_partial){ + /*So far coding this super block as partial was cheaper anyway.*/ + if(b_coded_count>15||_fr->b_coded_prev<0){ + int sb_bits; + /*If the block run is too long, this will limit how far it can be + extended into the next partial super block. + If we need to extend it farther, we don't want to have to roll all + the way back here (since there could be many full SBs between now + and then), so we disallow this. + Similarly, if this is the start of a stripe, we don't know how the + length of the outstanding block run from the previous stripe.*/ + sb_bits=oc_fr_state_sb_cost(_fr,sb_partial,sb_full); + _fr->bits+=sb_bits-_fr->sb_bits; + _fr->sb_bits=sb_bits; + } + else sb_partial=1; } - _fr->bits=bits; - _fr->b_coded_count=b_coded_count; - _fr->b_coded_count_prev=b_coded_count; - _fr->b_count=0; - _fr->b_coded=b_coded; - _fr->b_coded_prev=b_coded; - oc_fr_state_advance_sb(_fr,sb_partial,sb_full); } + oc_fr_state_advance_sb(_fr,sb_partial,sb_full); } static void oc_fr_state_advance_block(oc_fr_state *_fr,int _b_coded){ ptrdiff_t bits; + int sb_bits; int b_coded_count; int b_count; - int sb_partial; - int sb_full=sb_full; - bits=_fr->bits; - /*Extend the b_coded run, or start a new one.*/ + int sb_prefer_partial; + sb_bits=_fr->sb_bits; + bits=_fr->bits-sb_bits; + b_count=_fr->b_count; b_coded_count=_fr->b_coded_count; - if(_fr->b_coded==_b_coded)bits-=oc_block_run_bits(b_coded_count); - else b_coded_count=0; - b_coded_count++; - b_count=_fr->b_count+1; - if(b_count>=16){ - /*We finished a superblock.*/ - if(b_coded_count>=16){ - /*It was fully coded/uncoded; roll back the partial block flags.*/ - if(b_coded_count>16)bits+=oc_block_run_bits(b_coded_count-16); - sb_partial=0; - sb_full=_b_coded; - _b_coded=_fr->b_coded_prev; - b_coded_count=_fr->b_coded_count_prev; + sb_prefer_partial=_fr->sb_prefer_partial; + if(b_coded_count>=b_count){ + int sb_partial_bits; + /*This super block is currently fully coded/uncoded.*/ + if(b_count<=0){ + /*This is the first block in this SB.*/ + b_count=1; + /*Check to see whether it's cheaper to code it partially or fully.*/ + if(_fr->b_coded==_b_coded){ + sb_partial_bits=-oc_block_run_bits(b_coded_count); + sb_partial_bits+=oc_block_run_bits(++b_coded_count); + } + else{ + b_coded_count=1; + sb_partial_bits=2; + } + sb_partial_bits+=oc_fr_state_sb_cost(_fr,1,_b_coded); + sb_bits=oc_fr_state_sb_cost(_fr,0,_b_coded); + sb_prefer_partial=sb_partial_bits<sb_bits; + sb_bits^=(sb_partial_bits^sb_bits)&-sb_prefer_partial; + } + else if(_fr->b_coded==_b_coded){ + b_coded_count++; + if(++b_count<16){ + if(sb_prefer_partial){ + /*Check to see if it's cheaper to code it fully.*/ + sb_partial_bits=sb_bits; + sb_partial_bits+=oc_block_run_bits(b_coded_count); + if(b_coded_count>0){ + sb_partial_bits-=oc_block_run_bits(b_coded_count-1); + } + sb_bits=oc_fr_state_sb_cost(_fr,0,_b_coded); + sb_prefer_partial=sb_partial_bits<sb_bits; + sb_bits^=(sb_partial_bits^sb_bits)&-sb_prefer_partial; + } + /*There's no need to check the converse (whether it's cheaper to code + this SB partially if we were coding it fully), since the cost to + code a SB partially can only increase as we add more blocks, whereas + the cost to code it fully stays constant.*/ + } + else{ + /*If we get to the end and this SB is still full, then force it to be + coded full. + Otherwise we might not be able to extend the block run far enough + into the next partial SB.*/ + if(sb_prefer_partial){ + sb_prefer_partial=0; + sb_bits=oc_fr_state_sb_cost(_fr,0,_b_coded); + } + } } else{ - bits+=oc_block_run_bits(b_coded_count); - /*It was partially coded.*/ - sb_partial=1; - /*sb_full is unused.*/ + /*This SB was full, but now must be made partial.*/ + if(!sb_prefer_partial){ + sb_bits=oc_block_run_bits(b_coded_count); + if(b_coded_count>b_count){ + sb_bits-=oc_block_run_bits(b_coded_count-b_count); + } + sb_bits+=oc_fr_state_sb_cost(_fr,1,_b_coded); + } + b_count++; + b_coded_count=1; + sb_prefer_partial=1; + sb_bits+=2; } - _fr->bits=bits; - _fr->b_coded_count=b_coded_count; - _fr->b_coded_count_prev=b_coded_count; - _fr->b_count=0; - _fr->b_coded=_b_coded; - _fr->b_coded_prev=_b_coded; - oc_fr_state_advance_sb(_fr,sb_partial,sb_full); } else{ - bits+=oc_block_run_bits(b_coded_count); - _fr->bits=bits; - _fr->b_coded_count=b_coded_count; - _fr->b_count=b_count; - _fr->b_coded=_b_coded; + b_count++; + if(_fr->b_coded==_b_coded)sb_bits-=oc_block_run_bits(b_coded_count); + else b_coded_count=0; + sb_bits+=oc_block_run_bits(++b_coded_count); } + _fr->bits=bits+sb_bits; + _fr->b_coded_count=b_coded_count; + _fr->b_coded=_b_coded; + _fr->b_count=b_count; + _fr->sb_prefer_partial=sb_prefer_partial; + _fr->sb_bits=sb_bits; } static void oc_fr_skip_block(oc_fr_state *_fr){ @@ -395,16 +452,6 @@ static int oc_fr_cost4(const oc_fr_state *_pre,const oc_fr_state *_post){ -struct oc_qii_state{ - ptrdiff_t bits; - unsigned qi01_count:14; - signed int qi01:2; - unsigned qi12_count:14; - signed int qi12:2; -}; - - - static void oc_qii_state_init(oc_qii_state *_qs){ _qs->bits=0; _qs->qi01_count=0; @@ -458,49 +505,17 @@ static void oc_qii_state_advance(oc_qii_state *_qd, -/*Temporary encoder state for the analysis pipeline.*/ -struct oc_enc_pipeline_state{ - int bounding_values[256]; - oc_fr_state fr[3]; - oc_qii_state qs[3]; - /*Condensed dequantization tables.*/ - const ogg_uint16_t *dequant[3][3][2]; - /*Condensed quantization tables.*/ - const oc_iquant *enquant[3][3][2]; - /*Skip SSD storage for the current MCU in each plane.*/ - unsigned *skip_ssd[3]; - /*Coded/uncoded fragment lists for each plane for the current MCU.*/ - ptrdiff_t *coded_fragis[3]; - ptrdiff_t *uncoded_fragis[3]; - ptrdiff_t ncoded_fragis[3]; - ptrdiff_t nuncoded_fragis[3]; - /*The starting fragment for the current MCU in each plane.*/ - ptrdiff_t froffset[3]; - /*The starting row for the current MCU in each plane.*/ - int fragy0[3]; - /*The ending row for the current MCU in each plane.*/ - int fragy_end[3]; - /*The starting superblock for the current MCU in each plane.*/ - unsigned sbi0[3]; - /*The ending superblock for the current MCU in each plane.*/ - unsigned sbi_end[3]; - /*The number of tokens for zzi=1 for each color plane.*/ - int ndct_tokens1[3]; - /*The outstanding eob_run count for zzi=1 for each color plane.*/ - int eob_run1[3]; - /*Whether or not the loop filter is enabled.*/ - int loop_filter; -}; - - static void oc_enc_pipeline_init(oc_enc_ctx *_enc,oc_enc_pipeline_state *_pipe){ ptrdiff_t *coded_fragis; unsigned mcu_nvsbs; ptrdiff_t mcu_nfrags; + int flimit; int hdec; int vdec; int pli; + int nqis; int qii; + int qi0; int qti; /*Initialize the per-plane coded block flag trackers. These are used for bit-estimation purposes only; the real flag bits span @@ -529,24 +544,36 @@ static void oc_enc_pipeline_init(oc_enc_ctx *_enc,oc_enc_pipeline_state *_pipe){ memset(_pipe->ncoded_fragis,0,sizeof(_pipe->ncoded_fragis)); memset(_pipe->nuncoded_fragis,0,sizeof(_pipe->nuncoded_fragis)); /*Set up condensed quantizer tables.*/ + qi0=_enc->state.qis[0]; + nqis=_enc->state.nqis; for(pli=0;pli<3;pli++){ - for(qii=0;qii<_enc->state.nqis;qii++){ + for(qii=0;qii<nqis;qii++){ int qi; qi=_enc->state.qis[qii]; for(qti=0;qti<2;qti++){ - _pipe->dequant[pli][qii][qti]=_enc->state.dequant_tables[qi][pli][qti]; - _pipe->enquant[pli][qii][qti]=_enc->enquant_tables[qi][pli][qti]; + /*Set the DC coefficient in the dequantization table.*/ + _enc->state.dequant_tables[qi][pli][qti][0]= + _enc->dequant_dc[qi0][pli][qti]; + _enc->dequant[pli][qii][qti]=_enc->state.dequant_tables[qi][pli][qti]; + /*Copy over the quantization table.*/ + memcpy(_enc->enquant[pli][qii][qti],_enc->enquant_tables[qi][pli][qti], + _enc->opt_data.enquant_table_size); } } } + /*Fix up the DC coefficients in the quantization tables.*/ + oc_enc_enquant_table_fixup(_enc,_enc->enquant,nqis); /*Initialize the tokenization state.*/ for(pli=0;pli<3;pli++){ _pipe->ndct_tokens1[pli]=0; _pipe->eob_run1[pli]=0; } /*Initialize the bounding value array for the loop filter.*/ - _pipe->loop_filter=!oc_state_loop_filter_init(&_enc->state, - _pipe->bounding_values); + flimit=_enc->state.loop_filter_limits[_enc->state.qis[0]]; + _pipe->loop_filter=flimit!=0; + if(flimit!=0)oc_loop_filter_init(&_enc->state,_pipe->bounding_values,flimit); + /*Clear the temporary DCT scratch space.*/ + memset(_pipe->dct_data,0,sizeof(_pipe->dct_data)); } /*Sets the current MCU stripe to super block row _sby. @@ -585,13 +612,17 @@ static int oc_enc_pipeline_set_stripe(oc_enc_ctx *_enc, static void oc_enc_pipeline_finish_mcu_plane(oc_enc_ctx *_enc, oc_enc_pipeline_state *_pipe,int _pli,int _sdelay,int _edelay){ - int refi; /*Copy over all the uncoded fragments from this plane and advance the uncoded fragment list.*/ - _pipe->uncoded_fragis[_pli]-=_pipe->nuncoded_fragis[_pli]; - oc_state_frag_copy_list(&_enc->state,_pipe->uncoded_fragis[_pli], - _pipe->nuncoded_fragis[_pli],OC_FRAME_SELF,OC_FRAME_PREV,_pli); - _pipe->nuncoded_fragis[_pli]=0; + if(_pipe->nuncoded_fragis[_pli]>0){ + _pipe->uncoded_fragis[_pli]-=_pipe->nuncoded_fragis[_pli]; + oc_frag_copy_list(&_enc->state, + _enc->state.ref_frame_data[OC_FRAME_SELF], + _enc->state.ref_frame_data[OC_FRAME_PREV], + _enc->state.ref_ystride[_pli],_pipe->uncoded_fragis[_pli], + _pipe->nuncoded_fragis[_pli],_enc->state.frag_buf_offs); + _pipe->nuncoded_fragis[_pli]=0; + } /*Perform DC prediction.*/ oc_enc_pred_dc_frag_rows(_enc,_pli, _pipe->fragy0[_pli],_pipe->fragy_end[_pli]); @@ -606,17 +637,18 @@ static void oc_enc_pipeline_finish_mcu_plane(oc_enc_ctx *_enc, _pipe->coded_fragis[_pli]+=_pipe->ncoded_fragis[_pli]; _pipe->ncoded_fragis[_pli]=0; /*Apply the loop filter if necessary.*/ - refi=_enc->state.ref_frame_idx[OC_FRAME_SELF]; if(_pipe->loop_filter){ - oc_state_loop_filter_frag_rows(&_enc->state,_pipe->bounding_values, - refi,_pli,_pipe->fragy0[_pli]-_sdelay,_pipe->fragy_end[_pli]-_edelay); + oc_state_loop_filter_frag_rows(&_enc->state, + _pipe->bounding_values,OC_FRAME_SELF,_pli, + _pipe->fragy0[_pli]-_sdelay,_pipe->fragy_end[_pli]-_edelay); } else _sdelay=_edelay=0; /*To fill borders, we have an additional two pixel delay, since a fragment in the next row could filter its top edge, using two pixels from a fragment in this row. But there's no reason to delay a full fragment between the two.*/ - oc_state_borders_fill_rows(&_enc->state,refi,_pli, + oc_state_borders_fill_rows(&_enc->state, + _enc->state.ref_frame_idx[OC_FRAME_SELF],_pli, (_pipe->fragy0[_pli]-_sdelay<<3)-(_sdelay<<1), (_pipe->fragy_end[_pli]-_edelay<<3)-(_edelay<<1)); } @@ -634,62 +666,62 @@ struct oc_rd_metric{ static int oc_enc_block_transform_quantize(oc_enc_ctx *_enc, - oc_enc_pipeline_state *_pipe,int _pli,ptrdiff_t _fragi,int _overhead_bits, - oc_rd_metric *_mo,oc_token_checkpoint **_stack){ - OC_ALIGN16(ogg_int16_t dct[64]); - OC_ALIGN16(ogg_int16_t data[64]); - ogg_uint16_t dc_dequant; + oc_enc_pipeline_state *_pipe,int _pli,ptrdiff_t _fragi, + unsigned _rd_scale,unsigned _rd_iscale,oc_rd_metric *_mo, + oc_fr_state *_fr,oc_token_checkpoint **_stack){ + ogg_int16_t *data; + ogg_int16_t *dct; + ogg_int16_t *idct; + oc_qii_state qs; const ogg_uint16_t *dequant; - const oc_iquant *enquant; + ogg_uint16_t dequant_dc; ptrdiff_t frag_offs; int ystride; const unsigned char *src; const unsigned char *ref; unsigned char *dst; - int frame_type; int nonzero; unsigned uncoded_ssd; unsigned coded_ssd; - int coded_dc; oc_token_checkpoint *checkpoint; oc_fragment *frags; int mb_mode; + int refi; int mv_offs[2]; int nmv_offs; int ac_bits; int borderi; + int nqis; int qti; int qii; - int pi; - int zzi; - int v; - int val; - int d; - int s; int dc; + nqis=_enc->state.nqis; frags=_enc->state.frags; frag_offs=_enc->state.frag_buf_offs[_fragi]; ystride=_enc->state.ref_ystride[_pli]; src=_enc->state.ref_frame_data[OC_FRAME_IO]+frag_offs; borderi=frags[_fragi].borderi; qii=frags[_fragi].qii; + data=_enc->pipe.dct_data; + dct=data+64; + idct=data+128; if(qii&~3){ #if !defined(OC_COLLECT_METRICS) if(_enc->sp_level>=OC_SP_LEVEL_EARLY_SKIP){ /*Enable early skip detection.*/ frags[_fragi].coded=0; + frags[_fragi].refi=OC_FRAME_NONE; + oc_fr_skip_block(_fr); return 0; } #endif /*Try and code this block anyway.*/ qii&=3; - frags[_fragi].qii=qii; } + refi=frags[_fragi].refi; mb_mode=frags[_fragi].mb_mode; - ref=_enc->state.ref_frame_data[ - _enc->state.ref_frame_idx[OC_FRAME_FOR_MODE(mb_mode)]]+frag_offs; - dst=_enc->state.ref_frame_data[_enc->state.ref_frame_idx[OC_FRAME_SELF]] - +frag_offs; + ref=_enc->state.ref_frame_data[refi]+frag_offs; + dst=_enc->state.ref_frame_data[OC_FRAME_SELF]+frag_offs; /*Motion compensation:*/ switch(mb_mode){ case OC_MODE_INTRA:{ @@ -704,9 +736,9 @@ static int oc_enc_block_transform_quantize(oc_enc_ctx *_enc, }break; default:{ const oc_mv *frag_mvs; - frag_mvs=(const oc_mv *)_enc->state.frag_mvs; - nmv_offs=oc_state_get_mv_offsets(&_enc->state,mv_offs,_pli, - frag_mvs[_fragi][0],frag_mvs[_fragi][1]); + frag_mvs=_enc->state.frag_mvs; + nmv_offs=oc_state_get_mv_offsets(&_enc->state,mv_offs, + _pli,frag_mvs[_fragi]); if(nmv_offs>1){ oc_enc_frag_copy2(_enc,dst, ref+mv_offs[0],ref+mv_offs[1],ystride); @@ -717,126 +749,121 @@ static int oc_enc_block_transform_quantize(oc_enc_ctx *_enc, } #if defined(OC_COLLECT_METRICS) { + unsigned sad; unsigned satd; switch(nmv_offs){ - case 0:satd=oc_enc_frag_intra_satd(_enc,src,ystride);break; + case 0:{ + sad=oc_enc_frag_intra_sad(_enc,src,ystride); + satd=oc_enc_frag_intra_satd(_enc,&dc,src,ystride); + }break; case 1:{ - satd=oc_enc_frag_satd_thresh(_enc,src,ref+mv_offs[0],ystride,UINT_MAX); + sad=oc_enc_frag_sad_thresh(_enc,src,ref+mv_offs[0],ystride,UINT_MAX); + satd=oc_enc_frag_satd(_enc,&dc,src,ref+mv_offs[0],ystride); + satd+=abs(dc); }break; default:{ - satd=oc_enc_frag_satd_thresh(_enc,src,dst,ystride,UINT_MAX); - } + sad=oc_enc_frag_sad_thresh(_enc,src,dst,ystride,UINT_MAX); + satd=oc_enc_frag_satd(_enc,&dc,src,dst,ystride); + satd+=abs(dc); + }break; } + _enc->frag_sad[_fragi]=sad; _enc->frag_satd[_fragi]=satd; } #endif /*Transform:*/ oc_enc_fdct8x8(_enc,dct,data); - /*Quantize the DC coefficient:*/ + /*Quantize:*/ qti=mb_mode!=OC_MODE_INTRA; - enquant=_pipe->enquant[_pli][0][qti]; - dc_dequant=_pipe->dequant[_pli][0][qti][0]; - v=dct[0]; - val=v<<1; - s=OC_SIGNMASK(val); - val+=dc_dequant+s^s; - val=((enquant[0].m*(ogg_int32_t)val>>16)+val>>enquant[0].l)-s; - dc=OC_CLAMPI(-580,val,580); - nonzero=0; - /*Quantize the AC coefficients:*/ - dequant=_pipe->dequant[_pli][qii][qti]; - enquant=_pipe->enquant[_pli][qii][qti]; - for(zzi=1;zzi<64;zzi++){ - v=dct[OC_FZIG_ZAG[zzi]]; - d=dequant[zzi]; - val=v<<1; - v=abs(val); - if(v>=d){ - s=OC_SIGNMASK(val); - /*The bias added here rounds ties away from zero, since token - optimization can only decrease the magnitude of the quantized - value.*/ - val+=d+s^s; - /*Note the arithmetic right shift is not guaranteed by ANSI C. - Hopefully no one still uses ones-complement architectures.*/ - val=((enquant[zzi].m*(ogg_int32_t)val>>16)+val>>enquant[zzi].l)-s; - data[zzi]=OC_CLAMPI(-580,val,580); - nonzero=zzi; - } - else data[zzi]=0; - } + dequant=_enc->dequant[_pli][qii][qti]; + nonzero=oc_enc_quantize(_enc,data,dct,dequant,_enc->enquant[_pli][qii][qti]); + dc=data[0]; /*Tokenize.*/ checkpoint=*_stack; - ac_bits=oc_enc_tokenize_ac(_enc,_pli,_fragi,data,dequant,dct,nonzero+1, - _stack,qti?0:3); + if(_enc->sp_level<OC_SP_LEVEL_FAST_ANALYSIS){ + ac_bits=oc_enc_tokenize_ac(_enc,_pli,_fragi,idct,data,dequant,dct, + nonzero+1,_stack,OC_RD_ISCALE(_enc->lambda,_rd_iscale),qti?0:3); + } + else{ + ac_bits=oc_enc_tokenize_ac_fast(_enc,_pli,_fragi,idct,data,dequant,dct, + nonzero+1,_stack,OC_RD_ISCALE(_enc->lambda,_rd_iscale),qti?0:3); + } /*Reconstruct. TODO: nonzero may need to be adjusted after tokenization.*/ + dequant_dc=dequant[0]; if(nonzero==0){ ogg_int16_t p; int ci; + int qi01; + int qi12; /*We round this dequant product (and not any of the others) because there's no iDCT rounding.*/ - p=(ogg_int16_t)(dc*(ogg_int32_t)dc_dequant+15>>5); + p=(ogg_int16_t)(dc*(ogg_int32_t)dequant_dc+15>>5); /*LOOP VECTORIZES.*/ for(ci=0;ci<64;ci++)data[ci]=p; + /*We didn't code any AC coefficients, so don't change the quantizer.*/ + qi01=_pipe->qs[_pli].qi01; + qi12=_pipe->qs[_pli].qi12; + if(qi01>0)qii=1+qi12; + else if(qi01>=0)qii=0; } else{ - data[0]=dc*dc_dequant; - oc_idct8x8(&_enc->state,data,nonzero+1); + idct[0]=dc*dequant_dc; + /*Note: This clears idct[] back to zero for the next block.*/ + oc_idct8x8(&_enc->state,data,idct,nonzero+1); + } + frags[_fragi].qii=qii; + if(nqis>1){ + oc_qii_state_advance(&qs,_pipe->qs+_pli,qii); + ac_bits+=qs.bits-_pipe->qs[_pli].bits; } if(!qti)oc_enc_frag_recon_intra(_enc,dst,ystride,data); else{ oc_enc_frag_recon_inter(_enc,dst, nmv_offs==1?ref+mv_offs[0]:dst,ystride,data); } - frame_type=_enc->state.frame_type; + /*If _fr is NULL, then this is an INTRA frame, and we can't skip blocks.*/ #if !defined(OC_COLLECT_METRICS) - if(frame_type!=OC_INTRA_FRAME) + if(_fr!=NULL) #endif { /*In retrospect, should we have skipped this block?*/ - oc_enc_frag_sub(_enc,data,src,dst,ystride); - coded_ssd=coded_dc=0; if(borderi<0){ - for(pi=0;pi<64;pi++){ - coded_ssd+=data[pi]*data[pi]; - coded_dc+=data[pi]; - } + coded_ssd=oc_enc_frag_ssd(_enc,src,dst,ystride); } else{ - ogg_int64_t mask; - mask=_enc->state.borders[borderi].mask; - for(pi=0;pi<64;pi++,mask>>=1)if(mask&1){ - coded_ssd+=data[pi]*data[pi]; - coded_dc+=data[pi]; - } + coded_ssd=oc_enc_frag_border_ssd(_enc,src,dst,ystride, + _enc->state.borders[borderi].mask); } /*Scale to match DCT domain.*/ coded_ssd<<=4; - /*We actually only want the AC contribution to the SSD.*/ - coded_ssd-=coded_dc*coded_dc>>2; #if defined(OC_COLLECT_METRICS) _enc->frag_ssd[_fragi]=coded_ssd; } - if(frame_type!=OC_INTRA_FRAME){ + if(_fr!=NULL){ #endif + coded_ssd=OC_RD_SCALE(coded_ssd,_rd_scale); uncoded_ssd=_pipe->skip_ssd[_pli][_fragi-_pipe->froffset[_pli]]; - if(uncoded_ssd<UINT_MAX){ + if(uncoded_ssd<UINT_MAX&& + /*Don't allow luma blocks to be skipped in 4MV mode when VP3 compatibility + is enabled.*/ + (!_enc->vp3_compatible||mb_mode!=OC_MODE_INTER_MV_FOUR||_pli)){ + int overhead_bits; + overhead_bits=oc_fr_cost1(_fr); /*Although the fragment coding overhead determination is accurate, it is greedy, using very coarse-grained local information. Allowing it to mildly discourage coding turns out to be beneficial, but it's not clear that allowing it to encourage coding through negative coding overhead deltas is useful. - For that reason, we disallow negative coding_overheads.*/ - if(_overhead_bits<0)_overhead_bits=0; - if(uncoded_ssd<=coded_ssd+(_overhead_bits+ac_bits)*_enc->lambda&& - /*Don't allow luma blocks to be skipped in 4MV mode when VP3 - compatibility is enabled.*/ - (!_enc->vp3_compatible||mb_mode!=OC_MODE_INTER_MV_FOUR||_pli)){ + For that reason, we disallow negative coding overheads.*/ + if(overhead_bits<0)overhead_bits=0; + if(uncoded_ssd<=coded_ssd+(overhead_bits+ac_bits)*_enc->lambda){ /*Hm, not worth it; roll back.*/ oc_enc_tokenlog_rollback(_enc,checkpoint,(*_stack)-checkpoint); *_stack=checkpoint; frags[_fragi].coded=0; + frags[_fragi].refi=OC_FRAME_NONE; + oc_fr_skip_block(_fr); return 0; } } @@ -844,15 +871,20 @@ static int oc_enc_block_transform_quantize(oc_enc_ctx *_enc, _mo->uncoded_ac_ssd+=uncoded_ssd; _mo->coded_ac_ssd+=coded_ssd; _mo->ac_bits+=ac_bits; + oc_fr_code_block(_fr); } - oc_qii_state_advance(_pipe->qs+_pli,_pipe->qs+_pli,qii); + /*GCC 4.4.4 generates a warning here because it can't tell that + the init code in the nqis check above will run anytime this + line runs.*/ + if(nqis>1)*(_pipe->qs+_pli)=*&qs; frags[_fragi].dc=dc; frags[_fragi].coded=1; return 1; } -static int oc_enc_mb_transform_quantize_luma(oc_enc_ctx *_enc, - oc_enc_pipeline_state *_pipe,unsigned _mbi,int _mode_overhead){ +static int oc_enc_mb_transform_quantize_inter_luma(oc_enc_ctx *_enc, + oc_enc_pipeline_state *_pipe,unsigned _mbi,int _mode_overhead, + const unsigned _rd_scale[4],const unsigned _rd_iscale[4]){ /*Worst case token stack usage for 4 fragments.*/ oc_token_checkpoint stack[64*4]; oc_token_checkpoint *stackptr; @@ -867,6 +899,7 @@ static int oc_enc_mb_transform_quantize_luma(oc_enc_ctx *_enc, oc_fr_state fr_checkpoint; oc_qii_state qs_checkpoint; int mb_mode; + int refi; int ncoded; ptrdiff_t fragi; int bi; @@ -880,78 +913,83 @@ static int oc_enc_mb_transform_quantize_luma(oc_enc_ctx *_enc, uncoded_fragis=_pipe->uncoded_fragis[0]; nuncoded_fragis=_pipe->nuncoded_fragis[0]; mb_mode=mb_modes[_mbi]; + refi=OC_FRAME_FOR_MODE(mb_mode); ncoded=0; stackptr=stack; memset(&mo,0,sizeof(mo)); for(bi=0;bi<4;bi++){ fragi=sb_maps[_mbi>>2][_mbi&3][bi]; + frags[fragi].refi=refi; frags[fragi].mb_mode=mb_mode; - if(oc_enc_block_transform_quantize(_enc, - _pipe,0,fragi,oc_fr_cost1(_pipe->fr+0),&mo,&stackptr)){ - oc_fr_code_block(_pipe->fr+0); + if(oc_enc_block_transform_quantize(_enc,_pipe,0,fragi, + _rd_scale[bi],_rd_iscale[bi],&mo,_pipe->fr+0,&stackptr)){ coded_fragis[ncoded_fragis++]=fragi; ncoded++; } - else{ - *(uncoded_fragis-++nuncoded_fragis)=fragi; - oc_fr_skip_block(_pipe->fr+0); - } + else *(uncoded_fragis-++nuncoded_fragis)=fragi; } - if(_enc->state.frame_type!=OC_INTRA_FRAME){ - if(ncoded>0&&!mo.dc_flag){ - int cost; - /*Some individual blocks were worth coding. - See if that's still true when accounting for mode and MV overhead.*/ - cost=mo.coded_ac_ssd+_enc->lambda*(mo.ac_bits - +oc_fr_cost4(&fr_checkpoint,_pipe->fr+0)+_mode_overhead); - if(mo.uncoded_ac_ssd<=cost){ - /*Taking macroblock overhead into account, it is not worth coding this - MB.*/ - oc_enc_tokenlog_rollback(_enc,stack,stackptr-stack); - *(_pipe->fr+0)=*&fr_checkpoint; - *(_pipe->qs+0)=*&qs_checkpoint; - for(bi=0;bi<4;bi++){ - fragi=sb_maps[_mbi>>2][_mbi&3][bi]; - if(frags[fragi].coded){ - *(uncoded_fragis-++nuncoded_fragis)=fragi; - frags[fragi].coded=0; - } - oc_fr_skip_block(_pipe->fr+0); + if(ncoded>0&&!mo.dc_flag){ + int cost; + /*Some individual blocks were worth coding. + See if that's still true when accounting for mode and MV overhead.*/ + cost=mo.coded_ac_ssd+_enc->lambda*(mo.ac_bits + +oc_fr_cost4(&fr_checkpoint,_pipe->fr+0)+_mode_overhead); + if(mo.uncoded_ac_ssd<=cost){ + /*Taking macroblock overhead into account, it is not worth coding this + MB.*/ + oc_enc_tokenlog_rollback(_enc,stack,stackptr-stack); + *(_pipe->fr+0)=*&fr_checkpoint; + *(_pipe->qs+0)=*&qs_checkpoint; + for(bi=0;bi<4;bi++){ + fragi=sb_maps[_mbi>>2][_mbi&3][bi]; + if(frags[fragi].coded){ + *(uncoded_fragis-++nuncoded_fragis)=fragi; + frags[fragi].coded=0; + frags[fragi].refi=OC_FRAME_NONE; } - ncoded_fragis-=ncoded; - ncoded=0; + oc_fr_skip_block(_pipe->fr+0); } - } - /*If no luma blocks coded, the mode is forced.*/ - if(ncoded==0)mb_modes[_mbi]=OC_MODE_INTER_NOMV; - /*Assume that a 1MV with a single coded block is always cheaper than a 4MV - with a single coded block. - This may not be strictly true: a 4MV computes chroma MVs using (0,0) for - skipped blocks, while a 1MV does not.*/ - else if(ncoded==1&&mb_mode==OC_MODE_INTER_MV_FOUR){ - mb_modes[_mbi]=OC_MODE_INTER_MV; + ncoded_fragis-=ncoded; + ncoded=0; } } + /*If no luma blocks coded, the mode is forced.*/ + if(ncoded==0)mb_modes[_mbi]=OC_MODE_INTER_NOMV; + /*Assume that a 1MV with a single coded block is always cheaper than a 4MV + with a single coded block. + This may not be strictly true: a 4MV computes chroma MVs using (0,0) for + skipped blocks, while a 1MV does not.*/ + else if(ncoded==1&&mb_mode==OC_MODE_INTER_MV_FOUR){ + mb_modes[_mbi]=OC_MODE_INTER_MV; + } _pipe->ncoded_fragis[0]=ncoded_fragis; _pipe->nuncoded_fragis[0]=nuncoded_fragis; return ncoded; } -static void oc_enc_sb_transform_quantize_chroma(oc_enc_ctx *_enc, +static void oc_enc_sb_transform_quantize_inter_chroma(oc_enc_ctx *_enc, oc_enc_pipeline_state *_pipe,int _pli,int _sbi_start,int _sbi_end){ - const oc_sb_map *sb_maps; - oc_sb_flags *sb_flags; - ptrdiff_t *coded_fragis; - ptrdiff_t ncoded_fragis; - ptrdiff_t *uncoded_fragis; - ptrdiff_t nuncoded_fragis; - int sbi; + const ogg_uint16_t *mcu_rd_scale; + const ogg_uint16_t *mcu_rd_iscale; + const oc_sb_map *sb_maps; + oc_sb_flags *sb_flags; + oc_fr_state *fr; + ptrdiff_t *coded_fragis; + ptrdiff_t ncoded_fragis; + ptrdiff_t *uncoded_fragis; + ptrdiff_t nuncoded_fragis; + ptrdiff_t froffset; + int sbi; + fr=_pipe->fr+_pli; + mcu_rd_scale=(const ogg_uint16_t *)_enc->mcu_rd_scale; + mcu_rd_iscale=(const ogg_uint16_t *)_enc->mcu_rd_iscale; sb_maps=(const oc_sb_map *)_enc->state.sb_maps; sb_flags=_enc->state.sb_flags; coded_fragis=_pipe->coded_fragis[_pli]; ncoded_fragis=_pipe->ncoded_fragis[_pli]; uncoded_fragis=_pipe->uncoded_fragis[_pli]; nuncoded_fragis=_pipe->nuncoded_fragis[_pli]; + froffset=_pipe->froffset[_pli]; for(sbi=_sbi_start;sbi<_sbi_end;sbi++){ /*Worst case token stack usage for 1 fragment.*/ oc_token_checkpoint stack[64]; @@ -964,21 +1002,21 @@ static void oc_enc_sb_transform_quantize_chroma(oc_enc_ctx *_enc, fragi=sb_maps[sbi][quadi][bi]; if(fragi>=0){ oc_token_checkpoint *stackptr; + unsigned rd_scale; + unsigned rd_iscale; + rd_scale=mcu_rd_scale[fragi-froffset]; + rd_iscale=mcu_rd_iscale[fragi-froffset]; stackptr=stack; - if(oc_enc_block_transform_quantize(_enc, - _pipe,_pli,fragi,oc_fr_cost1(_pipe->fr+_pli),&mo,&stackptr)){ + if(oc_enc_block_transform_quantize(_enc,_pipe,_pli,fragi, + rd_scale,rd_iscale,&mo,fr,&stackptr)){ coded_fragis[ncoded_fragis++]=fragi; - oc_fr_code_block(_pipe->fr+_pli); - } - else{ - *(uncoded_fragis-++nuncoded_fragis)=fragi; - oc_fr_skip_block(_pipe->fr+_pli); } + else *(uncoded_fragis-++nuncoded_fragis)=fragi; } } - oc_fr_state_flush_sb(_pipe->fr+_pli); - sb_flags[sbi].coded_fully=_pipe->fr[_pli].sb_full; - sb_flags[sbi].coded_partially=_pipe->fr[_pli].sb_partial; + oc_fr_state_flush_sb(fr); + sb_flags[sbi].coded_fully=fr->sb_full; + sb_flags[sbi].coded_partially=fr->sb_partial; } _pipe->ncoded_fragis[_pli]=ncoded_fragis; _pipe->nuncoded_fragis[_pli]=nuncoded_fragis; @@ -1006,8 +1044,8 @@ static void oc_enc_sb_transform_quantize_chroma(oc_enc_ctx *_enc, The bit counts and SSD measurements are obtained by examining actual encoded frames, with appropriate lambda values and optimal Huffman codes selected. EOB bits are assigned to the fragment that started the EOB run (as opposed to - dividing them among all the blocks in the run; though the latter approach - seems more theoretically correct, Monty's testing showed a small improvement + dividing them among all the blocks in the run; the latter approach seems + more theoretically correct, but Monty's testing showed a small improvement with the former, though that may have been merely statistical noise). @ARTICLE{Kim03, @@ -1028,11 +1066,63 @@ static void oc_enc_sb_transform_quantize_chroma(oc_enc_ctx *_enc, +(((_ssd)&(1<<OC_BIT_SCALE)-1)+((_rate)&(1<<OC_BIT_SCALE)-1)*(_lambda) \ +((1<<OC_BIT_SCALE)>>1)>>OC_BIT_SCALE) +static void oc_enc_mode_rd_init(oc_enc_ctx *_enc){ +#if !defined(OC_COLLECT_METRICS) + const +#endif + oc_mode_rd (*oc_mode_rd_table)[3][2][OC_COMP_BINS]= + _enc->sp_level<OC_SP_LEVEL_NOSATD?OC_MODE_RD_SATD:OC_MODE_RD_SAD; + int qii; +#if defined(OC_COLLECT_METRICS) + oc_enc_mode_metrics_load(_enc); +#endif + for(qii=0;qii<_enc->state.nqis;qii++){ + int qi; + int pli; + qi=_enc->state.qis[qii]; + for(pli=0;pli<3;pli++){ + int qti; + for(qti=0;qti<2;qti++){ + int log_plq; + int modeline; + int bin; + int dx; + int dq; + log_plq=_enc->log_plq[qi][pli][qti]; + /*Find the pair of rows in the mode table that bracket this quantizer. + If it falls outside the range the table covers, then we just use a + pair on the edge for linear extrapolation.*/ + for(modeline=0;modeline<OC_LOGQ_BINS-1&& + OC_MODE_LOGQ[modeline+1][pli][qti]>log_plq;modeline++); + /*Interpolate a row for this quantizer.*/ + dx=OC_MODE_LOGQ[modeline][pli][qti]-log_plq; + dq=OC_MODE_LOGQ[modeline][pli][qti]-OC_MODE_LOGQ[modeline+1][pli][qti]; + if(dq==0)dq=1; + for(bin=0;bin<OC_COMP_BINS;bin++){ + int y0; + int z0; + int dy; + int dz; + y0=oc_mode_rd_table[modeline][pli][qti][bin].rate; + z0=oc_mode_rd_table[modeline][pli][qti][bin].rmse; + dy=oc_mode_rd_table[modeline+1][pli][qti][bin].rate-y0; + dz=oc_mode_rd_table[modeline+1][pli][qti][bin].rmse-z0; + _enc->mode_rd[qii][pli][qti][bin].rate= + (ogg_int16_t)OC_CLAMPI(-32768,y0+(dy*dx+(dq>>1))/dq,32767); + _enc->mode_rd[qii][pli][qti][bin].rmse= + (ogg_int16_t)OC_CLAMPI(-32768,z0+(dz*dx+(dq>>1))/dq,32767); + } + } + } + } +} + /*Estimate the R-D cost of the DCT coefficients given the SATD of a block after prediction.*/ -static unsigned oc_dct_cost2(unsigned *_ssd, - int _qi,int _pli,int _qti,int _satd){ +static unsigned oc_dct_cost2(oc_enc_ctx *_enc,unsigned *_ssd, + int _qii,int _pli,int _qti,int _satd){ unsigned rmse; + int shift; int bin; int dx; int y0; @@ -1042,20 +1132,279 @@ static unsigned oc_dct_cost2(unsigned *_ssd, /*SATD metrics for chroma planes vary much less than luma, so we scale them by 4 to distribute them into the mode decision bins more evenly.*/ _satd<<=_pli+1&2; - bin=OC_MINI(_satd>>OC_SAD_SHIFT,OC_SAD_BINS-2); - dx=_satd-(bin<<OC_SAD_SHIFT); - y0=OC_MODE_RD[_qi][_pli][_qti][bin].rate; - z0=OC_MODE_RD[_qi][_pli][_qti][bin].rmse; - dy=OC_MODE_RD[_qi][_pli][_qti][bin+1].rate-y0; - dz=OC_MODE_RD[_qi][_pli][_qti][bin+1].rmse-z0; - rmse=OC_MAXI(z0+(dz*dx>>OC_SAD_SHIFT),0); + shift=_enc->sp_level<OC_SP_LEVEL_NOSATD?OC_SATD_SHIFT:OC_SAD_SHIFT; + bin=OC_MINI(_satd>>shift,OC_COMP_BINS-2); + dx=_satd-(bin<<shift); + y0=_enc->mode_rd[_qii][_pli][_qti][bin].rate; + z0=_enc->mode_rd[_qii][_pli][_qti][bin].rmse; + dy=_enc->mode_rd[_qii][_pli][_qti][bin+1].rate-y0; + dz=_enc->mode_rd[_qii][_pli][_qti][bin+1].rmse-z0; + rmse=OC_MAXI(z0+(dz*dx>>shift),0); *_ssd=rmse*rmse>>2*OC_RMSE_SCALE-OC_BIT_SCALE; - return OC_MAXI(y0+(dy*dx>>OC_SAD_SHIFT),0); + return OC_MAXI(y0+(dy*dx>>shift),0); +} + +/*activity_avg must be positive, or flat regions could get a zero weight, which + confounds analysis. + We set the minimum to this value so that it also avoids the need for divide + by zero checks in oc_mb_masking().*/ +# define OC_ACTIVITY_AVG_MIN (1<<OC_RD_SCALE_BITS) + +static unsigned oc_mb_activity(oc_enc_ctx *_enc,unsigned _mbi, + unsigned _activity[4]){ + const unsigned char *src; + const ptrdiff_t *frag_buf_offs; + const ptrdiff_t *sb_map; + unsigned luma; + int ystride; + ptrdiff_t frag_offs; + ptrdiff_t fragi; + int bi; + frag_buf_offs=_enc->state.frag_buf_offs; + sb_map=_enc->state.sb_maps[_mbi>>2][_mbi&3]; + src=_enc->state.ref_frame_data[OC_FRAME_IO]; + ystride=_enc->state.ref_ystride[0]; + luma=0; + for(bi=0;bi<4;bi++){ + const unsigned char *s; + unsigned x; + unsigned x2; + unsigned act; + int i; + int j; + fragi=sb_map[bi]; + frag_offs=frag_buf_offs[fragi]; + /*TODO: This could be replaced with SATD^2, since we already have to + compute SATD.*/ + x=x2=0; + s=src+frag_offs; + for(i=0;i<8;i++){ + for(j=0;j<8;j++){ + unsigned c; + c=s[j]; + x+=c; + x2+=c*c; + } + s+=ystride; + } + luma+=x; + act=(x2<<6)-x*x; + if(act<8<<12){ + /*The region is flat.*/ + act=OC_MINI(act,5<<12); + } + else{ + unsigned e1; + unsigned e2; + unsigned e3; + unsigned e4; + /*Test for an edge. + TODO: There are probably much simpler ways to do this (e.g., it could + probably be combined with the SATD calculation). + Alternatively, we could split the block around the mean and compute the + reduction in variance in each half. + For a Gaussian source the reduction should be + (1-2/pi) ~= 0.36338022763241865692446494650994. + Significantly more reduction is a good indication of a bi-level image. + This has the advantage of identifying, in addition to straight edges, + small text regions, which would otherwise be classified as "texture".*/ + e1=e2=e3=e4=0; + s=src+frag_offs-1; + for(i=0;i<8;i++){ + for(j=0;j<8;j++){ + e1+=abs((s[j+2]-s[j]<<1)+(s-ystride)[j+2]-(s-ystride)[j] + +(s+ystride)[j+2]-(s+ystride)[j]); + e2+=abs(((s+ystride)[j+1]-(s-ystride)[j+1]<<1) + +(s+ystride)[j]-(s-ystride)[j]+(s+ystride)[j+2]-(s-ystride)[j+2]); + e3+=abs(((s+ystride)[j+2]-(s-ystride)[j]<<1) + +(s+ystride)[j+1]-s[j]+s[j+2]-(s-ystride)[j+1]); + e4+=abs(((s+ystride)[j]-(s-ystride)[j+2]<<1) + +(s+ystride)[j+1]-s[j+2]+s[j]-(s-ystride)[j+1]); + } + s+=ystride; + } + /*If the largest component of the edge energy is at least 40% of the + total, then classify the block as an edge block.*/ + if(5*OC_MAXI(OC_MAXI(e1,e2),OC_MAXI(e3,e4))>2*(e1+e2+e3+e4)){ + /*act=act_th*(act/act_th)**0.7 + =exp(log(act_th)+0.7*(log(act)-log(act_th))). + Here act_th=5.0 and 0x394A=oc_blog32_q10(5<<12).*/ + act=oc_bexp32_q10(0x394A+(7*(oc_blog32_q10(act)-0x394A+5)/10)); + } + } + _activity[bi]=act; + } + return luma; +} + +static void oc_mb_activity_fast(oc_enc_ctx *_enc,unsigned _mbi, + unsigned _activity[4],const unsigned _intra_satd[12]){ + int bi; + for(bi=0;bi<4;bi++){ + unsigned act; + act=(11*_intra_satd[bi]>>8)*_intra_satd[bi]; + if(act<8<<12){ + /*The region is flat.*/ + act=OC_MINI(act,5<<12); + } + _activity[bi]=act; + } +} + +/*Compute the masking scales for the blocks in a macro block. + All masking is computed from the luma blocks. + We derive scaling factors for the chroma blocks from these, and use the same + ones for all chroma blocks, regardless of the subsampling. + It's possible for luma to be perfectly flat and yet have high chroma energy, + but this is unlikely in non-artificial images, and not a case that has been + addressed by any research to my knowledge. + The output of the masking process is two scale factors, which are fed into + the various R-D optimizations. + The first, rd_scale, is applied to D in the equation + D*rd_scale+lambda*R. + This is the form that must be used to properly combine scores from multiple + blocks, and can be interpreted as scaling distortions by their visibility. + The inverse, rd_iscale, is applied to lambda in the equation + D+rd_iscale*lambda*R. + This is equivalent to the first form within a single block, but much faster + to use when evaluating many possible distortions (e.g., during actual + quantization, where separate distortions are evaluated for every + coefficient). + The two macros OC_RD_SCALE(rd_scale,d) and OC_RD_ISCALE(rd_iscale,lambda) are + used to perform the multiplications with the proper re-scaling for the range + of the scaling factors. + Many researchers apply masking values directly to the quantizers used, and + not to the R-D cost. + Since we generally use MSE for D, rd_scale must use the square of their + values to generate an equivalent effect.*/ +static unsigned oc_mb_masking(unsigned _rd_scale[5],unsigned _rd_iscale[5], + const ogg_uint16_t _chroma_rd_scale[2],const unsigned _activity[4], + unsigned _activity_avg,unsigned _luma,unsigned _luma_avg){ + unsigned activity_sum; + unsigned la; + unsigned lb; + unsigned d; + int bi; + int bi_min; + int bi_min2; + /*The ratio lb/la is meant to approximate + ((((_luma-16)/219)*(255/128))**0.649**0.4**2), which is the + effective luminance masking from~\cite{LKW06} (including the self-masking + deflator). + The following actually turns out to be a pretty good approximation for + _luma>75 or so. + For smaller values luminance does not really follow Weber's Law anyway, and + this approximation gives a much less aggressive bitrate boost in this + region. + Though some researchers claim that contrast sensitivity actually decreases + for very low luminance values, in my experience excessive brightness on + LCDs or buggy color conversions (e.g., treating Y' as full-range instead + of the CCIR 601 range) make artifacts in such regions extremely visible. + We substitute _luma_avg for 128 to allow the strength of the masking to + vary with the actual average image luminance, within certain limits (the + caller has clamped _luma_avg to the range [90,160], inclusive). + @ARTICLE{LKW06, + author="Zhen Liu and Lina J. Karam and Andrew B. Watson", + title="{JPEG2000} Encoding With Perceptual Distortion Control", + journal="{IEEE} Transactions on Image Processing", + volume=15, + number=7, + pages="1763--1778", + month=Jul, + year=2006 + }*/ +#if 0 + la=_luma+4*_luma_avg; + lb=4*_luma+_luma_avg; +#else + /*Disable luminance masking.*/ + la=lb=1; +#endif + activity_sum=0; + for(bi=0;bi<4;bi++){ + unsigned a; + unsigned b; + activity_sum+=_activity[bi]; + /*Apply activity masking.*/ + a=_activity[bi]+4*_activity_avg; + b=4*_activity[bi]+_activity_avg; + d=OC_RD_SCALE(b,1); + /*And luminance masking.*/ + d=(a+(d>>1))/d; + _rd_scale[bi]=(d*la+(lb>>1))/lb; + /*And now the inverse.*/ + d=OC_MAXI(OC_RD_ISCALE(a,1),1); + d=(b+(d>>1))/d; + _rd_iscale[bi]=(d*lb+(la>>1))/la; + } + /*Now compute scaling factors for chroma blocks. + We start by finding the two smallest iscales from the luma blocks.*/ + bi_min=_rd_iscale[1]<_rd_iscale[0]; + bi_min2=1-bi_min; + for(bi=2;bi<4;bi++){ + if(_rd_iscale[bi]<_rd_iscale[bi_min]){ + bi_min2=bi_min; + bi_min=bi; + } + else if(_rd_iscale[bi]<_rd_iscale[bi_min2])bi_min2=bi; + } + /*If the minimum iscale is less than 1.0, use the second smallest instead, + and force the value to at least 1.0 (inflating chroma is a waste).*/ + if(_rd_iscale[bi_min]<(1<<OC_RD_ISCALE_BITS))bi_min=bi_min2; + d=OC_MINI(_rd_scale[bi_min],1<<OC_RD_SCALE_BITS); + _rd_scale[4]=OC_RD_SCALE(d,_chroma_rd_scale[0]); + d=OC_MAXI(_rd_iscale[bi_min],1<<OC_RD_ISCALE_BITS); + _rd_iscale[4]=OC_RD_ISCALE(d,_chroma_rd_scale[1]); + return activity_sum; +} + +static int oc_mb_intra_satd(oc_enc_ctx *_enc,unsigned _mbi, + unsigned _frag_satd[12]){ + const unsigned char *src; + const ptrdiff_t *frag_buf_offs; + const ptrdiff_t *sb_map; + const oc_mb_map_plane *mb_map; + const unsigned char *map_idxs; + int map_nidxs; + int mapii; + int mapi; + int ystride; + int pli; + int bi; + ptrdiff_t fragi; + ptrdiff_t frag_offs; + unsigned luma; + int dc; + frag_buf_offs=_enc->state.frag_buf_offs; + sb_map=_enc->state.sb_maps[_mbi>>2][_mbi&3]; + src=_enc->state.ref_frame_data[OC_FRAME_IO]; + ystride=_enc->state.ref_ystride[0]; + luma=0; + for(bi=0;bi<4;bi++){ + fragi=sb_map[bi]; + frag_offs=frag_buf_offs[fragi]; + _frag_satd[bi]=oc_enc_frag_intra_satd(_enc,&dc,src+frag_offs,ystride); + luma+=dc; + } + mb_map=(const oc_mb_map_plane *)_enc->state.mb_maps[_mbi]; + map_idxs=OC_MB_MAP_IDXS[_enc->state.info.pixel_fmt]; + map_nidxs=OC_MB_MAP_NIDXS[_enc->state.info.pixel_fmt]; + /*Note: This assumes ref_ystride[1]==ref_ystride[2].*/ + ystride=_enc->state.ref_ystride[1]; + for(mapii=4;mapii<map_nidxs;mapii++){ + mapi=map_idxs[mapii]; + pli=mapi>>2; + bi=mapi&3; + fragi=mb_map[pli][bi]; + frag_offs=frag_buf_offs[fragi]; + _frag_satd[mapii]=oc_enc_frag_intra_satd(_enc,&dc,src+frag_offs,ystride); + } + return luma; } /*Select luma block-level quantizers for a MB in an INTRA frame.*/ static unsigned oc_analyze_intra_mb_luma(oc_enc_ctx *_enc, - const oc_qii_state *_qs,unsigned _mbi){ + const oc_qii_state *_qs,unsigned _mbi,const unsigned _rd_scale[4]){ const unsigned char *src; const ptrdiff_t *frag_buf_offs; const oc_sb_map *sb_maps; @@ -1068,6 +1417,7 @@ static unsigned oc_analyze_intra_mb_luma(oc_enc_ctx *_enc, unsigned rate[4][3]; int prev[3][3]; unsigned satd; + int dc; unsigned best_cost; unsigned best_ssd; unsigned best_rate; @@ -1083,19 +1433,30 @@ static unsigned oc_analyze_intra_mb_luma(oc_enc_ctx *_enc, ystride=_enc->state.ref_ystride[0]; fragi=sb_maps[_mbi>>2][_mbi&3][0]; frag_offs=frag_buf_offs[fragi]; - satd=oc_enc_frag_intra_satd(_enc,src+frag_offs,ystride); + if(_enc->sp_level<OC_SP_LEVEL_NOSATD){ + satd=oc_enc_frag_intra_satd(_enc,&dc,src+frag_offs,ystride); + } + else{ + satd=oc_enc_frag_intra_sad(_enc,src+frag_offs,ystride); + } nqis=_enc->state.nqis; lambda=_enc->lambda; for(qii=0;qii<nqis;qii++){ oc_qii_state_advance(qs[0]+qii,_qs,qii); - rate[0][qii]=oc_dct_cost2(ssd[0]+qii,_enc->state.qis[qii],0,0,satd) + rate[0][qii]=oc_dct_cost2(_enc,ssd[0]+qii,qii,0,0,satd) +(qs[0][qii].bits-_qs->bits<<OC_BIT_SCALE); + ssd[0][qii]=OC_RD_SCALE(ssd[0][qii],_rd_scale[0]); cost[0][qii]=OC_MODE_RD_COST(ssd[0][qii],rate[0][qii],lambda); } for(bi=1;bi<4;bi++){ fragi=sb_maps[_mbi>>2][_mbi&3][bi]; frag_offs=frag_buf_offs[fragi]; - satd=oc_enc_frag_intra_satd(_enc,src+frag_offs,ystride); + if(_enc->sp_level<OC_SP_LEVEL_NOSATD){ + satd=oc_enc_frag_intra_satd(_enc,&dc,src+frag_offs,ystride); + } + else{ + satd=oc_enc_frag_intra_sad(_enc,src+frag_offs,ystride); + } for(qii=0;qii<nqis;qii++){ oc_qii_state qt[3]; unsigned cur_ssd; @@ -1103,7 +1464,8 @@ static unsigned oc_analyze_intra_mb_luma(oc_enc_ctx *_enc, int best_qij; int qij; oc_qii_state_advance(qt+0,qs[bi-1]+0,qii); - cur_rate=oc_dct_cost2(&cur_ssd,_enc->state.qis[qii],0,0,satd); + cur_rate=oc_dct_cost2(_enc,&cur_ssd,qii,0,0,satd); + cur_ssd=OC_RD_SCALE(cur_ssd,_rd_scale[bi]); best_ssd=ssd[bi-1][0]+cur_ssd; best_rate=rate[bi-1][0]+cur_rate +(qt[0].bits-qs[bi-1][0].bits<<OC_BIT_SCALE); @@ -1152,13 +1514,14 @@ static unsigned oc_analyze_intra_mb_luma(oc_enc_ctx *_enc, /*Select a block-level quantizer for a single chroma block in an INTRA frame.*/ static unsigned oc_analyze_intra_chroma_block(oc_enc_ctx *_enc, - const oc_qii_state *_qs,int _pli,ptrdiff_t _fragi){ + const oc_qii_state *_qs,int _pli,ptrdiff_t _fragi,unsigned _rd_scale){ const unsigned char *src; oc_fragment *frags; ptrdiff_t frag_offs; oc_qii_state qt[3]; unsigned cost[3]; unsigned satd; + int dc; unsigned best_cost; int best_qii; int qii; @@ -1168,16 +1531,30 @@ static unsigned oc_analyze_intra_chroma_block(oc_enc_ctx *_enc, src=_enc->state.ref_frame_data[OC_FRAME_IO]; ystride=_enc->state.ref_ystride[_pli]; frag_offs=_enc->state.frag_buf_offs[_fragi]; - satd=oc_enc_frag_intra_satd(_enc,src+frag_offs,ystride); + if(_enc->sp_level<OC_SP_LEVEL_NOSATD){ + satd=oc_enc_frag_intra_satd(_enc,&dc,src+frag_offs,ystride); + } + else{ + satd=oc_enc_frag_intra_sad(_enc,src+frag_offs,ystride); + } + /*Most chroma blocks have no AC coefficients to speak of anyway, so it's not + worth spending the bits to change the AC quantizer. + TODO: This may be worth revisiting when we separate out DC and AC + predictions from SATD.*/ +#if 0 nqis=_enc->state.nqis; +#else + nqis=1; +#endif lambda=_enc->lambda; best_qii=0; for(qii=0;qii<nqis;qii++){ unsigned cur_rate; unsigned cur_ssd; oc_qii_state_advance(qt+qii,_qs,qii); - cur_rate=oc_dct_cost2(&cur_ssd,_enc->state.qis[qii],_pli,0,satd) + cur_rate=oc_dct_cost2(_enc,&cur_ssd,qii,_pli,0,satd) +(qt[qii].bits-_qs->bits<<OC_BIT_SCALE); + cur_ssd=OC_RD_SCALE(cur_ssd,_rd_scale); cost[qii]=OC_MODE_RD_COST(cur_ssd,cur_rate,lambda); } best_cost=cost[0]; @@ -1192,17 +1569,49 @@ static unsigned oc_analyze_intra_chroma_block(oc_enc_ctx *_enc, return best_cost; } +static void oc_enc_mb_transform_quantize_intra_luma(oc_enc_ctx *_enc, + oc_enc_pipeline_state *_pipe,unsigned _mbi, + const unsigned _rd_scale[4],const unsigned _rd_iscale[4]){ + /*Worst case token stack usage for 4 fragments.*/ + oc_token_checkpoint stack[64*4]; + oc_token_checkpoint *stackptr; + const oc_sb_map *sb_maps; + oc_fragment *frags; + ptrdiff_t *coded_fragis; + ptrdiff_t ncoded_fragis; + ptrdiff_t fragi; + int bi; + sb_maps=(const oc_sb_map *)_enc->state.sb_maps; + frags=_enc->state.frags; + coded_fragis=_pipe->coded_fragis[0]; + ncoded_fragis=_pipe->ncoded_fragis[0]; + stackptr=stack; + for(bi=0;bi<4;bi++){ + fragi=sb_maps[_mbi>>2][_mbi&3][bi]; + frags[fragi].refi=OC_FRAME_SELF; + frags[fragi].mb_mode=OC_MODE_INTRA; + oc_enc_block_transform_quantize(_enc,_pipe,0,fragi, + _rd_scale[bi],_rd_iscale[bi],NULL,NULL,&stackptr); + coded_fragis[ncoded_fragis++]=fragi; + } + _pipe->ncoded_fragis[0]=ncoded_fragis; +} + static void oc_enc_sb_transform_quantize_intra_chroma(oc_enc_ctx *_enc, oc_enc_pipeline_state *_pipe,int _pli,int _sbi_start,int _sbi_end){ - const oc_sb_map *sb_maps; - oc_sb_flags *sb_flags; - ptrdiff_t *coded_fragis; - ptrdiff_t ncoded_fragis; - int sbi; + const ogg_uint16_t *mcu_rd_scale; + const ogg_uint16_t *mcu_rd_iscale; + const oc_sb_map *sb_maps; + ptrdiff_t *coded_fragis; + ptrdiff_t ncoded_fragis; + ptrdiff_t froffset; + int sbi; + mcu_rd_scale=(const ogg_uint16_t *)_enc->mcu_rd_scale; + mcu_rd_iscale=(const ogg_uint16_t *)_enc->mcu_rd_iscale; sb_maps=(const oc_sb_map *)_enc->state.sb_maps; - sb_flags=_enc->state.sb_flags; coded_fragis=_pipe->coded_fragis[_pli]; ncoded_fragis=_pipe->ncoded_fragis[_pli]; + froffset=_pipe->froffset[_pli]; for(sbi=_sbi_start;sbi<_sbi_end;sbi++){ /*Worst case token stack usage for 1 fragment.*/ oc_token_checkpoint stack[64]; @@ -1213,10 +1622,14 @@ static void oc_enc_sb_transform_quantize_intra_chroma(oc_enc_ctx *_enc, fragi=sb_maps[sbi][quadi][bi]; if(fragi>=0){ oc_token_checkpoint *stackptr; - oc_analyze_intra_chroma_block(_enc,_pipe->qs+_pli,_pli,fragi); + unsigned rd_scale; + unsigned rd_iscale; + rd_scale=mcu_rd_scale[fragi-froffset]; + rd_iscale=mcu_rd_iscale[fragi-froffset]; + oc_analyze_intra_chroma_block(_enc,_pipe->qs+_pli,_pli,fragi,rd_scale); stackptr=stack; - oc_enc_block_transform_quantize(_enc, - _pipe,_pli,fragi,0,NULL,&stackptr); + oc_enc_block_transform_quantize(_enc,_pipe,_pli,fragi, + rd_scale,rd_iscale,NULL,NULL,&stackptr); coded_fragis[ncoded_fragis++]=fragi; } } @@ -1226,13 +1639,19 @@ static void oc_enc_sb_transform_quantize_intra_chroma(oc_enc_ctx *_enc, /*Analysis stage for an INTRA frame.*/ void oc_enc_analyze_intra(oc_enc_ctx *_enc,int _recode){ - oc_enc_pipeline_state pipe; + ogg_int64_t activity_sum; + ogg_int64_t luma_sum; + unsigned activity_avg; + unsigned luma_avg; + const ogg_uint16_t *chroma_rd_scale; + ogg_uint16_t *mcu_rd_scale; + ogg_uint16_t *mcu_rd_iscale; const unsigned char *map_idxs; int nmap_idxs; oc_sb_flags *sb_flags; signed char *mb_modes; const oc_mb_map *mb_maps; - oc_mb_enc_info *embs; + const oc_sb_map *sb_maps; oc_fragment *frags; unsigned stripe_sby; unsigned mcu_nvsbs; @@ -1242,7 +1661,14 @@ void oc_enc_analyze_intra(oc_enc_ctx *_enc,int _recode){ int pli; _enc->state.frame_type=OC_INTRA_FRAME; oc_enc_tokenize_start(_enc); - oc_enc_pipeline_init(_enc,&pipe); + oc_enc_pipeline_init(_enc,&_enc->pipe); + oc_enc_mode_rd_init(_enc); + activity_sum=luma_sum=0; + activity_avg=_enc->activity_avg; + luma_avg=OC_CLAMPI(90<<8,_enc->luma_avg,160<<8); + chroma_rd_scale=_enc->chroma_rd_scale[OC_INTRA_FRAME][_enc->state.qis[0]]; + mcu_rd_scale=_enc->mcu_rd_scale; + mcu_rd_iscale=_enc->mcu_rd_iscale; /*Choose MVs and MB modes and quantize and code luma. Must be done in Hilbert order.*/ map_idxs=OC_MB_MAP_IDXS[_enc->state.info.pixel_fmt]; @@ -1253,52 +1679,91 @@ void oc_enc_analyze_intra(oc_enc_ctx *_enc,int _recode){ sb_flags=_enc->state.sb_flags; mb_modes=_enc->state.mb_modes; mb_maps=(const oc_mb_map *)_enc->state.mb_maps; - embs=_enc->mb_info; + sb_maps=(const oc_sb_map *)_enc->state.sb_maps; frags=_enc->state.frags; notstart=0; notdone=1; mcu_nvsbs=_enc->mcu_nvsbs; for(stripe_sby=0;notdone;stripe_sby+=mcu_nvsbs){ - unsigned sbi; - unsigned sbi_end; - notdone=oc_enc_pipeline_set_stripe(_enc,&pipe,stripe_sby); - sbi_end=pipe.sbi_end[0]; - for(sbi=pipe.sbi0[0];sbi<sbi_end;sbi++){ + ptrdiff_t cfroffset; + unsigned sbi; + unsigned sbi_end; + notdone=oc_enc_pipeline_set_stripe(_enc,&_enc->pipe,stripe_sby); + sbi_end=_enc->pipe.sbi_end[0]; + cfroffset=_enc->pipe.froffset[1]; + for(sbi=_enc->pipe.sbi0[0];sbi<sbi_end;sbi++){ int quadi; /*Mode addressing is through Y plane, always 4 MB per SB.*/ for(quadi=0;quadi<4;quadi++)if(sb_flags[sbi].quad_valid&1<<quadi){ + unsigned activity[4]; + unsigned rd_scale[5]; + unsigned rd_iscale[5]; + unsigned luma; unsigned mbi; int mapii; int mapi; int bi; ptrdiff_t fragi; mbi=sbi<<2|quadi; + /*Activity masking.*/ + if(_enc->sp_level<OC_SP_LEVEL_FAST_ANALYSIS){ + luma=oc_mb_activity(_enc,mbi,activity); + } + else{ + unsigned intra_satd[12]; + luma=oc_mb_intra_satd(_enc,mbi,intra_satd); + oc_mb_activity_fast(_enc,mbi,activity,intra_satd); + for(bi=0;bi<4;bi++)frags[sb_maps[mbi>>2][mbi&3][bi]].qii=0; + } + activity_sum+=oc_mb_masking(rd_scale,rd_iscale, + chroma_rd_scale,activity,activity_avg,luma,luma_avg); + luma_sum+=luma; /*Motion estimation: - We always do a basic 1MV search for all macroblocks, coded or not, - keyframe or not.*/ - if(!_recode&&_enc->state.curframe_num>0)oc_mcenc_search(_enc,mbi); - oc_analyze_intra_mb_luma(_enc,pipe.qs+0,mbi); + We do a basic 1MV search for all macroblocks, coded or not, + keyframe or not, unless we aren't using motion estimation at all.*/ + if(!_recode&&_enc->state.curframe_num>0&& + _enc->sp_level<OC_SP_LEVEL_NOMC&&_enc->keyframe_frequency_force>1){ + oc_mcenc_search(_enc,mbi); + } + if(_enc->sp_level<OC_SP_LEVEL_FAST_ANALYSIS){ + oc_analyze_intra_mb_luma(_enc,_enc->pipe.qs+0,mbi,rd_scale); + } mb_modes[mbi]=OC_MODE_INTRA; - oc_enc_mb_transform_quantize_luma(_enc,&pipe,mbi,0); + oc_enc_mb_transform_quantize_intra_luma(_enc,&_enc->pipe, + mbi,rd_scale,rd_iscale); /*Propagate final MB mode and MVs to the chroma blocks.*/ for(mapii=4;mapii<nmap_idxs;mapii++){ mapi=map_idxs[mapii]; pli=mapi>>2; bi=mapi&3; fragi=mb_maps[mbi][pli][bi]; + frags[fragi].refi=OC_FRAME_SELF; frags[fragi].mb_mode=OC_MODE_INTRA; } + /*Save masking scale factors for chroma blocks.*/ + for(mapii=4;mapii<(nmap_idxs-4>>1)+4;mapii++){ + mapi=map_idxs[mapii]; + bi=mapi&3; + fragi=mb_maps[mbi][1][bi]; + mcu_rd_scale[fragi-cfroffset]=(ogg_uint16_t)rd_scale[4]; + mcu_rd_iscale[fragi-cfroffset]=(ogg_uint16_t)rd_iscale[4]; + } } } - oc_enc_pipeline_finish_mcu_plane(_enc,&pipe,0,notstart,notdone); + oc_enc_pipeline_finish_mcu_plane(_enc,&_enc->pipe,0,notstart,notdone); /*Code chroma planes.*/ for(pli=1;pli<3;pli++){ - oc_enc_sb_transform_quantize_intra_chroma(_enc,&pipe, - pli,pipe.sbi0[pli],pipe.sbi_end[pli]); - oc_enc_pipeline_finish_mcu_plane(_enc,&pipe,pli,notstart,notdone); + oc_enc_sb_transform_quantize_intra_chroma(_enc,&_enc->pipe, + pli,_enc->pipe.sbi0[pli],_enc->pipe.sbi_end[pli]); + oc_enc_pipeline_finish_mcu_plane(_enc,&_enc->pipe,pli,notstart,notdone); } notstart=1; } + /*Compute the average block activity and MB luma score for the frame.*/ + _enc->activity_avg=OC_MAXI(OC_ACTIVITY_AVG_MIN, + (unsigned)((activity_sum+(_enc->state.fplanes[0].nfrags>>1))/ + _enc->state.fplanes[0].nfrags)); + _enc->luma_avg=(unsigned)((luma_sum+(_enc->state.nmbs>>1))/_enc->state.nmbs); /*Finish filling in the reference frame borders.*/ refi=_enc->state.ref_frame_idx[OC_FRAME_SELF]; for(pli=0;pli<3;pli++)oc_state_borders_fill_caps(&_enc->state,refi,pli); @@ -1339,27 +1804,21 @@ static const unsigned OC_NOSKIP[12]={ static void oc_analyze_mb_mode_luma(oc_enc_ctx *_enc, oc_mode_choice *_modec,const oc_fr_state *_fr,const oc_qii_state *_qs, - const unsigned _frag_satd[12],const unsigned _skip_ssd[12],int _qti){ + const unsigned _frag_satd[12],const unsigned _skip_ssd[12], + const unsigned _rd_scale[4],int _qti){ oc_fr_state fr; oc_qii_state qs; unsigned ssd; unsigned rate; - int overhead; unsigned satd; unsigned best_ssd; unsigned best_rate; - int best_overhead; int best_fri; int best_qii; - unsigned cur_cost; - unsigned cur_ssd; - unsigned cur_rate; - int cur_overhead; int lambda; int nqis; int nskipped; int bi; - int qii; lambda=_enc->lambda; nqis=_enc->state.nqis; /*We could do a trellis optimization here, but we don't make final skip @@ -1370,26 +1829,36 @@ static void oc_analyze_mb_mode_luma(oc_enc_ctx *_enc, code the flags, anyway.*/ *&fr=*_fr; *&qs=*_qs; - ssd=rate=overhead=nskipped=0; + ssd=rate=nskipped=0; for(bi=0;bi<4;bi++){ oc_fr_state ft[2]; oc_qii_state qt[3]; unsigned best_cost; + unsigned cur_cost; + unsigned cur_ssd; + unsigned cur_rate; + unsigned cur_overhead; + int qii; satd=_frag_satd[bi]; *(ft+0)=*&fr; oc_fr_code_block(ft+0); - oc_qii_state_advance(qt+0,&qs,0); - best_overhead=(ft[0].bits-fr.bits<<OC_BIT_SCALE); - best_rate=oc_dct_cost2(&best_ssd,_enc->state.qis[0],0,_qti,satd) - +(qt[0].bits-qs.bits<<OC_BIT_SCALE); - best_cost=OC_MODE_RD_COST(ssd+best_ssd,rate+best_rate+best_overhead,lambda); + cur_overhead=ft[0].bits-fr.bits; + best_rate=oc_dct_cost2(_enc,&best_ssd,0,0,_qti,satd) + +(cur_overhead<<OC_BIT_SCALE); + if(nqis>1){ + oc_qii_state_advance(qt+0,&qs,0); + best_rate+=qt[0].bits-qs.bits<<OC_BIT_SCALE; + } + best_ssd=OC_RD_SCALE(best_ssd,_rd_scale[bi]); + best_cost=OC_MODE_RD_COST(ssd+best_ssd,rate+best_rate,lambda); best_fri=0; best_qii=0; for(qii=1;qii<nqis;qii++){ oc_qii_state_advance(qt+qii,&qs,qii); - cur_rate=oc_dct_cost2(&cur_ssd,_enc->state.qis[qii],0,_qti,satd) - +(qt[qii].bits-qs.bits<<OC_BIT_SCALE); - cur_cost=OC_MODE_RD_COST(ssd+cur_ssd,rate+cur_rate+best_overhead,lambda); + cur_rate=oc_dct_cost2(_enc,&cur_ssd,qii,0,_qti,satd) + +(cur_overhead+qt[qii].bits-qs.bits<<OC_BIT_SCALE); + cur_ssd=OC_RD_SCALE(cur_ssd,_rd_scale[bi]); + cur_cost=OC_MODE_RD_COST(ssd+cur_ssd,rate+cur_rate,lambda); if(cur_cost<best_cost){ best_cost=cur_cost; best_ssd=cur_ssd; @@ -1397,7 +1866,7 @@ static void oc_analyze_mb_mode_luma(oc_enc_ctx *_enc, best_qii=qii; } } - if(_skip_ssd[bi]<UINT_MAX&&nskipped<3){ + if(_skip_ssd[bi]<(UINT_MAX>>OC_BIT_SCALE+2)&&nskipped<3){ *(ft+1)=*&fr; oc_fr_skip_block(ft+1); cur_overhead=ft[1].bits-fr.bits<<OC_BIT_SCALE; @@ -1405,15 +1874,13 @@ static void oc_analyze_mb_mode_luma(oc_enc_ctx *_enc, cur_cost=OC_MODE_RD_COST(ssd+cur_ssd,rate+cur_overhead,lambda); if(cur_cost<=best_cost){ best_ssd=cur_ssd; - best_rate=0; - best_overhead=cur_overhead; + best_rate=cur_overhead; best_fri=1; best_qii+=4; } } rate+=best_rate; ssd+=best_ssd; - overhead+=best_overhead; *&fr=*(ft+best_fri); if(best_fri==0)*&qs=*(qt+best_qii); else nskipped++; @@ -1421,12 +1888,12 @@ static void oc_analyze_mb_mode_luma(oc_enc_ctx *_enc, } _modec->ssd=ssd; _modec->rate=rate; - _modec->overhead=OC_MAXI(overhead,0); } static void oc_analyze_mb_mode_chroma(oc_enc_ctx *_enc, oc_mode_choice *_modec,const oc_fr_state *_fr,const oc_qii_state *_qs, - const unsigned _frag_satd[12],const unsigned _skip_ssd[12],int _qti){ + const unsigned _frag_satd[12],const unsigned _skip_ssd[12], + unsigned _rd_scale,int _qti){ unsigned ssd; unsigned rate; unsigned satd; @@ -1443,7 +1910,15 @@ static void oc_analyze_mb_mode_chroma(oc_enc_ctx *_enc, int bi; int qii; lambda=_enc->lambda; + /*Most chroma blocks have no AC coefficients to speak of anyway, so it's not + worth spending the bits to change the AC quantizer. + TODO: This may be worth revisiting when we separate out DC and AC + predictions from SATD.*/ +#if 0 nqis=_enc->state.nqis; +#else + nqis=1; +#endif ssd=_modec->ssd; rate=_modec->rate; /*Because (except in 4:4:4 mode) we aren't considering chroma blocks in coded @@ -1455,13 +1930,15 @@ static void oc_analyze_mb_mode_chroma(oc_enc_ctx *_enc, for(;bi<nblocks;bi++){ unsigned best_cost; satd=_frag_satd[bi]; - best_rate=oc_dct_cost2(&best_ssd,_enc->state.qis[0],pli,_qti,satd) + best_rate=oc_dct_cost2(_enc,&best_ssd,0,pli,_qti,satd) +OC_CHROMA_QII_RATE; + best_ssd=OC_RD_SCALE(best_ssd,_rd_scale); best_cost=OC_MODE_RD_COST(ssd+best_ssd,rate+best_rate,lambda); best_qii=0; for(qii=1;qii<nqis;qii++){ - cur_rate=oc_dct_cost2(&cur_ssd,_enc->state.qis[qii],0,_qti,satd) + cur_rate=oc_dct_cost2(_enc,&cur_ssd,qii,pli,_qti,satd) +OC_CHROMA_QII_RATE; + cur_ssd=OC_RD_SCALE(cur_ssd,_rd_scale); cur_cost=OC_MODE_RD_COST(ssd+cur_ssd,rate+cur_rate,lambda); if(cur_cost<best_cost){ best_cost=cur_cost; @@ -1470,7 +1947,7 @@ static void oc_analyze_mb_mode_chroma(oc_enc_ctx *_enc, best_qii=qii; } } - if(_skip_ssd[bi]<UINT_MAX){ + if(_skip_ssd[bi]<(UINT_MAX>>OC_BIT_SCALE+2)){ cur_ssd=_skip_ssd[bi]<<OC_BIT_SCALE; cur_cost=OC_MODE_RD_COST(ssd+cur_ssd,rate,lambda); if(cur_cost<=best_cost){ @@ -1490,65 +1967,50 @@ static void oc_analyze_mb_mode_chroma(oc_enc_ctx *_enc, } static void oc_skip_cost(oc_enc_ctx *_enc,oc_enc_pipeline_state *_pipe, - unsigned _mbi,unsigned _ssd[12]){ - OC_ALIGN16(ogg_int16_t buffer[64]); - const unsigned char *src; - const unsigned char *ref; - int ystride; - const oc_fragment *frags; - const ptrdiff_t *frag_buf_offs; - const ptrdiff_t *sb_map; - const oc_mb_map_plane *mb_map; - const unsigned char *map_idxs; - int map_nidxs; - ogg_int64_t mask; - unsigned uncoded_ssd; - int uncoded_dc; - unsigned dc_dequant; - int dc_flag; - int mapii; - int mapi; - int pli; - int bi; - ptrdiff_t fragi; - ptrdiff_t frag_offs; - int borderi; - int pi; + unsigned _mbi,const unsigned _rd_scale[4],unsigned _ssd[12]){ + const unsigned char *src; + const unsigned char *ref; + int ystride; + const oc_fragment *frags; + const ptrdiff_t *frag_buf_offs; + const ptrdiff_t *sb_map; + const oc_mb_map_plane *mb_map; + const unsigned char *map_idxs; + oc_mv *mvs; + int map_nidxs; + unsigned uncoded_ssd; + int mapii; + int mapi; + int pli; + int bi; + ptrdiff_t fragi; + ptrdiff_t frag_offs; + int borderi; src=_enc->state.ref_frame_data[OC_FRAME_IO]; - ref=_enc->state.ref_frame_data[_enc->state.ref_frame_idx[OC_FRAME_PREV]]; + ref=_enc->state.ref_frame_data[OC_FRAME_PREV]; ystride=_enc->state.ref_ystride[0]; frags=_enc->state.frags; frag_buf_offs=_enc->state.frag_buf_offs; sb_map=_enc->state.sb_maps[_mbi>>2][_mbi&3]; - dc_dequant=_enc->state.dequant_tables[_enc->state.qis[0]][0][1][0]; + mvs=_enc->mb_info[_mbi].block_mv; for(bi=0;bi<4;bi++){ fragi=sb_map[bi]; - frag_offs=frag_buf_offs[fragi]; - oc_enc_frag_sub(_enc,buffer,src+frag_offs,ref+frag_offs,ystride); borderi=frags[fragi].borderi; - uncoded_ssd=uncoded_dc=0; + frag_offs=frag_buf_offs[fragi]; if(borderi<0){ - for(pi=0;pi<64;pi++){ - uncoded_ssd+=buffer[pi]*buffer[pi]; - uncoded_dc+=buffer[pi]; - } + uncoded_ssd=oc_enc_frag_ssd(_enc,src+frag_offs,ref+frag_offs,ystride); } else{ - ogg_int64_t mask; - mask=_enc->state.borders[borderi].mask; - for(pi=0;pi<64;pi++,mask>>=1)if(mask&1){ - uncoded_ssd+=buffer[pi]*buffer[pi]; - uncoded_dc+=buffer[pi]; - } + uncoded_ssd=oc_enc_frag_border_ssd(_enc, + src+frag_offs,ref+frag_offs,ystride,_enc->state.borders[borderi].mask); } - /*Scale to match DCT domain.*/ - uncoded_ssd<<=4; - /*We actually only want the AC contribution to the SSD.*/ - uncoded_ssd-=uncoded_dc*uncoded_dc>>2; - /*DC is a special case; if there's more than a full-quantizer improvement - in the effective DC component, always force-code the block.*/ - dc_flag=abs(uncoded_dc)>dc_dequant<<1; - uncoded_ssd|=-dc_flag; + /*Scale to match DCT domain and RD.*/ + uncoded_ssd=OC_RD_SKIP_SCALE(uncoded_ssd,_rd_scale[bi]); + /*Motion is a special case; if there is more than a full-pixel motion + against the prior frame, penalize skipping. + TODO: The factor of two here is a kludge, but it tested out better than a + hard limit.*/ + if(mvs[bi]!=0)uncoded_ssd*=2; _pipe->skip_ssd[0][fragi-_pipe->froffset[0]]=_ssd[bi]=uncoded_ssd; } mb_map=(const oc_mb_map_plane *)_enc->state.mb_maps[_mbi]; @@ -1556,96 +2018,52 @@ static void oc_skip_cost(oc_enc_ctx *_enc,oc_enc_pipeline_state *_pipe, map_idxs=OC_MB_MAP_IDXS[_enc->state.info.pixel_fmt]; map_nidxs=(map_nidxs-4>>1)+4; mapii=4; + mvs=_enc->mb_info[_mbi].unref_mv; for(pli=1;pli<3;pli++){ ystride=_enc->state.ref_ystride[pli]; - dc_dequant=_enc->state.dequant_tables[_enc->state.qis[0]][pli][1][0]; for(;mapii<map_nidxs;mapii++){ mapi=map_idxs[mapii]; bi=mapi&3; fragi=mb_map[pli][bi]; - frag_offs=frag_buf_offs[fragi]; - oc_enc_frag_sub(_enc,buffer,src+frag_offs,ref+frag_offs,ystride); borderi=frags[fragi].borderi; - uncoded_ssd=uncoded_dc=0; + frag_offs=frag_buf_offs[fragi]; if(borderi<0){ - for(pi=0;pi<64;pi++){ - uncoded_ssd+=buffer[pi]*buffer[pi]; - uncoded_dc+=buffer[pi]; - } + uncoded_ssd=oc_enc_frag_ssd(_enc,src+frag_offs,ref+frag_offs,ystride); } else{ - mask=_enc->state.borders[borderi].mask; - for(pi=0;pi<64;pi++,mask>>=1)if(mask&1){ - uncoded_ssd+=buffer[pi]*buffer[pi]; - uncoded_dc+=buffer[pi]; - } + uncoded_ssd=oc_enc_frag_border_ssd(_enc, + src+frag_offs,ref+frag_offs,ystride,_enc->state.borders[borderi].mask); } - /*Scale to match DCT domain.*/ - uncoded_ssd<<=4; - /*We actually only want the AC contribution to the SSD.*/ - uncoded_ssd-=uncoded_dc*uncoded_dc>>2; - /*DC is a special case; if there's more than a full-quantizer improvement - in the effective DC component, always force-code the block.*/ - dc_flag=abs(uncoded_dc)>dc_dequant<<1; - uncoded_ssd|=-dc_flag; + /*Scale to match DCT domain and RD.*/ + uncoded_ssd=OC_RD_SKIP_SCALE(uncoded_ssd,_rd_scale[4]); + /*Motion is a special case; if there is more than a full-pixel motion + against the prior frame, penalize skipping. + TODO: The factor of two here is a kludge, but it tested out better than + a hard limit*/ + if(mvs[OC_FRAME_PREV]!=0)uncoded_ssd*=2; _pipe->skip_ssd[pli][fragi-_pipe->froffset[pli]]=_ssd[mapii]=uncoded_ssd; } map_nidxs=(map_nidxs-4<<1)+4; } } -static void oc_mb_intra_satd(oc_enc_ctx *_enc,unsigned _mbi, - unsigned _frag_satd[12]){ - const unsigned char *src; - const ptrdiff_t *frag_buf_offs; - const ptrdiff_t *sb_map; - const oc_mb_map_plane *mb_map; - const unsigned char *map_idxs; - int map_nidxs; - int mapii; - int mapi; - int ystride; - int pli; - int bi; - ptrdiff_t fragi; - ptrdiff_t frag_offs; - frag_buf_offs=_enc->state.frag_buf_offs; - sb_map=_enc->state.sb_maps[_mbi>>2][_mbi&3]; - src=_enc->state.ref_frame_data[OC_FRAME_IO]; - ystride=_enc->state.ref_ystride[0]; - for(bi=0;bi<4;bi++){ - fragi=sb_map[bi]; - frag_offs=frag_buf_offs[fragi]; - _frag_satd[bi]=oc_enc_frag_intra_satd(_enc,src+frag_offs,ystride); - } - mb_map=(const oc_mb_map_plane *)_enc->state.mb_maps[_mbi]; - map_idxs=OC_MB_MAP_IDXS[_enc->state.info.pixel_fmt]; - map_nidxs=OC_MB_MAP_NIDXS[_enc->state.info.pixel_fmt]; - /*Note: This assumes ref_ystride[1]==ref_ystride[2].*/ - ystride=_enc->state.ref_ystride[1]; - for(mapii=4;mapii<map_nidxs;mapii++){ - mapi=map_idxs[mapii]; - pli=mapi>>2; - bi=mapi&3; - fragi=mb_map[pli][bi]; - frag_offs=frag_buf_offs[fragi]; - _frag_satd[mapii]=oc_enc_frag_intra_satd(_enc,src+frag_offs,ystride); - } -} static void oc_cost_intra(oc_enc_ctx *_enc,oc_mode_choice *_modec, unsigned _mbi,const oc_fr_state *_fr,const oc_qii_state *_qs, - const unsigned _frag_satd[12],const unsigned _skip_ssd[12]){ - oc_analyze_mb_mode_luma(_enc,_modec,_fr,_qs,_frag_satd,_skip_ssd,0); - oc_analyze_mb_mode_chroma(_enc,_modec,_fr,_qs,_frag_satd,_skip_ssd,0); - _modec->overhead+= + const unsigned _frag_satd[12],const unsigned _skip_ssd[12], + const unsigned _rd_scale[5]){ + oc_analyze_mb_mode_luma(_enc,_modec,_fr,_qs,_frag_satd,_skip_ssd,_rd_scale,0); + oc_analyze_mb_mode_chroma(_enc,_modec,_fr,_qs, + _frag_satd,_skip_ssd,_rd_scale[4],0); + _modec->overhead= oc_mode_scheme_chooser_cost(&_enc->chooser,OC_MODE_INTRA)<<OC_BIT_SCALE; oc_mode_set_cost(_modec,_enc->lambda); } static void oc_cost_inter(oc_enc_ctx *_enc,oc_mode_choice *_modec, - unsigned _mbi,int _mb_mode,const signed char *_mv, - const oc_fr_state *_fr,const oc_qii_state *_qs,const unsigned _skip_ssd[12]){ + unsigned _mbi,int _mb_mode,oc_mv _mv, + const oc_fr_state *_fr,const oc_qii_state *_qs, + const unsigned _skip_ssd[12],const unsigned _rd_scale[5]){ unsigned frag_satd[12]; const unsigned char *src; const unsigned char *ref; @@ -1658,35 +2076,45 @@ static void oc_cost_inter(oc_enc_ctx *_enc,oc_mode_choice *_modec, int mapii; int mapi; int mv_offs[2]; - int dx; - int dy; int pli; int bi; ptrdiff_t fragi; ptrdiff_t frag_offs; + int dc; src=_enc->state.ref_frame_data[OC_FRAME_IO]; - ref=_enc->state.ref_frame_data[ - _enc->state.ref_frame_idx[OC_FRAME_FOR_MODE(_mb_mode)]]; + ref=_enc->state.ref_frame_data[OC_FRAME_FOR_MODE(_mb_mode)]; ystride=_enc->state.ref_ystride[0]; frag_buf_offs=_enc->state.frag_buf_offs; sb_map=_enc->state.sb_maps[_mbi>>2][_mbi&3]; - dx=_mv[0]; - dy=_mv[1]; _modec->rate=_modec->ssd=0; - if(oc_state_get_mv_offsets(&_enc->state,mv_offs,0,dx,dy)>1){ + if(oc_state_get_mv_offsets(&_enc->state,mv_offs,0,_mv)>1){ for(bi=0;bi<4;bi++){ fragi=sb_map[bi]; frag_offs=frag_buf_offs[fragi]; - frag_satd[bi]=oc_enc_frag_satd2_thresh(_enc,src+frag_offs, - ref+frag_offs+mv_offs[0],ref+frag_offs+mv_offs[1],ystride,UINT_MAX); + if(_enc->sp_level<OC_SP_LEVEL_NOSATD){ + frag_satd[bi]=oc_enc_frag_satd2(_enc,&dc,src+frag_offs, + ref+frag_offs+mv_offs[0],ref+frag_offs+mv_offs[1],ystride); + frag_satd[bi]+=abs(dc); + } + else{ + frag_satd[bi]=oc_enc_frag_sad2_thresh(_enc,src+frag_offs, + ref+frag_offs+mv_offs[0],ref+frag_offs+mv_offs[1],ystride,UINT_MAX); + } } } else{ for(bi=0;bi<4;bi++){ fragi=sb_map[bi]; frag_offs=frag_buf_offs[fragi]; - frag_satd[bi]=oc_enc_frag_satd_thresh(_enc,src+frag_offs, - ref+frag_offs+mv_offs[0],ystride,UINT_MAX); + if(_enc->sp_level<OC_SP_LEVEL_NOSATD){ + frag_satd[bi]=oc_enc_frag_satd(_enc,&dc,src+frag_offs, + ref+frag_offs+mv_offs[0],ystride); + frag_satd[bi]+=abs(dc); + } + else{ + frag_satd[bi]=oc_enc_frag_sad(_enc,src+frag_offs, + ref+frag_offs+mv_offs[0],ystride); + } } } mb_map=(const oc_mb_map_plane *)_enc->state.mb_maps[_mbi]; @@ -1694,15 +2122,22 @@ static void oc_cost_inter(oc_enc_ctx *_enc,oc_mode_choice *_modec, map_nidxs=OC_MB_MAP_NIDXS[_enc->state.info.pixel_fmt]; /*Note: This assumes ref_ystride[1]==ref_ystride[2].*/ ystride=_enc->state.ref_ystride[1]; - if(oc_state_get_mv_offsets(&_enc->state,mv_offs,1,dx,dy)>1){ + if(oc_state_get_mv_offsets(&_enc->state,mv_offs,1,_mv)>1){ for(mapii=4;mapii<map_nidxs;mapii++){ mapi=map_idxs[mapii]; pli=mapi>>2; bi=mapi&3; fragi=mb_map[pli][bi]; frag_offs=frag_buf_offs[fragi]; - frag_satd[mapii]=oc_enc_frag_satd2_thresh(_enc,src+frag_offs, - ref+frag_offs+mv_offs[0],ref+frag_offs+mv_offs[1],ystride,UINT_MAX); + if(_enc->sp_level<OC_SP_LEVEL_NOSATD){ + frag_satd[mapii]=oc_enc_frag_satd2(_enc,&dc,src+frag_offs, + ref+frag_offs+mv_offs[0],ref+frag_offs+mv_offs[1],ystride); + frag_satd[mapii]+=abs(dc); + } + else{ + frag_satd[mapii]=oc_enc_frag_sad2_thresh(_enc,src+frag_offs, + ref+frag_offs+mv_offs[0],ref+frag_offs+mv_offs[1],ystride,UINT_MAX); + } } } else{ @@ -1712,30 +2147,38 @@ static void oc_cost_inter(oc_enc_ctx *_enc,oc_mode_choice *_modec, bi=mapi&3; fragi=mb_map[pli][bi]; frag_offs=frag_buf_offs[fragi]; - frag_satd[mapii]=oc_enc_frag_satd_thresh(_enc,src+frag_offs, - ref+frag_offs+mv_offs[0],ystride,UINT_MAX); + if(_enc->sp_level<OC_SP_LEVEL_NOSATD){ + frag_satd[mapii]=oc_enc_frag_satd(_enc,&dc,src+frag_offs, + ref+frag_offs+mv_offs[0],ystride); + frag_satd[mapii]+=abs(dc); + } + else{ + frag_satd[mapii]=oc_enc_frag_sad(_enc,src+frag_offs, + ref+frag_offs+mv_offs[0],ystride); + } } } - oc_analyze_mb_mode_luma(_enc,_modec,_fr,_qs,frag_satd,_skip_ssd,1); - oc_analyze_mb_mode_chroma(_enc,_modec,_fr,_qs,frag_satd,_skip_ssd,1); - _modec->overhead+= + oc_analyze_mb_mode_luma(_enc,_modec,_fr,_qs,frag_satd,_skip_ssd,_rd_scale,1); + oc_analyze_mb_mode_chroma(_enc,_modec,_fr,_qs, + frag_satd,_skip_ssd,_rd_scale[4],1); + _modec->overhead= oc_mode_scheme_chooser_cost(&_enc->chooser,_mb_mode)<<OC_BIT_SCALE; oc_mode_set_cost(_modec,_enc->lambda); } static void oc_cost_inter_nomv(oc_enc_ctx *_enc,oc_mode_choice *_modec, unsigned _mbi,int _mb_mode,const oc_fr_state *_fr,const oc_qii_state *_qs, - const unsigned _skip_ssd[12]){ - static const oc_mv OC_MV_ZERO; - oc_cost_inter(_enc,_modec,_mbi,_mb_mode,OC_MV_ZERO,_fr,_qs,_skip_ssd); + const unsigned _skip_ssd[12],const unsigned _rd_scale[4]){ + oc_cost_inter(_enc,_modec,_mbi,_mb_mode,0,_fr,_qs,_skip_ssd,_rd_scale); } static int oc_cost_inter1mv(oc_enc_ctx *_enc,oc_mode_choice *_modec, - unsigned _mbi,int _mb_mode,const signed char *_mv, - const oc_fr_state *_fr,const oc_qii_state *_qs,const unsigned _skip_ssd[12]){ + unsigned _mbi,int _mb_mode,oc_mv _mv, + const oc_fr_state *_fr,const oc_qii_state *_qs,const unsigned _skip_ssd[12], + const unsigned _rd_scale[4]){ int bits0; - oc_cost_inter(_enc,_modec,_mbi,_mb_mode,_mv,_fr,_qs,_skip_ssd); - bits0=OC_MV_BITS[0][_mv[0]+31]+OC_MV_BITS[0][_mv[1]+31]; + oc_cost_inter(_enc,_modec,_mbi,_mb_mode,_mv,_fr,_qs,_skip_ssd,_rd_scale); + bits0=OC_MV_BITS[0][OC_MV_X(_mv)+31]+OC_MV_BITS[0][OC_MV_Y(_mv)+31]; _modec->overhead+=OC_MINI(_enc->mv_bits[0]+bits0,_enc->mv_bits[1]+12) -OC_MINI(_enc->mv_bits[0],_enc->mv_bits[1])<<OC_BIT_SCALE; oc_mode_set_cost(_modec,_enc->lambda); @@ -1749,7 +2192,7 @@ static const unsigned char OC_MB_PHASE[4][4]={ static void oc_cost_inter4mv(oc_enc_ctx *_enc,oc_mode_choice *_modec, unsigned _mbi,oc_mv _mv[4],const oc_fr_state *_fr,const oc_qii_state *_qs, - const unsigned _skip_ssd[12]){ + const unsigned _skip_ssd[12],const unsigned _rd_scale[5]){ unsigned frag_satd[12]; oc_mv lbmvs[4]; oc_mv cbmvs[4]; @@ -1765,8 +2208,6 @@ static void oc_cost_inter4mv(oc_enc_ctx *_enc,oc_mode_choice *_modec, int mapii; int mapi; int mv_offs[2]; - int dx; - int dy; int pli; int bi; ptrdiff_t fragi; @@ -1774,8 +2215,9 @@ static void oc_cost_inter4mv(oc_enc_ctx *_enc,oc_mode_choice *_modec, int bits0; int bits1; unsigned satd; + int dc; src=_enc->state.ref_frame_data[OC_FRAME_IO]; - ref=_enc->state.ref_frame_data[_enc->state.ref_frame_idx[OC_FRAME_PREV]]; + ref=_enc->state.ref_frame_data[OC_FRAME_PREV]; ystride=_enc->state.ref_ystride[0]; frag_buf_offs=_enc->state.frag_buf_offs; frag_mvs=_enc->state.frag_mvs; @@ -1783,41 +2225,36 @@ static void oc_cost_inter4mv(oc_enc_ctx *_enc,oc_mode_choice *_modec, _modec->rate=_modec->ssd=0; for(bi=0;bi<4;bi++){ fragi=mb_map[0][bi]; - dx=_mv[bi][0]; - dy=_mv[bi][1]; /*Save the block MVs as the current ones while we're here; we'll replace them if we don't ultimately choose 4MV mode.*/ - frag_mvs[fragi][0]=(signed char)dx; - frag_mvs[fragi][1]=(signed char)dy; + frag_mvs[fragi]=_mv[bi]; frag_offs=frag_buf_offs[fragi]; - if(oc_state_get_mv_offsets(&_enc->state,mv_offs,0,dx,dy)>1){ - satd=oc_enc_frag_satd2_thresh(_enc,src+frag_offs, - ref+frag_offs+mv_offs[0],ref+frag_offs+mv_offs[1],ystride,UINT_MAX); + if(oc_state_get_mv_offsets(&_enc->state,mv_offs,0,_mv[bi])>1){ + satd=oc_enc_frag_satd2(_enc,&dc,src+frag_offs, + ref+frag_offs+mv_offs[0],ref+frag_offs+mv_offs[1],ystride); } else{ - satd=oc_enc_frag_satd_thresh(_enc,src+frag_offs, - ref+frag_offs+mv_offs[0],ystride,UINT_MAX); + satd=oc_enc_frag_satd(_enc,&dc,src+frag_offs, + ref+frag_offs+mv_offs[0],ystride); } - frag_satd[OC_MB_PHASE[_mbi&3][bi]]=satd; + frag_satd[OC_MB_PHASE[_mbi&3][bi]]=satd+abs(dc); } oc_analyze_mb_mode_luma(_enc,_modec,_fr,_qs,frag_satd, - _enc->vp3_compatible?OC_NOSKIP:_skip_ssd,1); + _enc->vp3_compatible?OC_NOSKIP:_skip_ssd,_rd_scale,1); /*Figure out which blocks are being skipped and give them (0,0) MVs.*/ bits0=0; bits1=0; nqis=_enc->state.nqis; for(bi=0;bi<4;bi++){ - if(_modec->qii[OC_MB_PHASE[_mbi&3][bi]]>=nqis){ - memset(lbmvs+bi,0,sizeof(*lbmvs)); - } + if(_modec->qii[OC_MB_PHASE[_mbi&3][bi]]>=nqis)lbmvs[bi]=0; else{ - memcpy(lbmvs+bi,_mv+bi,sizeof(*lbmvs)); - bits0+=OC_MV_BITS[0][_mv[bi][0]+31]+OC_MV_BITS[0][_mv[bi][1]+31]; + lbmvs[bi]=_mv[bi]; + bits0+=OC_MV_BITS[0][OC_MV_X(_mv[bi])+31] + +OC_MV_BITS[0][OC_MV_Y(_mv[bi])+31]; bits1+=12; } } - (*OC_SET_CHROMA_MVS_TABLE[_enc->state.info.pixel_fmt])(cbmvs, - (const oc_mv *)lbmvs); + (*OC_SET_CHROMA_MVS_TABLE[_enc->state.info.pixel_fmt])(cbmvs,lbmvs); map_idxs=OC_MB_MAP_IDXS[_enc->state.info.pixel_fmt]; map_nidxs=OC_MB_MAP_NIDXS[_enc->state.info.pixel_fmt]; /*Note: This assumes ref_ystride[1]==ref_ystride[2].*/ @@ -1827,23 +2264,22 @@ static void oc_cost_inter4mv(oc_enc_ctx *_enc,oc_mode_choice *_modec, pli=mapi>>2; bi=mapi&3; fragi=mb_map[pli][bi]; - dx=cbmvs[bi][0]; - dy=cbmvs[bi][1]; frag_offs=frag_buf_offs[fragi]; /*TODO: We could save half these calls by re-using the results for the Cb and Cr planes; is it worth it?*/ - if(oc_state_get_mv_offsets(&_enc->state,mv_offs,pli,dx,dy)>1){ - satd=oc_enc_frag_satd2_thresh(_enc,src+frag_offs, - ref+frag_offs+mv_offs[0],ref+frag_offs+mv_offs[1],ystride,UINT_MAX); + if(oc_state_get_mv_offsets(&_enc->state,mv_offs,pli,cbmvs[bi])>1){ + satd=oc_enc_frag_satd2(_enc,&dc,src+frag_offs, + ref+frag_offs+mv_offs[0],ref+frag_offs+mv_offs[1],ystride); } else{ - satd=oc_enc_frag_satd_thresh(_enc,src+frag_offs, - ref+frag_offs+mv_offs[0],ystride,UINT_MAX); + satd=oc_enc_frag_satd(_enc,&dc,src+frag_offs, + ref+frag_offs+mv_offs[0],ystride); } - frag_satd[mapii]=satd; + frag_satd[mapii]=satd+abs(dc); } - oc_analyze_mb_mode_chroma(_enc,_modec,_fr,_qs,frag_satd,_skip_ssd,1); - _modec->overhead+= + oc_analyze_mb_mode_chroma(_enc,_modec,_fr,_qs, + frag_satd,_skip_ssd,_rd_scale[4],1); + _modec->overhead= oc_mode_scheme_chooser_cost(&_enc->chooser,OC_MODE_INTER_MV_FOUR) +OC_MINI(_enc->mv_bits[0]+bits0,_enc->mv_bits[1]+bits1) -OC_MINI(_enc->mv_bits[0],_enc->mv_bits[1])<<OC_BIT_SCALE; @@ -1852,12 +2288,18 @@ static void oc_cost_inter4mv(oc_enc_ctx *_enc,oc_mode_choice *_modec, int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode){ oc_set_chroma_mvs_func set_chroma_mvs; - oc_enc_pipeline_state pipe; oc_qii_state intra_luma_qs; oc_mv last_mv; oc_mv prior_mv; ogg_int64_t interbits; ogg_int64_t intrabits; + ogg_int64_t activity_sum; + ogg_int64_t luma_sum; + unsigned activity_avg; + unsigned luma_avg; + const ogg_uint16_t *chroma_rd_scale; + ogg_uint16_t *mcu_rd_scale; + ogg_uint16_t *mcu_rd_iscale; const unsigned char *map_idxs; int nmap_idxs; unsigned *coded_mbis; @@ -1871,30 +2313,36 @@ int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode){ oc_mb_enc_info *embs; oc_fragment *frags; oc_mv *frag_mvs; - int qi; unsigned stripe_sby; unsigned mcu_nvsbs; int notstart; int notdone; - int vdec; unsigned sbi; unsigned sbi_end; int refi; int pli; + int sp_level; + sp_level=_enc->sp_level; set_chroma_mvs=OC_SET_CHROMA_MVS_TABLE[_enc->state.info.pixel_fmt]; _enc->state.frame_type=OC_INTER_FRAME; oc_mode_scheme_chooser_reset(&_enc->chooser); oc_enc_tokenize_start(_enc); - oc_enc_pipeline_init(_enc,&pipe); + oc_enc_pipeline_init(_enc,&_enc->pipe); + oc_enc_mode_rd_init(_enc); if(_allow_keyframe)oc_qii_state_init(&intra_luma_qs); _enc->mv_bits[0]=_enc->mv_bits[1]=0; interbits=intrabits=0; - last_mv[0]=last_mv[1]=prior_mv[0]=prior_mv[1]=0; + activity_sum=luma_sum=0; + activity_avg=_enc->activity_avg; + luma_avg=OC_CLAMPI(90<<8,_enc->luma_avg,160<<8); + chroma_rd_scale=_enc->chroma_rd_scale[OC_INTER_FRAME][_enc->state.qis[0]]; + mcu_rd_scale=_enc->mcu_rd_scale; + mcu_rd_iscale=_enc->mcu_rd_iscale; + last_mv=prior_mv=0; /*Choose MVs and MB modes and quantize and code luma. Must be done in Hilbert order.*/ map_idxs=OC_MB_MAP_IDXS[_enc->state.info.pixel_fmt]; nmap_idxs=OC_MB_MAP_NIDXS[_enc->state.info.pixel_fmt]; - qi=_enc->state.qis[0]; coded_mbis=_enc->coded_mbis; uncoded_mbis=coded_mbis+_enc->state.nmbs; ncoded_mbis=0; @@ -1909,37 +2357,51 @@ int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode){ embs=_enc->mb_info; frags=_enc->state.frags; frag_mvs=_enc->state.frag_mvs; - vdec=!(_enc->state.info.pixel_fmt&2); notstart=0; notdone=1; mcu_nvsbs=_enc->mcu_nvsbs; for(stripe_sby=0;notdone;stripe_sby+=mcu_nvsbs){ - notdone=oc_enc_pipeline_set_stripe(_enc,&pipe,stripe_sby); - sbi_end=pipe.sbi_end[0]; - for(sbi=pipe.sbi0[0];sbi<sbi_end;sbi++){ + ptrdiff_t cfroffset; + notdone=oc_enc_pipeline_set_stripe(_enc,&_enc->pipe,stripe_sby); + sbi_end=_enc->pipe.sbi_end[0]; + cfroffset=_enc->pipe.froffset[1]; + for(sbi=_enc->pipe.sbi0[0];sbi<sbi_end;sbi++){ int quadi; /*Mode addressing is through Y plane, always 4 MB per SB.*/ for(quadi=0;quadi<4;quadi++)if(sb_flags[sbi].quad_valid&1<<quadi){ oc_mode_choice modes[8]; + unsigned activity[4]; + unsigned rd_scale[5]; + unsigned rd_iscale[5]; unsigned skip_ssd[12]; unsigned intra_satd[12]; + unsigned luma; int mb_mv_bits_0; int mb_gmv_bits_0; int inter_mv_pref; int mb_mode; - int dx; - int dy; + int refi; + int mv; unsigned mbi; int mapii; int mapi; int bi; ptrdiff_t fragi; mbi=sbi<<2|quadi; + luma=oc_mb_intra_satd(_enc,mbi,intra_satd); + /*Activity masking.*/ + if(sp_level<OC_SP_LEVEL_FAST_ANALYSIS){ + oc_mb_activity(_enc,mbi,activity); + } + else oc_mb_activity_fast(_enc,mbi,activity,intra_satd); + luma_sum+=luma; + activity_sum+=oc_mb_masking(rd_scale,rd_iscale, + chroma_rd_scale,activity,activity_avg,luma,luma_avg); /*Motion estimation: We always do a basic 1MV search for all macroblocks, coded or not, keyframe or not.*/ - if(!_recode&&_enc->sp_level<OC_SP_LEVEL_NOMC)oc_mcenc_search(_enc,mbi); - dx=dy=0; + if(!_recode&&sp_level<OC_SP_LEVEL_NOMC)oc_mcenc_search(_enc,mbi); + mv=0; /*Find the block choice with the lowest estimated coding cost. If a Cb or Cr block is coded but no Y' block from a macro block then the mode MUST be OC_MODE_INTER_NOMV. @@ -1948,15 +2410,16 @@ int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode){ /*Block coding cost is estimated from correlated SATD metrics.*/ /*At this point, all blocks that are in frame are still marked coded.*/ if(!_recode){ - memcpy(embs[mbi].unref_mv, - embs[mbi].analysis_mv[0],sizeof(embs[mbi].unref_mv)); + embs[mbi].unref_mv[OC_FRAME_GOLD]= + embs[mbi].analysis_mv[0][OC_FRAME_GOLD]; + embs[mbi].unref_mv[OC_FRAME_PREV]= + embs[mbi].analysis_mv[0][OC_FRAME_PREV]; embs[mbi].refined=0; } - oc_mb_intra_satd(_enc,mbi,intra_satd); /*Estimate the cost of coding this MB in a keyframe.*/ if(_allow_keyframe){ oc_cost_intra(_enc,modes+OC_MODE_INTRA,mbi, - pipe.fr+0,&intra_luma_qs,intra_satd,OC_NOSKIP); + _enc->pipe.fr+0,&intra_luma_qs,intra_satd,OC_NOSKIP,rd_scale); intrabits+=modes[OC_MODE_INTRA].rate; for(bi=0;bi<4;bi++){ oc_qii_state_advance(&intra_luma_qs,&intra_luma_qs, @@ -1964,26 +2427,28 @@ int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode){ } } /*Estimate the cost in a delta frame for various modes.*/ - oc_skip_cost(_enc,&pipe,mbi,skip_ssd); - oc_cost_inter_nomv(_enc,modes+OC_MODE_INTER_NOMV,mbi, - OC_MODE_INTER_NOMV,pipe.fr+0,pipe.qs+0,skip_ssd); - if(_enc->sp_level<OC_SP_LEVEL_NOMC){ + oc_skip_cost(_enc,&_enc->pipe,mbi,rd_scale,skip_ssd); + if(sp_level<OC_SP_LEVEL_NOMC){ + oc_cost_inter_nomv(_enc,modes+OC_MODE_INTER_NOMV,mbi, + OC_MODE_INTER_NOMV,_enc->pipe.fr+0,_enc->pipe.qs+0, + skip_ssd,rd_scale); oc_cost_intra(_enc,modes+OC_MODE_INTRA,mbi, - pipe.fr+0,pipe.qs+0,intra_satd,skip_ssd); + _enc->pipe.fr+0,_enc->pipe.qs+0,intra_satd,skip_ssd,rd_scale); mb_mv_bits_0=oc_cost_inter1mv(_enc,modes+OC_MODE_INTER_MV,mbi, OC_MODE_INTER_MV,embs[mbi].unref_mv[OC_FRAME_PREV], - pipe.fr+0,pipe.qs+0,skip_ssd); + _enc->pipe.fr+0,_enc->pipe.qs+0,skip_ssd,rd_scale); oc_cost_inter(_enc,modes+OC_MODE_INTER_MV_LAST,mbi, - OC_MODE_INTER_MV_LAST,last_mv,pipe.fr+0,pipe.qs+0,skip_ssd); + OC_MODE_INTER_MV_LAST,last_mv,_enc->pipe.fr+0,_enc->pipe.qs+0, + skip_ssd,rd_scale); oc_cost_inter(_enc,modes+OC_MODE_INTER_MV_LAST2,mbi, - OC_MODE_INTER_MV_LAST2,prior_mv,pipe.fr+0,pipe.qs+0,skip_ssd); - oc_cost_inter4mv(_enc,modes+OC_MODE_INTER_MV_FOUR,mbi, - embs[mbi].block_mv,pipe.fr+0,pipe.qs+0,skip_ssd); + OC_MODE_INTER_MV_LAST2,prior_mv,_enc->pipe.fr+0,_enc->pipe.qs+0, + skip_ssd,rd_scale); oc_cost_inter_nomv(_enc,modes+OC_MODE_GOLDEN_NOMV,mbi, - OC_MODE_GOLDEN_NOMV,pipe.fr+0,pipe.qs+0,skip_ssd); + OC_MODE_GOLDEN_NOMV,_enc->pipe.fr+0,_enc->pipe.qs+0, + skip_ssd,rd_scale); mb_gmv_bits_0=oc_cost_inter1mv(_enc,modes+OC_MODE_GOLDEN_MV,mbi, OC_MODE_GOLDEN_MV,embs[mbi].unref_mv[OC_FRAME_GOLD], - pipe.fr+0,pipe.qs+0,skip_ssd); + _enc->pipe.fr+0,_enc->pipe.qs+0,skip_ssd,rd_scale); /*The explicit MV modes (2,6,7) have not yet gone through halfpel refinement. We choose the explicit MV mode that's already furthest ahead on @@ -1991,6 +2456,14 @@ int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode){ We have to be careful to remember which ones we've refined so that we don't refine it again if we re-encode this frame.*/ inter_mv_pref=_enc->lambda*3; + if(sp_level<OC_SP_LEVEL_FAST_ANALYSIS){ + oc_cost_inter4mv(_enc,modes+OC_MODE_INTER_MV_FOUR,mbi, + embs[mbi].block_mv,_enc->pipe.fr+0,_enc->pipe.qs+0, + skip_ssd,rd_scale); + } + else{ + modes[OC_MODE_INTER_MV_FOUR].cost=UINT_MAX; + } if(modes[OC_MODE_INTER_MV_FOUR].cost<modes[OC_MODE_INTER_MV].cost&& modes[OC_MODE_INTER_MV_FOUR].cost<modes[OC_MODE_GOLDEN_MV].cost){ if(!(embs[mbi].refined&0x80)){ @@ -1998,7 +2471,8 @@ int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode){ embs[mbi].refined|=0x80; } oc_cost_inter4mv(_enc,modes+OC_MODE_INTER_MV_FOUR,mbi, - embs[mbi].ref_mv,pipe.fr+0,pipe.qs+0,skip_ssd); + embs[mbi].ref_mv,_enc->pipe.fr+0,_enc->pipe.qs+0, + skip_ssd,rd_scale); } else if(modes[OC_MODE_GOLDEN_MV].cost+inter_mv_pref< modes[OC_MODE_INTER_MV].cost){ @@ -2008,7 +2482,7 @@ int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode){ } mb_gmv_bits_0=oc_cost_inter1mv(_enc,modes+OC_MODE_GOLDEN_MV,mbi, OC_MODE_GOLDEN_MV,embs[mbi].analysis_mv[0][OC_FRAME_GOLD], - pipe.fr+0,pipe.qs+0,skip_ssd); + _enc->pipe.fr+0,_enc->pipe.qs+0,skip_ssd,rd_scale); } if(!(embs[mbi].refined&0x04)){ oc_mcenc_refine1mv(_enc,mbi,OC_FRAME_PREV); @@ -2016,7 +2490,7 @@ int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode){ } mb_mv_bits_0=oc_cost_inter1mv(_enc,modes+OC_MODE_INTER_MV,mbi, OC_MODE_INTER_MV,embs[mbi].analysis_mv[0][OC_FRAME_PREV], - pipe.fr+0,pipe.qs+0,skip_ssd); + _enc->pipe.fr+0,_enc->pipe.qs+0,skip_ssd,rd_scale); /*Finally, pick the mode with the cheapest estimated R-D cost.*/ mb_mode=OC_MODE_INTER_NOMV; if(modes[OC_MODE_INTRA].cost<modes[OC_MODE_INTER_NOMV].cost){ @@ -2046,8 +2520,14 @@ int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode){ } } else{ + oc_cost_inter_nomv(_enc,modes+OC_MODE_INTER_NOMV,mbi, + OC_MODE_INTER_NOMV,_enc->pipe.fr+0,_enc->pipe.qs+0, + skip_ssd,rd_scale); + oc_cost_intra(_enc,modes+OC_MODE_INTRA,mbi, + _enc->pipe.fr+0,_enc->pipe.qs+0,intra_satd,skip_ssd,rd_scale); oc_cost_inter_nomv(_enc,modes+OC_MODE_GOLDEN_NOMV,mbi, - OC_MODE_GOLDEN_NOMV,pipe.fr+0,pipe.qs+0,skip_ssd); + OC_MODE_GOLDEN_NOMV,_enc->pipe.fr+0,_enc->pipe.qs+0, + skip_ssd,rd_scale); mb_mode=OC_MODE_INTER_NOMV; if(modes[OC_MODE_INTRA].cost<modes[OC_MODE_INTER_NOMV].cost){ mb_mode=OC_MODE_INTRA; @@ -2062,67 +2542,55 @@ int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode){ if(mb_mode!=OC_MODE_INTER_MV_FOUR){ switch(mb_mode){ case OC_MODE_INTER_MV:{ - dx=embs[mbi].analysis_mv[0][OC_FRAME_PREV][0]; - dy=embs[mbi].analysis_mv[0][OC_FRAME_PREV][1]; - }break; - case OC_MODE_INTER_MV_LAST:{ - dx=last_mv[0]; - dy=last_mv[1]; - }break; - case OC_MODE_INTER_MV_LAST2:{ - dx=prior_mv[0]; - dy=prior_mv[1]; + mv=embs[mbi].analysis_mv[0][OC_FRAME_PREV]; }break; + case OC_MODE_INTER_MV_LAST:mv=last_mv;break; + case OC_MODE_INTER_MV_LAST2:mv=prior_mv;break; case OC_MODE_GOLDEN_MV:{ - dx=embs[mbi].analysis_mv[0][OC_FRAME_GOLD][0]; - dy=embs[mbi].analysis_mv[0][OC_FRAME_GOLD][1]; + mv=embs[mbi].analysis_mv[0][OC_FRAME_GOLD]; }break; } for(bi=0;bi<4;bi++){ fragi=mb_maps[mbi][0][bi]; - frag_mvs[fragi][0]=(signed char)dx; - frag_mvs[fragi][1]=(signed char)dy; + frag_mvs[fragi]=mv; } } for(bi=0;bi<4;bi++){ fragi=sb_maps[mbi>>2][mbi&3][bi]; frags[fragi].qii=modes[mb_mode].qii[bi]; } - if(oc_enc_mb_transform_quantize_luma(_enc,&pipe,mbi, - modes[mb_mode].overhead>>OC_BIT_SCALE)>0){ + if(oc_enc_mb_transform_quantize_inter_luma(_enc,&_enc->pipe,mbi, + modes[mb_mode].overhead>>OC_BIT_SCALE,rd_scale,rd_iscale)>0){ int orig_mb_mode; orig_mb_mode=mb_mode; mb_mode=mb_modes[mbi]; + refi=OC_FRAME_FOR_MODE(mb_mode); switch(mb_mode){ case OC_MODE_INTER_MV:{ - memcpy(prior_mv,last_mv,sizeof(prior_mv)); + prior_mv=last_mv; /*If we're backing out from 4MV, find the MV we're actually using.*/ if(orig_mb_mode==OC_MODE_INTER_MV_FOUR){ for(bi=0;;bi++){ fragi=mb_maps[mbi][0][bi]; if(frags[fragi].coded){ - memcpy(last_mv,frag_mvs[fragi],sizeof(last_mv)); - dx=frag_mvs[fragi][0]; - dy=frag_mvs[fragi][1]; + mv=last_mv=frag_mvs[fragi]; break; } } - mb_mv_bits_0=OC_MV_BITS[0][dx+31]+OC_MV_BITS[0][dy+31]; + mb_mv_bits_0=OC_MV_BITS[0][OC_MV_X(mv)+31] + +OC_MV_BITS[0][OC_MV_Y(mv)+31]; } /*Otherwise we used the original analysis MV.*/ - else{ - memcpy(last_mv, - embs[mbi].analysis_mv[0][OC_FRAME_PREV],sizeof(last_mv)); - } + else last_mv=embs[mbi].analysis_mv[0][OC_FRAME_PREV]; _enc->mv_bits[0]+=mb_mv_bits_0; _enc->mv_bits[1]+=12; }break; case OC_MODE_INTER_MV_LAST2:{ oc_mv tmp_mv; - memcpy(tmp_mv,prior_mv,sizeof(tmp_mv)); - memcpy(prior_mv,last_mv,sizeof(prior_mv)); - memcpy(last_mv,tmp_mv,sizeof(last_mv)); + tmp_mv=prior_mv; + prior_mv=last_mv; + last_mv=tmp_mv; }break; case OC_MODE_GOLDEN_MV:{ _enc->mv_bits[0]+=mb_gmv_bits_0; @@ -2131,28 +2599,28 @@ int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode){ case OC_MODE_INTER_MV_FOUR:{ oc_mv lbmvs[4]; oc_mv cbmvs[4]; - memcpy(prior_mv,last_mv,sizeof(prior_mv)); + prior_mv=last_mv; for(bi=0;bi<4;bi++){ fragi=mb_maps[mbi][0][bi]; if(frags[fragi].coded){ - memcpy(last_mv,frag_mvs[fragi],sizeof(last_mv)); - memcpy(lbmvs[bi],frag_mvs[fragi],sizeof(lbmvs[bi])); - _enc->mv_bits[0]+=OC_MV_BITS[0][frag_mvs[fragi][0]+31] - +OC_MV_BITS[0][frag_mvs[fragi][1]+31]; + lbmvs[bi]=last_mv=frag_mvs[fragi]; + _enc->mv_bits[0]+=OC_MV_BITS[0][OC_MV_X(last_mv)+31] + +OC_MV_BITS[0][OC_MV_Y(last_mv)+31]; _enc->mv_bits[1]+=12; } /*Replace the block MVs for not-coded blocks with (0,0).*/ - else memset(lbmvs[bi],0,sizeof(lbmvs[bi])); + else lbmvs[bi]=0; } - (*set_chroma_mvs)(cbmvs,(const oc_mv *)lbmvs); + (*set_chroma_mvs)(cbmvs,lbmvs); for(mapii=4;mapii<nmap_idxs;mapii++){ mapi=map_idxs[mapii]; pli=mapi>>2; bi=mapi&3; fragi=mb_maps[mbi][pli][bi]; - frags[fragi].mb_mode=mb_mode; frags[fragi].qii=modes[OC_MODE_INTER_MV_FOUR].qii[mapii]; - memcpy(frag_mvs[fragi],cbmvs[bi],sizeof(frag_mvs[fragi])); + frags[fragi].refi=refi; + frags[fragi].mb_mode=mb_mode; + frag_mvs[fragi]=cbmvs[bi]; } }break; } @@ -2163,7 +2631,8 @@ int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode){ else{ *(uncoded_mbis-++nuncoded_mbis)=mbi; mb_mode=OC_MODE_INTER_NOMV; - dx=dy=0; + refi=OC_FRAME_PREV; + mv=0; } /*Propagate final MB mode and MVs to the chroma blocks. This has already been done for 4MV mode, since it requires individual @@ -2174,43 +2643,56 @@ int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode){ pli=mapi>>2; bi=mapi&3; fragi=mb_maps[mbi][pli][bi]; - frags[fragi].mb_mode=mb_mode; /*If we switched from 4MV mode to INTER_MV mode, then the qii values won't have been chosen with the right MV, but it's probaby not worth re-estimating them.*/ frags[fragi].qii=modes[mb_mode].qii[mapii]; - frag_mvs[fragi][0]=(signed char)dx; - frag_mvs[fragi][1]=(signed char)dy; + frags[fragi].refi=refi; + frags[fragi].mb_mode=mb_mode; + frag_mvs[fragi]=mv; } } + /*Save masking scale factors for chroma blocks.*/ + for(mapii=4;mapii<(nmap_idxs-4>>1)+4;mapii++){ + mapi=map_idxs[mapii]; + bi=mapi&3; + fragi=mb_maps[mbi][1][bi]; + mcu_rd_scale[fragi-cfroffset]=(ogg_uint16_t)rd_scale[4]; + mcu_rd_iscale[fragi-cfroffset]=(ogg_uint16_t)rd_iscale[4]; + } } - oc_fr_state_flush_sb(pipe.fr+0); - sb_flags[sbi].coded_fully=pipe.fr[0].sb_full; - sb_flags[sbi].coded_partially=pipe.fr[0].sb_partial; + oc_fr_state_flush_sb(_enc->pipe.fr+0); + sb_flags[sbi].coded_fully=_enc->pipe.fr[0].sb_full; + sb_flags[sbi].coded_partially=_enc->pipe.fr[0].sb_partial; } - oc_enc_pipeline_finish_mcu_plane(_enc,&pipe,0,notstart,notdone); + oc_enc_pipeline_finish_mcu_plane(_enc,&_enc->pipe,0,notstart,notdone); /*Code chroma planes.*/ for(pli=1;pli<3;pli++){ - oc_enc_sb_transform_quantize_chroma(_enc,&pipe, - pli,pipe.sbi0[pli],pipe.sbi_end[pli]); - oc_enc_pipeline_finish_mcu_plane(_enc,&pipe,pli,notstart,notdone); + oc_enc_sb_transform_quantize_inter_chroma(_enc,&_enc->pipe, + pli,_enc->pipe.sbi0[pli],_enc->pipe.sbi_end[pli]); + oc_enc_pipeline_finish_mcu_plane(_enc,&_enc->pipe,pli,notstart,notdone); } notstart=1; } + /*Update the average block activity and MB luma score for the frame. + We could use a Bessel follower here, but fast reaction is probably almost + always best.*/ + _enc->activity_avg=OC_MAXI(OC_ACTIVITY_AVG_MIN, + (unsigned)((activity_sum+(_enc->state.fplanes[0].nfrags>>1))/ + _enc->state.fplanes[0].nfrags)); + _enc->luma_avg=(unsigned)((luma_sum+(_enc->state.nmbs>>1))/_enc->state.nmbs); /*Finish filling in the reference frame borders.*/ refi=_enc->state.ref_frame_idx[OC_FRAME_SELF]; for(pli=0;pli<3;pli++)oc_state_borders_fill_caps(&_enc->state,refi,pli); /*Finish adding flagging overhead costs to inter bit counts to determine if we should have coded a key frame instead.*/ if(_allow_keyframe){ - if(interbits>intrabits)return 1; /*Technically the chroma plane counts are over-estimations, because they don't account for continuing runs from the luma planes, but the - inaccuracy is small.*/ - for(pli=0;pli<3;pli++)interbits+=pipe.fr[pli].bits<<OC_BIT_SCALE; - interbits+=OC_MINI(_enc->mv_bits[0],_enc->mv_bits[1])<<OC_BIT_SCALE; - interbits+= - _enc->chooser.scheme_bits[_enc->chooser.scheme_list[0]]<<OC_BIT_SCALE; + inaccuracy is small. + We don't need to add the luma plane coding flag costs, because they are + already included in the MB rate estimates.*/ + for(pli=1;pli<3;pli++)interbits+=_enc->pipe.fr[pli].bits<<OC_BIT_SCALE; if(interbits>intrabits)return 1; } _enc->ncoded_mbis=ncoded_mbis; @@ -2228,482 +2710,3 @@ int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode){ } return 0; } - -#if defined(OC_COLLECT_METRICS) -# include <stdio.h> -# include <math.h> - -/*TODO: It may be helpful (for block-level quantizers especially) to separate - out the contributions from AC and DC into separate tables.*/ - -# define OC_ZWEIGHT (0.25) - -static void oc_mode_metrics_add(oc_mode_metrics *_metrics, - double _w,int _satd,int _rate,double _rmse){ - double rate; - /*Accumulate statistics without the scaling; this lets us change the scale - factor yet still use old data.*/ - rate=ldexp(_rate,-OC_BIT_SCALE); - if(_metrics->fragw>0){ - double dsatd; - double drate; - double drmse; - double w; - dsatd=_satd-_metrics->satd/_metrics->fragw; - drate=rate-_metrics->rate/_metrics->fragw; - drmse=_rmse-_metrics->rmse/_metrics->fragw; - w=_metrics->fragw*_w/(_metrics->fragw+_w); - _metrics->satd2+=dsatd*dsatd*w; - _metrics->satdrate+=dsatd*drate*w; - _metrics->rate2+=drate*drate*w; - _metrics->satdrmse+=dsatd*drmse*w; - _metrics->rmse2+=drmse*drmse*w; - } - _metrics->fragw+=_w; - _metrics->satd+=_satd*_w; - _metrics->rate+=rate*_w; - _metrics->rmse+=_rmse*_w; -} - -static void oc_mode_metrics_merge(oc_mode_metrics *_dst, - const oc_mode_metrics *_src,int _n){ - int i; - /*Find a non-empty set of metrics.*/ - for(i=0;i<_n&&_src[i].fragw<=0;i++); - if(i>=_n){ - memset(_dst,0,sizeof(*_dst)); - return; - } - memcpy(_dst,_src+i,sizeof(*_dst)); - /*And iterate over the remaining non-empty sets of metrics.*/ - for(i++;i<_n;i++)if(_src[i].fragw>0){ - double wa; - double wb; - double dsatd; - double drate; - double drmse; - double w; - wa=_dst->fragw; - wb=_src[i].fragw; - dsatd=_src[i].satd/wb-_dst->satd/wa; - drate=_src[i].rate/wb-_dst->rate/wa; - drmse=_src[i].rmse/wb-_dst->rmse/wa; - w=wa*wb/(wa+wb); - _dst->fragw+=_src[i].fragw; - _dst->satd+=_src[i].satd; - _dst->rate+=_src[i].rate; - _dst->rmse+=_src[i].rmse; - _dst->satd2+=_src[i].satd2+dsatd*dsatd*w; - _dst->satdrate+=_src[i].satdrate+dsatd*drate*w; - _dst->rate2+=_src[i].rate2+drate*drate*w; - _dst->satdrmse+=_src[i].satdrmse+dsatd*drmse*w; - _dst->rmse2+=_src[i].rmse2+drmse*drmse*w; - } -} - -/*Compile collected SATD/rate/RMSE metrics into a form that's immediately - useful for mode decision.*/ -static void oc_enc_mode_metrics_update(oc_enc_ctx *_enc,int _qi){ - int pli; - int qti; - oc_restore_fpu(&_enc->state); - /*Convert raw collected data into cleaned up sample points.*/ - for(pli=0;pli<3;pli++){ - for(qti=0;qti<2;qti++){ - double fragw; - int bin0; - int bin1; - int bin; - fragw=0; - bin0=bin1=0; - for(bin=0;bin<OC_SAD_BINS;bin++){ - oc_mode_metrics metrics; - OC_MODE_RD[_qi][pli][qti][bin].rate=0; - OC_MODE_RD[_qi][pli][qti][bin].rmse=0; - /*Find some points on either side of the current bin.*/ - while((bin1<bin+1||fragw<OC_ZWEIGHT)&&bin1<OC_SAD_BINS-1){ - fragw+=OC_MODE_METRICS[_qi][pli][qti][bin1++].fragw; - } - while(bin0+1<bin&&bin0+1<bin1&& - fragw-OC_MODE_METRICS[_qi][pli][qti][bin0].fragw>=OC_ZWEIGHT){ - fragw-=OC_MODE_METRICS[_qi][pli][qti][bin0++].fragw; - } - /*Merge statistics and fit lines.*/ - oc_mode_metrics_merge(&metrics, - OC_MODE_METRICS[_qi][pli][qti]+bin0,bin1-bin0); - if(metrics.fragw>0&&metrics.satd2>0){ - double a; - double b; - double msatd; - double mrate; - double mrmse; - double rate; - double rmse; - msatd=metrics.satd/metrics.fragw; - mrate=metrics.rate/metrics.fragw; - mrmse=metrics.rmse/metrics.fragw; - /*Compute the points on these lines corresponding to the actual bin - value.*/ - b=metrics.satdrate/metrics.satd2; - a=mrate-b*msatd; - rate=ldexp(a+b*(bin<<OC_SAD_SHIFT),OC_BIT_SCALE); - OC_MODE_RD[_qi][pli][qti][bin].rate= - (ogg_int16_t)OC_CLAMPI(-32768,(int)(rate+0.5),32767); - b=metrics.satdrmse/metrics.satd2; - a=mrmse-b*msatd; - rmse=ldexp(a+b*(bin<<OC_SAD_SHIFT),OC_RMSE_SCALE); - OC_MODE_RD[_qi][pli][qti][bin].rmse= - (ogg_int16_t)OC_CLAMPI(-32768,(int)(rmse+0.5),32767); - } - } - } - } -} - - - -/*The following token skipping code used to also be used in the decoder (and - even at one point other places in the encoder). - However, it was obsoleted by other optimizations, and is now only used here. - It has been moved here to avoid generating the code when it's not needed.*/ - -/*Determines the number of blocks or coefficients to be skipped for a given - token value. - _token: The token value to skip. - _extra_bits: The extra bits attached to this token. - Return: A positive value indicates that number of coefficients are to be - skipped in the current block. - Otherwise, the negative of the return value indicates that number of - blocks are to be ended.*/ -typedef ptrdiff_t (*oc_token_skip_func)(int _token,int _extra_bits); - -/*Handles the simple end of block tokens.*/ -static ptrdiff_t oc_token_skip_eob(int _token,int _extra_bits){ - int nblocks_adjust; - nblocks_adjust=OC_UNIBBLE_TABLE32(0,1,2,3,7,15,0,0,_token)+1; - return -_extra_bits-nblocks_adjust; -} - -/*The last EOB token has a special case, where an EOB run of size zero ends all - the remaining blocks in the frame.*/ -static ptrdiff_t oc_token_skip_eob6(int _token,int _extra_bits){ - /*Note: We want to return -PTRDIFF_MAX, but that requires C99, which is not - yet available everywhere; this should be equivalent.*/ - if(!_extra_bits)return -(~(size_t)0>>1); - return -_extra_bits; -} - -/*Handles the pure zero run tokens.*/ -static ptrdiff_t oc_token_skip_zrl(int _token,int _extra_bits){ - return _extra_bits+1; -} - -/*Handles a normal coefficient value token.*/ -static ptrdiff_t oc_token_skip_val(void){ - return 1; -} - -/*Handles a category 1A zero run/coefficient value combo token.*/ -static ptrdiff_t oc_token_skip_run_cat1a(int _token){ - return _token-OC_DCT_RUN_CAT1A+2; -} - -/*Handles category 1b, 1c, 2a, and 2b zero run/coefficient value combo tokens.*/ -static ptrdiff_t oc_token_skip_run(int _token,int _extra_bits){ - int run_cati; - int ncoeffs_mask; - int ncoeffs_adjust; - run_cati=_token-OC_DCT_RUN_CAT1B; - ncoeffs_mask=OC_BYTE_TABLE32(3,7,0,1,run_cati); - ncoeffs_adjust=OC_BYTE_TABLE32(7,11,2,3,run_cati); - return (_extra_bits&ncoeffs_mask)+ncoeffs_adjust; -} - -/*A jump table for computing the number of coefficients or blocks to skip for - a given token value. - This reduces all the conditional branches, etc., needed to parse these token - values down to one indirect jump.*/ -static const oc_token_skip_func OC_TOKEN_SKIP_TABLE[TH_NDCT_TOKENS]={ - oc_token_skip_eob, - oc_token_skip_eob, - oc_token_skip_eob, - oc_token_skip_eob, - oc_token_skip_eob, - oc_token_skip_eob, - oc_token_skip_eob6, - oc_token_skip_zrl, - oc_token_skip_zrl, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_run_cat1a, - (oc_token_skip_func)oc_token_skip_run_cat1a, - (oc_token_skip_func)oc_token_skip_run_cat1a, - (oc_token_skip_func)oc_token_skip_run_cat1a, - (oc_token_skip_func)oc_token_skip_run_cat1a, - oc_token_skip_run, - oc_token_skip_run, - oc_token_skip_run, - oc_token_skip_run -}; - -/*Determines the number of blocks or coefficients to be skipped for a given - token value. - _token: The token value to skip. - _extra_bits: The extra bits attached to this token. - Return: A positive value indicates that number of coefficients are to be - skipped in the current block. - Otherwise, the negative of the return value indicates that number of - blocks are to be ended. - 0 will never be returned, so that at least one coefficient in one - block will always be decoded for every token.*/ -static ptrdiff_t oc_dct_token_skip(int _token,int _extra_bits){ - return (*OC_TOKEN_SKIP_TABLE[_token])(_token,_extra_bits); -} - - - -void oc_enc_mode_metrics_collect(oc_enc_ctx *_enc){ - static const unsigned char OC_ZZI_HUFF_OFFSET[64]={ - 0,16,16,16,16,16,32,32, - 32,32,32,32,32,32,32,48, - 48,48,48,48,48,48,48,48, - 48,48,48,48,64,64,64,64, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64 - }; - const oc_fragment *frags; - const unsigned *frag_satd; - const unsigned *frag_ssd; - const ptrdiff_t *coded_fragis; - ptrdiff_t ncoded_fragis; - ptrdiff_t fragii; - double fragw; - int qti; - int qii; - int qi; - int pli; - int zzi; - int token; - int eb; - oc_restore_fpu(&_enc->state); - /*Load any existing mode metrics if we haven't already.*/ - if(!oc_has_mode_metrics){ - FILE *fmetrics; - memset(OC_MODE_METRICS,0,sizeof(OC_MODE_METRICS)); - fmetrics=fopen("modedec.stats","rb"); - if(fmetrics!=NULL){ - fread(OC_MODE_METRICS,sizeof(OC_MODE_METRICS),1,fmetrics); - fclose(fmetrics); - } - for(qi=0;qi<64;qi++)oc_enc_mode_metrics_update(_enc,qi); - oc_has_mode_metrics=1; - } - qti=_enc->state.frame_type; - frags=_enc->state.frags; - frag_satd=_enc->frag_satd; - frag_ssd=_enc->frag_ssd; - coded_fragis=_enc->state.coded_fragis; - ncoded_fragis=fragii=0; - /*Weight the fragments by the inverse frame size; this prevents HD content - from dominating the statistics.*/ - fragw=1.0/_enc->state.nfrags; - for(pli=0;pli<3;pli++){ - ptrdiff_t ti[64]; - int eob_token[64]; - int eob_run[64]; - /*Set up token indices and eob run counts. - We don't bother trying to figure out the real cost of the runs that span - coefficients; instead we use the costs that were available when R-D - token optimization was done.*/ - for(zzi=0;zzi<64;zzi++){ - ti[zzi]=_enc->dct_token_offs[pli][zzi]; - if(ti[zzi]>0){ - token=_enc->dct_tokens[pli][zzi][0]; - eb=_enc->extra_bits[pli][zzi][0]; - eob_token[zzi]=token; - eob_run[zzi]=-oc_dct_token_skip(token,eb); - } - else{ - eob_token[zzi]=OC_NDCT_EOB_TOKEN_MAX; - eob_run[zzi]=0; - } - } - /*Scan the list of coded fragments for this plane.*/ - ncoded_fragis+=_enc->state.ncoded_fragis[pli]; - for(;fragii<ncoded_fragis;fragii++){ - ptrdiff_t fragi; - ogg_uint32_t frag_bits; - int huffi; - int skip; - int mb_mode; - unsigned satd; - int bin; - fragi=coded_fragis[fragii]; - frag_bits=0; - for(zzi=0;zzi<64;){ - if(eob_run[zzi]>0){ - /*We've reached the end of the block.*/ - eob_run[zzi]--; - break; - } - huffi=_enc->huff_idxs[qti][zzi>0][pli+1>>1] - +OC_ZZI_HUFF_OFFSET[zzi]; - if(eob_token[zzi]<OC_NDCT_EOB_TOKEN_MAX){ - /*This token caused an EOB run to be flushed. - Therefore it gets the bits associated with it.*/ - frag_bits+=_enc->huff_codes[huffi][eob_token[zzi]].nbits - +OC_DCT_TOKEN_EXTRA_BITS[eob_token[zzi]]; - eob_token[zzi]=OC_NDCT_EOB_TOKEN_MAX; - } - token=_enc->dct_tokens[pli][zzi][ti[zzi]]; - eb=_enc->extra_bits[pli][zzi][ti[zzi]]; - ti[zzi]++; - skip=oc_dct_token_skip(token,eb); - if(skip<0){ - eob_token[zzi]=token; - eob_run[zzi]=-skip; - } - else{ - /*A regular DCT value token; accumulate the bits for it.*/ - frag_bits+=_enc->huff_codes[huffi][token].nbits - +OC_DCT_TOKEN_EXTRA_BITS[token]; - zzi+=skip; - } - } - mb_mode=frags[fragi].mb_mode; - qi=_enc->state.qis[frags[fragi].qii]; - satd=frag_satd[fragi]<<(pli+1&2); - bin=OC_MINI(satd>>OC_SAD_SHIFT,OC_SAD_BINS-1); - oc_mode_metrics_add(OC_MODE_METRICS[qi][pli][mb_mode!=OC_MODE_INTRA]+bin, - fragw,satd,frag_bits<<OC_BIT_SCALE,sqrt(frag_ssd[fragi])); - } - } - /*Update global SATD/rate/RMSE estimation matrix.*/ - for(qii=0;qii<_enc->state.nqis;qii++){ - oc_enc_mode_metrics_update(_enc,_enc->state.qis[qii]); - } -} - -void oc_enc_mode_metrics_dump(oc_enc_ctx *_enc){ - FILE *fmetrics; - int qi; - /*Generate sample points for complete list of QI values.*/ - for(qi=0;qi<64;qi++)oc_enc_mode_metrics_update(_enc,qi); - fmetrics=fopen("modedec.stats","wb"); - if(fmetrics!=NULL){ - fwrite(OC_MODE_METRICS,sizeof(OC_MODE_METRICS),1,fmetrics); - fclose(fmetrics); - } - fprintf(stdout, - "/*File generated by libtheora with OC_COLLECT_METRICS" - " defined at compile time.*/\n" - "#if !defined(_modedec_H)\n" - "# define _modedec_H (1)\n" - "\n" - "\n" - "\n" - "# if defined(OC_COLLECT_METRICS)\n" - "typedef struct oc_mode_metrics oc_mode_metrics;\n" - "# endif\n" - "typedef struct oc_mode_rd oc_mode_rd;\n" - "\n" - "\n" - "\n" - "/*The number of extra bits of precision at which to store rate" - " metrics.*/\n" - "# define OC_BIT_SCALE (%i)\n" - "/*The number of extra bits of precision at which to store RMSE metrics.\n" - " This must be at least half OC_BIT_SCALE (rounded up).*/\n" - "# define OC_RMSE_SCALE (%i)\n" - "/*The number of bins to partition statistics into.*/\n" - "# define OC_SAD_BINS (%i)\n" - "/*The number of bits of precision to drop" - " from SAD scores to assign them to a\n" - " bin.*/\n" - "# define OC_SAD_SHIFT (%i)\n" - "\n" - "\n" - "\n" - "# if defined(OC_COLLECT_METRICS)\n" - "struct oc_mode_metrics{\n" - " double fragw;\n" - " double satd;\n" - " double rate;\n" - " double rmse;\n" - " double satd2;\n" - " double satdrate;\n" - " double rate2;\n" - " double satdrmse;\n" - " double rmse2;\n" - "};\n" - "\n" - "\n" - "int oc_has_mode_metrics;\n" - "oc_mode_metrics OC_MODE_METRICS[64][3][2][OC_SAD_BINS];\n" - "# endif\n" - "\n" - "\n" - "\n" - "struct oc_mode_rd{\n" - " ogg_int16_t rate;\n" - " ogg_int16_t rmse;\n" - "};\n" - "\n" - "\n" - "# if !defined(OC_COLLECT_METRICS)\n" - "static const\n" - "# endif\n" - "oc_mode_rd OC_MODE_RD[64][3][2][OC_SAD_BINS]={\n", - OC_BIT_SCALE,OC_RMSE_SCALE,OC_SAD_BINS,OC_SAD_SHIFT); - for(qi=0;qi<64;qi++){ - int pli; - fprintf(stdout," {\n"); - for(pli=0;pli<3;pli++){ - int qti; - fprintf(stdout," {\n"); - for(qti=0;qti<2;qti++){ - int bin; - static const char *pl_names[3]={"Y'","Cb","Cr"}; - static const char *qti_names[2]={"INTRA","INTER"}; - fprintf(stdout," /*%s qi=%i %s*/\n", - pl_names[pli],qi,qti_names[qti]); - fprintf(stdout," {\n"); - fprintf(stdout," "); - for(bin=0;bin<OC_SAD_BINS;bin++){ - if(bin&&!(bin&0x3))fprintf(stdout,"\n "); - fprintf(stdout,"{%5i,%5i}", - OC_MODE_RD[qi][pli][qti][bin].rate, - OC_MODE_RD[qi][pli][qti][bin].rmse); - if(bin+1<OC_SAD_BINS)fprintf(stdout,","); - } - fprintf(stdout,"\n }"); - if(qti<1)fprintf(stdout,","); - fprintf(stdout,"\n"); - } - fprintf(stdout," }"); - if(pli<2)fprintf(stdout,","); - fprintf(stdout,"\n"); - } - fprintf(stdout," }"); - if(qi<63)fprintf(stdout,","); - fprintf(stdout,"\n"); - } - fprintf(stdout, - "};\n" - "\n" - "#endif\n"); -} -#endif diff --git a/thirdparty/libtheora/apiwrapper.c b/thirdparty/libtheora/apiwrapper.c index dc959b8d13..87b4e939f2 100644 --- a/thirdparty/libtheora/apiwrapper.c +++ b/thirdparty/libtheora/apiwrapper.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: apiwrapper.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ diff --git a/thirdparty/libtheora/apiwrapper.h b/thirdparty/libtheora/apiwrapper.h index 93454d7bda..ff45e0a4d6 100644 --- a/thirdparty/libtheora/apiwrapper.h +++ b/thirdparty/libtheora/apiwrapper.h @@ -21,7 +21,7 @@ # include <theora/theora.h> # include "theora/theoradec.h" # include "theora/theoraenc.h" -# include "internal.h" +# include "state.h" typedef struct th_api_wrapper th_api_wrapper; typedef struct th_api_info th_api_info; diff --git a/thirdparty/libtheora/bitpack.c b/thirdparty/libtheora/bitpack.c index 8195003bad..5125dde6b0 100644 --- a/thirdparty/libtheora/bitpack.c +++ b/thirdparty/libtheora/bitpack.c @@ -11,7 +11,7 @@ ******************************************************************** function: packing variable sized words into an octet stream - last mod: $Id: bitpack.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ #include <string.h> @@ -32,15 +32,18 @@ static oc_pb_window oc_pack_refill(oc_pack_buf *_b,int _bits){ const unsigned char *stop; oc_pb_window window; int available; + unsigned shift; + stop=_b->stop; + ptr=_b->ptr; window=_b->window; available=_b->bits; - ptr=_b->ptr; - stop=_b->stop; - while(available<=OC_PB_WINDOW_SIZE-8&&ptr<stop){ - available+=8; - window|=(oc_pb_window)*ptr++<<OC_PB_WINDOW_SIZE-available; + shift=OC_PB_WINDOW_SIZE-available; + while(7<shift&&ptr<stop){ + shift-=8; + window|=(oc_pb_window)*ptr++<<shift; } _b->ptr=ptr; + available=OC_PB_WINDOW_SIZE-shift; if(_bits>available){ if(ptr>=stop){ _b->eof=1; @@ -67,7 +70,7 @@ void oc_pack_adv1(oc_pack_buf *_b){ } /*Here we assume that 0<=_bits&&_bits<=32.*/ -long oc_pack_read(oc_pack_buf *_b,int _bits){ +long oc_pack_read_c(oc_pack_buf *_b,int _bits){ oc_pb_window window; int available; long result; @@ -82,12 +85,12 @@ long oc_pack_read(oc_pack_buf *_b,int _bits){ available-=_bits; window<<=1; window<<=_bits-1; - _b->bits=available; _b->window=window; + _b->bits=available; return result; } -int oc_pack_read1(oc_pack_buf *_b){ +int oc_pack_read1_c(oc_pack_buf *_b){ oc_pb_window window; int available; int result; @@ -100,8 +103,8 @@ int oc_pack_read1(oc_pack_buf *_b){ result=window>>OC_PB_WINDOW_SIZE-1; available--; window<<=1; - _b->bits=available; _b->window=window; + _b->bits=available; return result; } diff --git a/thirdparty/libtheora/bitpack.h b/thirdparty/libtheora/bitpack.h index a020a292f5..237b584055 100644 --- a/thirdparty/libtheora/bitpack.h +++ b/thirdparty/libtheora/bitpack.h @@ -16,15 +16,32 @@ ********************************************************************/ #if !defined(_bitpack_H) # define _bitpack_H (1) +# include <stddef.h> # include <limits.h> +# include "internal.h" -typedef unsigned long oc_pb_window; +typedef size_t oc_pb_window; typedef struct oc_pack_buf oc_pack_buf; +/*Custom bitpacker implementations.*/ +# if defined(OC_ARM_ASM) +# include "arm/armbits.h" +# endif + +# if !defined(oc_pack_read) +# define oc_pack_read oc_pack_read_c +# endif +# if !defined(oc_pack_read1) +# define oc_pack_read1 oc_pack_read1_c +# endif +# if !defined(oc_huff_token_decode) +# define oc_huff_token_decode oc_huff_token_decode_c +# endif + # define OC_PB_WINDOW_SIZE ((int)sizeof(oc_pb_window)*CHAR_BIT) /*This is meant to be a large, positive constant that can still be efficiently loaded as an immediate (on platforms like ARM, for example). @@ -34,9 +51,9 @@ typedef struct oc_pack_buf oc_pack_buf; struct oc_pack_buf{ - oc_pb_window window; - const unsigned char *ptr; const unsigned char *stop; + const unsigned char *ptr; + oc_pb_window window; int bits; int eof; }; @@ -45,8 +62,8 @@ void oc_pack_readinit(oc_pack_buf *_b,unsigned char *_buf,long _bytes); int oc_pack_look1(oc_pack_buf *_b); void oc_pack_adv1(oc_pack_buf *_b); /*Here we assume 0<=_bits&&_bits<=32.*/ -long oc_pack_read(oc_pack_buf *_b,int _bits); -int oc_pack_read1(oc_pack_buf *_b); +long oc_pack_read_c(oc_pack_buf *_b,int _bits); +int oc_pack_read1_c(oc_pack_buf *_b); /* returns -1 for read beyond EOF, or the number of whole bytes available */ long oc_pack_bytes_left(oc_pack_buf *_b); diff --git a/thirdparty/libtheora/collect.c b/thirdparty/libtheora/collect.c new file mode 100644 index 0000000000..c0d8a2733f --- /dev/null +++ b/thirdparty/libtheora/collect.c @@ -0,0 +1,974 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2011 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: mode selection code + last mod: $Id$ + + ********************************************************************/ +#include <stdio.h> +#include <limits.h> +#include <math.h> +#include <string.h> +#include "collect.h" + +#if defined(OC_COLLECT_METRICS) + +int OC_HAS_MODE_METRICS; +double OC_MODE_RD_WEIGHT_SATD[OC_LOGQ_BINS][3][2][OC_COMP_BINS]; +double OC_MODE_RD_WEIGHT_SAD[OC_LOGQ_BINS][3][2][OC_COMP_BINS]; +oc_mode_metrics OC_MODE_METRICS_SATD[OC_LOGQ_BINS-1][3][2][OC_COMP_BINS]; +oc_mode_metrics OC_MODE_METRICS_SAD[OC_LOGQ_BINS-1][3][2][OC_COMP_BINS]; +const char *OC_MODE_METRICS_FILENAME="modedec.stats"; + +void oc_mode_metrics_add(oc_mode_metrics *_metrics, + double _w,int _s,int _q,int _r,double _d){ + if(_metrics->w>0){ + double ds; + double dq; + double dr; + double dd; + double ds2; + double dq2; + double s2; + double sq; + double q2; + double sr; + double qr; + double sd; + double qd; + double s2q; + double sq2; + double w; + double wa; + double rwa; + double rwa2; + double rwb; + double rwb2; + double rw2; + double rw3; + double rw4; + wa=_metrics->w; + ds=_s-_metrics->s/wa; + dq=_q-_metrics->q/wa; + dr=_r-_metrics->r/wa; + dd=_d-_metrics->d/wa; + ds2=ds*ds; + dq2=dq*dq; + s2=_metrics->s2; + sq=_metrics->sq; + q2=_metrics->q2; + sr=_metrics->sr; + qr=_metrics->qr; + sd=_metrics->sd; + qd=_metrics->qd; + s2q=_metrics->s2q; + sq2=_metrics->sq2; + w=wa+_w; + rwa=wa/w; + rwb=_w/w; + rwa2=rwa*rwa; + rwb2=rwb*rwb; + rw2=wa*rwb; + rw3=rw2*(rwa2-rwb2); + rw4=_w*rwa2*rwa2+wa*rwb2*rwb2; + _metrics->s2q2+=-2*(ds*sq2+dq*s2q)*rwb + +(ds2*q2+4*ds*dq*sq+dq2*s2)*rwb2+ds2*dq2*rw4; + _metrics->s2q+=(-2*ds*sq-dq*s2)*rwb+ds2*dq*rw3; + _metrics->sq2+=(-ds*q2-2*dq*sq)*rwb+ds*dq2*rw3; + _metrics->sqr+=(-ds*qr-dq*sr-dr*sq)*rwb+ds*dq*dr*rw3; + _metrics->sqd+=(-ds*qd-dq*sd-dd*sq)*rwb+ds*dq*dd*rw3; + _metrics->s2+=ds2*rw2; + _metrics->sq+=ds*dq*rw2; + _metrics->q2+=dq2*rw2; + _metrics->sr+=ds*dr*rw2; + _metrics->qr+=dq*dr*rw2; + _metrics->r2+=dr*dr*rw2; + _metrics->sd+=ds*dd*rw2; + _metrics->qd+=dq*dd*rw2; + _metrics->d2+=dd*dd*rw2; + } + _metrics->w+=_w; + _metrics->s+=_s*_w; + _metrics->q+=_q*_w; + _metrics->r+=_r*_w; + _metrics->d+=_d*_w; +} + +void oc_mode_metrics_merge(oc_mode_metrics *_dst, + const oc_mode_metrics *_src,int _n){ + int i; + /*Find a non-empty set of metrics.*/ + for(i=0;i<_n&&_src[i].w==0;i++); + if(i>=_n){ + memset(_dst,0,sizeof(*_dst)); + return; + } + memcpy(_dst,_src+i,sizeof(*_dst)); + /*And iterate over the remaining non-empty sets of metrics.*/ + for(i++;i<_n;i++)if(_src[i].w!=0){ + double ds; + double dq; + double dr; + double dd; + double ds2; + double dq2; + double s2a; + double s2b; + double sqa; + double sqb; + double q2a; + double q2b; + double sra; + double srb; + double qra; + double qrb; + double sda; + double sdb; + double qda; + double qdb; + double s2qa; + double s2qb; + double sq2a; + double sq2b; + double w; + double wa; + double wb; + double rwa; + double rwb; + double rwa2; + double rwb2; + double rw2; + double rw3; + double rw4; + wa=_dst->w; + wb=_src[i].w; + ds=_src[i].s/wb-_dst->s/wa; + dq=_src[i].q/wb-_dst->q/wa; + dr=_src[i].r/wb-_dst->r/wa; + dd=_src[i].d/wb-_dst->d/wa; + ds2=ds*ds; + dq2=dq*dq; + s2a=_dst->s2; + sqa=_dst->sq; + q2a=_dst->q2; + sra=_dst->sr; + qra=_dst->qr; + sda=_dst->sd; + qda=_dst->qd; + s2qa=_dst->s2q; + sq2a=_dst->sq2; + s2b=_src[i].s2; + sqb=_src[i].sq; + q2b=_src[i].q2; + srb=_src[i].sr; + qrb=_src[i].qr; + sdb=_src[i].sd; + qdb=_src[i].qd; + s2qb=_src[i].s2q; + sq2b=_src[i].sq2; + w=wa+wb; + if(w==0)rwa=rwb=0; + else{ + rwa=wa/w; + rwb=wb/w; + } + rwa2=rwa*rwa; + rwb2=rwb*rwb; + rw2=wa*rwb; + rw3=rw2*(rwa2-rwb2); + rw4=wb*rwa2*rwa2+wa*rwb2*rwb2; + /* + (1,1,1) -> + (0,0,0)# + (1,0,0) C(1,1)*C(1,0)*C(1,0)-> d^{1,0,0}*(rwa*B_{0,1,1}-rwb*A_{0,1,1}) + (0,1,0) C(1,0)*C(1,1)*C(1,0)-> d^{0,1,0}*(rwa*B_{1,0,1}-rwb*A_{1,0,1}) + (0,0,1) C(1,0)*C(1,0)*C(1,1)-> d^{0,0,1}*(rwa*B_{1,1,0}-rwb*A_{1,1,0}) + (1,1,0)* + (1,0,1)* + (0,1,1)* + (1,1,1) C(1,1)*C(1,1)*C(1,1)-> d^{1,1,1}*(rwa^3*wb-rwb^3*wa) + (2,1) -> + (0,0)# + (1,0) C(2,1)*C(1,1)->2*d^{1,0}*(rwa*B_{1,1}-rwb*A_{1,1}) + (0,1) C(2,0)*C(1,1)-> d^{0,1}*(rwa*B_{2,0}-rwb*A_{2,0}) + (2,0)* + (1,1)* + (2,1) C(2,2)*C(1,1)-> d^{2,1}*(rwa^3*wb-rwb^3*wa) + (2,2) -> + (0,0)# + (1,0) C(2,1)*C(2,0)->2*d^{1,0}*(rwa*B_{1,2}-rwb*A_{1,2}) + (0,1) C(2,0)*C(2,1)->2*d^{0,1}*(rwa*B_{2,1}-rwb*A_{2,1}) + (2,0) C(2,2)*C(2,0)-> d^{2,0}*(rwa^2*B_{0,2}+rwb^2*A_{0,2}) + (1,1) C(2,1)*C(2,1)->4*d^{1,1}*(rwa^2*B_{1,1}+rwb^2*A_{1,1}) + (0,2) C(2,0)*C(2,2)-> d^{0,2}*(rwa^2*B_{2,0}+rwb^2*A_{2,0}) + (1,2)* + (2,1)* + (2,2) C(2,2)*C(2,2)*d^{2,2}*(rwa^4*wb+rwb^4*wa) + */ + _dst->s2q2+=_src[i].s2q2+2*(ds*(rwa*sq2b-rwb*sq2a)+dq*(rwa*s2qb-rwb*s2qa)) + +ds2*(rwa2*q2b+rwb2*q2a)+4*ds*dq*(rwa2*sqb+rwb2*sqa) + +dq2*(rwa2*s2b+rwb2*s2a)+ds2*dq2*rw4; + _dst->s2q+=_src[i].s2q+2*ds*(rwa*sqb-rwb*sqa) + +dq*(rwa*s2b-rwb*s2a)+ds2*dq*rw3; + _dst->sq2+=_src[i].sq2+ds*(rwa*q2b-rwb*q2a) + +2*dq*(rwa*sqb-rwb*sqa)+ds*dq2*rw3; + _dst->sqr+=_src[i].sqr+ds*(rwa*qrb-rwb*qra)+dq*(rwa*srb-rwb*sra) + +dr*(rwa*sqb-rwb*sqa)+ds*dq*dr*rw3; + _dst->sqd+=_src[i].sqd+ds*(rwa*qdb-rwb*qda)+dq*(rwa*sdb-rwb*sda) + +dd*(rwa*sqb-rwb*sqa)+ds*dq*dd*rw3; + _dst->s2+=_src[i].s2+ds2*rw2; + _dst->sq+=_src[i].sq+ds*dq*rw2; + _dst->q2+=_src[i].q2+dq2*rw2; + _dst->sr+=_src[i].sr+ds*dr*rw2; + _dst->qr+=_src[i].qr+dq*dr*rw2; + _dst->r2+=_src[i].r2+dr*dr*rw2; + _dst->sd+=_src[i].sd+ds*dd*rw2; + _dst->qd+=_src[i].qd+dq*dd*rw2; + _dst->d2+=_src[i].d2+dd*dd*rw2; + _dst->w+=_src[i].w; + _dst->s+=_src[i].s; + _dst->q+=_src[i].q; + _dst->r+=_src[i].r; + _dst->d+=_src[i].d; + } +} + +/*Adjust a single corner of a set of metric bins to minimize the squared + prediction error of R and D. + Each bin is assumed to cover a quad like so: + (s0,q0) (s1,q0) + A----------B + | | + | | + | | + | | + C----------Z + (s0,q1) (s1,q1) + The values A, B, and C are fixed, and Z is the free parameter. + Then, for example, R_i is predicted via bilinear interpolation as + x_i=(s_i-s0)/(s1-s0) + y_i=(q_i-q0)/(q1-q0) + dRds1_i=A+(B-A)*x_i + dRds2_i=C+(Z-C)*x_i + R_i=dRds1_i+(dRds2_i-dRds1_i)*y_i + To find the Z that minimizes the squared prediction error over i, this can + be rewritten as + R_i-(A+(B-A)*x_i+(C-A)*y_i+(A-B-C)*x_i*y_i)=x_i*y_i*Z + Letting X={...,x_i*y_i,...}^T and + Y={...,R_i-(A+(B-A)*x_i+(C-A)*y_i+(A-B-C)*x_i*y_i),...}^T, + the optimal Z is given by Z=(X^T.Y)/(X^T.X). + Now, we need to compute these dot products without actually storing data for + each sample. + Starting with X^T.X, we have + X^T.X = sum(x_i^2*y_i^2) = sum((s_i-s0)^2*(q_i-q0)^2)/((s1-s0)^2*(q1-q0)^2). + Expanding the interior of the sum in a monomial basis of s_i and q_i gives + s0^2*q0^2 *(1) + -2*s0*q0^2*(s_i) + -2*s0^2*q0*(q_i) + +q0^2 *(s_i^2) + +4*s0*q0 *(s_i*q_i) + +s0^2 *(q_i^2) + -2*q0 *(s_i^2*q_i) + -2*s0 *(s_i*q_i^2) + +1 *(s_i^2*q_i^2). + However, computing things directly in this basis leads to gross numerical + errors, as most of the terms will have similar size and destructive + cancellation results. + A much better basis is the central (co-)moment basis: + {1,s_i-sbar,q_i-qbar,(s_i-sbar)^2,(s_i-sbar)*(q_i-qbar),(q_i-qbar)^2, + (s_i-sbar)^2*(q_i-qbar),(s_i-sbar)*(q_i-qbar)^2,(s_i-sbar)^2*(q_i-qbar)^2}, + where sbar and qbar are the average s and q values over the bin, + respectively. + In that basis, letting ds=sbar-s0 and dq=qbar-q0, (s_i-s0)^2*(q_i-q0)^2 is + ds^2*dq^2*(1) + +dq^2 *((s_i-sbar)^2) + +4*ds*dq*((s_i-sbar)*(q_i-qbar)) + +ds^2 *((q_i-qbar)^2) + +2*dq *((s_i-sbar)^2*(q_i-qbar)) + +2*ds *((s_i-sbar)*(q_i-qbar)^2) + +1 *((s_i-sbar)^2*(q_i-qbar)^2). + With these expressions in the central (co-)moment bases, all we need to do + is compute sums over the (co-)moment terms, which can be done + incrementally (see oc_mode_metrics_add() and oc_mode_metrics_merge()), + with no need to store the individual samples. + Now, for X^T.Y, we have + X^T.Y = sum((R_i-A-((B-A)/(s1-s0))*(s_i-s0)-((C-A)/(q1-q0))*(q_i-q0) + -((A-B-C)/((s1-s0)*(q1-q0)))*(s_i-s0)*(q_i-q0))*(s_i-s0)*(q_i-q0))/ + ((s1-s0)*(q1-q0)), + or, rewriting the constants to simplify notation, + X^T.Y = sum((C0+C1*(s_i-s0)+C2*(q_i-q0) + +C3*(s_i-s0)*(q_i-q0)+R_i)*(s_i-s0)*(q_i-q0))/((s1-s0)*(q1-q0)). + Again, converting to the central (co-)moment basis, the interior of the + above sum is + ds*dq*(rbar+C0+C1*ds+C2*dq+C3*ds*dq) *(1) + +(C1*dq+C3*dq^2) *((s_i-sbar)^2) + +(rbar+C0+2*C1*ds+2*C2*dq+4*C3*ds*dq)*((s_i-sbar)*(q_i-qbar)) + +(C2*ds+C3*ds^2) *((q_i-qbar)^2) + +dq *((s_i-sbar)*(r_i-rbar)) + +ds *((q_i-qbar)*(r_i-rbar)) + +(C1+2*C3*dq) *((s_i-sbar)^2*(q_i-qbar)) + +(C2+2*C3*ds) *((s_i-sbar)*(q_i-qbar)^2) + +1 *((s_i-sbar)*(q_i-qbar)*(r_i-rbar)) + +C3 *((s_i-sbar)^2*(q_i-qbar)^2). + You might think it would be easier (if perhaps slightly less robust) to + accumulate terms directly around s0 and q0. + However, we update each corner of the bins in turn, so we would have to + change basis to move the sums from corner to corner anyway.*/ +double oc_mode_metrics_solve(double *_r,double *_d, + const oc_mode_metrics *_metrics,const int *_s0,const int *_s1, + const int *_q0,const int *_q1, + const double *_ra,const double *_rb,const double *_rc, + const double *_da,const double *_db,const double *_dc,int _n){ + double xx; + double rxy; + double dxy; + double wt; + int i; + xx=rxy=dxy=wt=0; + for(i=0;i<_n;i++)if(_metrics[i].w>0){ + double s10; + double q10; + double sq10; + double ds; + double dq; + double ds2; + double dq2; + double r; + double d; + double s2; + double sq; + double q2; + double sr; + double qr; + double sd; + double qd; + double s2q; + double sq2; + double sqr; + double sqd; + double s2q2; + double c0; + double c1; + double c2; + double c3; + double w; + w=_metrics[i].w; + wt+=w; + s10=_s1[i]-_s0[i]; + q10=_q1[i]-_q0[i]; + sq10=s10*q10; + ds=_metrics[i].s/w-_s0[i]; + dq=_metrics[i].q/w-_q0[i]; + ds2=ds*ds; + dq2=dq*dq; + s2=_metrics[i].s2; + sq=_metrics[i].sq; + q2=_metrics[i].q2; + s2q=_metrics[i].s2q; + sq2=_metrics[i].sq2; + s2q2=_metrics[i].s2q2; + xx+=(dq2*(ds2*w+s2)+4*ds*dq*sq+ds2*q2+2*(dq*s2q+ds*sq2)+s2q2)/(sq10*sq10); + r=_metrics[i].r/w; + sr=_metrics[i].sr; + qr=_metrics[i].qr; + sqr=_metrics[i].sqr; + c0=-_ra[i]; + c1=-(_rb[i]-_ra[i])/s10; + c2=-(_rc[i]-_ra[i])/q10; + c3=-(_ra[i]-_rb[i]-_rc[i])/sq10; + rxy+=(ds*dq*(r+c0+c1*ds+c2*dq+c3*ds*dq)*w+(c1*dq+c3*dq2)*s2 + +(r+c0+2*(c1*ds+(c2+2*c3*ds)*dq))*sq+(c2*ds+c3*ds2)*q2+dq*sr+ds*qr + +(c1+2*c3*dq)*s2q+(c2+2*c3*ds)*sq2+sqr+c3*s2q2)/sq10; + d=_metrics[i].d/w; + sd=_metrics[i].sd; + qd=_metrics[i].qd; + sqd=_metrics[i].sqd; + c0=-_da[i]; + c1=-(_db[i]-_da[i])/s10; + c2=-(_dc[i]-_da[i])/q10; + c3=-(_da[i]-_db[i]-_dc[i])/sq10; + dxy+=(ds*dq*(d+c0+c1*ds+c2*dq+c3*ds*dq)*w+(c1*dq+c3*dq2)*s2 + +(d+c0+2*(c1*ds+(c2+2*c3*ds)*dq))*sq+(c2*ds+c3*ds2)*q2+dq*sd+ds*qd + +(c1+2*c3*dq)*s2q+(c2+2*c3*ds)*sq2+sqd+c3*s2q2)/sq10; + } + if(xx>1E-3){ + *_r=rxy/xx; + *_d=dxy/xx; + } + else{ + *_r=0; + *_d=0; + } + return wt; +} + +/*Compile collected SATD/logq/rate/RMSE metrics into a form that's immediately + useful for mode decision.*/ +void oc_mode_metrics_update(oc_mode_metrics (*_metrics)[3][2][OC_COMP_BINS], + int _niters_min,int _reweight,oc_mode_rd (*_table)[3][2][OC_COMP_BINS], + int _shift,double (*_weight)[3][2][OC_COMP_BINS]){ + int niters; + int prevdr; + int prevdd; + int dr; + int dd; + int pli; + int qti; + int qi; + int si; + dd=dr=INT_MAX; + niters=0; + /*The encoder interpolates rate and RMSE terms bilinearly from an + OC_LOGQ_BINS by OC_COMP_BINS grid of sample points in _table. + To find the sample values at the grid points that minimize the total + squared prediction error actually requires solving a relatively sparse + linear system with a number of variables equal to the number of grid + points. + Instead of writing a general sparse linear system solver, we just use + Gauss-Seidel iteration, i.e., we update one grid point at time until + they stop changing.*/ + do{ + prevdr=dr; + prevdd=dd; + dd=dr=0; + for(pli=0;pli<3;pli++){ + for(qti=0;qti<2;qti++){ + for(qi=0;qi<OC_LOGQ_BINS;qi++){ + for(si=0;si<OC_COMP_BINS;si++){ + oc_mode_metrics m[4]; + int s0[4]; + int s1[4]; + int q0[4]; + int q1[4]; + double ra[4]; + double rb[4]; + double rc[4]; + double da[4]; + double db[4]; + double dc[4]; + double r; + double d; + int rate; + int rmse; + int ds; + int n; + n=0; + /*Collect the statistics for the (up to) four bins grid point + (si,qi) touches.*/ + if(qi>0&&si>0){ + q0[n]=OC_MODE_LOGQ[qi-1][pli][qti]; + q1[n]=OC_MODE_LOGQ[qi][pli][qti]; + s0[n]=si-1<<_shift; + s1[n]=si<<_shift; + ra[n]=ldexp(_table[qi-1][pli][qti][si-1].rate,-OC_BIT_SCALE); + da[n]=ldexp(_table[qi-1][pli][qti][si-1].rmse,-OC_RMSE_SCALE); + rb[n]=ldexp(_table[qi-1][pli][qti][si].rate,-OC_BIT_SCALE); + db[n]=ldexp(_table[qi-1][pli][qti][si].rmse,-OC_RMSE_SCALE); + rc[n]=ldexp(_table[qi][pli][qti][si-1].rate,-OC_BIT_SCALE); + dc[n]=ldexp(_table[qi][pli][qti][si-1].rmse,-OC_RMSE_SCALE); + *(m+n++)=*(_metrics[qi-1][pli][qti]+si-1); + } + if(qi>0){ + ds=si+1<OC_COMP_BINS?1:-1; + q0[n]=OC_MODE_LOGQ[qi-1][pli][qti]; + q1[n]=OC_MODE_LOGQ[qi][pli][qti]; + s0[n]=si+ds<<_shift; + s1[n]=si<<_shift; + ra[n]=ldexp(_table[qi-1][pli][qti][si+ds].rate,-OC_BIT_SCALE); + da[n]= + ldexp(_table[qi-1][pli][qti][si+ds].rmse,-OC_RMSE_SCALE); + rb[n]=ldexp(_table[qi-1][pli][qti][si].rate,-OC_BIT_SCALE); + db[n]=ldexp(_table[qi-1][pli][qti][si].rmse,-OC_RMSE_SCALE); + rc[n]=ldexp(_table[qi][pli][qti][si+ds].rate,-OC_BIT_SCALE); + dc[n]=ldexp(_table[qi][pli][qti][si+ds].rmse,-OC_RMSE_SCALE); + *(m+n++)=*(_metrics[qi-1][pli][qti]+si); + } + if(qi+1<OC_LOGQ_BINS&&si>0){ + q0[n]=OC_MODE_LOGQ[qi+1][pli][qti]; + q1[n]=OC_MODE_LOGQ[qi][pli][qti]; + s0[n]=si-1<<_shift; + s1[n]=si<<_shift; + ra[n]=ldexp(_table[qi+1][pli][qti][si-1].rate,-OC_BIT_SCALE); + da[n]=ldexp(_table[qi+1][pli][qti][si-1].rmse,-OC_RMSE_SCALE); + rb[n]=ldexp(_table[qi+1][pli][qti][si].rate,-OC_BIT_SCALE); + db[n]=ldexp(_table[qi+1][pli][qti][si].rmse,-OC_RMSE_SCALE); + rc[n]=ldexp(_table[qi][pli][qti][si-1].rate,-OC_BIT_SCALE); + dc[n]=ldexp(_table[qi][pli][qti][si-1].rmse,-OC_RMSE_SCALE); + *(m+n++)=*(_metrics[qi][pli][qti]+si-1); + } + if(qi+1<OC_LOGQ_BINS){ + ds=si+1<OC_COMP_BINS?1:-1; + q0[n]=OC_MODE_LOGQ[qi+1][pli][qti]; + q1[n]=OC_MODE_LOGQ[qi][pli][qti]; + s0[n]=si+ds<<_shift; + s1[n]=si<<_shift; + ra[n]=ldexp(_table[qi+1][pli][qti][si+ds].rate,-OC_BIT_SCALE); + da[n]= + ldexp(_table[qi+1][pli][qti][si+ds].rmse,-OC_RMSE_SCALE); + rb[n]=ldexp(_table[qi+1][pli][qti][si].rate,-OC_BIT_SCALE); + db[n]=ldexp(_table[qi+1][pli][qti][si].rmse,-OC_RMSE_SCALE); + rc[n]=ldexp(_table[qi][pli][qti][si+ds].rate,-OC_BIT_SCALE); + dc[n]=ldexp(_table[qi][pli][qti][si+ds].rmse,-OC_RMSE_SCALE); + *(m+n++)=*(_metrics[qi][pli][qti]+si); + } + /*On the first pass, initialize with a simple weighted average of + the neighboring bins.*/ + if(!OC_HAS_MODE_METRICS&&niters==0){ + double w; + w=r=d=0; + while(n-->0){ + w+=m[n].w; + r+=m[n].r; + d+=m[n].d; + } + r=w>1E-3?r/w:0; + d=w>1E-3?d/w:0; + _weight[qi][pli][qti][si]=w; + } + else{ + /*Update the grid point and save the weight for later.*/ + _weight[qi][pli][qti][si]= + oc_mode_metrics_solve(&r,&d,m,s0,s1,q0,q1,ra,rb,rc,da,db,dc,n); + } + rate=OC_CLAMPI(-32768,(int)(ldexp(r,OC_BIT_SCALE)+0.5),32767); + rmse=OC_CLAMPI(-32768,(int)(ldexp(d,OC_RMSE_SCALE)+0.5),32767); + dr+=abs(rate-_table[qi][pli][qti][si].rate); + dd+=abs(rmse-_table[qi][pli][qti][si].rmse); + _table[qi][pli][qti][si].rate=(ogg_int16_t)rate; + _table[qi][pli][qti][si].rmse=(ogg_int16_t)rmse; + } + } + } + } + } + /*After a fixed number of initial iterations, only iterate so long as the + total change is decreasing. + This ensures we don't oscillate forever, which is a danger, as all of our + results are rounded fairly coarsely.*/ + while((dr>0||dd>0)&&(niters++<_niters_min||(dr<prevdr&&dd<prevdd))); + if(_reweight){ + /*Now, reduce the values of the optimal solution until we get enough + samples in each bin to overcome the constant OC_ZWEIGHT factor. + This encourages sampling under-populated bins and prevents a single large + sample early on from discouraging coding in that bin ever again.*/ + for(pli=0;pli<3;pli++){ + for(qti=0;qti<2;qti++){ + for(qi=0;qi<OC_LOGQ_BINS;qi++){ + for(si=0;si<OC_COMP_BINS;si++){ + double wt; + wt=_weight[qi][pli][qti][si]; + wt/=OC_ZWEIGHT+wt; + _table[qi][pli][qti][si].rate=(ogg_int16_t) + (_table[qi][pli][qti][si].rate*wt+0.5); + _table[qi][pli][qti][si].rmse=(ogg_int16_t) + (_table[qi][pli][qti][si].rmse*wt+0.5); + } + } + } + } + } +} + +/*Dump the in memory mode metrics to a file. + Note this data format isn't portable between different platforms.*/ +void oc_mode_metrics_dump(void){ + FILE *fmetrics; + fmetrics=fopen(OC_MODE_METRICS_FILENAME,"wb"); + if(fmetrics!=NULL){ + (void)fwrite(OC_MODE_LOGQ,sizeof(OC_MODE_LOGQ),1,fmetrics); + (void)fwrite(OC_MODE_METRICS_SATD,sizeof(OC_MODE_METRICS_SATD),1,fmetrics); + (void)fwrite(OC_MODE_METRICS_SAD,sizeof(OC_MODE_METRICS_SAD),1,fmetrics); + fclose(fmetrics); + } +} + +void oc_mode_metrics_print_rd(FILE *_fout,const char *_table_name, +#if !defined(OC_COLLECT_METRICS) + const oc_mode_rd (*_mode_rd_table)[3][2][OC_COMP_BINS]){ +#else + oc_mode_rd (*_mode_rd_table)[3][2][OC_COMP_BINS]){ +#endif + int qii; + fprintf(_fout, + "# if !defined(OC_COLLECT_METRICS)\n" + "static const\n" + "# endif\n" + "oc_mode_rd %s[OC_LOGQ_BINS][3][2][OC_COMP_BINS]={\n",_table_name); + for(qii=0;qii<OC_LOGQ_BINS;qii++){ + int pli; + fprintf(_fout," {\n"); + for(pli=0;pli<3;pli++){ + int qti; + fprintf(_fout," {\n"); + for(qti=0;qti<2;qti++){ + int bin; + int qi; + static const char *pl_names[3]={"Y'","Cb","Cr"}; + static const char *qti_names[2]={"INTRA","INTER"}; + qi=(63*qii+(OC_LOGQ_BINS-1>>1))/(OC_LOGQ_BINS-1); + fprintf(_fout," /*%s qi=%i %s*/\n", + pl_names[pli],qi,qti_names[qti]); + fprintf(_fout," {\n"); + fprintf(_fout," "); + for(bin=0;bin<OC_COMP_BINS;bin++){ + if(bin&&!(bin&0x3))fprintf(_fout,"\n "); + fprintf(_fout,"{%5i,%5i}", + _mode_rd_table[qii][pli][qti][bin].rate, + _mode_rd_table[qii][pli][qti][bin].rmse); + if(bin+1<OC_COMP_BINS)fprintf(_fout,","); + } + fprintf(_fout,"\n }"); + if(qti<1)fprintf(_fout,","); + fprintf(_fout,"\n"); + } + fprintf(_fout," }"); + if(pli<2)fprintf(_fout,","); + fprintf(_fout,"\n"); + } + fprintf(_fout," }"); + if(qii+1<OC_LOGQ_BINS)fprintf(_fout,","); + fprintf(_fout,"\n"); + } + fprintf(_fout, + "};\n" + "\n"); +} + +void oc_mode_metrics_print(FILE *_fout){ + int qii; + fprintf(_fout, + "/*File generated by libtheora with OC_COLLECT_METRICS" + " defined at compile time.*/\n" + "#if !defined(_modedec_H)\n" + "# define _modedec_H (1)\n" + "# include \"encint.h\"\n" + "\n" + "\n" + "\n" + "/*The log of the average quantizer for each of the OC_MODE_RD table rows\n" + " (e.g., for the represented qi's, and each pli and qti), in Q10 format.\n" + " The actual statistics used by the encoder will be interpolated from\n" + " that table based on log_plq for the actual quantization matrix used.*/\n" + "# if !defined(OC_COLLECT_METRICS)\n" + "static const\n" + "# endif\n" + "ogg_int16_t OC_MODE_LOGQ[OC_LOGQ_BINS][3][2]={\n"); + for(qii=0;qii<OC_LOGQ_BINS;qii++){ + fprintf(_fout," { {0x%04X,0x%04X},{0x%04X,0x%04X},{0x%04X,0x%04X} }%s\n", + OC_MODE_LOGQ[qii][0][0],OC_MODE_LOGQ[qii][0][1],OC_MODE_LOGQ[qii][1][0], + OC_MODE_LOGQ[qii][1][1],OC_MODE_LOGQ[qii][2][0],OC_MODE_LOGQ[qii][2][1], + qii+1<OC_LOGQ_BINS?",":""); + } + fprintf(_fout, + "};\n" + "\n"); + oc_mode_metrics_print_rd(_fout,"OC_MODE_RD_SATD",OC_MODE_RD_SATD); + oc_mode_metrics_print_rd(_fout,"OC_MODE_RD_SAD",OC_MODE_RD_SAD); + fprintf(_fout, + "#endif\n"); +} + + +# if !defined(OC_COLLECT_NO_ENC_FUNCS) +void oc_enc_mode_metrics_load(oc_enc_ctx *_enc){ + oc_restore_fpu(&_enc->state); + /*Load any existing mode metrics if we haven't already.*/ + if(!OC_HAS_MODE_METRICS){ + FILE *fmetrics; + memset(OC_MODE_METRICS_SATD,0,sizeof(OC_MODE_METRICS_SATD)); + memset(OC_MODE_METRICS_SAD,0,sizeof(OC_MODE_METRICS_SAD)); + fmetrics=fopen(OC_MODE_METRICS_FILENAME,"rb"); + if(fmetrics!=NULL){ + /*Read in the binary structures as written my oc_mode_metrics_dump(). + Note this format isn't portable between different platforms.*/ + (void)fread(OC_MODE_LOGQ,sizeof(OC_MODE_LOGQ),1,fmetrics); + (void)fread(OC_MODE_METRICS_SATD,sizeof(OC_MODE_METRICS_SATD),1,fmetrics); + (void)fread(OC_MODE_METRICS_SAD,sizeof(OC_MODE_METRICS_SAD),1,fmetrics); + fclose(fmetrics); + } + else{ + int qii; + int qi; + int pli; + int qti; + for(qii=0;qii<OC_LOGQ_BINS;qii++){ + qi=(63*qii+(OC_LOGQ_BINS-1>>1))/(OC_LOGQ_BINS-1); + for(pli=0;pli<3;pli++)for(qti=0;qti<2;qti++){ + OC_MODE_LOGQ[qii][pli][qti]=_enc->log_plq[qi][pli][qti]; + } + } + } + oc_mode_metrics_update(OC_MODE_METRICS_SATD,100,1, + OC_MODE_RD_SATD,OC_SATD_SHIFT,OC_MODE_RD_WEIGHT_SATD); + oc_mode_metrics_update(OC_MODE_METRICS_SAD,100,1, + OC_MODE_RD_SAD,OC_SAD_SHIFT,OC_MODE_RD_WEIGHT_SAD); + OC_HAS_MODE_METRICS=1; + } +} + +/*The following token skipping code used to also be used in the decoder (and + even at one point other places in the encoder). + However, it was obsoleted by other optimizations, and is now only used here. + It has been moved here to avoid generating the code when it's not needed.*/ + +/*Determines the number of blocks or coefficients to be skipped for a given + token value. + _token: The token value to skip. + _extra_bits: The extra bits attached to this token. + Return: A positive value indicates that number of coefficients are to be + skipped in the current block. + Otherwise, the negative of the return value indicates that number of + blocks are to be ended.*/ +typedef ptrdiff_t (*oc_token_skip_func)(int _token,int _extra_bits); + +/*Handles the simple end of block tokens.*/ +static ptrdiff_t oc_token_skip_eob(int _token,int _extra_bits){ + int nblocks_adjust; + nblocks_adjust=OC_UNIBBLE_TABLE32(0,1,2,3,7,15,0,0,_token)+1; + return -_extra_bits-nblocks_adjust; +} + +/*The last EOB token has a special case, where an EOB run of size zero ends all + the remaining blocks in the frame.*/ +static ptrdiff_t oc_token_skip_eob6(int _token,int _extra_bits){ + /*Note: We want to return -PTRDIFF_MAX, but that requires C99, which is not + yet available everywhere; this should be equivalent.*/ + if(!_extra_bits)return -(~(size_t)0>>1); + return -_extra_bits; +} + +/*Handles the pure zero run tokens.*/ +static ptrdiff_t oc_token_skip_zrl(int _token,int _extra_bits){ + return _extra_bits+1; +} + +/*Handles a normal coefficient value token.*/ +static ptrdiff_t oc_token_skip_val(void){ + return 1; +} + +/*Handles a category 1A zero run/coefficient value combo token.*/ +static ptrdiff_t oc_token_skip_run_cat1a(int _token){ + return _token-OC_DCT_RUN_CAT1A+2; +} + +/*Handles category 1b, 1c, 2a, and 2b zero run/coefficient value combo tokens.*/ +static ptrdiff_t oc_token_skip_run(int _token,int _extra_bits){ + int run_cati; + int ncoeffs_mask; + int ncoeffs_adjust; + run_cati=_token-OC_DCT_RUN_CAT1B; + ncoeffs_mask=OC_BYTE_TABLE32(3,7,0,1,run_cati); + ncoeffs_adjust=OC_BYTE_TABLE32(7,11,2,3,run_cati); + return (_extra_bits&ncoeffs_mask)+ncoeffs_adjust; +} + +/*A jump table for computing the number of coefficients or blocks to skip for + a given token value. + This reduces all the conditional branches, etc., needed to parse these token + values down to one indirect jump.*/ +static const oc_token_skip_func OC_TOKEN_SKIP_TABLE[TH_NDCT_TOKENS]={ + oc_token_skip_eob, + oc_token_skip_eob, + oc_token_skip_eob, + oc_token_skip_eob, + oc_token_skip_eob, + oc_token_skip_eob, + oc_token_skip_eob6, + oc_token_skip_zrl, + oc_token_skip_zrl, + (oc_token_skip_func)oc_token_skip_val, + (oc_token_skip_func)oc_token_skip_val, + (oc_token_skip_func)oc_token_skip_val, + (oc_token_skip_func)oc_token_skip_val, + (oc_token_skip_func)oc_token_skip_val, + (oc_token_skip_func)oc_token_skip_val, + (oc_token_skip_func)oc_token_skip_val, + (oc_token_skip_func)oc_token_skip_val, + (oc_token_skip_func)oc_token_skip_val, + (oc_token_skip_func)oc_token_skip_val, + (oc_token_skip_func)oc_token_skip_val, + (oc_token_skip_func)oc_token_skip_val, + (oc_token_skip_func)oc_token_skip_val, + (oc_token_skip_func)oc_token_skip_val, + (oc_token_skip_func)oc_token_skip_run_cat1a, + (oc_token_skip_func)oc_token_skip_run_cat1a, + (oc_token_skip_func)oc_token_skip_run_cat1a, + (oc_token_skip_func)oc_token_skip_run_cat1a, + (oc_token_skip_func)oc_token_skip_run_cat1a, + oc_token_skip_run, + oc_token_skip_run, + oc_token_skip_run, + oc_token_skip_run +}; + +/*Determines the number of blocks or coefficients to be skipped for a given + token value. + _token: The token value to skip. + _extra_bits: The extra bits attached to this token. + Return: A positive value indicates that number of coefficients are to be + skipped in the current block. + Otherwise, the negative of the return value indicates that number of + blocks are to be ended. + 0 will never be returned, so that at least one coefficient in one + block will always be decoded for every token.*/ +static ptrdiff_t oc_dct_token_skip(int _token,int _extra_bits){ + return (*OC_TOKEN_SKIP_TABLE[_token])(_token,_extra_bits); +} + + +void oc_enc_mode_metrics_collect(oc_enc_ctx *_enc){ + static const unsigned char OC_ZZI_HUFF_OFFSET[64]={ + 0,16,16,16,16,16,32,32, + 32,32,32,32,32,32,32,48, + 48,48,48,48,48,48,48,48, + 48,48,48,48,64,64,64,64, + 64,64,64,64,64,64,64,64, + 64,64,64,64,64,64,64,64, + 64,64,64,64,64,64,64,64 + }; + const oc_fragment *frags; + const unsigned *frag_sad; + const unsigned *frag_satd; + const unsigned *frag_ssd; + const ptrdiff_t *coded_fragis; + ptrdiff_t ncoded_fragis; + ptrdiff_t fragii; + double fragw; + int modelines[3][3][2]; + int qti; + int qii; + int qi; + int pli; + int zzi; + int token; + int eb; + oc_restore_fpu(&_enc->state); + /*Figure out which metric bins to use for this frame's quantizers.*/ + for(qii=0;qii<_enc->state.nqis;qii++){ + for(pli=0;pli<3;pli++){ + for(qti=0;qti<2;qti++){ + int log_plq; + int modeline; + log_plq=_enc->log_plq[_enc->state.qis[qii]][pli][qti]; + for(modeline=0;modeline<OC_LOGQ_BINS-1&& + OC_MODE_LOGQ[modeline+1][pli][qti]>log_plq;modeline++); + modelines[qii][pli][qti]=modeline; + } + } + } + qti=_enc->state.frame_type; + frags=_enc->state.frags; + frag_sad=_enc->frag_sad; + frag_satd=_enc->frag_satd; + frag_ssd=_enc->frag_ssd; + coded_fragis=_enc->state.coded_fragis; + ncoded_fragis=fragii=0; + /*Weight the fragments by the inverse frame size; this prevents HD content + from dominating the statistics.*/ + fragw=1.0/_enc->state.nfrags; + for(pli=0;pli<3;pli++){ + ptrdiff_t ti[64]; + int eob_token[64]; + int eob_run[64]; + /*Set up token indices and eob run counts. + We don't bother trying to figure out the real cost of the runs that span + coefficients; instead we use the costs that were available when R-D + token optimization was done.*/ + for(zzi=0;zzi<64;zzi++){ + ti[zzi]=_enc->dct_token_offs[pli][zzi]; + if(ti[zzi]>0){ + token=_enc->dct_tokens[pli][zzi][0]; + eb=_enc->extra_bits[pli][zzi][0]; + eob_token[zzi]=token; + eob_run[zzi]=-oc_dct_token_skip(token,eb); + } + else{ + eob_token[zzi]=OC_NDCT_EOB_TOKEN_MAX; + eob_run[zzi]=0; + } + } + /*Scan the list of coded fragments for this plane.*/ + ncoded_fragis+=_enc->state.ncoded_fragis[pli]; + for(;fragii<ncoded_fragis;fragii++){ + ptrdiff_t fragi; + int frag_bits; + int huffi; + int skip; + int mb_mode; + unsigned sad; + unsigned satd; + double sqrt_ssd; + int bin; + int qtj; + fragi=coded_fragis[fragii]; + frag_bits=0; + for(zzi=0;zzi<64;){ + if(eob_run[zzi]>0){ + /*We've reached the end of the block.*/ + eob_run[zzi]--; + break; + } + huffi=_enc->huff_idxs[qti][zzi>0][pli+1>>1] + +OC_ZZI_HUFF_OFFSET[zzi]; + if(eob_token[zzi]<OC_NDCT_EOB_TOKEN_MAX){ + /*This token caused an EOB run to be flushed. + Therefore it gets the bits associated with it.*/ + frag_bits+=_enc->huff_codes[huffi][eob_token[zzi]].nbits + +OC_DCT_TOKEN_EXTRA_BITS[eob_token[zzi]]; + eob_token[zzi]=OC_NDCT_EOB_TOKEN_MAX; + } + token=_enc->dct_tokens[pli][zzi][ti[zzi]]; + eb=_enc->extra_bits[pli][zzi][ti[zzi]]; + ti[zzi]++; + skip=oc_dct_token_skip(token,eb); + if(skip<0){ + eob_token[zzi]=token; + eob_run[zzi]=-skip; + } + else{ + /*A regular DCT value token; accumulate the bits for it.*/ + frag_bits+=_enc->huff_codes[huffi][token].nbits + +OC_DCT_TOKEN_EXTRA_BITS[token]; + zzi+=skip; + } + } + mb_mode=frags[fragi].mb_mode; + qii=frags[fragi].qii; + qi=_enc->state.qis[qii]; + sad=frag_sad[fragi]<<(pli+1&2); + satd=frag_satd[fragi]<<(pli+1&2); + sqrt_ssd=sqrt(frag_ssd[fragi]); + qtj=mb_mode!=OC_MODE_INTRA; + /*Accumulate statistics. + The rate (frag_bits) and RMSE (sqrt(frag_ssd)) are not scaled by + OC_BIT_SCALE and OC_RMSE_SCALE; this lets us change the scale factor + yet still use old data.*/ + bin=OC_MINI(satd>>OC_SATD_SHIFT,OC_COMP_BINS-1); + oc_mode_metrics_add( + OC_MODE_METRICS_SATD[modelines[qii][pli][qtj]][pli][qtj]+bin, + fragw,satd,_enc->log_plq[qi][pli][qtj],frag_bits,sqrt_ssd); + bin=OC_MINI(sad>>OC_SAD_SHIFT,OC_COMP_BINS-1); + oc_mode_metrics_add( + OC_MODE_METRICS_SAD[modelines[qii][pli][qtj]][pli][qtj]+bin, + fragw,sad,_enc->log_plq[qi][pli][qtj],frag_bits,sqrt_ssd); + } + } + /*Update global SA(T)D/logq/rate/RMSE estimation matrix.*/ + oc_mode_metrics_update(OC_MODE_METRICS_SATD,4,1, + OC_MODE_RD_SATD,OC_SATD_SHIFT,OC_MODE_RD_WEIGHT_SATD); + oc_mode_metrics_update(OC_MODE_METRICS_SAD,4,1, + OC_MODE_RD_SAD,OC_SAD_SHIFT,OC_MODE_RD_WEIGHT_SAD); +} +# endif + +#endif diff --git a/thirdparty/libtheora/collect.h b/thirdparty/libtheora/collect.h new file mode 100644 index 0000000000..9458b84e3f --- /dev/null +++ b/thirdparty/libtheora/collect.h @@ -0,0 +1,109 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: mode selection code + last mod: $Id$ + + ********************************************************************/ +#if !defined(_collect_H) +# define _collect_H (1) +# include "encint.h" +# if defined(OC_COLLECT_METRICS) +# include <stdio.h> + + + +typedef struct oc_mode_metrics oc_mode_metrics; + + + +/**Sets the file name to load/store mode metrics from/to. + * The file name string is stored by reference, and so must be valid for the + * lifetime of the encoder. + * Mode metric collection uses global tables; do not attempt to perform + * multiple collections at once. + * \param[in] _buf <tt>char[]</tt> The file name. + * \retval TH_EIMPL Not supported by this implementation.*/ +#define TH_ENCCTL_SET_METRICS_FILE (0x8000) + + + +/*Accumulates various weighted sums of the measurements. + w -> weight + s -> SATD + q -> log quantizer + r -> rate (in bits) + d -> RMSE + All of the single letters correspond to direct, weighted sums, e.g., + w=sum(w_i), s=sum(s_i*w_i), etc. + The others correspond to central moments (or co-moments) of the given order, + e.g., sq=sum((s_i-s/w)*(q_i-q/w)*w_i). + Because we need some moments up to fourth order, we use central moments to + minimize the dynamic range and prevent rounding error from dominating the + calculations.*/ +struct oc_mode_metrics{ + double w; + double s; + double q; + double r; + double d; + double s2; + double sq; + double q2; + double sr; + double qr; + double r2; + double sd; + double qd; + double d2; + double s2q; + double sq2; + double sqr; + double sqd; + double s2q2; +}; + + +# define OC_ZWEIGHT (0.25) + +/*TODO: It may be helpful (for block-level quantizers especially) to separate + out the contributions from AC and DC into separate tables.*/ + +extern ogg_int16_t OC_MODE_LOGQ[OC_LOGQ_BINS][3][2]; +extern oc_mode_rd OC_MODE_RD_SATD[OC_LOGQ_BINS][3][2][OC_COMP_BINS]; +extern oc_mode_rd OC_MODE_RD_SAD[OC_LOGQ_BINS][3][2][OC_COMP_BINS]; + +extern int OC_HAS_MODE_METRICS; +extern oc_mode_metrics OC_MODE_METRICS_SATD[OC_LOGQ_BINS-1][3][2][OC_COMP_BINS]; +extern oc_mode_metrics OC_MODE_METRICS_SAD[OC_LOGQ_BINS-1][3][2][OC_COMP_BINS]; +extern const char *OC_MODE_METRICS_FILENAME; + +void oc_mode_metrics_dump(); +void oc_mode_metrics_print(FILE *_fout); + +void oc_mode_metrics_add(oc_mode_metrics *_metrics, + double _w,int _s,int _q,int _r,double _d); +void oc_mode_metrics_merge(oc_mode_metrics *_dst, + const oc_mode_metrics *_src,int _n); +double oc_mode_metrics_solve(double *_r,double *_d, + const oc_mode_metrics *_metrics,const int *_s0,const int *_s1, + const int *_q0,const int *_q1, + const double *_ra,const double *_rb,const double *_rc, + const double *_da,const double *_db,const double *_dc,int _n); +void oc_mode_metrics_update(oc_mode_metrics (*_metrics)[3][2][OC_COMP_BINS], + int _niters_min,int _reweight,oc_mode_rd (*_table)[3][2][OC_COMP_BINS], + int shift,double (*_weight)[3][2][OC_COMP_BINS]); +void oc_enc_mode_metrics_load(oc_enc_ctx *_enc); +void oc_enc_mode_metrics_collect(oc_enc_ctx *_enc); + +# endif +#endif diff --git a/thirdparty/libtheora/dct.h b/thirdparty/libtheora/dct.h index 24ba6f111a..8052ea6bc1 100644 --- a/thirdparty/libtheora/dct.h +++ b/thirdparty/libtheora/dct.h @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: dct.h 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ diff --git a/thirdparty/libtheora/decinfo.c b/thirdparty/libtheora/decinfo.c index 845eb1361c..a91e740b15 100644 --- a/thirdparty/libtheora/decinfo.c +++ b/thirdparty/libtheora/decinfo.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: decinfo.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ @@ -20,6 +20,11 @@ #include <limits.h> #include "decint.h" +/*Only used for fuzzing.*/ +#if defined(HAVE_MEMORY_CONSTRAINT) +static const int MAX_FUZZING_WIDTH = 16384; +static const int MAX_FUZZING_HEIGHT = 16384; +#endif /*Unpacks a series of octets from a given byte array into the pack buffer. @@ -55,8 +60,8 @@ static int oc_info_unpack(oc_pack_buf *_opb,th_info *_info){ /*verify we can parse this bitstream version. We accept earlier minors and all subminors, by spec*/ if(_info->version_major>TH_VERSION_MAJOR|| - _info->version_major==TH_VERSION_MAJOR&& - _info->version_minor>TH_VERSION_MINOR){ + (_info->version_major==TH_VERSION_MAJOR&& + _info->version_minor>TH_VERSION_MINOR)){ return TH_EVERSION; } /*Read the encoded frame description.*/ @@ -82,6 +87,11 @@ static int oc_info_unpack(oc_pack_buf *_opb,th_info *_info){ _info->fps_numerator==0||_info->fps_denominator==0){ return TH_EBADHEADER; } +#if defined(HAVE_MEMORY_CONSTRAINT) + if(_info->frame_width>=MAX_FUZZING_WIDTH&&_info->frame_height>=MAX_FUZZING_HEIGHT){ + return TH_EBADHEADER; + } +#endif /*Note: The sense of pic_y is inverted in what we pass back to the application compared to how it is stored in the bitstream. This is because the bitstream uses a right-handed coordinate system, while @@ -128,6 +138,10 @@ static int oc_comment_unpack(oc_pack_buf *_opb,th_comment *_tc){ _tc->comments*sizeof(_tc->comment_lengths[0])); _tc->user_comments=(char **)_ogg_malloc( _tc->comments*sizeof(_tc->user_comments[0])); + if(_tc->comment_lengths==NULL||_tc->user_comments==NULL){ + _tc->comments=0; + return TH_EFAULT; + } for(i=0;i<_tc->comments;i++){ len=oc_unpack_length(_opb); if(len<0||len>oc_pack_bytes_left(_opb)){ @@ -168,9 +182,23 @@ static int oc_dec_headerin(oc_pack_buf *_opb,th_info *_info, int ret; val=oc_pack_read(_opb,8); packtype=(int)val; - /*If we're at a data packet and we have received all three headers, we're - done.*/ - if(!(packtype&0x80)&&_info->frame_width>0&&_tc->vendor!=NULL&&*_setup!=NULL){ + /*If we're at a data packet...*/ + if(!(packtype&0x80)){ + /*Check to make sure we received all three headers... + If we haven't seen any valid headers, assume this is not actually + Theora.*/ + if(_info->frame_width<=0)return TH_ENOTFORMAT; + /*Follow our documentation, which says we'll return TH_EFAULT if this + are NULL (_info was checked by our caller).*/ + if(_tc==NULL)return TH_EFAULT; + /*And if any other headers were missing, declare this packet "out of + sequence" instead.*/ + if(_tc->vendor==NULL)return TH_EBADHEADER; + /*Don't check this until it's needed, since we allow passing NULL for the + arguments that we're not expecting the next header to fill in yet.*/ + if(_setup==NULL)return TH_EFAULT; + if(*_setup==NULL)return TH_EBADHEADER; + /*If we got everything, we're done.*/ return 0; } /*Check the codec string.*/ diff --git a/thirdparty/libtheora/decint.h b/thirdparty/libtheora/decint.h index 261b67631a..3cea6b1439 100644 --- a/thirdparty/libtheora/decint.h +++ b/thirdparty/libtheora/decint.h @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: decint.h 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ @@ -19,15 +19,39 @@ #if !defined(_decint_H) # define _decint_H (1) # include "theora/theoradec.h" -# include "internal.h" +# include "state.h" # include "bitpack.h" - -typedef struct th_setup_info oc_setup_info; -typedef struct th_dec_ctx oc_dec_ctx; - # include "huffdec.h" # include "dequant.h" +typedef struct th_setup_info oc_setup_info; +typedef struct oc_dec_opt_vtable oc_dec_opt_vtable; +typedef struct oc_dec_pipeline_state oc_dec_pipeline_state; +typedef struct th_dec_ctx oc_dec_ctx; + + + +/*Decoder-specific accelerated functions.*/ +# if defined(OC_C64X_ASM) +# include "c64x/c64xdec.h" +# endif + +# if !defined(oc_dec_accel_init) +# define oc_dec_accel_init oc_dec_accel_init_c +# endif +# if defined(OC_DEC_USE_VTABLE) +# if !defined(oc_dec_dc_unpredict_mcu_plane) +# define oc_dec_dc_unpredict_mcu_plane(_dec,_pipe,_pli) \ + ((*(_dec)->opt_vtable.dc_unpredict_mcu_plane)(_dec,_pipe,_pli)) +# endif +# else +# if !defined(oc_dec_dc_unpredict_mcu_plane) +# define oc_dec_dc_unpredict_mcu_plane oc_dec_dc_unpredict_mcu_plane_c +# endif +# endif + + + /*Constants for the packet-in state machine specific to the decoder.*/ /*Next packet to read: Data packet.*/ @@ -37,71 +61,125 @@ typedef struct th_dec_ctx oc_dec_ctx; struct th_setup_info{ /*The Huffman codes.*/ - oc_huff_node *huff_tables[TH_NHUFFMAN_TABLES]; + ogg_int16_t *huff_tables[TH_NHUFFMAN_TABLES]; /*The quantization parameters.*/ th_quant_info qinfo; }; +/*Decoder specific functions with accelerated variants.*/ +struct oc_dec_opt_vtable{ + void (*dc_unpredict_mcu_plane)(oc_dec_ctx *_dec, + oc_dec_pipeline_state *_pipe,int _pli); +}; + + + +struct oc_dec_pipeline_state{ + /*Decoded DCT coefficients. + These are placed here instead of on the stack so that they can persist + between blocks, which makes clearing them back to zero much faster when + only a few non-zero coefficients were decoded. + It requires at least 65 elements because the zig-zag index array uses the + 65th element as a dumping ground for out-of-range indices to protect us + from buffer overflow. + We make it fully twice as large so that the second half can serve as the + reconstruction buffer, which saves passing another parameter to all the + acceleration functios. + It also solves problems with 16-byte alignment for NEON on ARM. + gcc (as of 4.2.1) only seems to be able to give stack variables 8-byte + alignment, and silently produces incorrect results if you ask for 16. + Finally, keeping it off the stack means there's less likely to be a data + hazard beween the NEON co-processor and the regular ARM core, which avoids + unnecessary stalls.*/ + OC_ALIGN16(ogg_int16_t dct_coeffs[128]); + OC_ALIGN16(signed char bounding_values[256]); + ptrdiff_t ti[3][64]; + ptrdiff_t ebi[3][64]; + ptrdiff_t eob_runs[3][64]; + const ptrdiff_t *coded_fragis[3]; + const ptrdiff_t *uncoded_fragis[3]; + ptrdiff_t ncoded_fragis[3]; + ptrdiff_t nuncoded_fragis[3]; + const ogg_uint16_t *dequant[3][3][2]; + int fragy0[3]; + int fragy_end[3]; + int pred_last[3][4]; + int mcu_nvfrags; + int loop_filter; + int pp_level; +}; + + struct th_dec_ctx{ /*Shared encoder/decoder state.*/ - oc_theora_state state; + oc_theora_state state; /*Whether or not packets are ready to be emitted. This takes on negative values while there are remaining header packets to be emitted, reaches 0 when the codec is ready for input, and goes to 1 when a frame has been processed and a data packet is ready.*/ - int packet_state; + int packet_state; /*Buffer in which to assemble packets.*/ - oc_pack_buf opb; + oc_pack_buf opb; /*Huffman decode trees.*/ - oc_huff_node *huff_tables[TH_NHUFFMAN_TABLES]; + ogg_int16_t *huff_tables[TH_NHUFFMAN_TABLES]; /*The index of the first token in each plane for each coefficient.*/ - ptrdiff_t ti0[3][64]; + ptrdiff_t ti0[3][64]; /*The number of outstanding EOB runs at the start of each coefficient in each plane.*/ - ptrdiff_t eob_runs[3][64]; + ptrdiff_t eob_runs[3][64]; /*The DCT token lists.*/ - unsigned char *dct_tokens; + unsigned char *dct_tokens; /*The extra bits associated with DCT tokens.*/ - unsigned char *extra_bits; + unsigned char *extra_bits; /*The number of dct tokens unpacked so far.*/ - int dct_tokens_count; + int dct_tokens_count; /*The out-of-loop post-processing level.*/ - int pp_level; + int pp_level; /*The DC scale used for out-of-loop deblocking.*/ - int pp_dc_scale[64]; + int pp_dc_scale[64]; /*The sharpen modifier used for out-of-loop deringing.*/ - int pp_sharp_mod[64]; + int pp_sharp_mod[64]; /*The DC quantization index of each block.*/ - unsigned char *dc_qis; + unsigned char *dc_qis; /*The variance of each block.*/ - int *variances; + int *variances; /*The storage for the post-processed frame buffer.*/ - unsigned char *pp_frame_data; + unsigned char *pp_frame_data; /*Whether or not the post-processsed frame buffer has space for chroma.*/ - int pp_frame_state; + int pp_frame_state; /*The buffer used for the post-processed frame. Note that this is _not_ guaranteed to have the same strides and offsets as the reference frame buffers.*/ - th_ycbcr_buffer pp_frame_buf; + th_ycbcr_buffer pp_frame_buf; /*The striped decode callback function.*/ - th_stripe_callback stripe_cb; + th_stripe_callback stripe_cb; + oc_dec_pipeline_state pipe; +# if defined(OC_DEC_USE_VTABLE) + /*Table for decoder acceleration functions.*/ + oc_dec_opt_vtable opt_vtable; +# endif # if defined(HAVE_CAIRO) /*Output metrics for debugging.*/ - int telemetry; - int telemetry_mbmode; - int telemetry_mv; - int telemetry_qi; - int telemetry_bits; - int telemetry_frame_bytes; - int telemetry_coding_bytes; - int telemetry_mode_bytes; - int telemetry_mv_bytes; - int telemetry_qi_bytes; - int telemetry_dc_bytes; - unsigned char *telemetry_frame_data; + int telemetry_mbmode; + int telemetry_mv; + int telemetry_qi; + int telemetry_bits; + int telemetry_frame_bytes; + int telemetry_coding_bytes; + int telemetry_mode_bytes; + int telemetry_mv_bytes; + int telemetry_qi_bytes; + int telemetry_dc_bytes; + unsigned char *telemetry_frame_data; # endif }; +/*Default pure-C implementations of decoder-specific accelerated functions.*/ +void oc_dec_accel_init_c(oc_dec_ctx *_dec); + +void oc_dec_dc_unpredict_mcu_plane_c(oc_dec_ctx *_dec, + oc_dec_pipeline_state *_pipe,int _pli); + #endif diff --git a/thirdparty/libtheora/decode.c b/thirdparty/libtheora/decode.c index bde967b794..fad26e0927 100644 --- a/thirdparty/libtheora/decode.c +++ b/thirdparty/libtheora/decode.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: decode.c 16581 2009-09-25 22:56:16Z gmaxwell $ + last mod: $Id$ ********************************************************************/ @@ -118,7 +118,7 @@ static const unsigned char OC_INTERNAL_DCT_TOKEN_EXTRA_BITS[15]={ /*Whether or not an internal token needs any additional extra bits.*/ #define OC_DCT_TOKEN_NEEDS_MORE(token) \ - (token<(sizeof(OC_INTERNAL_DCT_TOKEN_EXTRA_BITS)/ \ + (token<(int)(sizeof(OC_INTERNAL_DCT_TOKEN_EXTRA_BITS)/ \ sizeof(*OC_INTERNAL_DCT_TOKEN_EXTRA_BITS))) /*This token (OC_DCT_REPEAT_RUN3_TOKEN) requires more than 8 extra bits.*/ @@ -129,7 +129,7 @@ static const unsigned char OC_INTERNAL_DCT_TOKEN_EXTRA_BITS[15]={ is not yet available everywhere; this should be equivalent.*/ #define OC_DCT_EOB_FINISH (~(size_t)0>>1) -/*The location of the (6) run legth bits in the code word. +/*The location of the (6) run length bits in the code word. These are placed at index 0 and given 8 bits (even though 6 would suffice) because it may be faster to extract the lower byte on some platforms.*/ #define OC_DCT_CW_RLEN_SHIFT (0) @@ -297,8 +297,6 @@ static const ogg_int32_t OC_DCT_CODE_WORD[92]={ static int oc_sb_run_unpack(oc_pack_buf *_opb){ - long bits; - int ret; /*Coding scheme: Codeword Run Length 0 1 @@ -308,32 +306,26 @@ static int oc_sb_run_unpack(oc_pack_buf *_opb){ 11110xxx 10-17 111110xxxx 18-33 111111xxxxxxxxxxxx 34-4129*/ - bits=oc_pack_read1(_opb); - if(bits==0)return 1; - bits=oc_pack_read(_opb,2); - if((bits&2)==0)return 2+(int)bits; - else if((bits&1)==0){ - bits=oc_pack_read1(_opb); - return 4+(int)bits; - } - bits=oc_pack_read(_opb,3); - if((bits&4)==0)return 6+(int)bits; - else if((bits&2)==0){ - ret=10+((bits&1)<<2); - bits=oc_pack_read(_opb,2); - return ret+(int)bits; - } - else if((bits&1)==0){ - bits=oc_pack_read(_opb,4); - return 18+(int)bits; + static const ogg_int16_t OC_SB_RUN_TREE[22]={ + 4, + -(1<<8|1),-(1<<8|1),-(1<<8|1),-(1<<8|1), + -(1<<8|1),-(1<<8|1),-(1<<8|1),-(1<<8|1), + -(3<<8|2),-(3<<8|2),-(3<<8|3),-(3<<8|3), + -(4<<8|4),-(4<<8|5),-(4<<8|2<<4|6-6),17, + 2, + -(2<<8|2<<4|10-6),-(2<<8|2<<4|14-6),-(2<<8|4<<4|18-6),-(2<<8|12<<4|34-6) + }; + int ret; + ret=oc_huff_token_decode(_opb,OC_SB_RUN_TREE); + if(ret>=0x10){ + int offs; + offs=ret&0x1F; + ret=6+offs+(int)oc_pack_read(_opb,ret-offs>>4); } - bits=oc_pack_read(_opb,12); - return 34+(int)bits; + return ret; } static int oc_block_run_unpack(oc_pack_buf *_opb){ - long bits; - long bits2; /*Coding scheme: Codeword Run Length 0x 1-2 @@ -342,26 +334,37 @@ static int oc_block_run_unpack(oc_pack_buf *_opb){ 1110xx 7-10 11110xx 11-14 11111xxxx 15-30*/ - bits=oc_pack_read(_opb,2); - if((bits&2)==0)return 1+(int)bits; - else if((bits&1)==0){ - bits=oc_pack_read1(_opb); - return 3+(int)bits; - } - bits=oc_pack_read(_opb,2); - if((bits&2)==0)return 5+(int)bits; - else if((bits&1)==0){ - bits=oc_pack_read(_opb,2); - return 7+(int)bits; - } - bits=oc_pack_read(_opb,3); - if((bits&4)==0)return 11+bits; - bits2=oc_pack_read(_opb,2); - return 15+((bits&3)<<2)+bits2; + static const ogg_int16_t OC_BLOCK_RUN_TREE[61]={ + 5, + -(2<<8|1),-(2<<8|1),-(2<<8|1),-(2<<8|1), + -(2<<8|1),-(2<<8|1),-(2<<8|1),-(2<<8|1), + -(2<<8|2),-(2<<8|2),-(2<<8|2),-(2<<8|2), + -(2<<8|2),-(2<<8|2),-(2<<8|2),-(2<<8|2), + -(3<<8|3),-(3<<8|3),-(3<<8|3),-(3<<8|3), + -(3<<8|4),-(3<<8|4),-(3<<8|4),-(3<<8|4), + -(4<<8|5),-(4<<8|5),-(4<<8|6),-(4<<8|6), + 33, 36, 39, 44, + 1,-(1<<8|7),-(1<<8|8), + 1,-(1<<8|9),-(1<<8|10), + 2,-(2<<8|11),-(2<<8|12),-(2<<8|13),-(2<<8|14), + 4, + -(4<<8|15),-(4<<8|16),-(4<<8|17),-(4<<8|18), + -(4<<8|19),-(4<<8|20),-(4<<8|21),-(4<<8|22), + -(4<<8|23),-(4<<8|24),-(4<<8|25),-(4<<8|26), + -(4<<8|27),-(4<<8|28),-(4<<8|29),-(4<<8|30) + }; + return oc_huff_token_decode(_opb,OC_BLOCK_RUN_TREE); } +void oc_dec_accel_init_c(oc_dec_ctx *_dec){ +# if defined(OC_DEC_USE_VTABLE) + _dec->opt_vtable.dc_unpredict_mcu_plane= + oc_dec_dc_unpredict_mcu_plane_c; +# endif +} + static int oc_dec_init(oc_dec_ctx *_dec,const th_info *_info, const th_setup_info *_setup){ int qti; @@ -371,7 +374,7 @@ static int oc_dec_init(oc_dec_ctx *_dec,const th_info *_info, ret=oc_state_init(&_dec->state,_info,3); if(ret<0)return ret; ret=oc_huff_trees_copy(_dec->huff_tables, - (const oc_huff_node *const *)_setup->huff_tables); + (const ogg_int16_t *const *)_setup->huff_tables); if(ret<0){ oc_state_clear(&_dec->state); return ret; @@ -406,6 +409,7 @@ static int oc_dec_init(oc_dec_ctx *_dec,const th_info *_info, } memcpy(_dec->state.loop_filter_limits,_setup->qinfo.loop_filter_limits, sizeof(_dec->state.loop_filter_limits)); + oc_dec_accel_init(_dec); _dec->pp_level=OC_PP_LEVEL_DISABLED; _dec->dc_qis=NULL; _dec->variances=NULL; @@ -413,7 +417,6 @@ static int oc_dec_init(oc_dec_ctx *_dec,const th_info *_info, _dec->stripe_cb.ctx=NULL; _dec->stripe_cb.stripe_decoded=NULL; #if defined(HAVE_CAIRO) - _dec->telemetry=0; _dec->telemetry_bits=0; _dec->telemetry_qi=0; _dec->telemetry_mbmode=0; @@ -504,6 +507,7 @@ static void oc_dec_mark_all_intra(oc_dec_ctx *_dec){ fragi=sb_maps[sbi][quadi][bi]; if(fragi>=0){ frags[fragi].coded=1; + frags[fragi].refi=OC_FRAME_SELF; frags[fragi].mb_mode=OC_MODE_INTRA; coded_fragis[ncoded_fragis++]=fragi; } @@ -595,6 +599,7 @@ static void oc_dec_coded_sb_flags_unpack(oc_dec_ctx *_dec){ static void oc_dec_coded_flags_unpack(oc_dec_ctx *_dec){ const oc_sb_map *sb_maps; const oc_sb_flags *sb_flags; + signed char *mb_modes; oc_fragment *frags; unsigned nsbs; unsigned sbi; @@ -617,6 +622,7 @@ static void oc_dec_coded_flags_unpack(oc_dec_ctx *_dec){ else flag=0; sb_maps=(const oc_sb_map *)_dec->state.sb_maps; sb_flags=_dec->state.sb_flags; + mb_modes=_dec->state.mb_modes; frags=_dec->state.frags; sbi=nsbs=run_count=0; coded_fragis=_dec->state.coded_fragis; @@ -627,7 +633,9 @@ static void oc_dec_coded_flags_unpack(oc_dec_ctx *_dec){ for(;sbi<nsbs;sbi++){ int quadi; for(quadi=0;quadi<4;quadi++)if(sb_flags[sbi].quad_valid&1<<quadi){ + int quad_coded; int bi; + quad_coded=0; for(bi=0;bi<4;bi++){ ptrdiff_t fragi; fragi=sb_maps[sbi][quadi][bi]; @@ -645,9 +653,13 @@ static void oc_dec_coded_flags_unpack(oc_dec_ctx *_dec){ } if(coded)coded_fragis[ncoded_fragis++]=fragi; else *(uncoded_fragis-++nuncoded_fragis)=fragi; + quad_coded|=coded; frags[fragi].coded=coded; + frags[fragi].refi=OC_FRAME_NONE; } } + /*Remember if there's a coded luma block in this macro block.*/ + if(!pli)mb_modes[sbi<<2|quadi]=quad_coded; } } _dec->state.ncoded_fragis[pli]=ncoded_fragis-prev_ncoded_fragis; @@ -659,33 +671,39 @@ static void oc_dec_coded_flags_unpack(oc_dec_ctx *_dec){ } +/*Coding scheme: + Codeword Mode Index + 0 0 + 10 1 + 110 2 + 1110 3 + 11110 4 + 111110 5 + 1111110 6 + 1111111 7*/ +static const ogg_int16_t OC_VLC_MODE_TREE[26]={ + 4, + -(1<<8|0),-(1<<8|0),-(1<<8|0),-(1<<8|0), + -(1<<8|0),-(1<<8|0),-(1<<8|0),-(1<<8|0), + -(2<<8|1),-(2<<8|1),-(2<<8|1),-(2<<8|1), + -(3<<8|2),-(3<<8|2),-(4<<8|3),17, + 3, + -(1<<8|4),-(1<<8|4),-(1<<8|4),-(1<<8|4), + -(2<<8|5),-(2<<8|5),-(3<<8|6),-(3<<8|7) +}; -typedef int (*oc_mode_unpack_func)(oc_pack_buf *_opb); - -static int oc_vlc_mode_unpack(oc_pack_buf *_opb){ - long val; - int i; - for(i=0;i<7;i++){ - val=oc_pack_read1(_opb); - if(!val)break; - } - return i; -} - -static int oc_clc_mode_unpack(oc_pack_buf *_opb){ - long val; - val=oc_pack_read(_opb,3); - return (int)val; -} +static const ogg_int16_t OC_CLC_MODE_TREE[9]={ + 3, + -(3<<8|0),-(3<<8|1),-(3<<8|2),-(3<<8|3), + -(3<<8|4),-(3<<8|5),-(3<<8|6),-(3<<8|7) +}; /*Unpacks the list of macro block modes for INTER frames.*/ static void oc_dec_mb_modes_unpack(oc_dec_ctx *_dec){ - const oc_mb_map *mb_maps; signed char *mb_modes; - const oc_fragment *frags; const unsigned char *alphabet; unsigned char scheme0_alphabet[8]; - oc_mode_unpack_func mode_unpack; + const ogg_int16_t *mode_tree; size_t nmbs; size_t mbi; long val; @@ -707,65 +725,80 @@ static void oc_dec_mb_modes_unpack(oc_dec_ctx *_dec){ alphabet=scheme0_alphabet; } else alphabet=OC_MODE_ALPHABETS[mode_scheme-1]; - if(mode_scheme==7)mode_unpack=oc_clc_mode_unpack; - else mode_unpack=oc_vlc_mode_unpack; + mode_tree=mode_scheme==7?OC_CLC_MODE_TREE:OC_VLC_MODE_TREE; mb_modes=_dec->state.mb_modes; - mb_maps=(const oc_mb_map *)_dec->state.mb_maps; nmbs=_dec->state.nmbs; - frags=_dec->state.frags; for(mbi=0;mbi<nmbs;mbi++){ - if(mb_modes[mbi]!=OC_MODE_INVALID){ - int bi; - /*Check for a coded luma block in this macro block.*/ - for(bi=0;bi<4&&!frags[mb_maps[mbi][0][bi]].coded;bi++); - /*We found one, decode a mode.*/ - if(bi<4)mb_modes[mbi]=alphabet[(*mode_unpack)(&_dec->opb)]; - /*There were none: INTER_NOMV is forced.*/ - else mb_modes[mbi]=OC_MODE_INTER_NOMV; + if(mb_modes[mbi]>0){ + /*We have a coded luma block; decode a mode.*/ + mb_modes[mbi]=alphabet[oc_huff_token_decode(&_dec->opb,mode_tree)]; } + /*For other valid macro blocks, INTER_NOMV is forced, but we rely on the + fact that OC_MODE_INTER_NOMV is already 0.*/ } } -typedef int (*oc_mv_comp_unpack_func)(oc_pack_buf *_opb); +static const ogg_int16_t OC_VLC_MV_COMP_TREE[101]={ + 5, + -(3<<8|32+0),-(3<<8|32+0),-(3<<8|32+0),-(3<<8|32+0), + -(3<<8|32+1),-(3<<8|32+1),-(3<<8|32+1),-(3<<8|32+1), + -(3<<8|32-1),-(3<<8|32-1),-(3<<8|32-1),-(3<<8|32-1), + -(4<<8|32+2),-(4<<8|32+2),-(4<<8|32-2),-(4<<8|32-2), + -(4<<8|32+3),-(4<<8|32+3),-(4<<8|32-3),-(4<<8|32-3), + 33, 36, 39, 42, + 45, 50, 55, 60, + 65, 74, 83, 92, + 1,-(1<<8|32+4),-(1<<8|32-4), + 1,-(1<<8|32+5),-(1<<8|32-5), + 1,-(1<<8|32+6),-(1<<8|32-6), + 1,-(1<<8|32+7),-(1<<8|32-7), + 2,-(2<<8|32+8),-(2<<8|32-8),-(2<<8|32+9),-(2<<8|32-9), + 2,-(2<<8|32+10),-(2<<8|32-10),-(2<<8|32+11),-(2<<8|32-11), + 2,-(2<<8|32+12),-(2<<8|32-12),-(2<<8|32+13),-(2<<8|32-13), + 2,-(2<<8|32+14),-(2<<8|32-14),-(2<<8|32+15),-(2<<8|32-15), + 3, + -(3<<8|32+16),-(3<<8|32-16),-(3<<8|32+17),-(3<<8|32-17), + -(3<<8|32+18),-(3<<8|32-18),-(3<<8|32+19),-(3<<8|32-19), + 3, + -(3<<8|32+20),-(3<<8|32-20),-(3<<8|32+21),-(3<<8|32-21), + -(3<<8|32+22),-(3<<8|32-22),-(3<<8|32+23),-(3<<8|32-23), + 3, + -(3<<8|32+24),-(3<<8|32-24),-(3<<8|32+25),-(3<<8|32-25), + -(3<<8|32+26),-(3<<8|32-26),-(3<<8|32+27),-(3<<8|32-27), + 3, + -(3<<8|32+28),-(3<<8|32-28),-(3<<8|32+29),-(3<<8|32-29), + -(3<<8|32+30),-(3<<8|32-30),-(3<<8|32+31),-(3<<8|32-31) +}; + +static const ogg_int16_t OC_CLC_MV_COMP_TREE[65]={ + 6, + -(6<<8|32 +0),-(6<<8|32 -0),-(6<<8|32 +1),-(6<<8|32 -1), + -(6<<8|32 +2),-(6<<8|32 -2),-(6<<8|32 +3),-(6<<8|32 -3), + -(6<<8|32 +4),-(6<<8|32 -4),-(6<<8|32 +5),-(6<<8|32 -5), + -(6<<8|32 +6),-(6<<8|32 -6),-(6<<8|32 +7),-(6<<8|32 -7), + -(6<<8|32 +8),-(6<<8|32 -8),-(6<<8|32 +9),-(6<<8|32 -9), + -(6<<8|32+10),-(6<<8|32-10),-(6<<8|32+11),-(6<<8|32-11), + -(6<<8|32+12),-(6<<8|32-12),-(6<<8|32+13),-(6<<8|32-13), + -(6<<8|32+14),-(6<<8|32-14),-(6<<8|32+15),-(6<<8|32-15), + -(6<<8|32+16),-(6<<8|32-16),-(6<<8|32+17),-(6<<8|32-17), + -(6<<8|32+18),-(6<<8|32-18),-(6<<8|32+19),-(6<<8|32-19), + -(6<<8|32+20),-(6<<8|32-20),-(6<<8|32+21),-(6<<8|32-21), + -(6<<8|32+22),-(6<<8|32-22),-(6<<8|32+23),-(6<<8|32-23), + -(6<<8|32+24),-(6<<8|32-24),-(6<<8|32+25),-(6<<8|32-25), + -(6<<8|32+26),-(6<<8|32-26),-(6<<8|32+27),-(6<<8|32-27), + -(6<<8|32+28),-(6<<8|32-28),-(6<<8|32+29),-(6<<8|32-29), + -(6<<8|32+30),-(6<<8|32-30),-(6<<8|32+31),-(6<<8|32-31) +}; -static int oc_vlc_mv_comp_unpack(oc_pack_buf *_opb){ - long bits; - int mask; - int mv; - bits=oc_pack_read(_opb,3); - switch(bits){ - case 0:return 0; - case 1:return 1; - case 2:return -1; - case 3: - case 4:{ - mv=(int)(bits-1); - bits=oc_pack_read1(_opb); - }break; - /*case 5: - case 6: - case 7:*/ - default:{ - mv=1<<bits-3; - bits=oc_pack_read(_opb,bits-2); - mv+=(int)(bits>>1); - bits&=1; - }break; - } - mask=-(int)bits; - return mv+mask^mask; -} -static int oc_clc_mv_comp_unpack(oc_pack_buf *_opb){ - long bits; - int mask; - int mv; - bits=oc_pack_read(_opb,6); - mv=(int)bits>>1; - mask=-((int)bits&1); - return mv+mask^mask; +static oc_mv oc_mv_unpack(oc_pack_buf *_opb,const ogg_int16_t *_tree){ + int dx; + int dy; + dx=oc_huff_token_decode(_opb,_tree)-32; + dy=oc_huff_token_decode(_opb,_tree)-32; + return OC_MV(dx,dy); } /*Unpacks the list of motion vectors for INTER frames, and propagtes the macro @@ -774,105 +807,93 @@ static void oc_dec_mv_unpack_and_frag_modes_fill(oc_dec_ctx *_dec){ const oc_mb_map *mb_maps; const signed char *mb_modes; oc_set_chroma_mvs_func set_chroma_mvs; - oc_mv_comp_unpack_func mv_comp_unpack; + const ogg_int16_t *mv_comp_tree; oc_fragment *frags; oc_mv *frag_mvs; const unsigned char *map_idxs; int map_nidxs; - oc_mv last_mv[2]; + oc_mv last_mv; + oc_mv prior_mv; oc_mv cbmvs[4]; size_t nmbs; size_t mbi; long val; set_chroma_mvs=OC_SET_CHROMA_MVS_TABLE[_dec->state.info.pixel_fmt]; val=oc_pack_read1(&_dec->opb); - mv_comp_unpack=val?oc_clc_mv_comp_unpack:oc_vlc_mv_comp_unpack; + mv_comp_tree=val?OC_CLC_MV_COMP_TREE:OC_VLC_MV_COMP_TREE; map_idxs=OC_MB_MAP_IDXS[_dec->state.info.pixel_fmt]; map_nidxs=OC_MB_MAP_NIDXS[_dec->state.info.pixel_fmt]; - memset(last_mv,0,sizeof(last_mv)); + prior_mv=last_mv=0; frags=_dec->state.frags; frag_mvs=_dec->state.frag_mvs; mb_maps=(const oc_mb_map *)_dec->state.mb_maps; mb_modes=_dec->state.mb_modes; nmbs=_dec->state.nmbs; for(mbi=0;mbi<nmbs;mbi++){ - int mb_mode; + int mb_mode; mb_mode=mb_modes[mbi]; if(mb_mode!=OC_MODE_INVALID){ - oc_mv mbmv; - ptrdiff_t fragi; - int coded[13]; - int codedi; - int ncoded; - int mapi; - int mapii; - /*Search for at least one coded fragment.*/ - ncoded=mapii=0; - do{ - mapi=map_idxs[mapii]; - fragi=mb_maps[mbi][mapi>>2][mapi&3]; - if(frags[fragi].coded)coded[ncoded++]=mapi; - } - while(++mapii<map_nidxs); - if(ncoded<=0)continue; - switch(mb_mode){ - case OC_MODE_INTER_MV_FOUR:{ - oc_mv lbmvs[4]; - int bi; - /*Mark the tail of the list, so we don't accidentally go past it.*/ - coded[ncoded]=-1; - for(bi=codedi=0;bi<4;bi++){ - if(coded[codedi]==bi){ - codedi++; - fragi=mb_maps[mbi][0][bi]; - frags[fragi].mb_mode=mb_mode; - lbmvs[bi][0]=(signed char)(*mv_comp_unpack)(&_dec->opb); - lbmvs[bi][1]=(signed char)(*mv_comp_unpack)(&_dec->opb); - memcpy(frag_mvs[fragi],lbmvs[bi],sizeof(lbmvs[bi])); - } - else lbmvs[bi][0]=lbmvs[bi][1]=0; - } - if(codedi>0){ - memcpy(last_mv[1],last_mv[0],sizeof(last_mv[1])); - memcpy(last_mv[0],lbmvs[coded[codedi-1]],sizeof(last_mv[0])); + oc_mv mbmv; + ptrdiff_t fragi; + int mapi; + int mapii; + int refi; + if(mb_mode==OC_MODE_INTER_MV_FOUR){ + oc_mv lbmvs[4]; + int bi; + prior_mv=last_mv; + for(bi=0;bi<4;bi++){ + fragi=mb_maps[mbi][0][bi]; + if(frags[fragi].coded){ + frags[fragi].refi=OC_FRAME_PREV; + frags[fragi].mb_mode=OC_MODE_INTER_MV_FOUR; + lbmvs[bi]=last_mv=oc_mv_unpack(&_dec->opb,mv_comp_tree); + frag_mvs[fragi]=lbmvs[bi]; } - if(codedi<ncoded){ - (*set_chroma_mvs)(cbmvs,(const oc_mv *)lbmvs); - for(;codedi<ncoded;codedi++){ - mapi=coded[codedi]; - bi=mapi&3; - fragi=mb_maps[mbi][mapi>>2][bi]; - frags[fragi].mb_mode=mb_mode; - memcpy(frag_mvs[fragi],cbmvs[bi],sizeof(cbmvs[bi])); - } + else lbmvs[bi]=0; + } + (*set_chroma_mvs)(cbmvs,lbmvs); + for(mapii=4;mapii<map_nidxs;mapii++){ + mapi=map_idxs[mapii]; + bi=mapi&3; + fragi=mb_maps[mbi][mapi>>2][bi]; + if(frags[fragi].coded){ + frags[fragi].refi=OC_FRAME_PREV; + frags[fragi].mb_mode=OC_MODE_INTER_MV_FOUR; + frag_mvs[fragi]=cbmvs[bi]; } - }break; - case OC_MODE_INTER_MV:{ - memcpy(last_mv[1],last_mv[0],sizeof(last_mv[1])); - mbmv[0]=last_mv[0][0]=(signed char)(*mv_comp_unpack)(&_dec->opb); - mbmv[1]=last_mv[0][1]=(signed char)(*mv_comp_unpack)(&_dec->opb); - }break; - case OC_MODE_INTER_MV_LAST:memcpy(mbmv,last_mv[0],sizeof(mbmv));break; - case OC_MODE_INTER_MV_LAST2:{ - memcpy(mbmv,last_mv[1],sizeof(mbmv)); - memcpy(last_mv[1],last_mv[0],sizeof(last_mv[1])); - memcpy(last_mv[0],mbmv,sizeof(last_mv[0])); - }break; - case OC_MODE_GOLDEN_MV:{ - mbmv[0]=(signed char)(*mv_comp_unpack)(&_dec->opb); - mbmv[1]=(signed char)(*mv_comp_unpack)(&_dec->opb); - }break; - default:memset(mbmv,0,sizeof(mbmv));break; + } } - /*4MV mode fills in the fragments itself. - For all other modes we can use this common code.*/ - if(mb_mode!=OC_MODE_INTER_MV_FOUR){ - for(codedi=0;codedi<ncoded;codedi++){ - mapi=coded[codedi]; + else{ + switch(mb_mode){ + case OC_MODE_INTER_MV:{ + prior_mv=last_mv; + last_mv=mbmv=oc_mv_unpack(&_dec->opb,mv_comp_tree); + }break; + case OC_MODE_INTER_MV_LAST:mbmv=last_mv;break; + case OC_MODE_INTER_MV_LAST2:{ + mbmv=prior_mv; + prior_mv=last_mv; + last_mv=mbmv; + }break; + case OC_MODE_GOLDEN_MV:{ + mbmv=oc_mv_unpack(&_dec->opb,mv_comp_tree); + }break; + default:mbmv=0;break; + } + /*Fill in the MVs for the fragments.*/ + refi=OC_FRAME_FOR_MODE(mb_mode); + mapii=0; + do{ + mapi=map_idxs[mapii]; fragi=mb_maps[mbi][mapi>>2][mapi&3]; - frags[fragi].mb_mode=mb_mode; - memcpy(frag_mvs[fragi],mbmv,sizeof(mbmv)); + if(frags[fragi].coded){ + frags[fragi].refi=refi; + frags[fragi].mb_mode=mb_mode; + frag_mvs[fragi]=mbmv; + } } + while(++mapii<map_nidxs); } } } @@ -1181,6 +1202,9 @@ static void oc_dec_residual_tokens_unpack(oc_dec_ctx *_dec){ static int oc_dec_postprocess_init(oc_dec_ctx *_dec){ + /*musl libc malloc()/realloc() calls might use floating point, so make sure + we've cleared the MMX state for them.*/ + oc_restore_fpu(&_dec->state); /*pp_level 0: disabled; free any memory used and return*/ if(_dec->pp_level<=OC_PP_LEVEL_DISABLED){ if(_dec->dc_qis!=NULL){ @@ -1301,34 +1325,16 @@ static int oc_dec_postprocess_init(oc_dec_ctx *_dec){ } - -typedef struct{ - int bounding_values[256]; - ptrdiff_t ti[3][64]; - ptrdiff_t eob_runs[3][64]; - const ptrdiff_t *coded_fragis[3]; - const ptrdiff_t *uncoded_fragis[3]; - ptrdiff_t ncoded_fragis[3]; - ptrdiff_t nuncoded_fragis[3]; - const ogg_uint16_t *dequant[3][3][2]; - int fragy0[3]; - int fragy_end[3]; - int pred_last[3][3]; - int mcu_nvfrags; - int loop_filter; - int pp_level; -}oc_dec_pipeline_state; - - - /*Initialize the main decoding pipeline.*/ static void oc_dec_pipeline_init(oc_dec_ctx *_dec, oc_dec_pipeline_state *_pipe){ const ptrdiff_t *coded_fragis; const ptrdiff_t *uncoded_fragis; + int flimit; int pli; int qii; int qti; + int zzi; /*If chroma is sub-sampled in the vertical direction, we have to decode two super block rows of Y' for each super block row of Cb and Cr.*/ _pipe->mcu_nvfrags=4<<!(_dec->state.info.pixel_fmt&2); @@ -1360,8 +1366,9 @@ static void oc_dec_pipeline_init(oc_dec_ctx *_dec, /*Set the previous DC predictor to 0 for all color planes and frame types.*/ memset(_pipe->pred_last,0,sizeof(_pipe->pred_last)); /*Initialize the bounding value array for the loop filter.*/ - _pipe->loop_filter=!oc_state_loop_filter_init(&_dec->state, - _pipe->bounding_values); + flimit=_dec->state.loop_filter_limits[_dec->state.qis[0]]; + _pipe->loop_filter=flimit!=0; + if(flimit!=0)oc_loop_filter_init(&_dec->state,_pipe->bounding_values,flimit); /*Initialize any buffers needed for post-processing. We also save the current post-processing level, to guard against the user changing it from a callback.*/ @@ -1374,13 +1381,15 @@ static void oc_dec_pipeline_init(oc_dec_ctx *_dec, _dec->state.ref_frame_bufs[_dec->state.ref_frame_idx[OC_FRAME_SELF]], sizeof(_dec->pp_frame_buf[0])*3); } + /*Clear down the DCT coefficient buffer for the first block.*/ + for(zzi=0;zzi<64;zzi++)_pipe->dct_coeffs[zzi]=0; } /*Undo the DC prediction in a single plane of an MCU (one or two super block rows). As a side effect, the number of coded and uncoded fragments in this plane of the MCU is also computed.*/ -static void oc_dec_dc_unpredict_mcu_plane(oc_dec_ctx *_dec, +void oc_dec_dc_unpredict_mcu_plane_c(oc_dec_ctx *_dec, oc_dec_pipeline_state *_pipe,int _pli){ const oc_fragment_plane *fplane; oc_fragment *frags; @@ -1408,9 +1417,9 @@ static void oc_dec_dc_unpredict_mcu_plane(oc_dec_ctx *_dec, predictor for the same reference frame.*/ for(fragx=0;fragx<nhfrags;fragx++,fragi++){ if(frags[fragi].coded){ - int ref; - ref=OC_FRAME_FOR_MODE(frags[fragi].mb_mode); - pred_last[ref]=frags[fragi].dc+=pred_last[ref]; + int refi; + refi=frags[fragi].refi; + pred_last[refi]=frags[fragi].dc+=pred_last[refi]; ncoded_fragis++; } } @@ -1423,27 +1432,24 @@ static void oc_dec_dc_unpredict_mcu_plane(oc_dec_ctx *_dec, u_frags=frags-nhfrags; l_ref=-1; ul_ref=-1; - u_ref=u_frags[fragi].coded?OC_FRAME_FOR_MODE(u_frags[fragi].mb_mode):-1; + u_ref=u_frags[fragi].refi; for(fragx=0;fragx<nhfrags;fragx++,fragi++){ int ur_ref; if(fragx+1>=nhfrags)ur_ref=-1; - else{ - ur_ref=u_frags[fragi+1].coded? - OC_FRAME_FOR_MODE(u_frags[fragi+1].mb_mode):-1; - } + else ur_ref=u_frags[fragi+1].refi; if(frags[fragi].coded){ int pred; - int ref; - ref=OC_FRAME_FOR_MODE(frags[fragi].mb_mode); + int refi; + refi=frags[fragi].refi; /*We break out a separate case based on which of our neighbors use the same reference frames. This is somewhat faster than trying to make a generic case which handles all of them, since it reduces lots of poorly predicted jumps to one switch statement, and also lets a number of the multiplications be optimized out by strength reduction.*/ - switch((l_ref==ref)|(ul_ref==ref)<<1| - (u_ref==ref)<<2|(ur_ref==ref)<<3){ - default:pred=pred_last[ref];break; + switch((l_ref==refi)|(ul_ref==refi)<<1| + (u_ref==refi)<<2|(ur_ref==refi)<<3){ + default:pred=pred_last[refi];break; case 1: case 3:pred=frags[fragi-1].dc;break; case 2:pred=u_frags[fragi-1].dc;break; @@ -1455,6 +1461,7 @@ static void oc_dec_dc_unpredict_mcu_plane(oc_dec_ctx *_dec, case 9: case 11: case 13:{ + /*The TI compiler mis-compiles this line.*/ pred=(75*frags[fragi-1].dc+53*u_frags[fragi+1].dc)/128; }break; case 10:pred=(u_frags[fragi-1].dc+u_frags[fragi+1].dc)/2;break; @@ -1476,9 +1483,9 @@ static void oc_dec_dc_unpredict_mcu_plane(oc_dec_ctx *_dec, else if(abs(pred-p1)>128)pred=p1; }break; } - pred_last[ref]=frags[fragi].dc+=pred; + pred_last[refi]=frags[fragi].dc+=pred; ncoded_fragis++; - l_ref=ref; + l_ref=refi; } else l_ref=-1; ul_ref=u_ref; @@ -1495,7 +1502,7 @@ static void oc_dec_dc_unpredict_mcu_plane(oc_dec_ctx *_dec, /*Reconstructs all coded fragments in a single MCU (one or two super block rows). This requires that each coded fragment have a proper macro block mode and - motion vector (if not in INTRA mode), and have it's DC value decoded, with + motion vector (if not in INTRA mode), and have its DC value decoded, with the DC prediction process reversed, and the number of coded and uncoded fragments in this plane of the MCU be counted. The token lists for each color plane and coefficient should also be filled @@ -1522,16 +1529,11 @@ static void oc_dec_frags_recon_mcu_plane(oc_dec_ctx *_dec, eob_runs=_pipe->eob_runs[_pli]; for(qti=0;qti<2;qti++)dc_quant[qti]=_pipe->dequant[_pli][0][qti][0]; for(fragii=0;fragii<ncoded_fragis;fragii++){ - /*This array is made one element larger because the zig-zag index array - uses the final element as a dumping ground for out-of-range indices - to protect us from buffer overflow.*/ - OC_ALIGN8(ogg_int16_t dct_coeffs[65]); const ogg_uint16_t *ac_quant; ptrdiff_t fragi; int last_zzi; int zzi; fragi=coded_fragis[fragii]; - for(zzi=0;zzi<64;zzi++)dct_coeffs[zzi]=0; qti=frags[fragi].mb_mode!=OC_MODE_INTRA; ac_quant=_pipe->dequant[_pli][frags[fragi].qii][qti]; /*Decode the AC coefficients.*/ @@ -1568,18 +1570,19 @@ static void oc_dec_frags_recon_mcu_plane(oc_dec_ctx *_dec, eob_runs[zzi]=eob; ti[zzi]=lti; zzi+=rlen; - dct_coeffs[dct_fzig_zag[zzi]]=(ogg_int16_t)(coeff*(int)ac_quant[zzi]); + _pipe->dct_coeffs[dct_fzig_zag[zzi]]= + (ogg_int16_t)(coeff*(int)ac_quant[zzi]); zzi+=!eob; } } /*TODO: zzi should be exactly 64 here. If it's not, we should report some kind of warning.*/ zzi=OC_MINI(zzi,64); - dct_coeffs[0]=(ogg_int16_t)frags[fragi].dc; + _pipe->dct_coeffs[0]=(ogg_int16_t)frags[fragi].dc; /*last_zzi is always initialized. If your compiler thinks otherwise, it is dumb.*/ oc_state_frag_recon(&_dec->state,fragi,_pli, - dct_coeffs,last_zzi,dc_quant[qti]); + _pipe->dct_coeffs,last_zzi,dc_quant[qti]); } _pipe->coded_fragis[_pli]+=ncoded_fragis; /*Right now the reconstructed MCU has only the coded blocks in it.*/ @@ -1593,9 +1596,14 @@ static void oc_dec_frags_recon_mcu_plane(oc_dec_ctx *_dec, code, and the hard case (high bitrate, high resolution) is handled correctly.*/ /*Copy the uncoded blocks from the previous reference frame.*/ - _pipe->uncoded_fragis[_pli]-=_pipe->nuncoded_fragis[_pli]; - oc_state_frag_copy_list(&_dec->state,_pipe->uncoded_fragis[_pli], - _pipe->nuncoded_fragis[_pli],OC_FRAME_SELF,OC_FRAME_PREV,_pli); + if(_pipe->nuncoded_fragis[_pli]>0){ + _pipe->uncoded_fragis[_pli]-=_pipe->nuncoded_fragis[_pli]; + oc_frag_copy_list(&_dec->state, + _dec->state.ref_frame_data[OC_FRAME_SELF], + _dec->state.ref_frame_data[OC_FRAME_PREV], + _dec->state.ref_ystride[_pli],_pipe->uncoded_fragis[_pli], + _pipe->nuncoded_fragis[_pli],_dec->state.frag_buf_offs); + } } /*Filter a horizontal block edge.*/ @@ -1953,9 +1961,9 @@ static void oc_dec_dering_frag_rows(oc_dec_ctx *_dec,th_img_plane *_img, th_dec_ctx *th_decode_alloc(const th_info *_info,const th_setup_info *_setup){ oc_dec_ctx *dec; if(_info==NULL||_setup==NULL)return NULL; - dec=_ogg_malloc(sizeof(*dec)); + dec=oc_aligned_malloc(sizeof(*dec),16); if(dec==NULL||oc_dec_init(dec,_info,_setup)<0){ - _ogg_free(dec); + oc_aligned_free(dec); return NULL; } dec->state.curframe_num=0; @@ -1965,7 +1973,7 @@ th_dec_ctx *th_decode_alloc(const th_info *_info,const th_setup_info *_setup){ void th_decode_free(th_dec_ctx *_dec){ if(_dec!=NULL){ oc_dec_clear(_dec); - _ogg_free(_dec); + oc_aligned_free(_dec); } } @@ -2013,28 +2021,24 @@ int th_decode_ctl(th_dec_ctx *_dec,int _req,void *_buf, case TH_DECCTL_SET_TELEMETRY_MBMODE:{ if(_dec==NULL||_buf==NULL)return TH_EFAULT; if(_buf_sz!=sizeof(int))return TH_EINVAL; - _dec->telemetry=1; _dec->telemetry_mbmode=*(int *)_buf; return 0; }break; case TH_DECCTL_SET_TELEMETRY_MV:{ if(_dec==NULL||_buf==NULL)return TH_EFAULT; if(_buf_sz!=sizeof(int))return TH_EINVAL; - _dec->telemetry=1; _dec->telemetry_mv=*(int *)_buf; return 0; }break; case TH_DECCTL_SET_TELEMETRY_QI:{ if(_dec==NULL||_buf==NULL)return TH_EFAULT; if(_buf_sz!=sizeof(int))return TH_EINVAL; - _dec->telemetry=1; _dec->telemetry_qi=*(int *)_buf; return 0; }break; case TH_DECCTL_SET_TELEMETRY_BITS:{ if(_dec==NULL||_buf==NULL)return TH_EFAULT; if(_buf_sz!=sizeof(int))return TH_EINVAL; - _dec->telemetry=1; _dec->telemetry_bits=*(int *)_buf; return 0; }break; @@ -2047,63 +2051,751 @@ int th_decode_ctl(th_dec_ctx *_dec,int _req,void *_buf, buffers (i.e., decoding did not start on a key frame). We initialize them to a solid gray here.*/ static void oc_dec_init_dummy_frame(th_dec_ctx *_dec){ - th_info *info; - size_t yplane_sz; - size_t cplane_sz; - int yhstride; - int yheight; - int chstride; - int cheight; + th_info *info; + size_t yplane_sz; + size_t cplane_sz; + ptrdiff_t yoffset; + int yhstride; + int yheight; + int chstride; + int cheight; _dec->state.ref_frame_idx[OC_FRAME_GOLD]=0; _dec->state.ref_frame_idx[OC_FRAME_PREV]=0; - _dec->state.ref_frame_idx[OC_FRAME_SELF]=1; + _dec->state.ref_frame_idx[OC_FRAME_SELF]=0; + _dec->state.ref_frame_data[OC_FRAME_GOLD]= + _dec->state.ref_frame_data[OC_FRAME_PREV]= + _dec->state.ref_frame_data[OC_FRAME_SELF]= + _dec->state.ref_frame_bufs[0][0].data; + memcpy(_dec->pp_frame_buf,_dec->state.ref_frame_bufs[0], + sizeof(_dec->pp_frame_buf[0])*3); info=&_dec->state.info; - yhstride=info->frame_width+2*OC_UMV_PADDING; + yhstride=abs(_dec->state.ref_ystride[0]); yheight=info->frame_height+2*OC_UMV_PADDING; - chstride=yhstride>>!(info->pixel_fmt&1); + chstride=abs(_dec->state.ref_ystride[1]); cheight=yheight>>!(info->pixel_fmt&2); - yplane_sz=yhstride*(size_t)yheight; + yplane_sz=yhstride*(size_t)yheight+16; cplane_sz=chstride*(size_t)cheight; - memset(_dec->state.ref_frame_data[0],0x80,yplane_sz+2*cplane_sz); + yoffset=yhstride*(ptrdiff_t)(yheight-OC_UMV_PADDING-1)+OC_UMV_PADDING; + memset(_dec->state.ref_frame_data[0]-yoffset,0x80,yplane_sz+2*cplane_sz); +} + +#if defined(HAVE_CAIRO) +static void oc_render_telemetry(th_dec_ctx *_dec,th_ycbcr_buffer _ycbcr, + int _telemetry){ + /*Stuff the plane into cairo.*/ + cairo_surface_t *cs; + unsigned char *data; + unsigned char *y_row; + unsigned char *u_row; + unsigned char *v_row; + unsigned char *rgb_row; + int cstride; + int w; + int h; + int x; + int y; + int hdec; + int vdec; + w=_ycbcr[0].width; + h=_ycbcr[0].height; + hdec=!(_dec->state.info.pixel_fmt&1); + vdec=!(_dec->state.info.pixel_fmt&2); + /*Lazy data buffer init. + We could try to re-use the post-processing buffer, which would save + memory, but complicate the allocation logic there. + I don't think anyone cares about memory usage when using telemetry; it is + not meant for embedded devices.*/ + if(_dec->telemetry_frame_data==NULL){ + _dec->telemetry_frame_data=_ogg_malloc( + (w*h+2*(w>>hdec)*(h>>vdec))*sizeof(*_dec->telemetry_frame_data)); + if(_dec->telemetry_frame_data==NULL)return; + } + cs=cairo_image_surface_create(CAIRO_FORMAT_RGB24,w,h); + /*Sadly, no YUV support in Cairo (yet); convert into the RGB buffer.*/ + data=cairo_image_surface_get_data(cs); + if(data==NULL){ + cairo_surface_destroy(cs); + return; + } + cstride=cairo_image_surface_get_stride(cs); + y_row=_ycbcr[0].data; + u_row=_ycbcr[1].data; + v_row=_ycbcr[2].data; + rgb_row=data; + for(y=0;y<h;y++){ + for(x=0;x<w;x++){ + int r; + int g; + int b; + r=(1904000*y_row[x]+2609823*v_row[x>>hdec]-363703744)/1635200; + g=(3827562*y_row[x]-1287801*u_row[x>>hdec] + -2672387*v_row[x>>hdec]+447306710)/3287200; + b=(952000*y_row[x]+1649289*u_row[x>>hdec]-225932192)/817600; + rgb_row[4*x+0]=OC_CLAMP255(b); + rgb_row[4*x+1]=OC_CLAMP255(g); + rgb_row[4*x+2]=OC_CLAMP255(r); + } + y_row+=_ycbcr[0].stride; + u_row+=_ycbcr[1].stride&-((y&1)|!vdec); + v_row+=_ycbcr[2].stride&-((y&1)|!vdec); + rgb_row+=cstride; + } + /*Draw coded identifier for each macroblock (stored in Hilbert order).*/ + { + cairo_t *c; + const oc_fragment *frags; + oc_mv *frag_mvs; + const signed char *mb_modes; + oc_mb_map *mb_maps; + size_t nmbs; + size_t mbi; + int row2; + int col2; + int qim[3]={0,0,0}; + if(_dec->state.nqis==2){ + int bqi; + bqi=_dec->state.qis[0]; + if(_dec->state.qis[1]>bqi)qim[1]=1; + if(_dec->state.qis[1]<bqi)qim[1]=-1; + } + if(_dec->state.nqis==3){ + int bqi; + int cqi; + int dqi; + bqi=_dec->state.qis[0]; + cqi=_dec->state.qis[1]; + dqi=_dec->state.qis[2]; + if(cqi>bqi&&dqi>bqi){ + if(dqi>cqi){ + qim[1]=1; + qim[2]=2; + } + else{ + qim[1]=2; + qim[2]=1; + } + } + else if(cqi<bqi&&dqi<bqi){ + if(dqi<cqi){ + qim[1]=-1; + qim[2]=-2; + } + else{ + qim[1]=-2; + qim[2]=-1; + } + } + else{ + if(cqi<bqi)qim[1]=-1; + else qim[1]=1; + if(dqi<bqi)qim[2]=-1; + else qim[2]=1; + } + } + c=cairo_create(cs); + frags=_dec->state.frags; + frag_mvs=_dec->state.frag_mvs; + mb_modes=_dec->state.mb_modes; + mb_maps=_dec->state.mb_maps; + nmbs=_dec->state.nmbs; + row2=0; + col2=0; + for(mbi=0;mbi<nmbs;mbi++){ + float x; + float y; + int bi; + y=h-(row2+((col2+1>>1)&1))*16-16; + x=(col2>>1)*16; + cairo_set_line_width(c,1.); + /*Keyframe (all intra) red box.*/ + if(_dec->state.frame_type==OC_INTRA_FRAME){ + if(_dec->telemetry_mbmode&0x02){ + cairo_set_source_rgba(c,1.,0,0,.5); + cairo_rectangle(c,x+2.5,y+2.5,11,11); + cairo_stroke_preserve(c); + cairo_set_source_rgba(c,1.,0,0,.25); + cairo_fill(c); + } + } + else{ + ptrdiff_t fragi; + int frag_mvx; + int frag_mvy; + for(bi=0;bi<4;bi++){ + fragi=mb_maps[mbi][0][bi]; + if(fragi>=0&&frags[fragi].coded){ + frag_mvx=OC_MV_X(frag_mvs[fragi]); + frag_mvy=OC_MV_Y(frag_mvs[fragi]); + break; + } + } + if(bi<4){ + switch(mb_modes[mbi]){ + case OC_MODE_INTRA:{ + if(_dec->telemetry_mbmode&0x02){ + cairo_set_source_rgba(c,1.,0,0,.5); + cairo_rectangle(c,x+2.5,y+2.5,11,11); + cairo_stroke_preserve(c); + cairo_set_source_rgba(c,1.,0,0,.25); + cairo_fill(c); + } + }break; + case OC_MODE_INTER_NOMV:{ + if(_dec->telemetry_mbmode&0x01){ + cairo_set_source_rgba(c,0,0,1.,.5); + cairo_rectangle(c,x+2.5,y+2.5,11,11); + cairo_stroke_preserve(c); + cairo_set_source_rgba(c,0,0,1.,.25); + cairo_fill(c); + } + }break; + case OC_MODE_INTER_MV:{ + if(_dec->telemetry_mbmode&0x04){ + cairo_rectangle(c,x+2.5,y+2.5,11,11); + cairo_set_source_rgba(c,0,1.,0,.5); + cairo_stroke(c); + } + if(_dec->telemetry_mv&0x04){ + cairo_move_to(c,x+8+frag_mvx,y+8-frag_mvy); + cairo_set_source_rgba(c,1.,1.,1.,.9); + cairo_set_line_width(c,3.); + cairo_line_to(c,x+8+frag_mvx*.66,y+8-frag_mvy*.66); + cairo_stroke_preserve(c); + cairo_set_line_width(c,2.); + cairo_line_to(c,x+8+frag_mvx*.33,y+8-frag_mvy*.33); + cairo_stroke_preserve(c); + cairo_set_line_width(c,1.); + cairo_line_to(c,x+8,y+8); + cairo_stroke(c); + } + }break; + case OC_MODE_INTER_MV_LAST:{ + if(_dec->telemetry_mbmode&0x08){ + cairo_rectangle(c,x+2.5,y+2.5,11,11); + cairo_set_source_rgba(c,0,1.,0,.5); + cairo_move_to(c,x+13.5,y+2.5); + cairo_line_to(c,x+2.5,y+8); + cairo_line_to(c,x+13.5,y+13.5); + cairo_stroke(c); + } + if(_dec->telemetry_mv&0x08){ + cairo_move_to(c,x+8+frag_mvx,y+8-frag_mvy); + cairo_set_source_rgba(c,1.,1.,1.,.9); + cairo_set_line_width(c,3.); + cairo_line_to(c,x+8+frag_mvx*.66,y+8-frag_mvy*.66); + cairo_stroke_preserve(c); + cairo_set_line_width(c,2.); + cairo_line_to(c,x+8+frag_mvx*.33,y+8-frag_mvy*.33); + cairo_stroke_preserve(c); + cairo_set_line_width(c,1.); + cairo_line_to(c,x+8,y+8); + cairo_stroke(c); + } + }break; + case OC_MODE_INTER_MV_LAST2:{ + if(_dec->telemetry_mbmode&0x10){ + cairo_rectangle(c,x+2.5,y+2.5,11,11); + cairo_set_source_rgba(c,0,1.,0,.5); + cairo_move_to(c,x+8,y+2.5); + cairo_line_to(c,x+2.5,y+8); + cairo_line_to(c,x+8,y+13.5); + cairo_move_to(c,x+13.5,y+2.5); + cairo_line_to(c,x+8,y+8); + cairo_line_to(c,x+13.5,y+13.5); + cairo_stroke(c); + } + if(_dec->telemetry_mv&0x10){ + cairo_move_to(c,x+8+frag_mvx,y+8-frag_mvy); + cairo_set_source_rgba(c,1.,1.,1.,.9); + cairo_set_line_width(c,3.); + cairo_line_to(c,x+8+frag_mvx*.66,y+8-frag_mvy*.66); + cairo_stroke_preserve(c); + cairo_set_line_width(c,2.); + cairo_line_to(c,x+8+frag_mvx*.33,y+8-frag_mvy*.33); + cairo_stroke_preserve(c); + cairo_set_line_width(c,1.); + cairo_line_to(c,x+8,y+8); + cairo_stroke(c); + } + }break; + case OC_MODE_GOLDEN_NOMV:{ + if(_dec->telemetry_mbmode&0x20){ + cairo_set_source_rgba(c,1.,1.,0,.5); + cairo_rectangle(c,x+2.5,y+2.5,11,11); + cairo_stroke_preserve(c); + cairo_set_source_rgba(c,1.,1.,0,.25); + cairo_fill(c); + } + }break; + case OC_MODE_GOLDEN_MV:{ + if(_dec->telemetry_mbmode&0x40){ + cairo_rectangle(c,x+2.5,y+2.5,11,11); + cairo_set_source_rgba(c,1.,1.,0,.5); + cairo_stroke(c); + } + if(_dec->telemetry_mv&0x40){ + cairo_move_to(c,x+8+frag_mvx,y+8-frag_mvy); + cairo_set_source_rgba(c,1.,1.,1.,.9); + cairo_set_line_width(c,3.); + cairo_line_to(c,x+8+frag_mvx*.66,y+8-frag_mvy*.66); + cairo_stroke_preserve(c); + cairo_set_line_width(c,2.); + cairo_line_to(c,x+8+frag_mvx*.33,y+8-frag_mvy*.33); + cairo_stroke_preserve(c); + cairo_set_line_width(c,1.); + cairo_line_to(c,x+8,y+8); + cairo_stroke(c); + } + }break; + case OC_MODE_INTER_MV_FOUR:{ + if(_dec->telemetry_mbmode&0x80){ + cairo_rectangle(c,x+2.5,y+2.5,4,4); + cairo_rectangle(c,x+9.5,y+2.5,4,4); + cairo_rectangle(c,x+2.5,y+9.5,4,4); + cairo_rectangle(c,x+9.5,y+9.5,4,4); + cairo_set_source_rgba(c,0,1.,0,.5); + cairo_stroke(c); + } + /*4mv is odd, coded in raster order.*/ + fragi=mb_maps[mbi][0][0]; + if(frags[fragi].coded&&_dec->telemetry_mv&0x80){ + frag_mvx=OC_MV_X(frag_mvs[fragi]); + frag_mvx=OC_MV_Y(frag_mvs[fragi]); + cairo_move_to(c,x+4+frag_mvx,y+12-frag_mvy); + cairo_set_source_rgba(c,1.,1.,1.,.9); + cairo_set_line_width(c,3.); + cairo_line_to(c,x+4+frag_mvx*.66,y+12-frag_mvy*.66); + cairo_stroke_preserve(c); + cairo_set_line_width(c,2.); + cairo_line_to(c,x+4+frag_mvx*.33,y+12-frag_mvy*.33); + cairo_stroke_preserve(c); + cairo_set_line_width(c,1.); + cairo_line_to(c,x+4,y+12); + cairo_stroke(c); + } + fragi=mb_maps[mbi][0][1]; + if(frags[fragi].coded&&_dec->telemetry_mv&0x80){ + frag_mvx=OC_MV_X(frag_mvs[fragi]); + frag_mvx=OC_MV_Y(frag_mvs[fragi]); + cairo_move_to(c,x+12+frag_mvx,y+12-frag_mvy); + cairo_set_source_rgba(c,1.,1.,1.,.9); + cairo_set_line_width(c,3.); + cairo_line_to(c,x+12+frag_mvx*.66,y+12-frag_mvy*.66); + cairo_stroke_preserve(c); + cairo_set_line_width(c,2.); + cairo_line_to(c,x+12+frag_mvx*.33,y+12-frag_mvy*.33); + cairo_stroke_preserve(c); + cairo_set_line_width(c,1.); + cairo_line_to(c,x+12,y+12); + cairo_stroke(c); + } + fragi=mb_maps[mbi][0][2]; + if(frags[fragi].coded&&_dec->telemetry_mv&0x80){ + frag_mvx=OC_MV_X(frag_mvs[fragi]); + frag_mvx=OC_MV_Y(frag_mvs[fragi]); + cairo_move_to(c,x+4+frag_mvx,y+4-frag_mvy); + cairo_set_source_rgba(c,1.,1.,1.,.9); + cairo_set_line_width(c,3.); + cairo_line_to(c,x+4+frag_mvx*.66,y+4-frag_mvy*.66); + cairo_stroke_preserve(c); + cairo_set_line_width(c,2.); + cairo_line_to(c,x+4+frag_mvx*.33,y+4-frag_mvy*.33); + cairo_stroke_preserve(c); + cairo_set_line_width(c,1.); + cairo_line_to(c,x+4,y+4); + cairo_stroke(c); + } + fragi=mb_maps[mbi][0][3]; + if(frags[fragi].coded&&_dec->telemetry_mv&0x80){ + frag_mvx=OC_MV_X(frag_mvs[fragi]); + frag_mvx=OC_MV_Y(frag_mvs[fragi]); + cairo_move_to(c,x+12+frag_mvx,y+4-frag_mvy); + cairo_set_source_rgba(c,1.,1.,1.,.9); + cairo_set_line_width(c,3.); + cairo_line_to(c,x+12+frag_mvx*.66,y+4-frag_mvy*.66); + cairo_stroke_preserve(c); + cairo_set_line_width(c,2.); + cairo_line_to(c,x+12+frag_mvx*.33,y+4-frag_mvy*.33); + cairo_stroke_preserve(c); + cairo_set_line_width(c,1.); + cairo_line_to(c,x+12,y+4); + cairo_stroke(c); + } + }break; + } + } + } + /*qii illustration.*/ + if(_dec->telemetry_qi&0x2){ + cairo_set_line_cap(c,CAIRO_LINE_CAP_SQUARE); + for(bi=0;bi<4;bi++){ + ptrdiff_t fragi; + int qiv; + int xp; + int yp; + xp=x+(bi&1)*8; + yp=y+8-(bi&2)*4; + fragi=mb_maps[mbi][0][bi]; + if(fragi>=0&&frags[fragi].coded){ + qiv=qim[frags[fragi].qii]; + cairo_set_line_width(c,3.); + cairo_set_source_rgba(c,0.,0.,0.,.5); + switch(qiv){ + /*Double plus:*/ + case 2:{ + if((bi&1)^((bi&2)>>1)){ + cairo_move_to(c,xp+2.5,yp+1.5); + cairo_line_to(c,xp+2.5,yp+3.5); + cairo_move_to(c,xp+1.5,yp+2.5); + cairo_line_to(c,xp+3.5,yp+2.5); + cairo_move_to(c,xp+5.5,yp+4.5); + cairo_line_to(c,xp+5.5,yp+6.5); + cairo_move_to(c,xp+4.5,yp+5.5); + cairo_line_to(c,xp+6.5,yp+5.5); + cairo_stroke_preserve(c); + cairo_set_source_rgba(c,0.,1.,1.,1.); + } + else{ + cairo_move_to(c,xp+5.5,yp+1.5); + cairo_line_to(c,xp+5.5,yp+3.5); + cairo_move_to(c,xp+4.5,yp+2.5); + cairo_line_to(c,xp+6.5,yp+2.5); + cairo_move_to(c,xp+2.5,yp+4.5); + cairo_line_to(c,xp+2.5,yp+6.5); + cairo_move_to(c,xp+1.5,yp+5.5); + cairo_line_to(c,xp+3.5,yp+5.5); + cairo_stroke_preserve(c); + cairo_set_source_rgba(c,0.,1.,1.,1.); + } + }break; + /*Double minus:*/ + case -2:{ + cairo_move_to(c,xp+2.5,yp+2.5); + cairo_line_to(c,xp+5.5,yp+2.5); + cairo_move_to(c,xp+2.5,yp+5.5); + cairo_line_to(c,xp+5.5,yp+5.5); + cairo_stroke_preserve(c); + cairo_set_source_rgba(c,1.,1.,1.,1.); + }break; + /*Plus:*/ + case 1:{ + if((bi&2)==0)yp-=2; + if((bi&1)==0)xp-=2; + cairo_move_to(c,xp+4.5,yp+2.5); + cairo_line_to(c,xp+4.5,yp+6.5); + cairo_move_to(c,xp+2.5,yp+4.5); + cairo_line_to(c,xp+6.5,yp+4.5); + cairo_stroke_preserve(c); + cairo_set_source_rgba(c,.1,1.,.3,1.); + break; + } + /*Fall through.*/ + /*Minus:*/ + case -1:{ + cairo_move_to(c,xp+2.5,yp+4.5); + cairo_line_to(c,xp+6.5,yp+4.5); + cairo_stroke_preserve(c); + cairo_set_source_rgba(c,1.,.3,.1,1.); + }break; + default:continue; + } + cairo_set_line_width(c,1.); + cairo_stroke(c); + } + } + } + col2++; + if((col2>>1)>=_dec->state.nhmbs){ + col2=0; + row2+=2; + } + } + /*Bit usage indicator[s]:*/ + if(_dec->telemetry_bits){ + int widths[6]; + int fpsn; + int fpsd; + int mult; + int fullw; + int padw; + int i; + fpsn=_dec->state.info.fps_numerator; + fpsd=_dec->state.info.fps_denominator; + mult=(_dec->telemetry_bits>=0xFF?1:_dec->telemetry_bits); + fullw=250.f*h*fpsd*mult/fpsn; + padw=w-24; + /*Header and coded block bits.*/ + if(_dec->telemetry_frame_bytes<0|| + _dec->telemetry_frame_bytes==OC_LOTS_OF_BITS){ + _dec->telemetry_frame_bytes=0; + } + if(_dec->telemetry_coding_bytes<0|| + _dec->telemetry_coding_bytes>_dec->telemetry_frame_bytes){ + _dec->telemetry_coding_bytes=0; + } + if(_dec->telemetry_mode_bytes<0|| + _dec->telemetry_mode_bytes>_dec->telemetry_frame_bytes){ + _dec->telemetry_mode_bytes=0; + } + if(_dec->telemetry_mv_bytes<0|| + _dec->telemetry_mv_bytes>_dec->telemetry_frame_bytes){ + _dec->telemetry_mv_bytes=0; + } + if(_dec->telemetry_qi_bytes<0|| + _dec->telemetry_qi_bytes>_dec->telemetry_frame_bytes){ + _dec->telemetry_qi_bytes=0; + } + if(_dec->telemetry_dc_bytes<0|| + _dec->telemetry_dc_bytes>_dec->telemetry_frame_bytes){ + _dec->telemetry_dc_bytes=0; + } + widths[0]=padw* + (_dec->telemetry_frame_bytes-_dec->telemetry_coding_bytes)/fullw; + widths[1]=padw* + (_dec->telemetry_coding_bytes-_dec->telemetry_mode_bytes)/fullw; + widths[2]=padw* + (_dec->telemetry_mode_bytes-_dec->telemetry_mv_bytes)/fullw; + widths[3]=padw*(_dec->telemetry_mv_bytes-_dec->telemetry_qi_bytes)/fullw; + widths[4]=padw*(_dec->telemetry_qi_bytes-_dec->telemetry_dc_bytes)/fullw; + widths[5]=padw*(_dec->telemetry_dc_bytes)/fullw; + for(i=0;i<6;i++)if(widths[i]>w)widths[i]=w; + cairo_set_source_rgba(c,.0,.0,.0,.6); + cairo_rectangle(c,10,h-33,widths[0]+1,5); + cairo_rectangle(c,10,h-29,widths[1]+1,5); + cairo_rectangle(c,10,h-25,widths[2]+1,5); + cairo_rectangle(c,10,h-21,widths[3]+1,5); + cairo_rectangle(c,10,h-17,widths[4]+1,5); + cairo_rectangle(c,10,h-13,widths[5]+1,5); + cairo_fill(c); + cairo_set_source_rgb(c,1,0,0); + cairo_rectangle(c,10.5,h-32.5,widths[0],4); + cairo_fill(c); + cairo_set_source_rgb(c,0,1,0); + cairo_rectangle(c,10.5,h-28.5,widths[1],4); + cairo_fill(c); + cairo_set_source_rgb(c,0,0,1); + cairo_rectangle(c,10.5,h-24.5,widths[2],4); + cairo_fill(c); + cairo_set_source_rgb(c,.6,.4,.0); + cairo_rectangle(c,10.5,h-20.5,widths[3],4); + cairo_fill(c); + cairo_set_source_rgb(c,.3,.3,.3); + cairo_rectangle(c,10.5,h-16.5,widths[4],4); + cairo_fill(c); + cairo_set_source_rgb(c,.5,.5,.8); + cairo_rectangle(c,10.5,h-12.5,widths[5],4); + cairo_fill(c); + } + /*Master qi indicator[s]:*/ + if(_dec->telemetry_qi&0x1){ + cairo_text_extents_t extents; + char buffer[10]; + int p; + int y; + p=0; + y=h-7.5; + if(_dec->state.qis[0]>=10)buffer[p++]=48+_dec->state.qis[0]/10; + buffer[p++]=48+_dec->state.qis[0]%10; + if(_dec->state.nqis>=2){ + buffer[p++]=' '; + if(_dec->state.qis[1]>=10)buffer[p++]=48+_dec->state.qis[1]/10; + buffer[p++]=48+_dec->state.qis[1]%10; + } + if(_dec->state.nqis==3){ + buffer[p++]=' '; + if(_dec->state.qis[2]>=10)buffer[p++]=48+_dec->state.qis[2]/10; + buffer[p++]=48+_dec->state.qis[2]%10; + } + buffer[p++]='\0'; + cairo_select_font_face(c,"sans", + CAIRO_FONT_SLANT_NORMAL,CAIRO_FONT_WEIGHT_BOLD); + cairo_set_font_size(c,18); + cairo_text_extents(c,buffer,&extents); + cairo_set_source_rgb(c,1,1,1); + cairo_move_to(c,w-extents.x_advance-10,y); + cairo_show_text(c,buffer); + cairo_set_source_rgb(c,0,0,0); + cairo_move_to(c,w-extents.x_advance-10,y); + cairo_text_path(c,buffer); + cairo_set_line_width(c,.8); + cairo_set_line_join(c,CAIRO_LINE_JOIN_ROUND); + cairo_stroke(c); + } + cairo_destroy(c); + } + /*Out of the Cairo plane into the telemetry YUV buffer.*/ + _ycbcr[0].data=_dec->telemetry_frame_data; + _ycbcr[0].stride=_ycbcr[0].width; + _ycbcr[1].data=_ycbcr[0].data+h*_ycbcr[0].stride; + _ycbcr[1].stride=_ycbcr[1].width; + _ycbcr[2].data=_ycbcr[1].data+(h>>vdec)*_ycbcr[1].stride; + _ycbcr[2].stride=_ycbcr[2].width; + y_row=_ycbcr[0].data; + u_row=_ycbcr[1].data; + v_row=_ycbcr[2].data; + rgb_row=data; + /*This is one of the few places it's worth handling chroma on a + case-by-case basis.*/ + switch(_dec->state.info.pixel_fmt){ + case TH_PF_420:{ + for(y=0;y<h;y+=2){ + unsigned char *y_row2; + unsigned char *rgb_row2; + y_row2=y_row+_ycbcr[0].stride; + rgb_row2=rgb_row+cstride; + for(x=0;x<w;x+=2){ + int y; + int u; + int v; + y=(65481*rgb_row[4*x+2]+128553*rgb_row[4*x+1] + +24966*rgb_row[4*x+0]+4207500)/255000; + y_row[x]=OC_CLAMP255(y); + y=(65481*rgb_row[4*x+6]+128553*rgb_row[4*x+5] + +24966*rgb_row[4*x+4]+4207500)/255000; + y_row[x+1]=OC_CLAMP255(y); + y=(65481*rgb_row2[4*x+2]+128553*rgb_row2[4*x+1] + +24966*rgb_row2[4*x+0]+4207500)/255000; + y_row2[x]=OC_CLAMP255(y); + y=(65481*rgb_row2[4*x+6]+128553*rgb_row2[4*x+5] + +24966*rgb_row2[4*x+4]+4207500)/255000; + y_row2[x+1]=OC_CLAMP255(y); + u=(-8372*(rgb_row[4*x+2]+rgb_row[4*x+6] + +rgb_row2[4*x+2]+rgb_row2[4*x+6]) + -16436*(rgb_row[4*x+1]+rgb_row[4*x+5] + +rgb_row2[4*x+1]+rgb_row2[4*x+5]) + +24808*(rgb_row[4*x+0]+rgb_row[4*x+4] + +rgb_row2[4*x+0]+rgb_row2[4*x+4])+29032005)/225930; + v=(39256*(rgb_row[4*x+2]+rgb_row[4*x+6] + +rgb_row2[4*x+2]+rgb_row2[4*x+6]) + -32872*(rgb_row[4*x+1]+rgb_row[4*x+5] + +rgb_row2[4*x+1]+rgb_row2[4*x+5]) + -6384*(rgb_row[4*x+0]+rgb_row[4*x+4] + +rgb_row2[4*x+0]+rgb_row2[4*x+4])+45940035)/357510; + u_row[x>>1]=OC_CLAMP255(u); + v_row[x>>1]=OC_CLAMP255(v); + } + y_row+=_ycbcr[0].stride<<1; + u_row+=_ycbcr[1].stride; + v_row+=_ycbcr[2].stride; + rgb_row+=cstride<<1; + } + }break; + case TH_PF_422:{ + for(y=0;y<h;y++){ + for(x=0;x<w;x+=2){ + int y; + int u; + int v; + y=(65481*rgb_row[4*x+2]+128553*rgb_row[4*x+1] + +24966*rgb_row[4*x+0]+4207500)/255000; + y_row[x]=OC_CLAMP255(y); + y=(65481*rgb_row[4*x+6]+128553*rgb_row[4*x+5] + +24966*rgb_row[4*x+4]+4207500)/255000; + y_row[x+1]=OC_CLAMP255(y); + u=(-16744*(rgb_row[4*x+2]+rgb_row[4*x+6]) + -32872*(rgb_row[4*x+1]+rgb_row[4*x+5]) + +49616*(rgb_row[4*x+0]+rgb_row[4*x+4])+29032005)/225930; + v=(78512*(rgb_row[4*x+2]+rgb_row[4*x+6]) + -65744*(rgb_row[4*x+1]+rgb_row[4*x+5]) + -12768*(rgb_row[4*x+0]+rgb_row[4*x+4])+45940035)/357510; + u_row[x>>1]=OC_CLAMP255(u); + v_row[x>>1]=OC_CLAMP255(v); + } + y_row+=_ycbcr[0].stride; + u_row+=_ycbcr[1].stride; + v_row+=_ycbcr[2].stride; + rgb_row+=cstride; + } + }break; + /*case TH_PF_444:*/ + default:{ + for(y=0;y<h;y++){ + for(x=0;x<w;x++){ + int y; + int u; + int v; + y=(65481*rgb_row[4*x+2]+128553*rgb_row[4*x+1] + +24966*rgb_row[4*x+0]+4207500)/255000; + u=(-33488*rgb_row[4*x+2]-65744*rgb_row[4*x+1] + +99232*rgb_row[4*x+0]+29032005)/225930; + v=(157024*rgb_row[4*x+2]-131488*rgb_row[4*x+1] + -25536*rgb_row[4*x+0]+45940035)/357510; + y_row[x]=OC_CLAMP255(y); + u_row[x]=OC_CLAMP255(u); + v_row[x]=OC_CLAMP255(v); + } + y_row+=_ycbcr[0].stride; + u_row+=_ycbcr[1].stride; + v_row+=_ycbcr[2].stride; + rgb_row+=cstride; + } + }break; + } + /*Finished. + Destroy the surface.*/ + cairo_surface_destroy(cs); } +#endif int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op, ogg_int64_t *_granpos){ int ret; if(_dec==NULL||_op==NULL)return TH_EFAULT; /*A completely empty packet indicates a dropped frame and is treated exactly - like an inter frame with no coded blocks. - Only proceed if we have a non-empty packet.*/ - if(_op->bytes!=0){ - oc_dec_pipeline_state pipe; - th_ycbcr_buffer stripe_buf; - int stripe_fragy; - int refi; - int pli; - int notstart; - int notdone; + like an inter frame with no coded blocks.*/ + if(_op->bytes==0){ + _dec->state.frame_type=OC_INTER_FRAME; + _dec->state.ntotal_coded_fragis=0; + } + else{ oc_pack_readinit(&_dec->opb,_op->packet,_op->bytes); + ret=oc_dec_frame_header_unpack(_dec); + if(ret<0)return ret; + if(_dec->state.frame_type==OC_INTRA_FRAME)oc_dec_mark_all_intra(_dec); + else oc_dec_coded_flags_unpack(_dec); + } + /*If there have been no reference frames, and we need one, initialize one.*/ + if(_dec->state.frame_type!=OC_INTRA_FRAME&& + (_dec->state.ref_frame_idx[OC_FRAME_GOLD]<0|| + _dec->state.ref_frame_idx[OC_FRAME_PREV]<0)){ + oc_dec_init_dummy_frame(_dec); + } + /*If this was an inter frame with no coded blocks...*/ + if(_dec->state.ntotal_coded_fragis<=0){ + /*Just update the granule position and return.*/ + _dec->state.granpos=(_dec->state.keyframe_num+_dec->state.granpos_bias<< + _dec->state.info.keyframe_granule_shift) + +(_dec->state.curframe_num-_dec->state.keyframe_num); + _dec->state.curframe_num++; + if(_granpos!=NULL)*_granpos=_dec->state.granpos; + return TH_DUPFRAME; + } + else{ + th_ycbcr_buffer stripe_buf; + int stripe_fragy; + int refi; + int pli; + int notstart; + int notdone; +#ifdef HAVE_CAIRO + int telemetry; + /*Save the current telemetry state. + This prevents it from being modified in the middle of decoding this + frame, which could cause us to skip calls to the striped decoding + callback.*/ + telemetry=_dec->telemetry_mbmode||_dec->telemetry_mv|| + _dec->telemetry_qi||_dec->telemetry_bits; +#endif + /*Select a free buffer to use for the reconstructed version of this frame.*/ + for(refi=0;refi==_dec->state.ref_frame_idx[OC_FRAME_GOLD]|| + refi==_dec->state.ref_frame_idx[OC_FRAME_PREV];refi++); + _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi; + _dec->state.ref_frame_data[OC_FRAME_SELF]= + _dec->state.ref_frame_bufs[refi][0].data; #if defined(HAVE_CAIRO) _dec->telemetry_frame_bytes=_op->bytes; #endif - ret=oc_dec_frame_header_unpack(_dec); - if(ret<0)return ret; - /*Select a free buffer to use for the reconstructed version of this - frame.*/ - if(_dec->state.frame_type!=OC_INTRA_FRAME&& - (_dec->state.ref_frame_idx[OC_FRAME_GOLD]<0|| - _dec->state.ref_frame_idx[OC_FRAME_PREV]<0)){ - /*No reference frames yet!*/ - oc_dec_init_dummy_frame(_dec); - refi=_dec->state.ref_frame_idx[OC_FRAME_SELF]; - } - else{ - for(refi=0;refi==_dec->state.ref_frame_idx[OC_FRAME_GOLD]|| - refi==_dec->state.ref_frame_idx[OC_FRAME_PREV];refi++); - _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi; - } if(_dec->state.frame_type==OC_INTRA_FRAME){ - oc_dec_mark_all_intra(_dec); _dec->state.keyframe_num=_dec->state.curframe_num; #if defined(HAVE_CAIRO) _dec->telemetry_coding_bytes= @@ -2112,7 +2804,6 @@ int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op, #endif } else{ - oc_dec_coded_flags_unpack(_dec); #if defined(HAVE_CAIRO) _dec->telemetry_coding_bytes=oc_pack_bytes_left(&_dec->opb); #endif @@ -2160,15 +2851,15 @@ int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op, An application callback allows further application processing (blitting to video memory, color conversion, etc.) to also use the data while it's in cache.*/ - oc_dec_pipeline_init(_dec,&pipe); + oc_dec_pipeline_init(_dec,&_dec->pipe); oc_ycbcr_buffer_flip(stripe_buf,_dec->pp_frame_buf); notstart=0; notdone=1; - for(stripe_fragy=0;notdone;stripe_fragy+=pipe.mcu_nvfrags){ + for(stripe_fragy=0;notdone;stripe_fragy+=_dec->pipe.mcu_nvfrags){ int avail_fragy0; int avail_fragy_end; avail_fragy0=avail_fragy_end=_dec->state.fplanes[0].nvfrags; - notdone=stripe_fragy+pipe.mcu_nvfrags<avail_fragy_end; + notdone=stripe_fragy+_dec->pipe.mcu_nvfrags<avail_fragy_end; for(pli=0;pli<3;pli++){ oc_fragment_plane *fplane; int frag_shift; @@ -2179,45 +2870,46 @@ int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op, /*Compute the first and last fragment row of the current MCU for this plane.*/ frag_shift=pli!=0&&!(_dec->state.info.pixel_fmt&2); - pipe.fragy0[pli]=stripe_fragy>>frag_shift; - pipe.fragy_end[pli]=OC_MINI(fplane->nvfrags, - pipe.fragy0[pli]+(pipe.mcu_nvfrags>>frag_shift)); - oc_dec_dc_unpredict_mcu_plane(_dec,&pipe,pli); - oc_dec_frags_recon_mcu_plane(_dec,&pipe,pli); + _dec->pipe.fragy0[pli]=stripe_fragy>>frag_shift; + _dec->pipe.fragy_end[pli]=OC_MINI(fplane->nvfrags, + _dec->pipe.fragy0[pli]+(_dec->pipe.mcu_nvfrags>>frag_shift)); + oc_dec_dc_unpredict_mcu_plane(_dec,&_dec->pipe,pli); + oc_dec_frags_recon_mcu_plane(_dec,&_dec->pipe,pli); sdelay=edelay=0; - if(pipe.loop_filter){ + if(_dec->pipe.loop_filter){ sdelay+=notstart; edelay+=notdone; - oc_state_loop_filter_frag_rows(&_dec->state,pipe.bounding_values, - refi,pli,pipe.fragy0[pli]-sdelay,pipe.fragy_end[pli]-edelay); + oc_state_loop_filter_frag_rows(&_dec->state, + _dec->pipe.bounding_values,OC_FRAME_SELF,pli, + _dec->pipe.fragy0[pli]-sdelay,_dec->pipe.fragy_end[pli]-edelay); } /*To fill the borders, we have an additional two pixel delay, since a fragment in the next row could filter its top edge, using two pixels from a fragment in this row. But there's no reason to delay a full fragment between the two.*/ oc_state_borders_fill_rows(&_dec->state,refi,pli, - (pipe.fragy0[pli]-sdelay<<3)-(sdelay<<1), - (pipe.fragy_end[pli]-edelay<<3)-(edelay<<1)); + (_dec->pipe.fragy0[pli]-sdelay<<3)-(sdelay<<1), + (_dec->pipe.fragy_end[pli]-edelay<<3)-(edelay<<1)); /*Out-of-loop post-processing.*/ pp_offset=3*(pli!=0); - if(pipe.pp_level>=OC_PP_LEVEL_DEBLOCKY+pp_offset){ + if(_dec->pipe.pp_level>=OC_PP_LEVEL_DEBLOCKY+pp_offset){ /*Perform de-blocking in one plane.*/ sdelay+=notstart; edelay+=notdone; oc_dec_deblock_frag_rows(_dec,_dec->pp_frame_buf, _dec->state.ref_frame_bufs[refi],pli, - pipe.fragy0[pli]-sdelay,pipe.fragy_end[pli]-edelay); - if(pipe.pp_level>=OC_PP_LEVEL_DERINGY+pp_offset){ + _dec->pipe.fragy0[pli]-sdelay,_dec->pipe.fragy_end[pli]-edelay); + if(_dec->pipe.pp_level>=OC_PP_LEVEL_DERINGY+pp_offset){ /*Perform de-ringing in one plane.*/ sdelay+=notstart; edelay+=notdone; oc_dec_dering_frag_rows(_dec,_dec->pp_frame_buf,pli, - pipe.fragy0[pli]-sdelay,pipe.fragy_end[pli]-edelay); + _dec->pipe.fragy0[pli]-sdelay,_dec->pipe.fragy_end[pli]-edelay); } } /*If no post-processing is done, we still need to delay a row for the loop filter, thanks to the strange filtering order VP3 chose.*/ - else if(pipe.loop_filter){ + else if(_dec->pipe.loop_filter){ sdelay+=notstart; edelay+=notdone; } @@ -2226,11 +2918,16 @@ int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op, doubled, but luma might have more post-processing filters enabled than chroma, so we don't know up front which one is the limiting factor.*/ - avail_fragy0=OC_MINI(avail_fragy0,pipe.fragy0[pli]-sdelay<<frag_shift); + avail_fragy0=OC_MINI(avail_fragy0, + _dec->pipe.fragy0[pli]-sdelay<<frag_shift); avail_fragy_end=OC_MINI(avail_fragy_end, - pipe.fragy_end[pli]-edelay<<frag_shift); + _dec->pipe.fragy_end[pli]-edelay<<frag_shift); } +#ifdef HAVE_CAIRO + if(_dec->stripe_cb.stripe_decoded!=NULL&&!telemetry){ +#else if(_dec->stripe_cb.stripe_decoded!=NULL){ +#endif /*The callback might want to use the FPU, so let's make sure they can. We violate all kinds of ABI restrictions by not doing this until now, but none of them actually matter since we don't use floating @@ -2252,692 +2949,44 @@ int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op, _dec->state.ref_frame_idx[OC_FRAME_GOLD]= _dec->state.ref_frame_idx[OC_FRAME_PREV]= _dec->state.ref_frame_idx[OC_FRAME_SELF]; + _dec->state.ref_frame_data[OC_FRAME_GOLD]= + _dec->state.ref_frame_data[OC_FRAME_PREV]= + _dec->state.ref_frame_data[OC_FRAME_SELF]; } else{ /*Otherwise, just replace the previous reference frame.*/ _dec->state.ref_frame_idx[OC_FRAME_PREV]= _dec->state.ref_frame_idx[OC_FRAME_SELF]; + _dec->state.ref_frame_data[OC_FRAME_PREV]= + _dec->state.ref_frame_data[OC_FRAME_SELF]; } /*Restore the FPU before dump_frame, since that _does_ use the FPU (for PNG gamma values, if nothing else).*/ oc_restore_fpu(&_dec->state); +#ifdef HAVE_CAIRO + /*If telemetry ioctls are active, we need to draw to the output buffer.*/ + if(telemetry){ + oc_render_telemetry(_dec,stripe_buf,telemetry); + oc_ycbcr_buffer_flip(_dec->pp_frame_buf,stripe_buf); + /*If we had a striped decoding callback, we skipped calling it above + (because the telemetry wasn't rendered yet). + Call it now with the whole frame.*/ + if(_dec->stripe_cb.stripe_decoded!=NULL){ + (*_dec->stripe_cb.stripe_decoded)(_dec->stripe_cb.ctx, + stripe_buf,0,_dec->state.fplanes[0].nvfrags); + } + } +#endif #if defined(OC_DUMP_IMAGES) - /*Don't dump images for dropped frames.*/ + /*We only dump images if there were some coded blocks.*/ oc_state_dump_frame(&_dec->state,OC_FRAME_SELF,"dec"); #endif return 0; } - else{ - if(_dec->state.ref_frame_idx[OC_FRAME_GOLD]<0|| - _dec->state.ref_frame_idx[OC_FRAME_PREV]<0){ - int refi; - /*No reference frames yet!*/ - oc_dec_init_dummy_frame(_dec); - refi=_dec->state.ref_frame_idx[OC_FRAME_PREV]; - _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi; - memcpy(_dec->pp_frame_buf,_dec->state.ref_frame_bufs[refi], - sizeof(_dec->pp_frame_buf[0])*3); - } - /*Just update the granule position and return.*/ - _dec->state.granpos=(_dec->state.keyframe_num+_dec->state.granpos_bias<< - _dec->state.info.keyframe_granule_shift) - +(_dec->state.curframe_num-_dec->state.keyframe_num); - _dec->state.curframe_num++; - if(_granpos!=NULL)*_granpos=_dec->state.granpos; - return TH_DUPFRAME; - } } int th_decode_ycbcr_out(th_dec_ctx *_dec,th_ycbcr_buffer _ycbcr){ if(_dec==NULL||_ycbcr==NULL)return TH_EFAULT; oc_ycbcr_buffer_flip(_ycbcr,_dec->pp_frame_buf); -#if defined(HAVE_CAIRO) - /*If telemetry ioctls are active, we need to draw to the output buffer. - Stuff the plane into cairo.*/ - if(_dec->telemetry){ - cairo_surface_t *cs; - unsigned char *data; - unsigned char *y_row; - unsigned char *u_row; - unsigned char *v_row; - unsigned char *rgb_row; - int cstride; - int w; - int h; - int x; - int y; - int hdec; - int vdec; - w=_ycbcr[0].width; - h=_ycbcr[0].height; - hdec=!(_dec->state.info.pixel_fmt&1); - vdec=!(_dec->state.info.pixel_fmt&2); - /*Lazy data buffer init. - We could try to re-use the post-processing buffer, which would save - memory, but complicate the allocation logic there. - I don't think anyone cares about memory usage when using telemetry; it is - not meant for embedded devices.*/ - if(_dec->telemetry_frame_data==NULL){ - _dec->telemetry_frame_data=_ogg_malloc( - (w*h+2*(w>>hdec)*(h>>vdec))*sizeof(*_dec->telemetry_frame_data)); - if(_dec->telemetry_frame_data==NULL)return 0; - } - cs=cairo_image_surface_create(CAIRO_FORMAT_RGB24,w,h); - /*Sadly, no YUV support in Cairo (yet); convert into the RGB buffer.*/ - data=cairo_image_surface_get_data(cs); - if(data==NULL){ - cairo_surface_destroy(cs); - return 0; - } - cstride=cairo_image_surface_get_stride(cs); - y_row=_ycbcr[0].data; - u_row=_ycbcr[1].data; - v_row=_ycbcr[2].data; - rgb_row=data; - for(y=0;y<h;y++){ - for(x=0;x<w;x++){ - int r; - int g; - int b; - r=(1904000*y_row[x]+2609823*v_row[x>>hdec]-363703744)/1635200; - g=(3827562*y_row[x]-1287801*u_row[x>>hdec] - -2672387*v_row[x>>hdec]+447306710)/3287200; - b=(952000*y_row[x]+1649289*u_row[x>>hdec]-225932192)/817600; - rgb_row[4*x+0]=OC_CLAMP255(b); - rgb_row[4*x+1]=OC_CLAMP255(g); - rgb_row[4*x+2]=OC_CLAMP255(r); - } - y_row+=_ycbcr[0].stride; - u_row+=_ycbcr[1].stride&-((y&1)|!vdec); - v_row+=_ycbcr[2].stride&-((y&1)|!vdec); - rgb_row+=cstride; - } - /*Draw coded identifier for each macroblock (stored in Hilbert order).*/ - { - cairo_t *c; - const oc_fragment *frags; - oc_mv *frag_mvs; - const signed char *mb_modes; - oc_mb_map *mb_maps; - size_t nmbs; - size_t mbi; - int row2; - int col2; - int qim[3]={0,0,0}; - if(_dec->state.nqis==2){ - int bqi; - bqi=_dec->state.qis[0]; - if(_dec->state.qis[1]>bqi)qim[1]=1; - if(_dec->state.qis[1]<bqi)qim[1]=-1; - } - if(_dec->state.nqis==3){ - int bqi; - int cqi; - int dqi; - bqi=_dec->state.qis[0]; - cqi=_dec->state.qis[1]; - dqi=_dec->state.qis[2]; - if(cqi>bqi&&dqi>bqi){ - if(dqi>cqi){ - qim[1]=1; - qim[2]=2; - } - else{ - qim[1]=2; - qim[2]=1; - } - } - else if(cqi<bqi&&dqi<bqi){ - if(dqi<cqi){ - qim[1]=-1; - qim[2]=-2; - } - else{ - qim[1]=-2; - qim[2]=-1; - } - } - else{ - if(cqi<bqi)qim[1]=-1; - else qim[1]=1; - if(dqi<bqi)qim[2]=-1; - else qim[2]=1; - } - } - c=cairo_create(cs); - frags=_dec->state.frags; - frag_mvs=_dec->state.frag_mvs; - mb_modes=_dec->state.mb_modes; - mb_maps=_dec->state.mb_maps; - nmbs=_dec->state.nmbs; - row2=0; - col2=0; - for(mbi=0;mbi<nmbs;mbi++){ - float x; - float y; - int bi; - y=h-(row2+((col2+1>>1)&1))*16-16; - x=(col2>>1)*16; - cairo_set_line_width(c,1.); - /*Keyframe (all intra) red box.*/ - if(_dec->state.frame_type==OC_INTRA_FRAME){ - if(_dec->telemetry_mbmode&0x02){ - cairo_set_source_rgba(c,1.,0,0,.5); - cairo_rectangle(c,x+2.5,y+2.5,11,11); - cairo_stroke_preserve(c); - cairo_set_source_rgba(c,1.,0,0,.25); - cairo_fill(c); - } - } - else{ - const signed char *frag_mv; - ptrdiff_t fragi; - for(bi=0;bi<4;bi++){ - fragi=mb_maps[mbi][0][bi]; - if(fragi>=0&&frags[fragi].coded){ - frag_mv=frag_mvs[fragi]; - break; - } - } - if(bi<4){ - switch(mb_modes[mbi]){ - case OC_MODE_INTRA:{ - if(_dec->telemetry_mbmode&0x02){ - cairo_set_source_rgba(c,1.,0,0,.5); - cairo_rectangle(c,x+2.5,y+2.5,11,11); - cairo_stroke_preserve(c); - cairo_set_source_rgba(c,1.,0,0,.25); - cairo_fill(c); - } - }break; - case OC_MODE_INTER_NOMV:{ - if(_dec->telemetry_mbmode&0x01){ - cairo_set_source_rgba(c,0,0,1.,.5); - cairo_rectangle(c,x+2.5,y+2.5,11,11); - cairo_stroke_preserve(c); - cairo_set_source_rgba(c,0,0,1.,.25); - cairo_fill(c); - } - }break; - case OC_MODE_INTER_MV:{ - if(_dec->telemetry_mbmode&0x04){ - cairo_rectangle(c,x+2.5,y+2.5,11,11); - cairo_set_source_rgba(c,0,1.,0,.5); - cairo_stroke(c); - } - if(_dec->telemetry_mv&0x04){ - cairo_move_to(c,x+8+frag_mv[0],y+8-frag_mv[1]); - cairo_set_source_rgba(c,1.,1.,1.,.9); - cairo_set_line_width(c,3.); - cairo_line_to(c,x+8+frag_mv[0]*.66,y+8-frag_mv[1]*.66); - cairo_stroke_preserve(c); - cairo_set_line_width(c,2.); - cairo_line_to(c,x+8+frag_mv[0]*.33,y+8-frag_mv[1]*.33); - cairo_stroke_preserve(c); - cairo_set_line_width(c,1.); - cairo_line_to(c,x+8,y+8); - cairo_stroke(c); - } - }break; - case OC_MODE_INTER_MV_LAST:{ - if(_dec->telemetry_mbmode&0x08){ - cairo_rectangle(c,x+2.5,y+2.5,11,11); - cairo_set_source_rgba(c,0,1.,0,.5); - cairo_move_to(c,x+13.5,y+2.5); - cairo_line_to(c,x+2.5,y+8); - cairo_line_to(c,x+13.5,y+13.5); - cairo_stroke(c); - } - if(_dec->telemetry_mv&0x08){ - cairo_move_to(c,x+8+frag_mv[0],y+8-frag_mv[1]); - cairo_set_source_rgba(c,1.,1.,1.,.9); - cairo_set_line_width(c,3.); - cairo_line_to(c,x+8+frag_mv[0]*.66,y+8-frag_mv[1]*.66); - cairo_stroke_preserve(c); - cairo_set_line_width(c,2.); - cairo_line_to(c,x+8+frag_mv[0]*.33,y+8-frag_mv[1]*.33); - cairo_stroke_preserve(c); - cairo_set_line_width(c,1.); - cairo_line_to(c,x+8,y+8); - cairo_stroke(c); - } - }break; - case OC_MODE_INTER_MV_LAST2:{ - if(_dec->telemetry_mbmode&0x10){ - cairo_rectangle(c,x+2.5,y+2.5,11,11); - cairo_set_source_rgba(c,0,1.,0,.5); - cairo_move_to(c,x+8,y+2.5); - cairo_line_to(c,x+2.5,y+8); - cairo_line_to(c,x+8,y+13.5); - cairo_move_to(c,x+13.5,y+2.5); - cairo_line_to(c,x+8,y+8); - cairo_line_to(c,x+13.5,y+13.5); - cairo_stroke(c); - } - if(_dec->telemetry_mv&0x10){ - cairo_move_to(c,x+8+frag_mv[0],y+8-frag_mv[1]); - cairo_set_source_rgba(c,1.,1.,1.,.9); - cairo_set_line_width(c,3.); - cairo_line_to(c,x+8+frag_mv[0]*.66,y+8-frag_mv[1]*.66); - cairo_stroke_preserve(c); - cairo_set_line_width(c,2.); - cairo_line_to(c,x+8+frag_mv[0]*.33,y+8-frag_mv[1]*.33); - cairo_stroke_preserve(c); - cairo_set_line_width(c,1.); - cairo_line_to(c,x+8,y+8); - cairo_stroke(c); - } - }break; - case OC_MODE_GOLDEN_NOMV:{ - if(_dec->telemetry_mbmode&0x20){ - cairo_set_source_rgba(c,1.,1.,0,.5); - cairo_rectangle(c,x+2.5,y+2.5,11,11); - cairo_stroke_preserve(c); - cairo_set_source_rgba(c,1.,1.,0,.25); - cairo_fill(c); - } - }break; - case OC_MODE_GOLDEN_MV:{ - if(_dec->telemetry_mbmode&0x40){ - cairo_rectangle(c,x+2.5,y+2.5,11,11); - cairo_set_source_rgba(c,1.,1.,0,.5); - cairo_stroke(c); - } - if(_dec->telemetry_mv&0x40){ - cairo_move_to(c,x+8+frag_mv[0],y+8-frag_mv[1]); - cairo_set_source_rgba(c,1.,1.,1.,.9); - cairo_set_line_width(c,3.); - cairo_line_to(c,x+8+frag_mv[0]*.66,y+8-frag_mv[1]*.66); - cairo_stroke_preserve(c); - cairo_set_line_width(c,2.); - cairo_line_to(c,x+8+frag_mv[0]*.33,y+8-frag_mv[1]*.33); - cairo_stroke_preserve(c); - cairo_set_line_width(c,1.); - cairo_line_to(c,x+8,y+8); - cairo_stroke(c); - } - }break; - case OC_MODE_INTER_MV_FOUR:{ - if(_dec->telemetry_mbmode&0x80){ - cairo_rectangle(c,x+2.5,y+2.5,4,4); - cairo_rectangle(c,x+9.5,y+2.5,4,4); - cairo_rectangle(c,x+2.5,y+9.5,4,4); - cairo_rectangle(c,x+9.5,y+9.5,4,4); - cairo_set_source_rgba(c,0,1.,0,.5); - cairo_stroke(c); - } - /*4mv is odd, coded in raster order.*/ - fragi=mb_maps[mbi][0][0]; - if(frags[fragi].coded&&_dec->telemetry_mv&0x80){ - frag_mv=frag_mvs[fragi]; - cairo_move_to(c,x+4+frag_mv[0],y+12-frag_mv[1]); - cairo_set_source_rgba(c,1.,1.,1.,.9); - cairo_set_line_width(c,3.); - cairo_line_to(c,x+4+frag_mv[0]*.66,y+12-frag_mv[1]*.66); - cairo_stroke_preserve(c); - cairo_set_line_width(c,2.); - cairo_line_to(c,x+4+frag_mv[0]*.33,y+12-frag_mv[1]*.33); - cairo_stroke_preserve(c); - cairo_set_line_width(c,1.); - cairo_line_to(c,x+4,y+12); - cairo_stroke(c); - } - fragi=mb_maps[mbi][0][1]; - if(frags[fragi].coded&&_dec->telemetry_mv&0x80){ - frag_mv=frag_mvs[fragi]; - cairo_move_to(c,x+12+frag_mv[0],y+12-frag_mv[1]); - cairo_set_source_rgba(c,1.,1.,1.,.9); - cairo_set_line_width(c,3.); - cairo_line_to(c,x+12+frag_mv[0]*.66,y+12-frag_mv[1]*.66); - cairo_stroke_preserve(c); - cairo_set_line_width(c,2.); - cairo_line_to(c,x+12+frag_mv[0]*.33,y+12-frag_mv[1]*.33); - cairo_stroke_preserve(c); - cairo_set_line_width(c,1.); - cairo_line_to(c,x+12,y+12); - cairo_stroke(c); - } - fragi=mb_maps[mbi][0][2]; - if(frags[fragi].coded&&_dec->telemetry_mv&0x80){ - frag_mv=frag_mvs[fragi]; - cairo_move_to(c,x+4+frag_mv[0],y+4-frag_mv[1]); - cairo_set_source_rgba(c,1.,1.,1.,.9); - cairo_set_line_width(c,3.); - cairo_line_to(c,x+4+frag_mv[0]*.66,y+4-frag_mv[1]*.66); - cairo_stroke_preserve(c); - cairo_set_line_width(c,2.); - cairo_line_to(c,x+4+frag_mv[0]*.33,y+4-frag_mv[1]*.33); - cairo_stroke_preserve(c); - cairo_set_line_width(c,1.); - cairo_line_to(c,x+4,y+4); - cairo_stroke(c); - } - fragi=mb_maps[mbi][0][3]; - if(frags[fragi].coded&&_dec->telemetry_mv&0x80){ - frag_mv=frag_mvs[fragi]; - cairo_move_to(c,x+12+frag_mv[0],y+4-frag_mv[1]); - cairo_set_source_rgba(c,1.,1.,1.,.9); - cairo_set_line_width(c,3.); - cairo_line_to(c,x+12+frag_mv[0]*.66,y+4-frag_mv[1]*.66); - cairo_stroke_preserve(c); - cairo_set_line_width(c,2.); - cairo_line_to(c,x+12+frag_mv[0]*.33,y+4-frag_mv[1]*.33); - cairo_stroke_preserve(c); - cairo_set_line_width(c,1.); - cairo_line_to(c,x+12,y+4); - cairo_stroke(c); - } - }break; - } - } - } - /*qii illustration.*/ - if(_dec->telemetry_qi&0x2){ - cairo_set_line_cap(c,CAIRO_LINE_CAP_SQUARE); - for(bi=0;bi<4;bi++){ - ptrdiff_t fragi; - int qiv; - int xp; - int yp; - xp=x+(bi&1)*8; - yp=y+8-(bi&2)*4; - fragi=mb_maps[mbi][0][bi]; - if(fragi>=0&&frags[fragi].coded){ - qiv=qim[frags[fragi].qii]; - cairo_set_line_width(c,3.); - cairo_set_source_rgba(c,0.,0.,0.,.5); - switch(qiv){ - /*Double plus:*/ - case 2:{ - if((bi&1)^((bi&2)>>1)){ - cairo_move_to(c,xp+2.5,yp+1.5); - cairo_line_to(c,xp+2.5,yp+3.5); - cairo_move_to(c,xp+1.5,yp+2.5); - cairo_line_to(c,xp+3.5,yp+2.5); - cairo_move_to(c,xp+5.5,yp+4.5); - cairo_line_to(c,xp+5.5,yp+6.5); - cairo_move_to(c,xp+4.5,yp+5.5); - cairo_line_to(c,xp+6.5,yp+5.5); - cairo_stroke_preserve(c); - cairo_set_source_rgba(c,0.,1.,1.,1.); - } - else{ - cairo_move_to(c,xp+5.5,yp+1.5); - cairo_line_to(c,xp+5.5,yp+3.5); - cairo_move_to(c,xp+4.5,yp+2.5); - cairo_line_to(c,xp+6.5,yp+2.5); - cairo_move_to(c,xp+2.5,yp+4.5); - cairo_line_to(c,xp+2.5,yp+6.5); - cairo_move_to(c,xp+1.5,yp+5.5); - cairo_line_to(c,xp+3.5,yp+5.5); - cairo_stroke_preserve(c); - cairo_set_source_rgba(c,0.,1.,1.,1.); - } - }break; - /*Double minus:*/ - case -2:{ - cairo_move_to(c,xp+2.5,yp+2.5); - cairo_line_to(c,xp+5.5,yp+2.5); - cairo_move_to(c,xp+2.5,yp+5.5); - cairo_line_to(c,xp+5.5,yp+5.5); - cairo_stroke_preserve(c); - cairo_set_source_rgba(c,1.,1.,1.,1.); - }break; - /*Plus:*/ - case 1:{ - if(bi&2==0)yp-=2; - if(bi&1==0)xp-=2; - cairo_move_to(c,xp+4.5,yp+2.5); - cairo_line_to(c,xp+4.5,yp+6.5); - cairo_move_to(c,xp+2.5,yp+4.5); - cairo_line_to(c,xp+6.5,yp+4.5); - cairo_stroke_preserve(c); - cairo_set_source_rgba(c,.1,1.,.3,1.); - break; - } - /*Fall through.*/ - /*Minus:*/ - case -1:{ - cairo_move_to(c,xp+2.5,yp+4.5); - cairo_line_to(c,xp+6.5,yp+4.5); - cairo_stroke_preserve(c); - cairo_set_source_rgba(c,1.,.3,.1,1.); - }break; - default:continue; - } - cairo_set_line_width(c,1.); - cairo_stroke(c); - } - } - } - col2++; - if((col2>>1)>=_dec->state.nhmbs){ - col2=0; - row2+=2; - } - } - /*Bit usage indicator[s]:*/ - if(_dec->telemetry_bits){ - int widths[6]; - int fpsn; - int fpsd; - int mult; - int fullw; - int padw; - int i; - fpsn=_dec->state.info.fps_numerator; - fpsd=_dec->state.info.fps_denominator; - mult=(_dec->telemetry_bits>=0xFF?1:_dec->telemetry_bits); - fullw=250.f*h*fpsd*mult/fpsn; - padw=w-24; - /*Header and coded block bits.*/ - if(_dec->telemetry_frame_bytes<0|| - _dec->telemetry_frame_bytes==OC_LOTS_OF_BITS){ - _dec->telemetry_frame_bytes=0; - } - if(_dec->telemetry_coding_bytes<0|| - _dec->telemetry_coding_bytes>_dec->telemetry_frame_bytes){ - _dec->telemetry_coding_bytes=0; - } - if(_dec->telemetry_mode_bytes<0|| - _dec->telemetry_mode_bytes>_dec->telemetry_frame_bytes){ - _dec->telemetry_mode_bytes=0; - } - if(_dec->telemetry_mv_bytes<0|| - _dec->telemetry_mv_bytes>_dec->telemetry_frame_bytes){ - _dec->telemetry_mv_bytes=0; - } - if(_dec->telemetry_qi_bytes<0|| - _dec->telemetry_qi_bytes>_dec->telemetry_frame_bytes){ - _dec->telemetry_qi_bytes=0; - } - if(_dec->telemetry_dc_bytes<0|| - _dec->telemetry_dc_bytes>_dec->telemetry_frame_bytes){ - _dec->telemetry_dc_bytes=0; - } - widths[0]=padw*(_dec->telemetry_frame_bytes-_dec->telemetry_coding_bytes)/fullw; - widths[1]=padw*(_dec->telemetry_coding_bytes-_dec->telemetry_mode_bytes)/fullw; - widths[2]=padw*(_dec->telemetry_mode_bytes-_dec->telemetry_mv_bytes)/fullw; - widths[3]=padw*(_dec->telemetry_mv_bytes-_dec->telemetry_qi_bytes)/fullw; - widths[4]=padw*(_dec->telemetry_qi_bytes-_dec->telemetry_dc_bytes)/fullw; - widths[5]=padw*(_dec->telemetry_dc_bytes)/fullw; - for(i=0;i<6;i++)if(widths[i]>w)widths[i]=w; - cairo_set_source_rgba(c,.0,.0,.0,.6); - cairo_rectangle(c,10,h-33,widths[0]+1,5); - cairo_rectangle(c,10,h-29,widths[1]+1,5); - cairo_rectangle(c,10,h-25,widths[2]+1,5); - cairo_rectangle(c,10,h-21,widths[3]+1,5); - cairo_rectangle(c,10,h-17,widths[4]+1,5); - cairo_rectangle(c,10,h-13,widths[5]+1,5); - cairo_fill(c); - cairo_set_source_rgb(c,1,0,0); - cairo_rectangle(c,10.5,h-32.5,widths[0],4); - cairo_fill(c); - cairo_set_source_rgb(c,0,1,0); - cairo_rectangle(c,10.5,h-28.5,widths[1],4); - cairo_fill(c); - cairo_set_source_rgb(c,0,0,1); - cairo_rectangle(c,10.5,h-24.5,widths[2],4); - cairo_fill(c); - cairo_set_source_rgb(c,.6,.4,.0); - cairo_rectangle(c,10.5,h-20.5,widths[3],4); - cairo_fill(c); - cairo_set_source_rgb(c,.3,.3,.3); - cairo_rectangle(c,10.5,h-16.5,widths[4],4); - cairo_fill(c); - cairo_set_source_rgb(c,.5,.5,.8); - cairo_rectangle(c,10.5,h-12.5,widths[5],4); - cairo_fill(c); - } - /*Master qi indicator[s]:*/ - if(_dec->telemetry_qi&0x1){ - cairo_text_extents_t extents; - char buffer[10]; - int p; - int y; - p=0; - y=h-7.5; - if(_dec->state.qis[0]>=10)buffer[p++]=48+_dec->state.qis[0]/10; - buffer[p++]=48+_dec->state.qis[0]%10; - if(_dec->state.nqis>=2){ - buffer[p++]=' '; - if(_dec->state.qis[1]>=10)buffer[p++]=48+_dec->state.qis[1]/10; - buffer[p++]=48+_dec->state.qis[1]%10; - } - if(_dec->state.nqis==3){ - buffer[p++]=' '; - if(_dec->state.qis[2]>=10)buffer[p++]=48+_dec->state.qis[2]/10; - buffer[p++]=48+_dec->state.qis[2]%10; - } - buffer[p++]='\0'; - cairo_select_font_face(c,"sans", - CAIRO_FONT_SLANT_NORMAL,CAIRO_FONT_WEIGHT_BOLD); - cairo_set_font_size(c,18); - cairo_text_extents(c,buffer,&extents); - cairo_set_source_rgb(c,1,1,1); - cairo_move_to(c,w-extents.x_advance-10,y); - cairo_show_text(c,buffer); - cairo_set_source_rgb(c,0,0,0); - cairo_move_to(c,w-extents.x_advance-10,y); - cairo_text_path(c,buffer); - cairo_set_line_width(c,.8); - cairo_set_line_join(c,CAIRO_LINE_JOIN_ROUND); - cairo_stroke(c); - } - cairo_destroy(c); - } - /*Out of the Cairo plane into the telemetry YUV buffer.*/ - _ycbcr[0].data=_dec->telemetry_frame_data; - _ycbcr[0].stride=_ycbcr[0].width; - _ycbcr[1].data=_ycbcr[0].data+h*_ycbcr[0].stride; - _ycbcr[1].stride=_ycbcr[1].width; - _ycbcr[2].data=_ycbcr[1].data+(h>>vdec)*_ycbcr[1].stride; - _ycbcr[2].stride=_ycbcr[2].width; - y_row=_ycbcr[0].data; - u_row=_ycbcr[1].data; - v_row=_ycbcr[2].data; - rgb_row=data; - /*This is one of the few places it's worth handling chroma on a - case-by-case basis.*/ - switch(_dec->state.info.pixel_fmt){ - case TH_PF_420:{ - for(y=0;y<h;y+=2){ - unsigned char *y_row2; - unsigned char *rgb_row2; - y_row2=y_row+_ycbcr[0].stride; - rgb_row2=rgb_row+cstride; - for(x=0;x<w;x+=2){ - int y; - int u; - int v; - y=(65481*rgb_row[4*x+2]+128553*rgb_row[4*x+1] - +24966*rgb_row[4*x+0]+4207500)/255000; - y_row[x]=OC_CLAMP255(y); - y=(65481*rgb_row[4*x+6]+128553*rgb_row[4*x+5] - +24966*rgb_row[4*x+4]+4207500)/255000; - y_row[x+1]=OC_CLAMP255(y); - y=(65481*rgb_row2[4*x+2]+128553*rgb_row2[4*x+1] - +24966*rgb_row2[4*x+0]+4207500)/255000; - y_row2[x]=OC_CLAMP255(y); - y=(65481*rgb_row2[4*x+6]+128553*rgb_row2[4*x+5] - +24966*rgb_row2[4*x+4]+4207500)/255000; - y_row2[x+1]=OC_CLAMP255(y); - u=(-8372*(rgb_row[4*x+2]+rgb_row[4*x+6] - +rgb_row2[4*x+2]+rgb_row2[4*x+6]) - -16436*(rgb_row[4*x+1]+rgb_row[4*x+5] - +rgb_row2[4*x+1]+rgb_row2[4*x+5]) - +24808*(rgb_row[4*x+0]+rgb_row[4*x+4] - +rgb_row2[4*x+0]+rgb_row2[4*x+4])+29032005)/225930; - v=(39256*(rgb_row[4*x+2]+rgb_row[4*x+6] - +rgb_row2[4*x+2]+rgb_row2[4*x+6]) - -32872*(rgb_row[4*x+1]+rgb_row[4*x+5] - +rgb_row2[4*x+1]+rgb_row2[4*x+5]) - -6384*(rgb_row[4*x+0]+rgb_row[4*x+4] - +rgb_row2[4*x+0]+rgb_row2[4*x+4])+45940035)/357510; - u_row[x>>1]=OC_CLAMP255(u); - v_row[x>>1]=OC_CLAMP255(v); - } - y_row+=_ycbcr[0].stride<<1; - u_row+=_ycbcr[1].stride; - v_row+=_ycbcr[2].stride; - rgb_row+=cstride<<1; - } - }break; - case TH_PF_422:{ - for(y=0;y<h;y++){ - for(x=0;x<w;x+=2){ - int y; - int u; - int v; - y=(65481*rgb_row[4*x+2]+128553*rgb_row[4*x+1] - +24966*rgb_row[4*x+0]+4207500)/255000; - y_row[x]=OC_CLAMP255(y); - y=(65481*rgb_row[4*x+6]+128553*rgb_row[4*x+5] - +24966*rgb_row[4*x+4]+4207500)/255000; - y_row[x+1]=OC_CLAMP255(y); - u=(-16744*(rgb_row[4*x+2]+rgb_row[4*x+6]) - -32872*(rgb_row[4*x+1]+rgb_row[4*x+5]) - +49616*(rgb_row[4*x+0]+rgb_row[4*x+4])+29032005)/225930; - v=(78512*(rgb_row[4*x+2]+rgb_row[4*x+6]) - -65744*(rgb_row[4*x+1]+rgb_row[4*x+5]) - -12768*(rgb_row[4*x+0]+rgb_row[4*x+4])+45940035)/357510; - u_row[x>>1]=OC_CLAMP255(u); - v_row[x>>1]=OC_CLAMP255(v); - } - y_row+=_ycbcr[0].stride; - u_row+=_ycbcr[1].stride; - v_row+=_ycbcr[2].stride; - rgb_row+=cstride; - } - }break; - /*case TH_PF_444:*/ - default:{ - for(y=0;y<h;y++){ - for(x=0;x<w;x++){ - int y; - int u; - int v; - y=(65481*rgb_row[4*x+2]+128553*rgb_row[4*x+1] - +24966*rgb_row[4*x+0]+4207500)/255000; - u=(-33488*rgb_row[4*x+2]-65744*rgb_row[4*x+1] - +99232*rgb_row[4*x+0]+29032005)/225930; - v=(157024*rgb_row[4*x+2]-131488*rgb_row[4*x+1] - -25536*rgb_row[4*x+0]+45940035)/357510; - y_row[x]=OC_CLAMP255(y); - u_row[x]=OC_CLAMP255(u); - v_row[x]=OC_CLAMP255(v); - } - y_row+=_ycbcr[0].stride; - u_row+=_ycbcr[1].stride; - v_row+=_ycbcr[2].stride; - rgb_row+=cstride; - } - }break; - } - /*Finished. - Destroy the surface.*/ - cairo_surface_destroy(cs); - } -#endif return 0; } diff --git a/thirdparty/libtheora/dequant.c b/thirdparty/libtheora/dequant.c index e554872d4e..860536f72d 100644 --- a/thirdparty/libtheora/dequant.c +++ b/thirdparty/libtheora/dequant.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: dequant.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ diff --git a/thirdparty/libtheora/dequant.h b/thirdparty/libtheora/dequant.h index ef25838e35..9d6cd6be56 100644 --- a/thirdparty/libtheora/dequant.h +++ b/thirdparty/libtheora/dequant.h @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: dequant.h 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ diff --git a/thirdparty/libtheora/encfrag.c b/thirdparty/libtheora/encfrag.c index bb814c8e4a..0e18111ac7 100644 --- a/thirdparty/libtheora/encfrag.c +++ b/thirdparty/libtheora/encfrag.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: encfrag.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ #include <stdlib.h> @@ -19,11 +19,6 @@ #include "encint.h" -void oc_enc_frag_sub(const oc_enc_ctx *_enc,ogg_int16_t _diff[64], - const unsigned char *_src,const unsigned char *_ref,int _ystride){ - (*_enc->opt_vtable.frag_sub)(_diff,_src,_ref,_ystride); -} - void oc_enc_frag_sub_c(ogg_int16_t _diff[64],const unsigned char *_src, const unsigned char *_ref,int _ystride){ int i; @@ -35,11 +30,6 @@ void oc_enc_frag_sub_c(ogg_int16_t _diff[64],const unsigned char *_src, } } -void oc_enc_frag_sub_128(const oc_enc_ctx *_enc,ogg_int16_t _diff[64], - const unsigned char *_src,int _ystride){ - (*_enc->opt_vtable.frag_sub_128)(_diff,_src,_ystride); -} - void oc_enc_frag_sub_128_c(ogg_int16_t *_diff, const unsigned char *_src,int _ystride){ int i; @@ -50,11 +40,6 @@ void oc_enc_frag_sub_128_c(ogg_int16_t *_diff, } } -unsigned oc_enc_frag_sad(const oc_enc_ctx *_enc,const unsigned char *_x, - const unsigned char *_y,int _ystride){ - return (*_enc->opt_vtable.frag_sad)(_x,_y,_ystride); -} - unsigned oc_enc_frag_sad_c(const unsigned char *_src, const unsigned char *_ref,int _ystride){ unsigned sad; @@ -69,12 +54,6 @@ unsigned oc_enc_frag_sad_c(const unsigned char *_src, return sad; } -unsigned oc_enc_frag_sad_thresh(const oc_enc_ctx *_enc, - const unsigned char *_src,const unsigned char *_ref,int _ystride, - unsigned _thresh){ - return (*_enc->opt_vtable.frag_sad_thresh)(_src,_ref,_ystride,_thresh); -} - unsigned oc_enc_frag_sad_thresh_c(const unsigned char *_src, const unsigned char *_ref,int _ystride,unsigned _thresh){ unsigned sad; @@ -90,13 +69,6 @@ unsigned oc_enc_frag_sad_thresh_c(const unsigned char *_src, return sad; } -unsigned oc_enc_frag_sad2_thresh(const oc_enc_ctx *_enc, - const unsigned char *_src,const unsigned char *_ref1, - const unsigned char *_ref2,int _ystride,unsigned _thresh){ - return (*_enc->opt_vtable.frag_sad2_thresh)(_src,_ref1,_ref2,_ystride, - _thresh); -} - unsigned oc_enc_frag_sad2_thresh_c(const unsigned char *_src, const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, unsigned _thresh){ @@ -114,6 +86,27 @@ unsigned oc_enc_frag_sad2_thresh_c(const unsigned char *_src, return sad; } +unsigned oc_enc_frag_intra_sad_c(const unsigned char *_src, int _ystride){ + const unsigned char *src = _src; + unsigned dc; + unsigned sad; + int i; + dc=0; + for(i=8;i-->0;){ + int j; + for(j=0;j<8;j++)dc+=src[j]; + src+=_ystride; + } + dc=dc+32>>6; + sad=0; + for(i=8;i-->0;){ + int j; + for(j=0;j<8;j++)sad+=abs(_src[j]-dc); + _src+=_ystride; + } + return sad; +} + static void oc_diff_hadamard(ogg_int16_t _buf[64],const unsigned char *_src, const unsigned char *_ref,int _ystride){ int i; @@ -269,19 +262,20 @@ static void oc_intra_hadamard(ogg_int16_t _buf[64],const unsigned char *_src, } } -unsigned oc_hadamard_sad_thresh(const ogg_int16_t _buf[64],unsigned _thresh){ - unsigned sad; - int t0; - int t1; - int t2; - int t3; - int t4; - int t5; - int t6; - int t7; - int r; - int i; - sad=0; +unsigned oc_hadamard_sad(int *_dc,const ogg_int16_t _buf[64]){ + unsigned sad; + int dc; + int t0; + int t1; + int t2; + int t3; + int t4; + int t5; + int t6; + int t7; + int r; + int i; + sad=dc=0; for(i=0;i<8;i++){ /*Hadamard stage 1:*/ t0=_buf[i*8+0]+_buf[i*8+4]; @@ -306,7 +300,7 @@ unsigned oc_hadamard_sad_thresh(const ogg_int16_t _buf[64],unsigned _thresh){ t5+=t7; t7=r-t7; /*Hadamard stage 3:*/ - r=abs(t0+t1); + r=abs(t0+t1)&-(i>0); r+=abs(t0-t1); r+=abs(t2+t3); r+=abs(t2-t3); @@ -315,54 +309,61 @@ unsigned oc_hadamard_sad_thresh(const ogg_int16_t _buf[64],unsigned _thresh){ r+=abs(t6+t7); r+=abs(t6-t7); sad+=r; - if(sad>_thresh)break; } + dc=_buf[0]+_buf[1]+_buf[2]+_buf[3]+_buf[4]+_buf[5]+_buf[6]+_buf[7]; + *_dc=dc; return sad; } -unsigned oc_enc_frag_satd_thresh(const oc_enc_ctx *_enc, - const unsigned char *_src,const unsigned char *_ref,int _ystride, - unsigned _thresh){ - return (*_enc->opt_vtable.frag_satd_thresh)(_src,_ref,_ystride,_thresh); -} - -unsigned oc_enc_frag_satd_thresh_c(const unsigned char *_src, - const unsigned char *_ref,int _ystride,unsigned _thresh){ +unsigned oc_enc_frag_satd_c(int *_dc,const unsigned char *_src, + const unsigned char *_ref,int _ystride){ ogg_int16_t buf[64]; oc_diff_hadamard(buf,_src,_ref,_ystride); - return oc_hadamard_sad_thresh(buf,_thresh); -} - -unsigned oc_enc_frag_satd2_thresh(const oc_enc_ctx *_enc, - const unsigned char *_src,const unsigned char *_ref1, - const unsigned char *_ref2,int _ystride,unsigned _thresh){ - return (*_enc->opt_vtable.frag_satd2_thresh)(_src,_ref1,_ref2,_ystride, - _thresh); + return oc_hadamard_sad(_dc,buf); } -unsigned oc_enc_frag_satd2_thresh_c(const unsigned char *_src, - const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, - unsigned _thresh){ +unsigned oc_enc_frag_satd2_c(int *_dc,const unsigned char *_src, + const unsigned char *_ref1,const unsigned char *_ref2,int _ystride){ ogg_int16_t buf[64]; oc_diff_hadamard2(buf,_src,_ref1,_ref2,_ystride); - return oc_hadamard_sad_thresh(buf,_thresh); + return oc_hadamard_sad(_dc,buf); } -unsigned oc_enc_frag_intra_satd(const oc_enc_ctx *_enc, +unsigned oc_enc_frag_intra_satd_c(int *_dc, const unsigned char *_src,int _ystride){ - return (*_enc->opt_vtable.frag_intra_satd)(_src,_ystride); -} - -unsigned oc_enc_frag_intra_satd_c(const unsigned char *_src,int _ystride){ ogg_int16_t buf[64]; oc_intra_hadamard(buf,_src,_ystride); - return oc_hadamard_sad_thresh(buf,UINT_MAX) - -abs(buf[0]+buf[1]+buf[2]+buf[3]+buf[4]+buf[5]+buf[6]+buf[7]); + return oc_hadamard_sad(_dc,buf); } -void oc_enc_frag_copy2(const oc_enc_ctx *_enc,unsigned char *_dst, - const unsigned char *_src1,const unsigned char *_src2,int _ystride){ - (*_enc->opt_vtable.frag_copy2)(_dst,_src1,_src2,_ystride); +unsigned oc_enc_frag_ssd_c(const unsigned char *_src, + const unsigned char *_ref,int _ystride){ + unsigned ret; + int y; + int x; + ret=0; + for(y=0;y<8;y++){ + for(x=0;x<8;x++)ret+=(_src[x]-_ref[x])*(_src[x]-_ref[x]); + _src+=_ystride; + _ref+=_ystride; + } + return ret; +} + +unsigned oc_enc_frag_border_ssd_c(const unsigned char *_src, + const unsigned char *_ref,int _ystride,ogg_int64_t _mask){ + unsigned ret; + int y; + int x; + ret=0; + for(y=0;y<8;y++){ + for(x=0;x<8;x++,_mask>>=1){ + if(_mask&1)ret+=(_src[x]-_ref[x])*(_src[x]-_ref[x]); + } + _src+=_ystride; + _ref+=_ystride; + } + return ret; } void oc_enc_frag_copy2_c(unsigned char *_dst, @@ -376,13 +377,3 @@ void oc_enc_frag_copy2_c(unsigned char *_dst, _src2+=_ystride; } } - -void oc_enc_frag_recon_intra(const oc_enc_ctx *_enc, - unsigned char *_dst,int _ystride,const ogg_int16_t _residue[64]){ - (*_enc->opt_vtable.frag_recon_intra)(_dst,_ystride,_residue); -} - -void oc_enc_frag_recon_inter(const oc_enc_ctx *_enc,unsigned char *_dst, - const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]){ - (*_enc->opt_vtable.frag_recon_inter)(_dst,_src,_ystride,_residue); -} diff --git a/thirdparty/libtheora/encinfo.c b/thirdparty/libtheora/encinfo.c index 83be1dae72..41db6bad45 100644 --- a/thirdparty/libtheora/encinfo.c +++ b/thirdparty/libtheora/encinfo.c @@ -1,6 +1,6 @@ #include <stdlib.h> #include <string.h> -#include "internal.h" +#include "state.h" #include "enquant.h" #include "huffenc.h" diff --git a/thirdparty/libtheora/encint.h b/thirdparty/libtheora/encint.h index 97897d5a04..d25de4b8f6 100644 --- a/thirdparty/libtheora/encint.h +++ b/thirdparty/libtheora/encint.h @@ -11,17 +11,13 @@ ******************************************************************** function: - last mod: $Id: encint.h 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ #if !defined(_encint_H) # define _encint_H (1) -# if defined(HAVE_CONFIG_H) -# include "config.h" -# endif # include "theora/theoraenc.h" -# include "internal.h" -# include "ocintrin.h" +# include "state.h" # include "mathops.h" # include "enquant.h" # include "huffenc.h" @@ -32,8 +28,13 @@ typedef oc_mv oc_mv2[2]; typedef struct oc_enc_opt_vtable oc_enc_opt_vtable; +typedef struct oc_enc_opt_data oc_enc_opt_data; typedef struct oc_mb_enc_info oc_mb_enc_info; typedef struct oc_mode_scheme_chooser oc_mode_scheme_chooser; +typedef struct oc_fr_state oc_fr_state; +typedef struct oc_qii_state oc_qii_state; +typedef struct oc_enc_pipeline_state oc_enc_pipeline_state; +typedef struct oc_mode_rd oc_mode_rd; typedef struct oc_iir_filter oc_iir_filter; typedef struct oc_frame_metrics oc_frame_metrics; typedef struct oc_rc_state oc_rc_state; @@ -42,6 +43,170 @@ typedef struct oc_token_checkpoint oc_token_checkpoint; +/*Encoder-specific accelerated functions.*/ +# if defined(OC_X86_ASM) +# if defined(_MSC_VER) +# include "x86_vc/x86enc.h" +# else +# include "x86/x86enc.h" +# endif +# endif +# if defined(OC_ARM_ASM) +# include "arm/armenc.h" +# endif + +# if !defined(oc_enc_accel_init) +# define oc_enc_accel_init oc_enc_accel_init_c +# endif +# if defined(OC_ENC_USE_VTABLE) +# if !defined(oc_enc_frag_sub) +# define oc_enc_frag_sub(_enc,_diff,_src,_ref,_ystride) \ + ((*(_enc)->opt_vtable.frag_sub)(_diff,_src,_ref,_ystride)) +# endif +# if !defined(oc_enc_frag_sub_128) +# define oc_enc_frag_sub_128(_enc,_diff,_src,_ystride) \ + ((*(_enc)->opt_vtable.frag_sub_128)(_diff,_src,_ystride)) +# endif +# if !defined(oc_enc_frag_sad) +# define oc_enc_frag_sad(_enc,_src,_ref,_ystride) \ + ((*(_enc)->opt_vtable.frag_sad)(_src,_ref,_ystride)) +# endif +# if !defined(oc_enc_frag_sad_thresh) +# define oc_enc_frag_sad_thresh(_enc,_src,_ref,_ystride,_thresh) \ + ((*(_enc)->opt_vtable.frag_sad_thresh)(_src,_ref,_ystride,_thresh)) +# endif +# if !defined(oc_enc_frag_sad2_thresh) +# define oc_enc_frag_sad2_thresh(_enc,_src,_ref1,_ref2,_ystride,_thresh) \ + ((*(_enc)->opt_vtable.frag_sad2_thresh)(_src,_ref1,_ref2,_ystride,_thresh)) +# endif +# if !defined(oc_enc_frag_intra_sad) +# define oc_enc_frag_intra_sad(_enc,_src,_ystride) \ + ((*(_enc)->opt_vtable.frag_intra_sad)(_src,_ystride)) +# endif +# if !defined(oc_enc_frag_satd) +# define oc_enc_frag_satd(_enc,_dc,_src,_ref,_ystride) \ + ((*(_enc)->opt_vtable.frag_satd)(_dc,_src,_ref,_ystride)) +# endif +# if !defined(oc_enc_frag_satd2) +# define oc_enc_frag_satd2(_enc,_dc,_src,_ref1,_ref2,_ystride) \ + ((*(_enc)->opt_vtable.frag_satd2)(_dc,_src,_ref1,_ref2,_ystride)) +# endif +# if !defined(oc_enc_frag_intra_satd) +# define oc_enc_frag_intra_satd(_enc,_dc,_src,_ystride) \ + ((*(_enc)->opt_vtable.frag_intra_satd)(_dc,_src,_ystride)) +# endif +# if !defined(oc_enc_frag_ssd) +# define oc_enc_frag_ssd(_enc,_src,_ref,_ystride) \ + ((*(_enc)->opt_vtable.frag_ssd)(_src,_ref,_ystride)) +# endif +# if !defined(oc_enc_frag_border_ssd) +# define oc_enc_frag_border_ssd(_enc,_src,_ref,_ystride,_mask) \ + ((*(_enc)->opt_vtable.frag_border_ssd)(_src,_ref,_ystride,_mask)) +# endif +# if !defined(oc_enc_frag_copy2) +# define oc_enc_frag_copy2(_enc,_dst,_src1,_src2,_ystride) \ + ((*(_enc)->opt_vtable.frag_copy2)(_dst,_src1,_src2,_ystride)) +# endif +# if !defined(oc_enc_enquant_table_init) +# define oc_enc_enquant_table_init(_enc,_enquant,_dequant) \ + ((*(_enc)->opt_vtable.enquant_table_init)(_enquant,_dequant)) +# endif +# if !defined(oc_enc_enquant_table_fixup) +# define oc_enc_enquant_table_fixup(_enc,_enquant,_nqis) \ + ((*(_enc)->opt_vtable.enquant_table_fixup)(_enquant,_nqis)) +# endif +# if !defined(oc_enc_quantize) +# define oc_enc_quantize(_enc,_qdct,_dct,_dequant,_enquant) \ + ((*(_enc)->opt_vtable.quantize)(_qdct,_dct,_dequant,_enquant)) +# endif +# if !defined(oc_enc_frag_recon_intra) +# define oc_enc_frag_recon_intra(_enc,_dst,_ystride,_residue) \ + ((*(_enc)->opt_vtable.frag_recon_intra)(_dst,_ystride,_residue)) +# endif +# if !defined(oc_enc_frag_recon_inter) +# define oc_enc_frag_recon_inter(_enc,_dst,_src,_ystride,_residue) \ + ((*(_enc)->opt_vtable.frag_recon_inter)(_dst,_src,_ystride,_residue)) +# endif +# if !defined(oc_enc_fdct8x8) +# define oc_enc_fdct8x8(_enc,_y,_x) \ + ((*(_enc)->opt_vtable.fdct8x8)(_y,_x)) +# endif +# else +# if !defined(oc_enc_frag_sub) +# define oc_enc_frag_sub(_enc,_diff,_src,_ref,_ystride) \ + oc_enc_frag_sub_c(_diff,_src,_ref,_ystride) +# endif +# if !defined(oc_enc_frag_sub_128) +# define oc_enc_frag_sub_128(_enc,_diff,_src,_ystride) \ + oc_enc_frag_sub_128_c(_diff,_src,_ystride) +# endif +# if !defined(oc_enc_frag_sad) +# define oc_enc_frag_sad(_enc,_src,_ref,_ystride) \ + oc_enc_frag_sad_c(_src,_ref,_ystride) +# endif +# if !defined(oc_enc_frag_sad_thresh) +# define oc_enc_frag_sad_thresh(_enc,_src,_ref,_ystride,_thresh) \ + oc_enc_frag_sad_thresh_c(_src,_ref,_ystride,_thresh) +# endif +# if !defined(oc_enc_frag_sad2_thresh) +# define oc_enc_frag_sad2_thresh(_enc,_src,_ref1,_ref2,_ystride,_thresh) \ + oc_enc_frag_sad2_thresh_c(_src,_ref1,_ref2,_ystride,_thresh) +# endif +# if !defined(oc_enc_frag_intra_sad) +# define oc_enc_frag_intra_sad(_enc,_src,_ystride) \ + oc_enc_frag_intra_sad_c(_src,_ystride) +# endif +# if !defined(oc_enc_frag_satd) +# define oc_enc_frag_satd(_enc,_dc,_src,_ref,_ystride) \ + oc_enc_frag_satd_c(_dc,_src,_ref,_ystride) +# endif +# if !defined(oc_enc_frag_satd2) +# define oc_enc_frag_satd2(_enc,_dc,_src,_ref1,_ref2,_ystride) \ + oc_enc_frag_satd2_c(_dc,_src,_ref1,_ref2,_ystride) +# endif +# if !defined(oc_enc_frag_intra_satd) +# define oc_enc_frag_intra_satd(_enc,_dc,_src,_ystride) \ + oc_enc_frag_intra_satd_c(_dc,_src,_ystride) +# endif +# if !defined(oc_enc_frag_ssd) +# define oc_enc_frag_ssd(_enc,_src,_ref,_ystride) \ + oc_enc_frag_ssd_c(_src,_ref,_ystride) +# endif +# if !defined(oc_enc_frag_border_ssd) +# define oc_enc_frag_border_ssd(_enc,_src,_ref,_ystride,_mask) \ + oc_enc_frag_border_ssd_c(_src,_ref,_ystride,_mask) +# endif +# if !defined(oc_enc_frag_copy2) +# define oc_enc_frag_copy2(_enc,_dst,_src1,_src2,_ystride) \ + oc_enc_frag_copy2_c(_dst,_src1,_src2,_ystride) +# endif +# if !defined(oc_enc_enquant_table_init) +# define oc_enc_enquant_table_init(_enc,_enquant,_dequant) \ + oc_enc_enquant_table_init_c(_enquant,_dequant) +# endif +# if !defined(oc_enc_enquant_table_fixup) +# define oc_enc_enquant_table_fixup(_enc,_enquant,_nqis) \ + oc_enc_enquant_table_fixup_c(_enquant,_nqis) +# endif +# if !defined(oc_enc_quantize) +# define oc_enc_quantize(_enc,_qdct,_dct,_dequant,_enquant) \ + oc_enc_quantize_c(_qdct,_dct,_dequant,_enquant) +# endif +# if !defined(oc_enc_frag_recon_intra) +# define oc_enc_frag_recon_intra(_enc,_dst,_ystride,_residue) \ + oc_frag_recon_intra_c(_dst,_ystride,_residue) +# endif +# if !defined(oc_enc_frag_recon_inter) +# define oc_enc_frag_recon_inter(_enc,_dst,_src,_ystride,_residue) \ + oc_frag_recon_inter_c(_dst,_src,_ystride,_residue) +# endif +# if !defined(oc_enc_fdct8x8) +# define oc_enc_fdct8x8(_enc,_y,_x) oc_enc_fdct8x8_c(_y,_x) +# endif +# endif + + + /*Constants for the packet-out state machine specific to the encoder.*/ /*Next packet to emit: Data packet, but none are ready yet.*/ @@ -50,13 +215,61 @@ typedef struct oc_token_checkpoint oc_token_checkpoint; #define OC_PACKET_READY (1) /*All features enabled.*/ -#define OC_SP_LEVEL_SLOW (0) +#define OC_SP_LEVEL_SLOW (0) /*Enable early skip.*/ -#define OC_SP_LEVEL_EARLY_SKIP (1) +#define OC_SP_LEVEL_EARLY_SKIP (1) +/*Use analysis shortcuts, single quantizer, and faster tokenization.*/ +#define OC_SP_LEVEL_FAST_ANALYSIS (2) +/*Use SAD instead of SATD*/ +#define OC_SP_LEVEL_NOSATD (3) /*Disable motion compensation.*/ -#define OC_SP_LEVEL_NOMC (2) +#define OC_SP_LEVEL_NOMC (4) /*Maximum valid speed level.*/ -#define OC_SP_LEVEL_MAX (2) +#define OC_SP_LEVEL_MAX (4) + + +/*The number of extra bits of precision at which to store rate metrics.*/ +# define OC_BIT_SCALE (6) +/*The number of extra bits of precision at which to store RMSE metrics. + This must be at least half OC_BIT_SCALE (rounded up).*/ +# define OC_RMSE_SCALE (5) +/*The number of quantizer bins to partition statistics into.*/ +# define OC_LOGQ_BINS (8) +/*The number of SAD/SATD bins to partition statistics into.*/ +# define OC_COMP_BINS (24) +/*The number of bits of precision to drop from SAD and SATD scores + to assign them to a bin.*/ +# define OC_SAD_SHIFT (6) +# define OC_SATD_SHIFT (9) + +/*Masking is applied by scaling the D used in R-D optimization (via rd_scale) + or the lambda parameter (via rd_iscale). + These are only equivalent within a single block; when more than one block is + being considered, the former is the interpretation used.*/ + +/*This must be at least 4 for OC_RD_SKIP_SCALE() to work below.*/ +# define OC_RD_SCALE_BITS (12-OC_BIT_SCALE) +# define OC_RD_ISCALE_BITS (11) + +/*This macro is applied to _ssd values with just 4 bits of headroom + ((15-OC_RMSE_SCALE)*2+OC_BIT_SCALE+2); since we want to allow rd_scales as + large as 16, and need additional fractional bits, our only recourse that + doesn't lose precision on blocks with very small SSDs is to use a wider + multiply.*/ +# if LONG_MAX>2147483647 +# define OC_RD_SCALE(_ssd,_rd_scale) \ + ((unsigned)((unsigned long)(_ssd)*(_rd_scale) \ + +((1<<OC_RD_SCALE_BITS)>>1)>>OC_RD_SCALE_BITS)) +# else +# define OC_RD_SCALE(_ssd,_rd_scale) \ + (((_ssd)>>OC_RD_SCALE_BITS)*(_rd_scale) \ + +(((_ssd)&(1<<OC_RD_SCALE_BITS)-1)*(_rd_scale) \ + +((1<<OC_RD_SCALE_BITS)>>1)>>OC_RD_SCALE_BITS)) +# endif +# define OC_RD_SKIP_SCALE(_ssd,_rd_scale) \ + ((_ssd)*(_rd_scale)+((1<<OC_RD_SCALE_BITS-4)>>1)>>OC_RD_SCALE_BITS-4) +# define OC_RD_ISCALE(_lambda,_rd_iscale) \ + ((_lambda)*(_rd_iscale)+((1<<OC_RD_ISCALE_BITS)>>1)>>OC_RD_ISCALE_BITS) /*The bits used for each of the MB mode codebooks.*/ @@ -78,6 +291,10 @@ extern const unsigned char OC_BLOCK_RUN_CODE_NBITS[30]; /*Encoder specific functions with accelerated variants.*/ struct oc_enc_opt_vtable{ + void (*frag_sub)(ogg_int16_t _diff[64],const unsigned char *_src, + const unsigned char *_ref,int _ystride); + void (*frag_sub_128)(ogg_int16_t _diff[64], + const unsigned char *_src,int _ystride); unsigned (*frag_sad)(const unsigned char *_src, const unsigned char *_ref,int _ystride); unsigned (*frag_sad_thresh)(const unsigned char *_src, @@ -85,18 +302,23 @@ struct oc_enc_opt_vtable{ unsigned (*frag_sad2_thresh)(const unsigned char *_src, const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, unsigned _thresh); - unsigned (*frag_satd_thresh)(const unsigned char *_src, - const unsigned char *_ref,int _ystride,unsigned _thresh); - unsigned (*frag_satd2_thresh)(const unsigned char *_src, - const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, - unsigned _thresh); - unsigned (*frag_intra_satd)(const unsigned char *_src,int _ystride); - void (*frag_sub)(ogg_int16_t _diff[64],const unsigned char *_src, + unsigned (*frag_intra_sad)(const unsigned char *_src,int _ystride); + unsigned (*frag_satd)(int *_dc,const unsigned char *_src, const unsigned char *_ref,int _ystride); - void (*frag_sub_128)(ogg_int16_t _diff[64], - const unsigned char *_src,int _ystride); + unsigned (*frag_satd2)(int *_dc,const unsigned char *_src, + const unsigned char *_ref1,const unsigned char *_ref2,int _ystride); + unsigned (*frag_intra_satd)(int *_dc,const unsigned char *_src,int _ystride); + unsigned (*frag_ssd)(const unsigned char *_src, + const unsigned char *_ref,int _ystride); + unsigned (*frag_border_ssd)(const unsigned char *_src, + const unsigned char *_ref,int _ystride,ogg_int64_t _mask); void (*frag_copy2)(unsigned char *_dst, const unsigned char *_src1,const unsigned char *_src2,int _ystride); + void (*enquant_table_init)(void *_enquant, + const ogg_uint16_t _dequant[64]); + void (*enquant_table_fixup)(void *_enquant[3][3][2],int _nqis); + int (*quantize)(ogg_int16_t _qdct[64],const ogg_int16_t _dct[64], + const ogg_uint16_t _dequant[64],const void *_enquant); void (*frag_recon_intra)(unsigned char *_dst,int _ystride, const ogg_int16_t _residue[64]); void (*frag_recon_inter)(unsigned char *_dst, @@ -105,7 +327,19 @@ struct oc_enc_opt_vtable{ }; -void oc_enc_vtable_init(oc_enc_ctx *_enc); +/*Encoder specific data that varies according to which variants of the above + functions are used.*/ +struct oc_enc_opt_data{ + /*The size of a single quantizer table. + This must be a multiple of enquant_table_alignment.*/ + size_t enquant_table_size; + /*The alignment required for the quantizer tables. + This must be a positive power of two.*/ + int enquant_table_alignment; +}; + + +void oc_enc_accel_init(oc_enc_ctx *_enc); @@ -158,7 +392,7 @@ struct oc_mode_scheme_chooser{ corresponds to the ranks above.*/ unsigned char scheme0_list[OC_NMODES]; /*The number of times each mode has been chosen so far.*/ - int mode_counts[OC_NMODES]; + unsigned mode_counts[OC_NMODES]; /*The list of mode coding schemes, sorted in ascending order of bit cost.*/ unsigned char scheme_list[8]; /*The number of bits used by each mode coding scheme.*/ @@ -170,6 +404,106 @@ void oc_mode_scheme_chooser_init(oc_mode_scheme_chooser *_chooser); +/*State to track coded block flags and their bit cost. + We use opportunity cost to measure the bits required to code or skip the next + block, using the cheaper of the cost to code it fully or partially, so long + as both are possible.*/ +struct oc_fr_state{ + /*The number of bits required for the coded block flags so far this frame.*/ + ptrdiff_t bits; + /*The length of the current run for the partial super block flag, not + including the current super block.*/ + unsigned sb_partial_count:16; + /*The length of the current run for the full super block flag, not + including the current super block.*/ + unsigned sb_full_count:16; + /*The length of the coded block flag run when the current super block + started.*/ + unsigned b_coded_count_prev:6; + /*The coded block flag when the current super block started.*/ + signed int b_coded_prev:2; + /*The length of the current coded block flag run.*/ + unsigned b_coded_count:6; + /*The current coded block flag.*/ + signed int b_coded:2; + /*The number of blocks processed in the current super block.*/ + unsigned b_count:5; + /*Whether or not it is cheaper to code the current super block partially, + even if it could still be coded fully.*/ + unsigned sb_prefer_partial:1; + /*Whether the last super block was coded partially.*/ + signed int sb_partial:2; + /*The number of bits required for the flags for the current super block.*/ + unsigned sb_bits:6; + /*Whether the last non-partial super block was coded fully.*/ + signed int sb_full:2; +}; + + + +struct oc_qii_state{ + ptrdiff_t bits; + unsigned qi01_count:14; + signed int qi01:2; + unsigned qi12_count:14; + signed int qi12:2; +}; + + + +/*Temporary encoder state for the analysis pipeline.*/ +struct oc_enc_pipeline_state{ + /*DCT coefficient storage. + This is kept off the stack because a) gcc can't align things on the stack + reliably on ARM, and b) it avoids (unintentional) data hazards between + ARM and NEON code.*/ + OC_ALIGN16(ogg_int16_t dct_data[64*3]); + OC_ALIGN16(signed char bounding_values[256]); + oc_fr_state fr[3]; + oc_qii_state qs[3]; + /*Skip SSD storage for the current MCU in each plane.*/ + unsigned *skip_ssd[3]; + /*Coded/uncoded fragment lists for each plane for the current MCU.*/ + ptrdiff_t *coded_fragis[3]; + ptrdiff_t *uncoded_fragis[3]; + ptrdiff_t ncoded_fragis[3]; + ptrdiff_t nuncoded_fragis[3]; + /*The starting fragment for the current MCU in each plane.*/ + ptrdiff_t froffset[3]; + /*The starting row for the current MCU in each plane.*/ + int fragy0[3]; + /*The ending row for the current MCU in each plane.*/ + int fragy_end[3]; + /*The starting superblock for the current MCU in each plane.*/ + unsigned sbi0[3]; + /*The ending superblock for the current MCU in each plane.*/ + unsigned sbi_end[3]; + /*The number of tokens for zzi=1 for each color plane.*/ + int ndct_tokens1[3]; + /*The outstanding eob_run count for zzi=1 for each color plane.*/ + int eob_run1[3]; + /*Whether or not the loop filter is enabled.*/ + int loop_filter; +}; + + + +/*Statistics used to estimate R-D cost of a block in a given coding mode. + See modedec.h for more details.*/ +struct oc_mode_rd{ + /*The expected bits used by the DCT tokens, shifted by OC_BIT_SCALE.*/ + ogg_int16_t rate; + /*The expected square root of the sum of squared errors, shifted by + OC_RMSE_SCALE.*/ + ogg_int16_t rmse; +}; + +# if defined(OC_COLLECT_METRICS) +# include "collect.h" +# endif + + + /*A 2nd order low-pass Bessel follower. We use this for rate control because it has fast reaction time, but is critically damped.*/ @@ -190,6 +524,8 @@ struct oc_frame_metrics{ unsigned dup_count:31; /*The frame type from pass 1.*/ unsigned frame_type:1; + /*The frame activity average from pass 1.*/ + unsigned activity_avg; }; @@ -335,10 +671,15 @@ struct th_enc_ctx{ size_t mv_bits[2]; /*The mode scheme chooser for estimating mode coding costs.*/ oc_mode_scheme_chooser chooser; + /*Temporary encoder state for the analysis pipeline.*/ + oc_enc_pipeline_state pipe; /*The number of vertical super blocks in an MCU.*/ int mcu_nvsbs; /*The SSD error for skipping each fragment in the current MCU.*/ unsigned *mcu_skip_ssd; + /*The masking scale factors for chroma blocks in the current MCU.*/ + ogg_uint16_t *mcu_rd_scale; + ogg_uint16_t *mcu_rd_iscale; /*The DCT token lists for each coefficient and each plane.*/ unsigned char **dct_tokens[3]; /*The extra bits associated with each DCT token.*/ @@ -350,8 +691,10 @@ struct th_enc_ctx{ /*The offset of the first DCT token for each coefficient for each plane.*/ unsigned char dct_token_offs[3][64]; /*The last DC coefficient for each plane and reference frame.*/ - int dc_pred_last[3][3]; + int dc_pred_last[3][4]; #if defined(OC_COLLECT_METRICS) + /*Fragment SAD statistics for MB mode estimation metrics.*/ + unsigned *frag_sad; /*Fragment SATD statistics for MB mode estimation metrics.*/ unsigned *frag_satd; /*Fragment SSD statistics for MB mode estimation metrics.*/ @@ -359,32 +702,56 @@ struct th_enc_ctx{ #endif /*The R-D optimization parameter.*/ int lambda; + /*The average block "activity" of the previous frame.*/ + unsigned activity_avg; + /*The average MB luma of the previous frame.*/ + unsigned luma_avg; /*The huffman tables in use.*/ th_huff_code huff_codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS]; /*The quantization parameters in use.*/ th_quant_info qinfo; - oc_iquant *enquant_tables[64][3][2]; - oc_iquant_table enquant_table_data[64][3][2]; - /*An "average" quantizer for each quantizer type (INTRA or INTER) and qi - value. - This is used to paramterize the rate control decisions. + /*The original DC coefficients saved off from the dequatization tables.*/ + ogg_uint16_t dequant_dc[64][3][2]; + /*Condensed dequantization tables.*/ + const ogg_uint16_t *dequant[3][3][2]; + /*Condensed quantization tables.*/ + void *enquant[3][3][2]; + /*The full set of quantization tables.*/ + void *enquant_tables[64][3][2]; + /*Storage for the quantization tables.*/ + unsigned char *enquant_table_data; + /*An "average" quantizer for each frame type (INTRA or INTER) and qi value. + This is used to parameterize the rate control decisions. They are kept in the log domain to simplify later processing. - Keep in mind these are DCT domain quantizers, and so are scaled by an - additional factor of 4 from the pixel domain.*/ + These are DCT domain quantizers, and so are scaled by an additional factor + of 4 from the pixel domain.*/ ogg_int64_t log_qavg[2][64]; + /*The "average" quantizer futher partitioned by color plane. + This is used to parameterize mode decision. + These are DCT domain quantizers, and so are scaled by an additional factor + of 4 from the pixel domain.*/ + ogg_int16_t log_plq[64][3][2]; + /*The R-D scale factors to apply to chroma blocks for a given frame type + (INTRA or INTER) and qi value. + The first is the "D" modifier (rd_scale), while the second is the "lambda" + modifier (rd_iscale).*/ + ogg_uint16_t chroma_rd_scale[2][64][2]; + /*The interpolated mode decision R-D lookup tables for the current + quantizers, color plane, and quantization type.*/ + oc_mode_rd mode_rd[3][3][2][OC_COMP_BINS]; /*The buffer state used to drive rate control.*/ oc_rc_state rc; +# if defined(OC_ENC_USE_VTABLE) /*Table for encoder acceleration functions.*/ oc_enc_opt_vtable opt_vtable; +# endif + /*Table for encoder data used by accelerated functions.*/ + oc_enc_opt_data opt_data; }; void oc_enc_analyze_intra(oc_enc_ctx *_enc,int _recode); int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode); -#if defined(OC_COLLECT_METRICS) -void oc_enc_mode_metrics_collect(oc_enc_ctx *_enc); -void oc_enc_mode_metrics_dump(oc_enc_ctx *_enc); -#endif @@ -415,8 +782,13 @@ struct oc_token_checkpoint{ void oc_enc_tokenize_start(oc_enc_ctx *_enc); int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, - ogg_int16_t *_qdct,const ogg_uint16_t *_dequant,const ogg_int16_t *_dct, - int _zzi,oc_token_checkpoint **_stack,int _acmin); + ogg_int16_t *_qdct_out,const ogg_int16_t *_qdct_in, + const ogg_uint16_t *_dequant,const ogg_int16_t *_dct, + int _zzi,oc_token_checkpoint **_stack,int _lambda,int _acmin); +int oc_enc_tokenize_ac_fast(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, + ogg_int16_t *_qdct_out,const ogg_int16_t *_qdct_in, + const ogg_uint16_t *_dequant,const ogg_int16_t *_dct, + int _zzi,oc_token_checkpoint **_stack,int _lambda,int _acmin); void oc_enc_tokenlog_rollback(oc_enc_ctx *_enc, const oc_token_checkpoint *_stack,int _n); void oc_enc_pred_dc_frag_rows(oc_enc_ctx *_enc, @@ -436,45 +808,13 @@ int oc_state_flushheader(oc_theora_state *_state,int *_packet_state, -/*Encoder-specific accelerated functions.*/ -void oc_enc_frag_sub(const oc_enc_ctx *_enc,ogg_int16_t _diff[64], - const unsigned char *_src,const unsigned char *_ref,int _ystride); -void oc_enc_frag_sub_128(const oc_enc_ctx *_enc,ogg_int16_t _diff[64], - const unsigned char *_src,int _ystride); -unsigned oc_enc_frag_sad(const oc_enc_ctx *_enc,const unsigned char *_src, - const unsigned char *_ref,int _ystride); -unsigned oc_enc_frag_sad_thresh(const oc_enc_ctx *_enc, - const unsigned char *_src,const unsigned char *_ref,int _ystride, - unsigned _thresh); -unsigned oc_enc_frag_sad2_thresh(const oc_enc_ctx *_enc, - const unsigned char *_src,const unsigned char *_ref1, - const unsigned char *_ref2,int _ystride,unsigned _thresh); -unsigned oc_enc_frag_satd_thresh(const oc_enc_ctx *_enc, - const unsigned char *_src,const unsigned char *_ref,int _ystride, - unsigned _thresh); -unsigned oc_enc_frag_satd2_thresh(const oc_enc_ctx *_enc, - const unsigned char *_src,const unsigned char *_ref1, - const unsigned char *_ref2,int _ystride,unsigned _thresh); -unsigned oc_enc_frag_intra_satd(const oc_enc_ctx *_enc, - const unsigned char *_src,int _ystride); -void oc_enc_frag_copy2(const oc_enc_ctx *_enc,unsigned char *_dst, - const unsigned char *_src1,const unsigned char *_src2,int _ystride); -void oc_enc_frag_recon_intra(const oc_enc_ctx *_enc, - unsigned char *_dst,int _ystride,const ogg_int16_t _residue[64]); -void oc_enc_frag_recon_inter(const oc_enc_ctx *_enc,unsigned char *_dst, - const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]); -void oc_enc_fdct8x8(const oc_enc_ctx *_enc,ogg_int16_t _y[64], - const ogg_int16_t _x[64]); - -/*Default pure-C implementations.*/ -void oc_enc_vtable_init_c(oc_enc_ctx *_enc); +/*Default pure-C implementations of encoder-specific accelerated functions.*/ +void oc_enc_accel_init_c(oc_enc_ctx *_enc); void oc_enc_frag_sub_c(ogg_int16_t _diff[64], const unsigned char *_src,const unsigned char *_ref,int _ystride); void oc_enc_frag_sub_128_c(ogg_int16_t _diff[64], const unsigned char *_src,int _ystride); -void oc_enc_frag_copy2_c(unsigned char *_dst, - const unsigned char *_src1,const unsigned char *_src2,int _ystride); unsigned oc_enc_frag_sad_c(const unsigned char *_src, const unsigned char *_ref,int _ystride); unsigned oc_enc_frag_sad_thresh_c(const unsigned char *_src, @@ -482,12 +822,24 @@ unsigned oc_enc_frag_sad_thresh_c(const unsigned char *_src, unsigned oc_enc_frag_sad2_thresh_c(const unsigned char *_src, const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, unsigned _thresh); -unsigned oc_enc_frag_satd_thresh_c(const unsigned char *_src, - const unsigned char *_ref,int _ystride,unsigned _thresh); -unsigned oc_enc_frag_satd2_thresh_c(const unsigned char *_src, - const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, - unsigned _thresh); -unsigned oc_enc_frag_intra_satd_c(const unsigned char *_src,int _ystride); +unsigned oc_enc_frag_intra_sad_c(const unsigned char *_src, int _ystride); +unsigned oc_enc_frag_satd_c(int *_dc,const unsigned char *_src, + const unsigned char *_ref,int _ystride); +unsigned oc_enc_frag_satd2_c(int *_dc,const unsigned char *_src, + const unsigned char *_ref1,const unsigned char *_ref2,int _ystride); +unsigned oc_enc_frag_intra_satd_c(int *_dc, + const unsigned char *_src,int _ystride); +unsigned oc_enc_frag_ssd_c(const unsigned char *_src, + const unsigned char *_ref,int _ystride); +unsigned oc_enc_frag_border_ssd_c(const unsigned char *_src, + const unsigned char *_ref,int _ystride,ogg_int64_t _mask); +void oc_enc_frag_copy2_c(unsigned char *_dst, + const unsigned char *_src1,const unsigned char *_src2,int _ystride); +void oc_enc_enquant_table_init_c(void *_enquant, + const ogg_uint16_t _dequant[64]); +void oc_enc_enquant_table_fixup_c(void *_enquant[3][3][2],int _nqis); +int oc_enc_quantize_c(ogg_int16_t _qdct[64],const ogg_int16_t _dct[64], + const ogg_uint16_t _dequant[64],const void *_enquant); void oc_enc_fdct8x8_c(ogg_int16_t _y[64],const ogg_int16_t _x[64]); #endif diff --git a/thirdparty/libtheora/encode.c b/thirdparty/libtheora/encode.c index 0c5ea6a172..3309f97c03 100644 --- a/thirdparty/libtheora/encode.c +++ b/thirdparty/libtheora/encode.c @@ -11,15 +11,13 @@ ******************************************************************** function: - last mod: $Id: encode.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ #include <stdlib.h> #include <string.h> #include "encint.h" -#if defined(OC_X86_ASM) -# include "x86/x86enc.h" -#endif +#include "dequant.h" @@ -288,12 +286,12 @@ const th_quant_info TH_DEF_QUANT_INFO={ 28, 25, 24, 22, 20, 17, 14, 10 }, { - 30,25,20,20,15,15,14,14, - 13,13,12,12,11,11,10,10, - 9, 9, 8, 8, 7, 7, 7, 7, - 6, 6, 6, 6, 5, 5, 5, 5, - 4, 4, 4, 4, 3, 3, 3, 3, + 15,12, 9, 8, 6, 6, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 4, 4, 4, 4, 4, 4, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, @@ -623,11 +621,15 @@ static void oc_enc_mb_modes_pack(oc_enc_ctx *_enc){ } } -static void oc_enc_mv_pack(oc_enc_ctx *_enc,int _mv_scheme,int _dx,int _dy){ +static void oc_enc_mv_pack(oc_enc_ctx *_enc,int _mv_scheme,oc_mv _mv){ + int dx; + int dy; + dx=OC_MV_X(_mv); + dy=OC_MV_Y(_mv); oggpackB_write(&_enc->opb, - OC_MV_CODES[_mv_scheme][_dx+31],OC_MV_BITS[_mv_scheme][_dx+31]); + OC_MV_CODES[_mv_scheme][dx+31],OC_MV_BITS[_mv_scheme][dx+31]); oggpackB_write(&_enc->opb, - OC_MV_CODES[_mv_scheme][_dy+31],OC_MV_BITS[_mv_scheme][_dy+31]); + OC_MV_CODES[_mv_scheme][dy+31],OC_MV_BITS[_mv_scheme][dy+31]); } static void oc_enc_mvs_pack(oc_enc_ctx *_enc){ @@ -650,7 +652,7 @@ static void oc_enc_mvs_pack(oc_enc_ctx *_enc){ mb_modes=_enc->state.mb_modes; mb_maps=(const oc_mb_map *)_enc->state.mb_maps; frags=_enc->state.frags; - frag_mvs=(const oc_mv *)_enc->state.frag_mvs; + frag_mvs=_enc->state.frag_mvs; for(mbii=0;mbii<ncoded_mbis;mbii++){ ptrdiff_t fragi; unsigned mbi; @@ -662,8 +664,7 @@ static void oc_enc_mvs_pack(oc_enc_ctx *_enc){ for(bi=0;;bi++){ fragi=mb_maps[mbi][0][bi]; if(frags[fragi].coded){ - oc_enc_mv_pack(_enc,mv_scheme, - frag_mvs[fragi][0],frag_mvs[fragi][1]); + oc_enc_mv_pack(_enc,mv_scheme,frag_mvs[fragi]); /*Only code a single MV for this macro block.*/ break; } @@ -673,8 +674,7 @@ static void oc_enc_mvs_pack(oc_enc_ctx *_enc){ for(bi=0;bi<4;bi++){ fragi=mb_maps[mbi][0][bi]; if(frags[fragi].coded){ - oc_enc_mv_pack(_enc,mv_scheme, - frag_mvs[fragi][0],frag_mvs[fragi][1]); + oc_enc_mv_pack(_enc,mv_scheme,frag_mvs[fragi]); /*Keep coding all the MVs for this macro block.*/ } } @@ -863,11 +863,55 @@ static void oc_enc_residual_tokens_pack(oc_enc_ctx *_enc){ } } +/*Packs an explicit drop frame, instead of using the more efficient 0-byte + packet. + This is only enabled in VP3-compatibility mode, even though it is not + strictly required for VP3 compatibility (VP3 could be encoded in AVI, which + also supports dropping frames by inserting 0 byte packets). + However, almost every _Theora_ player used to get this wrong (and many still + do), and it wasn't until we started shipping a post-VP3 encoder that + actually used non-VP3 features that this began to be discovered and fixed, + despite being in the standard since 2004. + The pack buffer must be reset before calling this function.*/ +static void oc_enc_drop_frame_pack(oc_enc_ctx *_enc){ + unsigned nsbs; + /*Mark this as a data packet.*/ + oggpackB_write(&_enc->opb,0,1); + /*Output the frame type (key frame or delta frame).*/ + oggpackB_write(&_enc->opb,OC_INTER_FRAME,1); + /*Write out the current qi list. + We always use just 1 qi, to avoid wasting bits on the others.*/ + oggpackB_write(&_enc->opb,_enc->state.qis[0],6); + oggpackB_write(&_enc->opb,0,1); + /*Coded block flags: everything is uncoded.*/ + nsbs=_enc->state.nsbs; + /*No partially coded SBs.*/ + oggpackB_write(&_enc->opb,0,1); + oc_sb_run_pack(&_enc->opb,nsbs,0,1); + /*No fully coded SBs.*/ + oggpackB_write(&_enc->opb,0,1); + oc_sb_run_pack(&_enc->opb,nsbs,0,1); + /*MB modes: just need write which scheme to use. + Since we have no coded MBs, we can pick any of them except 0, which would + require writing out an additional mode list.*/ + oggpackB_write(&_enc->opb,7,3); + /*MVs: just need write which scheme to use. + We can pick either one, since we have no MVs.*/ + oggpackB_write(&_enc->opb,1,1); + /*Write the chosen DC token tables.*/ + oggpackB_write(&_enc->opb,_enc->huff_idxs[OC_INTER_FRAME][0][0],4); + oggpackB_write(&_enc->opb,_enc->huff_idxs[OC_INTER_FRAME][0][1],4); + /*Write the chosen AC token tables.*/ + oggpackB_write(&_enc->opb,_enc->huff_idxs[OC_INTER_FRAME][1][0],4); + oggpackB_write(&_enc->opb,_enc->huff_idxs[OC_INTER_FRAME][1][1],4); +} + static void oc_enc_frame_pack(oc_enc_ctx *_enc){ + /*musl libc malloc()/realloc() calls might use floating point, so make sure + we've cleared the MMX state for them.*/ + oc_restore_fpu(&_enc->state); oggpackB_reset(&_enc->opb); - /*Only proceed if we have some coded blocks. - If there are no coded blocks, we can drop this frame simply by emitting a - 0 byte packet.*/ + /*Only proceed if we have some coded blocks.*/ if(_enc->state.ntotal_coded_fragis>0){ oc_enc_frame_header_pack(_enc); if(_enc->state.frame_type==OC_INTER_FRAME){ @@ -880,6 +924,10 @@ static void oc_enc_frame_pack(oc_enc_ctx *_enc){ oc_enc_tokenize_finish(_enc); oc_enc_residual_tokens_pack(_enc); } + /*If there are no coded blocks, we can drop this frame simply by emitting a + 0 byte packet. + We emit an inter frame with no coded blocks in VP3-compatibility mode.*/ + else if(_enc->vp3_compatible)oc_enc_drop_frame_pack(_enc); /*Success: Mark the packet as ready to be flushed.*/ _enc->packet_state=OC_PACKET_READY; #if defined(OC_COLLECT_METRICS) @@ -888,21 +936,31 @@ static void oc_enc_frame_pack(oc_enc_ctx *_enc){ } -void oc_enc_vtable_init_c(oc_enc_ctx *_enc){ +void oc_enc_accel_init_c(oc_enc_ctx *_enc){ /*The implementations prefixed with oc_enc_ are encoder-specific. The rest we re-use from the decoder.*/ +# if defined(OC_ENC_USE_VTABLE) + _enc->opt_vtable.frag_sub=oc_enc_frag_sub_c; + _enc->opt_vtable.frag_sub_128=oc_enc_frag_sub_128_c; _enc->opt_vtable.frag_sad=oc_enc_frag_sad_c; _enc->opt_vtable.frag_sad_thresh=oc_enc_frag_sad_thresh_c; _enc->opt_vtable.frag_sad2_thresh=oc_enc_frag_sad2_thresh_c; - _enc->opt_vtable.frag_satd_thresh=oc_enc_frag_satd_thresh_c; - _enc->opt_vtable.frag_satd2_thresh=oc_enc_frag_satd2_thresh_c; + _enc->opt_vtable.frag_intra_sad=oc_enc_frag_intra_sad_c; + _enc->opt_vtable.frag_satd=oc_enc_frag_satd_c; + _enc->opt_vtable.frag_satd2=oc_enc_frag_satd2_c; _enc->opt_vtable.frag_intra_satd=oc_enc_frag_intra_satd_c; - _enc->opt_vtable.frag_sub=oc_enc_frag_sub_c; - _enc->opt_vtable.frag_sub_128=oc_enc_frag_sub_128_c; + _enc->opt_vtable.frag_ssd=oc_enc_frag_ssd_c; + _enc->opt_vtable.frag_border_ssd=oc_enc_frag_border_ssd_c; _enc->opt_vtable.frag_copy2=oc_enc_frag_copy2_c; + _enc->opt_vtable.enquant_table_init=oc_enc_enquant_table_init_c; + _enc->opt_vtable.enquant_table_fixup=oc_enc_enquant_table_fixup_c; + _enc->opt_vtable.quantize=oc_enc_quantize_c; _enc->opt_vtable.frag_recon_intra=oc_frag_recon_intra_c; _enc->opt_vtable.frag_recon_inter=oc_frag_recon_inter_c; _enc->opt_vtable.fdct8x8=oc_enc_fdct8x8_c; +# endif + _enc->opt_data.enquant_table_size=64*sizeof(oc_iquant); + _enc->opt_data.enquant_table_alignment=16; } /*Initialize the macro block neighbor lists for MC analysis. @@ -1003,6 +1061,55 @@ static int oc_enc_set_huffman_codes(oc_enc_ctx *_enc, return 0; } +static void oc_enc_enquant_tables_init(oc_enc_ctx *_enc, + const th_quant_info *_qinfo){ + unsigned char *etd; + size_t ets; + int align; + int qii; + int qi; + int pli; + int qti; + for(qi=0;qi<64;qi++)for(pli=0;pli<3;pli++)for(qti=0;qti<2;qti++){ + _enc->state.dequant_tables[qi][pli][qti]= + _enc->state.dequant_table_data[qi][pli][qti]; + } + /*Initialize the dequantization tables.*/ + oc_dequant_tables_init(_enc->state.dequant_tables,NULL,_qinfo); + /*And save off the DC values.*/ + for(qi=0;qi<64;qi++)for(pli=0;pli<3;pli++)for(qti=0;qti<2;qti++){ + _enc->dequant_dc[qi][pli][qti]=_enc->state.dequant_tables[qi][pli][qti][0]; + } + /*Set up storage for the quantization tables.*/ + etd=_enc->enquant_table_data; + ets=_enc->opt_data.enquant_table_size; + align=-(etd-(unsigned char *)0)&_enc->opt_data.enquant_table_alignment-1; + etd+=align; + /*Set up the main tables.*/ + for(qi=0;qi<64;qi++)for(pli=0;pli<3;pli++)for(qti=0;qti<2;qti++){ + _enc->enquant_tables[qi][pli][qti]=etd; + oc_enc_enquant_table_init(_enc,etd, + _enc->state.dequant_tables[qi][pli][qti]); + etd+=ets; + } + /*Set up storage for the local copies we modify for each frame.*/ + for(pli=0;pli<3;pli++)for(qii=0;qii<3;qii++)for(qti=0;qti<2;qti++){ + _enc->enquant[pli][qii][qti]=etd; + etd+=ets; + } +} + +/*Updates the encoder state after the quantization parameters have been + changed.*/ +static void oc_enc_quant_params_updated(oc_enc_ctx *_enc, + const th_quant_info *_qinfo){ + oc_enc_enquant_tables_init(_enc,_qinfo); + memcpy(_enc->state.loop_filter_limits,_qinfo->loop_filter_limits, + sizeof(_enc->state.loop_filter_limits)); + oc_enquant_qavg_init(_enc->log_qavg,_enc->log_plq,_enc->chroma_rd_scale, + _enc->state.dequant_tables,_enc->state.info.pixel_fmt); +} + /*Sets the quantization parameters to use. This may only be called before the setup header is written. If it is called multiple times, only the last call has any effect. @@ -1012,25 +1119,20 @@ static int oc_enc_set_huffman_codes(oc_enc_ctx *_enc, will be used.*/ static int oc_enc_set_quant_params(oc_enc_ctx *_enc, const th_quant_info *_qinfo){ - int qi; - int pli; - int qti; + th_quant_info old_qinfo; + int ret; if(_enc==NULL)return TH_EFAULT; if(_enc->packet_state>OC_PACKET_SETUP_HDR)return TH_EINVAL; if(_qinfo==NULL)_qinfo=&TH_DEF_QUANT_INFO; - /*TODO: Analyze for packing purposes instead of just doing a shallow copy.*/ - memcpy(&_enc->qinfo,_qinfo,sizeof(_enc->qinfo)); - for(qi=0;qi<64;qi++)for(pli=0;pli<3;pli++)for(qti=0;qti<2;qti++){ - _enc->state.dequant_tables[qi][pli][qti]= - _enc->state.dequant_table_data[qi][pli][qti]; - _enc->enquant_tables[qi][pli][qti]=_enc->enquant_table_data[qi][pli][qti]; + memcpy(&old_qinfo,&_enc->qinfo,sizeof(old_qinfo)); + ret=oc_quant_params_clone(&_enc->qinfo,_qinfo); + if(ret<0){ + oc_quant_params_clear(&_enc->qinfo); + memcpy(&_enc->qinfo,&old_qinfo,sizeof(old_qinfo)); + return ret; } - oc_enquant_tables_init(_enc->state.dequant_tables, - _enc->enquant_tables,_qinfo); - memcpy(_enc->state.loop_filter_limits,_qinfo->loop_filter_limits, - sizeof(_enc->state.loop_filter_limits)); - oc_enquant_qavg_init(_enc->log_qavg,_enc->state.dequant_tables, - _enc->state.info.pixel_fmt); + else oc_quant_params_clear(&old_qinfo); + oc_enc_quant_params_updated(_enc,_qinfo); return 0; } @@ -1039,6 +1141,7 @@ static void oc_enc_clear(oc_enc_ctx *_enc); static int oc_enc_init(oc_enc_ctx *_enc,const th_info *_info){ th_info info; size_t mcu_nmbs; + ptrdiff_t mcu_ncfrags; ptrdiff_t mcu_nfrags; int hdec; int vdec; @@ -1053,8 +1156,9 @@ static int oc_enc_init(oc_enc_ctx *_enc,const th_info *_info){ if(info.quality<0)info.quality=32; if(info.target_bitrate<0)info.target_bitrate=0; /*Initialize the shared encoder/decoder state.*/ - ret=oc_state_init(&_enc->state,&info,4); + ret=oc_state_init(&_enc->state,&info,6); if(ret<0)return ret; + oc_enc_accel_init(_enc); _enc->mb_info=_ogg_calloc(_enc->state.nmbs,sizeof(*_enc->mb_info)); _enc->frag_dc=_ogg_calloc(_enc->state.nfrags,sizeof(*_enc->frag_dc)); _enc->coded_mbis= @@ -1065,9 +1169,14 @@ static int oc_enc_init(oc_enc_ctx *_enc,const th_info *_info){ super block rows of Y' for each super block row of Cb and Cr.*/ _enc->mcu_nvsbs=1<<vdec; mcu_nmbs=_enc->mcu_nvsbs*_enc->state.fplanes[0].nhsbs*(size_t)4; - mcu_nfrags=4*mcu_nmbs+(8*mcu_nmbs>>hdec+vdec); + mcu_ncfrags=mcu_nmbs<<3-(hdec+vdec); + mcu_nfrags=4*mcu_nmbs+mcu_ncfrags; _enc->mcu_skip_ssd=(unsigned *)_ogg_malloc( mcu_nfrags*sizeof(*_enc->mcu_skip_ssd)); + _enc->mcu_rd_scale=(ogg_uint16_t *)_ogg_malloc( + (mcu_ncfrags>>1)*sizeof(*_enc->mcu_rd_scale)); + _enc->mcu_rd_iscale=(ogg_uint16_t *)_ogg_malloc( + (mcu_ncfrags>>1)*sizeof(*_enc->mcu_rd_iscale)); for(pli=0;pli<3;pli++){ _enc->dct_tokens[pli]=(unsigned char **)oc_malloc_2d(64, _enc->state.fplanes[pli].nfrags,sizeof(**_enc->dct_tokens)); @@ -1075,34 +1184,22 @@ static int oc_enc_init(oc_enc_ctx *_enc,const th_info *_info){ _enc->state.fplanes[pli].nfrags,sizeof(**_enc->extra_bits)); } #if defined(OC_COLLECT_METRICS) + _enc->frag_sad=_ogg_calloc(_enc->state.nfrags,sizeof(*_enc->frag_sad)); _enc->frag_satd=_ogg_calloc(_enc->state.nfrags,sizeof(*_enc->frag_satd)); _enc->frag_ssd=_ogg_calloc(_enc->state.nfrags,sizeof(*_enc->frag_ssd)); #endif -#if defined(OC_X86_ASM) - oc_enc_vtable_init_x86(_enc); -#else - oc_enc_vtable_init_c(_enc); -#endif + _enc->enquant_table_data=(unsigned char *)_ogg_malloc( + (64+3)*3*2*_enc->opt_data.enquant_table_size + +_enc->opt_data.enquant_table_alignment-1); _enc->keyframe_frequency_force=1<<_enc->state.info.keyframe_granule_shift; _enc->state.qis[0]=_enc->state.info.quality; _enc->state.nqis=1; + _enc->activity_avg=90<<12; + _enc->luma_avg=128<<8; oc_rc_state_init(&_enc->rc,_enc); oggpackB_writeinit(&_enc->opb); - if(_enc->mb_info==NULL||_enc->frag_dc==NULL||_enc->coded_mbis==NULL|| - _enc->mcu_skip_ssd==NULL||_enc->dct_tokens[0]==NULL|| - _enc->dct_tokens[1]==NULL||_enc->dct_tokens[2]==NULL|| - _enc->extra_bits[0]==NULL||_enc->extra_bits[1]==NULL|| - _enc->extra_bits[2]==NULL -#if defined(OC_COLLECT_METRICS) - ||_enc->frag_satd==NULL||_enc->frag_ssd==NULL -#endif - ){ - oc_enc_clear(_enc); - return TH_EFAULT; - } - oc_mode_scheme_chooser_init(&_enc->chooser); - oc_enc_mb_info_init(_enc); - memset(_enc->huff_idxs,0,sizeof(_enc->huff_idxs)); + memcpy(_enc->huff_codes,TH_VP31_HUFF_CODES,sizeof(_enc->huff_codes)); + memset(_enc->qinfo.qi_ranges,0,sizeof(_enc->qinfo.qi_ranges)); /*Reset the packet-out state machine.*/ _enc->packet_state=OC_PACKET_INFO_HDR; _enc->dup_count=0; @@ -1114,26 +1211,45 @@ static int oc_enc_init(oc_enc_ctx *_enc,const th_info *_info){ _enc->vp3_compatible=0; /*No INTER frames coded yet.*/ _enc->coded_inter_frame=0; - memcpy(_enc->huff_codes,TH_VP31_HUFF_CODES,sizeof(_enc->huff_codes)); - oc_enc_set_quant_params(_enc,NULL); + if(_enc->mb_info==NULL||_enc->frag_dc==NULL||_enc->coded_mbis==NULL + ||_enc->mcu_skip_ssd==NULL||_enc->dct_tokens[0]==NULL + ||_enc->dct_tokens[1]==NULL||_enc->dct_tokens[2]==NULL + ||_enc->extra_bits[0]==NULL||_enc->extra_bits[1]==NULL + ||_enc->extra_bits[2]==NULL +#if defined(OC_COLLECT_METRICS) + ||_enc->frag_sad==NULL||_enc->frag_satd==NULL||_enc->frag_ssd==NULL +#endif + ||oc_enc_set_quant_params(_enc,NULL)<0){ + oc_enc_clear(_enc); + return TH_EFAULT; + } + oc_mode_scheme_chooser_init(&_enc->chooser); + oc_enc_mb_info_init(_enc); + memset(_enc->huff_idxs,0,sizeof(_enc->huff_idxs)); return 0; } static void oc_enc_clear(oc_enc_ctx *_enc){ int pli; oc_rc_state_clear(&_enc->rc); -#if defined(OC_COLLECT_METRICS) - oc_enc_mode_metrics_dump(_enc); -#endif oggpackB_writeclear(&_enc->opb); + oc_quant_params_clear(&_enc->qinfo); + _ogg_free(_enc->enquant_table_data); #if defined(OC_COLLECT_METRICS) + /*Save the collected metrics from this run. + Use tools/process_modedec_stats to actually generate modedec.h from the + resulting file.*/ + oc_mode_metrics_dump(); _ogg_free(_enc->frag_ssd); _ogg_free(_enc->frag_satd); + _ogg_free(_enc->frag_sad); #endif for(pli=3;pli-->0;){ oc_free_2d(_enc->extra_bits[pli]); oc_free_2d(_enc->dct_tokens[pli]); } + _ogg_free(_enc->mcu_rd_iscale); + _ogg_free(_enc->mcu_rd_scale); _ogg_free(_enc->mcu_skip_ssd); _ogg_free(_enc->coded_mbis); _ogg_free(_enc->frag_dc); @@ -1145,10 +1261,14 @@ static void oc_enc_drop_frame(th_enc_ctx *_enc){ /*Use the previous frame's reconstruction.*/ _enc->state.ref_frame_idx[OC_FRAME_SELF]= _enc->state.ref_frame_idx[OC_FRAME_PREV]; + _enc->state.ref_frame_data[OC_FRAME_SELF]= + _enc->state.ref_frame_data[OC_FRAME_PREV]; /*Flag motion vector analysis about the frame drop.*/ _enc->prevframe_dropped=1; /*Zero the packet.*/ oggpackB_reset(&_enc->opb); + /*Emit an inter frame with no coded blocks in VP3-compatibility mode.*/ + if(_enc->vp3_compatible)oc_enc_drop_frame_pack(_enc); } static void oc_enc_compress_keyframe(oc_enc_ctx *_enc,int _recode){ @@ -1222,9 +1342,9 @@ static void oc_enc_set_granpos(oc_enc_ctx *_enc){ th_enc_ctx *th_encode_alloc(const th_info *_info){ oc_enc_ctx *enc; if(_info==NULL)return NULL; - enc=_ogg_malloc(sizeof(*enc)); + enc=oc_aligned_malloc(sizeof(*enc),16); if(enc==NULL||oc_enc_init(enc,_info)<0){ - _ogg_free(enc); + oc_aligned_free(enc); return NULL; } return enc; @@ -1233,7 +1353,7 @@ th_enc_ctx *th_encode_alloc(const th_info *_info){ void th_encode_free(th_enc_ctx *_enc){ if(_enc!=NULL){ oc_enc_clear(_enc); - _ogg_free(_enc); + oc_aligned_free(_enc); } } @@ -1272,12 +1392,17 @@ int th_encode_ctl(th_enc_ctx *_enc,int _req,void *_buf,size_t _buf_sz){ }break; case TH_ENCCTL_SET_VP3_COMPATIBLE:{ int vp3_compatible; + int ret; if(_enc==NULL||_buf==NULL)return TH_EFAULT; if(_buf_sz!=sizeof(vp3_compatible))return TH_EINVAL; + /*Try this before we change anything else, because it can fail.*/ + ret=oc_enc_set_quant_params(_enc,&TH_VP31_QUANT_INFO); + /*If we can't allocate enough memory, don't change any of the state.*/ + if(ret==TH_EFAULT)return ret; vp3_compatible=*(int *)_buf; _enc->vp3_compatible=vp3_compatible; if(oc_enc_set_huffman_codes(_enc,TH_VP31_HUFF_CODES)<0)vp3_compatible=0; - if(oc_enc_set_quant_params(_enc,&TH_VP31_QUANT_INFO)<0)vp3_compatible=0; + if(ret<0)vp3_compatible=0; if(_enc->state.info.pixel_fmt!=TH_PF_420|| _enc->state.info.pic_width<_enc->state.info.frame_width|| _enc->state.info.pic_height<_enc->state.info.frame_height|| @@ -1386,6 +1511,44 @@ int th_encode_ctl(th_enc_ctx *_enc,int _req,void *_buf,size_t _buf_sz){ } return oc_enc_rc_2pass_in(_enc,_buf,_buf_sz); }break; + case TH_ENCCTL_SET_COMPAT_CONFIG:{ + unsigned char buf[7]; + oc_pack_buf opb; + th_quant_info qinfo; + th_huff_code huff_codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS]; + int ret; + int i; + if(_enc==NULL||_buf==NULL)return TH_EFAULT; + if(_enc->packet_state>OC_PACKET_SETUP_HDR)return TH_EINVAL; + oc_pack_readinit(&opb,_buf,_buf_sz); + /*Validate the setup packet header.*/ + for(i=0;i<7;i++)buf[i]=(unsigned char)oc_pack_read(&opb,8); + if(!(buf[0]&0x80)||memcmp(buf+1,"theora",6)!=0)return TH_ENOTFORMAT; + if(buf[0]!=0x82)return TH_EBADHEADER; + /*Reads its contents.*/ + ret=oc_quant_params_unpack(&opb,&qinfo); + if(ret<0){ + oc_quant_params_clear(&qinfo); + return ret; + } + ret=oc_huff_codes_unpack(&opb,huff_codes); + if(ret<0){ + oc_quant_params_clear(&qinfo); + return ret; + } + /*Install the new state.*/ + oc_quant_params_clear(&_enc->qinfo); + memcpy(&_enc->qinfo,&qinfo,sizeof(qinfo)); + oc_enc_quant_params_updated(_enc,&qinfo); + memcpy(_enc->huff_codes,huff_codes,sizeof(_enc->huff_codes)); + return 0; + } +#if defined(OC_COLLECT_METRICS) + case TH_ENCCTL_SET_METRICS_FILE:{ + OC_MODE_METRICS_FILENAME=(const char *)_buf; + return 0; + } +#endif default:return TH_EIMPL; } } @@ -1477,6 +1640,12 @@ static void oc_img_plane_copy_pad(th_img_plane *_dst,th_img_plane *_src, int th_encode_ycbcr_in(th_enc_ctx *_enc,th_ycbcr_buffer _img){ th_ycbcr_buffer img; + int frame_width; + int frame_height; + int pic_width; + int pic_height; + int pic_x; + int pic_y; int cframe_width; int cframe_height; int cpic_width; @@ -1492,53 +1661,94 @@ int th_encode_ycbcr_in(th_enc_ctx *_enc,th_ycbcr_buffer _img){ if(_enc==NULL||_img==NULL)return TH_EFAULT; if(_enc->packet_state==OC_PACKET_DONE)return TH_EINVAL; if(_enc->rc.twopass&&_enc->rc.twopass_buffer_bytes==0)return TH_EINVAL; - if((ogg_uint32_t)_img[0].width!=_enc->state.info.frame_width|| - (ogg_uint32_t)_img[0].height!=_enc->state.info.frame_height){ - return TH_EINVAL; - } hdec=!(_enc->state.info.pixel_fmt&1); vdec=!(_enc->state.info.pixel_fmt&2); - cframe_width=_enc->state.info.frame_width>>hdec; - cframe_height=_enc->state.info.frame_height>>vdec; - if(_img[1].width!=cframe_width||_img[2].width!=cframe_width|| - _img[1].height!=cframe_height||_img[2].height!=cframe_height){ - return TH_EINVAL; - } - /*Step 2: Copy the input to our internal buffer. - This lets us add padding, if necessary, so we don't have to worry about - dereferencing possibly invalid addresses, and allows us to use the same - strides and fragment offsets for both the input frame and the reference - frames.*/ + frame_width=_enc->state.info.frame_width; + frame_height=_enc->state.info.frame_height; + pic_x=_enc->state.info.pic_x; + pic_y=_enc->state.info.pic_y; + pic_width=_enc->state.info.pic_width; + pic_height=_enc->state.info.pic_height; + cframe_width=frame_width>>hdec; + cframe_height=frame_height>>vdec; + cpic_x=pic_x>>hdec; + cpic_y=pic_y>>vdec; + cpic_width=(pic_x+pic_width+hdec>>hdec)-cpic_x; + cpic_height=(pic_y+pic_height+vdec>>vdec)-cpic_y; /*Flip the input buffer upside down.*/ oc_ycbcr_buffer_flip(img,_img); - oc_img_plane_copy_pad(_enc->state.ref_frame_bufs[OC_FRAME_IO]+0,img+0, - _enc->state.info.pic_x,_enc->state.info.pic_y, - _enc->state.info.pic_width,_enc->state.info.pic_height); - cpic_x=_enc->state.info.pic_x>>hdec; - cpic_y=_enc->state.info.pic_y>>vdec; - cpic_width=(_enc->state.info.pic_x+_enc->state.info.pic_width+hdec>>hdec) - -cpic_x; - cpic_height=(_enc->state.info.pic_y+_enc->state.info.pic_height+vdec>>vdec) - -cpic_y; - for(pli=1;pli<3;pli++){ - oc_img_plane_copy_pad(_enc->state.ref_frame_bufs[OC_FRAME_IO]+pli,img+pli, - cpic_x,cpic_y,cpic_width,cpic_height); + if(img[0].width!=frame_width||img[0].height!=frame_height|| + img[1].width!=cframe_width||img[2].width!=cframe_width|| + img[1].height!=cframe_height||img[2].height!=cframe_height){ + /*The buffer does not match the frame size. + Check to see if it matches the picture size.*/ + if(img[0].width!=pic_width||img[0].height!=pic_height|| + img[1].width!=cpic_width||img[2].width!=cpic_width|| + img[1].height!=cpic_height||img[2].height!=cpic_height){ + /*It doesn't; we don't know how to handle it.*/ + return TH_EINVAL; + } + /*Adjust the pointers to address a full frame. + We still only use the picture region, however.*/ + img[0].data-=pic_y*(ptrdiff_t)img[0].stride+pic_x; + img[1].data-=cpic_y*(ptrdiff_t)img[1].stride+cpic_x; + img[2].data-=cpic_y*(ptrdiff_t)img[2].stride+cpic_x; } - /*Step 3: Update the buffer state.*/ + /*Step 2: Update the buffer state.*/ if(_enc->state.ref_frame_idx[OC_FRAME_SELF]>=0){ _enc->state.ref_frame_idx[OC_FRAME_PREV]= _enc->state.ref_frame_idx[OC_FRAME_SELF]; + _enc->state.ref_frame_data[OC_FRAME_PREV]= + _enc->state.ref_frame_data[OC_FRAME_SELF]; if(_enc->state.frame_type==OC_INTRA_FRAME){ /*The new frame becomes both the previous and gold reference frames.*/ _enc->state.keyframe_num=_enc->state.curframe_num; _enc->state.ref_frame_idx[OC_FRAME_GOLD]= _enc->state.ref_frame_idx[OC_FRAME_SELF]; + _enc->state.ref_frame_data[OC_FRAME_GOLD]= + _enc->state.ref_frame_data[OC_FRAME_SELF]; + } + } + if(_enc->state.ref_frame_idx[OC_FRAME_IO]>=0&&_enc->prevframe_dropped==0){ + _enc->state.ref_frame_idx[OC_FRAME_PREV_ORIG]= + _enc->state.ref_frame_idx[OC_FRAME_IO]; + _enc->state.ref_frame_data[OC_FRAME_PREV_ORIG]= + _enc->state.ref_frame_data[OC_FRAME_IO]; + if(_enc->state.frame_type==OC_INTRA_FRAME){ + /*The new input frame becomes both the previous and gold + original-reference frames.*/ + _enc->state.ref_frame_idx[OC_FRAME_GOLD_ORIG]= + _enc->state.ref_frame_idx[OC_FRAME_IO]; + _enc->state.ref_frame_data[OC_FRAME_GOLD_ORIG]= + _enc->state.ref_frame_data[OC_FRAME_IO]; } } + /*Select a free buffer to use for the incoming frame*/ + for(refi=3;refi==_enc->state.ref_frame_idx[OC_FRAME_GOLD_ORIG]|| + refi==_enc->state.ref_frame_idx[OC_FRAME_PREV_ORIG];refi++); + _enc->state.ref_frame_idx[OC_FRAME_IO]=refi; + _enc->state.ref_frame_data[OC_FRAME_IO]= + _enc->state.ref_frame_bufs[refi][0].data; + /*Step 3: Copy the input to our internal buffer. + This lets us add padding, so we don't have to worry about dereferencing + possibly invalid addresses, and allows us to use the same strides and + fragment offsets for both the input frame and the reference frames.*/ + oc_img_plane_copy_pad(_enc->state.ref_frame_bufs[refi]+0,img+0, + pic_x,pic_y,pic_width,pic_height); + oc_state_borders_fill_rows(&_enc->state,refi,0,0,frame_height); + oc_state_borders_fill_caps(&_enc->state,refi,0); + for(pli=1;pli<3;pli++){ + oc_img_plane_copy_pad(_enc->state.ref_frame_bufs[refi]+pli,img+pli, + cpic_x,cpic_y,cpic_width,cpic_height); + oc_state_borders_fill_rows(&_enc->state,refi,pli,0,cframe_height); + oc_state_borders_fill_caps(&_enc->state,refi,pli); + } /*Select a free buffer to use for the reconstructed version of this frame.*/ for(refi=0;refi==_enc->state.ref_frame_idx[OC_FRAME_GOLD]|| refi==_enc->state.ref_frame_idx[OC_FRAME_PREV];refi++); _enc->state.ref_frame_idx[OC_FRAME_SELF]=refi; + _enc->state.ref_frame_data[OC_FRAME_SELF]= + _enc->state.ref_frame_bufs[refi][0].data; _enc->state.curframe_num+=_enc->prev_dup_count+1; /*Step 4: Compress the frame.*/ /*Start with a keyframe, and don't allow the generation of invalid files that @@ -1575,11 +1785,11 @@ int th_encode_ycbcr_in(th_enc_ctx *_enc,th_ycbcr_buffer _img){ } int th_encode_packetout(th_enc_ctx *_enc,int _last_p,ogg_packet *_op){ + unsigned char *packet; if(_enc==NULL||_op==NULL)return TH_EFAULT; if(_enc->packet_state==OC_PACKET_READY){ _enc->packet_state=OC_PACKET_EMPTY; if(_enc->rc.twopass!=1){ - unsigned char *packet; packet=oggpackB_get_buffer(&_enc->opb); /*If there's no packet, malloc failed while writing; it's lost forever.*/ if(packet==NULL)return TH_EFAULT; @@ -1595,8 +1805,22 @@ int th_encode_packetout(th_enc_ctx *_enc,int _last_p,ogg_packet *_op){ else if(_enc->packet_state==OC_PACKET_EMPTY){ if(_enc->nqueued_dups>0){ _enc->nqueued_dups--; - _op->packet=NULL; - _op->bytes=0; + /*Emit an inter frame with no coded blocks in VP3-compatibility mode.*/ + if(_enc->vp3_compatible){ + oggpackB_reset(&_enc->opb); + oc_enc_drop_frame_pack(_enc); + packet=oggpackB_get_buffer(&_enc->opb); + /*If there's no packet, malloc failed while writing; it's lost + forever.*/ + if(packet==NULL)return TH_EFAULT; + _op->packet=packet; + _op->bytes=oggpackB_bytes(&_enc->opb); + } + /*Otherwise emit a 0-byte packet.*/ + else{ + _op->packet=NULL; + _op->bytes=0; + } } else{ if(_last_p)_enc->packet_state=OC_PACKET_DONE; diff --git a/thirdparty/libtheora/encoder_disabled.c b/thirdparty/libtheora/encoder_disabled.c index 0cbf6645ac..ba6d995505 100644 --- a/thirdparty/libtheora/encoder_disabled.c +++ b/thirdparty/libtheora/encoder_disabled.c @@ -11,12 +11,15 @@ ******************************************************************** function: - last mod: $Id: encoder_disabled.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ #include "apiwrapper.h" #include "encint.h" +const th_quant_info TH_VP31_QUANT_INFO = {}; +const th_huff_code TH_VP31_HUFF_CODES[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS]; + th_enc_ctx *th_encode_alloc(const th_info *_info){ return NULL; } diff --git a/thirdparty/libtheora/enquant.c b/thirdparty/libtheora/enquant.c index 3372fed221..8fd220edd7 100644 --- a/thirdparty/libtheora/enquant.c +++ b/thirdparty/libtheora/enquant.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: enquant.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ #include <stdlib.h> @@ -20,6 +20,69 @@ +int oc_quant_params_clone(th_quant_info *_dst,const th_quant_info *_src){ + int i; + memcpy(_dst,_src,sizeof(*_dst)); + memset(_dst->qi_ranges,0,sizeof(_dst->qi_ranges)); + for(i=0;i<6;i++){ + int nranges; + int qti; + int pli; + int qtj; + int plj; + int pdup; + int qdup; + qti=i/3; + pli=i%3; + qtj=(i-1)/3; + plj=(i-1)%3; + nranges=_src->qi_ranges[qti][pli].nranges; + /*Check for those duplicates that can be cleanly handled by + oc_quant_params_clear().*/ + pdup=i>0&&nranges<=_src->qi_ranges[qtj][plj].nranges; + qdup=qti>0&&nranges<=_src->qi_ranges[0][pli].nranges; + _dst->qi_ranges[qti][pli].nranges=nranges; + if(pdup&&_src->qi_ranges[qti][pli].sizes==_src->qi_ranges[qtj][plj].sizes){ + _dst->qi_ranges[qti][pli].sizes=_dst->qi_ranges[qtj][plj].sizes; + } + else if(qdup&&_src->qi_ranges[1][pli].sizes==_src->qi_ranges[0][pli].sizes){ + _dst->qi_ranges[1][pli].sizes=_dst->qi_ranges[0][pli].sizes; + } + else{ + int *sizes; + sizes=(int *)_ogg_malloc(nranges*sizeof(*sizes)); + /*Note: The caller is responsible for cleaning up any partially + constructed qinfo.*/ + if(sizes==NULL)return TH_EFAULT; + memcpy(sizes,_src->qi_ranges[qti][pli].sizes,nranges*sizeof(*sizes)); + _dst->qi_ranges[qti][pli].sizes=sizes; + } + if(pdup&&_src->qi_ranges[qti][pli].base_matrices== + _src->qi_ranges[qtj][plj].base_matrices){ + _dst->qi_ranges[qti][pli].base_matrices= + _dst->qi_ranges[qtj][plj].base_matrices; + } + else if(qdup&&_src->qi_ranges[1][pli].base_matrices== + _src->qi_ranges[0][pli].base_matrices){ + _dst->qi_ranges[1][pli].base_matrices= + _dst->qi_ranges[0][pli].base_matrices; + } + else{ + th_quant_base *base_matrices; + base_matrices=(th_quant_base *)_ogg_malloc( + (nranges+1)*sizeof(*base_matrices)); + /*Note: The caller is responsible for cleaning up any partially + constructed qinfo.*/ + if(base_matrices==NULL)return TH_EFAULT; + memcpy(base_matrices,_src->qi_ranges[qti][pli].base_matrices, + (nranges+1)*sizeof(*base_matrices)); + _dst->qi_ranges[qti][pli].base_matrices= + (const th_quant_base *)base_matrices; + } + } + return 0; +} + void oc_quant_params_pack(oggpack_buffer *_opb,const th_quant_info *_qinfo){ const th_quant_ranges *qranges; const th_quant_base *base_mats[2*3*64]; @@ -119,7 +182,7 @@ void oc_quant_params_pack(oggpack_buffer *_opb,const th_quant_info *_qinfo){ } } -static void oc_iquant_init(oc_iquant *_this,ogg_uint16_t _d){ +void oc_iquant_init(oc_iquant *_this,ogg_uint16_t _d){ ogg_uint32_t t; int l; _d<<=1; @@ -129,48 +192,61 @@ static void oc_iquant_init(oc_iquant *_this,ogg_uint16_t _d){ _this->l=l; } -/*See comments at oc_dequant_tables_init() for how the quantization tables' - storage should be initialized.*/ -void oc_enquant_tables_init(ogg_uint16_t *_dequant[64][3][2], - oc_iquant *_enquant[64][3][2],const th_quant_info *_qinfo){ - int qi; +void oc_enc_enquant_table_init_c(void *_enquant, + const ogg_uint16_t _dequant[64]){ + oc_iquant *enquant; + int zzi; + /*In the original VP3.2 code, the rounding offset and the size of the + dead zone around 0 were controlled by a "sharpness" parameter. + We now R-D optimize the tokens for each block after quantization, + so the rounding offset should always be 1/2, and an explicit dead + zone is unnecessary. + Hence, all of that VP3.2 code is gone from here, and the remaining + floating point code has been implemented as equivalent integer + code with exact precision.*/ + enquant=(oc_iquant *)_enquant; + for(zzi=0;zzi<64;zzi++)oc_iquant_init(enquant+zzi,_dequant[zzi]); +} + +void oc_enc_enquant_table_fixup_c(void *_enquant[3][3][2],int _nqis){ int pli; + int qii; int qti; - /*Initialize the dequantization tables first.*/ - oc_dequant_tables_init(_dequant,NULL,_qinfo); - /*Derive the quantization tables directly from the dequantization tables.*/ - for(qi=0;qi<64;qi++)for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){ - int zzi; - int plj; - int qtj; - int dupe; - dupe=0; - for(qtj=0;qtj<=qti;qtj++){ - for(plj=0;plj<(qtj<qti?3:pli);plj++){ - if(_dequant[qi][pli][qti]==_dequant[qi][plj][qtj]){ - dupe=1; - break; - } - } - if(dupe)break; - } - if(dupe){ - _enquant[qi][pli][qti]=_enquant[qi][plj][qtj]; - continue; - } - /*In the original VP3.2 code, the rounding offset and the size of the - dead zone around 0 were controlled by a "sharpness" parameter. - We now R-D optimize the tokens for each block after quantization, - so the rounding offset should always be 1/2, and an explicit dead - zone is unnecessary. - Hence, all of that VP3.2 code is gone from here, and the remaining - floating point code has been implemented as equivalent integer - code with exact precision.*/ - for(zzi=0;zzi<64;zzi++){ - oc_iquant_init(_enquant[qi][pli][qti]+zzi, - _dequant[qi][pli][qti][zzi]); + for(pli=0;pli<3;pli++)for(qii=1;qii<_nqis;qii++)for(qti=0;qti<2;qti++){ + *((oc_iquant *)_enquant[pli][qii][qti])= + *((oc_iquant *)_enquant[pli][0][qti]); + } +} + +int oc_enc_quantize_c(ogg_int16_t _qdct[64],const ogg_int16_t _dct[64], + const ogg_uint16_t _dequant[64],const void *_enquant){ + const oc_iquant *enquant; + int nonzero; + int zzi; + int val; + int d; + int s; + enquant=(const oc_iquant *)_enquant; + nonzero=0; + for(zzi=0;zzi<64;zzi++){ + val=_dct[zzi]; + d=_dequant[zzi]; + val=val<<1; + if(abs(val)>=d){ + s=OC_SIGNMASK(val); + /*The bias added here rounds ties away from zero, since token + optimization can only decrease the magnitude of the quantized + value.*/ + val+=d+s^s; + /*Note the arithmetic right shift is not guaranteed by ANSI C. + Hopefully no one still uses ones-complement architectures.*/ + val=((enquant[zzi].m*(ogg_int32_t)val>>16)+val>>enquant[zzi].l)-s; + _qdct[zzi]=(ogg_int16_t)val; + nonzero=zzi; } + else _qdct[zzi]=0; } + return nonzero; } @@ -226,7 +302,7 @@ static const ogg_uint16_t OC_RPSD[2][64]={ relative to the total, scaled by 2**16, for each pixel format. These values were measured after motion-compensated prediction, before quantization, over a large set of test video encoded at all possible rates. - TODO: These values are only from INTER frames; it should be re-measured for + TODO: These values are only from INTER frames; they should be re-measured for INTRA frames.*/ static const ogg_uint16_t OC_PCD[4][3]={ {59926, 3038, 2572}, @@ -236,38 +312,58 @@ static const ogg_uint16_t OC_PCD[4][3]={ }; -/*Compute an "average" quantizer for each qi level. - We do one for INTER and one for INTRA, since their behavior is very - different, but average across chroma channels. +/*Compute "average" quantizers for each qi level to use for rate control. + We do one for each color channel, as well as an average across color + channels, separately for INTER and INTRA, since their behavior is very + different. The basic approach is to compute a harmonic average of the squared quantizer, weighted by the expected squared magnitude of the DCT coefficients. Under the (not quite true) assumption that DCT coefficients are Laplacian-distributed, this preserves the product Q*lambda, where lambda=sqrt(2/sigma**2) is the Laplacian distribution parameter (not to be confused with the lambda used in R-D optimization throughout most of the - rest of the code). - The value Q*lambda completely determines the entropy of the coefficients.*/ + rest of the code), when the distributions from multiple coefficients are + pooled. + The value Q*lambda completely determines the entropy of coefficients drawn + from a Laplacian distribution, and thus the expected bitrate.*/ void oc_enquant_qavg_init(ogg_int64_t _log_qavg[2][64], + ogg_int16_t _log_plq[64][3][2],ogg_uint16_t _chroma_rd_scale[2][64][2], ogg_uint16_t *_dequant[64][3][2],int _pixel_fmt){ int qi; int pli; int qti; int ci; for(qti=0;qti<2;qti++)for(qi=0;qi<64;qi++){ - ogg_int64_t q2; + ogg_int64_t q2; + ogg_uint32_t qp[3]; + ogg_uint32_t cqp; + ogg_uint32_t d; q2=0; for(pli=0;pli<3;pli++){ - ogg_uint32_t qp; - qp=0; + qp[pli]=0; for(ci=0;ci<64;ci++){ unsigned rq; unsigned qd; qd=_dequant[qi][pli][qti][OC_IZIG_ZAG[ci]]; rq=(OC_RPSD[qti][ci]+(qd>>1))/qd; - qp+=rq*(ogg_uint32_t)rq; + qp[pli]+=rq*(ogg_uint32_t)rq; } - q2+=OC_PCD[_pixel_fmt][pli]*(ogg_int64_t)qp; + q2+=OC_PCD[_pixel_fmt][pli]*(ogg_int64_t)qp[pli]; + /*plq=1.0/sqrt(qp)*/ + _log_plq[qi][pli][qti]= + (ogg_int16_t)(OC_Q10(32)-oc_blog32_q10(qp[pli])>>1); } + d=OC_PCD[_pixel_fmt][1]+OC_PCD[_pixel_fmt][2]; + cqp=(ogg_uint32_t)((OC_PCD[_pixel_fmt][1]*(ogg_int64_t)qp[1]+ + OC_PCD[_pixel_fmt][2]*(ogg_int64_t)qp[2]+(d>>1))/d); + /*chroma_rd_scale=clamp(0.25,cqp/qp[0],4)*/ + d=OC_MAXI(qp[0]+(1<<OC_RD_SCALE_BITS-1)>>OC_RD_SCALE_BITS,1); + d=OC_CLAMPI(1<<OC_RD_SCALE_BITS-2,(cqp+(d>>1))/d,4<<OC_RD_SCALE_BITS); + _chroma_rd_scale[qti][qi][0]=(ogg_int16_t)d; + /*chroma_rd_iscale=clamp(0.25,qp[0]/cqp,4)*/ + d=OC_MAXI(OC_RD_ISCALE(cqp,1),1); + d=OC_CLAMPI(1<<OC_RD_ISCALE_BITS-2,(qp[0]+(d>>1))/d,4<<OC_RD_ISCALE_BITS); + _chroma_rd_scale[qti][qi][1]=(ogg_int16_t)d; /*qavg=1.0/sqrt(q2).*/ _log_qavg[qti][qi]=OC_Q57(48)-oc_blog64(q2)>>1; } diff --git a/thirdparty/libtheora/enquant.h b/thirdparty/libtheora/enquant.h index d62df10d1a..e5f78144cc 100644 --- a/thirdparty/libtheora/enquant.h +++ b/thirdparty/libtheora/enquant.h @@ -14,14 +14,13 @@ struct oc_iquant{ ogg_int16_t l; }; -typedef oc_iquant oc_iquant_table[64]; - +int oc_quant_params_clone(th_quant_info *_dst,const th_quant_info *_src); void oc_quant_params_pack(oggpack_buffer *_opb,const th_quant_info *_qinfo); -void oc_enquant_tables_init(ogg_uint16_t *_dequant[64][3][2], - oc_iquant *_enquant[64][3][2],const th_quant_info *_qinfo); +void oc_iquant_init(oc_iquant *_this,ogg_uint16_t _d); void oc_enquant_qavg_init(ogg_int64_t _log_qavg[2][64], + ogg_int16_t _log_plq[64][3][2],ogg_uint16_t _pl_rd_scale[2][64][2], ogg_uint16_t *_dequant[64][3][2],int _pixel_fmt); #endif diff --git a/thirdparty/libtheora/fdct.c b/thirdparty/libtheora/fdct.c index dc3a66f245..9c2f8b0446 100644 --- a/thirdparty/libtheora/fdct.c +++ b/thirdparty/libtheora/fdct.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: fdct.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ #include "encint.h" @@ -120,11 +120,6 @@ static void oc_fdct8(ogg_int16_t _y[8],const ogg_int16_t *_x){ _y[7]=v; } -void oc_enc_fdct8x8(const oc_enc_ctx *_enc,ogg_int16_t _y[64], - const ogg_int16_t _x[64]){ - (*_enc->opt_vtable.fdct8x8)(_y,_x); -} - /*Performs a forward 8x8 Type-II DCT transform. The output is scaled by a factor of 4 relative to the orthonormal version of the transform. @@ -152,7 +147,7 @@ void oc_enc_fdct8x8_c(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ /*Round the result back to the external working precision (which is still scaled by four relative to the orthogonal result). TODO: We should just update the external working precision.*/ - for(i=0;i<64;i++)_y[i]=w[i]+2>>2; + for(i=0;i<64;i++)_y[i]=w[OC_FZIG_ZAG[i]]+2>>2; } diff --git a/thirdparty/libtheora/fragment.c b/thirdparty/libtheora/fragment.c index 15372e9d9f..14c38be507 100644 --- a/thirdparty/libtheora/fragment.c +++ b/thirdparty/libtheora/fragment.c @@ -11,17 +11,12 @@ ******************************************************************** function: - last mod: $Id: fragment.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ #include <string.h> #include "internal.h" -void oc_frag_copy(const oc_theora_state *_state,unsigned char *_dst, - const unsigned char *_src,int _ystride){ - (*_state->opt_vtable.frag_copy)(_dst,_src,_ystride); -} - void oc_frag_copy_c(unsigned char *_dst,const unsigned char *_src,int _ystride){ int i; for(i=8;i-->0;){ @@ -31,9 +26,24 @@ void oc_frag_copy_c(unsigned char *_dst,const unsigned char *_src,int _ystride){ } } -void oc_frag_recon_intra(const oc_theora_state *_state,unsigned char *_dst, - int _ystride,const ogg_int16_t _residue[64]){ - _state->opt_vtable.frag_recon_intra(_dst,_ystride,_residue); +/*Copies the fragments specified by the lists of fragment indices from one + frame to another. + _dst_frame: The reference frame to copy to. + _src_frame: The reference frame to copy from. + _ystride: The row stride of the reference frames. + _fragis: A pointer to a list of fragment indices. + _nfragis: The number of fragment indices to copy. + _frag_buf_offs: The offsets of fragments in the reference frames.*/ +void oc_frag_copy_list_c(unsigned char *_dst_frame, + const unsigned char *_src_frame,int _ystride, + const ptrdiff_t *_fragis,ptrdiff_t _nfragis,const ptrdiff_t *_frag_buf_offs){ + ptrdiff_t fragii; + for(fragii=0;fragii<_nfragis;fragii++){ + ptrdiff_t frag_buf_off; + frag_buf_off=_frag_buf_offs[_fragis[fragii]]; + oc_frag_copy_c(_dst_frame+frag_buf_off, + _src_frame+frag_buf_off,_ystride); + } } void oc_frag_recon_intra_c(unsigned char *_dst,int _ystride, @@ -46,11 +56,6 @@ void oc_frag_recon_intra_c(unsigned char *_dst,int _ystride, } } -void oc_frag_recon_inter(const oc_theora_state *_state,unsigned char *_dst, - const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]){ - _state->opt_vtable.frag_recon_inter(_dst,_src,_ystride,_residue); -} - void oc_frag_recon_inter_c(unsigned char *_dst, const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]){ int i; @@ -62,12 +67,6 @@ void oc_frag_recon_inter_c(unsigned char *_dst, } } -void oc_frag_recon_inter2(const oc_theora_state *_state,unsigned char *_dst, - const unsigned char *_src1,const unsigned char *_src2,int _ystride, - const ogg_int16_t _residue[64]){ - _state->opt_vtable.frag_recon_inter2(_dst,_src1,_src2,_ystride,_residue); -} - void oc_frag_recon_inter2_c(unsigned char *_dst,const unsigned char *_src1, const unsigned char *_src2,int _ystride,const ogg_int16_t _residue[64]){ int i; @@ -80,8 +79,4 @@ void oc_frag_recon_inter2_c(unsigned char *_dst,const unsigned char *_src1, } } -void oc_restore_fpu(const oc_theora_state *_state){ - _state->opt_vtable.restore_fpu(); -} - void oc_restore_fpu_c(void){} diff --git a/thirdparty/libtheora/huffdec.c b/thirdparty/libtheora/huffdec.c index 8cf27f0341..5a83c5f150 100644 --- a/thirdparty/libtheora/huffdec.c +++ b/thirdparty/libtheora/huffdec.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: huffdec.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ @@ -22,14 +22,60 @@ #include "decint.h" -/*The ANSI offsetof macro is broken on some platforms (e.g., older DECs).*/ -#define _ogg_offsetof(_type,_field)\ - ((size_t)((char *)&((_type *)0)->_field-(char *)0)) -/*The number of internal tokens associated with each of the spec tokens.*/ -static const unsigned char OC_DCT_TOKEN_MAP_ENTRIES[TH_NDCT_TOKENS]={ - 1,1,1,4,8,1,1,8,1,1,1,1,1,2,2,2,2,4,8,2,2,2,4,2,2,2,2,2,8,2,4,8 -}; +/*Instead of storing every branching in the tree, subtrees can be collapsed + into one node, with a table of size 1<<nbits pointing directly to its + descedents nbits levels down. + This allows more than one bit to be read at a time, and avoids following all + the intermediate branches with next to no increased code complexity once + the collapsed tree has been built. + We do _not_ require that a subtree be complete to be collapsed, but instead + store duplicate pointers in the table, and record the actual depth of the + node below its parent. + This tells us the number of bits to advance the stream after reaching it. + + This turns out to be equivalent to the method described in \cite{Hash95}, + without the requirement that codewords be sorted by length. + If the codewords were sorted by length (so-called ``canonical-codes''), they + could be decoded much faster via either Lindell and Moffat's approach or + Hashemian's Condensed Huffman Code approach, the latter of which has an + extremely small memory footprint. + We can't use Choueka et al.'s finite state machine approach, which is + extremely fast, because we can't allow multiple symbols to be output at a + time; the codebook can and does change between symbols. + It also has very large memory requirements, which impairs cache coherency. + + We store the tree packed in an array of 16-bit integers (words). + Each node consists of a single word, followed consecutively by two or more + indices of its children. + Let n be the value of this first word. + This is the number of bits that need to be read to traverse the node, and + must be positive. + 1<<n entries follow in the array, each an index to a child node. + If the child is positive, then it is the index of another internal node in + the table. + If the child is negative or zero, then it is a leaf node. + These are stored directly in the child pointer to save space, since they only + require a single word. + If a leaf node would have been encountered before reading n bits, then it is + duplicated the necessary number of times in this table. + Leaf nodes pack both a token value and their actual depth in the tree. + The token in the leaf node is (-leaf&255). + The number of bits that need to be consumed to reach the leaf, starting from + the current node, is (-leaf>>8). + + @ARTICLE{Hash95, + author="Reza Hashemian", + title="Memory Efficient and High-Speed Search {Huffman} Coding", + journal="{IEEE} Transactions on Communications", + volume=43, + number=10, + pages="2576--2581", + month=Oct, + year=1995 + }*/ + + /*The map from external spec-defined tokens to internal tokens. This is constructed so that any extra bits read with the original token value @@ -99,391 +145,371 @@ static const unsigned char OC_DCT_TOKEN_MAP[TH_NDCT_TOKENS]={ 40 }; -/*These three functions are really part of the bitpack.c module, but - they are only used here. - Declaring local static versions so they can be inlined saves considerable - function call overhead.*/ - -static oc_pb_window oc_pack_refill(oc_pack_buf *_b,int _bits){ - const unsigned char *ptr; - const unsigned char *stop; - oc_pb_window window; - int available; - window=_b->window; - available=_b->bits; - ptr=_b->ptr; - stop=_b->stop; - /*This version of _refill() doesn't bother setting eof because we won't - check for it after we've started decoding DCT tokens.*/ - if(ptr>=stop)available=OC_LOTS_OF_BITS; - while(available<=OC_PB_WINDOW_SIZE-8){ - available+=8; - window|=(oc_pb_window)*ptr++<<OC_PB_WINDOW_SIZE-available; - if(ptr>=stop)available=OC_LOTS_OF_BITS; - } - _b->ptr=ptr; - if(_bits>available)window|=*ptr>>(available&7); - _b->bits=available; - return window; -} - - -/*Read in bits without advancing the bit pointer. - Here we assume 0<=_bits&&_bits<=32.*/ -static long oc_pack_look(oc_pack_buf *_b,int _bits){ - oc_pb_window window; - int available; - long result; - window=_b->window; - available=_b->bits; - if(_bits==0)return 0; - if(_bits>available)_b->window=window=oc_pack_refill(_b,_bits); - result=window>>OC_PB_WINDOW_SIZE-_bits; - return result; -} - -/*Advance the bit pointer.*/ -static void oc_pack_adv(oc_pack_buf *_b,int _bits){ - /*We ignore the special cases for _bits==0 and _bits==32 here, since they are - never used actually used. - OC_HUFF_SLUSH (defined below) would have to be at least 27 to actually read - 32 bits in a single go, and would require a 32 GB lookup table (assuming - 8 byte pointers, since 4 byte pointers couldn't fit such a table).*/ - _b->window<<=_bits; - _b->bits-=_bits; -} +/*The log base 2 of number of internal tokens associated with each of the spec + tokens (i.e., how many of the extra bits are folded into the token value). + Increasing the maximum value beyond 3 will enlarge the amount of stack + required for tree construction.*/ +static const unsigned char OC_DCT_TOKEN_MAP_LOG_NENTRIES[TH_NDCT_TOKENS]={ + 0,0,0,2,3,0,0,3,0,0,0,0,0,1,1,1,1,2,3,1,1,1,2,1,1,1,1,1,3,1,2,3 +}; -/*The log_2 of the size of a lookup table is allowed to grow to relative to - the number of unique nodes it contains. - E.g., if OC_HUFF_SLUSH is 2, then at most 75% of the space in the tree is - wasted (each node will have an amortized cost of at most 20 bytes when using - 4-byte pointers). +/*The size a lookup table is allowed to grow to relative to the number of + unique nodes it contains. + E.g., if OC_HUFF_SLUSH is 4, then at most 75% of the space in the tree is + wasted (1/4 of the space must be used). Larger numbers can decode tokens with fewer read operations, while smaller - numbers may save more space (requiring as little as 8 bytes amortized per - node, though there will be more nodes). + numbers may save more space. With a sample file: 32233473 read calls are required when no tree collapsing is done (100.0%). - 19269269 read calls are required when OC_HUFF_SLUSH is 0 (59.8%). - 11144969 read calls are required when OC_HUFF_SLUSH is 1 (34.6%). - 10538563 read calls are required when OC_HUFF_SLUSH is 2 (32.7%). - 10192578 read calls are required when OC_HUFF_SLUSH is 3 (31.6%). - Since a value of 1 gets us the vast majority of the speed-up with only a - small amount of wasted memory, this is what we use.*/ -#define OC_HUFF_SLUSH (1) - - -/*Determines the size in bytes of a Huffman tree node that represents a - subtree of depth _nbits. - _nbits: The depth of the subtree. - If this is 0, the node is a leaf node. - Otherwise 1<<_nbits pointers are allocated for children. - Return: The number of bytes required to store the node.*/ -static size_t oc_huff_node_size(int _nbits){ - size_t size; - size=_ogg_offsetof(oc_huff_node,nodes); - if(_nbits>0)size+=sizeof(oc_huff_node *)*(1<<_nbits); - return size; -} - -static oc_huff_node *oc_huff_node_init(char **_storage,size_t _size,int _nbits){ - oc_huff_node *ret; - ret=(oc_huff_node *)*_storage; - ret->nbits=(unsigned char)_nbits; - (*_storage)+=_size; - return ret; -} - - -/*Determines the size in bytes of a Huffman tree. - _nbits: The depth of the subtree. - If this is 0, the node is a leaf node. - Otherwise storage for 1<<_nbits pointers are added for children. - Return: The number of bytes required to store the tree.*/ -static size_t oc_huff_tree_size(const oc_huff_node *_node){ - size_t size; - size=oc_huff_node_size(_node->nbits); - if(_node->nbits){ - int nchildren; - int i; - nchildren=1<<_node->nbits; - for(i=0;i<nchildren;i+=1<<_node->nbits-_node->nodes[i]->depth){ - size+=oc_huff_tree_size(_node->nodes[i]); - } - } - return size; -} - - -/*Unpacks a sub-tree from the given buffer. - _opb: The buffer to unpack from. - _binodes: The nodes to store the sub-tree in. - _nbinodes: The number of nodes available for the sub-tree. - Return: 0 on success, or a negative value on error.*/ -static int oc_huff_tree_unpack(oc_pack_buf *_opb, - oc_huff_node *_binodes,int _nbinodes){ - oc_huff_node *binode; - long bits; - int nused; - if(_nbinodes<1)return TH_EBADHEADER; - binode=_binodes; - nused=0; - bits=oc_pack_read1(_opb); - if(oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER; - /*Read an internal node:*/ - if(!bits){ - int ret; - nused++; - binode->nbits=1; - binode->depth=1; - binode->nodes[0]=_binodes+nused; - ret=oc_huff_tree_unpack(_opb,_binodes+nused,_nbinodes-nused); - if(ret>=0){ - nused+=ret; - binode->nodes[1]=_binodes+nused; - ret=oc_huff_tree_unpack(_opb,_binodes+nused,_nbinodes-nused); - } - if(ret<0)return ret; - nused+=ret; - } - /*Read a leaf node:*/ - else{ - int ntokens; - int token; - int i; - bits=oc_pack_read(_opb,OC_NDCT_TOKEN_BITS); + 19269269 read calls are required when OC_HUFF_SLUSH is 1 (59.8%). + 11144969 read calls are required when OC_HUFF_SLUSH is 2 (34.6%). + 10538563 read calls are required when OC_HUFF_SLUSH is 4 (32.7%). + 10192578 read calls are required when OC_HUFF_SLUSH is 8 (31.6%). + Since a value of 2 gets us the vast majority of the speed-up with only a + small amount of wasted memory, this is what we use. + This value must be less than 128, or you could create a tree with more than + 32767 entries, which would overflow the 16-bit words used to index it.*/ +#define OC_HUFF_SLUSH (2) +/*The root of the tree is on the fast path, and a larger value here is more + beneficial than elsewhere in the tree. + 7 appears to give the best performance, trading off between increased use of + the single-read fast path and cache footprint for the tables, though + obviously this will depend on your cache size. + Using 7 here, the VP3 tables are about twice as large compared to using 2.*/ +#define OC_ROOT_HUFF_SLUSH (7) + + + +/*Unpacks a Huffman codebook. + _opb: The buffer to unpack from. + _tokens: Stores a list of internal tokens, in the order they were found in + the codebook, and the lengths of their corresponding codewords. + This is enough to completely define the codebook, while minimizing + stack usage and avoiding temporary allocations (for platforms + where free() is a no-op). + Return: The number of internal tokens in the codebook, or a negative value + on error.*/ +int oc_huff_tree_unpack(oc_pack_buf *_opb,unsigned char _tokens[256][2]){ + ogg_uint32_t code; + int len; + int ntokens; + int nleaves; + code=0; + len=ntokens=nleaves=0; + for(;;){ + long bits; + bits=oc_pack_read1(_opb); + /*Only process nodes so long as there's more bits in the buffer.*/ if(oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER; - /*Find out how many internal tokens we translate this external token into.*/ - ntokens=OC_DCT_TOKEN_MAP_ENTRIES[bits]; - if(_nbinodes<2*ntokens-1)return TH_EBADHEADER; - /*Fill in a complete binary tree pointing to the internal tokens.*/ - for(i=1;i<ntokens;i<<=1){ - int j; - binode=_binodes+nused; - nused+=i; - for(j=0;j<i;j++){ - binode[j].nbits=1; - binode[j].depth=1; - binode[j].nodes[0]=_binodes+nused+2*j; - binode[j].nodes[1]=_binodes+nused+2*j+1; - } + /*Read an internal node:*/ + if(!bits){ + len++; + /*Don't allow codewords longer than 32 bits.*/ + if(len>32)return TH_EBADHEADER; } - /*And now the leaf nodes with those tokens.*/ - token=OC_DCT_TOKEN_MAP[bits]; - for(i=0;i<ntokens;i++){ - binode=_binodes+nused++; - binode->nbits=0; - binode->depth=1; - binode->token=token+i; + /*Read a leaf node:*/ + else{ + ogg_uint32_t code_bit; + int neb; + int nentries; + int token; + /*Don't allow more than 32 spec-tokens per codebook.*/ + if(++nleaves>32)return TH_EBADHEADER; + bits=oc_pack_read(_opb,OC_NDCT_TOKEN_BITS); + neb=OC_DCT_TOKEN_MAP_LOG_NENTRIES[bits]; + token=OC_DCT_TOKEN_MAP[bits]; + nentries=1<<neb; + while(nentries-->0){ + _tokens[ntokens][0]=(unsigned char)token++; + _tokens[ntokens][1]=(unsigned char)(len+neb); + ntokens++; + } + code_bit=0x80000000U>>len-1; + while(len>0&&(code&code_bit)){ + code^=code_bit; + code_bit<<=1; + len--; + } + if(len<=0)break; + code|=code_bit; } } - return nused; -} - -/*Finds the depth of shortest branch of the given sub-tree. - The tree must be binary. - _binode: The root of the given sub-tree. - _binode->nbits must be 0 or 1. - Return: The smallest depth of a leaf node in this sub-tree. - 0 indicates this sub-tree is a leaf node.*/ -static int oc_huff_tree_mindepth(oc_huff_node *_binode){ - int depth0; - int depth1; - if(_binode->nbits==0)return 0; - depth0=oc_huff_tree_mindepth(_binode->nodes[0]); - depth1=oc_huff_tree_mindepth(_binode->nodes[1]); - return OC_MINI(depth0,depth1)+1; -} - -/*Finds the number of internal nodes at a given depth, plus the number of - leaves at that depth or shallower. - The tree must be binary. - _binode: The root of the given sub-tree. - _binode->nbits must be 0 or 1. - Return: The number of entries that would be contained in a jump table of the - given depth.*/ -static int oc_huff_tree_occupancy(oc_huff_node *_binode,int _depth){ - if(_binode->nbits==0||_depth<=0)return 1; - else{ - return oc_huff_tree_occupancy(_binode->nodes[0],_depth-1)+ - oc_huff_tree_occupancy(_binode->nodes[1],_depth-1); - } + return ntokens; } -/*Makes a copy of the given Huffman tree. - _node: The Huffman tree to copy. - Return: The copy of the Huffman tree.*/ -static oc_huff_node *oc_huff_tree_copy(const oc_huff_node *_node, - char **_storage){ - oc_huff_node *ret; - ret=oc_huff_node_init(_storage,oc_huff_node_size(_node->nbits),_node->nbits); - ret->depth=_node->depth; - if(_node->nbits){ - int nchildren; - int i; - int inext; - nchildren=1<<_node->nbits; - for(i=0;i<nchildren;){ - ret->nodes[i]=oc_huff_tree_copy(_node->nodes[i],_storage); - inext=i+(1<<_node->nbits-ret->nodes[i]->depth); - while(++i<inext)ret->nodes[i]=ret->nodes[i-1]; +/*Count how many tokens would be required to fill a subtree at depth _depth. + _tokens: A list of internal tokens, in the order they are found in the + codebook, and the lengths of their corresponding codewords. + _depth: The depth of the desired node in the corresponding tree structure. + Return: The number of tokens that belong to that subtree.*/ +static int oc_huff_subtree_tokens(unsigned char _tokens[][2],int _depth){ + ogg_uint32_t code; + int ti; + code=0; + ti=0; + do{ + if(_tokens[ti][1]-_depth<32)code+=0x80000000U>>_tokens[ti++][1]-_depth; + else{ + /*Because of the expanded internal tokens, we can have codewords as long + as 35 bits. + A single recursion here is enough to advance past them.*/ + code++; + ti+=oc_huff_subtree_tokens(_tokens+ti,_depth+31); } } - else ret->token=_node->token; - return ret; + while(code<0x80000000U); + return ti; } -static size_t oc_huff_tree_collapse_size(oc_huff_node *_binode,int _depth){ - size_t size; - int mindepth; - int depth; - int loccupancy; - int occupancy; - if(_binode->nbits!=0&&_depth>0){ - return oc_huff_tree_collapse_size(_binode->nodes[0],_depth-1)+ - oc_huff_tree_collapse_size(_binode->nodes[1],_depth-1); - } - depth=mindepth=oc_huff_tree_mindepth(_binode); - occupancy=1<<mindepth; +/*Compute the number of bits to use for a collapsed tree node at the given + depth. + _tokens: A list of internal tokens, in the order they are found in the + codebook, and the lengths of their corresponding codewords. + _ntokens: The number of tokens corresponding to this tree node. + _depth: The depth of this tree node. + Return: The number of bits to use for a collapsed tree node rooted here. + This is always at least one, even if this was a leaf node.*/ +static int oc_huff_tree_collapse_depth(unsigned char _tokens[][2], + int _ntokens,int _depth){ + int got_leaves; + int loccupancy; + int occupancy; + int slush; + int nbits; + int best_nbits; + slush=_depth>0?OC_HUFF_SLUSH:OC_ROOT_HUFF_SLUSH; + /*It's legal to have a tree with just a single node, which requires no bits + to decode and always returns the same token. + However, no encoder actually does this (yet). + To avoid a special case in oc_huff_token_decode(), we force the number of + lookahead bits to be at least one. + This will produce a tree that looks ahead one bit and then advances the + stream zero bits.*/ + nbits=1; + occupancy=2; + got_leaves=1; do{ + int ti; + if(got_leaves)best_nbits=nbits; + nbits++; + got_leaves=0; loccupancy=occupancy; - occupancy=oc_huff_tree_occupancy(_binode,++depth); - } - while(occupancy>loccupancy&&occupancy>=1<<OC_MAXI(depth-OC_HUFF_SLUSH,0)); - depth--; - size=oc_huff_node_size(depth); - if(depth>0){ - size+=oc_huff_tree_collapse_size(_binode->nodes[0],depth-1); - size+=oc_huff_tree_collapse_size(_binode->nodes[1],depth-1); + for(occupancy=ti=0;ti<_ntokens;occupancy++){ + if(_tokens[ti][1]<_depth+nbits)ti++; + else if(_tokens[ti][1]==_depth+nbits){ + got_leaves=1; + ti++; + } + else ti+=oc_huff_subtree_tokens(_tokens+ti,_depth+nbits); + } } - return size; + while(occupancy>loccupancy&&occupancy*slush>=1<<nbits); + return best_nbits; } -static oc_huff_node *oc_huff_tree_collapse(oc_huff_node *_binode, - char **_storage); - -/*Fills the given nodes table with all the children in the sub-tree at the - given depth. - The nodes in the sub-tree with a depth less than that stored in the table - are freed. - The sub-tree must be binary and complete up until the given depth. - _nodes: The nodes table to fill. - _binode: The root of the sub-tree to fill it with. - _binode->nbits must be 0 or 1. - _level: The current level in the table. - 0 indicates that the current node should be stored, regardless of - whether it is a leaf node or an internal node. - _depth: The depth of the nodes to fill the table with, relative to their - parent.*/ -static void oc_huff_node_fill(oc_huff_node **_nodes, - oc_huff_node *_binode,int _level,int _depth,char **_storage){ - if(_level<=0||_binode->nbits==0){ - int i; - _binode->depth=(unsigned char)(_depth-_level); - _nodes[0]=oc_huff_tree_collapse(_binode,_storage); - for(i=1;i<1<<_level;i++)_nodes[i]=_nodes[0]; - } - else{ - _level--; - oc_huff_node_fill(_nodes,_binode->nodes[0],_level,_depth,_storage); - _nodes+=1<<_level; - oc_huff_node_fill(_nodes,_binode->nodes[1],_level,_depth,_storage); - } +/*Determines the size in words of a Huffman tree node that represents a + subtree of depth _nbits. + _nbits: The depth of the subtree. + This must be greater than zero. + Return: The number of words required to store the node.*/ +static size_t oc_huff_node_size(int _nbits){ + return 1+(1<<_nbits); } -/*Finds the largest complete sub-tree rooted at the current node and collapses - it into a single node. - This procedure is then applied recursively to all the children of that node. - _binode: The root of the sub-tree to collapse. - _binode->nbits must be 0 or 1. - Return: The new root of the collapsed sub-tree.*/ -static oc_huff_node *oc_huff_tree_collapse(oc_huff_node *_binode, - char **_storage){ - oc_huff_node *root; - size_t size; - int mindepth; - int depth; - int loccupancy; - int occupancy; - depth=mindepth=oc_huff_tree_mindepth(_binode); - occupancy=1<<mindepth; +/*Produces a collapsed-tree representation of the given token list. + _tree: The storage for the collapsed Huffman tree. + This may be NULL to compute the required storage size instead of + constructing the tree. + _tokens: A list of internal tokens, in the order they are found in the + codebook, and the lengths of their corresponding codewords. + _ntokens: The number of tokens corresponding to this tree node. + Return: The number of words required to store the tree.*/ +static size_t oc_huff_tree_collapse(ogg_int16_t *_tree, + unsigned char _tokens[][2],int _ntokens){ + ogg_int16_t node[34]; + unsigned char depth[34]; + unsigned char last[34]; + size_t ntree; + int ti; + int l; + depth[0]=0; + last[0]=(unsigned char)(_ntokens-1); + ntree=0; + ti=0; + l=0; do{ - loccupancy=occupancy; - occupancy=oc_huff_tree_occupancy(_binode,++depth); + int nbits; + nbits=oc_huff_tree_collapse_depth(_tokens+ti,last[l]+1-ti,depth[l]); + node[l]=(ogg_int16_t)ntree; + ntree+=oc_huff_node_size(nbits); + if(_tree!=NULL)_tree[node[l]++]=(ogg_int16_t)nbits; + do{ + while(ti<=last[l]&&_tokens[ti][1]<=depth[l]+nbits){ + if(_tree!=NULL){ + ogg_int16_t leaf; + int nentries; + nentries=1<<depth[l]+nbits-_tokens[ti][1]; + leaf=(ogg_int16_t)-(_tokens[ti][1]-depth[l]<<8|_tokens[ti][0]); + while(nentries-->0)_tree[node[l]++]=leaf; + } + ti++; + } + if(ti<=last[l]){ + /*We need to recurse*/ + depth[l+1]=(unsigned char)(depth[l]+nbits); + if(_tree!=NULL)_tree[node[l]++]=(ogg_int16_t)ntree; + l++; + last[l]= + (unsigned char)(ti+oc_huff_subtree_tokens(_tokens+ti,depth[l])-1); + break; + } + /*Pop back up a level of recursion.*/ + else if(l-->0)nbits=depth[l+1]-depth[l]; + } + while(l>=0); } - while(occupancy>loccupancy&&occupancy>=1<<OC_MAXI(depth-OC_HUFF_SLUSH,0)); - depth--; - if(depth<=1)return oc_huff_tree_copy(_binode,_storage); - size=oc_huff_node_size(depth); - root=oc_huff_node_init(_storage,size,depth); - root->depth=_binode->depth; - oc_huff_node_fill(root->nodes,_binode,depth,depth,_storage); - return root; + while(l>=0); + return ntree; } /*Unpacks a set of Huffman trees, and reduces them to a collapsed representation. _opb: The buffer to unpack the trees from. _nodes: The table to fill with the Huffman trees. - Return: 0 on success, or a negative value on error.*/ + Return: 0 on success, or a negative value on error. + The caller is responsible for cleaning up any partially initialized + _nodes on failure.*/ int oc_huff_trees_unpack(oc_pack_buf *_opb, - oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]){ + ogg_int16_t *_nodes[TH_NHUFFMAN_TABLES]){ int i; for(i=0;i<TH_NHUFFMAN_TABLES;i++){ - oc_huff_node nodes[511]; - char *storage; - size_t size; - int ret; + unsigned char tokens[256][2]; + int ntokens; + ogg_int16_t *tree; + size_t size; /*Unpack the full tree into a temporary buffer.*/ - ret=oc_huff_tree_unpack(_opb,nodes,sizeof(nodes)/sizeof(*nodes)); - if(ret<0)return ret; - /*Figure out how big the collapsed tree will be.*/ - size=oc_huff_tree_collapse_size(nodes,0); - storage=(char *)_ogg_calloc(1,size); - if(storage==NULL)return TH_EFAULT; - /*And collapse it.*/ - _nodes[i]=oc_huff_tree_collapse(nodes,&storage); + ntokens=oc_huff_tree_unpack(_opb,tokens); + if(ntokens<0)return ntokens; + /*Figure out how big the collapsed tree will be and allocate space for it.*/ + size=oc_huff_tree_collapse(NULL,tokens,ntokens); + /*This should never happen; if it does it means you set OC_HUFF_SLUSH or + OC_ROOT_HUFF_SLUSH too large.*/ + if(size>32767)return TH_EIMPL; + tree=(ogg_int16_t *)_ogg_malloc(size*sizeof(*tree)); + if(tree==NULL)return TH_EFAULT; + /*Construct the collapsed the tree.*/ + oc_huff_tree_collapse(tree,tokens,ntokens); + _nodes[i]=tree; } return 0; } +/*Determines the size in words of a Huffman subtree. + _tree: The complete Huffman tree. + _node: The index of the root of the desired subtree. + Return: The number of words required to store the tree.*/ +static size_t oc_huff_tree_size(const ogg_int16_t *_tree,int _node){ + size_t size; + int nchildren; + int n; + int i; + n=_tree[_node]; + size=oc_huff_node_size(n); + nchildren=1<<n; + i=0; + do{ + int child; + child=_tree[_node+i+1]; + if(child<=0)i+=1<<n-(-child>>8); + else{ + size+=oc_huff_tree_size(_tree,child); + i++; + } + } + while(i<nchildren); + return size; +} + /*Makes a copy of the given set of Huffman trees. _dst: The array to store the copy in. _src: The array of trees to copy.*/ -int oc_huff_trees_copy(oc_huff_node *_dst[TH_NHUFFMAN_TABLES], - const oc_huff_node *const _src[TH_NHUFFMAN_TABLES]){ +int oc_huff_trees_copy(ogg_int16_t *_dst[TH_NHUFFMAN_TABLES], + const ogg_int16_t *const _src[TH_NHUFFMAN_TABLES]){ + int total; int i; + total=0; for(i=0;i<TH_NHUFFMAN_TABLES;i++){ - size_t size; - char *storage; - size=oc_huff_tree_size(_src[i]); - storage=(char *)_ogg_calloc(1,size); - if(storage==NULL){ + size_t size; + size=oc_huff_tree_size(_src[i],0); + total+=size; + _dst[i]=(ogg_int16_t *)_ogg_malloc(size*sizeof(*_dst[i])); + if(_dst[i]==NULL){ while(i-->0)_ogg_free(_dst[i]); return TH_EFAULT; } - _dst[i]=oc_huff_tree_copy(_src[i],&storage); + memcpy(_dst[i],_src[i],size*sizeof(*_dst[i])); } return 0; } /*Frees the memory used by a set of Huffman trees. _nodes: The array of trees to free.*/ -void oc_huff_trees_clear(oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]){ +void oc_huff_trees_clear(ogg_int16_t *_nodes[TH_NHUFFMAN_TABLES]){ int i; for(i=0;i<TH_NHUFFMAN_TABLES;i++)_ogg_free(_nodes[i]); } + /*Unpacks a single token using the given Huffman tree. _opb: The buffer to unpack the token from. _node: The tree to unpack the token with. Return: The token value.*/ -int oc_huff_token_decode(oc_pack_buf *_opb,const oc_huff_node *_node){ - long bits; - while(_node->nbits!=0){ - bits=oc_pack_look(_opb,_node->nbits); - _node=_node->nodes[bits]; - oc_pack_adv(_opb,_node->depth); +int oc_huff_token_decode_c(oc_pack_buf *_opb,const ogg_int16_t *_tree){ + const unsigned char *ptr; + const unsigned char *stop; + oc_pb_window window; + int available; + long bits; + int node; + int n; + ptr=_opb->ptr; + window=_opb->window; + stop=_opb->stop; + available=_opb->bits; + node=0; + for(;;){ + n=_tree[node]; + if(n>available){ + unsigned shift; + shift=OC_PB_WINDOW_SIZE-available; + do{ + /*We don't bother setting eof because we won't check for it after we've + started decoding DCT tokens.*/ + if(ptr>=stop){ + shift=(unsigned)-OC_LOTS_OF_BITS; + break; + } + shift-=8; + window|=(oc_pb_window)*ptr++<<shift; + } + while(shift>=8); + /*Note: We never request more than 24 bits, so there's no need to fill in + the last partial byte here.*/ + available=OC_PB_WINDOW_SIZE-shift; + } + bits=window>>OC_PB_WINDOW_SIZE-n; + node=_tree[node+1+bits]; + if(node<=0)break; + window<<=n; + available-=n; } - return _node->token; + node=-node; + n=node>>8; + window<<=n; + available-=n; + _opb->ptr=ptr; + _opb->window=window; + _opb->bits=available; + return node&255; } diff --git a/thirdparty/libtheora/huffdec.h b/thirdparty/libtheora/huffdec.h index d7ffa0e99b..03d25dcd1e 100644 --- a/thirdparty/libtheora/huffdec.h +++ b/thirdparty/libtheora/huffdec.h @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: huffdec.h 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ @@ -22,71 +22,11 @@ -typedef struct oc_huff_node oc_huff_node; - -/*A node in the Huffman tree. - Instead of storing every branching in the tree, subtrees can be collapsed - into one node, with a table of size 1<<nbits pointing directly to its - descedents nbits levels down. - This allows more than one bit to be read at a time, and avoids following all - the intermediate branches with next to no increased code complexity once - the collapsed tree has been built. - We do _not_ require that a subtree be complete to be collapsed, but instead - store duplicate pointers in the table, and record the actual depth of the - node below its parent. - This tells us the number of bits to advance the stream after reaching it. - - This turns out to be equivalent to the method described in \cite{Hash95}, - without the requirement that codewords be sorted by length. - If the codewords were sorted by length (so-called ``canonical-codes''), they - could be decoded much faster via either Lindell and Moffat's approach or - Hashemian's Condensed Huffman Code approach, the latter of which has an - extremely small memory footprint. - We can't use Choueka et al.'s finite state machine approach, which is - extremely fast, because we can't allow multiple symbols to be output at a - time; the codebook can and does change between symbols. - It also has very large memory requirements, which impairs cache coherency. - - @ARTICLE{Hash95, - author="Reza Hashemian", - title="Memory Efficient and High-Speed Search {Huffman} Coding", - journal="{IEEE} Transactions on Communications", - volume=43, - number=10, - pages="2576--2581", - month=Oct, - year=1995 - }*/ -struct oc_huff_node{ - /*The number of bits of the code needed to descend through this node. - 0 indicates a leaf node. - Otherwise there are 1<<nbits nodes in the nodes table, which can be - indexed by reading nbits bits from the stream.*/ - unsigned char nbits; - /*The value of a token stored in a leaf node. - The value in non-leaf nodes is undefined.*/ - unsigned char token; - /*The depth of the current node, relative to its parent in the collapsed - tree. - This can be less than its parent's nbits value, in which case there are - 1<<nbits-depth copies of this node in the table, and the bitstream should - only be advanced depth bits after reaching this node.*/ - unsigned char depth; - /*The table of child nodes. - The ACTUAL size of this array is 1<<nbits, despite what the declaration - below claims. - The exception is that for leaf nodes the size is 0.*/ - oc_huff_node *nodes[2]; -}; - - - int oc_huff_trees_unpack(oc_pack_buf *_opb, - oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]); -int oc_huff_trees_copy(oc_huff_node *_dst[TH_NHUFFMAN_TABLES], - const oc_huff_node *const _src[TH_NHUFFMAN_TABLES]); -void oc_huff_trees_clear(oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]); -int oc_huff_token_decode(oc_pack_buf *_opb,const oc_huff_node *_node); - + ogg_int16_t *_nodes[TH_NHUFFMAN_TABLES]); +int oc_huff_trees_copy(ogg_int16_t *_dst[TH_NHUFFMAN_TABLES], + const ogg_int16_t *const _src[TH_NHUFFMAN_TABLES]); +void oc_huff_trees_clear(ogg_int16_t *_nodes[TH_NHUFFMAN_TABLES]); +int oc_huff_token_decode_c(oc_pack_buf *_opb,const ogg_int16_t *_node); #endif diff --git a/thirdparty/libtheora/huffenc.c b/thirdparty/libtheora/huffenc.c index bf624e0523..77ab584a19 100644 --- a/thirdparty/libtheora/huffenc.c +++ b/thirdparty/libtheora/huffenc.c @@ -859,9 +859,10 @@ int oc_huff_codes_pack(oggpack_buffer *_opb, /*First, find the maximum code length so we can align all the bit patterns.*/ maxlen=_codes[i][0].nbits; - for(j=1;j<TH_NDCT_TOKENS;j++){ - maxlen=OC_MAXI(_codes[i][j].nbits,maxlen); - } + for(j=1;j<TH_NDCT_TOKENS;j++)maxlen=OC_MAXI(_codes[i][j].nbits,maxlen); + /*It's improbable that a code with more than 32 bits could pass the + validation below, but abort early in any case.*/ + if(maxlen>32)return TH_EINVAL; mask=(1<<(maxlen>>1)<<(maxlen+1>>1))-1; /*Copy over the codes into our temporary workspace. The bit patterns are aligned, and the original entry each code is from @@ -877,34 +878,89 @@ int oc_huff_codes_pack(oggpack_buffer *_opb, /*For each leaf of the tree:*/ bpos=maxlen; for(j=0;j<TH_NDCT_TOKENS;j++){ - int bit; - /*If this code has any bits at all.*/ - if(entries[j].shift<maxlen){ - /*Descend into the tree, writing a bit for each branch.*/ - for(;bpos>entries[j].shift;bpos--)oggpackB_write(_opb,0,1); - /*Mark this as a leaf node, and write its value.*/ - oggpackB_write(_opb,1,1); - oggpackB_write(_opb,entries[j].token,5); - /*For each 1 branch we've descended, back up the tree until we reach a - 0 branch.*/ - bit=1<<bpos; - for(;entries[j].pattern&bit;bpos++)bit<<=1; - /*Validate the code.*/ - if(j+1<TH_NDCT_TOKENS){ - mask=~(bit-1)<<1; - /*The next entry should have a 1 bit where we had a 0, and should - match our code above that bit. - This verifies both fullness and prefix-freeness simultaneously.*/ - if(!(entries[j+1].pattern&bit)|| - (entries[j].pattern&mask)!=(entries[j+1].pattern&mask)){ - return TH_EINVAL; - } + ogg_uint32_t bit; + /*Fail if this code has no bits at all. + Technically a codebook with a single 0-bit entry is legal, but the + encoder currently does not support codebooks which do not contain all + the tokens.*/ + if(entries[j].shift>=maxlen)return TH_EINVAL; + /*Descend into the tree, writing a bit for each branch.*/ + for(;bpos>entries[j].shift;bpos--)oggpackB_write(_opb,0,1); + /*Mark this as a leaf node, and write its value.*/ + oggpackB_write(_opb,1,1); + oggpackB_write(_opb,entries[j].token,5); + /*For each 1 branch we've descended, back up the tree until we reach a + 0 branch.*/ + bit=(ogg_uint32_t)1<<bpos; + for(;entries[j].pattern&bit;bpos++)bit<<=1; + /*Validate the code.*/ + if(j+1<TH_NDCT_TOKENS){ + mask=~(bit-1)<<1; + /*The next entry should have a 1 bit where we had a 0, and should + match our code above that bit. + This verifies both fullness and prefix-freeness simultaneously.*/ + if(!(entries[j+1].pattern&bit)|| + (entries[j].pattern&mask)!=(entries[j+1].pattern&mask)){ + return TH_EINVAL; + } + } + /*If there are no more codes, we should have ascended back to the top + of the tree.*/ + else if(bpos<maxlen)return TH_EINVAL; + } + } + return 0; +} + +/*This is used to copy the configuration of an existing setup header for use by + the encoder. + The decoder uses a completely different data structure for the Huffman + codebooks.*/ +int oc_huff_codes_unpack(oc_pack_buf *_opb, + th_huff_code _codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS]){ + int i; + for(i=0;i<TH_NHUFFMAN_TABLES;i++){ + ogg_uint32_t code; + int len; + int nleaves; + code=0; + len=nleaves=0; + memset(_codes[i],0,TH_NDCT_TOKENS*sizeof(*_codes[i])); + for(;;){ + long bits; + bits=oc_pack_read1(_opb); + /*Only process nodes so long as there's more bits in the buffer.*/ + if(oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER; + /*Read an internal node:*/ + if(!bits){ + len++; + /*Don't allow codewords longer than 32 bits.*/ + if(len>32)return TH_EBADHEADER; + } + /*Read a leaf node:*/ + else{ + ogg_uint32_t code_bit; + /*Don't allow more than 32 tokens per codebook.*/ + if(++nleaves>32)return TH_EBADHEADER; + bits=oc_pack_read(_opb,OC_NDCT_TOKEN_BITS); + /*The current encoder does not support codebooks that do not contain + all of the tokens.*/ + if(_codes[i][bits].nbits>0)return TH_EINVAL; + _codes[i][bits].pattern=code>>32-len; + _codes[i][bits].nbits=len; + code_bit=0x80000000U>>len-1; + while(len>0&&(code&code_bit)){ + code^=code_bit; + code_bit<<=1; + len--; } - /*If there are no more codes, we should have ascended back to the top - of the tree.*/ - else if(bpos<maxlen)return TH_EINVAL; + if(len<=0)break; + code|=code_bit; } } + /*The current encoder does not support codebooks that do not contain all of + the tokens.*/ + if(nleaves<32)return TH_EINVAL; } return 0; } diff --git a/thirdparty/libtheora/huffenc.h b/thirdparty/libtheora/huffenc.h index c5a3956f1f..0554cc4060 100644 --- a/thirdparty/libtheora/huffenc.h +++ b/thirdparty/libtheora/huffenc.h @@ -1,6 +1,7 @@ #if !defined(_huffenc_H) # define _huffenc_H (1) # include "huffman.h" +# include "bitpack.h" @@ -15,5 +16,7 @@ extern const th_huff_code int oc_huff_codes_pack(oggpack_buffer *_opb, const th_huff_code _codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS]); +int oc_huff_codes_unpack(oc_pack_buf *_opb, + th_huff_code _codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS]); #endif diff --git a/thirdparty/libtheora/huffman.h b/thirdparty/libtheora/huffman.h index 36cf7572e5..eb805866b9 100644 --- a/thirdparty/libtheora/huffman.h +++ b/thirdparty/libtheora/huffman.h @@ -11,12 +11,12 @@ ******************************************************************** function: - last mod: $Id: huffman.h 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ #if !defined(_huffman_H) -# define _hufffman_H (1) +# define _huffman_H (1) # include "theora/codec.h" # include "ocintrin.h" diff --git a/thirdparty/libtheora/idct.c b/thirdparty/libtheora/idct.c index 0e68ac7658..838e3ad8ca 100644 --- a/thirdparty/libtheora/idct.c +++ b/thirdparty/libtheora/idct.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: idct.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ @@ -231,18 +231,18 @@ static void idct8_1(ogg_int16_t *_y,const ogg_int16_t _x[1]){ _y: The buffer to store the result in. This may be the same as _x. _x: The input coefficients.*/ -static void oc_idct8x8_3(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ - const ogg_int16_t *in; - ogg_int16_t *end; - ogg_int16_t *out; - ogg_int16_t w[64]; +static void oc_idct8x8_3(ogg_int16_t _y[64],ogg_int16_t _x[64]){ + ogg_int16_t w[64]; + int i; /*Transform rows of x into columns of w.*/ idct8_2(w,_x); idct8_1(w+1,_x+8); /*Transform rows of w into columns of y.*/ - for(in=w,out=_y,end=out+8;out<end;in+=8,out++)idct8_2(out,in); + for(i=0;i<8;i++)idct8_2(_y+i,w+i*8); /*Adjust for the scale factor.*/ - for(out=_y,end=out+64;out<end;out++)*out=(ogg_int16_t)(*out+8>>4); + for(i=0;i<64;i++)_y[i]=(ogg_int16_t)(_y[i]+8>>4); + /*Clear input data for next block.*/ + _x[0]=_x[1]=_x[8]=0; } /*Performs an inverse 8x8 Type-II DCT transform. @@ -260,20 +260,20 @@ static void oc_idct8x8_3(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ _y: The buffer to store the result in. This may be the same as _x. _x: The input coefficients.*/ -static void oc_idct8x8_10(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ - const ogg_int16_t *in; - ogg_int16_t *end; - ogg_int16_t *out; - ogg_int16_t w[64]; +static void oc_idct8x8_10(ogg_int16_t _y[64],ogg_int16_t _x[64]){ + ogg_int16_t w[64]; + int i; /*Transform rows of x into columns of w.*/ idct8_4(w,_x); idct8_3(w+1,_x+8); idct8_2(w+2,_x+16); idct8_1(w+3,_x+24); /*Transform rows of w into columns of y.*/ - for(in=w,out=_y,end=out+8;out<end;in+=8,out++)idct8_4(out,in); + for(i=0;i<8;i++)idct8_4(_y+i,w+i*8); /*Adjust for the scale factor.*/ - for(out=_y,end=out+64;out<end;out++)*out=(ogg_int16_t)(*out+8>>4); + for(i=0;i<64;i++)_y[i]=(ogg_int16_t)(_y[i]+8>>4); + /*Clear input data for next block.*/ + _x[0]=_x[1]=_x[2]=_x[3]=_x[8]=_x[9]=_x[10]=_x[16]=_x[17]=_x[24]=0; } /*Performs an inverse 8x8 Type-II DCT transform. @@ -282,28 +282,23 @@ static void oc_idct8x8_10(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ _y: The buffer to store the result in. This may be the same as _x. _x: The input coefficients.*/ -static void oc_idct8x8_slow(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ - const ogg_int16_t *in; - ogg_int16_t *end; - ogg_int16_t *out; - ogg_int16_t w[64]; +static void oc_idct8x8_slow(ogg_int16_t _y[64],ogg_int16_t _x[64]){ + ogg_int16_t w[64]; + int i; /*Transform rows of x into columns of w.*/ - for(in=_x,out=w,end=out+8;out<end;in+=8,out++)idct8(out,in); + for(i=0;i<8;i++)idct8(w+i,_x+i*8); /*Transform rows of w into columns of y.*/ - for(in=w,out=_y,end=out+8;out<end;in+=8,out++)idct8(out,in); + for(i=0;i<8;i++)idct8(_y+i,w+i*8); /*Adjust for the scale factor.*/ - for(out=_y,end=out+64;out<end;out++)*out=(ogg_int16_t)(*out+8>>4); -} - -void oc_idct8x8(const oc_theora_state *_state,ogg_int16_t _y[64], - int _last_zzi){ - (*_state->opt_vtable.idct8x8)(_y,_last_zzi); + for(i=0;i<64;i++)_y[i]=(ogg_int16_t)(_y[i]+8>>4); + /*Clear input data for next block.*/ + for(i=0;i<64;i++)_x[i]=0; } /*Performs an inverse 8x8 Type-II DCT transform. The input is assumed to be scaled by a factor of 4 relative to orthonormal version of the transform.*/ -void oc_idct8x8_c(ogg_int16_t _y[64],int _last_zzi){ +void oc_idct8x8_c(ogg_int16_t _y[64],ogg_int16_t _x[64],int _last_zzi){ /*_last_zzi is subtly different from an actual count of the number of coefficients we decoded for this block. It contains the value of zzi BEFORE the final token in the block was @@ -329,7 +324,7 @@ void oc_idct8x8_c(ogg_int16_t _y[64],int _last_zzi){ gets. Needless to say we inherited this approach from VP3.*/ /*Then perform the iDCT.*/ - if(_last_zzi<3)oc_idct8x8_3(_y,_y); - else if(_last_zzi<10)oc_idct8x8_10(_y,_y); - else oc_idct8x8_slow(_y,_y); + if(_last_zzi<=3)oc_idct8x8_3(_y,_x); + else if(_last_zzi<=10)oc_idct8x8_10(_y,_x); + else oc_idct8x8_slow(_y,_x); } diff --git a/thirdparty/libtheora/info.c b/thirdparty/libtheora/info.c index 6b9762978b..e5cecd2de5 100644 --- a/thirdparty/libtheora/info.c +++ b/thirdparty/libtheora/info.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: info.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ @@ -54,7 +54,7 @@ void th_comment_init(th_comment *_tc){ memset(_tc,0,sizeof(*_tc)); } -void th_comment_add(th_comment *_tc,char *_comment){ +void th_comment_add(th_comment *_tc,const char *_comment){ char **user_comments; int *comment_lengths; int comment_len; @@ -75,7 +75,7 @@ void th_comment_add(th_comment *_tc,char *_comment){ _tc->user_comments[_tc->comments]=NULL; } -void th_comment_add_tag(th_comment *_tc,char *_tag,char *_val){ +void th_comment_add_tag(th_comment *_tc,const char *_tag,const char *_val){ char *comment; int tag_len; int val_len; @@ -91,7 +91,7 @@ void th_comment_add_tag(th_comment *_tc,char *_tag,char *_val){ _ogg_free(comment); } -char *th_comment_query(th_comment *_tc,char *_tag,int _count){ +char *th_comment_query(th_comment *_tc,const char *_tag,int _count){ long i; int found; int tag_len; @@ -107,7 +107,7 @@ char *th_comment_query(th_comment *_tc,char *_tag,int _count){ return NULL; } -int th_comment_query_count(th_comment *_tc,char *_tag){ +int th_comment_query_count(th_comment *_tc,const char *_tag){ long i; int tag_len; int count; diff --git a/thirdparty/libtheora/internal.c b/thirdparty/libtheora/internal.c index 0fe4f63e72..afbb6efae7 100644 --- a/thirdparty/libtheora/internal.c +++ b/thirdparty/libtheora/internal.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: internal.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ @@ -97,79 +97,29 @@ int oc_ilog(unsigned _v){ -/*The function used to fill in the chroma plane motion vectors for a macro - block when 4 different motion vectors are specified in the luma plane. - This version is for use with chroma decimated in the X and Y directions - (4:2:0). - _cbmvs: The chroma block-level motion vectors to fill in. - _lbmvs: The luma block-level motion vectors.*/ -static void oc_set_chroma_mvs00(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){ - int dx; - int dy; - dx=_lbmvs[0][0]+_lbmvs[1][0]+_lbmvs[2][0]+_lbmvs[3][0]; - dy=_lbmvs[0][1]+_lbmvs[1][1]+_lbmvs[2][1]+_lbmvs[3][1]; - _cbmvs[0][0]=(signed char)OC_DIV_ROUND_POW2(dx,2,2); - _cbmvs[0][1]=(signed char)OC_DIV_ROUND_POW2(dy,2,2); -} - -/*The function used to fill in the chroma plane motion vectors for a macro - block when 4 different motion vectors are specified in the luma plane. - This version is for use with chroma decimated in the Y direction. - _cbmvs: The chroma block-level motion vectors to fill in. - _lbmvs: The luma block-level motion vectors.*/ -static void oc_set_chroma_mvs01(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){ - int dx; - int dy; - dx=_lbmvs[0][0]+_lbmvs[2][0]; - dy=_lbmvs[0][1]+_lbmvs[2][1]; - _cbmvs[0][0]=(signed char)OC_DIV_ROUND_POW2(dx,1,1); - _cbmvs[0][1]=(signed char)OC_DIV_ROUND_POW2(dy,1,1); - dx=_lbmvs[1][0]+_lbmvs[3][0]; - dy=_lbmvs[1][1]+_lbmvs[3][1]; - _cbmvs[1][0]=(signed char)OC_DIV_ROUND_POW2(dx,1,1); - _cbmvs[1][1]=(signed char)OC_DIV_ROUND_POW2(dy,1,1); -} - -/*The function used to fill in the chroma plane motion vectors for a macro - block when 4 different motion vectors are specified in the luma plane. - This version is for use with chroma decimated in the X direction (4:2:2). - _cbmvs: The chroma block-level motion vectors to fill in. - _lbmvs: The luma block-level motion vectors.*/ -static void oc_set_chroma_mvs10(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){ - int dx; - int dy; - dx=_lbmvs[0][0]+_lbmvs[1][0]; - dy=_lbmvs[0][1]+_lbmvs[1][1]; - _cbmvs[0][0]=(signed char)OC_DIV_ROUND_POW2(dx,1,1); - _cbmvs[0][1]=(signed char)OC_DIV_ROUND_POW2(dy,1,1); - dx=_lbmvs[2][0]+_lbmvs[3][0]; - dy=_lbmvs[2][1]+_lbmvs[3][1]; - _cbmvs[2][0]=(signed char)OC_DIV_ROUND_POW2(dx,1,1); - _cbmvs[2][1]=(signed char)OC_DIV_ROUND_POW2(dy,1,1); +void *oc_aligned_malloc(size_t _sz,size_t _align){ + unsigned char *p; + if(_align-1>UCHAR_MAX||(_align&_align-1)||_sz>~(size_t)0-_align)return NULL; + p=(unsigned char *)_ogg_malloc(_sz+_align); + if(p!=NULL){ + int offs; + offs=((p-(unsigned char *)0)-1&_align-1); + p[offs]=offs; + p+=offs+1; + } + return p; } -/*The function used to fill in the chroma plane motion vectors for a macro - block when 4 different motion vectors are specified in the luma plane. - This version is for use with no chroma decimation (4:4:4). - _cbmvs: The chroma block-level motion vectors to fill in. - _lmbmv: The luma macro-block level motion vector to fill in for use in - prediction. - _lbmvs: The luma block-level motion vectors.*/ -static void oc_set_chroma_mvs11(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){ - memcpy(_cbmvs,_lbmvs,4*sizeof(_lbmvs[0])); +void oc_aligned_free(void *_ptr){ + unsigned char *p; + p=(unsigned char *)_ptr; + if(p!=NULL){ + int offs; + offs=*--p; + _ogg_free(p-offs); + } } -/*A table of functions used to fill in the chroma plane motion vectors for a - macro block when 4 different motion vectors are specified in the luma - plane.*/ -const oc_set_chroma_mvs_func OC_SET_CHROMA_MVS_TABLE[TH_PF_NFORMATS]={ - (oc_set_chroma_mvs_func)oc_set_chroma_mvs00, - (oc_set_chroma_mvs_func)oc_set_chroma_mvs01, - (oc_set_chroma_mvs_func)oc_set_chroma_mvs10, - (oc_set_chroma_mvs_func)oc_set_chroma_mvs11 -}; - - void **oc_malloc_2d(size_t _height,size_t _width,size_t _sz){ size_t rowsz; @@ -181,7 +131,6 @@ void **oc_malloc_2d(size_t _height,size_t _width,size_t _sz){ datsz=rowsz*_height; /*Alloc array and row pointers.*/ ret=(char *)_ogg_malloc(datsz+colsz); - if(ret==NULL)return NULL; /*Initialize the array.*/ if(ret!=NULL){ size_t i; @@ -204,7 +153,6 @@ void **oc_calloc_2d(size_t _height,size_t _width,size_t _sz){ datsz=rowsz*_height; /*Alloc array and row pointers.*/ ret=(char *)_ogg_calloc(datsz+colsz,1); - if(ret==NULL)return NULL; /*Initialize the array.*/ if(ret!=NULL){ size_t i; diff --git a/thirdparty/libtheora/internal.h b/thirdparty/libtheora/internal.h index d81263e13e..53c77b88be 100644 --- a/thirdparty/libtheora/internal.h +++ b/thirdparty/libtheora/internal.h @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: internal.h 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ #if !defined(_internal_H) @@ -19,10 +19,20 @@ # include <stdlib.h> # include <limits.h> # if defined(HAVE_CONFIG_H) -# include <config.h> +# include "config.h" # endif # include "theora/codec.h" # include "theora/theora.h" +# include "ocintrin.h" + +# if !defined(__GNUC_PREREQ) +# if defined(__GNUC__)&&defined(__GNUC_MINOR__) +# define __GNUC_PREREQ(_maj,_min) \ + ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) +# else +# define __GNUC_PREREQ(_maj,_min) 0 +# endif +# endif # if defined(_MSC_VER) /*Disable missing EMMS warnings.*/ @@ -31,24 +41,25 @@ # pragma warning(disable:4554) # endif /*You, too, gcc.*/ -# if defined(__GNUC_PREREQ) -# if __GNUC_PREREQ(4,2) -# pragma GCC diagnostic ignored "-Wparentheses" -# endif +# if __GNUC_PREREQ(4,2) +# pragma GCC diagnostic ignored "-Wparentheses" # endif -# include "ocintrin.h" -# include "huffman.h" -# include "quant.h" - -/*Some assembly constructs require aligned operands.*/ -# if defined(OC_X86_ASM) +/*Some assembly constructs require aligned operands. + The following macros are _only_ intended for structure member declarations. + Although they will sometimes work on stack variables, gcc will often silently + ignore them. + A separate set of macros could be made for manual stack alignment, but we + don't actually require it anywhere.*/ +# if defined(OC_X86_ASM)||defined(OC_ARM_ASM) # if defined(__GNUC__) # define OC_ALIGN8(expr) expr __attribute__((aligned(8))) # define OC_ALIGN16(expr) expr __attribute__((aligned(16))) # elif defined(_MSC_VER) # define OC_ALIGN8(expr) __declspec (align(8)) expr # define OC_ALIGN16(expr) __declspec (align(16)) expr +# else +# error "Alignment macros required for this platform." # endif # endif # if !defined(OC_ALIGN8) @@ -60,19 +71,8 @@ -typedef struct oc_sb_flags oc_sb_flags; -typedef struct oc_border_info oc_border_info; -typedef struct oc_fragment oc_fragment; -typedef struct oc_fragment_plane oc_fragment_plane; -typedef struct oc_base_opt_vtable oc_base_opt_vtable; -typedef struct oc_base_opt_data oc_base_opt_data; -typedef struct oc_state_dispatch_vtable oc_state_dispatch_vtable; -typedef struct oc_theora_state oc_theora_state; - - - /*This library's version.*/ -# define OC_VENDOR_STRING "Xiph.Org libtheora 1.1 20090822 (Thusnelda)" +# define OC_VENDOR_STRING "Xiph.Org libtheora 1.2.0alpha 20100924 (Ptalarbvorm)" /*Theora bitstream version.*/ # define TH_VERSION_MAJOR (3) @@ -83,315 +83,6 @@ typedef struct oc_theora_state oc_theora_state; ((_info)->version_minor>(_min)||(_info)->version_minor==(_min)&& \ (_info)->version_subminor>=(_sub))) -/*A keyframe.*/ -#define OC_INTRA_FRAME (0) -/*A predicted frame.*/ -#define OC_INTER_FRAME (1) -/*A frame of unknown type (frame type decision has not yet been made).*/ -#define OC_UNKWN_FRAME (-1) - -/*The amount of padding to add to the reconstructed frame buffers on all - sides. - This is used to allow unrestricted motion vectors without special casing. - This must be a multiple of 2.*/ -#define OC_UMV_PADDING (16) - -/*Frame classification indices.*/ -/*The previous golden frame.*/ -#define OC_FRAME_GOLD (0) -/*The previous frame.*/ -#define OC_FRAME_PREV (1) -/*The current frame.*/ -#define OC_FRAME_SELF (2) - -/*The input or output buffer.*/ -#define OC_FRAME_IO (3) - -/*Macroblock modes.*/ -/*Macro block is invalid: It is never coded.*/ -#define OC_MODE_INVALID (-1) -/*Encoded difference from the same macro block in the previous frame.*/ -#define OC_MODE_INTER_NOMV (0) -/*Encoded with no motion compensated prediction.*/ -#define OC_MODE_INTRA (1) -/*Encoded difference from the previous frame offset by the given motion - vector.*/ -#define OC_MODE_INTER_MV (2) -/*Encoded difference from the previous frame offset by the last coded motion - vector.*/ -#define OC_MODE_INTER_MV_LAST (3) -/*Encoded difference from the previous frame offset by the second to last - coded motion vector.*/ -#define OC_MODE_INTER_MV_LAST2 (4) -/*Encoded difference from the same macro block in the previous golden - frame.*/ -#define OC_MODE_GOLDEN_NOMV (5) -/*Encoded difference from the previous golden frame offset by the given motion - vector.*/ -#define OC_MODE_GOLDEN_MV (6) -/*Encoded difference from the previous frame offset by the individual motion - vectors given for each block.*/ -#define OC_MODE_INTER_MV_FOUR (7) -/*The number of (coded) modes.*/ -#define OC_NMODES (8) - -/*Determines the reference frame used for a given MB mode.*/ -#define OC_FRAME_FOR_MODE(_x) \ - OC_UNIBBLE_TABLE32(OC_FRAME_PREV,OC_FRAME_SELF,OC_FRAME_PREV,OC_FRAME_PREV, \ - OC_FRAME_PREV,OC_FRAME_GOLD,OC_FRAME_GOLD,OC_FRAME_PREV,(_x)) - -/*Constants for the packet state machine common between encoder and decoder.*/ - -/*Next packet to emit/read: Codec info header.*/ -#define OC_PACKET_INFO_HDR (-3) -/*Next packet to emit/read: Comment header.*/ -#define OC_PACKET_COMMENT_HDR (-2) -/*Next packet to emit/read: Codec setup header.*/ -#define OC_PACKET_SETUP_HDR (-1) -/*No more packets to emit/read.*/ -#define OC_PACKET_DONE (INT_MAX) - - - -/*Super blocks are 32x32 segments of pixels in a single color plane indexed - in image order. - Internally, super blocks are broken up into four quadrants, each of which - contains a 2x2 pattern of blocks, each of which is an 8x8 block of pixels. - Quadrants, and the blocks within them, are indexed in a special order called - a "Hilbert curve" within the super block. - - In order to differentiate between the Hilbert-curve indexing strategy and - the regular image order indexing strategy, blocks indexed in image order - are called "fragments". - Fragments are indexed in image order, left to right, then bottom to top, - from Y' plane to Cb plane to Cr plane. - - The co-located fragments in all image planes corresponding to the location - of a single quadrant of a luma plane super block form a macro block. - Thus there is only a single set of macro blocks for all planes, each of which - contains between 6 and 12 fragments, depending on the pixel format. - Therefore macro block information is kept in a separate set of arrays from - super blocks to avoid unused space in the other planes. - The lists are indexed in super block order. - That is, the macro block corresponding to the macro block mbi in (luma plane) - super block sbi is at index (sbi<<2|mbi). - Thus the number of macro blocks in each dimension is always twice the number - of super blocks, even when only an odd number fall inside the coded frame. - These "extra" macro blocks are just an artifact of our internal data layout, - and not part of the coded stream; they are flagged with a negative MB mode.*/ - - - -/*A single quadrant of the map from a super block to fragment numbers.*/ -typedef ptrdiff_t oc_sb_map_quad[4]; -/*A map from a super block to fragment numbers.*/ -typedef oc_sb_map_quad oc_sb_map[4]; -/*A single plane of the map from a macro block to fragment numbers.*/ -typedef ptrdiff_t oc_mb_map_plane[4]; -/*A map from a macro block to fragment numbers.*/ -typedef oc_mb_map_plane oc_mb_map[3]; -/*A motion vector.*/ -typedef signed char oc_mv[2]; - - - -/*Super block information.*/ -struct oc_sb_flags{ - unsigned char coded_fully:1; - unsigned char coded_partially:1; - unsigned char quad_valid:4; -}; - - - -/*Information about a fragment which intersects the border of the displayable - region. - This marks which pixels belong to the displayable region.*/ -struct oc_border_info{ - /*A bit mask marking which pixels are in the displayable region. - Pixel (x,y) corresponds to bit (y<<3|x).*/ - ogg_int64_t mask; - /*The number of pixels in the displayable region. - This is always positive, and always less than 64.*/ - int npixels; -}; - - - -/*Fragment information.*/ -struct oc_fragment{ - /*A flag indicating whether or not this fragment is coded.*/ - unsigned coded:1; - /*A flag indicating that this entire fragment lies outside the displayable - region of the frame. - Note the contrast with an invalid macro block, which is outside the coded - frame, not just the displayable one. - There are no fragments outside the coded frame by construction.*/ - unsigned invalid:1; - /*The index of the quality index used for this fragment's AC coefficients.*/ - unsigned qii:6; - /*The mode of the macroblock this fragment belongs to.*/ - unsigned mb_mode:3; - /*The index of the associated border information for fragments which lie - partially outside the displayable region. - For fragments completely inside or outside this region, this is -1. - Note that the C standard requires an explicit signed keyword for bitfield - types, since some compilers may treat them as unsigned without it.*/ - signed int borderi:5; - /*The prediction-corrected DC component. - Note that the C standard requires an explicit signed keyword for bitfield - types, since some compilers may treat them as unsigned without it.*/ - signed int dc:16; -}; - - - -/*A description of each fragment plane.*/ -struct oc_fragment_plane{ - /*The number of fragments in the horizontal direction.*/ - int nhfrags; - /*The number of fragments in the vertical direction.*/ - int nvfrags; - /*The offset of the first fragment in the plane.*/ - ptrdiff_t froffset; - /*The total number of fragments in the plane.*/ - ptrdiff_t nfrags; - /*The number of super blocks in the horizontal direction.*/ - unsigned nhsbs; - /*The number of super blocks in the vertical direction.*/ - unsigned nvsbs; - /*The offset of the first super block in the plane.*/ - unsigned sboffset; - /*The total number of super blocks in the plane.*/ - unsigned nsbs; -}; - - - -/*The shared (encoder and decoder) functions that have accelerated variants.*/ -struct oc_base_opt_vtable{ - void (*frag_copy)(unsigned char *_dst, - const unsigned char *_src,int _ystride); - void (*frag_recon_intra)(unsigned char *_dst,int _ystride, - const ogg_int16_t _residue[64]); - void (*frag_recon_inter)(unsigned char *_dst, - const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]); - void (*frag_recon_inter2)(unsigned char *_dst,const unsigned char *_src1, - const unsigned char *_src2,int _ystride,const ogg_int16_t _residue[64]); - void (*idct8x8)(ogg_int16_t _y[64],int _last_zzi); - void (*state_frag_recon)(const oc_theora_state *_state,ptrdiff_t _fragi, - int _pli,ogg_int16_t _dct_coeffs[64],int _last_zzi,ogg_uint16_t _dc_quant); - void (*state_frag_copy_list)(const oc_theora_state *_state, - const ptrdiff_t *_fragis,ptrdiff_t _nfragis, - int _dst_frame,int _src_frame,int _pli); - void (*state_loop_filter_frag_rows)(const oc_theora_state *_state, - int _bv[256],int _refi,int _pli,int _fragy0,int _fragy_end); - void (*restore_fpu)(void); -}; - -/*The shared (encoder and decoder) tables that vary according to which variants - of the above functions are used.*/ -struct oc_base_opt_data{ - const unsigned char *dct_fzig_zag; -}; - - -/*State information common to both the encoder and decoder.*/ -struct oc_theora_state{ - /*The stream information.*/ - th_info info; - /*Table for shared accelerated functions.*/ - oc_base_opt_vtable opt_vtable; - /*Table for shared data used by accelerated functions.*/ - oc_base_opt_data opt_data; - /*CPU flags to detect the presence of extended instruction sets.*/ - ogg_uint32_t cpu_flags; - /*The fragment plane descriptions.*/ - oc_fragment_plane fplanes[3]; - /*The list of fragments, indexed in image order.*/ - oc_fragment *frags; - /*The the offset into the reference frame buffer to the upper-left pixel of - each fragment.*/ - ptrdiff_t *frag_buf_offs; - /*The motion vector for each fragment.*/ - oc_mv *frag_mvs; - /*The total number of fragments in a single frame.*/ - ptrdiff_t nfrags; - /*The list of super block maps, indexed in image order.*/ - oc_sb_map *sb_maps; - /*The list of super block flags, indexed in image order.*/ - oc_sb_flags *sb_flags; - /*The total number of super blocks in a single frame.*/ - unsigned nsbs; - /*The fragments from each color plane that belong to each macro block. - Fragments are stored in image order (left to right then top to bottom). - When chroma components are decimated, the extra fragments have an index of - -1.*/ - oc_mb_map *mb_maps; - /*The list of macro block modes. - A negative number indicates the macro block lies entirely outside the - coded frame.*/ - signed char *mb_modes; - /*The number of macro blocks in the X direction.*/ - unsigned nhmbs; - /*The number of macro blocks in the Y direction.*/ - unsigned nvmbs; - /*The total number of macro blocks.*/ - size_t nmbs; - /*The list of coded fragments, in coded order. - Uncoded fragments are stored in reverse order from the end of the list.*/ - ptrdiff_t *coded_fragis; - /*The number of coded fragments in each plane.*/ - ptrdiff_t ncoded_fragis[3]; - /*The total number of coded fragments.*/ - ptrdiff_t ntotal_coded_fragis; - /*The index of the buffers being used for each OC_FRAME_* reference frame.*/ - int ref_frame_idx[4]; - /*The actual buffers used for the previously decoded frames.*/ - th_ycbcr_buffer ref_frame_bufs[4]; - /*The storage for the reference frame buffers.*/ - unsigned char *ref_frame_data[4]; - /*The strides for each plane in the reference frames.*/ - int ref_ystride[3]; - /*The number of unique border patterns.*/ - int nborders; - /*The unique border patterns for all border fragments. - The borderi field of fragments which straddle the border indexes this - list.*/ - oc_border_info borders[16]; - /*The frame number of the last keyframe.*/ - ogg_int64_t keyframe_num; - /*The frame number of the current frame.*/ - ogg_int64_t curframe_num; - /*The granpos of the current frame.*/ - ogg_int64_t granpos; - /*The type of the current frame.*/ - unsigned char frame_type; - /*The bias to add to the frame count when computing granule positions.*/ - unsigned char granpos_bias; - /*The number of quality indices used in the current frame.*/ - unsigned char nqis; - /*The quality indices of the current frame.*/ - unsigned char qis[3]; - /*The dequantization tables, stored in zig-zag order, and indexed by - qi, pli, qti, and zzi.*/ - ogg_uint16_t *dequant_tables[64][3][2]; - OC_ALIGN16(oc_quant_table dequant_table_data[64][3][2]); - /*Loop filter strength parameters.*/ - unsigned char loop_filter_limits[64]; -}; - - - -/*The function type used to fill in the chroma plane motion vectors for a - macro block when 4 different motion vectors are specified in the luma - plane. - _cbmvs: The chroma block-level motion vectors to fill in. - _lmbmv: The luma macro-block level motion vector to fill in for use in - prediction. - _lbmvs: The luma block-level motion vectors.*/ -typedef void (*oc_set_chroma_mvs_func)(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]); - /*A map from the index in the zig zag scan to the coefficient number in a @@ -409,14 +100,12 @@ extern const unsigned char OC_MB_MAP_IDXS[TH_PF_NFORMATS][12]; /*The number of indices in the oc_mb_map array that can be valid for each of the various chroma decimation types.*/ extern const unsigned char OC_MB_MAP_NIDXS[TH_PF_NFORMATS]; -/*A table of functions used to fill in the Cb,Cr plane motion vectors for a - macro block when 4 different motion vectors are specified in the luma - plane.*/ -extern const oc_set_chroma_mvs_func OC_SET_CHROMA_MVS_TABLE[TH_PF_NFORMATS]; int oc_ilog(unsigned _v); +void *oc_aligned_malloc(size_t _sz,size_t _align); +void oc_aligned_free(void *_ptr); void **oc_malloc_2d(size_t _height,size_t _width,size_t _sz); void **oc_calloc_2d(size_t _height,size_t _width,size_t _sz); void oc_free_2d(void *_ptr); @@ -424,86 +113,4 @@ void oc_free_2d(void *_ptr); void oc_ycbcr_buffer_flip(th_ycbcr_buffer _dst, const th_ycbcr_buffer _src); -int oc_state_init(oc_theora_state *_state,const th_info *_info,int _nrefs); -void oc_state_clear(oc_theora_state *_state); -void oc_state_vtable_init_c(oc_theora_state *_state); -void oc_state_borders_fill_rows(oc_theora_state *_state,int _refi,int _pli, - int _y0,int _yend); -void oc_state_borders_fill_caps(oc_theora_state *_state,int _refi,int _pli); -void oc_state_borders_fill(oc_theora_state *_state,int _refi); -void oc_state_fill_buffer_ptrs(oc_theora_state *_state,int _buf_idx, - th_ycbcr_buffer _img); -int oc_state_mbi_for_pos(oc_theora_state *_state,int _mbx,int _mby); -int oc_state_get_mv_offsets(const oc_theora_state *_state,int _offsets[2], - int _pli,int _dx,int _dy); - -int oc_state_loop_filter_init(oc_theora_state *_state,int *_bv); -void oc_state_loop_filter(oc_theora_state *_state,int _frame); -#if defined(OC_DUMP_IMAGES) -int oc_state_dump_frame(const oc_theora_state *_state,int _frame, - const char *_suf); -#endif - -/*Shared accelerated functions.*/ -void oc_frag_copy(const oc_theora_state *_state,unsigned char *_dst, - const unsigned char *_src,int _ystride); -void oc_frag_recon_intra(const oc_theora_state *_state, - unsigned char *_dst,int _dst_ystride,const ogg_int16_t _residue[64]); -void oc_frag_recon_inter(const oc_theora_state *_state,unsigned char *_dst, - const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]); -void oc_frag_recon_inter2(const oc_theora_state *_state, - unsigned char *_dst,const unsigned char *_src1,const unsigned char *_src2, - int _ystride,const ogg_int16_t _residue[64]); -void oc_idct8x8(const oc_theora_state *_state,ogg_int16_t _y[64],int _last_zzi); -void oc_state_frag_recon(const oc_theora_state *_state,ptrdiff_t _fragi, - int _pli,ogg_int16_t _dct_coeffs[64],int _last_zzi,ogg_uint16_t _dc_quant); -void oc_state_frag_copy_list(const oc_theora_state *_state, - const ptrdiff_t *_fragis,ptrdiff_t _nfragis, - int _dst_frame,int _src_frame,int _pli); -void oc_state_loop_filter_frag_rows(const oc_theora_state *_state, - int _bv[256],int _refi,int _pli,int _fragy0,int _fragy_end); -void oc_restore_fpu(const oc_theora_state *_state); - -/*Default pure-C implementations.*/ -void oc_frag_copy_c(unsigned char *_dst, - const unsigned char *_src,int _src_ystride); -void oc_frag_recon_intra_c(unsigned char *_dst,int _dst_ystride, - const ogg_int16_t _residue[64]); -void oc_frag_recon_inter_c(unsigned char *_dst, - const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]); -void oc_frag_recon_inter2_c(unsigned char *_dst,const unsigned char *_src1, - const unsigned char *_src2,int _ystride,const ogg_int16_t _residue[64]); -void oc_idct8x8_c(ogg_int16_t _y[64],int _last_zzi); -void oc_state_frag_recon_c(const oc_theora_state *_state,ptrdiff_t _fragi, - int _pli,ogg_int16_t _dct_coeffs[64],int _last_zzi,ogg_uint16_t _dc_quant); -void oc_state_frag_copy_list_c(const oc_theora_state *_state, - const ptrdiff_t *_fragis,ptrdiff_t _nfragis, - int _dst_frame,int _src_frame,int _pli); -void oc_state_loop_filter_frag_rows_c(const oc_theora_state *_state, - int _bv[256],int _refi,int _pli,int _fragy0,int _fragy_end); -void oc_restore_fpu_c(void); - -/*We need a way to call a few encoder functions without introducing a link-time - dependency into the decoder, while still allowing the old alpha API which - does not distinguish between encoder and decoder objects to be used. - We do this by placing a function table at the start of the encoder object - which can dispatch into the encoder library. - We do a similar thing for the decoder in case we ever decide to split off a - common base library.*/ -typedef void (*oc_state_clear_func)(theora_state *_th); -typedef int (*oc_state_control_func)(theora_state *th,int _req, - void *_buf,size_t _buf_sz); -typedef ogg_int64_t (*oc_state_granule_frame_func)(theora_state *_th, - ogg_int64_t _granulepos); -typedef double (*oc_state_granule_time_func)(theora_state *_th, - ogg_int64_t _granulepos); - - -struct oc_state_dispatch_vtable{ - oc_state_clear_func clear; - oc_state_control_func control; - oc_state_granule_frame_func granule_frame; - oc_state_granule_time_func granule_time; -}; - #endif diff --git a/thirdparty/libtheora/mathops.c b/thirdparty/libtheora/mathops.c index d3fb909194..23c8f6e1ba 100644 --- a/thirdparty/libtheora/mathops.c +++ b/thirdparty/libtheora/mathops.c @@ -1,10 +1,8 @@ +#include "internal.h" #include "mathops.h" -#include <limits.h> /*The fastest fallback strategy for platforms with fast multiplication appears to be based on de Bruijn sequences~\cite{LP98}. - Tests confirmed this to be true even on an ARM11, where it is actually faster - than using the native clz instruction. Define OC_ILOG_NODEBRUIJN to use a simpler fallback on platforms where multiplication or table lookups are too expensive. @@ -15,8 +13,7 @@ year=1998, note="\url{http://supertech.csail.mit.edu/papers/debruijn.pdf}" }*/ -#if !defined(OC_ILOG_NODEBRUIJN)&& \ - !defined(OC_CLZ32)||!defined(OC_CLZ64)&&LONG_MAX<9223372036854775807LL +#if !defined(OC_ILOG_NODEBRUIJN)&&!defined(OC_CLZ32) static const unsigned char OC_DEBRUIJN_IDX32[32]={ 0, 1,28, 2,29,14,24, 3,30,22,20,15,25,17, 4, 8, 31,27,13,23,21,19,16, 7,26,12,18, 6,11, 5,10, 9 @@ -25,7 +22,7 @@ static const unsigned char OC_DEBRUIJN_IDX32[32]={ int oc_ilog32(ogg_uint32_t _v){ #if defined(OC_CLZ32) - return (OC_CLZ32_OFFS-OC_CLZ32(_v))&-!!_v; + return OC_CLZ32_OFFS-OC_CLZ32(_v)&-!!_v; #else /*On a Pentium M, this branchless version tested as the fastest version without multiplications on 1,000,000,000 random 32-bit integers, edging out a @@ -51,12 +48,12 @@ int oc_ilog32(ogg_uint32_t _v){ /*This de Bruijn sequence version is faster if you have a fast multiplier.*/ # else int ret; - ret=_v>0; _v|=_v>>1; _v|=_v>>2; _v|=_v>>4; _v|=_v>>8; _v|=_v>>16; + ret=_v&1; _v=(_v>>1)+1; ret+=OC_DEBRUIJN_IDX32[_v*0x77CB531U>>27&0x1F]; return ret; @@ -66,16 +63,21 @@ int oc_ilog32(ogg_uint32_t _v){ int oc_ilog64(ogg_int64_t _v){ #if defined(OC_CLZ64) - return (OC_CLZ64_OFFS-OC_CLZ64(_v))&-!!_v; + return OC_CLZ64_OFFS-OC_CLZ64(_v)&-!!_v; #else -# if defined(OC_ILOG_NODEBRUIJN) +/*If we don't have a fast 64-bit word implementation, split it into two 32-bit + halves.*/ +# if defined(OC_ILOG_NODEBRUIJN)|| \ + defined(OC_CLZ32)||LONG_MAX<9223372036854775807LL ogg_uint32_t v; int ret; int m; - ret=_v>0; m=(_v>0xFFFFFFFFU)<<5; v=(ogg_uint32_t)(_v>>m); - ret|=m; +# if defined(OC_CLZ32) + ret=m+OC_CLZ32_OFFS-OC_CLZ32(v)&-!!v; +# elif defined(OC_ILOG_NODEBRUIJN) + ret=v>0|m; m=(v>0xFFFFU)<<4; v>>=m; ret|=m; @@ -90,26 +92,19 @@ int oc_ilog64(ogg_int64_t _v){ ret|=m; ret+=v>1; return ret; -# else -/*If we don't have a 64-bit word, split it into two 32-bit halves.*/ -# if LONG_MAX<9223372036854775807LL - ogg_uint32_t v; - int ret; - int m; - ret=_v>0; - m=(_v>0xFFFFFFFFU)<<5; - v=(ogg_uint32_t)(_v>>m); - ret|=m; +# else v|=v>>1; v|=v>>2; v|=v>>4; v|=v>>8; v|=v>>16; + ret=v&1|m; v=(v>>1)+1; ret+=OC_DEBRUIJN_IDX32[v*0x77CB531U>>27&0x1F]; +# endif return ret; -/*Otherwise do it in one 64-bit operation.*/ -# else +/*Otherwise do it in one 64-bit multiply.*/ +# else static const unsigned char OC_DEBRUIJN_IDX64[64]={ 0, 1, 2, 7, 3,13, 8,19, 4,25,14,28, 9,34,20,40, 5,17,26,38,15,46,29,48,10,31,35,54,21,50,41,57, @@ -117,17 +112,16 @@ int oc_ilog64(ogg_int64_t _v){ 62,11,23,32,36,44,52,55,61,22,43,51,60,42,59,58 }; int ret; - ret=_v>0; _v|=_v>>1; _v|=_v>>2; _v|=_v>>4; _v|=_v>>8; _v|=_v>>16; _v|=_v>>32; + ret=(int)_v&1; _v=(_v>>1)+1; ret+=OC_DEBRUIJN_IDX64[_v*0x218A392CD3D5DBF>>58&0x3F]; return ret; -# endif # endif #endif } @@ -294,3 +288,27 @@ ogg_int64_t oc_blog64(ogg_int64_t _w){ } return OC_Q57(ipart)+z; } + +/*Polynomial approximation of a binary exponential. + Q10 input, Q0 output.*/ +ogg_uint32_t oc_bexp32_q10(int _z){ + unsigned n; + int ipart; + ipart=_z>>10; + n=(_z&(1<<10)-1)<<4; + n=(n*((n*((n*((n*3548>>15)+6817)>>15)+15823)>>15)+22708)>>15)+16384; + return 14-ipart>0?n+(1<<13-ipart)>>14-ipart:n<<ipart-14; +} + +/*Polynomial approximation of a binary logarithm. + Q0 input, Q10 output.*/ +int oc_blog32_q10(ogg_uint32_t _w){ + int n; + int ipart; + int fpart; + if(_w<=0)return -1; + ipart=OC_ILOGNZ_32(_w); + n=(ipart-16>0?_w>>ipart-16:_w<<16-ipart)-32768-16384; + fpart=(n*((n*((n*((n*-1402>>15)+2546)>>15)-5216)>>15)+15745)>>15)-6793; + return (ipart<<10)+(fpart>>4); +} diff --git a/thirdparty/libtheora/mathops.h b/thirdparty/libtheora/mathops.h index efbc5377b0..a1a4f9df0e 100644 --- a/thirdparty/libtheora/mathops.h +++ b/thirdparty/libtheora/mathops.h @@ -2,29 +2,27 @@ # define _mathops_H (1) # include <ogg/ogg.h> -# ifdef __GNUC_PREREQ -# if __GNUC_PREREQ(3,4) -# include <limits.h> +# if __GNUC_PREREQ(3,4) +# include <limits.h> /*Note the casts to (int) below: this prevents OC_CLZ{32|64}_OFFS from "upgrading" the type of an entire expression to an (unsigned) size_t.*/ -# if INT_MAX>=2147483647 -# define OC_CLZ32_OFFS ((int)sizeof(unsigned)*CHAR_BIT) -# define OC_CLZ32(_x) (__builtin_clz(_x)) -# elif LONG_MAX>=2147483647L -# define OC_CLZ32_OFFS ((int)sizeof(unsigned long)*CHAR_BIT) -# define OC_CLZ32(_x) (__builtin_clzl(_x)) -# endif -# if INT_MAX>=9223372036854775807LL -# define OC_CLZ64_OFFS ((int)sizeof(unsigned)*CHAR_BIT) -# define OC_CLZ64(_x) (__builtin_clz(_x)) -# elif LONG_MAX>=9223372036854775807LL -# define OC_CLZ64_OFFS ((int)sizeof(unsigned long)*CHAR_BIT) -# define OC_CLZ64(_x) (__builtin_clzl(_x)) -# elif LLONG_MAX>=9223372036854775807LL|| \ - __LONG_LONG_MAX__>=9223372036854775807LL -# define OC_CLZ64_OFFS ((int)sizeof(unsigned long long)*CHAR_BIT) -# define OC_CLZ64(_x) (__builtin_clzll(_x)) -# endif +# if INT_MAX>=2147483647 +# define OC_CLZ32_OFFS ((int)sizeof(unsigned)*CHAR_BIT) +# define OC_CLZ32(_x) (__builtin_clz(_x)) +# elif LONG_MAX>=2147483647L +# define OC_CLZ32_OFFS ((int)sizeof(unsigned long)*CHAR_BIT) +# define OC_CLZ32(_x) (__builtin_clzl(_x)) +# endif +# if INT_MAX>=9223372036854775807LL +# define OC_CLZ64_OFFS ((int)sizeof(unsigned)*CHAR_BIT) +# define OC_CLZ64(_x) (__builtin_clz(_x)) +# elif LONG_MAX>=9223372036854775807LL +# define OC_CLZ64_OFFS ((int)sizeof(unsigned long)*CHAR_BIT) +# define OC_CLZ64(_x) (__builtin_clzl(_x)) +# elif LLONG_MAX>=9223372036854775807LL|| \ + __LONG_LONG_MAX__>=9223372036854775807LL +# define OC_CLZ64_OFFS ((int)sizeof(unsigned long long)*CHAR_BIT) +# define OC_CLZ64(_x) (__builtin_clzll(_x)) # endif # endif @@ -134,8 +132,12 @@ int oc_ilog64(ogg_int64_t _v); # define OC_STATIC_ILOG_64(_v) (OC_STATIC_ILOG6((ogg_int64_t)(_v))) #define OC_Q57(_v) ((ogg_int64_t)(_v)<<57) +#define OC_Q10(_v) ((_v)<<10) ogg_int64_t oc_bexp64(ogg_int64_t _z); ogg_int64_t oc_blog64(ogg_int64_t _w); +ogg_uint32_t oc_bexp32_q10(int _z); +int oc_blog32_q10(ogg_uint32_t _w); + #endif diff --git a/thirdparty/libtheora/mcenc.c b/thirdparty/libtheora/mcenc.c index 797e81f4f9..82eb824a80 100644 --- a/thirdparty/libtheora/mcenc.c +++ b/thirdparty/libtheora/mcenc.c @@ -88,9 +88,11 @@ static const int OC_SQUARE_SITES[11][8]={ }; -static void oc_mcenc_find_candidates(oc_enc_ctx *_enc,oc_mcenc_ctx *_mcenc, - int _accum[2],int _mbi,int _frame){ +static void oc_mcenc_find_candidates_a(oc_enc_ctx *_enc,oc_mcenc_ctx *_mcenc, + oc_mv _accum,int _mbi,int _frame){ oc_mb_enc_info *embs; + int accum_x; + int accum_y; int a[3][2]; int ncandidates; unsigned nmbi; @@ -102,20 +104,24 @@ static void oc_mcenc_find_candidates(oc_enc_ctx *_enc,oc_mcenc_ctx *_mcenc, /*Fill in the first part of set A: the vectors from adjacent blocks.*/ for(i=0;i<embs[_mbi].ncneighbors;i++){ nmbi=embs[_mbi].cneighbors[i]; - _mcenc->candidates[ncandidates][0]=embs[nmbi].analysis_mv[0][_frame][0]; - _mcenc->candidates[ncandidates][1]=embs[nmbi].analysis_mv[0][_frame][1]; + _mcenc->candidates[ncandidates][0]= + OC_MV_X(embs[nmbi].analysis_mv[0][_frame]); + _mcenc->candidates[ncandidates][1]= + OC_MV_Y(embs[nmbi].analysis_mv[0][_frame]); ncandidates++; } } + accum_x=OC_MV_X(_accum); + accum_y=OC_MV_Y(_accum); /*Add a few additional vectors to set A: the vectors used in the previous frames and the (0,0) vector.*/ - _mcenc->candidates[ncandidates][0]=OC_CLAMPI(-31,_accum[0],31); - _mcenc->candidates[ncandidates][1]=OC_CLAMPI(-31,_accum[1],31); + _mcenc->candidates[ncandidates][0]=accum_x; + _mcenc->candidates[ncandidates][1]=accum_y; ncandidates++; _mcenc->candidates[ncandidates][0]=OC_CLAMPI(-31, - embs[_mbi].analysis_mv[1][_frame][0]+_accum[0],31); + OC_MV_X(embs[_mbi].analysis_mv[1][_frame])+accum_x,31); _mcenc->candidates[ncandidates][1]=OC_CLAMPI(-31, - embs[_mbi].analysis_mv[1][_frame][1]+_accum[1],31); + OC_MV_Y(embs[_mbi].analysis_mv[1][_frame])+accum_y,31); ncandidates++; _mcenc->candidates[ncandidates][0]=0; _mcenc->candidates[ncandidates][1]=0; @@ -131,30 +137,33 @@ static void oc_mcenc_find_candidates(oc_enc_ctx *_enc,oc_mcenc_ctx *_mcenc, OC_SORT2I(a[0][1],a[1][1]); _mcenc->candidates[0][0]=a[1][0]; _mcenc->candidates[0][1]=a[1][1]; - /*Fill in set B: accelerated predictors for this and adjacent macro blocks.*/ _mcenc->setb0=ncandidates; - /*The first time through the loop use the current macro block.*/ - nmbi=_mbi; - for(i=0;;i++){ - _mcenc->candidates[ncandidates][0]=OC_CLAMPI(-31, - 2*embs[_mbi].analysis_mv[1][_frame][0] - -embs[_mbi].analysis_mv[2][_frame][0]+_accum[0],31); - _mcenc->candidates[ncandidates][1]=OC_CLAMPI(-31, - 2*embs[_mbi].analysis_mv[1][_frame][1] - -embs[_mbi].analysis_mv[2][_frame][1]+_accum[1],31); - ncandidates++; - if(i>=embs[_mbi].npneighbors)break; - nmbi=embs[_mbi].pneighbors[i]; - } - /*Truncate to full-pel positions.*/ - for(i=0;i<ncandidates;i++){ - _mcenc->candidates[i][0]=OC_DIV2(_mcenc->candidates[i][0]); - _mcenc->candidates[i][1]=OC_DIV2(_mcenc->candidates[i][1]); - } +} + +static void oc_mcenc_find_candidates_b(oc_enc_ctx *_enc,oc_mcenc_ctx *_mcenc, + oc_mv _accum,int _mbi,int _frame){ + oc_mb_enc_info *embs; + int accum_x; + int accum_y; + int ncandidates; + embs=_enc->mb_info; + accum_x=OC_MV_X(_accum); + accum_y=OC_MV_Y(_accum); + /*Fill in set B: accelerated predictors for this and adjacent macro blocks.*/ + ncandidates=_mcenc->setb0; + /*Use only the current block. Using more did not appear to be helpful + with the current selection logic due to escaping the local search too + quickly.*/ + _mcenc->candidates[ncandidates][0]=OC_CLAMPI(-31, + 2*OC_MV_X(embs[_mbi].analysis_mv[1][_frame]) + -OC_MV_X(embs[_mbi].analysis_mv[2][_frame])+accum_x,31); + _mcenc->candidates[ncandidates][1]=OC_CLAMPI(-31, + 2*OC_MV_Y(embs[_mbi].analysis_mv[1][_frame]) + -OC_MV_Y(embs[_mbi].analysis_mv[2][_frame])+accum_y,31); + ncandidates++; _mcenc->ncandidates=ncandidates; } -#if 0 static unsigned oc_sad16_halfpel(const oc_enc_ctx *_enc, const ptrdiff_t *_frag_buf_offs,const ptrdiff_t _fragis[4], int _mvoffset0,int _mvoffset1,const unsigned char *_src, @@ -170,20 +179,21 @@ static unsigned oc_sad16_halfpel(const oc_enc_ctx *_enc, } return err; } -#endif static unsigned oc_satd16_halfpel(const oc_enc_ctx *_enc, const ptrdiff_t *_frag_buf_offs,const ptrdiff_t _fragis[4], int _mvoffset0,int _mvoffset1,const unsigned char *_src, const unsigned char *_ref,int _ystride,unsigned _best_err){ unsigned err; + int dc; int bi; err=0; for(bi=0;bi<4;bi++){ ptrdiff_t frag_offs; frag_offs=_frag_buf_offs[_fragis[bi]]; - err+=oc_enc_frag_satd2_thresh(_enc,_src+frag_offs,_ref+frag_offs+_mvoffset0, - _ref+frag_offs+_mvoffset1,_ystride,_best_err-err); + err+=oc_enc_frag_satd2(_enc,&dc,_src+frag_offs, + _ref+frag_offs+_mvoffset0,_ref+frag_offs+_mvoffset1,_ystride); + err+=abs(dc); } return err; } @@ -219,9 +229,17 @@ static int oc_mcenc_ysatd_check_mbcandidate_fullpel(const oc_enc_ctx *_enc, err=0; for(bi=0;bi<4;bi++){ ptrdiff_t frag_offs; + int dc; frag_offs=_frag_buf_offs[_fragis[bi]]; - err+=oc_enc_frag_satd_thresh(_enc, - _src+frag_offs,_ref+frag_offs+mvoffset,_ystride,UINT_MAX); + if(_enc->sp_level<OC_SP_LEVEL_NOSATD){ + err+=oc_enc_frag_satd(_enc,&dc, + _src+frag_offs,_ref+frag_offs+mvoffset,_ystride); + err+=abs(dc); + } + else{ + err+=oc_enc_frag_sad(_enc, + _src+frag_offs,_ref+frag_offs+mvoffset,_ystride); + } } return err; } @@ -229,8 +247,11 @@ static int oc_mcenc_ysatd_check_mbcandidate_fullpel(const oc_enc_ctx *_enc, static unsigned oc_mcenc_ysatd_check_bcandidate_fullpel(const oc_enc_ctx *_enc, ptrdiff_t _frag_offs,int _dx,int _dy, const unsigned char *_src,const unsigned char *_ref,int _ystride){ - return oc_enc_frag_satd_thresh(_enc, - _src+_frag_offs,_ref+_frag_offs+_dx+_dy*_ystride,_ystride,UINT_MAX); + unsigned err; + int dc; + err=oc_enc_frag_satd(_enc,&dc, + _src+_frag_offs,_ref+_frag_offs+_dx+_dy*_ystride,_ystride); + return err+abs(dc); } /*Perform a motion vector search for this macro block against a single @@ -239,11 +260,14 @@ static unsigned oc_mcenc_ysatd_check_bcandidate_fullpel(const oc_enc_ctx *_enc, the work can be shared. The actual motion vector is stored in the appropriate place in the oc_mb_enc_info structure. - _mcenc: The motion compensation context. - _accum: Drop frame/golden MV accumulators. - _mbi: The macro block index. - _frame: The frame to search, either OC_FRAME_PREV or OC_FRAME_GOLD.*/ -void oc_mcenc_search_frame(oc_enc_ctx *_enc,int _accum[2],int _mbi,int _frame){ + _accum: Drop frame/golden MV accumulators. + _mbi: The macro block index. + _frame: The frame to use for SATD calculations and refinement, + either OC_FRAME_PREV or OC_FRAME_GOLD. + _frame_full: The frame to perform the 1px search on, one of OC_FRAME_PREV, + OC_FRAME_GOLD, OC_FRAME_PREV_ORIG, or OC_FRAME_GOLD_ORIG.*/ +void oc_mcenc_search_frame(oc_enc_ctx *_enc,oc_mv _accum,int _mbi,int _frame, + int _frame_full){ /*Note: Traditionally this search is done using a rate-distortion objective function of the form D+lambda*R. However, xiphmont tested this and found it produced a small degredation, @@ -264,6 +288,7 @@ void oc_mcenc_search_frame(oc_enc_ctx *_enc,int _accum[2],int _mbi,int _frame){ const ptrdiff_t *fragis; const unsigned char *src; const unsigned char *ref; + const unsigned char *satd_ref; int ystride; oc_mb_enc_info *embs; ogg_int32_t hit_cache[31]; @@ -278,17 +303,18 @@ void oc_mcenc_search_frame(oc_enc_ctx *_enc,int _accum[2],int _mbi,int _frame){ int bi; embs=_enc->mb_info; /*Find some candidate motion vectors.*/ - oc_mcenc_find_candidates(_enc,&mcenc,_accum,_mbi,_frame); + oc_mcenc_find_candidates_a(_enc,&mcenc,_accum,_mbi,_frame); /*Clear the cache of locations we've examined.*/ memset(hit_cache,0,sizeof(hit_cache)); /*Start with the median predictor.*/ - candx=mcenc.candidates[0][0]; - candy=mcenc.candidates[0][1]; + candx=OC_DIV2(mcenc.candidates[0][0]); + candy=OC_DIV2(mcenc.candidates[0][1]); hit_cache[candy+15]|=(ogg_int32_t)1<<candx+15; frag_buf_offs=_enc->state.frag_buf_offs; fragis=_enc->state.mb_maps[_mbi][0]; src=_enc->state.ref_frame_data[OC_FRAME_IO]; - ref=_enc->state.ref_frame_data[_enc->state.ref_frame_idx[_frame]]; + ref=_enc->state.ref_frame_data[_frame_full]; + satd_ref=_enc->state.ref_frame_data[_frame]; ystride=_enc->state.ref_ystride[0]; /*TODO: customize error function for speed/(quality+size) tradeoff.*/ best_err=oc_mcenc_ysad_check_mbcandidate_fullpel(_enc, @@ -317,8 +343,8 @@ void oc_mcenc_search_frame(oc_enc_ctx *_enc,int _accum[2],int _mbi,int _frame){ t2+=(t2>>OC_YSAD_THRESH2_SCALE_BITS)+OC_YSAD_THRESH2_OFFSET; /*Examine the candidates in set A.*/ for(ci=1;ci<mcenc.setb0;ci++){ - candx=mcenc.candidates[ci][0]; - candy=mcenc.candidates[ci][1]; + candx=OC_DIV2(mcenc.candidates[ci][0]); + candy=OC_DIV2(mcenc.candidates[ci][1]); /*If we've already examined this vector, then we would be using it if it was better than what we are using.*/ hitbit=(ogg_int32_t)1<<candx+15; @@ -340,10 +366,11 @@ void oc_mcenc_search_frame(oc_enc_ctx *_enc,int _accum[2],int _mbi,int _frame){ } } if(best_err>t2){ + oc_mcenc_find_candidates_b(_enc,&mcenc,_accum,_mbi,_frame); /*Examine the candidates in set B.*/ for(;ci<mcenc.ncandidates;ci++){ - candx=mcenc.candidates[ci][0]; - candy=mcenc.candidates[ci][1]; + candx=OC_DIV2(mcenc.candidates[ci][0]); + candy=OC_DIV2(mcenc.candidates[ci][1]); hitbit=(ogg_int32_t)1<<candx+15; if(hit_cache[candy+15]&hitbit)continue; hit_cache[candy+15]|=hitbit; @@ -475,58 +502,50 @@ void oc_mcenc_search_frame(oc_enc_ctx *_enc,int _accum[2],int _mbi,int _frame){ candx=best_vec[0]; candy=best_vec[1]; embs[_mbi].satd[_frame]=oc_mcenc_ysatd_check_mbcandidate_fullpel(_enc, - frag_buf_offs,fragis,candx,candy,src,ref,ystride); - embs[_mbi].analysis_mv[0][_frame][0]=(signed char)(candx<<1); - embs[_mbi].analysis_mv[0][_frame][1]=(signed char)(candy<<1); - if(_frame==OC_FRAME_PREV){ + frag_buf_offs,fragis,candx,candy,src,satd_ref,ystride); + embs[_mbi].analysis_mv[0][_frame]=OC_MV(candx<<1,candy<<1); + if(_frame==OC_FRAME_PREV&&_enc->sp_level<OC_SP_LEVEL_FAST_ANALYSIS){ for(bi=0;bi<4;bi++){ candx=best_block_vec[bi][0]; candy=best_block_vec[bi][1]; embs[_mbi].block_satd[bi]=oc_mcenc_ysatd_check_bcandidate_fullpel(_enc, - frag_buf_offs[fragis[bi]],candx,candy,src,ref,ystride); - embs[_mbi].block_mv[bi][0]=(signed char)(candx<<1); - embs[_mbi].block_mv[bi][1]=(signed char)(candy<<1); + frag_buf_offs[fragis[bi]],candx,candy,src,satd_ref,ystride); + embs[_mbi].block_mv[bi]=OC_MV(candx<<1,candy<<1); } } } void oc_mcenc_search(oc_enc_ctx *_enc,int _mbi){ - oc_mv2 *mvs; - int accum_p[2]; - int accum_g[2]; + oc_mv2 *mvs; + oc_mv accum_p; + oc_mv accum_g; + oc_mv mv2_p; mvs=_enc->mb_info[_mbi].analysis_mv; - if(_enc->prevframe_dropped){ - accum_p[0]=mvs[0][OC_FRAME_PREV][0]; - accum_p[1]=mvs[0][OC_FRAME_PREV][1]; - } - else accum_p[1]=accum_p[0]=0; - accum_g[0]=mvs[2][OC_FRAME_GOLD][0]; - accum_g[1]=mvs[2][OC_FRAME_GOLD][1]; - mvs[0][OC_FRAME_PREV][0]-=mvs[2][OC_FRAME_PREV][0]; - mvs[0][OC_FRAME_PREV][1]-=mvs[2][OC_FRAME_PREV][1]; + if(_enc->prevframe_dropped)accum_p=mvs[0][OC_FRAME_PREV]; + else accum_p=0; + accum_g=mvs[2][OC_FRAME_GOLD]; /*Move the motion vector predictors back a frame.*/ - memmove(mvs+1,mvs,2*sizeof(*mvs)); + mv2_p=mvs[2][OC_FRAME_PREV]; + mvs[2][OC_FRAME_GOLD]=mvs[1][OC_FRAME_GOLD]; + mvs[2][OC_FRAME_PREV]=mvs[1][OC_FRAME_PREV]; + mvs[1][OC_FRAME_GOLD]=mvs[0][OC_FRAME_GOLD]; + mvs[1][OC_FRAME_PREV]=OC_MV_SUB(mvs[0][OC_FRAME_PREV],mv2_p); /*Search the last frame.*/ - oc_mcenc_search_frame(_enc,accum_p,_mbi,OC_FRAME_PREV); - mvs[2][OC_FRAME_PREV][0]=accum_p[0]; - mvs[2][OC_FRAME_PREV][1]=accum_p[1]; + oc_mcenc_search_frame(_enc,accum_p,_mbi,OC_FRAME_PREV,OC_FRAME_PREV_ORIG); + mvs[2][OC_FRAME_PREV]=accum_p; /*GOLDEN MVs are different from PREV MVs in that they're each absolute offsets from some frame in the past rather than relative offsets from the frame before. For predictor calculation to make sense, we need them to be in the same form as PREV MVs.*/ - mvs[1][OC_FRAME_GOLD][0]-=mvs[2][OC_FRAME_GOLD][0]; - mvs[1][OC_FRAME_GOLD][1]-=mvs[2][OC_FRAME_GOLD][1]; - mvs[2][OC_FRAME_GOLD][0]-=accum_g[0]; - mvs[2][OC_FRAME_GOLD][1]-=accum_g[1]; + mvs[1][OC_FRAME_GOLD]=OC_MV_SUB(mvs[1][OC_FRAME_GOLD],mvs[2][OC_FRAME_GOLD]); + mvs[2][OC_FRAME_GOLD]=OC_MV_SUB(mvs[2][OC_FRAME_GOLD],accum_g); /*Search the golden frame.*/ - oc_mcenc_search_frame(_enc,accum_g,_mbi,OC_FRAME_GOLD); + oc_mcenc_search_frame(_enc,accum_g,_mbi,OC_FRAME_GOLD,OC_FRAME_GOLD_ORIG); /*Put GOLDEN MVs back into absolute offset form. The newest MV is already an absolute offset.*/ - mvs[2][OC_FRAME_GOLD][0]+=accum_g[0]; - mvs[2][OC_FRAME_GOLD][1]+=accum_g[1]; - mvs[1][OC_FRAME_GOLD][0]+=mvs[2][OC_FRAME_GOLD][0]; - mvs[1][OC_FRAME_GOLD][1]+=mvs[2][OC_FRAME_GOLD][1]; + mvs[2][OC_FRAME_GOLD]=OC_MV_ADD(mvs[2][OC_FRAME_GOLD],accum_g); + mvs[1][OC_FRAME_GOLD]=OC_MV_ADD(mvs[1][OC_FRAME_GOLD],mvs[2][OC_FRAME_GOLD]); } #if 0 @@ -543,7 +562,7 @@ static int oc_mcenc_ysad_halfpel_mbrefine(const oc_enc_ctx *_enc,int _mbi, int sitei; int err; src=_enc->state.ref_frame_data[OC_FRAME_IO]; - ref=_enc->state.ref_frame_data[_enc->state.ref_frame_idx[_framei]]; + ref=_enc->state.ref_frame_data[_framei]; frag_buf_offs=_enc->state.frag_buf_offs; fragis=_enc->state.mb_maps[_mbi][0]; ystride=_enc->state.ref_ystride[0]; @@ -598,7 +617,7 @@ static unsigned oc_mcenc_ysatd_halfpel_mbrefine(const oc_enc_ctx *_enc, int sitei; int err; src=_enc->state.ref_frame_data[OC_FRAME_IO]; - ref=_enc->state.ref_frame_data[_enc->state.ref_frame_idx[_frame]]; + ref=_enc->state.ref_frame_data[_frame]; frag_buf_offs=_enc->state.frag_buf_offs; fragis=_enc->state.mb_maps[_mbi][0]; ystride=_enc->state.ref_ystride[0]; @@ -627,8 +646,14 @@ static unsigned oc_mcenc_ysatd_halfpel_mbrefine(const oc_enc_ctx *_enc, ymask=OC_SIGNMASK(((_vec[1]<<1)+dy)^dy); mvoffset0=mvoffset_base+(dx&xmask)+(offset_y[site]&ymask); mvoffset1=mvoffset_base+(dx&~xmask)+(offset_y[site]&~ymask); - err=oc_satd16_halfpel(_enc,frag_buf_offs,fragis, - mvoffset0,mvoffset1,src,ref,ystride,_best_err); + if(_enc->sp_level<OC_SP_LEVEL_NOSATD){ + err=oc_satd16_halfpel(_enc,frag_buf_offs,fragis, + mvoffset0,mvoffset1,src,ref,ystride,_best_err); + } + else{ + err=oc_sad16_halfpel(_enc,frag_buf_offs,fragis, + mvoffset0,mvoffset1,src,ref,ystride,_best_err); + } if(err<_best_err){ _best_err=err; best_site=site; @@ -643,12 +668,11 @@ void oc_mcenc_refine1mv(oc_enc_ctx *_enc,int _mbi,int _frame){ oc_mb_enc_info *embs; int vec[2]; embs=_enc->mb_info; - vec[0]=OC_DIV2(embs[_mbi].analysis_mv[0][_frame][0]); - vec[1]=OC_DIV2(embs[_mbi].analysis_mv[0][_frame][1]); + vec[0]=OC_DIV2(OC_MV_X(embs[_mbi].analysis_mv[0][_frame])); + vec[1]=OC_DIV2(OC_MV_Y(embs[_mbi].analysis_mv[0][_frame])); embs[_mbi].satd[_frame]=oc_mcenc_ysatd_halfpel_mbrefine(_enc, _mbi,vec,embs[_mbi].satd[_frame],_frame); - embs[_mbi].analysis_mv[0][_frame][0]=(signed char)vec[0]; - embs[_mbi].analysis_mv[0][_frame][1]=(signed char)vec[1]; + embs[_mbi].analysis_mv[0][_frame]=OC_MV(vec[0],vec[1]); } #if 0 @@ -704,6 +728,7 @@ static unsigned oc_mcenc_ysatd_halfpel_brefine(const oc_enc_ctx *_enc, best_site=4; for(sitei=0;sitei<8;sitei++){ unsigned err; + int dc; int site; int xmask; int ymask; @@ -723,8 +748,9 @@ static unsigned oc_mcenc_ysatd_halfpel_brefine(const oc_enc_ctx *_enc, ymask=OC_SIGNMASK(((_vec[1]<<1)+dy)^dy); mvoffset0=mvoffset_base+(dx&xmask)+(_offset_y[site]&ymask); mvoffset1=mvoffset_base+(dx&~xmask)+(_offset_y[site]&~ymask); - err=oc_enc_frag_satd2_thresh(_enc,_src, - _ref+mvoffset0,_ref+mvoffset1,_ystride,_best_err); + err=oc_enc_frag_satd2(_enc,&dc,_src, + _ref+mvoffset0,_ref+mvoffset1,_ystride); + err+=abs(dc); if(err<_best_err){ _best_err=err; best_site=site; @@ -748,7 +774,7 @@ void oc_mcenc_refine4mv(oc_enc_ctx *_enc,int _mbi){ frag_buf_offs=_enc->state.frag_buf_offs; fragis=_enc->state.mb_maps[_mbi][0]; src=_enc->state.ref_frame_data[OC_FRAME_IO]; - ref=_enc->state.ref_frame_data[_enc->state.ref_frame_idx[OC_FRAME_PREV]]; + ref=_enc->state.ref_frame_data[OC_FRAME_PREV]; offset_y[0]=offset_y[1]=offset_y[2]=-ystride; offset_y[3]=offset_y[5]=0; offset_y[6]=offset_y[7]=offset_y[8]=ystride; @@ -757,11 +783,10 @@ void oc_mcenc_refine4mv(oc_enc_ctx *_enc,int _mbi){ ptrdiff_t frag_offs; int vec[2]; frag_offs=frag_buf_offs[fragis[bi]]; - vec[0]=OC_DIV2(embs[_mbi].block_mv[bi][0]); - vec[1]=OC_DIV2(embs[_mbi].block_mv[bi][1]); + vec[0]=OC_DIV2(OC_MV_X(embs[_mbi].block_mv[bi])); + vec[1]=OC_DIV2(OC_MV_Y(embs[_mbi].block_mv[bi])); embs[_mbi].block_satd[bi]=oc_mcenc_ysatd_halfpel_brefine(_enc,vec, src+frag_offs,ref+frag_offs,ystride,offset_y,embs[_mbi].block_satd[bi]); - embs[_mbi].ref_mv[bi][0]=(signed char)vec[0]; - embs[_mbi].ref_mv[bi][1]=(signed char)vec[1]; + embs[_mbi].ref_mv[bi]=OC_MV(vec[0],vec[1]); } } diff --git a/thirdparty/libtheora/modedec.h b/thirdparty/libtheora/modedec.h index ea12c64afd..efe640e263 100644 --- a/thirdparty/libtheora/modedec.h +++ b/thirdparty/libtheora/modedec.h @@ -1,614 +1,91 @@ /*File generated by libtheora with OC_COLLECT_METRICS defined at compile time.*/ #if !defined(_modedec_H) # define _modedec_H (1) +# include "encint.h" -# if defined(OC_COLLECT_METRICS) -typedef struct oc_mode_metrics oc_mode_metrics; +/*The log of the average quantizer for each of the OC_MODE_RD table rows + (e.g., for the represented qi's, and each pli and qti), in Q10 format. + The actual statistics used by the encoder will be interpolated from + that table based on log_plq for the actual quantization matrix used.*/ +# if !defined(OC_COLLECT_METRICS) +static const # endif -typedef struct oc_mode_rd oc_mode_rd; - - - -/*The number of extra bits of precision at which to store rate metrics.*/ -# define OC_BIT_SCALE (6) -/*The number of extra bits of precision at which to store RMSE metrics. - This must be at least half OC_BIT_SCALE (rounded up).*/ -# define OC_RMSE_SCALE (5) -/*The number of bins to partition statistics into.*/ -# define OC_SAD_BINS (24) -/*The number of bits of precision to drop from SAD scores to assign them to a - bin.*/ -# define OC_SAD_SHIFT (9) - - - -# if defined(OC_COLLECT_METRICS) -struct oc_mode_metrics{ - double fragw; - double satd; - double rate; - double rmse; - double satd2; - double satdrate; - double rate2; - double satdrmse; - double rmse2; +ogg_int16_t OC_MODE_LOGQ[OC_LOGQ_BINS][3][2]={ + { {0x1F05,0x2101},{0x206E,0x2101},{0x206E,0x2101} }, + { {0x1C9A,0x1EAC},{0x1E0E,0x1EAC},{0x1E0E,0x1EAC} }, + { {0x1A31,0x1C48},{0x1B6F,0x1C48},{0x1B6F,0x1C48} }, + { {0x17B0,0x19E7},{0x1938,0x19E7},{0x1938,0x19E7} }, + { {0x152F,0x178F},{0x16AB,0x178F},{0x16AB,0x178F} }, + { {0x12F1,0x1534},{0x145D,0x1534},{0x145D,0x1534} }, + { {0x0FF3,0x1321},{0x11BE,0x1321},{0x11BE,0x1321} }, + { {0x0E1F,0x1073},{0x0E93,0x1073},{0x0E93,0x1073} } }; - -int oc_has_mode_metrics; -oc_mode_metrics OC_MODE_METRICS[64][3][2][OC_SAD_BINS]; -# endif - - - -struct oc_mode_rd{ - ogg_int16_t rate; - ogg_int16_t rmse; -}; - - # if !defined(OC_COLLECT_METRICS) static const # endif -oc_mode_rd OC_MODE_RD[64][3][2][OC_SAD_BINS]={ +oc_mode_rd OC_MODE_RD_SATD[OC_LOGQ_BINS][3][2][OC_COMP_BINS]={ { { /*Y' qi=0 INTRA*/ { - { 87, -66},{ 132, 1611},{ 197, 3474},{ 285, 5130}, - { 376, 6419},{ 450, 7545},{ 521, 8587},{ 600, 9587}, - { 689,10498},{ 790,11348},{ 899,12158},{ 1030,12855}, - { 1166,13459},{ 1276,14052},{ 1353,14732},{ 1444,15425}, - { 1535,16101},{ 1609,16856},{ 1697,17532},{ 1823,17995}, - { 1962,18426},{ 2085,18919},{ 2201,19503},{ 2304,20307} + { 57, 1550},{ 121, 2460},{ 185, 3901},{ 336, 5189}, + { 406, 6243},{ 501, 7329},{ 565, 8292},{ 674, 9257}, + { 746,10219},{ 843,11056},{ 961,11822},{ 1120,12512}, + { 1208,13233},{ 1394,13600},{ 1409,14381},{ 1492,15129}, + { 1593,15804},{ 1639,16573},{ 1731,17161},{ 1844,17707}, + { 1949,18300},{ 2073,18654},{ 2140,19465},{ 2278,19794} }, /*Y' qi=0 INTER*/ { - { 32, -105},{ 40, 1268},{ 54, 2919},{ 91, 4559}, - { 118, 6244},{ 132, 7932},{ 142, 9514},{ 149,10989}, - { 155,12375},{ 161,13679},{ 168,14958},{ 176,16215}, - { 187,17431},{ 196,18623},{ 207,19790},{ 218,20941}, - { 230,22083},{ 246,23213},{ 265,24333},{ 292,25439}, - { 328,26512},{ 372,27538},{ 427,28522},{ 494,29479} + { -18, 1274},{ 23, 2505},{ 32, 3612},{ 57, 5153}, + { 79, 6636},{ 97, 8082},{ 109, 9505},{ 122,10924}, + { 134,12293},{ 145,13634},{ 158,14942},{ 172,16212}, + { 186,17422},{ 198,18604},{ 209,19757},{ 218,20875}, + { 235,21980},{ 253,23056},{ 276,24121},{ 305,25184}, + { 342,26202},{ 393,27140},{ 439,28140},{ 556,28659} } }, { /*Cb qi=0 INTRA*/ { - { 1, 6},{ 27, 368},{ 52, 738},{ 67, 1171}, - { 80, 1642},{ 99, 2134},{ 110, 2642},{ 112, 3144}, - { 126, 3578},{ 154, 3967},{ 167, 4387},{ 172, 4839}, - { 191, 5278},{ 208, 5666},{ 220, 6036},{ 223, 6398}, - { 227, 6814},{ 253, 7157},{ 284, 7403},{ 292, 7699}, - { 314, 7983},{ 339, 8203},{ 363, 8460},{ 399, 8919} + { 32, 1763},{ 56, 2150},{ 78, 2336},{ 88, 2608}, + { 105, 2975},{ 121, 3297},{ 113, 3460},{ 126, 3993}, + { 142, 4432},{ 177, 4733},{ 185, 5058},{ 194, 5447}, + { 220, 5812},{ 227, 6202},{ 246, 6415},{ 269, 6821}, + { 279, 7026},{ 313, 7313},{ 321, 7708},{ 316, 8021}, + { 370, 8203},{ 389, 8573},{ 410, 8607},{ 431, 8816} }, /*Cb qi=0 INTER*/ { - { 68, -55},{ 63, 275},{ 58, 602},{ 53, 936}, - { 50, 1290},{ 54, 1691},{ 58, 2116},{ 62, 2553}, - { 67, 2992},{ 72, 3422},{ 78, 3843},{ 84, 4253}, - { 89, 4658},{ 94, 5062},{ 98, 5455},{ 100, 5848}, - { 102, 6231},{ 104, 6604},{ 104, 6982},{ 105, 7359}, - { 105, 7733},{ 104, 8104},{ 105, 8465},{ 111, 8828} + { 3, 282},{ 3, 1200},{ 3, 1605},{ 6, 2190}, + { 15, 2519},{ 18, 2798},{ 21, 3115},{ 25, 3460}, + { 33, 3839},{ 40, 4217},{ 47, 4592},{ 51, 4958}, + { 56, 5326},{ 59, 5710},{ 63, 6066},{ 65, 6412}, + { 67, 6762},{ 68, 7104},{ 70, 7461},{ 72, 7829}, + { 77, 8200},{ 80, 8566},{ 86, 8906},{ 90, 9203} } }, { /*Cr qi=0 INTRA*/ { - { 1, 8},{ 23, 375},{ 47, 759},{ 63, 1220}, - { 71, 1693},{ 82, 2171},{ 94, 2652},{ 109, 3103}, - { 125, 3567},{ 133, 3995},{ 151, 4375},{ 168, 4819}, - { 174, 5244},{ 190, 5635},{ 215, 6005},{ 242, 6347}, - { 257, 6758},{ 280, 7068},{ 311, 7336},{ 326, 7652}, - { 346, 7968},{ 372, 8213},{ 388, 8515},{ 408, 9060} + { 27, 1720},{ 44, 1920},{ 66, 2255},{ 73, 2429}, + { 95, 2988},{ 103, 3279},{ 123, 3691},{ 129, 4012}, + { 151, 4415},{ 150, 4760},{ 183, 5008},{ 193, 5351}, + { 211, 5788},{ 235, 6134},{ 263, 6400},{ 276, 6711}, + { 291, 7100},{ 346, 7285},{ 329, 7616},{ 387, 7827}, + { 361, 8214},{ 430, 8534},{ 429, 8608},{ 450, 8823} }, /*Cr qi=0 INTER*/ { - { 69, 0},{ 60, 314},{ 49, 624},{ 45, 943}, - { 45, 1285},{ 49, 1691},{ 55, 2130},{ 62, 2560}, - { 71, 2973},{ 79, 3385},{ 85, 3800},{ 89, 4207}, - { 92, 4620},{ 95, 5037},{ 96, 5436},{ 97, 5839}, - { 98, 6252},{ 99, 6653},{ 99, 7038},{ 103, 7426}, - { 107, 7810},{ 108, 8178},{ 107, 8539},{ 106, 8937} - } - } - }, - { - { - /*Y' qi=1 INTRA*/ - { - { 81, -71},{ 133, 1610},{ 203, 3460},{ 296, 5083}, - { 392, 6342},{ 467, 7454},{ 541, 8486},{ 625, 9466}, - { 716,10352},{ 823,11181},{ 940,11961},{ 1074,12643}, - { 1211,13233},{ 1324,13807},{ 1408,14489},{ 1504,15167}, - { 1598,15824},{ 1679,16544},{ 1788,17161},{ 1928,17579}, - { 2070,17991},{ 2202,18456},{ 2324,19021},{ 2425,19894} - }, - /*Y' qi=1 INTER*/ - { - { 34, 4},{ 40, 1307},{ 55, 2914},{ 93, 4555}, - { 120, 6243},{ 134, 7912},{ 144, 9468},{ 152,10918}, - { 158,12275},{ 164,13569},{ 171,14846},{ 180,16098}, - { 191,17310},{ 204,18484},{ 216,19636},{ 228,20779}, - { 242,21912},{ 261,23036},{ 286,24146},{ 320,25221}, - { 363,26265},{ 418,27261},{ 485,28203},{ 551,29148} - } - }, - { - /*Cb qi=1 INTRA*/ - { - { 1, 6},{ 28, 367},{ 52, 738},{ 68, 1172}, - { 86, 1644},{ 106, 2135},{ 115, 2642},{ 119, 3141}, - { 132, 3569},{ 157, 3951},{ 172, 4366},{ 177, 4819}, - { 194, 5258},{ 211, 5638},{ 224, 6006},{ 233, 6367}, - { 236, 6784},{ 258, 7121},{ 299, 7357},{ 319, 7637}, - { 337, 7921},{ 358, 8141},{ 381, 8367},{ 401, 8768} - }, - /*Cb qi=1 INTER*/ - { - { 95, -31},{ 81, 295},{ 67, 614},{ 53, 953}, - { 48, 1305},{ 51, 1700},{ 56, 2125},{ 61, 2563}, - { 67, 3008},{ 73, 3435},{ 79, 3844},{ 85, 4251}, - { 90, 4663},{ 95, 5073},{ 98, 5458},{ 100, 5844}, - { 101, 6231},{ 102, 6606},{ 102, 6980},{ 103, 7347}, - { 104, 7726},{ 105, 8096},{ 105, 8453},{ 105, 8789} - } - }, - { - /*Cr qi=1 INTRA*/ - { - { 1, 8},{ 25, 375},{ 50, 759},{ 65, 1221}, - { 74, 1695},{ 86, 2172},{ 101, 2651},{ 117, 3101}, - { 129, 3561},{ 135, 3985},{ 153, 4368},{ 171, 4807}, - { 182, 5223},{ 202, 5608},{ 225, 5964},{ 251, 6300}, - { 271, 6697},{ 295, 6978},{ 324, 7235},{ 348, 7558}, - { 367, 7877},{ 394, 8101},{ 413, 8386},{ 409, 8945} - }, - /*Cr qi=1 INTER*/ - { - { 66, 11},{ 59, 323},{ 51, 631},{ 44, 949}, - { 44, 1292},{ 49, 1703},{ 56, 2140},{ 62, 2566}, - { 69, 2991},{ 77, 3397},{ 84, 3799},{ 89, 4211}, - { 93, 4634},{ 94, 5049},{ 95, 5444},{ 96, 5854}, - { 94, 6260},{ 95, 6640},{ 96, 7032},{ 101, 7423}, - { 104, 7790},{ 105, 8158},{ 109, 8527},{ 108, 8872} - } - } - }, - { - { - /*Y' qi=2 INTRA*/ - { - { 87, -72},{ 139, 1607},{ 213, 3426},{ 315, 4992}, - { 416, 6217},{ 495, 7315},{ 574, 8317},{ 666, 9265}, - { 763,10124},{ 875,10906},{ 1001,11654},{ 1147,12305}, - { 1289,12865},{ 1407,13424},{ 1503,14076},{ 1610,14724}, - { 1720,15342},{ 1815,16020},{ 1937,16579},{ 2084,16981}, - { 2236,17371},{ 2385,17779},{ 2536,18250},{ 2689,18931} - }, - /*Y' qi=2 INTER*/ - { - { 30, -2},{ 40, 1308},{ 57, 2921},{ 96, 4567}, - { 122, 6260},{ 136, 7902},{ 148, 9418},{ 156,10826}, - { 162,12157},{ 169,13448},{ 177,14709},{ 188,15938}, - { 200,17133},{ 213,18295},{ 228,19433},{ 245,20564}, - { 264,21685},{ 289,22790},{ 323,23876},{ 368,24916}, - { 427,25906},{ 499,26837},{ 585,27700},{ 680,28514} - } - }, - { - /*Cb qi=2 INTRA*/ - { - { 1, 6},{ 30, 367},{ 58, 738},{ 77, 1172}, - { 93, 1645},{ 111, 2137},{ 123, 2642},{ 126, 3133}, - { 136, 3553},{ 162, 3934},{ 178, 4352},{ 183, 4803}, - { 199, 5231},{ 220, 5596},{ 235, 5957},{ 245, 6314}, - { 256, 6718},{ 286, 7048},{ 320, 7285},{ 336, 7568}, - { 366, 7829},{ 387, 8045},{ 405, 8261},{ 445, 8550} - }, - /*Cb qi=2 INTER*/ - { - { 115, -61},{ 93, 277},{ 71, 609},{ 54, 963}, - { 49, 1329},{ 53, 1715},{ 58, 2138},{ 63, 2583}, - { 69, 3017},{ 75, 3442},{ 81, 3857},{ 88, 4263}, - { 93, 4667},{ 96, 5065},{ 101, 5451},{ 101, 5832}, - { 102, 6213},{ 103, 6593},{ 103, 6968},{ 104, 7336}, - { 104, 7710},{ 105, 8076},{ 106, 8440},{ 106, 8822} - } - }, - { - /*Cr qi=2 INTRA*/ - { - { 1, 8},{ 27, 375},{ 54, 759},{ 70, 1222}, - { 79, 1696},{ 89, 2173},{ 106, 2652},{ 123, 3098}, - { 135, 3553},{ 143, 3972},{ 161, 4348},{ 181, 4782}, - { 194, 5189},{ 213, 5565},{ 235, 5907},{ 266, 6229}, - { 286, 6618},{ 311, 6897},{ 339, 7152},{ 362, 7454}, - { 392, 7721},{ 416, 7946},{ 429, 8227},{ 458, 8540} - }, - /*Cr qi=2 INTER*/ - { - { 74, 20},{ 63, 330},{ 51, 635},{ 44, 942}, - { 47, 1287},{ 54, 1710},{ 59, 2147},{ 65, 2571}, - { 72, 2996},{ 79, 3413},{ 86, 3820},{ 91, 4230}, - { 93, 4642},{ 95, 5046},{ 95, 5442},{ 95, 5839}, - { 96, 6243},{ 97, 6641},{ 99, 7021},{ 101, 7396}, - { 103, 7764},{ 106, 8138},{ 109, 8507},{ 114, 8851} - } - } - }, - { - { - /*Y' qi=3 INTRA*/ - { - { 91, -67},{ 141, 1606},{ 219, 3405},{ 328, 4929}, - { 433, 6122},{ 515, 7209},{ 598, 8204},{ 693, 9145}, - { 796, 9986},{ 912,10756},{ 1045,11471},{ 1200,12079}, - { 1345,12640},{ 1471,13179},{ 1571,13809},{ 1678,14450}, - { 1798,15047},{ 1905,15701},{ 2043,16205},{ 2202,16569}, - { 2351,16971},{ 2501,17393},{ 2660,17851},{ 2825,18455} - }, - /*Y' qi=3 INTER*/ - { - { 53, -164},{ 38, 1314},{ 59, 2917},{ 99, 4563}, - { 124, 6253},{ 139, 7882},{ 150, 9375},{ 159,10749}, - { 166,12059},{ 173,13349},{ 183,14608},{ 194,15826}, - { 208,17003},{ 223,18150},{ 240,19287},{ 259,20411}, - { 284,21508},{ 317,22593},{ 359,23656},{ 414,24671}, - { 483,25634},{ 569,26519},{ 670,27332},{ 786,28072} - } - }, - { - /*Cb qi=3 INTRA*/ - { - { 1, 5},{ 31, 367},{ 58, 739},{ 78, 1173}, - { 96, 1645},{ 113, 2134},{ 125, 2638},{ 133, 3127}, - { 148, 3542},{ 171, 3915},{ 184, 4328},{ 192, 4776}, - { 209, 5197},{ 230, 5556},{ 245, 5909},{ 252, 6261}, - { 272, 6641},{ 304, 6942},{ 330, 7184},{ 342, 7477}, - { 380, 7736},{ 404, 7962},{ 428, 8151},{ 469, 8430} - }, - /*Cb qi=3 INTER*/ - { - { 86, -29},{ 72, 296},{ 58, 618},{ 46, 964}, - { 47, 1338},{ 51, 1743},{ 56, 2158},{ 63, 2594}, - { 69, 3035},{ 77, 3455},{ 84, 3859},{ 89, 4266}, - { 94, 4673},{ 98, 5074},{ 101, 5460},{ 101, 5842}, - { 101, 6217},{ 101, 6593},{ 102, 6964},{ 104, 7325}, - { 103, 7696},{ 103, 8056},{ 104, 8430},{ 103, 8792} - } - }, - { - /*Cr qi=3 INTRA*/ - { - { 1, 8},{ 27, 374},{ 56, 759},{ 74, 1221}, - { 83, 1696},{ 96, 2173},{ 113, 2650},{ 127, 3091}, - { 140, 3542},{ 151, 3960},{ 164, 4334},{ 188, 4764}, - { 208, 5144},{ 224, 5493},{ 250, 5841},{ 278, 6162}, - { 298, 6548},{ 334, 6816},{ 365, 7045},{ 388, 7343}, - { 419, 7613},{ 443, 7836},{ 455, 8105},{ 484, 8445} - }, - /*Cr qi=3 INTER*/ - { - { 76, 26},{ 65, 332},{ 53, 638},{ 45, 945}, - { 45, 1304},{ 53, 1725},{ 60, 2153},{ 68, 2584}, - { 74, 3007},{ 81, 3425},{ 87, 3844},{ 91, 4253}, - { 94, 4657},{ 95, 5061},{ 94, 5462},{ 94, 5856}, - { 95, 6250},{ 96, 6635},{ 97, 7014},{ 101, 7393}, - { 104, 7761},{ 106, 8137},{ 109, 8506},{ 111, 8823} - } - } - }, - { - { - /*Y' qi=4 INTRA*/ - { - { 80, -67},{ 143, 1603},{ 227, 3378},{ 344, 4861}, - { 454, 6026},{ 537, 7104},{ 626, 8089},{ 725, 9006}, - { 830, 9827},{ 950,10581},{ 1089,11270},{ 1257,11826}, - { 1409,12366},{ 1535,12912},{ 1640,13528},{ 1753,14173}, - { 1884,14756},{ 2007,15368},{ 2148,15852},{ 2307,16212}, - { 2464,16591},{ 2614,17019},{ 2785,17455},{ 2970,17963} - }, - /*Y' qi=4 INTER*/ - { - { 50, -145},{ 38, 1324},{ 61, 2921},{ 102, 4566}, - { 127, 6248},{ 142, 7845},{ 154, 9300},{ 163,10656}, - { 169,11965},{ 177,13246},{ 188,14495},{ 202,15702}, - { 218,16864},{ 236,18003},{ 256,19124},{ 278,20233}, - { 307,21330},{ 347,22398},{ 398,23437},{ 463,24429}, - { 546,25343},{ 649,26170},{ 767,26935},{ 888,27674} - } - }, - { - /*Cb qi=4 INTRA*/ - { - { 1, 5},{ 33, 367},{ 61, 739},{ 80, 1173}, - { 98, 1646},{ 114, 2136},{ 126, 2639},{ 137, 3124}, - { 152, 3535},{ 176, 3903},{ 194, 4307},{ 206, 4753}, - { 222, 5165},{ 242, 5508},{ 260, 5857},{ 272, 6205}, - { 294, 6559},{ 332, 6848},{ 356, 7104},{ 364, 7389}, - { 396, 7637},{ 415, 7878},{ 446, 8064},{ 506, 8294} - }, - /*Cb qi=4 INTER*/ - { - { 86, -15},{ 73, 308},{ 60, 627},{ 46, 967}, - { 47, 1343},{ 51, 1754},{ 56, 2183},{ 63, 2615}, - { 70, 3044},{ 79, 3459},{ 85, 3866},{ 90, 4276}, - { 94, 4686},{ 97, 5088},{ 100, 5467},{ 102, 5837}, - { 102, 6205},{ 101, 6569},{ 103, 6939},{ 104, 7317}, - { 105, 7690},{ 107, 8043},{ 107, 8394},{ 111, 8736} - } - }, - { - /*Cr qi=4 INTRA*/ - { - { 1, 7},{ 28, 375},{ 57, 759},{ 79, 1221}, - { 92, 1697},{ 105, 2174},{ 122, 2648},{ 135, 3085}, - { 146, 3530},{ 157, 3947},{ 171, 4316},{ 195, 4737}, - { 218, 5117},{ 239, 5445},{ 268, 5767},{ 295, 6074}, - { 315, 6460},{ 355, 6735},{ 392, 6933},{ 418, 7218}, - { 448, 7495},{ 471, 7688},{ 481, 7954},{ 504, 8313} - }, - /*Cr qi=4 INTER*/ - { - { 68, 28},{ 57, 334},{ 47, 639},{ 43, 953}, - { 48, 1314},{ 54, 1736},{ 59, 2169},{ 69, 2592}, - { 78, 3017},{ 84, 3434},{ 88, 3850},{ 92, 4260}, - { 95, 4663},{ 96, 5068},{ 95, 5455},{ 95, 5839}, - { 96, 6243},{ 97, 6626},{ 98, 7006},{ 101, 7390}, - { 104, 7755},{ 108, 8115},{ 111, 8471},{ 110, 8825} - } - } - }, - { - { - /*Y' qi=5 INTRA*/ - { - { 84, -69},{ 147, 1599},{ 237, 3350},{ 360, 4796}, - { 475, 5934},{ 562, 6992},{ 657, 7953},{ 765, 8837}, - { 874, 9641},{ 998,10384},{ 1146,11047},{ 1322,11572}, - { 1484,12076},{ 1617,12609},{ 1731,13203},{ 1856,13806}, - { 1995,14367},{ 2132,14936},{ 2289,15386},{ 2460,15721}, - { 2635,16066},{ 2802,16442},{ 2980,16805},{ 3177,17272} - }, - /*Y' qi=5 INTER*/ - { - { 38, -86},{ 37, 1349},{ 64, 2920},{ 105, 4563}, - { 129, 6236},{ 145, 7809},{ 158, 9236},{ 167,10572}, - { 174,11871},{ 182,13141},{ 195,14368},{ 212,15558}, - { 230,16706},{ 250,17828},{ 274,18944},{ 303,20041}, - { 342,21116},{ 394,22152},{ 460,23144},{ 543,24073}, - { 648,24919},{ 773,25673},{ 922,26323},{ 1084,26924} - } - }, - { - /*Cb qi=5 INTRA*/ - { - { 1, 5},{ 34, 367},{ 63, 739},{ 82, 1174}, - { 102, 1647},{ 119, 2137},{ 134, 2639},{ 145, 3121}, - { 161, 3529},{ 189, 3891},{ 207, 4290},{ 216, 4721}, - { 232, 5113},{ 258, 5455},{ 277, 5798},{ 294, 6124}, - { 322, 6427},{ 352, 6697},{ 370, 6982},{ 384, 7283}, - { 423, 7529},{ 448, 7766},{ 478, 7943},{ 527, 8151} - }, - /*Cb qi=5 INTER*/ - { - { 83, -49},{ 69, 284},{ 55, 611},{ 48, 961}, - { 49, 1355},{ 52, 1769},{ 58, 2191},{ 65, 2616}, - { 73, 3041},{ 80, 3460},{ 87, 3868},{ 92, 4276}, - { 95, 4682},{ 98, 5077},{ 100, 5459},{ 102, 5827}, - { 102, 6200},{ 102, 6568},{ 103, 6930},{ 103, 7303}, - { 104, 7672},{ 106, 8032},{ 106, 8391},{ 106, 8727} - } - }, - { - /*Cr qi=5 INTRA*/ - { - { 1, 8},{ 28, 375},{ 57, 760},{ 81, 1222}, - { 99, 1696},{ 111, 2175},{ 125, 2648},{ 140, 3079}, - { 152, 3520},{ 162, 3927},{ 179, 4294},{ 203, 4714}, - { 225, 5080},{ 254, 5389},{ 286, 5703},{ 318, 5997}, - { 342, 6364},{ 380, 6640},{ 416, 6837},{ 445, 7103}, - { 473, 7370},{ 497, 7562},{ 514, 7811},{ 549, 8148} - }, - /*Cr qi=5 INTER*/ - { - { 60, 6},{ 54, 323},{ 46, 638},{ 43, 958}, - { 45, 1329},{ 54, 1749},{ 61, 2175},{ 70, 2600}, - { 79, 3021},{ 85, 3437},{ 89, 3847},{ 93, 4254}, - { 95, 4660},{ 96, 5065},{ 95, 5456},{ 95, 5849}, - { 96, 6243},{ 96, 6621},{ 97, 6996},{ 101, 7366}, - { 104, 7722},{ 107, 8088},{ 111, 8448},{ 119, 8816} - } - } - }, - { - { - /*Y' qi=6 INTRA*/ - { - { 88, -69},{ 151, 1593},{ 251, 3294},{ 387, 4681}, - { 507, 5790},{ 601, 6837},{ 702, 7787},{ 813, 8648}, - { 927, 9427},{ 1059,10152},{ 1213,10787},{ 1399,11284}, - { 1568,11781},{ 1705,12312},{ 1823,12890},{ 1957,13482}, - { 2106,14036},{ 2249,14600},{ 2411,15042},{ 2588,15359}, - { 2772,15699},{ 2947,16062},{ 3127,16429},{ 3320,16849} - }, - /*Y' qi=6 INTER*/ - { - { 44, -80},{ 36, 1346},{ 69, 2919},{ 111, 4563}, - { 136, 6216},{ 154, 7746},{ 168, 9139},{ 178,10461}, - { 185,11747},{ 195,13007},{ 211,14229},{ 230,15408}, - { 250,16547},{ 274,17663},{ 302,18769},{ 339,19851}, - { 386,20907},{ 446,21933},{ 527,22884},{ 631,23746}, - { 760,24512},{ 914,25178},{ 1087,25758},{ 1278,26262} - } - }, - { - /*Cb qi=6 INTRA*/ - { - { 1, 4},{ 36, 367},{ 66, 739},{ 84, 1174}, - { 105, 1648},{ 126, 2139},{ 140, 2639},{ 149, 3116}, - { 164, 3523},{ 194, 3880},{ 217, 4271},{ 226, 4694}, - { 243, 5077},{ 270, 5407},{ 291, 5742},{ 310, 6061}, - { 340, 6340},{ 373, 6609},{ 394, 6890},{ 409, 7189}, - { 444, 7434},{ 469, 7652},{ 499, 7853},{ 559, 8135} - }, - /*Cb qi=6 INTER*/ - { - { 68, -46},{ 60, 291},{ 50, 623},{ 49, 971}, - { 50, 1357},{ 55, 1781},{ 61, 2211},{ 69, 2634}, - { 78, 3052},{ 86, 3466},{ 91, 3882},{ 95, 4292}, - { 98, 4691},{ 101, 5080},{ 102, 5458},{ 103, 5830}, - { 103, 6192},{ 104, 6554},{ 104, 6916},{ 106, 7278}, - { 108, 7641},{ 110, 8004},{ 112, 8371},{ 112, 8758} - } - }, - { - /*Cr qi=6 INTRA*/ - { - { 1, 8},{ 29, 375},{ 59, 760},{ 84, 1223}, - { 99, 1698},{ 112, 2176},{ 129, 2647},{ 143, 3076}, - { 156, 3510},{ 168, 3906},{ 189, 4269},{ 220, 4682}, - { 241, 5047},{ 266, 5342},{ 299, 5649},{ 331, 5954}, - { 357, 6309},{ 393, 6579},{ 431, 6765},{ 467, 6997}, - { 501, 7276},{ 520, 7488},{ 525, 7749},{ 548, 8146} - }, - /*Cr qi=6 INTER*/ - { - { 94, 31},{ 69, 335},{ 47, 641},{ 43, 967}, - { 50, 1350},{ 57, 1772},{ 65, 2197},{ 74, 2625}, - { 83, 3043},{ 90, 3454},{ 94, 3867},{ 97, 4273}, - { 98, 4671},{ 99, 5068},{ 99, 5461},{ 98, 5857}, - { 98, 6245},{ 99, 6610},{ 103, 6975},{ 105, 7345}, - { 108, 7712},{ 111, 8073},{ 113, 8415},{ 119, 8768} - } - } - }, - { - { - /*Y' qi=7 INTRA*/ - { - { 92, -70},{ 156, 1590},{ 261, 3267},{ 403, 4618}, - { 529, 5704},{ 628, 6730},{ 736, 7657},{ 856, 8491}, - { 978, 9246},{ 1118, 9943},{ 1281,10550},{ 1472,11028}, - { 1645,11507},{ 1793,12008},{ 1924,12565},{ 2067,13130}, - { 2229,13638},{ 2388,14160},{ 2558,14584},{ 2744,14886}, - { 2932,15194},{ 3116,15531},{ 3311,15858},{ 3538,16197} - }, - /*Y' qi=7 INTER*/ - { - { 43, -8},{ 36, 1351},{ 71, 2923},{ 112, 4568}, - { 138, 6201},{ 157, 7705},{ 171, 9083},{ 181,10390}, - { 189,11664},{ 202,12910},{ 220,14121},{ 241,15281}, - { 266,16401},{ 295,17507},{ 328,18608},{ 371,19677}, - { 430,20701},{ 508,21676},{ 604,22588},{ 727,23397}, - { 878,24093},{ 1055,24690},{ 1263,25151},{ 1496,25504} - } - }, - { - /*Cb qi=7 INTRA*/ - { - { 1, 5},{ 40, 367},{ 72, 740},{ 89, 1175}, - { 108, 1649},{ 129, 2140},{ 143, 2637},{ 154, 3110}, - { 169, 3507},{ 198, 3860},{ 224, 4237},{ 235, 4652}, - { 253, 5037},{ 282, 5358},{ 307, 5674},{ 329, 5986}, - { 361, 6273},{ 393, 6527},{ 419, 6777},{ 435, 7078}, - { 467, 7342},{ 495, 7554},{ 529, 7757},{ 591, 8053} - }, - /*Cb qi=7 INTER*/ - { - { 79, -33},{ 68, 299},{ 56, 627},{ 50, 978}, - { 51, 1366},{ 55, 1786},{ 61, 2213},{ 70, 2642}, - { 80, 3062},{ 87, 3474},{ 92, 3886},{ 96, 4292}, - { 99, 4684},{ 102, 5072},{ 103, 5450},{ 104, 5814}, - { 104, 6176},{ 104, 6538},{ 107, 6905},{ 110, 7270}, - { 110, 7625},{ 110, 7978},{ 111, 8340},{ 117, 8674} - } - }, - { - /*Cr qi=7 INTRA*/ - { - { 2, 7},{ 31, 375},{ 62, 760},{ 87, 1223}, - { 103, 1698},{ 115, 2175},{ 131, 2644},{ 147, 3066}, - { 161, 3494},{ 175, 3889},{ 199, 4250},{ 229, 4653}, - { 250, 5001},{ 279, 5275},{ 311, 5577},{ 343, 5889}, - { 376, 6227},{ 417, 6486},{ 457, 6689},{ 484, 6925}, - { 518, 7174},{ 544, 7393},{ 549, 7662},{ 577, 8050} - }, - /*Cr qi=7 INTER*/ - { - { 89, 22},{ 62, 332},{ 45, 641},{ 47, 976}, - { 52, 1363},{ 59, 1779},{ 67, 2203},{ 76, 2628}, - { 84, 3046},{ 90, 3460},{ 94, 3875},{ 98, 4272}, - { 99, 4666},{ 98, 5063},{ 98, 5459},{ 98, 5849}, - { 99, 6226},{ 101, 6594},{ 104, 6957},{ 109, 7324}, - { 109, 7686},{ 111, 8042},{ 115, 8379},{ 119, 8699} - } - } - }, - { - { - /*Y' qi=8 INTRA*/ - { - { 91, -69},{ 160, 1585},{ 274, 3226},{ 423, 4538}, - { 557, 5596},{ 664, 6595},{ 778, 7506},{ 905, 8319}, - { 1038, 9035},{ 1186, 9701},{ 1355,10292},{ 1554,10754}, - { 1739,11196},{ 1904,11639},{ 2047,12184},{ 2194,12763}, - { 2361,13256},{ 2529,13753},{ 2709,14155},{ 2902,14433}, - { 3100,14723},{ 3292,15026},{ 3489,15327},{ 3714,15705} - }, - /*Y' qi=8 INTER*/ - { - { 32, -157},{ 33, 1346},{ 74, 2914},{ 116, 4554}, - { 142, 6172},{ 162, 7648},{ 177, 9004},{ 186,10300}, - { 196,11570},{ 210,12808},{ 231,14001},{ 256,15150}, - { 285,16259},{ 319,17352},{ 359,18435},{ 415,19475}, - { 489,20470},{ 584,21400},{ 703,22246},{ 852,22968}, - { 1038,23556},{ 1253,24032},{ 1503,24367},{ 1778,24628} - } - }, - { - /*Cb qi=8 INTRA*/ - { - { 1, 4},{ 42, 367},{ 75, 740},{ 93, 1176}, - { 111, 1649},{ 128, 2139},{ 144, 2635},{ 157, 3103}, - { 174, 3494},{ 206, 3844},{ 233, 4207},{ 251, 4605}, - { 277, 4980},{ 304, 5284},{ 335, 5584},{ 359, 5888}, - { 393, 6152},{ 432, 6398},{ 455, 6656},{ 471, 6956}, - { 502, 7193},{ 528, 7405},{ 562, 7630},{ 603, 7922} - }, - /*Cb qi=8 INTER*/ - { - { 77, -37},{ 68, 299},{ 58, 632},{ 50, 991}, - { 50, 1382},{ 55, 1799},{ 62, 2226},{ 73, 2647}, - { 82, 3066},{ 90, 3480},{ 94, 3891},{ 96, 4296}, - { 98, 4687},{ 101, 5073},{ 103, 5456},{ 104, 5817}, - { 105, 6170},{ 106, 6523},{ 107, 6886},{ 108, 7250}, - { 109, 7600},{ 110, 7955},{ 111, 8305},{ 112, 8641} - } - }, - { - /*Cr qi=8 INTRA*/ - { - { 2, 7},{ 33, 375},{ 64, 760},{ 92, 1224}, - { 111, 1700},{ 122, 2173},{ 137, 2637},{ 156, 3055}, - { 172, 3476},{ 186, 3856},{ 211, 4211},{ 242, 4597}, - { 263, 4939},{ 292, 5214},{ 335, 5489},{ 376, 5772}, - { 406, 6099},{ 440, 6378},{ 483, 6578},{ 517, 6797}, - { 550, 7049},{ 571, 7283},{ 583, 7560},{ 618, 7967} - }, - /*Cr qi=8 INTER*/ - { - { 74, 25},{ 58, 328},{ 43, 637},{ 45, 980}, - { 51, 1371},{ 59, 1788},{ 69, 2207},{ 79, 2630}, - { 86, 3051},{ 91, 3470},{ 95, 3880},{ 97, 4280}, - { 98, 4680},{ 97, 5074},{ 96, 5456},{ 97, 5839}, - { 99, 6219},{ 101, 6583},{ 103, 6945},{ 106, 7312}, - { 110, 7671},{ 114, 8009},{ 115, 8345},{ 117, 8686} + { 4, 439},{ 2, 1131},{ 3, 1593},{ 6, 2130}, + { 14, 2535},{ 17, 2786},{ 21, 3128},{ 27, 3494}, + { 35, 3875},{ 42, 4256},{ 48, 4637},{ 53, 5019}, + { 57, 5395},{ 61, 5777},{ 64, 6156},{ 66, 6512}, + { 68, 6853},{ 71, 7183},{ 77, 7511},{ 81, 7841}, + { 83, 8192},{ 88, 8510},{ 93, 8834},{ 98, 9138} } } }, @@ -616,557 +93,61 @@ oc_mode_rd OC_MODE_RD[64][3][2][OC_SAD_BINS]={ { /*Y' qi=9 INTRA*/ { - { 104, -68},{ 164, 1580},{ 288, 3173},{ 448, 4439}, - { 587, 5485},{ 702, 6465},{ 824, 7351},{ 958, 8148}, - { 1096, 8845},{ 1253, 9480},{ 1432,10047},{ 1640,10494}, - { 1835,10926},{ 2015,11350},{ 2166,11871},{ 2321,12428}, - { 2508,12876},{ 2684,13345},{ 2866,13741},{ 3069,13991}, - { 3281,14243},{ 3487,14518},{ 3689,14813},{ 3911,15175} + { 76, 777},{ 178, 1995},{ 340, 3162},{ 591, 4097}, + { 746, 4973},{ 916, 5847},{ 1047, 6687},{ 1218, 7430}, + { 1385, 8079},{ 1566, 8685},{ 1755, 9167},{ 1992, 9572}, + { 2164,10023},{ 2395,10270},{ 2536,10755},{ 2694,11285}, + { 2895,11580},{ 3029,12143},{ 3182,12543},{ 3377,12800}, + { 3525,13228},{ 3718,13463},{ 3878,13852},{ 4077,14001} }, /*Y' qi=9 INTER*/ { - { 47, -140},{ 34, 1348},{ 77, 2915},{ 119, 4552}, - { 145, 6150},{ 166, 7600},{ 182, 8936},{ 192,10221}, - { 203,11482},{ 220,12711},{ 244,13886},{ 274,15012}, - { 308,16111},{ 349,17190},{ 401,18244},{ 470,19257}, - { 561,20209},{ 680,21069},{ 830,21822},{ 1010,22463}, - { 1227,22971},{ 1482,23328},{ 1769,23544},{ 2077,23655} + { 10, 770},{ 45, 1845},{ 59, 3227},{ 99, 4708}, + { 135, 6092},{ 164, 7425},{ 190, 8729},{ 218, 9991}, + { 246,11234},{ 281,12427},{ 315,13573},{ 354,14678}, + { 402,15734},{ 467,16728},{ 543,17709},{ 639,18610}, + { 736,19503},{ 855,20312},{ 995,21033},{ 1151,21656}, + { 1341,22130},{ 1525,22582},{ 1735,22922},{ 1922,23102} } }, { /*Cb qi=9 INTRA*/ { - { 1, 5},{ 43, 367},{ 76, 740},{ 95, 1176}, - { 114, 1649},{ 135, 2138},{ 153, 2629},{ 165, 3091}, - { 184, 3481},{ 217, 3831},{ 244, 4187},{ 260, 4572}, - { 290, 4930},{ 320, 5231},{ 351, 5521},{ 379, 5812}, - { 414, 6055},{ 452, 6307},{ 483, 6564},{ 502, 6848}, - { 525, 7115},{ 554, 7321},{ 589, 7533},{ 626, 7833} + { 41, 1227},{ 70, 1452},{ 102, 1697},{ 110, 1967}, + { 134, 2326},{ 153, 2695},{ 160, 3007},{ 196, 3393}, + { 232, 3769},{ 266, 4067},{ 297, 4376},{ 326, 4728}, + { 351, 5040},{ 390, 5299},{ 398, 5538},{ 443, 5900}, + { 448, 6107},{ 506, 6370},{ 519, 6636},{ 525, 6953}, + { 567, 7177},{ 625, 7386},{ 622, 7613},{ 654, 7764} }, /*Cb qi=9 INTER*/ { - { 101, -43},{ 81, 298},{ 62, 637},{ 49, 989}, - { 51, 1381},{ 56, 1806},{ 65, 2231},{ 74, 2653}, - { 84, 3071},{ 91, 3482},{ 95, 3892},{ 97, 4293}, - { 99, 4684},{ 101, 5066},{ 103, 5437},{ 103, 5793}, - { 103, 6148},{ 104, 6511},{ 105, 6867},{ 107, 7221}, - { 110, 7572},{ 111, 7926},{ 112, 8283},{ 116, 8625} + { 7, 377},{ 2, 1102},{ 7, 1262},{ 19, 1693}, + { 22, 1957},{ 27, 2302},{ 35, 2654},{ 43, 3034}, + { 52, 3431},{ 58, 3826},{ 63, 4207},{ 67, 4570}, + { 71, 4927},{ 75, 5283},{ 79, 5624},{ 82, 5944}, + { 85, 6279},{ 88, 6616},{ 94, 6955},{ 102, 7284}, + { 108, 7622},{ 116, 7944},{ 124, 8293},{ 133, 8568} } }, { /*Cr qi=9 INTRA*/ { - { 2, 7},{ 35, 375},{ 66, 761},{ 93, 1224}, - { 112, 1700},{ 126, 2173},{ 144, 2633},{ 165, 3047}, - { 183, 3458},{ 199, 3835},{ 224, 4191},{ 257, 4558}, - { 283, 4887},{ 309, 5176},{ 351, 5446},{ 397, 5713}, - { 433, 6017},{ 469, 6283},{ 508, 6480},{ 546, 6687}, - { 579, 6945},{ 600, 7182},{ 610, 7434},{ 623, 7793} + { 38, 1217},{ 61, 1473},{ 88, 1650},{ 100, 1908}, + { 137, 2400},{ 147, 2777},{ 176, 3149},{ 205, 3433}, + { 227, 3772},{ 249, 4092},{ 286, 4370},{ 313, 4746}, + { 342, 5053},{ 368, 5261},{ 411, 5530},{ 442, 5859}, + { 494, 6061},{ 526, 6340},{ 532, 6646},{ 580, 6799}, + { 567, 7203},{ 649, 7357},{ 625, 7559},{ 660, 7709} }, /*Cr qi=9 INTER*/ { - { 77, 15},{ 57, 330},{ 45, 640},{ 48, 980}, - { 54, 1380},{ 61, 1802},{ 70, 2220},{ 80, 2639}, - { 87, 3057},{ 92, 3474},{ 94, 3882},{ 98, 4282}, - { 98, 4675},{ 97, 5062},{ 97, 5450},{ 98, 5829}, - { 100, 6197},{ 101, 6561},{ 104, 6927},{ 107, 7289}, - { 113, 7638},{ 117, 7978},{ 119, 8311},{ 117, 8629} - } - } - }, - { - { - /*Y' qi=10 INTRA*/ - { - { 101, -69},{ 168, 1574},{ 299, 3143},{ 465, 4386}, - { 610, 5410},{ 736, 6353},{ 866, 7207},{ 1006, 7982}, - { 1153, 8655},{ 1319, 9261},{ 1504, 9812},{ 1719,10248}, - { 1928,10653},{ 2116,11056},{ 2282,11550},{ 2458,12070}, - { 2654,12492},{ 2846,12923},{ 3043,13291},{ 3249,13537}, - { 3466,13764},{ 3682,13999},{ 3896,14268},{ 4145,14548} - }, - /*Y' qi=10 INTER*/ - { - { 48, -94},{ 34, 1355},{ 81, 2920},{ 124, 4545}, - { 151, 6113},{ 174, 7532},{ 190, 8850},{ 201,10125}, - { 214,11379},{ 235,12591},{ 264,13745},{ 299,14859}, - { 338,15948},{ 388,17008},{ 456,18029},{ 546,18988}, - { 661,19877},{ 808,20666},{ 993,21321},{ 1218,21835}, - { 1481,22203},{ 1783,22420},{ 2117,22504},{ 2469,22481} - } - }, - { - /*Cb qi=10 INTRA*/ - { - { 2, 4},{ 44, 367},{ 79, 740},{ 99, 1178}, - { 117, 1652},{ 137, 2141},{ 156, 2630},{ 170, 3089}, - { 192, 3474},{ 227, 3813},{ 259, 4157},{ 282, 4526}, - { 310, 4860},{ 342, 5140},{ 377, 5425},{ 400, 5714}, - { 436, 5952},{ 475, 6194},{ 496, 6468},{ 522, 6748}, - { 559, 6996},{ 587, 7216},{ 617, 7433},{ 673, 7678} - }, - /*Cb qi=10 INTER*/ - { - { 87, -37},{ 72, 301},{ 58, 636},{ 49, 995}, - { 51, 1394},{ 57, 1819},{ 66, 2241},{ 78, 2660}, - { 87, 3074},{ 93, 3482},{ 97, 3891},{ 99, 4294}, - { 101, 4678},{ 103, 5050},{ 105, 5414},{ 106, 5773}, - { 107, 6134},{ 108, 6485},{ 110, 6832},{ 113, 7187}, - { 113, 7547},{ 114, 7887},{ 117, 8230},{ 112, 8590} - } - }, - { - /*Cr qi=10 INTRA*/ - { - { 2, 7},{ 38, 375},{ 69, 761},{ 96, 1224}, - { 116, 1701},{ 131, 2175},{ 148, 2634},{ 168, 3041}, - { 190, 3439},{ 211, 3802},{ 238, 4151},{ 271, 4506}, - { 297, 4824},{ 331, 5103},{ 373, 5360},{ 415, 5632}, - { 459, 5928},{ 500, 6176},{ 535, 6386},{ 573, 6586}, - { 608, 6834},{ 629, 7079},{ 642, 7337},{ 686, 7680} - }, - /*Cr qi=10 INTER*/ - { - { 81, 34},{ 63, 333},{ 50, 633},{ 48, 987}, - { 53, 1397},{ 61, 1820},{ 71, 2237},{ 83, 2651}, - { 91, 3065},{ 95, 3479},{ 98, 3882},{ 100, 4279}, - { 101, 4673},{ 101, 5054},{ 100, 5429},{ 101, 5801}, - { 102, 6173},{ 104, 6541},{ 108, 6904},{ 110, 7264}, - { 114, 7609},{ 119, 7945},{ 123, 8275},{ 128, 8615} - } - } - }, - { - { - /*Y' qi=11 INTRA*/ - { - { 110, -66},{ 176, 1564},{ 316, 3087},{ 492, 4296}, - { 645, 5299},{ 781, 6217},{ 924, 7039},{ 1075, 7776}, - { 1232, 8421},{ 1410, 9005},{ 1607, 9532},{ 1834, 9929}, - { 2053,10300},{ 2249,10697},{ 2427,11184},{ 2619,11682}, - { 2826,12083},{ 3019,12508},{ 3225,12869},{ 3452,13064}, - { 3670,13280},{ 3890,13519},{ 4123,13750},{ 4367,14059} - }, - /*Y' qi=11 INTER*/ - { - { 72, -115},{ 32, 1354},{ 83, 2911},{ 126, 4534}, - { 154, 6080},{ 178, 7475},{ 194, 8779},{ 205,10047}, - { 222,11290},{ 246,12488},{ 281,13621},{ 322,14714}, - { 372,15786},{ 436,16821},{ 519,17813},{ 628,18728}, - { 770,19549},{ 950,20254},{ 1175,20800},{ 1443,21197}, - { 1752,21446},{ 2095,21555},{ 2457,21553},{ 2808,21544} - } - }, - { - /*Cb qi=11 INTRA*/ - { - { 2, 4},{ 45, 367},{ 81, 740},{ 101, 1177}, - { 121, 1650},{ 142, 2136},{ 159, 2621},{ 174, 3075}, - { 199, 3451},{ 234, 3778},{ 265, 4117},{ 297, 4473}, - { 333, 4789},{ 367, 5054},{ 402, 5319},{ 427, 5613}, - { 462, 5871},{ 503, 6107},{ 532, 6336},{ 560, 6584}, - { 601, 6842},{ 631, 7092},{ 662, 7292},{ 721, 7497} - }, - /*Cb qi=11 INTER*/ - { - { 117, -24},{ 93, 308},{ 69, 638},{ 52, 993}, - { 52, 1395},{ 58, 1822},{ 68, 2246},{ 80, 2665}, - { 89, 3082},{ 94, 3492},{ 96, 3900},{ 98, 4299}, - { 101, 4679},{ 103, 5047},{ 104, 5405},{ 106, 5763}, - { 106, 6120},{ 107, 6474},{ 109, 6823},{ 112, 7163}, - { 115, 7516},{ 117, 7868},{ 118, 8213},{ 119, 8561} - } - }, - { - /*Cr qi=11 INTRA*/ - { - { 2, 7},{ 40, 375},{ 75, 761},{ 100, 1224}, - { 119, 1700},{ 137, 2169},{ 154, 2622},{ 178, 3025}, - { 198, 3416},{ 220, 3770},{ 255, 4114},{ 294, 4459}, - { 323, 4756},{ 359, 5028},{ 399, 5292},{ 438, 5556}, - { 483, 5827},{ 518, 6073},{ 551, 6298},{ 598, 6501}, - { 634, 6754},{ 652, 6997},{ 670, 7211},{ 689, 7560} - }, - /*Cr qi=11 INTER*/ - { - { 75, 30},{ 61, 334},{ 51, 639},{ 49, 995}, - { 53, 1403},{ 62, 1821},{ 73, 2237},{ 84, 2654}, - { 91, 3070},{ 95, 3485},{ 96, 3890},{ 98, 4287}, - { 98, 4672},{ 99, 5050},{ 99, 5427},{ 100, 5798}, - { 103, 6169},{ 105, 6528},{ 107, 6881},{ 113, 7233}, - { 118, 7580},{ 121, 7916},{ 125, 8240},{ 130, 8551} - } - } - }, - { - { - /*Y' qi=12 INTRA*/ - { - { 104, -69},{ 182, 1557},{ 335, 3040},{ 521, 4205}, - { 684, 5178},{ 831, 6068},{ 986, 6854},{ 1151, 7559}, - { 1323, 8169},{ 1523, 8704},{ 1736, 9192},{ 1978, 9558}, - { 2213, 9908},{ 2421,10298},{ 2613,10757},{ 2822,11208}, - { 3042,11585},{ 3250,11991},{ 3474,12308},{ 3710,12480}, - { 3939,12687},{ 4174,12902},{ 4416,13102},{ 4672,13369} - }, - /*Y' qi=12 INTER*/ - { - { 52, -91},{ 34, 1355},{ 86, 2911},{ 129, 4518}, - { 159, 6037},{ 184, 7405},{ 200, 8694},{ 213, 9955}, - { 232,11185},{ 263,12360},{ 304,13479},{ 354,14555}, - { 415,15601},{ 495,16608},{ 601,17549},{ 738,18400}, - { 915,19136},{ 1139,19724},{ 1414,20150},{ 1731,20412}, - { 2090,20520},{ 2473,20509},{ 2851,20442},{ 3227,20328} - } - }, - { - /*Cb qi=12 INTRA*/ - { - { 1, 4},{ 46, 367},{ 85, 740},{ 109, 1178}, - { 126, 1650},{ 145, 2134},{ 165, 2617},{ 182, 3061}, - { 209, 3428},{ 245, 3749},{ 281, 4077},{ 316, 4417}, - { 354, 4718},{ 392, 4970},{ 430, 5217},{ 456, 5501}, - { 490, 5771},{ 534, 5996},{ 571, 6207},{ 600, 6458}, - { 644, 6697},{ 675, 6942},{ 707, 7151},{ 766, 7342} - }, - /*Cb qi=12 INTER*/ - { - { 84, -24},{ 73, 311},{ 60, 644},{ 52, 998}, - { 53, 1398},{ 60, 1825},{ 71, 2249},{ 83, 2665}, - { 90, 3081},{ 94, 3490},{ 97, 3893},{ 99, 4286}, - { 102, 4663},{ 104, 5032},{ 105, 5393},{ 106, 5751}, - { 107, 6102},{ 108, 6445},{ 111, 6788},{ 113, 7136}, - { 114, 7483},{ 117, 7828},{ 121, 8163},{ 122, 8496} - } - }, - { - /*Cr qi=12 INTRA*/ - { - { 3, 7},{ 41, 375},{ 78, 761},{ 106, 1225}, - { 124, 1700},{ 140, 2167},{ 163, 2616},{ 188, 3010}, - { 213, 3385},{ 240, 3718},{ 271, 4062},{ 309, 4406}, - { 345, 4691},{ 387, 4956},{ 430, 5212},{ 469, 5467}, - { 513, 5729},{ 554, 5970},{ 587, 6176},{ 633, 6395}, - { 673, 6659},{ 692, 6868},{ 712, 7061},{ 758, 7259} - }, - /*Cr qi=12 INTER*/ - { - { 73, 31},{ 59, 335},{ 48, 638},{ 50, 998}, - { 56, 1410},{ 65, 1827},{ 75, 2240},{ 85, 2657}, - { 92, 3073},{ 95, 3485},{ 97, 3888},{ 99, 4279}, - { 98, 4663},{ 99, 5042},{ 101, 5412},{ 102, 5779}, - { 105, 6142},{ 107, 6498},{ 108, 6848},{ 113, 7198}, - { 118, 7540},{ 121, 7867},{ 127, 8188},{ 132, 8508} - } - } - }, - { - { - /*Y' qi=13 INTRA*/ - { - { 109, -68},{ 187, 1551},{ 347, 3010},{ 541, 4153}, - { 709, 5107},{ 864, 5975},{ 1026, 6745},{ 1194, 7433}, - { 1375, 8021},{ 1581, 8550},{ 1803, 9026},{ 2054, 9371}, - { 2301, 9713},{ 2522,10082},{ 2728,10515},{ 2949,10956}, - { 3184,11297},{ 3408,11653},{ 3643,11946},{ 3886,12100}, - { 4124,12277},{ 4377,12459},{ 4632,12635},{ 4898,12861} - }, - /*Y' qi=13 INTER*/ - { - { 48, -78},{ 35, 1357},{ 89, 2914},{ 133, 4512}, - { 164, 6004},{ 190, 7348},{ 207, 8627},{ 222, 9881}, - { 247,11096},{ 284,12251},{ 333,13350},{ 392,14407}, - { 466,15426},{ 565,16391},{ 696,17279},{ 865,18058}, - { 1085,18689},{ 1358,19156},{ 1684,19456},{ 2050,19605}, - { 2447,19614},{ 2855,19524},{ 3243,19398},{ 3611,19201} - } - }, - { - /*Cb qi=13 INTRA*/ - { - { 2, 4},{ 47, 367},{ 86, 741},{ 108, 1179}, - { 127, 1651},{ 150, 2133},{ 173, 2611},{ 194, 3050}, - { 222, 3417},{ 262, 3733},{ 303, 4048},{ 337, 4375}, - { 378, 4657},{ 420, 4897},{ 456, 5148},{ 486, 5422}, - { 518, 5682},{ 558, 5903},{ 592, 6113},{ 623, 6372}, - { 662, 6628},{ 700, 6833},{ 751, 6989},{ 805, 7147} - }, - /*Cb qi=13 INTER*/ - { - { 94, -34},{ 78, 303},{ 60, 638},{ 51, 994}, - { 54, 1406},{ 61, 1836},{ 73, 2253},{ 84, 2668}, - { 92, 3082},{ 96, 3492},{ 99, 3894},{ 101, 4284}, - { 103, 4659},{ 105, 5023},{ 106, 5376},{ 108, 5726}, - { 109, 6070},{ 110, 6418},{ 113, 6765},{ 117, 7105}, - { 119, 7448},{ 122, 7784},{ 126, 8119},{ 131, 8463} - } - }, - { - /*Cr qi=13 INTRA*/ - { - { 3, 7},{ 43, 375},{ 80, 762},{ 110, 1226}, - { 131, 1701},{ 149, 2166},{ 172, 2610},{ 196, 2999}, - { 221, 3359},{ 254, 3679},{ 292, 4005},{ 332, 4329}, - { 369, 4612},{ 408, 4880},{ 456, 5139},{ 500, 5388}, - { 544, 5631},{ 581, 5877},{ 615, 6101},{ 660, 6316}, - { 692, 6594},{ 714, 6795},{ 736, 6997},{ 789, 7290} - }, - /*Cr qi=13 INTER*/ - { - { 73, 28},{ 61, 336},{ 46, 642},{ 50, 1003}, - { 58, 1414},{ 67, 1832},{ 79, 2245},{ 87, 2660}, - { 93, 3075},{ 97, 3484},{ 99, 3888},{ 100, 4277}, - { 100, 4651},{ 100, 5027},{ 101, 5403},{ 102, 5765}, - { 105, 6116},{ 109, 6470},{ 113, 6825},{ 119, 7163}, - { 124, 7497},{ 127, 7827},{ 131, 8137},{ 135, 8437} - } - } - }, - { - { - /*Y' qi=14 INTRA*/ - { - { 113, -68},{ 191, 1545},{ 358, 2981},{ 559, 4104}, - { 733, 5044},{ 896, 5890},{ 1066, 6636},{ 1241, 7304}, - { 1428, 7886},{ 1642, 8402},{ 1872, 8871},{ 2128, 9219}, - { 2380, 9547},{ 2609, 9908},{ 2825,10321},{ 3055,10728}, - { 3294,11076},{ 3523,11425},{ 3766,11689},{ 4013,11845}, - { 4254,12022},{ 4506,12209},{ 4759,12383},{ 5013,12637} - }, - /*Y' qi=14 INTER*/ - { - { 58, -82},{ 38, 1362},{ 93, 2914},{ 138, 4492}, - { 171, 5962},{ 198, 7289},{ 216, 8559},{ 234, 9804}, - { 263,11005},{ 306,12143},{ 363,13222},{ 434,14259}, - { 523,15255},{ 639,16188},{ 794,17021},{ 1000,17717}, - { 1262,18260},{ 1575,18645},{ 1943,18841},{ 2356,18872}, - { 2782,18802},{ 3194,18682},{ 3576,18559},{ 3923,18447} - } - }, - { - /*Cb qi=14 INTRA*/ - { - { 2, 3},{ 50, 367},{ 91, 741},{ 114, 1180}, - { 134, 1651},{ 157, 2131},{ 181, 2601},{ 208, 3028}, - { 239, 3391},{ 279, 3706},{ 322, 4000},{ 361, 4309}, - { 406, 4587},{ 445, 4822},{ 482, 5067},{ 515, 5344}, - { 546, 5612},{ 589, 5821},{ 626, 6020},{ 655, 6276}, - { 701, 6523},{ 748, 6717},{ 796, 6876},{ 815, 7151} - }, - /*Cb qi=14 INTER*/ - { - { 80, -43},{ 68, 301},{ 56, 644},{ 50, 1004}, - { 54, 1412},{ 63, 1836},{ 75, 2253},{ 87, 2670}, - { 94, 3083},{ 98, 3487},{ 101, 3885},{ 103, 4271}, - { 106, 4645},{ 107, 5004},{ 108, 5358},{ 109, 5705}, - { 112, 6047},{ 115, 6388},{ 118, 6731},{ 121, 7081}, - { 126, 7421},{ 129, 7747},{ 132, 8076},{ 137, 8419} - } - }, - { - /*Cr qi=14 INTRA*/ - { - { 3, 6},{ 45, 375},{ 85, 762},{ 116, 1226}, - { 138, 1700},{ 158, 2163},{ 180, 2602},{ 206, 2985}, - { 236, 3333},{ 270, 3639},{ 310, 3956},{ 359, 4258}, - { 397, 4524},{ 430, 4802},{ 478, 5068},{ 527, 5316}, - { 572, 5560},{ 613, 5802},{ 654, 6012},{ 699, 6216}, - { 734, 6489},{ 755, 6707},{ 775, 6898},{ 841, 7111} - }, - /*Cr qi=14 INTER*/ - { - { 78, 0},{ 59, 322},{ 46, 649},{ 51, 1016}, - { 58, 1422},{ 68, 1839},{ 81, 2253},{ 90, 2666}, - { 95, 3080},{ 98, 3486},{ 101, 3881},{ 102, 4268}, - { 102, 4644},{ 103, 5017},{ 105, 5382},{ 106, 5743}, - { 108, 6093},{ 112, 6442},{ 118, 6791},{ 124, 7130}, - { 127, 7463},{ 133, 7784},{ 138, 8085},{ 142, 8395} - } - } - }, - { - { - /*Y' qi=15 INTRA*/ - { - { 111, -66},{ 197, 1538},{ 370, 2949},{ 579, 4050}, - { 762, 4968},{ 933, 5798},{ 1112, 6520},{ 1299, 7161}, - { 1497, 7725},{ 1723, 8219},{ 1967, 8654},{ 2234, 8990}, - { 2499, 9302},{ 2740, 9637},{ 2968,10039},{ 3215,10414}, - { 3473,10709},{ 3721,11015},{ 3971,11270},{ 4228,11402}, - { 4487,11543},{ 4752,11707},{ 5011,11871},{ 5290,12099} - }, - /*Y' qi=15 INTER*/ - { - { 59, -113},{ 37, 1349},{ 95, 2904},{ 139, 4478}, - { 174, 5929},{ 201, 7244},{ 220, 8505},{ 241, 9736}, - { 275,10922},{ 327,12040},{ 395,13097},{ 477,14114}, - { 585,15071},{ 730,15947},{ 917,16714},{ 1162,17326}, - { 1468,17770},{ 1833,18029},{ 2251,18111},{ 2694,18068}, - { 3125,17968},{ 3529,17845},{ 3908,17713},{ 4260,17587} - } - }, - { - /*Cb qi=15 INTRA*/ - { - { 2, 3},{ 51, 367},{ 94, 741},{ 120, 1180}, - { 140, 1651},{ 160, 2129},{ 184, 2591},{ 213, 3010}, - { 246, 3371},{ 289, 3680},{ 335, 3969},{ 374, 4274}, - { 418, 4546},{ 460, 4783},{ 498, 5019},{ 532, 5280}, - { 565, 5553},{ 608, 5765},{ 647, 5958},{ 683, 6193}, - { 732, 6433},{ 782, 6620},{ 832, 6769},{ 848, 7027} - }, - /*Cb qi=15 INTER*/ - { - { 71, -52},{ 63, 296},{ 54, 644},{ 50, 1010}, - { 53, 1417},{ 64, 1837},{ 77, 2253},{ 88, 2666}, - { 95, 3079},{ 98, 3487},{ 100, 3882},{ 103, 4264}, - { 106, 4633},{ 108, 4991},{ 109, 5343},{ 109, 5693}, - { 112, 6038},{ 114, 6371},{ 119, 6709},{ 123, 7051}, - { 125, 7385},{ 130, 7716},{ 135, 8050},{ 140, 8374} - } - }, - { - /*Cr qi=15 INTRA*/ - { - { 2, 6},{ 47, 375},{ 87, 763},{ 119, 1225}, - { 143, 1699},{ 162, 2158},{ 185, 2595},{ 213, 2971}, - { 246, 3315},{ 279, 3618},{ 320, 3920},{ 372, 4210}, - { 409, 4480},{ 446, 4756},{ 496, 5017},{ 542, 5263}, - { 590, 5487},{ 639, 5721},{ 687, 5923},{ 724, 6132}, - { 753, 6417},{ 781, 6622},{ 805, 6806},{ 856, 6977} - }, - /*Cr qi=15 INTER*/ - { - { 71, 3},{ 61, 326},{ 52, 651},{ 50, 1017}, - { 58, 1422},{ 69, 1837},{ 82, 2251},{ 90, 2668}, - { 95, 3080},{ 98, 3484},{ 101, 3877},{ 102, 4257}, - { 102, 4632},{ 101, 5005},{ 103, 5370},{ 106, 5733}, - { 110, 6082},{ 116, 6424},{ 120, 6774},{ 124, 7106}, - { 130, 7427},{ 135, 7748},{ 141, 8052},{ 147, 8333} - } - } - }, - { - { - /*Y' qi=16 INTRA*/ - { - { 114, -63},{ 206, 1525},{ 396, 2887},{ 618, 3945}, - { 816, 4832},{ 1002, 5626},{ 1196, 6319},{ 1401, 6923}, - { 1616, 7458},{ 1857, 7928},{ 2121, 8334},{ 2405, 8645}, - { 2685, 8934},{ 2938, 9255},{ 3175, 9638},{ 3433, 9990}, - { 3707,10263},{ 3958,10577},{ 4218,10807},{ 4488,10906}, - { 4760,11028},{ 5037,11148},{ 5306,11286},{ 5625,11463} - }, - /*Y' qi=16 INTER*/ - { - { 69, -153},{ 39, 1348},{ 98, 2894},{ 144, 4448}, - { 181, 5872},{ 209, 7167},{ 228, 8422},{ 254, 9644}, - { 297,10810},{ 359,11908},{ 438,12944},{ 539,13930}, - { 672,14842},{ 850,15650},{ 1085,16318},{ 1391,16793}, - { 1769,17082},{ 2200,17198},{ 2659,17174},{ 3116,17072}, - { 3547,16948},{ 3943,16819},{ 4299,16701},{ 4611,16644} - } - }, - { - /*Cb qi=16 INTRA*/ - { - { 3, 4},{ 54, 367},{ 97, 742},{ 122, 1181}, - { 143, 1651},{ 168, 2123},{ 197, 2575},{ 226, 2985}, - { 263, 3338},{ 314, 3631},{ 367, 3903},{ 409, 4200}, - { 453, 4468},{ 491, 4703},{ 528, 4932},{ 566, 5188}, - { 601, 5459},{ 647, 5672},{ 693, 5844},{ 734, 6058}, - { 784, 6305},{ 836, 6460},{ 882, 6602},{ 905, 6891} - }, - /*Cb qi=16 INTER*/ - { - { 75, -64},{ 67, 292},{ 56, 645},{ 51, 1016}, - { 54, 1421},{ 66, 1842},{ 79, 2257},{ 89, 2670}, - { 95, 3082},{ 98, 3488},{ 101, 3879},{ 104, 4258}, - { 106, 4623},{ 108, 4974},{ 109, 5321},{ 113, 5664}, - { 116, 6001},{ 117, 6341},{ 123, 6677},{ 128, 7004}, - { 130, 7336},{ 136, 7671},{ 143, 7996},{ 148, 8310} - } - }, - { - /*Cr qi=16 INTRA*/ - { - { 4, 7},{ 50, 375},{ 90, 763},{ 124, 1225}, - { 148, 1698},{ 168, 2154},{ 195, 2582},{ 227, 2948}, - { 263, 3279},{ 302, 3575},{ 343, 3865},{ 394, 4137}, - { 439, 4402},{ 482, 4672},{ 533, 4925},{ 579, 5165}, - { 626, 5382},{ 675, 5616},{ 725, 5812},{ 769, 5991}, - { 810, 6242},{ 848, 6430},{ 868, 6615},{ 944, 6732} - }, - /*Cr qi=16 INTER*/ - { - { 78, 11},{ 62, 327},{ 49, 650},{ 50, 1025}, - { 59, 1431},{ 72, 1841},{ 83, 2253},{ 90, 2671}, - { 95, 3084},{ 98, 3487},{ 100, 3879},{ 101, 4254}, - { 102, 4625},{ 103, 4994},{ 106, 5355},{ 108, 5708}, - { 111, 6058},{ 115, 6400},{ 121, 6733},{ 128, 7058}, - { 134, 7374},{ 140, 7691},{ 146, 7993},{ 146, 8317} - } - } - }, - { - { - /*Y' qi=17 INTRA*/ - { - { 112, -59},{ 210, 1515},{ 409, 2850},{ 640, 3882}, - { 844, 4748},{ 1038, 5529},{ 1240, 6206},{ 1452, 6803}, - { 1676, 7330},{ 1925, 7792},{ 2194, 8201},{ 2483, 8512}, - { 2766, 8801},{ 3027, 9121},{ 3279, 9482},{ 3548, 9810}, - { 3825,10069},{ 4088,10345},{ 4362,10544},{ 4638,10644}, - { 4915,10744},{ 5196,10850},{ 5471,10981},{ 5802,11136} - }, - /*Y' qi=17 INTER*/ - { - { 70, -147},{ 45, 1349},{ 106, 2894},{ 155, 4425}, - { 195, 5818},{ 225, 7099},{ 247, 8348},{ 278, 9565}, - { 328,10717},{ 399,11794},{ 491,12807},{ 609,13760}, - { 766,14623},{ 984,15349},{ 1274,15902},{ 1642,16256}, - { 2082,16411},{ 2563,16409},{ 3048,16315},{ 3508,16194}, - { 3924,16064},{ 4306,15938},{ 4656,15828},{ 4966,15733} - } - }, - { - /*Cb qi=17 INTRA*/ - { - { 3, 4},{ 57, 367},{ 101, 742},{ 126, 1182}, - { 148, 1650},{ 175, 2118},{ 207, 2565},{ 241, 2966}, - { 279, 3307},{ 331, 3588},{ 389, 3845},{ 435, 4132}, - { 474, 4408},{ 517, 4641},{ 560, 4869},{ 602, 5122}, - { 638, 5389},{ 672, 5610},{ 716, 5787},{ 758, 6002}, - { 817, 6226},{ 869, 6393},{ 916, 6530},{ 950, 6799} - }, - /*Cb qi=17 INTER*/ - { - { 105, -65},{ 86, 288},{ 66, 638},{ 54, 1014}, - { 59, 1427},{ 71, 1844},{ 86, 2257},{ 95, 2668}, - { 100, 3075},{ 103, 3476},{ 106, 3867},{ 110, 4241}, - { 112, 4598},{ 114, 4948},{ 117, 5294},{ 121, 5633}, - { 123, 5968},{ 126, 6301},{ 131, 6637},{ 136, 6968}, - { 144, 7287},{ 152, 7606},{ 158, 7931},{ 162, 8262} - } - }, - { - /*Cr qi=17 INTRA*/ - { - { 4, 6},{ 55, 376},{ 97, 765},{ 128, 1226}, - { 152, 1696},{ 175, 2144},{ 204, 2568},{ 241, 2928}, - { 282, 3250},{ 323, 3530},{ 368, 3811},{ 420, 4089}, - { 463, 4347},{ 505, 4609},{ 562, 4860},{ 609, 5094}, - { 655, 5303},{ 709, 5535},{ 759, 5740},{ 803, 5913}, - { 844, 6153},{ 879, 6350},{ 905, 6527},{ 972, 6637} - }, - /*Cr qi=17 INTER*/ - { - { 88, 8},{ 68, 330},{ 51, 653},{ 54, 1028}, - { 65, 1433},{ 77, 1845},{ 89, 2257},{ 96, 2669}, - { 100, 3081},{ 102, 3481},{ 105, 3867},{ 106, 4245}, - { 108, 4613},{ 110, 4971},{ 112, 5328},{ 115, 5679}, - { 120, 6019},{ 127, 6355},{ 133, 6686},{ 140, 7007}, - { 149, 7316},{ 158, 7618},{ 166, 7924},{ 170, 8232} + { 5, 408},{ 3, 1197},{ 7, 1275},{ 16, 1695}, + { 22, 1979},{ 30, 2324},{ 38, 2691},{ 47, 3071}, + { 53, 3462},{ 59, 3857},{ 64, 4255},{ 69, 4612}, + { 74, 4975},{ 76, 5347},{ 81, 5694},{ 86, 6020}, + { 91, 6357},{ 96, 6687},{ 102, 7020},{ 108, 7351}, + { 115, 7663},{ 122, 7979},{ 125, 8298},{ 136, 8576} } } }, @@ -1174,557 +155,61 @@ oc_mode_rd OC_MODE_RD[64][3][2][OC_SAD_BINS]={ { /*Y' qi=18 INTRA*/ { - { 122, -58},{ 216, 1506},{ 425, 2815},{ 665, 3822}, - { 882, 4666},{ 1088, 5425},{ 1301, 6084},{ 1529, 6653}, - { 1766, 7162},{ 2026, 7611},{ 2312, 7987},{ 2612, 8278}, - { 2913, 8551},{ 3196, 8840},{ 3454, 9184},{ 3734, 9490}, - { 4030, 9725},{ 4305, 9973},{ 4585,10162},{ 4864,10251}, - { 5150,10324},{ 5443,10420},{ 5727,10536},{ 6053,10682} + { 83, 534},{ 261, 1697},{ 507, 2691},{ 852, 3418}, + { 1127, 4094},{ 1378, 4775},{ 1626, 5442},{ 1905, 5975}, + { 2164, 6468},{ 2445, 6913},{ 2704, 7301},{ 3001, 7631}, + { 3285, 7934},{ 3536, 8217},{ 3837, 8489},{ 4076, 8814}, + { 4325, 9046},{ 4590, 9313},{ 4794, 9546},{ 5062, 9751}, + { 5285, 9963},{ 5578,10079},{ 5777,10302},{ 6054,10296} }, /*Y' qi=18 INTER*/ { - { 66, -143},{ 47, 1351},{ 108, 2886},{ 158, 4401}, - { 200, 5775},{ 232, 7044},{ 256, 8288},{ 292, 9493}, - { 351,10625},{ 434,11679},{ 541,12665},{ 681,13578}, - { 875,14379},{ 1136,15025},{ 1483,15475},{ 1914,15709}, - { 2399,15767},{ 2907,15699},{ 3400,15579},{ 3852,15453}, - { 4259,15332},{ 4630,15221},{ 4976,15121},{ 5294,15061} + { 33, 490},{ 62, 1599},{ 96, 3015},{ 164, 4378}, + { 225, 5633},{ 285, 6831},{ 351, 7999},{ 427, 9133}, + { 526,10181},{ 652,11141},{ 829,11991},{ 1049,12732}, + { 1310,13367},{ 1592,13896},{ 1881,14350},{ 2207,14667}, + { 2529,14877},{ 2873,14980},{ 3231,14949},{ 3571,14926}, + { 3922,14816},{ 4246,14715},{ 4559,14579},{ 4778,14590} } }, { /*Cb qi=18 INTRA*/ { - { 2, 3},{ 61, 367},{ 107, 743},{ 131, 1182}, - { 155, 1648},{ 183, 2110},{ 220, 2542},{ 260, 2927}, - { 303, 3265},{ 359, 3540},{ 416, 3785},{ 462, 4063}, - { 506, 4334},{ 553, 4567},{ 595, 4797},{ 636, 5049}, - { 676, 5304},{ 717, 5516},{ 759, 5698},{ 801, 5904}, - { 861, 6133},{ 911, 6311},{ 962, 6443},{ 1021, 6645} + { 55, 825},{ 95, 1021},{ 131, 1276},{ 150, 1618}, + { 180, 1958},{ 220, 2306},{ 256, 2608},{ 322, 2939}, + { 385, 3239},{ 436, 3530},{ 475, 3771},{ 518, 4078}, + { 557, 4348},{ 604, 4592},{ 620, 4851},{ 676, 5083}, + { 704, 5363},{ 739, 5582},{ 788, 5782},{ 819, 6000}, + { 893, 6158},{ 940, 6418},{ 984, 6499},{ 1035, 6596} }, /*Cb qi=18 INTER*/ { - { 126, 5},{ 95, 326},{ 66, 643},{ 55, 1015}, - { 60, 1427},{ 73, 1843},{ 87, 2256},{ 96, 2667}, - { 101, 3073},{ 104, 3470},{ 108, 3853},{ 111, 4226}, - { 114, 4584},{ 117, 4928},{ 119, 5274},{ 122, 5612}, - { 126, 5942},{ 130, 6271},{ 136, 6606},{ 141, 6931}, - { 148, 7247},{ 156, 7568},{ 164, 7891},{ 173, 8211} + { -2, 642},{ 12, 771},{ 20, 1054},{ 29, 1394}, + { 35, 1721},{ 45, 2080},{ 53, 2450},{ 63, 2835}, + { 73, 3225},{ 81, 3596},{ 87, 3952},{ 95, 4300}, + { 102, 4634},{ 109, 4959},{ 115, 5283},{ 120, 5608}, + { 130, 5931},{ 139, 6254},{ 152, 6571},{ 163, 6887}, + { 179, 7204},{ 191, 7508},{ 198, 7834},{ 224, 8066} } }, { /*Cr qi=18 INTRA*/ { - { 4, 6},{ 59, 376},{ 104, 765},{ 133, 1226}, - { 156, 1692},{ 184, 2136},{ 218, 2548},{ 260, 2893}, - { 308, 3204},{ 348, 3481},{ 397, 3751},{ 448, 4024}, - { 490, 4281},{ 541, 4523},{ 593, 4776},{ 634, 5022}, - { 685, 5236},{ 748, 5455},{ 812, 5638},{ 856, 5818}, - { 891, 6048},{ 928, 6230},{ 961, 6405},{ 1055, 6449} + { 49, 780},{ 86, 986},{ 120, 1261},{ 137, 1588}, + { 183, 1998},{ 228, 2339},{ 291, 2670},{ 334, 2938}, + { 376, 3239},{ 412, 3522},{ 459, 3783},{ 490, 4113}, + { 547, 4321},{ 593, 4571},{ 640, 4828},{ 675, 5137}, + { 730, 5254},{ 774, 5524},{ 821, 5754},{ 859, 5911}, + { 887, 6178},{ 982, 6266},{ 941, 6536},{ 996, 6630} }, /*Cr qi=18 INTER*/ { - { 81, 34},{ 68, 342},{ 57, 652},{ 59, 1027}, - { 67, 1439},{ 80, 1848},{ 91, 2257},{ 97, 2670}, - { 100, 3076},{ 103, 3473},{ 106, 3857},{ 108, 4231}, - { 109, 4599},{ 110, 4958},{ 113, 5307},{ 119, 5650}, - { 125, 5991},{ 130, 6325},{ 138, 6651},{ 147, 6971}, - { 153, 7278},{ 162, 7578},{ 172, 7874},{ 177, 8156} - } - } - }, - { - { - /*Y' qi=19 INTRA*/ - { - { 128, -55},{ 228, 1495},{ 448, 2775},{ 699, 3758}, - { 931, 4571},{ 1154, 5296},{ 1386, 5914},{ 1636, 6450}, - { 1894, 6930},{ 2177, 7342},{ 2479, 7698},{ 2792, 7976}, - { 3099, 8235},{ 3392, 8517},{ 3658, 8853},{ 3938, 9155}, - { 4242, 9371},{ 4527, 9605},{ 4810, 9781},{ 5089, 9853}, - { 5378, 9920},{ 5674,10009},{ 5972,10110},{ 6336,10196} - }, - /*Y' qi=19 INTER*/ - { - { 69, -147},{ 49, 1353},{ 111, 2883},{ 162, 4381}, - { 205, 5737},{ 237, 6996},{ 264, 8232},{ 307, 9421}, - { 376,10534},{ 472,11567},{ 596,12525},{ 761,13395}, - { 990,14130},{ 1298,14694},{ 1695,15053},{ 2172,15195}, - { 2696,15173},{ 3213,15075},{ 3696,14948},{ 4141,14829}, - { 4541,14721},{ 4910,14609},{ 5245,14506},{ 5536,14399} - } - }, - { - /*Cb qi=19 INTRA*/ - { - { 3, 3},{ 61, 367},{ 109, 743},{ 135, 1182}, - { 161, 1646},{ 191, 2101},{ 229, 2524},{ 273, 2898}, - { 318, 3221},{ 376, 3490},{ 436, 3731},{ 487, 3994}, - { 539, 4251},{ 584, 4485},{ 621, 4721},{ 664, 4967}, - { 709, 5225},{ 752, 5431},{ 801, 5595},{ 846, 5796}, - { 912, 6011},{ 959, 6193},{ 1015, 6321},{ 1121, 6504} - }, - /*Cb qi=19 INTER*/ - { - { 126, 4},{ 97, 329},{ 69, 649},{ 56, 1017}, - { 61, 1432},{ 74, 1846},{ 88, 2255},{ 98, 2663}, - { 103, 3065},{ 106, 3460},{ 110, 3844},{ 114, 4211}, - { 117, 4564},{ 120, 4911},{ 122, 5253},{ 125, 5588}, - { 129, 5916},{ 135, 6241},{ 142, 6567},{ 149, 6885}, - { 155, 7206},{ 163, 7527},{ 174, 7843},{ 188, 8145} - } - }, - { - /*Cr qi=19 INTRA*/ - { - { 5, 6},{ 61, 376},{ 106, 765},{ 135, 1225}, - { 160, 1689},{ 192, 2126},{ 229, 2531},{ 271, 2869}, - { 321, 3168},{ 370, 3433},{ 421, 3704},{ 476, 3965}, - { 520, 4212},{ 572, 4452},{ 629, 4691},{ 671, 4939}, - { 724, 5152},{ 792, 5347},{ 858, 5510},{ 895, 5696}, - { 939, 5905},{ 991, 6056},{ 1027, 6244},{ 1127, 6333} - }, - /*Cr qi=19 INTER*/ - { - { 80, 45},{ 66, 344},{ 55, 654},{ 56, 1030}, - { 66, 1440},{ 80, 1850},{ 91, 2259},{ 98, 2668}, - { 102, 3072},{ 104, 3466},{ 107, 3845},{ 109, 4215}, - { 110, 4578},{ 112, 4933},{ 116, 5283},{ 122, 5625}, - { 129, 5963},{ 136, 6287},{ 143, 6611},{ 151, 6927}, - { 160, 7229},{ 170, 7528},{ 181, 7818},{ 191, 8092} - } - } - }, - { - { - /*Y' qi=20 INTRA*/ - { - { 129, -50},{ 238, 1481},{ 469, 2728},{ 730, 3684}, - { 974, 4473},{ 1213, 5171},{ 1463, 5763},{ 1729, 6281}, - { 2002, 6744},{ 2299, 7146},{ 2613, 7492},{ 2940, 7746}, - { 3265, 7978},{ 3571, 8228},{ 3853, 8543},{ 4156, 8815}, - { 4476, 9001},{ 4775, 9218},{ 5070, 9373},{ 5352, 9446}, - { 5649, 9510},{ 5956, 9580},{ 6268, 9660},{ 6647, 9705} - }, - /*Y' qi=20 INTER*/ - { - { 64, -93},{ 52, 1340},{ 116, 2862},{ 170, 4344}, - { 216, 5678},{ 249, 6928},{ 281, 8155},{ 333, 9326}, - { 418,10410},{ 533,11411},{ 683,12329},{ 890,13127}, - { 1183,13750},{ 1579,14162},{ 2066,14357},{ 2611,14370}, - { 3159,14284},{ 3675,14167},{ 4142,14053},{ 4568,13953}, - { 4961,13852},{ 5320,13755},{ 5649,13675},{ 5933,13610} - } - }, - { - /*Cb qi=20 INTRA*/ - { - { 3, 3},{ 62, 367},{ 112, 743},{ 140, 1183}, - { 165, 1646},{ 196, 2099},{ 235, 2517},{ 284, 2883}, - { 334, 3198},{ 393, 3460},{ 457, 3690},{ 509, 3945}, - { 560, 4198},{ 605, 4435},{ 647, 4658},{ 699, 4888}, - { 742, 5155},{ 788, 5350},{ 835, 5517},{ 880, 5730}, - { 956, 5914},{ 1007, 6060},{ 1053, 6199},{ 1158, 6358} - }, - /*Cb qi=20 INTER*/ - { - { 128, -6},{ 96, 322},{ 66, 653},{ 54, 1025}, - { 63, 1431},{ 79, 1844},{ 91, 2256},{ 99, 2665}, - { 104, 3065},{ 107, 3455},{ 111, 3831},{ 115, 4189}, - { 120, 4539},{ 123, 4885},{ 126, 5219},{ 130, 5548}, - { 135, 5876},{ 141, 6199},{ 149, 6519},{ 156, 6837}, - { 166, 7153},{ 179, 7468},{ 189, 7784},{ 194, 8102} - } - }, - { - /*Cr qi=20 INTRA*/ - { - { 4, 6},{ 63, 376},{ 109, 765},{ 139, 1225}, - { 165, 1689},{ 199, 2124},{ 239, 2523},{ 285, 2852}, - { 340, 3140},{ 388, 3398},{ 438, 3662},{ 499, 3914}, - { 547, 4155},{ 596, 4392},{ 652, 4634},{ 699, 4877}, - { 759, 5074},{ 824, 5257},{ 883, 5428},{ 936, 5589}, - { 986, 5790},{ 1030, 5960},{ 1074, 6119},{ 1172, 6191} - }, - /*Cr qi=20 INTER*/ - { - { 92, 40},{ 70, 345},{ 55, 658},{ 57, 1034}, - { 69, 1441},{ 84, 1852},{ 94, 2261},{ 98, 2669}, - { 102, 3074},{ 105, 3465},{ 107, 3841},{ 110, 4206}, - { 112, 4562},{ 116, 4915},{ 121, 5260},{ 127, 5591}, - { 134, 5920},{ 142, 6246},{ 153, 6562},{ 163, 6870}, - { 173, 7170},{ 186, 7463},{ 198, 7746},{ 199, 8030} - } - } - }, - { - { - /*Y' qi=21 INTRA*/ - { - { 130, -51},{ 244, 1476},{ 483, 2705},{ 756, 3635}, - { 1013, 4396},{ 1266, 5070},{ 1530, 5647},{ 1806, 6153}, - { 2093, 6600},{ 2411, 6976},{ 2739, 7299},{ 3079, 7534}, - { 3422, 7744},{ 3738, 7987},{ 4032, 8274},{ 4348, 8533}, - { 4675, 8721},{ 4989, 8909},{ 5291, 9051},{ 5577, 9111}, - { 5879, 9163},{ 6190, 9228},{ 6506, 9286},{ 6899, 9295} - }, - /*Y' qi=21 INTER*/ - { - { 64, -56},{ 55, 1341},{ 119, 2859},{ 174, 4324}, - { 223, 5640},{ 258, 6880},{ 295, 8096},{ 359, 9246}, - { 460,10302},{ 595,11268},{ 778,12131},{ 1032,12857}, - { 1387,13385},{ 1850,13683},{ 2399,13774},{ 2976,13729}, - { 3527,13619},{ 4034,13504},{ 4492,13401},{ 4912,13291}, - { 5298,13209},{ 5648,13137},{ 5974,13046},{ 6308,12977} - } - }, - { - /*Cb qi=21 INTRA*/ - { - { 4, 3},{ 64, 367},{ 114, 743},{ 141, 1183}, - { 166, 1645},{ 201, 2092},{ 247, 2502},{ 299, 2856}, - { 352, 3158},{ 413, 3412},{ 480, 3642},{ 536, 3893}, - { 588, 4137},{ 637, 4367},{ 678, 4598},{ 725, 4834}, - { 774, 5083},{ 827, 5269},{ 883, 5420},{ 930, 5633}, - { 999, 5829},{ 1057, 5959},{ 1113, 6082},{ 1200, 6265} - }, - /*Cb qi=21 INTER*/ - { - { 109, -8},{ 84, 321},{ 62, 654},{ 54, 1028}, - { 64, 1434},{ 80, 1847},{ 92, 2259},{ 100, 2664}, - { 105, 3060},{ 109, 3445},{ 114, 3815},{ 118, 4172}, - { 122, 4519},{ 126, 4861},{ 128, 5194},{ 133, 5520}, - { 139, 5847},{ 146, 6169},{ 155, 6487},{ 166, 6801}, - { 177, 7114},{ 189, 7423},{ 201, 7729},{ 208, 8035} - } - }, - { - /*Cr qi=21 INTRA*/ - { - { 4, 6},{ 64, 377},{ 111, 766},{ 144, 1225}, - { 174, 1683},{ 206, 2114},{ 248, 2506},{ 302, 2824}, - { 357, 3099},{ 404, 3357},{ 455, 3622},{ 519, 3867}, - { 573, 4098},{ 625, 4331},{ 683, 4571},{ 733, 4802}, - { 793, 4994},{ 863, 5173},{ 926, 5337},{ 978, 5492}, - { 1030, 5685},{ 1079, 5856},{ 1126, 6027},{ 1217, 6159} - }, - /*Cr qi=21 INTER*/ - { - { 82, 29},{ 67, 341},{ 55, 660},{ 58, 1038}, - { 71, 1443},{ 85, 1851},{ 95, 2258},{ 99, 2666}, - { 103, 3069},{ 107, 3456},{ 110, 3826},{ 112, 4188}, - { 114, 4544},{ 118, 4891},{ 124, 5231},{ 132, 5567}, - { 139, 5894},{ 148, 6210},{ 159, 6520},{ 171, 6822}, - { 185, 7111},{ 196, 7403},{ 209, 7691},{ 225, 7945} - } - } - }, - { - { - /*Y' qi=22 INTRA*/ - { - { 128, -45},{ 254, 1463},{ 507, 2662},{ 794, 3562}, - { 1070, 4292},{ 1340, 4941},{ 1622, 5492},{ 1920, 5968}, - { 2229, 6387},{ 2565, 6742},{ 2911, 7047},{ 3263, 7264}, - { 3615, 7464},{ 3944, 7689},{ 4258, 7950},{ 4591, 8183}, - { 4934, 8347},{ 5259, 8517},{ 5573, 8634},{ 5870, 8683}, - { 6186, 8723},{ 6508, 8762},{ 6831, 8801},{ 7232, 8830} - }, - /*Y' qi=22 INTER*/ - { - { 77, -48},{ 57, 1343},{ 122, 2853},{ 180, 4299}, - { 231, 5597},{ 269, 6826},{ 314, 8025},{ 393, 9150}, - { 512,10179},{ 673,11103},{ 894,11908},{ 1207,12542}, - { 1635,12956},{ 2166,13148},{ 2755,13167},{ 3345,13088}, - { 3895,12966},{ 4386,12848},{ 4832,12746},{ 5252,12647}, - { 5634,12563},{ 5978,12497},{ 6299,12412},{ 6633,12338} - } - }, - { - /*Cb qi=22 INTRA*/ - { - { 4, 3},{ 66, 367},{ 122, 744},{ 153, 1182}, - { 177, 1640},{ 213, 2080},{ 263, 2475},{ 323, 2811}, - { 382, 3103},{ 451, 3346},{ 522, 3568},{ 581, 3814}, - { 633, 4054},{ 674, 4288},{ 719, 4523},{ 768, 4756}, - { 823, 4979},{ 883, 5162},{ 937, 5325},{ 996, 5510}, - { 1070, 5687},{ 1129, 5807},{ 1193, 5929},{ 1311, 6099} - }, - /*Cb qi=22 INTER*/ - { - { 107, -5},{ 83, 322},{ 61, 653},{ 55, 1030}, - { 66, 1436},{ 81, 1845},{ 94, 2253},{ 102, 2656}, - { 107, 3050},{ 111, 3435},{ 115, 3804},{ 119, 4158}, - { 124, 4501},{ 128, 4835},{ 132, 5164},{ 138, 5490}, - { 146, 5812},{ 154, 6128},{ 163, 6442},{ 174, 6754}, - { 188, 7060},{ 205, 7361},{ 219, 7662},{ 233, 7953} - } - }, - { - /*Cr qi=22 INTRA*/ - { - { 4, 6},{ 67, 378},{ 118, 767},{ 151, 1222}, - { 182, 1675},{ 221, 2097},{ 269, 2476},{ 329, 2774}, - { 389, 3039},{ 444, 3292},{ 500, 3545},{ 560, 3788}, - { 615, 4020},{ 671, 4251},{ 734, 4484},{ 781, 4712}, - { 850, 4887},{ 925, 5060},{ 981, 5229},{ 1031, 5369}, - { 1092, 5549},{ 1148, 5715},{ 1200, 5861},{ 1291, 5943} - }, - /*Cr qi=22 INTER*/ - { - { 88, 34},{ 69, 340},{ 57, 657},{ 60, 1039}, - { 73, 1445},{ 87, 1851},{ 96, 2257},{ 100, 2662}, - { 103, 3058},{ 107, 3442},{ 111, 3812},{ 115, 4172}, - { 118, 4524},{ 123, 4864},{ 129, 5199},{ 136, 5531}, - { 145, 5855},{ 156, 6168},{ 170, 6468},{ 184, 6765}, - { 193, 7066},{ 207, 7353},{ 222, 7628},{ 230, 7900} - } - } - }, - { - { - /*Y' qi=23 INTRA*/ - { - { 126, -40},{ 257, 1458},{ 521, 2636},{ 825, 3501}, - { 1111, 4207},{ 1391, 4842},{ 1684, 5385},{ 1992, 5858}, - { 2311, 6277},{ 2653, 6626},{ 3005, 6929},{ 3366, 7134}, - { 3729, 7311},{ 4071, 7526},{ 4396, 7770},{ 4734, 7986}, - { 5086, 8131},{ 5421, 8286},{ 5735, 8404},{ 6033, 8456}, - { 6357, 8486},{ 6682, 8525},{ 7003, 8573},{ 7387, 8604} - }, - /*Y' qi=23 INTER*/ - { - { 64, -57},{ 60, 1345},{ 124, 2853},{ 185, 4284}, - { 239, 5565},{ 282, 6783},{ 336, 7967},{ 429, 9069}, - { 568,10063},{ 758,10943},{ 1028,11679},{ 1407,12216}, - { 1909,12520},{ 2502,12616},{ 3126,12573},{ 3722,12461}, - { 4258,12344},{ 4742,12236},{ 5185,12136},{ 5590,12052}, - { 5970,11980},{ 6315,11901},{ 6631,11826},{ 6954,11769} - } - }, - { - /*Cb qi=23 INTRA*/ - { - { 3, 3},{ 70, 367},{ 124, 744},{ 151, 1182}, - { 181, 1637},{ 222, 2071},{ 276, 2460},{ 343, 2785}, - { 403, 3072},{ 468, 3317},{ 542, 3534},{ 605, 3773}, - { 659, 4009},{ 703, 4243},{ 747, 4479},{ 795, 4707}, - { 852, 4923},{ 908, 5105},{ 972, 5254},{ 1043, 5423}, - { 1118, 5594},{ 1172, 5731},{ 1240, 5853},{ 1365, 6005} - }, - /*Cb qi=23 INTER*/ - { - { 109, -10},{ 87, 325},{ 63, 650},{ 57, 1031}, - { 67, 1439},{ 83, 1847},{ 96, 2253},{ 103, 2652}, - { 109, 3041},{ 114, 3421},{ 117, 3789},{ 122, 4141}, - { 128, 4480},{ 134, 4811},{ 139, 5138},{ 144, 5463}, - { 152, 5781},{ 161, 6096},{ 174, 6404},{ 185, 6714}, - { 198, 7023},{ 216, 7320},{ 233, 7621},{ 245, 7935} - } - }, - { - /*Cr qi=23 INTRA*/ - { - { 5, 6},{ 70, 379},{ 122, 768},{ 155, 1222}, - { 187, 1671},{ 231, 2088},{ 283, 2459},{ 346, 2750}, - { 411, 3009},{ 465, 3261},{ 523, 3509},{ 585, 3746}, - { 639, 3980},{ 695, 4219},{ 754, 4449},{ 803, 4671}, - { 873, 4840},{ 953, 5001},{ 1015, 5156},{ 1071, 5286}, - { 1137, 5464},{ 1191, 5629},{ 1249, 5782},{ 1359, 5885} - }, - /*Cr qi=23 INTER*/ - { - { 84, 29},{ 69, 343},{ 58, 660},{ 62, 1041}, - { 75, 1448},{ 88, 1853},{ 97, 2258},{ 102, 2659}, - { 105, 3050},{ 108, 3430},{ 113, 3799},{ 116, 4155}, - { 121, 4505},{ 126, 4845},{ 132, 5176},{ 142, 5504}, - { 153, 5826},{ 165, 6133},{ 180, 6432},{ 197, 6722}, - { 212, 7005},{ 226, 7287},{ 244, 7555},{ 258, 7828} - } - } - }, - { - { - /*Y' qi=24 INTRA*/ - { - { 125, -34},{ 268, 1444},{ 547, 2590},{ 866, 3422}, - { 1172, 4098},{ 1476, 4702},{ 1790, 5222},{ 2117, 5678}, - { 2453, 6080},{ 2811, 6418},{ 3178, 6700},{ 3552, 6895}, - { 3928, 7055},{ 4286, 7243},{ 4627, 7477},{ 4981, 7674}, - { 5344, 7802},{ 5683, 7944},{ 6009, 8043},{ 6313, 8082}, - { 6633, 8111},{ 6959, 8151},{ 7280, 8197},{ 7660, 8221} - }, - /*Y' qi=24 INTER*/ - { - { 62, -63},{ 68, 1345},{ 134, 2840},{ 199, 4245}, - { 256, 5508},{ 304, 6715},{ 371, 7880},{ 484, 8950}, - { 652, 9899},{ 892,10709},{ 1238,11334},{ 1722,11722}, - { 2326,11875},{ 2983,11864},{ 3616,11783},{ 4189,11678}, - { 4707,11570},{ 5178,11476},{ 5617,11395},{ 6017,11319}, - { 6380,11252},{ 6720,11185},{ 7044,11126},{ 7377,11118} - } - }, - { - /*Cb qi=24 INTRA*/ - { - { 4, 3},{ 75, 367},{ 132, 745},{ 159, 1182}, - { 187, 1634},{ 230, 2061},{ 289, 2439},{ 361, 2753}, - { 425, 3034},{ 492, 3278},{ 566, 3490},{ 630, 3720}, - { 686, 3956},{ 732, 4190},{ 777, 4420},{ 829, 4637}, - { 894, 4840},{ 958, 5012},{ 1023, 5155},{ 1090, 5326}, - { 1165, 5502},{ 1226, 5622},{ 1299, 5717},{ 1408, 5887} - }, - /*Cb qi=24 INTER*/ - { - { 110, 35},{ 92, 337},{ 70, 651},{ 63, 1033}, - { 74, 1440},{ 91, 1846},{ 102, 2248},{ 109, 2644}, - { 114, 3031},{ 120, 3404},{ 127, 3762},{ 133, 4109}, - { 138, 4445},{ 144, 4772},{ 151, 5094},{ 159, 5411}, - { 168, 5728},{ 180, 6037},{ 195, 6338},{ 210, 6640}, - { 227, 6944},{ 249, 7236},{ 272, 7528},{ 299, 7809} - } - }, - { - /*Cr qi=24 INTRA*/ - { - { 5, 6},{ 72, 380},{ 124, 770},{ 158, 1222}, - { 195, 1668},{ 240, 2079},{ 297, 2438},{ 367, 2715}, - { 433, 2966},{ 488, 3218},{ 549, 3467},{ 609, 3701}, - { 664, 3935},{ 728, 4165},{ 792, 4379},{ 845, 4586}, - { 917, 4744},{ 995, 4898},{ 1063, 5049},{ 1120, 5187}, - { 1190, 5359},{ 1249, 5522},{ 1304, 5672},{ 1397, 5806} - }, - /*Cr qi=24 INTER*/ - { - { 91, 56},{ 73, 353},{ 61, 664},{ 66, 1045}, - { 80, 1449},{ 95, 1851},{ 103, 2250},{ 107, 2648}, - { 111, 3038},{ 116, 3413},{ 120, 3774},{ 124, 4128}, - { 130, 4471},{ 138, 4802},{ 145, 5130},{ 156, 5453}, - { 171, 5764},{ 187, 6061},{ 204, 6355},{ 220, 6643}, - { 238, 6923},{ 254, 7204},{ 275, 7475},{ 289, 7752} - } - } - }, - { - { - /*Y' qi=25 INTRA*/ - { - { 125, -28},{ 285, 1426},{ 582, 2540},{ 917, 3351}, - { 1244, 3997},{ 1569, 4570},{ 1903, 5071},{ 2258, 5498}, - { 2626, 5866},{ 3002, 6182},{ 3382, 6448},{ 3770, 6623}, - { 4162, 6760},{ 4528, 6934},{ 4882, 7144},{ 5249, 7328}, - { 5610, 7453},{ 5958, 7578},{ 6291, 7672},{ 6597, 7708}, - { 6928, 7715},{ 7258, 7737},{ 7575, 7781},{ 7950, 7829} - }, - /*Y' qi=25 INTER*/ - { - { 64, -16},{ 72, 1348},{ 139, 2832},{ 206, 4218}, - { 268, 5465},{ 322, 6659},{ 403, 7803},{ 540, 8838}, - { 747, 9734},{ 1044,10465},{ 1473,10981},{ 2048,11249}, - { 2717,11311},{ 3397,11257},{ 4025,11161},{ 4589,11052}, - { 5099,10947},{ 5560,10859},{ 5989,10786},{ 6389,10717}, - { 6753,10652},{ 7078,10592},{ 7389,10535},{ 7697,10460} - } - }, - { - /*Cb qi=25 INTRA*/ - { - { 3, 3},{ 78, 368},{ 133, 745},{ 159, 1180}, - { 193, 1627},{ 242, 2046},{ 304, 2411},{ 381, 2714}, - { 456, 2983},{ 527, 3224},{ 598, 3437},{ 667, 3655}, - { 726, 3888},{ 776, 4117},{ 826, 4333},{ 883, 4543}, - { 954, 4727},{ 1019, 4878},{ 1095, 5014},{ 1171, 5187}, - { 1255, 5342},{ 1319, 5458},{ 1396, 5546},{ 1536, 5678} - }, - /*Cb qi=25 INTER*/ - { - { 117, 32},{ 89, 342},{ 67, 660},{ 64, 1037}, - { 77, 1441},{ 93, 1845},{ 105, 2243},{ 113, 2633}, - { 120, 3016},{ 125, 3387},{ 131, 3739},{ 137, 4080}, - { 144, 4416},{ 152, 4741},{ 160, 5057},{ 169, 5369}, - { 180, 5680},{ 193, 5990},{ 209, 6294},{ 227, 6594}, - { 249, 6888},{ 269, 7180},{ 294, 7467},{ 317, 7768} - } - }, - { - /*Cr qi=25 INTRA*/ - { - { 6, 6},{ 74, 380},{ 129, 770},{ 165, 1220}, - { 201, 1658},{ 253, 2061},{ 315, 2410},{ 388, 2676}, - { 462, 2920},{ 523, 3166},{ 584, 3404},{ 647, 3637}, - { 701, 3870},{ 769, 4086},{ 838, 4296},{ 898, 4491}, - { 980, 4627},{ 1065, 4759},{ 1126, 4920},{ 1187, 5058}, - { 1283, 5180},{ 1347, 5332},{ 1404, 5475},{ 1527, 5534} - }, - /*Cr qi=25 INTER*/ - { - { 92, 41},{ 75, 347},{ 64, 664},{ 70, 1045}, - { 85, 1448},{ 98, 1849},{ 105, 2245},{ 110, 2637}, - { 115, 3023},{ 120, 3395},{ 126, 3753},{ 131, 4102}, - { 136, 4439},{ 145, 4768},{ 156, 5094},{ 168, 5410}, - { 184, 5717},{ 203, 6010},{ 221, 6300},{ 239, 6577}, - { 262, 6847},{ 282, 7123},{ 303, 7390},{ 322, 7665} - } - } - }, - { - { - /*Y' qi=26 INTRA*/ - { - { 130, -24},{ 292, 1423},{ 594, 2525},{ 943, 3307}, - { 1289, 3921},{ 1633, 4467},{ 1991, 4943},{ 2368, 5348}, - { 2753, 5696},{ 3148, 5991},{ 3545, 6247},{ 3942, 6415}, - { 4342, 6535},{ 4726, 6690},{ 5093, 6883},{ 5466, 7047}, - { 5840, 7159},{ 6202, 7274},{ 6545, 7351},{ 6855, 7375}, - { 7186, 7384},{ 7517, 7416},{ 7840, 7447},{ 8238, 7450} - }, - /*Y' qi=26 INTER*/ - { - { 52, 16},{ 75, 1336},{ 143, 2815},{ 213, 4191}, - { 278, 5427},{ 339, 6611},{ 436, 7734},{ 600, 8732}, - { 843, 9579},{ 1195,10243},{ 1702,10660},{ 2355,10825}, - { 3070,10820},{ 3755,10743},{ 4372,10643},{ 4925,10538}, - { 5426,10440},{ 5882,10354},{ 6296,10290},{ 6686,10224}, - { 7049,10163},{ 7380,10113},{ 7672,10062},{ 7937,10021} - } - }, - { - /*Cb qi=26 INTRA*/ - { - { 4, 3},{ 79, 368},{ 138, 745},{ 167, 1180}, - { 200, 1623},{ 252, 2034},{ 322, 2389},{ 403, 2682}, - { 480, 2941},{ 558, 3176},{ 631, 3393},{ 700, 3608}, - { 766, 3825},{ 819, 4046},{ 868, 4265},{ 926, 4472}, - { 1002, 4645},{ 1070, 4800},{ 1151, 4924},{ 1242, 5063}, - { 1325, 5221},{ 1393, 5338},{ 1464, 5431},{ 1595, 5559} - }, - /*Cb qi=26 INTER*/ - { - { 98, 33},{ 83, 343},{ 65, 662},{ 65, 1037}, - { 80, 1437},{ 96, 1839},{ 107, 2238},{ 115, 2628}, - { 122, 3007},{ 128, 3373},{ 134, 3722},{ 142, 4060}, - { 149, 4390},{ 158, 4713},{ 167, 5029},{ 178, 5341}, - { 191, 5647},{ 208, 5948},{ 227, 6244},{ 247, 6539}, - { 269, 6833},{ 295, 7114},{ 328, 7388},{ 369, 7658} - } - }, - { - /*Cr qi=26 INTRA*/ - { - { 5, 6},{ 75, 380},{ 133, 769},{ 172, 1217}, - { 212, 1652},{ 266, 2048},{ 333, 2384},{ 412, 2643}, - { 490, 2880},{ 552, 3124},{ 616, 3365},{ 681, 3594}, - { 739, 3816},{ 810, 4024},{ 880, 4224},{ 945, 4405}, - { 1029, 4538},{ 1114, 4674},{ 1183, 4822},{ 1254, 4946}, - { 1346, 5063},{ 1417, 5201},{ 1478, 5345},{ 1597, 5411} - }, - /*Cr qi=26 INTER*/ - { - { 97, 29},{ 75, 342},{ 62, 667},{ 70, 1047}, - { 87, 1447},{ 100, 1846},{ 107, 2242},{ 113, 2633}, - { 118, 3016},{ 123, 3382},{ 128, 3737},{ 135, 4082}, - { 142, 4417},{ 151, 4746},{ 162, 5066},{ 176, 5377}, - { 194, 5679},{ 217, 5963},{ 239, 6244},{ 260, 6522}, - { 284, 6789},{ 309, 7052},{ 335, 7313},{ 355, 7582} + { 0, 741},{ 9, 743},{ 16, 1034},{ 26, 1385}, + { 39, 1741},{ 48, 2090},{ 56, 2459},{ 64, 2850}, + { 72, 3242},{ 81, 3622},{ 89, 3980},{ 98, 4323}, + { 104, 4667},{ 110, 5005},{ 118, 5337},{ 126, 5675}, + { 137, 5998},{ 146, 6311},{ 156, 6621},{ 170, 6914}, + { 181, 7205},{ 196, 7490},{ 203, 7779},{ 232, 8012} } } }, @@ -1732,557 +217,61 @@ oc_mode_rd OC_MODE_RD[64][3][2][OC_SAD_BINS]={ { /*Y' qi=27 INTRA*/ { - { 118, -10},{ 308, 1404},{ 630, 2473},{ 997, 3227}, - { 1360, 3819},{ 1719, 4354},{ 2086, 4829},{ 2470, 5233}, - { 2863, 5576},{ 3267, 5870},{ 3677, 6117},{ 4085, 6268}, - { 4499, 6376},{ 4888, 6521},{ 5257, 6705},{ 5638, 6865}, - { 6020, 6962},{ 6394, 7056},{ 6744, 7130},{ 7051, 7158}, - { 7386, 7164},{ 7717, 7185},{ 8042, 7209},{ 8444, 7206} + { 121, 378},{ 379, 1464},{ 810, 2335},{ 1447, 2725}, + { 1851, 3194},{ 2311, 3655},{ 2747, 4081},{ 3211, 4393}, + { 3640, 4672},{ 4056, 4933},{ 4427, 5150},{ 4842, 5259}, + { 5220, 5381},{ 5584, 5443},{ 5925, 5648},{ 6233, 5783}, + { 6547, 5944},{ 6905, 6056},{ 7203, 6181},{ 7526, 6207}, + { 7800, 6330},{ 8175, 6312},{ 8415, 6437},{ 8705, 6459} }, /*Y' qi=27 INTER*/ { - { 54, 19},{ 77, 1333},{ 147, 2806},{ 221, 4166}, - { 290, 5390},{ 360, 6564},{ 474, 7665},{ 664, 8630}, - { 949, 9423},{ 1370,10002},{ 1958,10323},{ 2670,10414}, - { 3406,10375},{ 4086,10285},{ 4691,10182},{ 5233,10085}, - { 5724, 9994},{ 6169, 9918},{ 6582, 9863},{ 6962, 9813}, - { 7316, 9759},{ 7645, 9707},{ 7948, 9660},{ 8262, 9623} + { 48, 199},{ 90, 1458},{ 167, 2824},{ 291, 4050}, + { 434, 5144},{ 638, 6133},{ 901, 7011},{ 1249, 7743}, + { 1726, 8280},{ 2317, 8616},{ 2957, 8789},{ 3561, 8896}, + { 4126, 8936},{ 4646, 8933},{ 5115, 8931},{ 5579, 8890}, + { 6008, 8804},{ 6411, 8744},{ 6774, 8646},{ 7153, 8549}, + { 7475, 8462},{ 7790, 8372},{ 8069, 8280},{ 8299, 8278} } }, { /*Cb qi=27 INTRA*/ { - { 4, 3},{ 79, 368},{ 137, 745},{ 166, 1180}, - { 200, 1622},{ 253, 2030},{ 324, 2381},{ 407, 2671}, - { 487, 2925},{ 567, 3156},{ 640, 3372},{ 712, 3580}, - { 782, 3792},{ 833, 4015},{ 887, 4227},{ 954, 4422}, - { 1031, 4592},{ 1103, 4738},{ 1187, 4856},{ 1280, 4990}, - { 1371, 5135},{ 1442, 5244},{ 1520, 5321},{ 1684, 5398} + { 75, 612},{ 117, 751},{ 160, 1068},{ 195, 1406}, + { 240, 1741},{ 305, 2066},{ 364, 2359},{ 454, 2639}, + { 538, 2899},{ 609, 3149},{ 664, 3384},{ 730, 3625}, + { 785, 3860},{ 836, 4094},{ 872, 4312},{ 948, 4507}, + { 1023, 4677},{ 1081, 4843},{ 1165, 4985},{ 1238, 5092}, + { 1316, 5235},{ 1418, 5345},{ 1430, 5478},{ 1505, 5538} }, /*Cb qi=27 INTER*/ { - { 113, 20},{ 90, 338},{ 66, 661},{ 67, 1034}, - { 82, 1438},{ 97, 1842},{ 108, 2238},{ 115, 2624}, - { 123, 3000},{ 130, 3361},{ 138, 3708},{ 146, 4040}, - { 155, 4367},{ 164, 4688},{ 174, 4999},{ 186, 5306}, - { 203, 5609},{ 222, 5908},{ 243, 6202},{ 268, 6494}, - { 295, 6781},{ 326, 7058},{ 367, 7319},{ 420, 7551} + { 16, 637},{ 13, 634},{ 32, 869},{ 46, 1230}, + { 55, 1583},{ 67, 1950},{ 79, 2320},{ 93, 2690}, + { 107, 3052},{ 120, 3399},{ 133, 3733},{ 146, 4054}, + { 162, 4367},{ 175, 4679},{ 191, 4984},{ 211, 5285}, + { 232, 5581},{ 252, 5875},{ 276, 6155},{ 305, 6433}, + { 333, 6706},{ 364, 6967},{ 398, 7244},{ 474, 7394} } }, { /*Cr qi=27 INTRA*/ { - { 5, 6},{ 75, 380},{ 133, 770},{ 173, 1217}, - { 214, 1650},{ 268, 2040},{ 337, 2375},{ 418, 2631}, - { 496, 2862},{ 558, 3104},{ 625, 3346},{ 692, 3571}, - { 753, 3786},{ 825, 3989},{ 896, 4182},{ 969, 4352}, - { 1059, 4479},{ 1144, 4614},{ 1212, 4757},{ 1284, 4871}, - { 1380, 4982},{ 1457, 5125},{ 1528, 5267},{ 1651, 5346} + { 64, 632},{ 107, 763},{ 147, 1054},{ 176, 1411}, + { 255, 1770},{ 324, 2079},{ 411, 2359},{ 475, 2621}, + { 545, 2880},{ 590, 3158},{ 647, 3425},{ 709, 3648}, + { 766, 3878},{ 831, 4082},{ 911, 4260},{ 960, 4493}, + { 1042, 4558},{ 1115, 4760},{ 1200, 4852},{ 1280, 4950}, + { 1327, 5186},{ 1445, 5157},{ 1443, 5431},{ 1518, 5493} }, /*Cr qi=27 INTER*/ { - { 92, 24},{ 74, 341},{ 61, 669},{ 71, 1049}, - { 88, 1448},{ 100, 1849},{ 107, 2243},{ 113, 2631}, - { 119, 3010},{ 125, 3373},{ 131, 3723},{ 137, 4064}, - { 146, 4396},{ 159, 4720},{ 172, 5033},{ 189, 5340}, - { 210, 5636},{ 233, 5920},{ 256, 6197},{ 282, 6465}, - { 310, 6730},{ 332, 7000},{ 359, 7259},{ 385, 7515} - } - } - }, - { - { - /*Y' qi=28 INTRA*/ - { - { 116, -8},{ 314, 1400},{ 640, 2458},{ 1013, 3197}, - { 1386, 3768},{ 1762, 4279},{ 2151, 4733},{ 2558, 5117}, - { 2970, 5442},{ 3393, 5714},{ 3820, 5935},{ 4243, 6069}, - { 4671, 6161},{ 5074, 6289},{ 5456, 6457},{ 5849, 6598}, - { 6244, 6689},{ 6632, 6777},{ 6984, 6833},{ 7294, 6855}, - { 7625, 6862},{ 7961, 6875},{ 8302, 6890},{ 8720, 6883} - }, - /*Y' qi=28 INTER*/ - { - { 54, 8},{ 81, 1333},{ 154, 2793},{ 231, 4138}, - { 304, 5352},{ 384, 6512},{ 519, 7585},{ 743, 8508}, - { 1082, 9236},{ 1587, 9717},{ 2267, 9928},{ 3034, 9944}, - { 3775, 9878},{ 4438, 9786},{ 5031, 9686},{ 5563, 9601}, - { 6042, 9523},{ 6481, 9456},{ 6890, 9405},{ 7266, 9356}, - { 7614, 9313},{ 7933, 9265},{ 8238, 9220},{ 8545, 9193} - } - }, - { - /*Cb qi=28 INTRA*/ - { - { 3, 3},{ 80, 368},{ 138, 746},{ 168, 1179}, - { 208, 1615},{ 268, 2014},{ 345, 2354},{ 432, 2637}, - { 515, 2884},{ 595, 3108},{ 669, 3323},{ 745, 3533}, - { 818, 3740},{ 876, 3953},{ 932, 4160},{ 1003, 4349}, - { 1088, 4501},{ 1154, 4648},{ 1241, 4768},{ 1349, 4889}, - { 1441, 5023},{ 1524, 5113},{ 1611, 5187},{ 1783, 5283} - }, - /*Cb qi=28 INTER*/ - { - { 117, 29},{ 91, 341},{ 65, 663},{ 68, 1038}, - { 85, 1440},{ 100, 1841},{ 110, 2234},{ 119, 2616}, - { 127, 2985},{ 135, 3342},{ 142, 3685},{ 151, 4015}, - { 162, 4337},{ 174, 4652},{ 186, 4960},{ 201, 5264}, - { 218, 5567},{ 239, 5863},{ 266, 6149},{ 295, 6434}, - { 328, 6715},{ 371, 6976},{ 409, 7239},{ 460, 7477} - } - }, - { - /*Cr qi=28 INTRA*/ - { - { 6, 7},{ 79, 381},{ 138, 771},{ 178, 1215}, - { 222, 1644},{ 285, 2026},{ 359, 2347},{ 441, 2597}, - { 521, 2827},{ 588, 3066},{ 655, 3303},{ 725, 3523}, - { 791, 3728},{ 870, 3920},{ 950, 4103},{ 1030, 4265}, - { 1121, 4388},{ 1198, 4520},{ 1266, 4659},{ 1356, 4759}, - { 1461, 4865},{ 1540, 4993},{ 1619, 5115},{ 1786, 5160} - }, - /*Cr qi=28 INTER*/ - { - { 96, 18},{ 78, 340},{ 66, 672},{ 74, 1051}, - { 90, 1450},{ 103, 1845},{ 110, 2235},{ 116, 2619}, - { 122, 2995},{ 129, 3356},{ 137, 3702},{ 146, 4038}, - { 156, 4365},{ 168, 4684},{ 182, 4995},{ 203, 5297}, - { 227, 5588},{ 253, 5866},{ 282, 6131},{ 311, 6394}, - { 339, 6664},{ 366, 6918},{ 400, 7171},{ 424, 7450} - } - } - }, - { - { - /*Y' qi=29 INTRA*/ - { - { 112, 7},{ 334, 1382},{ 681, 2410},{ 1081, 3112}, - { 1484, 3650},{ 1894, 4128},{ 2316, 4547},{ 2749, 4905}, - { 3188, 5208},{ 3634, 5458},{ 4079, 5666},{ 4517, 5791}, - { 4952, 5870},{ 5359, 5983},{ 5754, 6137},{ 6165, 6268}, - { 6568, 6351},{ 6958, 6423},{ 7320, 6471},{ 7638, 6490}, - { 7979, 6490},{ 8313, 6499},{ 8651, 6517},{ 9085, 6499} - }, - /*Y' qi=29 INTER*/ - { - { 55, 15},{ 85, 1336},{ 160, 2780},{ 242, 4104}, - { 323, 5302},{ 418, 6443},{ 586, 7480},{ 859, 8342}, - { 1278, 8982},{ 1888, 9347},{ 2658, 9457},{ 3457, 9425}, - { 4192, 9343},{ 4842, 9247},{ 5417, 9162},{ 5935, 9086}, - { 6404, 9011},{ 6841, 8952},{ 7241, 8907},{ 7609, 8867}, - { 7953, 8832},{ 8267, 8792},{ 8562, 8740},{ 8836, 8701} - } - }, - { - /*Cb qi=29 INTRA*/ - { - { 5, 3},{ 84, 368},{ 144, 746},{ 176, 1175}, - { 219, 1604},{ 285, 1991},{ 372, 2318},{ 462, 2591}, - { 546, 2833},{ 628, 3058},{ 704, 3274},{ 788, 3473}, - { 870, 3664},{ 935, 3865},{ 995, 4059},{ 1072, 4239}, - { 1167, 4388},{ 1248, 4518},{ 1334, 4634},{ 1429, 4765}, - { 1536, 4884},{ 1628, 4964},{ 1716, 5038},{ 1885, 5128} - }, - /*Cb qi=29 INTER*/ - { - { 126, 25},{ 95, 340},{ 69, 662},{ 71, 1039}, - { 88, 1440},{ 102, 1839},{ 113, 2227},{ 122, 2604}, - { 132, 2969},{ 141, 3320},{ 151, 3659},{ 161, 3985}, - { 172, 4301},{ 186, 4612},{ 200, 4917},{ 219, 5213}, - { 241, 5509},{ 265, 5800},{ 296, 6081},{ 329, 6360}, - { 369, 6633},{ 414, 6899},{ 465, 7148},{ 520, 7387} - } - }, - { - /*Cr qi=29 INTRA*/ - { - { 6, 7},{ 82, 382},{ 142, 772},{ 185, 1211}, - { 233, 1632},{ 303, 2000},{ 388, 2306},{ 475, 2550}, - { 556, 2779},{ 627, 3007},{ 707, 3237},{ 778, 3459}, - { 843, 3654},{ 927, 3834},{ 1012, 4012},{ 1101, 4152}, - { 1197, 4262},{ 1275, 4399},{ 1359, 4511},{ 1455, 4596}, - { 1562, 4708},{ 1644, 4833},{ 1719, 4954},{ 1888, 4988} - }, - /*Cr qi=29 INTER*/ - { - { 101, 28},{ 81, 343},{ 67, 673},{ 75, 1053}, - { 93, 1450},{ 106, 1844},{ 113, 2230},{ 119, 2610}, - { 127, 2980},{ 135, 3334},{ 143, 3676},{ 153, 4007}, - { 165, 4330},{ 180, 4645},{ 201, 4951},{ 224, 5243}, - { 253, 5522},{ 284, 5794},{ 314, 6060},{ 345, 6322}, - { 381, 6578},{ 419, 6828},{ 455, 7073},{ 495, 7316} - } - } - }, - { - { - /*Y' qi=30 INTRA*/ - { - { 112, 8},{ 335, 1380},{ 682, 2401},{ 1083, 3093}, - { 1489, 3619},{ 1902, 4092},{ 2332, 4511},{ 2777, 4865}, - { 3231, 5156},{ 3693, 5394},{ 4153, 5585},{ 4605, 5689}, - { 5049, 5764},{ 5468, 5871},{ 5875, 6004},{ 6295, 6120}, - { 6706, 6201},{ 7099, 6273},{ 7461, 6311},{ 7785, 6320}, - { 8128, 6322},{ 8469, 6331},{ 8806, 6342},{ 9220, 6338} - }, - /*Y' qi=30 INTER*/ - { - { 58, 8},{ 90, 1340},{ 169, 2771},{ 257, 4079}, - { 345, 5266},{ 459, 6387},{ 660, 7383},{ 990, 8180}, - { 1496, 8726},{ 2203, 8992},{ 3029, 9038},{ 3833, 8984}, - { 4549, 8900},{ 5183, 8813},{ 5745, 8735},{ 6250, 8674}, - { 6715, 8619},{ 7138, 8565},{ 7529, 8528},{ 7899, 8495}, - { 8234, 8465},{ 8550, 8429},{ 8856, 8395},{ 9160, 8374} - } - }, - { - /*Cb qi=30 INTRA*/ - { - { 7, 3},{ 88, 369},{ 149, 747},{ 185, 1175}, - { 232, 1599},{ 304, 1976},{ 392, 2293},{ 486, 2557}, - { 573, 2797},{ 656, 3027},{ 735, 3243},{ 819, 3442}, - { 903, 3629},{ 966, 3828},{ 1025, 4027},{ 1105, 4204}, - { 1201, 4343},{ 1282, 4469},{ 1379, 4575},{ 1486, 4689}, - { 1588, 4813},{ 1678, 4900},{ 1767, 4969},{ 1911, 5080} - }, - /*Cb qi=30 INTER*/ - { - { 120, 23},{ 96, 336},{ 72, 661},{ 75, 1043}, - { 91, 1441},{ 105, 1837},{ 117, 2221},{ 127, 2592}, - { 137, 2953},{ 148, 3301},{ 159, 3635},{ 170, 3959}, - { 184, 4271},{ 199, 4578},{ 216, 4879},{ 238, 5175}, - { 262, 5466},{ 294, 5750},{ 332, 6027},{ 373, 6298}, - { 421, 6559},{ 473, 6805},{ 526, 7053},{ 587, 7298} - } - }, - { - /*Cr qi=30 INTRA*/ - { - { 10, 7},{ 89, 384},{ 147, 773},{ 192, 1211}, - { 245, 1627},{ 322, 1984},{ 412, 2280},{ 501, 2520}, - { 583, 2750},{ 654, 2982},{ 736, 3207},{ 810, 3419}, - { 873, 3614},{ 957, 3794},{ 1048, 3965},{ 1139, 4102}, - { 1237, 4208},{ 1327, 4328},{ 1408, 4448},{ 1496, 4545}, - { 1604, 4652},{ 1699, 4760},{ 1780, 4877},{ 1937, 4942} - }, - /*Cr qi=30 INTER*/ - { - { 115, 26},{ 89, 342},{ 70, 672},{ 79, 1055}, - { 96, 1451},{ 108, 1841},{ 116, 2222},{ 124, 2599}, - { 132, 2965},{ 141, 3316},{ 151, 3655},{ 163, 3984}, - { 178, 4301},{ 197, 4609},{ 219, 4909},{ 247, 5195}, - { 280, 5469},{ 317, 5734},{ 351, 5991},{ 383, 6248}, - { 423, 6500},{ 467, 6744},{ 502, 6995},{ 558, 7226} - } - } - }, - { - { - /*Y' qi=31 INTRA*/ - { - { 116, 20},{ 359, 1361},{ 732, 2350},{ 1162, 3010}, - { 1597, 3507},{ 2042, 3950},{ 2503, 4339},{ 2974, 4670}, - { 3446, 4951},{ 3922, 5179},{ 4394, 5357},{ 4858, 5454}, - { 5313, 5519},{ 5734, 5626},{ 6154, 5755},{ 6585, 5859}, - { 7004, 5928},{ 7408, 5998},{ 7775, 6039},{ 8102, 6048}, - { 8442, 6051},{ 8790, 6054},{ 9136, 6057},{ 9554, 6041} - }, - /*Y' qi=31 INTER*/ - { - { 53, 12},{ 90, 1340},{ 169, 2765},{ 259, 4062}, - { 353, 5236},{ 483, 6340},{ 713, 7305},{ 1086, 8059}, - { 1651, 8548},{ 2423, 8751},{ 3288, 8754},{ 4106, 8674}, - { 4827, 8572},{ 5451, 8482},{ 6007, 8407},{ 6514, 8344}, - { 6970, 8282},{ 7397, 8225},{ 7795, 8193},{ 8159, 8161}, - { 8498, 8120},{ 8814, 8093},{ 9127, 8066},{ 9432, 8040} - } - }, - { - /*Cb qi=31 INTRA*/ - { - { 7, 3},{ 88, 369},{ 149, 746},{ 185, 1173}, - { 234, 1595},{ 308, 1967},{ 399, 2278},{ 494, 2537}, - { 583, 2774},{ 669, 2997},{ 755, 3204},{ 847, 3390}, - { 936, 3569},{ 1008, 3759},{ 1078, 3942},{ 1162, 4104}, - { 1262, 4238},{ 1352, 4364},{ 1442, 4470},{ 1557, 4567}, - { 1676, 4674},{ 1759, 4781},{ 1850, 4853},{ 2043, 4897} - }, - /*Cb qi=31 INTER*/ - { - { 121, 23},{ 96, 335},{ 72, 660},{ 74, 1043}, - { 90, 1440},{ 105, 1834},{ 116, 2217},{ 127, 2586}, - { 138, 2945},{ 148, 3293},{ 159, 3626},{ 172, 3945}, - { 185, 4256},{ 202, 4559},{ 223, 4856},{ 245, 5150}, - { 272, 5440},{ 306, 5719},{ 346, 5989},{ 391, 6253}, - { 443, 6511},{ 510, 6743},{ 583, 6965},{ 651, 7182} - } - }, - { - /*Cr qi=31 INTRA*/ - { - { 10, 7},{ 88, 384},{ 147, 773},{ 192, 1209}, - { 247, 1622},{ 326, 1974},{ 417, 2262},{ 509, 2500}, - { 596, 2726},{ 670, 2949},{ 754, 3170},{ 836, 3370}, - { 912, 3548},{ 999, 3724},{ 1093, 3888},{ 1198, 4000}, - { 1304, 4095},{ 1384, 4230},{ 1470, 4347},{ 1577, 4422}, - { 1696, 4513},{ 1798, 4620},{ 1869, 4746},{ 1991, 4798} - }, - /*Cr qi=31 INTER*/ - { - { 113, 32},{ 88, 345},{ 69, 674},{ 79, 1055}, - { 96, 1451},{ 108, 1839},{ 115, 2218},{ 123, 2592}, - { 132, 2957},{ 141, 3308},{ 151, 3643},{ 163, 3968}, - { 179, 4285},{ 200, 4590},{ 225, 4886},{ 254, 5169}, - { 291, 5436},{ 330, 5696},{ 368, 5951},{ 409, 6200}, - { 452, 6448},{ 493, 6695},{ 536, 6940},{ 571, 7204} - } - } - }, - { - { - /*Y' qi=32 INTRA*/ - { - { 123, 26},{ 370, 1356},{ 756, 2321},{ 1211, 2944}, - { 1674, 3408},{ 2148, 3826},{ 2639, 4193},{ 3138, 4504}, - { 3634, 4765},{ 4133, 4973},{ 4625, 5137},{ 5101, 5225}, - { 5567, 5274},{ 6002, 5363},{ 6437, 5482},{ 6885, 5566}, - { 7312, 5625},{ 7723, 5686},{ 8101, 5721},{ 8429, 5732}, - { 8769, 5728},{ 9120, 5726},{ 9472, 5723},{ 9918, 5700} - }, - /*Y' qi=32 INTER*/ - { - { 54, -3},{ 95, 1343},{ 179, 2750},{ 276, 4027}, - { 382, 5185},{ 543, 6256},{ 830, 7161},{ 1301, 7815}, - { 2003, 8172},{ 2883, 8266},{ 3779, 8217},{ 4578, 8127}, - { 5274, 8035},{ 5886, 7952},{ 6430, 7887},{ 6929, 7835}, - { 7380, 7779},{ 7796, 7737},{ 8190, 7705},{ 8552, 7672}, - { 8896, 7640},{ 9210, 7612},{ 9510, 7589},{ 9746, 7552} - } - }, - { - /*Cb qi=32 INTRA*/ - { - { 6, 3},{ 89, 369},{ 153, 746},{ 193, 1167}, - { 247, 1577},{ 330, 1935},{ 429, 2236},{ 528, 2494}, - { 620, 2732},{ 712, 2948},{ 801, 3146},{ 898, 3325}, - { 999, 3489},{ 1078, 3664},{ 1155, 3832},{ 1251, 3985}, - { 1360, 4115},{ 1451, 4236},{ 1549, 4338},{ 1667, 4433}, - { 1797, 4522},{ 1891, 4613},{ 1989, 4687},{ 2162, 4776} - }, - /*Cb qi=32 INTER*/ - { - { 116, -1},{ 98, 321},{ 80, 656},{ 80, 1042}, - { 96, 1438},{ 110, 1827},{ 122, 2205},{ 133, 2570}, - { 144, 2925},{ 157, 3268},{ 170, 3597},{ 185, 3911}, - { 202, 4216},{ 221, 4516},{ 244, 4809},{ 273, 5096}, - { 308, 5376},{ 350, 5644},{ 401, 5907},{ 459, 6160}, - { 520, 6401},{ 592, 6630},{ 676, 6837},{ 758, 7050} - } - }, - { - /*Cr qi=32 INTRA*/ - { - { 12, 7},{ 91, 386},{ 152, 773},{ 201, 1202}, - { 261, 1603},{ 347, 1942},{ 447, 2223},{ 540, 2460}, - { 626, 2684},{ 711, 2901},{ 801, 3115},{ 887, 3312}, - { 969, 3480},{ 1068, 3633},{ 1176, 3779},{ 1283, 3885}, - { 1392, 3969},{ 1485, 4090},{ 1573, 4206},{ 1686, 4274}, - { 1813, 4354},{ 1911, 4459},{ 2004, 4563},{ 2162, 4590} - }, - /*Cr qi=32 INTER*/ - { - { 129, 5},{ 98, 334},{ 75, 673},{ 84, 1055}, - { 101, 1448},{ 113, 1832},{ 121, 2206},{ 129, 2577}, - { 140, 2937},{ 151, 3282},{ 163, 3614},{ 179, 3932}, - { 198, 4240},{ 221, 4542},{ 252, 4830},{ 290, 5102}, - { 329, 5364},{ 373, 5618},{ 420, 5864},{ 468, 6105}, - { 513, 6351},{ 564, 6587},{ 624, 6810},{ 697, 7017} - } - } - }, - { - { - /*Y' qi=33 INTRA*/ - { - { 115, 36},{ 388, 1338},{ 791, 2289},{ 1258, 2899}, - { 1732, 3352},{ 2220, 3760},{ 2730, 4117},{ 3244, 4415}, - { 3751, 4662},{ 4261, 4858},{ 4766, 5012},{ 5249, 5094}, - { 5719, 5141},{ 6159, 5225},{ 6597, 5333},{ 7044, 5416}, - { 7474, 5472},{ 7893, 5531},{ 8268, 5570},{ 8591, 5580}, - { 8931, 5578},{ 9283, 5579},{ 9634, 5582},{10067, 5560} - }, - /*Y' qi=33 INTER*/ - { - { 65, -14},{ 102, 1345},{ 190, 2736},{ 294, 3999}, - { 411, 5146},{ 597, 6192},{ 934, 7045},{ 1488, 7622}, - { 2281, 7895},{ 3213, 7937},{ 4108, 7871},{ 4883, 7784}, - { 5556, 7709},{ 6150, 7643},{ 6685, 7585},{ 7176, 7539}, - { 7620, 7502},{ 8034, 7466},{ 8427, 7435},{ 8793, 7409}, - { 9136, 7386},{ 9446, 7364},{ 9743, 7339},{10025, 7303} - } - }, - { - /*Cb qi=33 INTRA*/ - { - { 5, 3},{ 92, 369},{ 159, 746},{ 203, 1163}, - { 263, 1564},{ 353, 1911},{ 458, 2204},{ 557, 2460}, - { 650, 2697},{ 744, 2913},{ 836, 3110},{ 934, 3292}, - { 1036, 3454},{ 1125, 3616},{ 1204, 3781},{ 1298, 3932}, - { 1410, 4058},{ 1507, 4170},{ 1606, 4265},{ 1725, 4358}, - { 1853, 4445},{ 1955, 4535},{ 2067, 4597},{ 2258, 4663} - }, - /*Cb qi=33 INTER*/ - { - { 109, 37},{ 94, 343},{ 81, 662},{ 85, 1042}, - { 102, 1436},{ 116, 1823},{ 128, 2195},{ 141, 2554}, - { 154, 2906},{ 167, 3246},{ 183, 3570},{ 202, 3881}, - { 220, 4185},{ 241, 4482},{ 268, 4772},{ 302, 5053}, - { 341, 5328},{ 388, 5592},{ 446, 5846},{ 507, 6096}, - { 581, 6328},{ 670, 6534},{ 762, 6731},{ 842, 6922} - } - }, - { - /*Cr qi=33 INTRA*/ - { - { 11, 7},{ 93, 387},{ 158, 774},{ 211, 1197}, - { 278, 1589},{ 372, 1917},{ 475, 2191},{ 569, 2429}, - { 658, 2655},{ 744, 2868},{ 835, 3083},{ 926, 3271}, - { 1010, 3430},{ 1110, 3586},{ 1224, 3724},{ 1336, 3826}, - { 1449, 3908},{ 1547, 4021},{ 1636, 4136},{ 1751, 4200}, - { 1886, 4277},{ 1977, 4384},{ 2070, 4474},{ 2232, 4510} - }, - /*Cr qi=33 INTER*/ - { - { 77, 9},{ 90, 347},{ 80, 674},{ 91, 1053}, - { 107, 1444},{ 119, 1825},{ 127, 2196},{ 137, 2563}, - { 149, 2919},{ 161, 3259},{ 176, 3588},{ 194, 3905}, - { 217, 4209},{ 246, 4504},{ 280, 4786},{ 320, 5055}, - { 364, 5316},{ 409, 5565},{ 460, 5804},{ 517, 6039}, - { 578, 6264},{ 640, 6489},{ 701, 6721},{ 772, 6948} - } - } - }, - { - { - /*Y' qi=34 INTRA*/ - { - { 124, 40},{ 401, 1333},{ 823, 2262},{ 1318, 2842}, - { 1823, 3265},{ 2339, 3650},{ 2872, 3991},{ 3405, 4274}, - { 3926, 4513},{ 4448, 4704},{ 4961, 4845},{ 5450, 4921}, - { 5925, 4971},{ 6372, 5053},{ 6813, 5160},{ 7264, 5242}, - { 7704, 5291},{ 8124, 5346},{ 8500, 5382},{ 8831, 5384}, - { 9178, 5380},{ 9525, 5387},{ 9869, 5389},{10310, 5356} - }, - /*Y' qi=34 INTER*/ - { - { 64, -17},{ 101, 1344},{ 190, 2730},{ 299, 3981}, - { 430, 5110},{ 648, 6127},{ 1036, 6933},{ 1664, 7445}, - { 2535, 7652},{ 3504, 7653},{ 4402, 7572},{ 5173, 7479}, - { 5843, 7400},{ 6441, 7334},{ 6976, 7280},{ 7464, 7231}, - { 7910, 7189},{ 8332, 7157},{ 8730, 7125},{ 9091, 7103}, - { 9422, 7086},{ 9753, 7061},{10067, 7036},{10316, 7029} - } - }, - { - /*Cb qi=34 INTRA*/ - { - { 5, 3},{ 91, 369},{ 158, 746},{ 204, 1162}, - { 266, 1561},{ 358, 1903},{ 466, 2189},{ 570, 2439}, - { 665, 2671},{ 765, 2880},{ 864, 3069},{ 970, 3238}, - { 1079, 3392},{ 1174, 3545},{ 1265, 3693},{ 1360, 3841}, - { 1471, 3968},{ 1572, 4083},{ 1675, 4181},{ 1804, 4255}, - { 1939, 4332},{ 2048, 4411},{ 2155, 4484},{ 2339, 4584} - }, - /*Cb qi=34 INTER*/ - { - { 99, 44},{ 92, 345},{ 82, 661},{ 86, 1043}, - { 101, 1436},{ 116, 1821},{ 128, 2191},{ 140, 2549}, - { 154, 2898},{ 168, 3235},{ 185, 3556},{ 203, 3865}, - { 224, 4166},{ 248, 4457},{ 278, 4741},{ 315, 5021}, - { 361, 5289},{ 416, 5546},{ 483, 5792},{ 559, 6025}, - { 651, 6237},{ 752, 6432},{ 849, 6626},{ 967, 6790} - } - }, - { - /*Cr qi=34 INTRA*/ - { - { 11, 7},{ 93, 387},{ 158, 773},{ 212, 1195}, - { 282, 1584},{ 378, 1909},{ 483, 2179},{ 578, 2414}, - { 671, 2633},{ 766, 2837},{ 866, 3038},{ 960, 3223}, - { 1049, 3376},{ 1158, 3520},{ 1285, 3644},{ 1400, 3740}, - { 1505, 3828},{ 1616, 3928},{ 1713, 4030},{ 1820, 4104}, - { 1957, 4185},{ 2063, 4280},{ 2160, 4355},{ 2320, 4341} - }, - /*Cr qi=34 INTER*/ - { - { 78, 11},{ 89, 347},{ 79, 674},{ 90, 1053}, - { 106, 1444},{ 117, 1823},{ 127, 2192},{ 137, 2558}, - { 149, 2912},{ 163, 3249},{ 178, 3574},{ 197, 3888}, - { 222, 4189},{ 252, 4481},{ 293, 4755},{ 341, 5013}, - { 386, 5268},{ 436, 5512},{ 498, 5743},{ 563, 5970}, - { 622, 6200},{ 694, 6415},{ 776, 6622},{ 871, 6818} - } - } - }, - { - { - /*Y' qi=35 INTRA*/ - { - { 116, 51},{ 433, 1312},{ 881, 2221},{ 1406, 2771}, - { 1948, 3156},{ 2511, 3501},{ 3085, 3811},{ 3654, 4066}, - { 4212, 4273},{ 4763, 4444},{ 5298, 4572},{ 5799, 4638}, - { 6285, 4678},{ 6747, 4746},{ 7203, 4838},{ 7673, 4905}, - { 8124, 4950},{ 8552, 5003},{ 8938, 5027},{ 9275, 5026}, - { 9628, 5019},{ 9981, 5024},{10331, 5030},{10795, 5000} - }, - /*Y' qi=35 INTER*/ - { - { 71, -10},{ 108, 1348},{ 203, 2710},{ 325, 3938}, - { 485, 5040},{ 766, 6000},{ 1267, 6706},{ 2048, 7089}, - { 3037, 7191},{ 4032, 7146},{ 4903, 7061},{ 5648, 6977}, - { 6301, 6912},{ 6884, 6857},{ 7413, 6812},{ 7898, 6775}, - { 8342, 6739},{ 8764, 6710},{ 9160, 6688},{ 9519, 6668}, - { 9859, 6646},{10190, 6625},{10492, 6612},{10755, 6595} - } - }, - { - /*Cb qi=35 INTRA*/ - { - { 6, 3},{ 95, 369},{ 164, 746},{ 214, 1156}, - { 287, 1542},{ 390, 1869},{ 504, 2143},{ 611, 2388}, - { 712, 2613},{ 822, 2811},{ 937, 2987},{ 1055, 3147}, - { 1174, 3285},{ 1286, 3420},{ 1386, 3560},{ 1488, 3698}, - { 1604, 3814},{ 1714, 3916},{ 1825, 4008},{ 1958, 4088}, - { 2101, 4159},{ 2224, 4226},{ 2339, 4292},{ 2538, 4383} - }, - /*Cb qi=35 INTER*/ - { - { 98, 41},{ 90, 348},{ 86, 665},{ 92, 1042}, - { 108, 1432},{ 122, 1812},{ 136, 2175},{ 151, 2528}, - { 165, 2872},{ 182, 3202},{ 202, 3516},{ 225, 3819}, - { 251, 4112},{ 281, 4398},{ 320, 4675},{ 367, 4944}, - { 421, 5204},{ 493, 5450},{ 579, 5679},{ 672, 5892}, - { 785, 6082},{ 906, 6258},{ 1026, 6432},{ 1153, 6592} - } - }, - { - /*Cr qi=35 INTRA*/ - { - { 12, 7},{ 98, 388},{ 166, 773},{ 226, 1187}, - { 306, 1563},{ 411, 1874},{ 524, 2134},{ 622, 2365}, - { 721, 2577},{ 826, 2768},{ 947, 2946},{ 1066, 3106}, - { 1163, 3250},{ 1274, 3395},{ 1417, 3508},{ 1539, 3590}, - { 1639, 3671},{ 1754, 3765},{ 1865, 3855},{ 1979, 3921}, - { 2127, 3998},{ 2249, 4085},{ 2346, 4172},{ 2473, 4210} - }, - /*Cr qi=35 INTER*/ - { - { 86, 12},{ 94, 354},{ 85, 677},{ 96, 1052}, - { 113, 1439},{ 125, 1811},{ 135, 2177},{ 147, 2537}, - { 160, 2884},{ 177, 3215},{ 195, 3535},{ 219, 3842}, - { 252, 4133},{ 292, 4413},{ 339, 4680},{ 396, 4928}, - { 455, 5169},{ 514, 5408},{ 588, 5626},{ 672, 5835}, - { 750, 6051},{ 837, 6257},{ 943, 6442},{ 1073, 6595} + { 12, 688},{ 11, 660},{ 28, 869},{ 46, 1227}, + { 60, 1598},{ 68, 1954},{ 79, 2318},{ 93, 2693}, + { 108, 3054},{ 123, 3406},{ 138, 3748},{ 151, 4078}, + { 165, 4400},{ 180, 4716},{ 197, 5024},{ 217, 5314}, + { 243, 5599},{ 275, 5866},{ 301, 6128},{ 327, 6394}, + { 352, 6644},{ 375, 6894},{ 376, 7180},{ 458, 7334} } } }, @@ -2290,557 +279,61 @@ oc_mode_rd OC_MODE_RD[64][3][2][OC_SAD_BINS]={ { /*Y' qi=36 INTRA*/ { - { 116, 52},{ 432, 1312},{ 881, 2215},{ 1407, 2759}, - { 1948, 3140},{ 2511, 3484},{ 3090, 3789},{ 3672, 4036}, - { 4243, 4236},{ 4803, 4397},{ 5346, 4517},{ 5856, 4581}, - { 6350, 4614},{ 6821, 4675},{ 7286, 4763},{ 7754, 4832}, - { 8201, 4875},{ 8631, 4922},{ 9015, 4948},{ 9351, 4945}, - { 9706, 4941},{10061, 4948},{10408, 4949},{10878, 4923} + { 156, 263},{ 484, 1370},{ 1174, 2110},{ 1914, 2456}, + { 2601, 2695},{ 3221, 2984},{ 3865, 3284},{ 4450, 3530}, + { 4979, 3739},{ 5470, 3928},{ 5905, 4080},{ 6375, 4200}, + { 6761, 4373},{ 7175, 4429},{ 7615, 4616},{ 8069, 4687}, + { 8417, 4820},{ 8813, 4908},{ 9211, 5001},{ 9508, 5073}, + { 9888, 5133},{10209, 5140},{10529, 5196},{10830, 5173} }, /*Y' qi=36 INTER*/ { - { 63, -16},{ 114, 1332},{ 216, 2690},{ 343, 3914}, - { 515, 5009},{ 829, 5939},{ 1399, 6586},{ 2263, 6901}, - { 3290, 6967},{ 4272, 6920},{ 5115, 6847},{ 5839, 6779}, - { 6478, 6726},{ 7051, 6685},{ 7571, 6649},{ 8050, 6614}, - { 8495, 6587},{ 8908, 6567},{ 9298, 6550},{ 9673, 6530}, - {10005, 6512},{10324, 6499},{10640, 6483},{10936, 6487} + { 68, 151},{ 107, 1413},{ 262, 2665},{ 542, 3715}, + { 946, 4584},{ 1508, 5279},{ 2167, 5829},{ 2968, 6179}, + { 3758, 6392},{ 4481, 6517},{ 5139, 6577},{ 5706, 6636}, + { 6271, 6612},{ 6746, 6585},{ 7216, 6533},{ 7622, 6496}, + { 8045, 6403},{ 8393, 6389},{ 8799, 6272},{ 9062, 6281}, + { 9436, 6184},{ 9637, 6238},{ 9864, 6215},{10147, 6215} } }, { /*Cb qi=36 INTRA*/ { - { 6, 3},{ 98, 370},{ 170, 746},{ 225, 1150}, - { 306, 1527},{ 416, 1845},{ 534, 2116},{ 642, 2363}, - { 743, 2591},{ 851, 2794},{ 964, 2972},{ 1081, 3133}, - { 1198, 3275},{ 1311, 3410},{ 1411, 3547},{ 1519, 3680}, - { 1642, 3789},{ 1750, 3892},{ 1860, 3982},{ 1998, 4054}, - { 2141, 4129},{ 2256, 4204},{ 2372, 4278},{ 2567, 4356} + { 91, 385},{ 138, 613},{ 205, 932},{ 265, 1239}, + { 353, 1549},{ 443, 1839},{ 518, 2104},{ 655, 2341}, + { 764, 2559},{ 876, 2756},{ 967, 2950},{ 1088, 3107}, + { 1184, 3266},{ 1295, 3396},{ 1375, 3548},{ 1502, 3664}, + { 1610, 3764},{ 1731, 3844},{ 1839, 3938},{ 1954, 4016}, + { 2069, 4100},{ 2207, 4167},{ 2274, 4253},{ 2374, 4289} }, /*Cb qi=36 INTER*/ { - { 107, 30},{ 96, 346},{ 88, 667},{ 100, 1039}, - { 115, 1426},{ 128, 1804},{ 142, 2164},{ 158, 2512}, - { 176, 2851},{ 195, 3178},{ 218, 3491},{ 243, 3791}, - { 270, 4084},{ 307, 4365},{ 348, 4638},{ 397, 4908}, - { 464, 5157},{ 545, 5392},{ 635, 5620},{ 734, 5831}, - { 854, 6015},{ 993, 6170},{ 1124, 6327},{ 1234, 6502} + { 59, 18},{ 56, 463},{ 50, 790},{ 76, 1155}, + { 90, 1515},{ 108, 1877},{ 125, 2226},{ 150, 2562}, + { 177, 2890},{ 203, 3203},{ 231, 3501},{ 259, 3789}, + { 289, 4074},{ 325, 4348},{ 367, 4608},{ 418, 4857}, + { 486, 5093},{ 574, 5307},{ 677, 5494},{ 784, 5688}, + { 914, 5844},{ 1033, 6004},{ 1142, 6179},{ 1307, 6220} } }, { /*Cr qi=36 INTRA*/ { - { 12, 7},{ 102, 388},{ 172, 773},{ 239, 1182}, - { 328, 1546},{ 439, 1848},{ 554, 2106},{ 651, 2341}, - { 747, 2561},{ 850, 2757},{ 972, 2934},{ 1086, 3097}, - { 1182, 3245},{ 1302, 3382},{ 1447, 3491},{ 1572, 3567}, - { 1677, 3641},{ 1793, 3733},{ 1899, 3828},{ 2013, 3894}, - { 2163, 3967},{ 2283, 4059},{ 2387, 4142},{ 2559, 4145} + { 87, 376},{ 132, 616},{ 190, 931},{ 268, 1260}, + { 358, 1550},{ 457, 1833},{ 592, 2082},{ 685, 2318}, + { 781, 2548},{ 867, 2757},{ 968, 2953},{ 1080, 3124}, + { 1173, 3255},{ 1282, 3390},{ 1410, 3477},{ 1528, 3593}, + { 1645, 3612},{ 1766, 3739},{ 1885, 3789},{ 1954, 3892}, + { 2115, 3987},{ 2202, 4052},{ 2280, 4172},{ 2379, 4213} }, /*Cr qi=36 INTER*/ { - { 98, -10},{ 96, 347},{ 89, 676},{ 102, 1048}, - { 118, 1433},{ 130, 1804},{ 141, 2167},{ 154, 2523}, - { 171, 2866},{ 190, 3194},{ 212, 3508},{ 240, 3809}, - { 276, 4099},{ 320, 4377},{ 372, 4638},{ 428, 4887}, - { 492, 5122},{ 560, 5353},{ 638, 5572},{ 725, 5779}, - { 814, 5985},{ 902, 6192},{ 1013, 6377},{ 1155, 6527} - } - } - }, - { - { - /*Y' qi=37 INTRA*/ - { - { 109, 58},{ 445, 1302},{ 927, 2177},{ 1489, 2689}, - { 2053, 3052},{ 2632, 3387},{ 3230, 3683},{ 3830, 3922}, - { 4417, 4114},{ 4992, 4266},{ 5546, 4375},{ 6067, 4430}, - { 6571, 4459},{ 7046, 4516},{ 7513, 4599},{ 7991, 4663}, - { 8445, 4706},{ 8883, 4749},{ 9273, 4771},{ 9612, 4770}, - { 9970, 4765},{10325, 4773},{10672, 4778},{11106, 4758} - }, - /*Y' qi=37 INTER*/ - { - { 56, -14},{ 114, 1333},{ 218, 2683},{ 354, 3894}, - { 550, 4966},{ 916, 5854},{ 1569, 6437},{ 2520, 6685}, - { 3596, 6704},{ 4585, 6635},{ 5424, 6556},{ 6147, 6489}, - { 6787, 6437},{ 7358, 6395},{ 7876, 6358},{ 8361, 6325}, - { 8807, 6294},{ 9229, 6271},{ 9631, 6253},{10002, 6238}, - {10356, 6228},{10678, 6212},{10975, 6197},{11274, 6185} - } - }, - { - /*Cb qi=37 INTRA*/ - { - { 6, 3},{ 99, 370},{ 171, 746},{ 227, 1149}, - { 309, 1522},{ 421, 1836},{ 541, 2104},{ 652, 2347}, - { 757, 2572},{ 871, 2768},{ 989, 2936},{ 1111, 3087}, - { 1238, 3223},{ 1357, 3352},{ 1465, 3486},{ 1576, 3612}, - { 1709, 3705},{ 1828, 3801},{ 1937, 3895},{ 2076, 3967}, - { 2220, 4035},{ 2345, 4104},{ 2466, 4173},{ 2680, 4265} - }, - /*Cb qi=37 INTER*/ - { - { 111, 27},{ 97, 344},{ 87, 667},{ 99, 1038}, - { 115, 1425},{ 128, 1802},{ 143, 2160},{ 159, 2506}, - { 176, 2843},{ 198, 3167},{ 220, 3477},{ 247, 3774}, - { 280, 4061},{ 321, 4338},{ 368, 4608},{ 427, 4867}, - { 501, 5109},{ 595, 5332},{ 701, 5544},{ 818, 5738}, - { 956, 5905},{ 1105, 6066},{ 1248, 6217},{ 1381, 6353} - } - }, - { - /*Cr qi=37 INTRA*/ - { - { 12, 7},{ 102, 388},{ 173, 773},{ 242, 1180}, - { 331, 1541},{ 444, 1839},{ 562, 2095},{ 662, 2326}, - { 763, 2540},{ 871, 2728},{ 1003, 2892},{ 1130, 3045}, - { 1230, 3188},{ 1350, 3321},{ 1503, 3418},{ 1634, 3492}, - { 1737, 3568},{ 1856, 3653},{ 1970, 3744},{ 2091, 3802}, - { 2247, 3871},{ 2371, 3962},{ 2477, 4041},{ 2655, 4052} - }, - /*Cr qi=37 INTER*/ - { - { 89, -9},{ 97, 347},{ 88, 677},{ 102, 1048}, - { 118, 1432},{ 130, 1802},{ 141, 2163},{ 154, 2517}, - { 172, 2857},{ 192, 3181},{ 216, 3494},{ 246, 3793}, - { 286, 4074},{ 337, 4343},{ 395, 4600},{ 464, 4837}, - { 534, 5066},{ 608, 5289},{ 694, 5501},{ 788, 5704}, - { 893, 5901},{ 1010, 6088},{ 1151, 6249},{ 1331, 6374} - } - } - }, - { - { - /*Y' qi=38 INTRA*/ - { - { 107, 65},{ 476, 1286},{ 968, 2148},{ 1548, 2641}, - { 2141, 2979},{ 2757, 3289},{ 3390, 3564},{ 4020, 3784}, - { 4632, 3957},{ 5224, 4097},{ 5794, 4201},{ 6326, 4250}, - { 6828, 4274},{ 7309, 4322},{ 7790, 4401},{ 8271, 4463}, - { 8729, 4498},{ 9165, 4540},{ 9552, 4566},{ 9901, 4560}, - {10266, 4552},{10617, 4563},{10964, 4572},{11393, 4567} - }, - /*Y' qi=38 INTER*/ - { - { 57, -13},{ 118, 1332},{ 233, 2665},{ 386, 3856}, - { 620, 4899},{ 1070, 5722},{ 1849, 6211},{ 2898, 6384}, - { 3989, 6376},{ 4947, 6311},{ 5754, 6249},{ 6454, 6199}, - { 7077, 6161},{ 7640, 6132},{ 8159, 6101},{ 8639, 6076}, - { 9081, 6054},{ 9502, 6037},{ 9900, 6027},{10274, 6012}, - {10621, 5999},{10938, 5991},{11237, 5977},{11557, 5966} - } - }, - { - /*Cb qi=38 INTRA*/ - { - { 8, 3},{ 104, 370},{ 179, 744},{ 243, 1139}, - { 338, 1498},{ 458, 1801},{ 584, 2060},{ 700, 2297}, - { 812, 2514},{ 935, 2699},{ 1061, 2858},{ 1189, 3007}, - { 1321, 3141},{ 1446, 3266},{ 1563, 3388},{ 1684, 3512}, - { 1816, 3614},{ 1942, 3702},{ 2055, 3793},{ 2201, 3857}, - { 2357, 3923},{ 2477, 3994},{ 2593, 4061},{ 2768, 4178} - }, - /*Cb qi=38 INTER*/ - { - { 118, 24},{ 102, 342},{ 91, 663},{ 101, 1040}, - { 116, 1427},{ 131, 1799},{ 147, 2152},{ 168, 2491}, - { 191, 2822},{ 215, 3139},{ 244, 3441},{ 276, 3731}, - { 316, 4013},{ 363, 4286},{ 423, 4546},{ 495, 4795}, - { 584, 5028},{ 691, 5242},{ 814, 5439},{ 959, 5608}, - { 1119, 5759},{ 1277, 5906},{ 1449, 6035},{ 1655, 6144} - } - }, - { - /*Cr qi=38 INTRA*/ - { - { 12, 6},{ 106, 387},{ 182, 771},{ 261, 1168}, - { 364, 1514},{ 483, 1802},{ 603, 2053},{ 707, 2282}, - { 817, 2489},{ 933, 2670},{ 1074, 2825},{ 1210, 2967}, - { 1320, 3104},{ 1444, 3229},{ 1599, 3324},{ 1735, 3396}, - { 1846, 3464},{ 1971, 3547},{ 2086, 3646},{ 2206, 3711}, - { 2366, 3773},{ 2499, 3859},{ 2603, 3945},{ 2766, 3952} - }, - /*Cr qi=38 INTER*/ - { - { 86, -9},{ 91, 352},{ 85, 680},{ 102, 1053}, - { 119, 1435},{ 132, 1799},{ 146, 2153},{ 162, 2501}, - { 183, 2835},{ 209, 3154},{ 240, 3458},{ 278, 3751}, - { 327, 4025},{ 388, 4284},{ 455, 4532},{ 529, 4766}, - { 616, 4980},{ 711, 5188},{ 815, 5386},{ 920, 5583}, - { 1042, 5770},{ 1186, 5936},{ 1348, 6080},{ 1542, 6196} - } - } - }, - { - { - /*Y' qi=39 INTRA*/ - { - { 103, 66},{ 479, 1283},{ 998, 2125},{ 1610, 2591}, - { 2223, 2913},{ 2855, 3214},{ 3501, 3482},{ 4146, 3698}, - { 4772, 3868},{ 5376, 3999},{ 5956, 4095},{ 6496, 4140}, - { 7008, 4162},{ 7499, 4209},{ 7987, 4282},{ 8478, 4338}, - { 8947, 4374},{ 9385, 4417},{ 9783, 4437},{10143, 4433}, - {10504, 4424},{10866, 4435},{11225, 4444},{11665, 4430} - }, - /*Y' qi=39 INTER*/ - { - { 56, 2},{ 118, 1332},{ 235, 2660},{ 395, 3843}, - { 653, 4867},{ 1153, 5652},{ 2003, 6089},{ 3113, 6214}, - { 4228, 6178},{ 5189, 6102},{ 6002, 6031},{ 6707, 5976}, - { 7336, 5936},{ 7901, 5900},{ 8424, 5870},{ 8915, 5844}, - { 9361, 5822},{ 9784, 5807},{10187, 5794},{10571, 5778}, - {10931, 5763},{11264, 5751},{11582, 5742},{11916, 5730} - } - }, - { - /*Cb qi=39 INTRA*/ - { - { 8, 3},{ 104, 370},{ 179, 744},{ 244, 1138}, - { 340, 1496},{ 461, 1796},{ 588, 2053},{ 705, 2288}, - { 820, 2503},{ 945, 2684},{ 1073, 2840},{ 1210, 2981}, - { 1352, 3106},{ 1480, 3225},{ 1603, 3342},{ 1728, 3464}, - { 1865, 3559},{ 1990, 3645},{ 2106, 3734},{ 2258, 3796}, - { 2413, 3856},{ 2540, 3920},{ 2667, 3986},{ 2887, 4060} - }, - /*Cb qi=39 INTER*/ - { - { 119, 19},{ 103, 340},{ 90, 664},{ 100, 1040}, - { 115, 1426},{ 131, 1797},{ 148, 2148},{ 169, 2486}, - { 192, 2816},{ 217, 3131},{ 247, 3432},{ 282, 3721}, - { 324, 3999},{ 374, 4268},{ 435, 4526},{ 520, 4766}, - { 621, 4990},{ 738, 5194},{ 878, 5376},{ 1035, 5543}, - { 1202, 5686},{ 1374, 5819},{ 1545, 5950},{ 1729, 6064} - } - }, - { - /*Cr qi=39 INTRA*/ - { - { 12, 6},{ 106, 387},{ 182, 771},{ 262, 1167}, - { 365, 1512},{ 486, 1798},{ 608, 2047},{ 713, 2274}, - { 824, 2479},{ 945, 2655},{ 1091, 2804},{ 1231, 2941}, - { 1346, 3073},{ 1475, 3194},{ 1633, 3282},{ 1778, 3345}, - { 1891, 3414},{ 2013, 3501},{ 2138, 3584},{ 2266, 3640}, - { 2428, 3701},{ 2568, 3782},{ 2674, 3863},{ 2816, 3894} - }, - /*Cr qi=39 INTER*/ - { - { 88, -7},{ 92, 352},{ 85, 680},{ 102, 1053}, - { 119, 1434},{ 132, 1797},{ 146, 2151},{ 163, 2498}, - { 185, 2830},{ 211, 3147},{ 243, 3451},{ 285, 3735}, - { 337, 4005},{ 401, 4260},{ 477, 4499},{ 565, 4721}, - { 655, 4937},{ 749, 5148},{ 858, 5344},{ 979, 5529}, - { 1110, 5710},{ 1264, 5871},{ 1460, 5990},{ 1677, 6086} - } - } - }, - { - { - /*Y' qi=40 INTRA*/ - { - { 98, 71},{ 491, 1274},{ 1023, 2103},{ 1641, 2559}, - { 2257, 2877},{ 2898, 3171},{ 3566, 3429},{ 4233, 3629}, - { 4881, 3784},{ 5499, 3906},{ 6088, 3997},{ 6631, 4040}, - { 7145, 4060},{ 7640, 4107},{ 8128, 4178},{ 8618, 4233}, - { 9077, 4267},{ 9514, 4304},{ 9919, 4324},{10277, 4317}, - {10635, 4312},{10985, 4324},{11338, 4331},{11792, 4334} - }, - /*Y' qi=40 INTER*/ - { - { 63, -26},{ 125, 1331},{ 256, 2640},{ 439, 3801}, - { 757, 4782},{ 1391, 5474},{ 2399, 5805},{ 3582, 5870}, - { 4678, 5824},{ 5600, 5763},{ 6386, 5710},{ 7076, 5667}, - { 7693, 5637},{ 8252, 5610},{ 8775, 5586},{ 9255, 5571}, - { 9694, 5556},{10115, 5541},{10530, 5530},{10903, 5522}, - {11242, 5515},{11596, 5501},{11904, 5482},{12205, 5475} - } - }, - { - /*Cb qi=40 INTRA*/ - { - { 8, 3},{ 108, 371},{ 189, 743},{ 265, 1128}, - { 371, 1475},{ 499, 1767},{ 628, 2022},{ 746, 2256}, - { 864, 2467},{ 991, 2647},{ 1124, 2801},{ 1270, 2933}, - { 1412, 3054},{ 1547, 3165},{ 1677, 3277},{ 1804, 3393}, - { 1946, 3483},{ 2078, 3569},{ 2201, 3651},{ 2352, 3711}, - { 2513, 3766},{ 2643, 3826},{ 2775, 3880},{ 3025, 3919} - }, - /*Cb qi=40 INTER*/ - { - { 114, 35},{ 104, 349},{ 96, 667},{ 106, 1040}, - { 121, 1423},{ 138, 1789},{ 158, 2132},{ 184, 2464}, - { 212, 2787},{ 242, 3095},{ 279, 3389},{ 321, 3671}, - { 374, 3941},{ 438, 4199},{ 517, 4446},{ 617, 4673}, - { 740, 4881},{ 891, 5064},{ 1058, 5225},{ 1239, 5372}, - { 1441, 5499},{ 1638, 5610},{ 1840, 5719},{ 2076, 5814} - } - }, - { - /*Cr qi=40 INTRA*/ - { - { 14, 7},{ 114, 389},{ 193, 771},{ 283, 1156}, - { 399, 1488},{ 523, 1768},{ 643, 2018},{ 752, 2245}, - { 865, 2450},{ 984, 2626},{ 1139, 2763},{ 1290, 2887}, - { 1413, 3014},{ 1550, 3128},{ 1711, 3211},{ 1865, 3268}, - { 1981, 3334},{ 2103, 3415},{ 2237, 3486},{ 2365, 3543}, - { 2529, 3610},{ 2666, 3700},{ 2775, 3779},{ 2929, 3803} - }, - /*Cr qi=40 INTER*/ - { - { 89, -8},{ 95, 353},{ 90, 681},{ 107, 1053}, - { 124, 1430},{ 139, 1787},{ 156, 2136},{ 177, 2477}, - { 203, 2803},{ 237, 3112},{ 276, 3406},{ 329, 3683}, - { 395, 3942},{ 475, 4182},{ 567, 4407},{ 665, 4624}, - { 767, 4834},{ 879, 5032},{ 1011, 5213},{ 1169, 5375}, - { 1348, 5525},{ 1547, 5654},{ 1785, 5743},{ 2066, 5787} - } - } - }, - { - { - /*Y' qi=41 INTRA*/ - { - { 98, 71},{ 495, 1272},{ 1040, 2090},{ 1675, 2533}, - { 2302, 2842},{ 2953, 3132},{ 3631, 3381},{ 4309, 3574}, - { 4966, 3726},{ 5593, 3846},{ 6189, 3934},{ 6738, 3972}, - { 7256, 3991},{ 7754, 4036},{ 8250, 4099},{ 8747, 4150}, - { 9207, 4185},{ 9650, 4222},{10057, 4242},{10411, 4237}, - {10771, 4230},{11127, 4244},{11486, 4254},{11933, 4252} - }, - /*Y' qi=41 INTER*/ - { - { 65, -25},{ 125, 1331},{ 260, 2633},{ 457, 3782}, - { 807, 4740},{ 1499, 5397},{ 2562, 5693},{ 3766, 5743}, - { 4859, 5695},{ 5776, 5638},{ 6556, 5590},{ 7243, 5554}, - { 7859, 5529},{ 8417, 5506},{ 8935, 5486},{ 9419, 5473}, - { 9869, 5460},{10296, 5446},{10711, 5436},{11089, 5430}, - {11445, 5421},{11802, 5412},{12129, 5404},{12465, 5393} - } - }, - { - /*Cb qi=41 INTRA*/ - { - { 8, 3},{ 108, 371},{ 189, 743},{ 267, 1126}, - { 374, 1471},{ 504, 1760},{ 635, 2011},{ 758, 2241}, - { 881, 2447},{ 1013, 2621},{ 1147, 2773},{ 1293, 2906}, - { 1441, 3023},{ 1580, 3131},{ 1712, 3243},{ 1844, 3360}, - { 1985, 3451},{ 2114, 3532},{ 2240, 3613},{ 2390, 3680}, - { 2550, 3740},{ 2687, 3800},{ 2825, 3862},{ 3052, 3944} - }, - /*Cb qi=41 INTER*/ - { - { 104, 39},{ 100, 350},{ 95, 667},{ 105, 1040}, - { 121, 1422},{ 137, 1787},{ 159, 2129},{ 185, 2459}, - { 216, 2778},{ 249, 3083},{ 287, 3374},{ 335, 3653}, - { 393, 3920},{ 462, 4175},{ 549, 4414},{ 660, 4636}, - { 791, 4839},{ 952, 5014},{ 1135, 5166},{ 1337, 5297}, - { 1552, 5411},{ 1752, 5530},{ 1972, 5634},{ 2224, 5724} - } - }, - { - /*Cr qi=41 INTRA*/ - { - { 15, 7},{ 115, 389},{ 193, 770},{ 284, 1154}, - { 401, 1484},{ 528, 1761},{ 652, 2005},{ 764, 2228}, - { 882, 2427},{ 1008, 2599},{ 1167, 2734},{ 1320, 2859}, - { 1443, 2990},{ 1580, 3103},{ 1743, 3181},{ 1894, 3241}, - { 2012, 3309},{ 2141, 3385},{ 2272, 3459},{ 2398, 3519}, - { 2566, 3584},{ 2707, 3680},{ 2816, 3762},{ 2991, 3770} - }, - /*Cr qi=41 INTER*/ - { - { 92, -9},{ 98, 354},{ 90, 682},{ 107, 1052}, - { 124, 1429},{ 139, 1786},{ 156, 2132},{ 178, 2471}, - { 207, 2794},{ 241, 3100},{ 285, 3391},{ 345, 3662}, - { 417, 3915},{ 503, 4151},{ 600, 4375},{ 703, 4589}, - { 815, 4791},{ 942, 4981},{ 1088, 5155},{ 1250, 5316}, - { 1432, 5462},{ 1653, 5575},{ 1930, 5639},{ 2250, 5655} - } - } - }, - { - { - /*Y' qi=42 INTRA*/ - { - { 109, 75},{ 534, 1257},{ 1114, 2047},{ 1793, 2456}, - { 2461, 2735},{ 3157, 2994},{ 3879, 3221},{ 4595, 3396}, - { 5282, 3531},{ 5931, 3638},{ 6546, 3714},{ 7105, 3749}, - { 7633, 3766},{ 8147, 3803},{ 8652, 3865},{ 9148, 3915}, - { 9613, 3946},{10075, 3976},{10489, 3997},{10835, 3994}, - {11195, 3985},{11553, 3997},{11909, 4004},{12369, 3990} - }, - /*Y' qi=42 INTER*/ - { - { 69, -23},{ 134, 1332},{ 287, 2611},{ 521, 3730}, - { 970, 4624},{ 1827, 5176},{ 3028, 5382},{ 4262, 5389}, - { 5325, 5338},{ 6214, 5291},{ 6976, 5255},{ 7651, 5228}, - { 8260, 5206},{ 8821, 5190},{ 9343, 5177},{ 9823, 5165}, - {10273, 5152},{10709, 5143},{11121, 5136},{11502, 5129}, - {11857, 5125},{12193, 5115},{12520, 5107},{12802, 5097} - } - }, - { - /*Cb qi=42 INTRA*/ - { - { 9, 3},{ 113, 371},{ 199, 743},{ 279, 1123}, - { 390, 1462},{ 525, 1743},{ 662, 1986},{ 789, 2208}, - { 916, 2406},{ 1057, 2571},{ 1204, 2712},{ 1362, 2835}, - { 1524, 2943},{ 1676, 3040},{ 1815, 3145},{ 1959, 3249}, - { 2117, 3325},{ 2249, 3406},{ 2377, 3488},{ 2537, 3547}, - { 2706, 3597},{ 2854, 3646},{ 2999, 3705},{ 3236, 3759} - }, - /*Cb qi=42 INTER*/ - { - { 114, 44},{ 107, 353},{ 101, 670},{ 111, 1041}, - { 129, 1418},{ 148, 1775},{ 174, 2110},{ 208, 2432}, - { 244, 2746},{ 283, 3046},{ 330, 3330},{ 388, 3602}, - { 460, 3858},{ 546, 4101},{ 655, 4326},{ 793, 4530}, - { 966, 4703},{ 1165, 4851},{ 1388, 4980},{ 1630, 5088}, - { 1869, 5189},{ 2122, 5268},{ 2403, 5328},{ 2667, 5417} - } - }, - { - /*Cr qi=42 INTRA*/ - { - { 15, 7},{ 120, 390},{ 202, 771},{ 298, 1150}, - { 421, 1473},{ 553, 1743},{ 681, 1982},{ 796, 2199}, - { 923, 2388},{ 1062, 2547},{ 1225, 2678},{ 1392, 2792}, - { 1531, 2907},{ 1682, 3007},{ 1856, 3074},{ 2009, 3134}, - { 2138, 3192},{ 2274, 3257},{ 2407, 3333},{ 2536, 3393}, - { 2711, 3455},{ 2875, 3531},{ 3000, 3598},{ 3186, 3599} - }, - /*Cr qi=42 INTER*/ - { - { 87, -4},{ 95, 358},{ 97, 683},{ 113, 1052}, - { 131, 1423},{ 148, 1774},{ 170, 2116},{ 198, 2448}, - { 234, 2762},{ 276, 3062},{ 331, 3343},{ 404, 3603}, - { 494, 3844},{ 598, 4067},{ 715, 4276},{ 842, 4471}, - { 977, 4661},{ 1128, 4840},{ 1311, 4991},{ 1516, 5127}, - { 1759, 5233},{ 2050, 5300},{ 2377, 5323},{ 2710, 5304} - } - } - }, - { - { - /*Y' qi=43 INTRA*/ - { - { 99, 79},{ 557, 1244},{ 1175, 2016},{ 1882, 2408}, - { 2570, 2677},{ 3288, 2926},{ 4030, 3141},{ 4760, 3307}, - { 5458, 3435},{ 6115, 3537},{ 6743, 3608},{ 7312, 3636}, - { 7841, 3652},{ 8357, 3687},{ 8870, 3742},{ 9376, 3788}, - { 9850, 3821},{10315, 3853},{10734, 3873},{11084, 3870}, - {11442, 3862},{11800, 3874},{12160, 3879},{12618, 3876} - }, - /*Y' qi=43 INTER*/ - { - { 69, -22},{ 134, 1331},{ 294, 2601},{ 551, 3703}, - { 1056, 4563},{ 2003, 5061},{ 3276, 5215},{ 4534, 5194}, - { 5599, 5133},{ 6488, 5083},{ 7257, 5044},{ 7938, 5014}, - { 8556, 4992},{ 9124, 4975},{ 9648, 4960},{10138, 4948}, - {10594, 4939},{11039, 4926},{11462, 4919},{11847, 4912}, - {12216, 4904},{12570, 4896},{12883, 4889},{13189, 4879} - } - }, - { - /*Cb qi=43 INTRA*/ - { - { 9, 3},{ 114, 371},{ 202, 740},{ 294, 1110}, - { 417, 1440},{ 558, 1716},{ 700, 1956},{ 833, 2172}, - { 966, 2365},{ 1116, 2524},{ 1269, 2661},{ 1431, 2781}, - { 1599, 2885},{ 1756, 2980},{ 1902, 3082},{ 2051, 3185}, - { 2209, 3261},{ 2337, 3342},{ 2464, 3420},{ 2633, 3475}, - { 2809, 3525},{ 2948, 3579},{ 3094, 3633},{ 3347, 3678} - }, - /*Cb qi=43 INTER*/ - { - { 111, 44},{ 106, 353},{ 102, 670},{ 112, 1040}, - { 128, 1416},{ 148, 1771},{ 176, 2104},{ 211, 2424}, - { 250, 2734},{ 293, 3030},{ 347, 3309},{ 411, 3575}, - { 490, 3828},{ 589, 4064},{ 716, 4278},{ 869, 4472}, - { 1050, 4640},{ 1264, 4781},{ 1512, 4895},{ 1775, 4991}, - { 2042, 5069},{ 2310, 5141},{ 2593, 5207},{ 2912, 5239} - } - }, - { - /*Cr qi=43 INTRA*/ - { - { 15, 7},{ 121, 390},{ 208, 767},{ 315, 1135}, - { 449, 1449},{ 586, 1715},{ 718, 1950},{ 843, 2158}, - { 977, 2342},{ 1120, 2501},{ 1290, 2632},{ 1466, 2739}, - { 1613, 2845},{ 1763, 2945},{ 1937, 3015},{ 2093, 3070}, - { 2225, 3126},{ 2366, 3194},{ 2501, 3267},{ 2634, 3324}, - { 2815, 3385},{ 2964, 3466},{ 3087, 3538},{ 3263, 3555} - }, - /*Cr qi=43 INTER*/ - { - { 84, -4},{ 93, 358},{ 95, 683},{ 113, 1052}, - { 131, 1421},{ 148, 1770},{ 171, 2110},{ 201, 2439}, - { 240, 2750},{ 287, 3046},{ 348, 3322},{ 429, 3576}, - { 527, 3811},{ 641, 4029},{ 767, 4230},{ 904, 4422}, - { 1053, 4603},{ 1225, 4765},{ 1433, 4903},{ 1661, 5030}, - { 1928, 5121},{ 2252, 5160},{ 2604, 5164},{ 2979, 5125} - } - } - }, - { - { - /*Y' qi=44 INTRA*/ - { - { 103, 80},{ 560, 1244},{ 1183, 2009},{ 1891, 2391}, - { 2586, 2649},{ 3324, 2884},{ 4093, 3089},{ 4850, 3243}, - { 5575, 3358},{ 6252, 3452},{ 6886, 3518},{ 7459, 3546}, - { 7993, 3562},{ 8515, 3594},{ 9030, 3645},{ 9534, 3691}, - {10004, 3723},{10469, 3750},{10887, 3765},{11236, 3766}, - {11596, 3762},{11960, 3775},{12317, 3784},{12766, 3789} - }, - /*Y' qi=44 INTER*/ - { - { 77, -24},{ 145, 1332},{ 332, 2580},{ 642, 3649}, - { 1270, 4438},{ 2360, 4860},{ 3685, 4982},{ 4910, 4966}, - { 5929, 4928},{ 6785, 4900},{ 7529, 4880},{ 8198, 4863}, - { 8804, 4850},{ 9361, 4842},{ 9882, 4836},{10371, 4830}, - {10827, 4822},{11262, 4816},{11672, 4811},{12052, 4807}, - {12431, 4806},{12780, 4798},{13095, 4792},{13401, 4791} - } - }, - { - /*Cb qi=44 INTRA*/ - { - { 9, 2},{ 122, 371},{ 214, 741},{ 307, 1109}, - { 433, 1432},{ 576, 1704},{ 718, 1939},{ 855, 2152}, - { 991, 2340},{ 1141, 2497},{ 1298, 2632},{ 1463, 2749}, - { 1636, 2851},{ 1796, 2944},{ 1947, 3041},{ 2101, 3140}, - { 2260, 3219},{ 2392, 3297},{ 2527, 3366},{ 2693, 3424}, - { 2872, 3477},{ 3025, 3525},{ 3175, 3584},{ 3451, 3626} - }, - /*Cb qi=44 INTER*/ - { - { 111, 14},{ 110, 339},{ 109, 671},{ 120, 1040}, - { 139, 1410},{ 162, 1758},{ 197, 2084},{ 243, 2397}, - { 291, 2702},{ 342, 2992},{ 405, 3265},{ 484, 3521}, - { 584, 3760},{ 705, 3983},{ 855, 4185},{ 1048, 4356}, - { 1274, 4500},{ 1531, 4617},{ 1816, 4707},{ 2111, 4783}, - { 2409, 4846},{ 2720, 4901},{ 3044, 4957},{ 3391, 4985} - } - }, - { - /*Cr qi=44 INTRA*/ - { - { 17, 7},{ 128, 392},{ 219, 770},{ 329, 1135}, - { 465, 1442},{ 601, 1703},{ 734, 1935},{ 862, 2142}, - { 998, 2325},{ 1147, 2482},{ 1321, 2606},{ 1496, 2710}, - { 1649, 2813},{ 1809, 2908},{ 1984, 2977},{ 2143, 3032}, - { 2279, 3087},{ 2423, 3152},{ 2559, 3225},{ 2684, 3288}, - { 2866, 3351},{ 3025, 3426},{ 3161, 3492},{ 3372, 3500} - }, - /*Cr qi=44 INTER*/ - { - { 89, 0},{ 101, 352},{ 104, 683},{ 121, 1051}, - { 141, 1414},{ 163, 1757},{ 192, 2092},{ 231, 2415}, - { 278, 2720},{ 336, 3007},{ 412, 3273},{ 510, 3516}, - { 633, 3733},{ 769, 3936},{ 914, 4130},{ 1076, 4307}, - { 1256, 4472},{ 1469, 4617},{ 1723, 4732},{ 2012, 4822}, - { 2347, 4871},{ 2716, 4875},{ 3082, 4866},{ 3422, 4826} + { 53, 45},{ 50, 467},{ 45, 789},{ 76, 1150}, + { 92, 1531},{ 107, 1877},{ 125, 2219},{ 147, 2561}, + { 176, 2893},{ 206, 3209},{ 231, 3514},{ 260, 3808}, + { 298, 4085},{ 350, 4344},{ 411, 4587},{ 475, 4814}, + { 532, 5037},{ 587, 5261},{ 647, 5480},{ 707, 5694}, + { 793, 5900},{ 891, 6093},{ 1017, 6292},{ 1205, 6307} } } }, @@ -2848,557 +341,61 @@ oc_mode_rd OC_MODE_RD[64][3][2][OC_SAD_BINS]={ { /*Y' qi=45 INTRA*/ { - { 119, 78},{ 610, 1226},{ 1271, 1965},{ 2026, 2319}, - { 2768, 2550},{ 3556, 2757},{ 4369, 2938},{ 5157, 3076}, - { 5901, 3182},{ 6598, 3268},{ 7253, 3326},{ 7844, 3343}, - { 8392, 3356},{ 8922, 3386},{ 9453, 3433},{ 9973, 3474}, - {10457, 3503},{10929, 3530},{11351, 3543},{11709, 3541}, - {12068, 3537},{12434, 3547},{12805, 3555},{13268, 3563} + { 47, 170},{ 955, 1217},{ 1713, 2014},{ 3050, 2094}, + { 3954, 2179},{ 4801, 2357},{ 5629, 2494},{ 6313, 2614}, + { 6962, 2716},{ 7566, 2820},{ 8138, 2886},{ 8613, 2949}, + { 9097, 3031},{ 9574, 3044},{10053, 3142},{10514, 3134}, + {10897, 3241},{11397, 3275},{11775, 3297},{12200, 3350}, + {12527, 3350},{12959, 3393},{13246, 3401},{13573, 3397} }, /*Y' qi=45 INTER*/ { - { 77, -20},{ 146, 1330},{ 342, 2566},{ 699, 3604}, - { 1439, 4332},{ 2669, 4672},{ 4075, 4727},{ 5318, 4679}, - { 6345, 4630},{ 7209, 4595},{ 7963, 4570},{ 8644, 4551}, - { 9262, 4535},{ 9831, 4525},{10370, 4515},{10872, 4506}, - {11334, 4500},{11783, 4492},{12219, 4489},{12617, 4483}, - {12995, 4477},{13350, 4472},{13674, 4466},{13968, 4468} + { 53, 73},{ 175, 1343},{ 649, 2439},{ 1339, 3250}, + { 2297, 3837},{ 3395, 4203},{ 4438, 4400},{ 5401, 4529}, + { 6222, 4588},{ 7018, 4564},{ 7713, 4532},{ 8378, 4464}, + { 8959, 4414},{ 9464, 4364},{ 9980, 4315},{10401, 4291}, + {10805, 4260},{11172, 4260},{11501, 4231},{11798, 4248}, + {12082, 4254},{12381, 4262},{12572, 4285},{12877, 4289} } }, { /*Cb qi=45 INTRA*/ { - { 9, 2},{ 122, 370},{ 219, 735},{ 324, 1096}, - { 465, 1414},{ 619, 1679},{ 771, 1905},{ 920, 2103}, - { 1070, 2276},{ 1236, 2419},{ 1410, 2539},{ 1595, 2644}, - { 1784, 2736},{ 1949, 2831},{ 2104, 2931},{ 2275, 3021}, - { 2443, 3092},{ 2586, 3166},{ 2735, 3234},{ 2904, 3288}, - { 3093, 3338},{ 3262, 3382},{ 3419, 3427},{ 3708, 3456} + { 112, -14},{ 173, 495},{ 260, 827},{ 355, 1122}, + { 451, 1420},{ 579, 1695},{ 697, 1934},{ 917, 2101}, + { 1104, 2244},{ 1266, 2381},{ 1417, 2520},{ 1609, 2611}, + { 1801, 2689},{ 1973, 2764},{ 2108, 2864},{ 2298, 2948}, + { 2452, 3008},{ 2588, 3080},{ 2732, 3161},{ 2888, 3203}, + { 3052, 3266},{ 3240, 3294},{ 3342, 3351},{ 3467, 3373} }, /*Cb qi=45 INTER*/ { - { 103, 0},{ 109, 339},{ 109, 670},{ 119, 1039}, - { 137, 1408},{ 162, 1754},{ 199, 2076},{ 248, 2386}, - { 301, 2684},{ 360, 2967},{ 433, 3234},{ 525, 3481}, - { 640, 3713},{ 780, 3924},{ 956, 4110},{ 1176, 4266}, - { 1438, 4390},{ 1736, 4481},{ 2057, 4553},{ 2385, 4613}, - { 2718, 4656},{ 3056, 4698},{ 3416, 4733},{ 3799, 4755} + { 41, -49},{ 52, 385},{ 87, 743},{ 110, 1102}, + { 135, 1453},{ 162, 1788},{ 207, 2096},{ 272, 2391}, + { 330, 2677},{ 392, 2950},{ 464, 3205},{ 556, 3442}, + { 674, 3656},{ 827, 3847},{ 1030, 4006},{ 1275, 4132}, + { 1544, 4234},{ 1809, 4317},{ 2089, 4408},{ 2377, 4456}, + { 2647, 4532},{ 2919, 4595},{ 3256, 4659},{ 3465, 4657} } }, { /*Cr qi=45 INTRA*/ { - { 16, 7},{ 128, 391},{ 225, 763},{ 350, 1120}, - { 500, 1420},{ 649, 1673},{ 792, 1893},{ 929, 2089}, - { 1084, 2257},{ 1250, 2401},{ 1440, 2518},{ 1633, 2614}, - { 1799, 2708},{ 1968, 2798},{ 2151, 2863},{ 2314, 2914}, - { 2453, 2968},{ 2611, 3025},{ 2759, 3095},{ 2887, 3160}, - { 3082, 3210},{ 3259, 3278},{ 3403, 3342},{ 3593, 3354} + { 99, -14},{ 164, 493},{ 247, 832},{ 358, 1123}, + { 468, 1416},{ 599, 1680},{ 795, 1886},{ 958, 2063}, + { 1133, 2211},{ 1300, 2345},{ 1480, 2461},{ 1664, 2554}, + { 1807, 2656},{ 1995, 2742},{ 2146, 2799},{ 2331, 2856}, + { 2440, 2894},{ 2592, 2996},{ 2751, 3033},{ 2865, 3112}, + { 3073, 3162},{ 3210, 3208},{ 3330, 3306},{ 3454, 3332} }, /*Cr qi=45 INTER*/ { - { 92, 0},{ 101, 352},{ 103, 682},{ 120, 1049}, - { 140, 1412},{ 163, 1752},{ 193, 2083},{ 234, 2402}, - { 287, 2702},{ 353, 2983},{ 442, 3240},{ 557, 3471}, - { 694, 3680},{ 846, 3873},{ 1014, 4056},{ 1200, 4224}, - { 1414, 4369},{ 1664, 4495},{ 1946, 4595},{ 2278, 4654}, - { 2654, 4673},{ 3047, 4658},{ 3438, 4627},{ 3825, 4585} - } - } - }, - { - { - /*Y' qi=46 INTRA*/ - { - { 119, 78},{ 610, 1227},{ 1277, 1960},{ 2043, 2309}, - { 2805, 2529},{ 3618, 2719},{ 4452, 2887},{ 5257, 3016}, - { 6017, 3115},{ 6727, 3195},{ 7392, 3248},{ 7984, 3267}, - { 8528, 3281},{ 9059, 3310},{ 9593, 3354},{10119, 3395}, - {10599, 3425},{11064, 3450},{11493, 3464},{11850, 3466}, - {12207, 3462},{12578, 3471},{12948, 3480},{13407, 3487} - }, - /*Y' qi=46 INTER*/ - { - { 74, -14},{ 149, 1326},{ 382, 2538},{ 807, 3541}, - { 1670, 4211},{ 3000, 4499},{ 4416, 4533},{ 5628, 4490}, - { 6628, 4453},{ 7479, 4425},{ 8228, 4406},{ 8902, 4393}, - { 9521, 4380},{10090, 4371},{10623, 4364},{11124, 4356}, - {11586, 4351},{12043, 4344},{12476, 4341},{12863, 4340}, - {13244, 4337},{13610, 4329},{13936, 4324},{14246, 4329} - } - }, - { - /*Cb qi=46 INTRA*/ - { - { 11, 2},{ 132, 371},{ 234, 737},{ 340, 1094}, - { 481, 1405},{ 637, 1667},{ 791, 1891},{ 944, 2084}, - { 1099, 2253},{ 1268, 2392},{ 1444, 2507},{ 1633, 2610}, - { 1825, 2700},{ 1990, 2794},{ 2147, 2895},{ 2321, 2984}, - { 2493, 3053},{ 2640, 3126},{ 2787, 3198},{ 2954, 3253}, - { 3146, 3297},{ 3313, 3344},{ 3473, 3393},{ 3757, 3434} - }, - /*Cb qi=46 INTER*/ - { - { 97, 0},{ 109, 339},{ 108, 669},{ 120, 1035}, - { 142, 1398},{ 173, 1737},{ 221, 2052},{ 281, 2353}, - { 345, 2646},{ 415, 2924},{ 504, 3183},{ 616, 3421}, - { 749, 3643},{ 914, 3842},{ 1123, 4012},{ 1379, 4150}, - { 1685, 4250},{ 2014, 4327},{ 2366, 4382},{ 2731, 4426}, - { 3083, 4470},{ 3445, 4490},{ 3805, 4511},{ 4146, 4539} - } - }, - { - /*Cr qi=46 INTRA*/ - { - { 19, 7},{ 137, 393},{ 237, 765},{ 364, 1116}, - { 516, 1411},{ 665, 1662},{ 809, 1880},{ 951, 2072}, - { 1109, 2236},{ 1278, 2378},{ 1474, 2491},{ 1669, 2584}, - { 1835, 2678},{ 2014, 2766},{ 2203, 2828},{ 2366, 2880}, - { 2506, 2933},{ 2661, 2988},{ 2810, 3053},{ 2941, 3116}, - { 3131, 3175},{ 3310, 3243},{ 3461, 3303},{ 3656, 3321} - }, - /*Cr qi=46 INTER*/ - { - { 91, 1},{ 103, 351},{ 104, 681},{ 121, 1046}, - { 144, 1401},{ 173, 1736},{ 213, 2060},{ 265, 2373}, - { 330, 2666},{ 410, 2938},{ 517, 3185},{ 655, 3404}, - { 815, 3601},{ 989, 3784},{ 1183, 3951},{ 1400, 4104}, - { 1649, 4241},{ 1933, 4352},{ 2261, 4427},{ 2646, 4458}, - { 3057, 4446},{ 3453, 4418},{ 3820, 4385},{ 4171, 4352} - } - } - }, - { - { - /*Y' qi=47 INTRA*/ - { - { 117, 83},{ 670, 1205},{ 1408, 1904},{ 2239, 2219}, - { 3049, 2414},{ 3905, 2584},{ 4775, 2734},{ 5610, 2852}, - { 6393, 2944},{ 7121, 3017},{ 7804, 3066},{ 8407, 3081}, - { 8957, 3093},{ 9498, 3119},{10043, 3160},{10582, 3199}, - {11083, 3226},{11561, 3250},{11993, 3263},{12352, 3264}, - {12711, 3259},{13092, 3266},{13463, 3271},{13918, 3275} - }, - /*Y' qi=47 INTER*/ - { - { 74, -11},{ 148, 1325},{ 404, 2518},{ 910, 3478}, - { 1916, 4080},{ 3369, 4298},{ 4823, 4292},{ 6035, 4238}, - { 7037, 4197},{ 7894, 4168},{ 8650, 4146},{ 9337, 4129}, - { 9968, 4116},{10549, 4105},{11096, 4096},{11605, 4089}, - {12081, 4083},{12547, 4076},{12990, 4070},{13399, 4070}, - {13776, 4065},{14133, 4059},{14486, 4057},{14842, 4053} - } - }, - { - /*Cb qi=47 INTRA*/ - { - { 11, 2},{ 133, 370},{ 242, 731},{ 367, 1077}, - { 524, 1378},{ 692, 1630},{ 860, 1844},{ 1028, 2024}, - { 1203, 2178},{ 1393, 2305},{ 1582, 2413},{ 1787, 2507}, - { 1992, 2590},{ 2175, 2676},{ 2351, 2767},{ 2534, 2851}, - { 2707, 2923},{ 2862, 2994},{ 3021, 3060},{ 3193, 3111}, - { 3396, 3147},{ 3573, 3184},{ 3752, 3220},{ 4038, 3255} - }, - /*Cb qi=47 INTER*/ - { - { 101, 0},{ 107, 339},{ 108, 667},{ 120, 1033}, - { 142, 1394},{ 175, 1729},{ 227, 2040},{ 295, 2335}, - { 369, 2619},{ 452, 2888},{ 556, 3138},{ 686, 3368}, - { 850, 3574},{ 1050, 3758},{ 1299, 3910},{ 1605, 4024}, - { 1950, 4104},{ 2317, 4163},{ 2689, 4210},{ 3077, 4239}, - { 3466, 4258},{ 3840, 4278},{ 4205, 4298},{ 4515, 4340} - } - }, - { - /*Cr qi=47 INTRA*/ - { - { 19, 7},{ 138, 392},{ 248, 758},{ 396, 1094}, - { 563, 1378},{ 723, 1621},{ 881, 1829},{ 1037, 2011}, - { 1214, 2165},{ 1410, 2290},{ 1623, 2393},{ 1834, 2480}, - { 2016, 2564},{ 2203, 2647},{ 2405, 2707},{ 2569, 2757}, - { 2709, 2810},{ 2871, 2860},{ 3027, 2924},{ 3178, 2980}, - { 3375, 3034},{ 3563, 3097},{ 3724, 3151},{ 3952, 3153} - }, - /*Cr qi=47 INTER*/ - { - { 91, 1},{ 100, 351},{ 102, 681},{ 120, 1043}, - { 144, 1397},{ 175, 1729},{ 219, 2049},{ 277, 2356}, - { 353, 2640},{ 451, 2902},{ 579, 3136},{ 739, 3342}, - { 926, 3525},{ 1125, 3698},{ 1343, 3859},{ 1595, 3998}, - { 1881, 4113},{ 2208, 4205},{ 2589, 4253},{ 3014, 4250}, - { 3444, 4220},{ 3838, 4183},{ 4196, 4147},{ 4521, 4116} - } - } - }, - { - { - /*Y' qi=48 INTRA*/ - { - { 107, 87},{ 681, 1200},{ 1456, 1883},{ 2306, 2193}, - { 3122, 2386},{ 3984, 2548},{ 4862, 2693},{ 5704, 2808}, - { 6495, 2899},{ 7232, 2970},{ 7915, 3018},{ 8524, 3034}, - { 9085, 3043},{ 9635, 3068},{10192, 3108},{10735, 3145}, - {11237, 3171},{11719, 3194},{12153, 3207},{12516, 3206}, - {12888, 3202},{13266, 3210},{13637, 3218},{14101, 3219} - }, - /*Y' qi=48 INTER*/ - { - { 83, -18},{ 147, 1328},{ 398, 2519},{ 923, 3468}, - { 1979, 4047},{ 3472, 4246},{ 4936, 4232},{ 6148, 4178}, - { 7150, 4139},{ 8007, 4111},{ 8765, 4091},{ 9458, 4076}, - {10090, 4063},{10676, 4054},{11226, 4045},{11742, 4038}, - {12223, 4033},{12686, 4029},{13127, 4022},{13527, 4015}, - {13915, 4012},{14277, 4007},{14619, 4004},{14966, 4001} - } - }, - { - /*Cb qi=48 INTRA*/ - { - { 11, 2},{ 134, 369},{ 245, 730},{ 373, 1075}, - { 531, 1374},{ 698, 1625},{ 865, 1839},{ 1033, 2019}, - { 1207, 2173},{ 1397, 2300},{ 1588, 2408},{ 1795, 2501}, - { 2003, 2581},{ 2187, 2666},{ 2362, 2757},{ 2548, 2841}, - { 2719, 2912},{ 2876, 2983},{ 3034, 3047},{ 3209, 3097}, - { 3409, 3137},{ 3589, 3178},{ 3762, 3216},{ 4004, 3252} - }, - /*Cb qi=48 INTER*/ - { - { 113, 26},{ 112, 344},{ 111, 668},{ 120, 1032}, - { 141, 1392},{ 173, 1727},{ 224, 2036},{ 290, 2330}, - { 363, 2612},{ 447, 2880},{ 551, 3130},{ 685, 3358}, - { 852, 3563},{ 1061, 3742},{ 1332, 3884},{ 1654, 3993}, - { 2011, 4068},{ 2394, 4120},{ 2782, 4160},{ 3172, 4186}, - { 3557, 4209},{ 3932, 4228},{ 4306, 4237},{ 4675, 4236} - } - }, - { - /*Cr qi=48 INTRA*/ - { - { 18, 7},{ 139, 389},{ 252, 755},{ 404, 1090}, - { 573, 1372},{ 732, 1615},{ 889, 1823},{ 1045, 2005}, - { 1222, 2159},{ 1417, 2285},{ 1631, 2387},{ 1843, 2474}, - { 2027, 2558},{ 2212, 2639},{ 2413, 2697},{ 2578, 2746}, - { 2720, 2798},{ 2887, 2852},{ 3040, 2913},{ 3181, 2970}, - { 3381, 3024},{ 3581, 3081},{ 3743, 3130},{ 3948, 3133} - }, - /*Cr qi=48 INTER*/ - { - { 89, 0},{ 106, 352},{ 105, 682},{ 120, 1044}, - { 144, 1395},{ 174, 1724},{ 215, 2044},{ 270, 2350}, - { 343, 2635},{ 441, 2895},{ 571, 3129},{ 735, 3334}, - { 926, 3518},{ 1139, 3684},{ 1371, 3836},{ 1628, 3977}, - { 1933, 4089},{ 2279, 4164},{ 2672, 4204},{ 3105, 4205}, - { 3533, 4176},{ 3931, 4135},{ 4290, 4089},{ 4624, 4057} - } - } - }, - { - { - /*Y' qi=49 INTRA*/ - { - { 120, 85},{ 706, 1194},{ 1485, 1875},{ 2348, 2187}, - { 3190, 2372},{ 4076, 2521},{ 4967, 2658},{ 5819, 2771}, - { 6611, 2861},{ 7345, 2936},{ 8026, 2990},{ 8626, 3013}, - { 9182, 3030},{ 9723, 3059},{10266, 3100},{10802, 3143}, - {11293, 3179},{11768, 3206},{12201, 3221},{12556, 3225}, - {12914, 3226},{13281, 3237},{13639, 3247},{14089, 3257} - }, - /*Y' qi=49 INTER*/ - { - { 72, -11},{ 155, 1320},{ 458, 2485},{ 1090, 3386}, - { 2284, 3907},{ 3835, 4075},{ 5272, 4064},{ 6449, 4026}, - { 7426, 4003},{ 8267, 3987},{ 9017, 3976},{ 9698, 3967}, - {10328, 3962},{10913, 3959},{11452, 3954},{11961, 3950}, - {12442, 3947},{12904, 3946},{13347, 3945},{13749, 3943}, - {14123, 3941},{14490, 3941},{14826, 3939},{15153, 3937} - } - }, - { - /*Cb qi=49 INTRA*/ - { - { 11, 2},{ 145, 369},{ 262, 729},{ 393, 1070}, - { 557, 1363},{ 731, 1607},{ 907, 1811},{ 1085, 1983}, - { 1268, 2130},{ 1465, 2251},{ 1658, 2359},{ 1868, 2454}, - { 2079, 2534},{ 2264, 2621},{ 2440, 2717},{ 2625, 2802}, - { 2792, 2878},{ 2945, 2954},{ 3106, 3021},{ 3277, 3075}, - { 3466, 3119},{ 3638, 3170},{ 3824, 3213},{ 4100, 3243} - }, - /*Cb qi=49 INTER*/ - { - { 98, -6},{ 113, 343},{ 110, 669},{ 122, 1029}, - { 149, 1380},{ 192, 1706},{ 258, 2007},{ 340, 2293}, - { 426, 2569},{ 525, 2831},{ 653, 3071},{ 814, 3287}, - { 1013, 3478},{ 1262, 3637},{ 1575, 3761},{ 1936, 3851}, - { 2328, 3910},{ 2741, 3949},{ 3163, 3970},{ 3559, 3994}, - { 3936, 4025},{ 4300, 4050},{ 4655, 4060},{ 4962, 4062} - } - }, - { - /*Cr qi=49 INTRA*/ - { - { 19, 7},{ 151, 389},{ 270, 753},{ 427, 1084}, - { 602, 1360},{ 767, 1595},{ 933, 1794},{ 1098, 1968}, - { 1285, 2115},{ 1489, 2237},{ 1699, 2342},{ 1912, 2435}, - { 2101, 2519},{ 2288, 2601},{ 2486, 2663},{ 2651, 2715}, - { 2799, 2769},{ 2958, 2825},{ 3106, 2890},{ 3257, 2948}, - { 3452, 3007},{ 3634, 3075},{ 3786, 3136},{ 3959, 3164} - }, - /*Cr qi=49 INTER*/ - { - { 85, 1},{ 103, 352},{ 104, 681},{ 121, 1039}, - { 152, 1382},{ 195, 1702},{ 248, 2015},{ 316, 2316}, - { 403, 2595},{ 520, 2847},{ 676, 3068},{ 870, 3258}, - { 1091, 3429},{ 1329, 3585},{ 1597, 3725},{ 1894, 3849}, - { 2242, 3940},{ 2656, 3984},{ 3098, 3992},{ 3531, 3981}, - { 3936, 3950},{ 4304, 3915},{ 4646, 3879},{ 4915, 3861} - } - } - }, - { - { - /*Y' qi=50 INTRA*/ - { - { 122, 89},{ 798, 1170},{ 1682, 1812},{ 2613, 2096}, - { 3501, 2260},{ 4430, 2388},{ 5352, 2510},{ 6228, 2613}, - { 7043, 2698},{ 7793, 2770},{ 8486, 2823},{ 9092, 2846}, - { 9652, 2865},{10210, 2895},{10773, 2936},{11315, 2979}, - {11817, 3014},{12297, 3041},{12734, 3057},{13097, 3064}, - {13443, 3067},{13813, 3078},{14190, 3088},{14646, 3103} - }, - /*Y' qi=50 INTER*/ - { - { 73, -11},{ 154, 1318},{ 501, 2457},{ 1281, 3291}, - { 2685, 3719},{ 4356, 3810},{ 5811, 3769},{ 6988, 3726}, - { 7976, 3700},{ 8835, 3682},{ 9606, 3669},{10307, 3659}, - {10953, 3652},{11556, 3645},{12115, 3643},{12641, 3640}, - {13138, 3636},{13613, 3634},{14068, 3629},{14488, 3627}, - {14876, 3625},{15237, 3621},{15585, 3623},{15922, 3629} - } - }, - { - /*Cb qi=50 INTRA*/ - { - { 11, 2},{ 148, 368},{ 278, 724},{ 431, 1052}, - { 613, 1334},{ 806, 1567},{ 1004, 1756},{ 1203, 1915}, - { 1405, 2051},{ 1621, 2163},{ 1833, 2262},{ 2059, 2347}, - { 2280, 2424},{ 2476, 2512},{ 2670, 2598},{ 2864, 2679}, - { 3037, 2754},{ 3201, 2826},{ 3376, 2887},{ 3562, 2936}, - { 3756, 2976},{ 3932, 3022},{ 4117, 3065},{ 4385, 3094} - }, - /*Cb qi=50 INTER*/ - { - { 92, -3},{ 112, 343},{ 109, 669},{ 121, 1027}, - { 149, 1375},{ 196, 1697},{ 270, 1992},{ 366, 2267}, - { 471, 2532},{ 594, 2782},{ 747, 3011},{ 942, 3212}, - { 1189, 3384},{ 1497, 3521},{ 1875, 3613},{ 2297, 3673}, - { 2739, 3710},{ 3195, 3725},{ 3644, 3737},{ 4057, 3751}, - { 4445, 3763},{ 4841, 3769},{ 5211, 3779},{ 5568, 3769} - } - }, - { - /*Cr qi=50 INTRA*/ - { - { 19, 7},{ 155, 388},{ 290, 744},{ 474, 1060}, - { 666, 1324},{ 847, 1549},{ 1033, 1737},{ 1219, 1898}, - { 1428, 2034},{ 1653, 2147},{ 1885, 2245},{ 2115, 2329}, - { 2316, 2410},{ 2517, 2486},{ 2730, 2539},{ 2901, 2586}, - { 3042, 2638},{ 3199, 2693},{ 3366, 2755},{ 3534, 2805}, - { 3738, 2858},{ 3934, 2916},{ 4079, 2975},{ 4257, 2992} - }, - /*Cr qi=50 INTER*/ - { - { 87, 1},{ 102, 353},{ 103, 680},{ 121, 1036}, - { 153, 1377},{ 199, 1694},{ 260, 1999},{ 339, 2291}, - { 446, 2559},{ 590, 2797},{ 780, 3003},{ 1010, 3176}, - { 1267, 3331},{ 1547, 3474},{ 1874, 3594},{ 2245, 3688}, - { 2666, 3742},{ 3130, 3758},{ 3594, 3748},{ 4028, 3711}, - { 4415, 3674},{ 4771, 3641},{ 5122, 3605},{ 5482, 3569} - } - } - }, - { - { - /*Y' qi=51 INTRA*/ - { - { 115, 93},{ 819, 1164},{ 1739, 1806},{ 2695, 2101}, - { 3612, 2257},{ 4552, 2374},{ 5479, 2490},{ 6352, 2593}, - { 7158, 2683},{ 7898, 2761},{ 8580, 2823},{ 9177, 2854}, - { 9728, 2880},{10268, 2917},{10816, 2966},{11350, 3016}, - {11834, 3058},{12311, 3089},{12741, 3109},{13092, 3119}, - {13434, 3126},{13791, 3142},{14156, 3155},{14590, 3171} - }, - /*Y' qi=51 INTER*/ - { - { 58, 0},{ 171, 1307},{ 610, 2407},{ 1563, 3175}, - { 3116, 3545},{ 4789, 3624},{ 6185, 3602},{ 7320, 3583}, - { 8282, 3574},{ 9124, 3569},{ 9878, 3567},{10569, 3565}, - {11207, 3563},{11801, 3564},{12359, 3566},{12884, 3567}, - {13373, 3568},{13841, 3567},{14289, 3566},{14699, 3568}, - {15086, 3568},{15446, 3566},{15788, 3564},{16103, 3568} - } - }, - { - /*Cb qi=51 INTRA*/ - { - { 14, 3},{ 161, 369},{ 297, 722},{ 454, 1047}, - { 639, 1325},{ 833, 1554},{ 1033, 1742},{ 1236, 1897}, - { 1440, 2032},{ 1653, 2148},{ 1860, 2253},{ 2077, 2347}, - { 2288, 2432},{ 2476, 2525},{ 2661, 2621},{ 2841, 2714}, - { 3010, 2797},{ 3170, 2876},{ 3333, 2945},{ 3510, 3000}, - { 3696, 3054},{ 3865, 3114},{ 4046, 3164},{ 4317, 3200} - }, - /*Cb qi=51 INTER*/ - { - { 88, -11},{ 109, 341},{ 109, 668},{ 126, 1019}, - { 168, 1358},{ 233, 1670},{ 329, 1955},{ 451, 2219}, - { 584, 2472},{ 736, 2711},{ 931, 2923},{ 1179, 3104}, - { 1480, 3254},{ 1846, 3368},{ 2265, 3448},{ 2714, 3501}, - { 3180, 3524},{ 3638, 3529},{ 4074, 3543},{ 4485, 3560}, - { 4868, 3571},{ 5238, 3581},{ 5597, 3594},{ 5953, 3591} - } - }, - { - /*Cr qi=51 INTRA*/ - { - { 24, 7},{ 168, 388},{ 309, 742},{ 496, 1054}, - { 688, 1316},{ 873, 1538},{ 1063, 1723},{ 1252, 1882}, - { 1460, 2018},{ 1682, 2134},{ 1907, 2238},{ 2125, 2332}, - { 2317, 2422},{ 2507, 2510},{ 2705, 2575},{ 2869, 2630}, - { 3015, 2684},{ 3178, 2744},{ 3329, 2815},{ 3477, 2878}, - { 3667, 2945},{ 3848, 3016},{ 3997, 3082},{ 4174, 3121} - }, - /*Cr qi=51 INTER*/ - { - { 83, -2},{ 102, 351},{ 102, 680},{ 126, 1029}, - { 172, 1359},{ 238, 1665},{ 321, 1962},{ 422, 2246}, - { 552, 2505},{ 733, 2728},{ 970, 2912},{ 1247, 3069}, - { 1552, 3209},{ 1876, 3338},{ 2251, 3440},{ 2692, 3502}, - { 3161, 3529},{ 3637, 3525},{ 4084, 3509},{ 4487, 3479}, - { 4850, 3444},{ 5181, 3419},{ 5507, 3406},{ 5786, 3398} - } - } - }, - { - { - /*Y' qi=52 INTRA*/ - { - { 117, 93},{ 814, 1168},{ 1729, 1822},{ 2706, 2119}, - { 3655, 2262},{ 4604, 2374},{ 5528, 2490},{ 6394, 2596}, - { 7189, 2691},{ 7921, 2777},{ 8596, 2846},{ 9184, 2885}, - { 9728, 2918},{10260, 2961},{10796, 3014},{11316, 3069}, - {11793, 3115},{12267, 3150},{12692, 3172},{13037, 3185}, - {13367, 3196},{13717, 3214},{14087, 3227},{14521, 3249} - }, - /*Y' qi=52 INTER*/ - { - { 52, 0},{ 169, 1308},{ 668, 2382},{ 1735, 3112}, - { 3384, 3451},{ 5077, 3519},{ 6461, 3506},{ 7587, 3496}, - { 8545, 3494},{ 9384, 3494},{10142, 3498},{10838, 3501}, - {11475, 3503},{12078, 3508},{12640, 3511},{13162, 3513}, - {13654, 3517},{14130, 3521},{14576, 3522},{14980, 3523}, - {15369, 3523},{15737, 3522},{16071, 3521},{16382, 3516} - } - }, - { - /*Cb qi=52 INTRA*/ - { - { 14, 3},{ 163, 369},{ 299, 722},{ 457, 1044}, - { 645, 1319},{ 843, 1545},{ 1050, 1728},{ 1261, 1879}, - { 1468, 2013},{ 1678, 2132},{ 1883, 2240},{ 2093, 2338}, - { 2301, 2428},{ 2488, 2523},{ 2667, 2619},{ 2843, 2718}, - { 3010, 2805},{ 3163, 2887},{ 3323, 2963},{ 3490, 3028}, - { 3665, 3087},{ 3841, 3145},{ 4011, 3197},{ 4289, 3230} - }, - /*Cb qi=52 INTER*/ - { - { 98, -7},{ 109, 342},{ 109, 668},{ 126, 1018}, - { 170, 1355},{ 242, 1663},{ 352, 1941},{ 490, 2195}, - { 642, 2439},{ 823, 2666},{ 1052, 2868},{ 1333, 3039}, - { 1670, 3178},{ 2074, 3280},{ 2524, 3348},{ 2996, 3390}, - { 3469, 3410},{ 3923, 3420},{ 4355, 3434},{ 4771, 3451}, - { 5166, 3468},{ 5532, 3483},{ 5885, 3499},{ 6263, 3501} - } - }, - { - /*Cr qi=52 INTRA*/ - { - { 25, 7},{ 170, 388},{ 312, 741},{ 500, 1051}, - { 694, 1310},{ 883, 1529},{ 1082, 1709},{ 1280, 1864}, - { 1491, 1998},{ 1710, 2117},{ 1932, 2225},{ 2143, 2324}, - { 2328, 2418},{ 2516, 2506},{ 2708, 2578},{ 2870, 2637}, - { 3017, 2693},{ 3170, 2758},{ 3312, 2835},{ 3455, 2901}, - { 3644, 2972},{ 3827, 3049},{ 3968, 3121},{ 4115, 3166} - }, - /*Cr qi=52 INTER*/ - { - { 86, -2},{ 101, 352},{ 100, 680},{ 126, 1028}, - { 175, 1356},{ 247, 1657},{ 341, 1948},{ 458, 2224}, - { 615, 2471},{ 828, 2681},{ 1091, 2857},{ 1395, 3008}, - { 1732, 3140},{ 2095, 3257},{ 2502, 3348},{ 2968, 3402}, - { 3457, 3420},{ 3926, 3413},{ 4360, 3388},{ 4759, 3357}, - { 5128, 3329},{ 5449, 3306},{ 5741, 3295},{ 6071, 3296} - } - } - }, - { - { - /*Y' qi=53 INTRA*/ - { - { 138, 93},{ 850, 1161},{ 1773, 1810},{ 2763, 2103}, - { 3722, 2245},{ 4675, 2360},{ 5600, 2483},{ 6464, 2597}, - { 7255, 2700},{ 7982, 2792},{ 8652, 2867},{ 9237, 2913}, - { 9775, 2950},{10302, 2998},{10834, 3058},{11347, 3121}, - {11826, 3169},{12299, 3207},{12713, 3235},{13054, 3250}, - {13387, 3265},{13744, 3286},{14110, 3302},{14515, 3323} - }, - /*Y' qi=53 INTER*/ - { - { 52, 2},{ 169, 1308},{ 680, 2377},{ 1763, 3103}, - { 3410, 3450},{ 5094, 3531},{ 6469, 3526},{ 7590, 3525}, - { 8547, 3530},{ 9385, 3534},{10139, 3540},{10835, 3548}, - {11479, 3553},{12075, 3559},{12634, 3565},{13159, 3570}, - {13650, 3573},{14124, 3576},{14575, 3580},{14993, 3583}, - {15375, 3584},{15744, 3584},{16091, 3583},{16421, 3586} - } - }, - { - /*Cb qi=53 INTRA*/ - { - { 14, 3},{ 167, 367},{ 317, 717},{ 492, 1033}, - { 687, 1306},{ 887, 1531},{ 1095, 1715},{ 1309, 1866}, - { 1517, 2000},{ 1729, 2119},{ 1932, 2227},{ 2146, 2325}, - { 2358, 2414},{ 2544, 2511},{ 2724, 2611},{ 2902, 2711}, - { 3070, 2800},{ 3227, 2878},{ 3381, 2954},{ 3548, 3021}, - { 3724, 3077},{ 3888, 3140},{ 4065, 3196},{ 4359, 3225} - }, - /*Cb qi=53 INTER*/ - { - { 93, -8},{ 110, 342},{ 108, 668},{ 125, 1018}, - { 170, 1355},{ 242, 1663},{ 353, 1939},{ 494, 2192}, - { 651, 2433},{ 838, 2658},{ 1076, 2856},{ 1368, 3022}, - { 1716, 3158},{ 2123, 3260},{ 2575, 3330},{ 3042, 3373}, - { 3507, 3396},{ 3962, 3413},{ 4394, 3430},{ 4797, 3452}, - { 5169, 3476},{ 5547, 3496},{ 5914, 3510},{ 6235, 3525} - } - }, - { - /*Cr qi=53 INTRA*/ - { - { 25, 7},{ 175, 386},{ 335, 734},{ 541, 1037}, - { 737, 1296},{ 926, 1516},{ 1125, 1696},{ 1324, 1851}, - { 1540, 1984},{ 1763, 2102},{ 1989, 2210},{ 2202, 2310}, - { 2386, 2404},{ 2572, 2495},{ 2768, 2569},{ 2929, 2627}, - { 3071, 2684},{ 3231, 2749},{ 3374, 2825},{ 3514, 2894}, - { 3703, 2963},{ 3882, 3040},{ 4024, 3111},{ 4190, 3150} - }, - /*Cr qi=53 INTER*/ - { - { 87, -1},{ 99, 352},{ 100, 680},{ 125, 1027}, - { 175, 1355},{ 249, 1657},{ 343, 1946},{ 462, 2220}, - { 624, 2465},{ 844, 2671},{ 1122, 2841},{ 1435, 2989}, - { 1768, 3125},{ 2134, 3243},{ 2545, 3334},{ 3002, 3393}, - { 3490, 3412},{ 3965, 3405},{ 4401, 3384},{ 4797, 3359}, - { 5156, 3328},{ 5482, 3297},{ 5800, 3292},{ 6135, 3293} + { 39, -33},{ 48, 403},{ 86, 744},{ 110, 1101}, + { 134, 1461},{ 165, 1779},{ 205, 2095},{ 259, 2401}, + { 318, 2686},{ 386, 2958},{ 481, 3204},{ 610, 3415}, + { 753, 3603},{ 908, 3780},{ 1055, 3959},{ 1220, 4132}, + { 1422, 4281},{ 1656, 4419},{ 1939, 4512},{ 2259, 4574}, + { 2593, 4593},{ 2950, 4569},{ 3339, 4505},{ 3542, 4497} } } }, @@ -3406,557 +403,563 @@ oc_mode_rd OC_MODE_RD[64][3][2][OC_SAD_BINS]={ { /*Y' qi=54 INTRA*/ { - { 184, 94},{ 902, 1151},{ 1876, 1776},{ 2881, 2057}, - { 3832, 2200},{ 4785, 2315},{ 5709, 2442},{ 6570, 2562}, - { 7362, 2672},{ 8092, 2771},{ 8760, 2852},{ 9337, 2901}, - { 9874, 2943},{10402, 2995},{10928, 3059},{11443, 3126}, - {11926, 3178},{12396, 3220},{12805, 3251},{13139, 3266}, - {13466, 3280},{13822, 3304},{14184, 3322},{14585, 3342} + { 339, 30},{ 785, 1251},{ 2395, 1971},{ 4075, 2063}, + { 4924, 2135},{ 5806, 2270},{ 6604, 2372},{ 7224, 2497}, + { 7879, 2608},{ 8400, 2729},{ 8951, 2829},{ 9379, 2864}, + { 9782, 2955},{10230, 3020},{10704, 3132},{11264, 3272}, + {11618, 3284},{12034, 3394},{12500, 3482},{12767, 3484}, + {13162, 3580},{13552, 3565},{13997, 3732},{14320, 3715} }, /*Y' qi=54 INTER*/ { - { 60, 5},{ 169, 1308},{ 683, 2375},{ 1791, 3090}, - { 3478, 3412},{ 5184, 3470},{ 6568, 3455},{ 7697, 3446}, - { 8659, 3446},{ 9503, 3447},{10266, 3450},{10971, 3454}, - {11619, 3458},{12223, 3462},{12789, 3467},{13315, 3471}, - {13811, 3475},{14291, 3479},{14743, 3479},{15148, 3481}, - {15535, 3483},{15913, 3481},{16252, 3479},{16569, 3472} + { 65, 95},{ 269, 1312},{ 1152, 2242},{ 2336, 2863}, + { 3728, 3239},{ 4944, 3439},{ 6034, 3543},{ 7064, 3580}, + { 7991, 3586},{ 8849, 3568},{ 9605, 3561},{10306, 3550}, + {10919, 3544},{11466, 3530},{11972, 3528},{12401, 3536}, + {12818, 3511},{13185, 3522},{13523, 3505},{13827, 3505}, + {14114, 3522},{14395, 3521},{14625, 3533},{14909, 3532} } }, { /*Cb qi=54 INTRA*/ { - { 13, 2},{ 165, 367},{ 318, 715},{ 498, 1030}, - { 698, 1301},{ 906, 1523},{ 1121, 1703},{ 1336, 1853}, - { 1549, 1984},{ 1765, 2100},{ 1974, 2207},{ 2192, 2306}, - { 2402, 2396},{ 2587, 2493},{ 2773, 2591},{ 2953, 2691}, - { 3119, 2778},{ 3277, 2858},{ 3430, 2940},{ 3603, 3004}, - { 3788, 3059},{ 3950, 3121},{ 4128, 3173},{ 4398, 3215} + { 148, -3},{ 218, 480},{ 351, 787},{ 437, 1069}, + { 550, 1350},{ 730, 1592},{ 931, 1784},{ 1243, 1884}, + { 1499, 1984},{ 1680, 2115},{ 1864, 2244},{ 2062, 2334}, + { 2278, 2407},{ 2442, 2496},{ 2602, 2603},{ 2783, 2686}, + { 2928, 2771},{ 3073, 2856},{ 3207, 2938},{ 3368, 2998}, + { 3516, 3077},{ 3699, 3122},{ 3818, 3202},{ 3939, 3230} }, /*Cb qi=54 INTER*/ { - { 100, -3},{ 109, 343},{ 107, 668},{ 125, 1018}, - { 169, 1354},{ 241, 1662},{ 353, 1938},{ 496, 2190}, - { 655, 2431},{ 843, 2655},{ 1082, 2851},{ 1381, 3015}, - { 1739, 3146},{ 2154, 3243},{ 2610, 3310},{ 3094, 3344}, - { 3581, 3358},{ 4034, 3371},{ 4457, 3384},{ 4867, 3399}, - { 5255, 3413},{ 5630, 3425},{ 6003, 3440},{ 6346, 3440} + { 48, -11},{ 54, 407},{ 86, 743},{ 122, 1083}, + { 176, 1400},{ 241, 1699},{ 347, 1968},{ 496, 2208}, + { 664, 2431},{ 863, 2637},{ 1120, 2816},{ 1442, 2961}, + { 1835, 3066},{ 2261, 3140},{ 2676, 3203},{ 3092, 3245}, + { 3480, 3266},{ 3862, 3286},{ 4254, 3305},{ 4604, 3316}, + { 4989, 3335},{ 5306, 3351},{ 5654, 3339},{ 5855, 3345} } }, { /*Cr qi=54 INTRA*/ { - { 23, 7},{ 174, 386},{ 338, 732},{ 549, 1034}, - { 751, 1289},{ 947, 1506},{ 1150, 1685},{ 1353, 1837}, - { 1572, 1969},{ 1800, 2087},{ 2031, 2192},{ 2248, 2291}, - { 2434, 2387},{ 2622, 2477},{ 2815, 2549},{ 2976, 2607}, - { 3126, 2663},{ 3286, 2727},{ 3427, 2807},{ 3569, 2877}, - { 3761, 2941},{ 3942, 3016},{ 4084, 3093},{ 4226, 3131} + { 137, 10},{ 212, 492},{ 315, 795},{ 470, 1061}, + { 612, 1333},{ 821, 1539},{ 1105, 1680},{ 1335, 1811}, + { 1566, 1927},{ 1773, 2038},{ 1973, 2153},{ 2148, 2259}, + { 2311, 2352},{ 2474, 2460},{ 2647, 2516},{ 2810, 2607}, + { 2928, 2638},{ 3085, 2742},{ 3232, 2815},{ 3348, 2899}, + { 3533, 2993},{ 3679, 3029},{ 3803, 3138},{ 3925, 3170} }, /*Cr qi=54 INTER*/ { - { 88, -2},{ 99, 351},{ 100, 680},{ 125, 1027}, - { 175, 1354},{ 248, 1656},{ 343, 1945},{ 463, 2219}, - { 626, 2463},{ 850, 2668},{ 1128, 2837},{ 1445, 2983}, - { 1791, 3111},{ 2168, 3224},{ 2597, 3309},{ 3075, 3351}, - { 3560, 3364},{ 4029, 3356},{ 4464, 3335},{ 4858, 3307}, - { 5218, 3275},{ 5547, 3256},{ 5850, 3247},{ 6171, 3214} + { 46, 2},{ 47, 419},{ 87, 746},{ 125, 1083}, + { 177, 1401},{ 249, 1687},{ 342, 1964},{ 453, 2226}, + { 627, 2454},{ 869, 2641},{ 1152, 2800},{ 1455, 2942}, + { 1776, 3077},{ 2135, 3187},{ 2524, 3287},{ 2984, 3325}, + { 3425, 3344},{ 3881, 3328},{ 4313, 3274},{ 4701, 3218}, + { 5027, 3171},{ 5299, 3130},{ 5597, 3107},{ 5791, 3120} } } }, { { - /*Y' qi=55 INTRA*/ - { - { 178, 95},{ 968, 1137},{ 2000, 1747},{ 3013, 2027}, - { 3966, 2173},{ 4920, 2294},{ 5842, 2427},{ 6702, 2553}, - { 7489, 2668},{ 8213, 2773},{ 8875, 2858},{ 9452, 2913}, - { 9986, 2959},{10504, 3016},{11023, 3085},{11530, 3157}, - {12011, 3213},{12480, 3257},{12882, 3291},{13214, 3310}, - {13542, 3325},{13890, 3350},{14248, 3371},{14671, 3398} + /*Y' qi=63 INTRA*/ + { + { -86, 167},{ 2070, 1104},{ 5138, 1428},{ 7014, 1535}, + { 8430, 1629},{ 9663, 1690},{10576, 1745},{11277, 1809}, + {12003, 1869},{12663, 1925},{13258, 1983},{13701, 2016}, + {14228, 2073},{14756, 2088},{15203, 2164},{15993, 2175}, + {16378, 2256},{16917, 2240},{17361, 2332},{17782, 2312}, + {18376, 2381},{18728, 2362},{19224, 2408},{19705, 2392} }, - /*Y' qi=55 INTER*/ - { - { 59, 5},{ 170, 1307},{ 725, 2358},{ 1886, 3058}, - { 3589, 3385},{ 5284, 3459},{ 6654, 3458},{ 7771, 3461}, - { 8727, 3470},{ 9564, 3478},{10322, 3488},{11019, 3497}, - {11658, 3505},{12258, 3513},{12819, 3520},{13344, 3527}, - {13840, 3533},{14314, 3537},{14755, 3541},{15161, 3544}, - {15552, 3548},{15916, 3548},{16257, 3548},{16576, 3540} + /*Y' qi=63 INTER*/ + { + { -529, 154},{ 967, 1233},{ 4201, 1610},{ 6285, 1800}, + { 8058, 1908},{ 9439, 1968},{10737, 1987},{11999, 1979}, + {13003, 1972},{13854, 1963},{14584, 1965},{15217, 1955}, + {15773, 1956},{16229, 1949},{16735, 1952},{17085, 1956}, + {17508, 1956},{17821, 1961},{18191, 1961},{18465, 1982}, + {18792, 1975},{19158, 1995},{19378, 2010},{19817, 2021} } }, { - /*Cb qi=55 INTRA*/ - { - { 13, 2},{ 167, 366},{ 322, 714},{ 508, 1026}, - { 716, 1292},{ 930, 1511},{ 1148, 1690},{ 1366, 1839}, - { 1578, 1972},{ 1793, 2090},{ 2001, 2199},{ 2217, 2300}, - { 2427, 2393},{ 2609, 2495},{ 2784, 2600},{ 2961, 2704}, - { 3121, 2797},{ 3268, 2884},{ 3423, 2965},{ 3590, 3032}, - { 3764, 3096},{ 3926, 3165},{ 4101, 3223},{ 4405, 3258} + /*Cb qi=63 INTRA*/ + { + { 136, 4},{ 338, 438},{ 593, 730},{ 835, 974}, + { 1168, 1188},{ 1602, 1345},{ 2004, 1467},{ 2465, 1505}, + { 2799, 1574},{ 3091, 1669},{ 3384, 1758},{ 3673, 1817}, + { 3950, 1861},{ 4190, 1924},{ 4444, 1993},{ 4701, 2051}, + { 4915, 2123},{ 5119, 2166},{ 5329, 2231},{ 5576, 2259}, + { 5793, 2310},{ 6001, 2334},{ 6198, 2384},{ 6344, 2401} }, - /*Cb qi=55 INTER*/ - { - { 90, -4},{ 109, 344},{ 107, 668},{ 126, 1017}, - { 172, 1351},{ 249, 1657},{ 370, 1928},{ 527, 2174}, - { 702, 2407},{ 909, 2624},{ 1170, 2814},{ 1493, 2970}, - { 1869, 3097},{ 2292, 3192},{ 2752, 3258},{ 3232, 3295}, - { 3709, 3314},{ 4156, 3335},{ 4592, 3355},{ 5004, 3373}, - { 5377, 3389},{ 5737, 3411},{ 6092, 3432},{ 6473, 3423} + /*Cb qi=63 INTER*/ + { + { 49, 4},{ 51, 403},{ 98, 729},{ 185, 1034}, + { 352, 1304},{ 622, 1533},{ 1068, 1696},{ 1604, 1821}, + { 2203, 1924},{ 2890, 1988},{ 3622, 2017},{ 4359, 2019}, + { 5025, 2005},{ 5586, 2002},{ 6090, 1989},{ 6519, 1977}, + { 6927, 1977},{ 7305, 1968},{ 7730, 1984},{ 8087, 1981}, + { 8435, 1991},{ 8822, 1987},{ 9155, 2008},{ 9392, 2011} } }, { - /*Cr qi=55 INTRA*/ - { - { 23, 7},{ 175, 385},{ 342, 730},{ 561, 1028}, - { 771, 1279},{ 973, 1493},{ 1181, 1669},{ 1384, 1822}, - { 1602, 1956},{ 1830, 2076},{ 2057, 2184},{ 2270, 2288}, - { 2452, 2389},{ 2637, 2484},{ 2823, 2559},{ 2983, 2621}, - { 3129, 2682},{ 3280, 2753},{ 3417, 2833},{ 3554, 2904}, - { 3743, 2977},{ 3921, 3060},{ 4055, 3137},{ 4185, 3186} + /*Cr qi=63 INTRA*/ + { + { 131, 11},{ 334, 448},{ 569, 739},{ 929, 946}, + { 1285, 1145},{ 1718, 1274},{ 2176, 1343},{ 2531, 1424}, + { 2866, 1504},{ 3176, 1580},{ 3475, 1657},{ 3736, 1728}, + { 3962, 1807},{ 4232, 1872},{ 4425, 1921},{ 4657, 1976}, + { 4817, 2009},{ 5063, 2082},{ 5281, 2129},{ 5480, 2199}, + { 5743, 2258},{ 5887, 2283},{ 6124, 2358},{ 6273, 2378} }, - /*Cr qi=55 INTER*/ - { - { 85, 0},{ 99, 352},{ 100, 679},{ 126, 1025}, - { 178, 1351},{ 256, 1650},{ 359, 1935},{ 493, 2202}, - { 675, 2439},{ 921, 2636},{ 1220, 2799},{ 1552, 2941}, - { 1910, 3068},{ 2303, 3177},{ 2735, 3262},{ 3206, 3311}, - { 3689, 3333},{ 4152, 3327},{ 4588, 3299},{ 4978, 3272}, - { 5325, 3243},{ 5651, 3221},{ 5969, 3210},{ 6218, 3185} + /*Cr qi=63 INTER*/ + { + { 47, 15},{ 40, 405},{ 100, 730},{ 189, 1037}, + { 351, 1303},{ 625, 1526},{ 984, 1719},{ 1512, 1862}, + { 2189, 1947},{ 2895, 2003},{ 3576, 2046},{ 4249, 2072}, + { 4901, 2068},{ 5514, 2043},{ 6079, 2009},{ 6528, 1977}, + { 6927, 1940},{ 7274, 1915},{ 7580, 1894},{ 7910, 1910}, + { 8211, 1902},{ 8472, 1920},{ 8742, 1926},{ 8981, 1930} } } - }, + } +}; + +# if !defined(OC_COLLECT_METRICS) +static const +# endif +oc_mode_rd OC_MODE_RD_SAD[OC_LOGQ_BINS][3][2][OC_COMP_BINS]={ { { - /*Y' qi=56 INTRA*/ - { - { 137, 104},{ 1048, 1128},{ 2147, 1760},{ 3261, 2029}, - { 4319, 2131},{ 5310, 2234},{ 6245, 2351},{ 7101, 2464}, - { 7886, 2572},{ 8610, 2675},{ 9270, 2762},{ 9840, 2818}, - {10365, 2869},{10875, 2928},{11393, 2997},{11900, 3071}, - {12371, 3128},{12834, 3172},{13233, 3208},{13562, 3228}, - {13878, 3245},{14221, 3271},{14584, 3292},{15008, 3320} + /*Y' qi=0 INTRA*/ + { + { 33, 122},{ 57, 1297},{ 13, 2226},{ 157, 3890}, + { 227, 3682},{ 169, 3084},{ 197, 2700},{ 227, 3238}, + { 290, 4294},{ 354, 5230},{ 406, 5615},{ 417, 5322}, + { 452, 5462},{ 455, 5683},{ 493, 5938},{ 553, 6374}, + { 558, 6464},{ 606, 6493},{ 616, 6417},{ 643, 6557}, + { 641, 6664},{ 716, 7285},{ 748, 7518},{ 747, 7502} }, - /*Y' qi=56 INTER*/ - { - { 19, 21},{ 207, 1292},{ 1031, 2252},{ 2553, 2846}, - { 4463, 3085},{ 6137, 3131},{ 7441, 3151},{ 8526, 3172}, - { 9468, 3193},{10301, 3209},{11059, 3224},{11760, 3237}, - {12405, 3249},{13008, 3261},{13570, 3270},{14100, 3278}, - {14597, 3284},{15074, 3289},{15524, 3297},{15929, 3302}, - {16314, 3306},{16675, 3307},{17004, 3305},{17288, 3301} + /*Y' qi=0 INTER*/ + { + { 16, 205},{ 5, 1338},{ 16, 2554},{ 6, 3809}, + { 9, 5188},{ 58, 6446},{ 76, 7561},{ 95, 8648}, + { 124, 9713},{ 158,10787},{ 193,11887},{ 233,12991}, + { 270,14116},{ 307,15236},{ 341,16346},{ 372,17426}, + { 398,18499},{ 422,19594},{ 448,20669},{ 479,21732}, + { 526,22720},{ 583,23572},{ 655,24516},{ 758,24647} } }, { - /*Cb qi=56 INTRA*/ - { - { 16, 3},{ 188, 367},{ 353, 712},{ 546, 1017}, - { 765, 1275},{ 989, 1484},{ 1221, 1653},{ 1459, 1791}, - { 1681, 1920},{ 1893, 2046},{ 2102, 2160},{ 2323, 2257}, - { 2534, 2347},{ 2720, 2447},{ 2902, 2549},{ 3075, 2654}, - { 3239, 2749},{ 3392, 2835},{ 3544, 2920},{ 3712, 2988}, - { 3882, 3052},{ 4052, 3123},{ 4227, 3181},{ 4483, 3213} + /*Cb qi=0 INTRA*/ + { + { 26, 40},{ 23, 589},{ 27, 784},{ 27, 1079}, + { 24, 1186},{ 25, 1641},{ 25, 1915},{ 29, 2207}, + { 39, 2361},{ 39, 2746},{ 32, 3020},{ 16, 3387}, + { 31, 3604},{ 36, 4076},{ 69, 4426},{ 102, 4724}, + { 139, 4923},{ 196, 5061},{ 211, 5103},{ 214, 5063}, + { 161, 4466},{ 208, 4793},{ 218, 4537},{ 219, 4539} }, - /*Cb qi=56 INTER*/ - { - { 92, -1},{ 111, 343},{ 114, 665},{ 148, 1003}, - { 224, 1321},{ 345, 1609},{ 526, 1858},{ 754, 2077}, - { 1009, 2281},{ 1319, 2464},{ 1702, 2614},{ 2145, 2732}, - { 2625, 2824},{ 3123, 2890},{ 3634, 2933},{ 4137, 2954}, - { 4614, 2965},{ 5052, 2988},{ 5468, 3015},{ 5852, 3035}, - { 6213, 3060},{ 6557, 3081},{ 6906, 3094},{ 7243, 3112} + /*Cb qi=0 INTER*/ + { + { 3, 164},{ 1, 535},{ 1, 779},{ 2, 1048}, + { 3, 1267},{ 1, 1625},{ 2, 1921},{ 5, 2224}, + { 8, 2481},{ 8, 2813},{ 4, 3089},{ -2, 3386}, + { -9, 3642},{ -14, 3993},{ -11, 4300},{ -6, 4628}, + { 4, 4929},{ 25, 5299},{ 44, 5623},{ 83, 5915}, + { 93, 6186},{ 91, 6483},{ 90, 6775},{ 95, 6952} } }, { - /*Cr qi=56 INTRA*/ - { - { 28, 8},{ 195, 385},{ 373, 727},{ 598, 1019}, - { 816, 1263},{ 1033, 1465},{ 1260, 1630},{ 1482, 1773}, - { 1717, 1900},{ 1949, 2018},{ 2178, 2128},{ 2393, 2233}, - { 2570, 2338},{ 2749, 2435},{ 2937, 2514},{ 3097, 2577}, - { 3240, 2638},{ 3398, 2709},{ 3540, 2791},{ 3673, 2865}, - { 3869, 2938},{ 4049, 3019},{ 4179, 3095},{ 4330, 3137} + /*Cr qi=0 INTRA*/ + { + { 22, 49},{ 26, 579},{ 23, 762},{ 15, 1050}, + { 20, 1191},{ 24, 1608},{ 26, 1875},{ 35, 2173}, + { 39, 2359},{ 30, 2736},{ 16, 2987},{ 0, 3334}, + { 14, 3625},{ 11, 4095},{ 57, 4512},{ 95, 4793}, + { 141, 4949},{ 206, 5242},{ 230, 5191},{ 242, 5177}, + { 178, 4775},{ 237, 5010},{ 223, 4656},{ 224, 4657} }, - /*Cr qi=56 INTER*/ - { - { 83, 0},{ 99, 353},{ 103, 676},{ 146, 1010}, - { 232, 1320},{ 355, 1601},{ 512, 1866},{ 713, 2109}, - { 988, 2312},{ 1344, 2471},{ 1750, 2602},{ 2180, 2719}, - { 2642, 2819},{ 3141, 2892},{ 3653, 2939},{ 4159, 2961}, - { 4636, 2961},{ 5072, 2945},{ 5464, 2917},{ 5813, 2895}, - { 6134, 2890},{ 6458, 2883},{ 6735, 2881},{ 6953, 2902} + /*Cr qi=0 INTER*/ + { + { 3, 163},{ 1, 536},{ 1, 773},{ 3, 1023}, + { 2, 1225},{ 1, 1607},{ 1, 1900},{ 5, 2204}, + { 9, 2453},{ 8, 2781},{ 3, 3049},{ -5, 3338}, + { -13, 3570},{ -17, 3950},{ -13, 4255},{ -6, 4596}, + { 7, 4893},{ 33, 5300},{ 53, 5632},{ 97, 5942}, + { 103, 6216},{ 96, 6522},{ 91, 6849},{ 98, 6995} } } }, { { - /*Y' qi=57 INTRA*/ - { - { 170, 106},{ 1106, 1120},{ 2246, 1740},{ 3399, 1993}, - { 4482, 2077},{ 5492, 2167},{ 6446, 2273},{ 7324, 2379}, - { 8130, 2482},{ 8866, 2578},{ 9537, 2661},{10119, 2715}, - {10646, 2762},{11161, 2820},{11694, 2886},{12214, 2957}, - {12693, 3013},{13166, 3053},{13569, 3087},{13897, 3106}, - {14224, 3122},{14568, 3148},{14931, 3167},{15390, 3192} + /*Y' qi=9 INTRA*/ + { + { 47, 152},{ 50, 1213},{ 144, 2543},{ 242, 2332}, + { 210, 1894},{ 250, 2386},{ 328, 3094},{ 407, 3419}, + { 464, 3507},{ 522, 3770},{ 613, 4194},{ 657, 4618}, + { 753, 5137},{ 796, 5248},{ 842, 5110},{ 927, 5330}, + { 994, 5487},{ 1008, 5463},{ 1101, 5794},{ 1169, 5966}, + { 1208, 6121},{ 1331, 6447},{ 1445, 6618},{ 1449, 6616} }, - /*Y' qi=57 INTER*/ - { - { 19, 20},{ 205, 1292},{ 1096, 2229},{ 2775, 2766}, - { 4811, 2943},{ 6512, 2964},{ 7832, 2976},{ 8940, 2990}, - { 9903, 3004},{10755, 3017},{11532, 3029},{12243, 3039}, - {12891, 3047},{13502, 3058},{14073, 3065},{14603, 3071}, - {15097, 3078},{15581, 3083},{16036, 3086},{16452, 3090}, - {16855, 3093},{17222, 3094},{17552, 3092},{17851, 3098} + /*Y' qi=9 INTER*/ + { + { 4, 218},{ 16, 1314},{ 4, 2563},{ 37, 3882}, + { 83, 5058},{ 109, 6184},{ 161, 7292},{ 224, 8389}, + { 287, 9485},{ 349,10565},{ 411,11608},{ 464,12648}, + { 518,13664},{ 575,14650},{ 649,15585},{ 742,16451}, + { 862,17214},{ 1003,17860},{ 1179,18325},{ 1372,18648}, + { 1576,18878},{ 1795,18903},{ 2040,18880},{ 2116,18759} } }, { - /*Cb qi=57 INTRA*/ - { - { 16, 3},{ 197, 365},{ 384, 704},{ 603, 1001}, - { 837, 1252},{ 1077, 1455},{ 1326, 1618},{ 1581, 1748}, - { 1819, 1871},{ 2042, 1993},{ 2264, 2104},{ 2500, 2196}, - { 2722, 2280},{ 2916, 2375},{ 3103, 2473},{ 3290, 2575}, - { 3456, 2667},{ 3612, 2748},{ 3775, 2829},{ 3958, 2896}, - { 4145, 2947},{ 4307, 3012},{ 4476, 3070},{ 4733, 3110} + /*Cb qi=9 INTRA*/ + { + { 27, 42},{ 23, 587},{ 34, 782},{ 37, 1079}, + { 34, 1204},{ 42, 1630},{ 37, 1887},{ 25, 2210}, + { 40, 2455},{ 71, 2880},{ 112, 3193},{ 156, 3427}, + { 168, 3403},{ 217, 3488},{ 203, 3335},{ 224, 3200}, + { 191, 2742},{ 195, 2810},{ 207, 2665},{ 201, 2661}, + { 169, 2078},{ 211, 2720},{ 226, 2813},{ 228, 2824} }, - /*Cb qi=57 INTER*/ - { - { 94, -1},{ 111, 344},{ 112, 665},{ 147, 1002}, - { 227, 1319},{ 353, 1604},{ 543, 1849},{ 785, 2062}, - { 1066, 2257},{ 1408, 2430},{ 1827, 2568},{ 2320, 2670}, - { 2848, 2743},{ 3386, 2791},{ 3934, 2812},{ 4453, 2820}, - { 4929, 2830},{ 5368, 2842},{ 5787, 2856},{ 6190, 2875}, - { 6554, 2896},{ 6895, 2913},{ 7229, 2927},{ 7572, 2932} + /*Cb qi=9 INTER*/ + { + { 4, 158},{ 2, 537},{ 3, 779},{ 2, 1045}, + { 3, 1284},{ 7, 1629},{ 7, 1917},{ 1, 2218}, + { -4, 2497},{ -3, 2845},{ 6, 3162},{ 23, 3482}, + { 42, 3788},{ 62, 4116},{ 76, 4416},{ 84, 4700}, + { 91, 4975},{ 95, 5259},{ 97, 5518},{ 94, 5790}, + { 99, 6052},{ 111, 6311},{ 126, 6601},{ 136, 6719} } }, { - /*Cr qi=57 INTRA*/ - { - { 28, 8},{ 207, 383},{ 413, 716},{ 661, 999}, - { 889, 1237},{ 1123, 1433},{ 1365, 1592},{ 1603, 1731}, - { 1853, 1852},{ 2103, 1965},{ 2345, 2072},{ 2571, 2173}, - { 2763, 2271},{ 2949, 2364},{ 3146, 2438},{ 3315, 2497}, - { 3459, 2552},{ 3618, 2616},{ 3767, 2697},{ 3906, 2773}, - { 4099, 2841},{ 4281, 2916},{ 4429, 2987},{ 4569, 3030} + /*Cr qi=9 INTRA*/ + { + { 25, 50},{ 32, 576},{ 32, 762},{ 21, 1049}, + { 28, 1207},{ 41, 1603},{ 36, 1839},{ 26, 2170}, + { 34, 2462},{ 59, 2872},{ 109, 3176},{ 157, 3364}, + { 188, 3397},{ 231, 3418},{ 250, 3341},{ 261, 3228}, + { 222, 2814},{ 258, 3091},{ 234, 2915},{ 228, 3042}, + { 210, 2610},{ 273, 3210},{ 274, 3231},{ 276, 3239} }, - /*Cr qi=57 INTER*/ - { - { 85, 0},{ 99, 352},{ 102, 675},{ 147, 1008}, - { 235, 1317},{ 363, 1597},{ 529, 1858},{ 748, 2094}, - { 1050, 2287},{ 1439, 2436},{ 1877, 2557},{ 2352, 2660}, - { 2869, 2740},{ 3413, 2791},{ 3962, 2815},{ 4485, 2819}, - { 4955, 2816},{ 5382, 2800},{ 5769, 2772},{ 6107, 2748}, - { 6443, 2740},{ 6754, 2739},{ 7029, 2737},{ 7284, 2745} + /*Cr qi=9 INTER*/ + { + { 4, 156},{ 2, 538},{ 3, 772},{ 2, 1028}, + { 3, 1254},{ 7, 1613},{ 7, 1893},{ 0, 2191}, + { -8, 2454},{ -4, 2811},{ 7, 3121},{ 27, 3442}, + { 48, 3749},{ 72, 4101},{ 88, 4410},{ 91, 4698}, + { 99, 4988},{ 99, 5279},{ 101, 5542},{ 95, 5813}, + { 99, 6088},{ 114, 6367},{ 125, 6683},{ 137, 6761} } } }, { { - /*Y' qi=58 INTRA*/ - { - { 164, 109},{ 1198, 1111},{ 2396, 1737},{ 3606, 1978}, - { 4727, 2048},{ 5749, 2138},{ 6708, 2243},{ 7584, 2347}, - { 8388, 2449},{ 9122, 2549},{ 9784, 2635},{10354, 2691}, - {10876, 2740},{11385, 2800},{11912, 2869},{12429, 2941}, - {12902, 2997},{13375, 3040},{13779, 3075},{14103, 3096}, - {14435, 3112},{14783, 3140},{15141, 3160},{15599, 3186} + /*Y' qi=18 INTRA*/ + { + { 51, 88},{ 88, 1344},{ 258, 1643},{ 228, 1325}, + { 372, 2208},{ 443, 2371},{ 520, 2382},{ 584, 2477}, + { 739, 2906},{ 859, 3348},{ 1008, 3697},{ 1131, 3884}, + { 1278, 4110},{ 1349, 4229},{ 1431, 4329},{ 1544, 4395}, + { 1602, 4439},{ 1669, 4535},{ 1814, 4656},{ 1883, 4716}, + { 1957, 4940},{ 2101, 5019},{ 2259, 5249},{ 2265, 5246} }, - /*Y' qi=58 INTER*/ - { - { 14, 23},{ 210, 1290},{ 1277, 2178},{ 3118, 2677}, - { 5207, 2834},{ 6902, 2857},{ 8218, 2878},{ 9323, 2900}, - {10285, 2919},{11132, 2934},{11899, 2949},{12599, 2961}, - {13235, 2971},{13835, 2982},{14394, 2991},{14917, 2997}, - {15412, 3005},{15882, 3009},{16325, 3013},{16735, 3016}, - {17131, 3018},{17501, 3021},{17824, 3021},{18125, 3016} + /*Y' qi=18 INTER*/ + { + { 26, 195},{ 1, 1317},{ 45, 2595},{ 103, 3750}, + { 168, 4903},{ 281, 6007},{ 397, 7062},{ 513, 8064}, + { 630, 9010},{ 758, 9902},{ 906,10732},{ 1095,11463}, + { 1338,12060},{ 1629,12490},{ 1969,12724},{ 2313,12842}, + { 2666,12828},{ 2993,12747},{ 3294,12670},{ 3558,12553}, + { 3813,12440},{ 3990,12379},{ 4177,12291},{ 4226,12265} } }, { - /*Cb qi=58 INTRA*/ - { - { 17, 3},{ 200, 365},{ 389, 703},{ 613, 996}, - { 853, 1243},{ 1095, 1445},{ 1349, 1604},{ 1613, 1731}, - { 1853, 1853},{ 2074, 1978},{ 2292, 2091},{ 2526, 2184}, - { 2750, 2266},{ 2945, 2360},{ 3134, 2458},{ 3320, 2561}, - { 3482, 2654},{ 3641, 2737},{ 3804, 2818},{ 3985, 2881}, - { 4168, 2935},{ 4331, 3003},{ 4499, 3060},{ 4751, 3100} + /*Cb qi=18 INTRA*/ + { + { 31, 43},{ 33, 585},{ 40, 781},{ 58, 1077}, + { 45, 1189},{ 58, 1655},{ 66, 1983},{ 123, 2221}, + { 168, 2193},{ 227, 2321},{ 241, 2246},{ 250, 2208}, + { 221, 1786},{ 250, 2087},{ 247, 2036},{ 250, 2164}, + { 241, 2054},{ 287, 2453},{ 302, 2551},{ 335, 2758}, + { 279, 2511},{ 379, 2973},{ 404, 3028},{ 406, 3029} }, - /*Cb qi=58 INTER*/ - { - { 94, -1},{ 112, 345},{ 112, 665},{ 152, 998}, - { 247, 1307},{ 406, 1580},{ 644, 1810},{ 938, 2007}, - { 1271, 2189},{ 1668, 2348},{ 2151, 2470},{ 2691, 2558}, - { 3249, 2619},{ 3798, 2659},{ 4334, 2682},{ 4849, 2692}, - { 5314, 2700},{ 5747, 2721},{ 6167, 2742},{ 6547, 2765}, - { 6902, 2790},{ 7251, 2804},{ 7583, 2819},{ 7924, 2833} + /*Cb qi=18 INTER*/ + { + { 7, 153},{ 4, 537},{ 3, 777},{ 9, 1034}, + { 6, 1282},{ 0, 1630},{ 0, 1943},{ 21, 2252}, + { 48, 2567},{ 67, 2881},{ 83, 3178},{ 89, 3463}, + { 92, 3738},{ 99, 4024},{ 114, 4289},{ 131, 4552}, + { 153, 4814},{ 179, 5081},{ 207, 5333},{ 241, 5581}, + { 273, 5822},{ 303, 6068},{ 335, 6368},{ 353, 6432} } }, { - /*Cr qi=58 INTRA*/ - { - { 29, 8},{ 210, 382},{ 419, 714},{ 671, 993}, - { 903, 1229},{ 1141, 1422},{ 1390, 1578},{ 1635, 1713}, - { 1889, 1833},{ 2140, 1946},{ 2379, 2055},{ 2604, 2157}, - { 2794, 2256},{ 2977, 2349},{ 3174, 2422},{ 3339, 2482}, - { 3483, 2537},{ 3643, 2604},{ 3790, 2684},{ 3927, 2757}, - { 4112, 2826},{ 4294, 2900},{ 4451, 2975},{ 4600, 3011} + /*Cr qi=18 INTRA*/ + { + { 31, 49},{ 42, 575},{ 42, 763},{ 38, 1045}, + { 41, 1184},{ 56, 1631},{ 87, 1968},{ 163, 2177}, + { 191, 2188},{ 236, 2264},{ 240, 2101},{ 234, 2047}, + { 206, 1651},{ 222, 1966},{ 238, 2013},{ 240, 2176}, + { 229, 2098},{ 321, 2592},{ 341, 2748},{ 378, 3025}, + { 367, 2849},{ 442, 3283},{ 453, 3315},{ 455, 3313} }, - /*Cr qi=58 INTER*/ - { - { 86, 0},{ 99, 352},{ 103, 675},{ 151, 1004}, - { 256, 1306},{ 417, 1573},{ 628, 1819},{ 901, 2040}, - { 1262, 2217},{ 1705, 2353},{ 2191, 2466},{ 2713, 2556}, - { 3268, 2622},{ 3831, 2664},{ 4374, 2682},{ 4881, 2686}, - { 5339, 2685},{ 5747, 2668},{ 6123, 2646},{ 6465, 2630}, - { 6783, 2618},{ 7082, 2623},{ 7366, 2632},{ 7673, 2654} + /*Cr qi=18 INTER*/ + { + { 6, 151},{ 3, 539},{ 3, 775},{ 8, 1027}, + { 6, 1260},{ -3, 1619},{ 0, 1927},{ 24, 2238}, + { 58, 2558},{ 76, 2871},{ 92, 3173},{ 96, 3461}, + { 98, 3742},{ 104, 4032},{ 116, 4306},{ 136, 4578}, + { 158, 4839},{ 185, 5123},{ 217, 5383},{ 250, 5642}, + { 279, 5910},{ 306, 6169},{ 333, 6502},{ 350, 6522} } } }, { { - /*Y' qi=59 INTRA*/ - { - { 142, 112},{ 1259, 1100},{ 2552, 1711},{ 3815, 1933}, - { 4955, 1987},{ 5983, 2068},{ 6949, 2165},{ 7832, 2263}, - { 8645, 2359},{ 9392, 2454},{10066, 2536},{10643, 2589}, - {11174, 2636},{11696, 2693},{12230, 2758},{12752, 2826}, - {13239, 2883},{13721, 2926},{14139, 2959},{14479, 2978}, - {14811, 2993},{15166, 3020},{15532, 3039},{16000, 3062} + /*Y' qi=27 INTRA*/ + { + { 10, 85},{ 280, 1349},{ 278, 815},{ 497, 1699}, + { 600, 1569},{ 744, 1944},{ 894, 2114},{ 1040, 2292}, + { 1216, 2484},{ 1485, 2816},{ 1778, 3065},{ 1990, 3243}, + { 2199, 3381},{ 2326, 3515},{ 2370, 3422},{ 2512, 3581}, + { 2548, 3526},{ 2656, 3615},{ 2803, 3679},{ 2946, 3766}, + { 3023, 3824},{ 3179, 3908},{ 3374, 4035},{ 3377, 4030} }, - /*Y' qi=59 INTER*/ - { - { 8, 25},{ 211, 1289},{ 1394, 2144},{ 3421, 2580}, - { 5611, 2689},{ 7316, 2701},{ 8643, 2717},{ 9762, 2734}, - {10735, 2750},{11587, 2763},{12353, 2775},{13056, 2785}, - {13693, 2793},{14288, 2805},{14843, 2814},{15361, 2821}, - {15857, 2827},{16328, 2831},{16763, 2834},{17171, 2838}, - {17568, 2840},{17941, 2842},{18285, 2843},{18586, 2839} + /*Y' qi=27 INTER*/ + { + { -2, 172},{ 31, 1347},{ 117, 2488},{ 245, 3651}, + { 448, 4719},{ 668, 5679},{ 918, 6524},{ 1204, 7255}, + { 1557, 7848},{ 1998, 8281},{ 2511, 8531},{ 3055, 8642}, + { 3582, 8648},{ 4062, 8611},{ 4482, 8582},{ 4845, 8560}, + { 5140, 8560},{ 5423, 8581},{ 5645, 8596},{ 5855, 8586}, + { 6061, 8608},{ 6211, 8558},{ 6402, 8583},{ 6472, 8575} } }, { - /*Cb qi=59 INTRA*/ - { - { 17, 3},{ 224, 363},{ 441, 696},{ 689, 982}, - { 945, 1222},{ 1204, 1416},{ 1474, 1571},{ 1751, 1695}, - { 2001, 1816},{ 2228, 1941},{ 2453, 2055},{ 2693, 2147}, - { 2924, 2227},{ 3125, 2321},{ 3321, 2416},{ 3510, 2520}, - { 3676, 2616},{ 3839, 2699},{ 4008, 2778},{ 4193, 2842}, - { 4371, 2898},{ 4535, 2965},{ 4710, 3023},{ 4921, 3068} + /*Cb qi=27 INTRA*/ + { + { 47, 49},{ 35, 580},{ 64, 778},{ 69, 1071}, + { 98, 1289},{ 186, 1556},{ 177, 1654},{ 197, 1736}, + { 211, 1373},{ 284, 1742},{ 321, 1840},{ 344, 2024}, + { 321, 1969},{ 386, 2254},{ 397, 2281},{ 425, 2320}, + { 396, 2088},{ 448, 2284},{ 462, 2213},{ 482, 2274}, + { 410, 1894},{ 513, 2310},{ 546, 2332},{ 549, 2334} }, - /*Cb qi=59 INTER*/ - { - { 95, -5},{ 111, 343},{ 112, 664},{ 157, 995}, - { 258, 1302},{ 429, 1569},{ 691, 1790},{ 1017, 1977}, - { 1387, 2148},{ 1832, 2294},{ 2368, 2401},{ 2961, 2472}, - { 3553, 2518},{ 4133, 2545},{ 4688, 2557},{ 5198, 2563}, - { 5663, 2574},{ 6100, 2590},{ 6511, 2608},{ 6898, 2621}, - { 7274, 2634},{ 7631, 2655},{ 7984, 2669},{ 8361, 2669} + /*Cb qi=27 INTER*/ + { + { 11, 145},{ 5, 539},{ 11, 771},{ 0, 1033}, + { 9, 1334},{ 44, 1644},{ 70, 1934},{ 87, 2227}, + { 96, 2508},{ 113, 2812},{ 139, 3085},{ 174, 3352}, + { 216, 3614},{ 261, 3873},{ 305, 4123},{ 349, 4372}, + { 396, 4611},{ 442, 4853},{ 493, 5088},{ 543, 5313}, + { 600, 5537},{ 662, 5752},{ 737, 6018},{ 775, 6037} } }, { - /*Cr qi=59 INTRA*/ - { - { 31, 8},{ 240, 379},{ 480, 706},{ 748, 978}, - { 993, 1208},{ 1250, 1394},{ 1519, 1543},{ 1779, 1674}, - { 2047, 1792},{ 2307, 1904},{ 2552, 2013},{ 2780, 2116}, - { 2973, 2216},{ 3165, 2309},{ 3362, 2383},{ 3528, 2444}, - { 3677, 2499},{ 3841, 2566},{ 3995, 2646},{ 4139, 2720}, - { 4324, 2793},{ 4504, 2867},{ 4658, 2939},{ 4806, 2975} + /*Cr qi=27 INTRA*/ + { + { 49, 52},{ 57, 570},{ 61, 762},{ 44, 1048}, + { 80, 1291},{ 196, 1513},{ 224, 1522},{ 242, 1532}, + { 213, 1293},{ 260, 1639},{ 253, 1691},{ 291, 1915}, + { 294, 1897},{ 367, 2178},{ 395, 2258},{ 432, 2310}, + { 407, 2105},{ 503, 2369},{ 492, 2293},{ 552, 2421}, + { 496, 2099},{ 598, 2549},{ 624, 2531},{ 627, 2532} }, - /*Cr qi=59 INTER*/ - { - { 89, -3},{ 98, 352},{ 103, 674},{ 156, 1002}, - { 268, 1300},{ 441, 1562},{ 673, 1801},{ 980, 2010}, - { 1385, 2175},{ 1868, 2301},{ 2401, 2402},{ 2984, 2474}, - { 3591, 2520},{ 4179, 2545},{ 4729, 2555},{ 5232, 2553}, - { 5679, 2545},{ 6081, 2530},{ 6447, 2510},{ 6791, 2496}, - { 7101, 2487},{ 7393, 2489},{ 7684, 2499},{ 7950, 2501} + /*Cr qi=27 INTER*/ + { + { 10, 147},{ 4, 538},{ 11, 769},{ 0, 1022}, + { 9, 1318},{ 51, 1635},{ 80, 1925},{ 97, 2214}, + { 101, 2493},{ 115, 2805},{ 143, 3083},{ 182, 3361}, + { 226, 3625},{ 270, 3898},{ 319, 4157},{ 366, 4405}, + { 418, 4649},{ 467, 4904},{ 509, 5157},{ 548, 5412}, + { 589, 5659},{ 636, 5909},{ 683, 6208},{ 710, 6190} } } }, { { - /*Y' qi=60 INTRA*/ - { - { 92, 116},{ 1361, 1085},{ 2746, 1686},{ 4050, 1895}, - { 5209, 1939},{ 6244, 2012},{ 7213, 2103},{ 8105, 2197}, - { 8928, 2290},{ 9685, 2381},{10371, 2460},{10952, 2511}, - {11487, 2556},{12026, 2611},{12574, 2674},{13102, 2739}, - {13597, 2793},{14092, 2831},{14523, 2862},{14862, 2881}, - {15198, 2897},{15568, 2923},{15949, 2941},{16416, 2964} + /*Y' qi=36 INTRA*/ + { + { 86, 252},{ 345, 662},{ 476, 1143},{ 698, 1169}, + { 894, 1457},{ 1218, 1728},{ 1465, 1849},{ 1731, 2019}, + { 2183, 2298},{ 2666, 2511},{ 3116, 2731},{ 3371, 2813}, + { 3621, 2923},{ 3675, 2949},{ 3710, 2921},{ 3740, 2896}, + { 3746, 2895},{ 3886, 2978},{ 4069, 2991},{ 4229, 3016}, + { 4338, 3102},{ 4530, 3124},{ 4751, 3248},{ 4753, 3244} }, - /*Y' qi=60 INTER*/ - { - { 4, 30},{ 215, 1287},{ 1547, 2104},{ 3729, 2491}, - { 5973, 2568},{ 7672, 2577},{ 9001, 2591},{10123, 2606}, - {11094, 2620},{11943, 2632},{12709, 2643},{13409, 2652}, - {14044, 2660},{14641, 2669},{15193, 2677},{15709, 2684}, - {16201, 2689},{16675, 2693},{17118, 2696},{17522, 2701}, - {17920, 2704},{18293, 2706},{18620, 2702},{18923, 2700} + /*Y' qi=36 INTER*/ + { + { 0, 208},{ 73, 1293},{ 248, 2449},{ 616, 3461}, + { 1061, 4329},{ 1601, 4986},{ 2189, 5447},{ 2875, 5723}, + { 3620, 5844},{ 4328, 5879},{ 4954, 5880},{ 5490, 5890}, + { 5934, 5901},{ 6353, 5926},{ 6706, 5924},{ 7036, 5930}, + { 7338, 5938},{ 7600, 5930},{ 7870, 5939},{ 8065, 5921}, + { 8318, 5914},{ 8451, 5912},{ 8648, 5923},{ 8734, 5926} } }, { - /*Cb qi=60 INTRA*/ - { - { 18, 3},{ 227, 362},{ 447, 694},{ 708, 974}, - { 981, 1207},{ 1252, 1397},{ 1532, 1547},{ 1822, 1663}, - { 2082, 1780},{ 2316, 1903},{ 2548, 2013},{ 2794, 2101}, - { 3029, 2178},{ 3242, 2266},{ 3445, 2360},{ 3638, 2459}, - { 3816, 2547},{ 3980, 2628},{ 4146, 2708},{ 4344, 2766}, - { 4546, 2812},{ 4725, 2872},{ 4880, 2930},{ 5054, 2966} + /*Cb qi=36 INTRA*/ + { + { 52, 54},{ 52, 575},{ 103, 776},{ 185, 1072}, + { 172, 1069},{ 211, 1302},{ 217, 1413},{ 285, 1586}, + { 330, 1463},{ 453, 1694},{ 500, 1741},{ 545, 1852}, + { 501, 1650},{ 584, 1874},{ 587, 1856},{ 638, 1919}, + { 581, 1742},{ 670, 1953},{ 688, 1934},{ 731, 2030}, + { 637, 1794},{ 806, 2123},{ 840, 2091},{ 843, 2091} }, - /*Cb qi=60 INTER*/ - { - { 97, -4},{ 112, 343},{ 114, 664},{ 162, 993}, - { 273, 1294},{ 472, 1553},{ 774, 1762},{ 1138, 1939}, - { 1543, 2102},{ 2034, 2236},{ 2620, 2329},{ 3244, 2389}, - { 3860, 2423},{ 4443, 2440},{ 4997, 2449},{ 5502, 2455}, - { 5962, 2458},{ 6413, 2466},{ 6836, 2485},{ 7217, 2506}, - { 7592, 2518},{ 7957, 2533},{ 8291, 2543},{ 8574, 2545} + /*Cb qi=36 INTER*/ + { + { 19, 142},{ 17, 534},{ 6, 772},{ 44, 1023}, + { 82, 1296},{ 94, 1614},{ 117, 1903},{ 158, 2187}, + { 218, 2450},{ 285, 2703},{ 352, 2943},{ 421, 3181}, + { 489, 3415},{ 564, 3644},{ 647, 3861},{ 748, 4060}, + { 861, 4246},{ 993, 4419},{ 1132, 4576},{ 1282, 4744}, + { 1445, 4894},{ 1600, 5034},{ 1782, 5211},{ 1837, 5200} } }, { - /*Cr qi=60 INTRA*/ - { - { 32, 8},{ 243, 379},{ 488, 702},{ 771, 968}, - { 1030, 1192},{ 1300, 1373},{ 1581, 1517},{ 1854, 1643}, - { 2127, 1757},{ 2393, 1864},{ 2645, 1968},{ 2879, 2068}, - { 3078, 2166},{ 3277, 2256},{ 3484, 2325},{ 3660, 2381}, - { 3808, 2433},{ 3970, 2496},{ 4138, 2571},{ 4288, 2643}, - { 4475, 2710},{ 4655, 2778},{ 4810, 2843},{ 4959, 2879} + /*Cr qi=36 INTRA*/ + { + { 62, 55},{ 90, 561},{ 56, 767},{ 148, 1014}, + { 207, 981},{ 258, 1216},{ 273, 1253},{ 326, 1392}, + { 338, 1383},{ 417, 1613},{ 443, 1629},{ 497, 1734}, + { 466, 1525},{ 561, 1778},{ 577, 1787},{ 631, 1892}, + { 591, 1706},{ 715, 1980},{ 730, 1958},{ 822, 2113}, + { 755, 1935},{ 928, 2228},{ 935, 2205},{ 938, 2205} }, - /*Cr qi=60 INTER*/ - { - { 86, -2},{ 99, 352},{ 103, 673},{ 160, 998}, - { 284, 1292},{ 484, 1546},{ 753, 1774},{ 1100, 1973}, - { 1546, 2129},{ 2072, 2246},{ 2652, 2334},{ 3279, 2392}, - { 3911, 2425},{ 4504, 2440},{ 5044, 2443},{ 5536, 2440}, - { 5979, 2430},{ 6381, 2413},{ 6735, 2397},{ 7062, 2382}, - { 7383, 2376},{ 7680, 2375},{ 7962, 2373},{ 8203, 2379} + /*Cr qi=36 INTER*/ + { + { 14, 145},{ 16, 535},{ 5, 772},{ 44, 1017}, + { 91, 1296},{ 100, 1605},{ 122, 1891},{ 163, 2174}, + { 225, 2443},{ 294, 2707},{ 362, 2962},{ 436, 3210}, + { 518, 3437},{ 607, 3664},{ 702, 3876},{ 795, 4094}, + { 886, 4310},{ 980, 4538},{ 1089, 4749},{ 1216, 4927}, + { 1357, 5116},{ 1506, 5247},{ 1758, 5338},{ 1787, 5306} } } }, { { - /*Y' qi=61 INTRA*/ - { - { 54, 121},{ 1477, 1069},{ 3061, 1638},{ 4465, 1808}, - { 5649, 1827},{ 6710, 1884},{ 7716, 1958},{ 8648, 2037}, - { 9514, 2116},{10311, 2192},{11033, 2261},{11641, 2305}, - {12202, 2342},{12771, 2387},{13356, 2440},{13924, 2493}, - {14444, 2541},{14951, 2576},{15409, 2600},{15779, 2615}, - {16131, 2626},{16521, 2648},{16921, 2663},{17409, 2694} + /*Y' qi=45 INTRA*/ + { + { 185, 246},{ 513, 647},{ 883, 891},{ 1313, 1142}, + { 1760, 1351},{ 2368, 1595},{ 2828, 1718},{ 3097, 1780}, + { 3762, 1951},{ 4454, 2121},{ 4986, 2227},{ 5281, 2281}, + { 5477, 2299},{ 5431, 2288},{ 5425, 2283},{ 5439, 2290}, + { 5324, 2249},{ 5509, 2279},{ 5703, 2321},{ 5896, 2348}, + { 6049, 2370},{ 6253, 2425},{ 6415, 2432},{ 6419, 2430} }, - /*Y' qi=61 INTER*/ - { - { -1, 32},{ 216, 1286},{ 1806, 2036},{ 4279, 2327}, - { 6629, 2352},{ 8347, 2352},{ 9707, 2357},{10860, 2364}, - {11857, 2372},{12726, 2377},{13508, 2382},{14225, 2387}, - {14877, 2392},{15484, 2398},{16048, 2401},{16581, 2405}, - {17092, 2409},{17573, 2409},{18016, 2410},{18427, 2413}, - {18829, 2415},{19221, 2415},{19578, 2415},{19980, 2413} + /*Y' qi=45 INTER*/ + { + { 6, 215},{ 152, 1261},{ 691, 2314},{ 1538, 3095}, + { 2505, 3632},{ 3475, 3935},{ 4355, 4084},{ 5209, 4139}, + { 5985, 4162},{ 6644, 4185},{ 7235, 4190},{ 7768, 4196}, + { 8266, 4200},{ 8736, 4210},{ 9143, 4207},{ 9511, 4215}, + { 9828, 4209},{10112, 4224},{10374, 4226},{10642, 4232}, + {10842, 4219},{10971, 4208},{11200, 4211},{11299, 4216} } }, { - /*Cb qi=61 INTRA*/ - { - { 19, 3},{ 231, 362},{ 456, 693},{ 733, 965}, - { 1032, 1188},{ 1330, 1369},{ 1637, 1508},{ 1956, 1612}, - { 2241, 1718},{ 2496, 1832},{ 2750, 1932},{ 3019, 2007}, - { 3274, 2074},{ 3505, 2154},{ 3725, 2236},{ 3943, 2323}, - { 4138, 2403},{ 4323, 2476},{ 4505, 2543},{ 4706, 2592}, - { 4909, 2630},{ 5109, 2675},{ 5292, 2724},{ 5495, 2768} + /*Cb qi=45 INTRA*/ + { + { 58, 71},{ 66, 548},{ 155, 762},{ 213, 944}, + { 192, 731},{ 324, 1147},{ 401, 1366},{ 481, 1480}, + { 508, 1238},{ 657, 1522},{ 727, 1563},{ 794, 1611}, + { 761, 1470},{ 885, 1710},{ 893, 1700},{ 958, 1760}, + { 893, 1543},{ 985, 1719},{ 1014, 1732},{ 1082, 1784}, + { 963, 1519},{ 1152, 1800},{ 1221, 1830},{ 1226, 1830} }, - /*Cb qi=61 INTER*/ - { - { 91, -2},{ 111, 344},{ 114, 663},{ 166, 989}, - { 291, 1285},{ 522, 1534},{ 875, 1729},{ 1302, 1889}, - { 1786, 2031},{ 2368, 2141},{ 3042, 2207},{ 3734, 2243}, - { 4388, 2259},{ 4982, 2264},{ 5533, 2265},{ 6043, 2262}, - { 6524, 2264},{ 6982, 2274},{ 7422, 2283},{ 7831, 2295}, - { 8198, 2308},{ 8593, 2319},{ 8965, 2329},{ 9258, 2340} + /*Cb qi=45 INTER*/ + { + { 35, 135},{ 12, 532},{ 54, 769},{ 106, 1007}, + { 127, 1258},{ 198, 1565},{ 289, 1832},{ 398, 2082}, + { 520, 2302},{ 653, 2511},{ 800, 2705},{ 956, 2897}, + { 1143, 3064},{ 1358, 3220},{ 1623, 3335},{ 1913, 3444}, + { 2198, 3534},{ 2502, 3626},{ 2787, 3711},{ 3114, 3783}, + { 3454, 3831},{ 3711, 3871},{ 4163, 3901},{ 4221, 3890} } }, { - /*Cr qi=61 INTRA*/ - { - { 33, 9},{ 245, 378},{ 497, 699},{ 801, 958}, - { 1087, 1171},{ 1384, 1342},{ 1692, 1474},{ 1992, 1589}, - { 2290, 1692},{ 2576, 1789},{ 2852, 1884},{ 3109, 1973}, - { 3324, 2061},{ 3544, 2142},{ 3763, 2199},{ 3945, 2244}, - { 4103, 2292},{ 4283, 2349},{ 4469, 2413},{ 4635, 2476}, - { 4836, 2534},{ 5038, 2592},{ 5210, 2649},{ 5358, 2682} + /*Cr qi=45 INTRA*/ + { + { 93, 68},{ 72, 541},{ 154, 769},{ 239, 848}, + { 214, 623},{ 377, 1060},{ 437, 1200},{ 514, 1280}, + { 512, 1160},{ 625, 1453},{ 657, 1470},{ 718, 1516}, + { 692, 1331},{ 831, 1617},{ 875, 1609},{ 944, 1678}, + { 886, 1469},{ 1061, 1699},{ 1082, 1714},{ 1226, 1823}, + { 1113, 1581},{ 1324, 1872},{ 1370, 1925},{ 1374, 1924} }, - /*Cr qi=61 INTER*/ - { - { 82, 0},{ 97, 353},{ 104, 672},{ 165, 995}, - { 303, 1284},{ 532, 1529},{ 852, 1742},{ 1273, 1921}, - { 1798, 2057},{ 2409, 2154},{ 3090, 2212},{ 3794, 2240}, - { 4460, 2251},{ 5057, 2249},{ 5596, 2249},{ 6085, 2245}, - { 6519, 2234},{ 6908, 2220},{ 7269, 2203},{ 7618, 2196}, - { 7949, 2198},{ 8269, 2195},{ 8554, 2196},{ 8928, 2217} + /*Cr qi=45 INTER*/ + { + { 31, 140},{ 13, 533},{ 52, 770},{ 109, 1000}, + { 134, 1253},{ 201, 1555},{ 298, 1821},{ 411, 2076}, + { 525, 2314},{ 659, 2545},{ 828, 2747},{ 1019, 2918}, + { 1205, 3082},{ 1405, 3266},{ 1609, 3443},{ 1847, 3606}, + { 2085, 3730},{ 2404, 3835},{ 2709, 3876},{ 3049, 3886}, + { 3381, 3821},{ 3708, 3780},{ 4026, 3663},{ 4043, 3646} } } }, { { - /*Y' qi=62 INTRA*/ - { - { 29, 124},{ 1527, 1067},{ 3221, 1618},{ 4703, 1751}, - { 5909, 1744},{ 7001, 1779},{ 8057, 1829},{ 9049, 1885}, - { 9968, 1943},{10813, 1999},{11572, 2050},{12206, 2082}, - {12801, 2107},{13402, 2140},{14020, 2180},{14625, 2223}, - {15179, 2260},{15718, 2288},{16196, 2305},{16581, 2313}, - {16963, 2324},{17382, 2341},{17800, 2351},{18318, 2376} + /*Y' qi=54 INTRA*/ + { + { 316, 203},{ 720, 585},{ 1596, 1077},{ 2316, 1289}, + { 2687, 1439},{ 3133, 1593},{ 3495, 1706},{ 3836, 1775}, + { 4249, 1892},{ 4804, 2031},{ 5320, 2139},{ 5617, 2203}, + { 5726, 2199},{ 5726, 2176},{ 5682, 2146},{ 5677, 2127}, + { 5717, 2124},{ 5707, 2129},{ 5853, 2148},{ 6110, 2180}, + { 6454, 2247},{ 6714, 2287},{ 6845, 2304},{ 6854, 2303} }, - /*Y' qi=62 INTER*/ - { - { -8, 36},{ 218, 1284},{ 2073, 1965},{ 4814, 2159}, - { 7237, 2138},{ 8979, 2124},{10378, 2115},{11570, 2109}, - {12601, 2106},{13503, 2103},{14320, 2103},{15064, 2103}, - {15746, 2103},{16384, 2104},{16975, 2105},{17534, 2105}, - {18062, 2106},{18564, 2107},{19035, 2106},{19471, 2107}, - {19890, 2107},{20288, 2107},{20651, 2107},{21012, 2108} + /*Y' qi=54 INTER*/ + { + { -48, 217},{ 314, 1261},{ 1450, 2126},{ 2761, 2728}, + { 4275, 3012},{ 5408, 3167},{ 6305, 3245},{ 7165, 3290}, + { 7966, 3325},{ 8698, 3359},{ 9352, 3377},{ 9907, 3391}, + {10389, 3390},{10856, 3395},{11170, 3385},{11530, 3385}, + {11780, 3362},{12018, 3362},{12266, 3361},{12443, 3339}, + {12683, 3342},{12713, 3317},{12967, 3325},{13082, 3332} } }, { - /*Cb qi=62 INTRA*/ - { - { 21, 3},{ 283, 360},{ 565, 683},{ 907, 938}, - { 1269, 1143},{ 1611, 1311},{ 1949, 1441},{ 2290, 1535}, - { 2596, 1632},{ 2877, 1738},{ 3162, 1828},{ 3458, 1893}, - { 3745, 1948},{ 4011, 2016},{ 4253, 2089},{ 4506, 2164}, - { 4734, 2233},{ 4943, 2294},{ 5162, 2353},{ 5381, 2393}, - { 5593, 2420},{ 5807, 2454},{ 6003, 2496},{ 6210, 2543} + /*Cb qi=54 INTRA*/ + { + { 94, 73},{ 83, 557},{ 152, 818},{ 304, 919}, + { 341, 819},{ 506, 1128},{ 593, 1281},{ 700, 1389}, + { 714, 1225},{ 907, 1502},{ 981, 1549},{ 1062, 1641}, + { 1032, 1523},{ 1170, 1710},{ 1217, 1727},{ 1258, 1714}, + { 1216, 1575},{ 1309, 1682},{ 1331, 1656},{ 1393, 1712}, + { 1247, 1456},{ 1469, 1728},{ 1530, 1711},{ 1532, 1711} }, - /*Cb qi=62 INTER*/ - { - { 91, -1},{ 110, 344},{ 113, 663},{ 169, 987}, - { 306, 1279},{ 562, 1519},{ 961, 1701},{ 1450, 1845}, - { 2013, 1967},{ 2686, 2053},{ 3437, 2095},{ 4171, 2109}, - { 4841, 2109},{ 5441, 2105},{ 6002, 2097},{ 6542, 2089}, - { 7028, 2087},{ 7491, 2088},{ 7949, 2090},{ 8377, 2089}, - { 8789, 2095},{ 9195, 2103},{ 9569, 2104},{ 9937, 2102} + /*Cb qi=54 INTER*/ + { + { 33, 133},{ 12, 532},{ 70, 770},{ 171, 996}, + { 279, 1233},{ 427, 1503},{ 600, 1736},{ 824, 1939}, + { 1101, 2097},{ 1411, 2237},{ 1735, 2374},{ 2097, 2493}, + { 2486, 2606},{ 2916, 2691},{ 3297, 2771},{ 3715, 2826}, + { 4088, 2855},{ 4460, 2886},{ 4849, 2911},{ 5198, 2932}, + { 5489, 2940},{ 5875, 2981},{ 6208, 3017},{ 6270, 3012} } }, { - /*Cr qi=62 INTRA*/ - { - { 38, 8},{ 308, 374},{ 619, 685},{ 984, 925}, - { 1326, 1126},{ 1662, 1285},{ 1999, 1407},{ 2328, 1512}, - { 2659, 1604},{ 2976, 1691},{ 3285, 1774},{ 3570, 1853}, - { 3815, 1931},{ 4068, 1998},{ 4304, 2044},{ 4491, 2082}, - { 4666, 2124},{ 4870, 2174},{ 5078, 2231},{ 5262, 2285}, - { 5480, 2335},{ 5703, 2378},{ 5905, 2423},{ 6075, 2454} + /*Cr qi=54 INTRA*/ + { + { 103, 63},{ 83, 580},{ 258, 796},{ 301, 802}, + { 361, 675},{ 538, 1001},{ 625, 1097},{ 713, 1171}, + { 699, 1103},{ 868, 1380},{ 915, 1400},{ 970, 1491}, + { 923, 1365},{ 1070, 1603},{ 1154, 1655},{ 1206, 1677}, + { 1157, 1541},{ 1366, 1736},{ 1391, 1723},{ 1506, 1797}, + { 1388, 1556},{ 1616, 1828},{ 1655, 1797},{ 1658, 1796} }, - /*Cr qi=62 INTER*/ - { - { 79, 1},{ 95, 353},{ 102, 671},{ 169, 992}, - { 318, 1277},{ 569, 1515},{ 936, 1716},{ 1428, 1876}, - { 2034, 1993},{ 2738, 2067},{ 3511, 2095},{ 4268, 2094}, - { 4943, 2087},{ 5543, 2079},{ 6074, 2074},{ 6552, 2069}, - { 6985, 2057},{ 7366, 2043},{ 7728, 2030},{ 8086, 2021}, - { 8423, 2017},{ 8752, 2016},{ 9057, 2014},{ 9376, 2008} + /*Cr qi=54 INTER*/ + { + { 30, 138},{ 14, 532},{ 63, 771},{ 176, 990}, + { 299, 1226},{ 438, 1496},{ 606, 1735},{ 814, 1950}, + { 1089, 2127},{ 1417, 2281},{ 1761, 2421},{ 2104, 2571}, + { 2467, 2701},{ 2881, 2827},{ 3303, 2900},{ 3735, 2917}, + { 4183, 2913},{ 4529, 2882},{ 4915, 2844},{ 5168, 2796}, + { 5410, 2763},{ 5562, 2753},{ 5815, 2764},{ 5832, 2755} } } }, @@ -3964,61 +967,61 @@ oc_mode_rd OC_MODE_RD[64][3][2][OC_SAD_BINS]={ { /*Y' qi=63 INTRA*/ { - { -59, 134},{ 1734, 1036},{ 3743, 1521},{ 5309, 1618}, - { 6520, 1597},{ 7664, 1609},{ 8809, 1630},{ 9894, 1657}, - {10907, 1687},{11838, 1717},{12673, 1744},{13379, 1758}, - {14038, 1767},{14698, 1784},{15379, 1806},{16062, 1831}, - {16694, 1852},{17300, 1867},{17827, 1878},{18250, 1881}, - {18702, 1884},{19199, 1892},{19665, 1896},{20273, 1908} + { 421, 194},{ 1272, 564},{ 3016, 943},{ 3831, 1079}, + { 4282, 1174},{ 4799, 1290},{ 5166, 1348},{ 5259, 1350}, + { 5720, 1426},{ 6501, 1539},{ 7048, 1606},{ 7328, 1642}, + { 7374, 1622},{ 7349, 1612},{ 7192, 1578},{ 7207, 1571}, + { 7161, 1555},{ 7259, 1573},{ 7432, 1592},{ 7710, 1613}, + { 8167, 1672},{ 8425, 1697},{ 8597, 1710},{ 8602, 1710} }, /*Y' qi=63 INTER*/ { - { -7, 33},{ 209, 1285},{ 2309, 1904},{ 5274, 2025}, - { 7801, 1966},{ 9637, 1924},{11126, 1892},{12403, 1868}, - {13515, 1849},{14491, 1834},{15380, 1822},{16197, 1814}, - {16944, 1806},{17645, 1799},{18303, 1794},{18916, 1789}, - {19494, 1785},{20056, 1782},{20568, 1779},{21047, 1776}, - {21508, 1775},{21925, 1772},{22327, 1770},{22678, 1771} + { -584, 286},{ 1231, 1186},{ 3939, 1663},{ 6096, 1865}, + { 7849, 1929},{ 8934, 1995},{ 9962, 2039},{11038, 2078}, + {12016, 2092},{12889, 2100},{13617, 2096},{14221, 2089}, + {14743, 2083},{15240, 2081},{15619, 2074},{15992, 2065}, + {16314, 2065},{16529, 2059},{16822, 2056},{17041, 2049}, + {17321, 2052},{17408, 2043},{17670, 2051},{17801, 2053} } }, { /*Cb qi=63 INTRA*/ { - { 20, 3},{ 294, 357},{ 608, 673},{ 1047, 908}, - { 1501, 1090},{ 1898, 1240},{ 2275, 1353},{ 2654, 1427}, - { 3014, 1502},{ 3366, 1579},{ 3726, 1637},{ 4084, 1674}, - { 4425, 1703},{ 4752, 1743},{ 5058, 1791},{ 5377, 1838}, - { 5676, 1877},{ 5946, 1912},{ 6213, 1945},{ 6458, 1969}, - { 6704, 1982},{ 6969, 1997},{ 7210, 2017},{ 7439, 2037} + { 154, 55},{ 280, 582},{ 507, 731},{ 788, 853}, + { 763, 738},{ 1141, 1008},{ 1323, 1090},{ 1540, 1220}, + { 1487, 1089},{ 1861, 1322},{ 1983, 1347},{ 2145, 1425}, + { 2047, 1317},{ 2334, 1475},{ 2352, 1413},{ 2458, 1467}, + { 2243, 1270},{ 2464, 1413},{ 2423, 1335},{ 2506, 1385}, + { 2182, 1180},{ 2565, 1376},{ 2555, 1321},{ 2557, 1321} }, /*Cb qi=63 INTER*/ { - { 86, 1},{ 108, 345},{ 111, 663},{ 168, 985}, - { 307, 1276},{ 577, 1513},{ 1007, 1688},{ 1550, 1819}, - { 2189, 1921},{ 2938, 1981},{ 3744, 2002},{ 4512, 2002}, - { 5199, 1996},{ 5824, 1986},{ 6419, 1971},{ 6978, 1954}, - { 7507, 1940},{ 8015, 1932},{ 8502, 1928},{ 8978, 1920}, - { 9410, 1915},{ 9842, 1910},{10262, 1901},{10634, 1896} + { 34, 133},{ 6, 531},{ 139, 767},{ 344, 975}, + { 608, 1180},{ 1048, 1367},{ 1651, 1495},{ 2376, 1572}, + { 3103, 1609},{ 3752, 1646},{ 4373, 1680},{ 4980, 1718}, + { 5540, 1744},{ 6023, 1764},{ 6431, 1766},{ 6800, 1769}, + { 7149, 1775},{ 7529, 1777},{ 7920, 1817},{ 8198, 1808}, + { 8691, 1848},{ 8965, 1845},{ 9372, 1865},{ 9459, 1863} } }, { /*Cr qi=63 INTRA*/ { - { 38, 7},{ 324, 367},{ 677, 670},{ 1136, 892}, - { 1562, 1070},{ 1951, 1209},{ 2326, 1313},{ 2694, 1399}, - { 3074, 1471},{ 3460, 1531},{ 3850, 1575},{ 4214, 1622}, - { 4522, 1679},{ 4819, 1723},{ 5089, 1749},{ 5315, 1769}, - { 5530, 1792},{ 5756, 1825},{ 6006, 1860},{ 6244, 1889}, - { 6514, 1924},{ 6792, 1946},{ 7026, 1962},{ 7191, 1971} + { 121, 59},{ 392, 570},{ 609, 654},{ 800, 760}, + { 720, 598},{ 1192, 892},{ 1298, 897},{ 1470, 1027}, + { 1411, 962},{ 1761, 1184},{ 1826, 1197},{ 1981, 1308}, + { 1854, 1198},{ 2229, 1427},{ 2269, 1365},{ 2428, 1453}, + { 2217, 1265},{ 2558, 1435},{ 2541, 1356},{ 2660, 1417}, + { 2337, 1199},{ 2688, 1382},{ 2603, 1301},{ 2605, 1300} }, /*Cr qi=63 INTER*/ { - { 80, 2},{ 95, 354},{ 101, 671},{ 167, 990}, - { 321, 1274},{ 585, 1509},{ 984, 1702},{ 1534, 1849}, - { 2217, 1947},{ 3005, 1995},{ 3839, 1999},{ 4619, 1986}, - { 5310, 1973},{ 5933, 1961},{ 6486, 1952},{ 6988, 1942}, - { 7435, 1927},{ 7817, 1911},{ 8198, 1900},{ 8552, 1895}, - { 8881, 1890},{ 9253, 1883},{ 9598, 1876},{ 9923, 1859} + { 31, 137},{ 10, 531},{ 136, 768},{ 360, 971}, + { 638, 1166},{ 1029, 1373},{ 1604, 1519},{ 2351, 1595}, + { 3129, 1640},{ 3861, 1691},{ 4491, 1751},{ 5101, 1783}, + { 5635, 1784},{ 6136, 1779},{ 6550, 1763},{ 6905, 1746}, + { 7172, 1726},{ 7495, 1732},{ 7738, 1735},{ 7949, 1735}, + { 8211, 1744},{ 8424, 1740},{ 8779, 1764},{ 8812, 1760} } } } diff --git a/thirdparty/libtheora/ocintrin.h b/thirdparty/libtheora/ocintrin.h index d49ebb2159..b200ceafce 100644 --- a/thirdparty/libtheora/ocintrin.h +++ b/thirdparty/libtheora/ocintrin.h @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: ocintrin.h 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ diff --git a/thirdparty/libtheora/patches/theora.git-0ae66d565e6bead8604d312bc1a4e9dccf245c88.patch b/thirdparty/libtheora/patches/theora.git-0ae66d565e6bead8604d312bc1a4e9dccf245c88.patch deleted file mode 100644 index 1b9c8e20be..0000000000 --- a/thirdparty/libtheora/patches/theora.git-0ae66d565e6bead8604d312bc1a4e9dccf245c88.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0ae66d565e6bead8604d312bc1a4e9dccf245c88 Mon Sep 17 00:00:00 2001 -From: Tim Terriberry <tterribe@xiph.org> -Date: Tue, 8 May 2012 02:51:57 +0000 -Subject: [PATCH] Fix pp_sharp_mod calculation. - -This was broken when the dequant_tables indexing changed in commit - r16102, but it only affected post-processing quality, so we never - noticed. -With gcc 4.8.0, this can now trigger a segfault during decoder - initialization. - -svn path=/trunk/theora/; revision=18268 ---- - decode.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/decode.c b/decode.c -index b803505..9f2516a 100644 ---- a/decode.c -+++ b/decode.c -@@ -400,10 +400,10 @@ static int oc_dec_init(oc_dec_ctx *_dec,const th_info *_info, - int qsum; - qsum=0; - for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){ -- qsum+=_dec->state.dequant_tables[qti][pli][qi][12]+ -- _dec->state.dequant_tables[qti][pli][qi][17]+ -- _dec->state.dequant_tables[qti][pli][qi][18]+ -- _dec->state.dequant_tables[qti][pli][qi][24]<<(pli==0); -+ qsum+=_dec->state.dequant_tables[qi][pli][qti][12]+ -+ _dec->state.dequant_tables[qi][pli][qti][17]+ -+ _dec->state.dequant_tables[qi][pli][qti][18]+ -+ _dec->state.dequant_tables[qi][pli][qti][24]<<(pli==0); - } - _dec->pp_sharp_mod[qi]=-(qsum>>11); - } --- -2.11.0 - diff --git a/thirdparty/libtheora/quant.c b/thirdparty/libtheora/quant.c index 8359f5abea..e206202844 100644 --- a/thirdparty/libtheora/quant.c +++ b/thirdparty/libtheora/quant.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: quant.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ @@ -21,6 +21,14 @@ #include "quant.h" #include "decint.h" +/*The maximum output of the DCT with +/- 255 inputs is +/- 8157. + These minimum quantizers ensure the result after quantization (and after + prediction for DC) will be no more than +/- 510. + The tokenization system can handle values up to +/- 580, so there is no need + to do any coefficient clamping. + I would rather have allowed smaller quantizers and had to clamp, but these + minimums were required when constructing the original VP3 matrices and have + been formalized in the spec.*/ static const unsigned OC_DC_QUANT_MIN[2]={4<<2,8<<2}; static const unsigned OC_AC_QUANT_MIN[2]={2<<2,4<<2}; diff --git a/thirdparty/libtheora/quant.h b/thirdparty/libtheora/quant.h index 49ce13a65c..247210eaae 100644 --- a/thirdparty/libtheora/quant.h +++ b/thirdparty/libtheora/quant.h @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: quant.h 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ diff --git a/thirdparty/libtheora/rate.c b/thirdparty/libtheora/rate.c index 4f43bb2e5f..bf2b1396a1 100644 --- a/thirdparty/libtheora/rate.c +++ b/thirdparty/libtheora/rate.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: rate.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ #include <stdlib.h> @@ -190,7 +190,8 @@ void oc_enc_calc_lambda(oc_enc_ctx *_enc,int _qti){ This may need to be revised if the R-D cost estimation or qii flag optimization strategies change.*/ nqis=1; - if(lq<(OC_Q57(56)>>3)&&!_enc->vp3_compatible){ + if(lq<(OC_Q57(56)>>3)&&!_enc->vp3_compatible&& + _enc->sp_level<OC_SP_LEVEL_FAST_ANALYSIS){ qi1=oc_enc_find_qi_for_target(_enc,_qti,OC_MAXI(qi-1,0),0, lq+(OC_Q57(7)+5)/10); if(qi1!=qi)_enc->state.qis[nqis++]=qi1; @@ -761,6 +762,7 @@ int oc_enc_update_rc_state(oc_enc_ctx *_enc, _enc->rc.cur_metrics.log_scale=oc_q57_to_q24(log_scale); _enc->rc.cur_metrics.dup_count=_enc->dup_count; _enc->rc.cur_metrics.frame_type=_enc->state.frame_type; + _enc->rc.cur_metrics.activity_avg=_enc->activity_avg; _enc->rc.twopass_buffer_bytes=0; }break; case 2:{ @@ -863,9 +865,9 @@ int oc_enc_update_rc_state(oc_enc_ctx *_enc, return dropped; } -#define OC_RC_2PASS_VERSION (1) +#define OC_RC_2PASS_VERSION (2) #define OC_RC_2PASS_HDR_SZ (38) -#define OC_RC_2PASS_PACKET_SZ (8) +#define OC_RC_2PASS_PACKET_SZ (12) static void oc_rc_buffer_val(oc_rc_state *_rc,ogg_int64_t _val,int _bytes){ while(_bytes-->0){ @@ -900,6 +902,7 @@ int oc_enc_rc_2pass_out(oc_enc_ctx *_enc,unsigned char **_buf){ oc_rc_buffer_val(&_enc->rc, _enc->rc.cur_metrics.dup_count|_enc->rc.cur_metrics.frame_type<<31,4); oc_rc_buffer_val(&_enc->rc,_enc->rc.cur_metrics.log_scale,4); + oc_rc_buffer_val(&_enc->rc,_enc->rc.cur_metrics.activity_avg,4); } } else if(_enc->packet_state==OC_PACKET_DONE&& @@ -1050,16 +1053,19 @@ int oc_enc_rc_2pass_in(oc_enc_ctx *_enc,unsigned char *_buf,size_t _bytes){ if(_enc->rc.twopass_buffer_fill>=OC_RC_2PASS_PACKET_SZ){ ogg_uint32_t dup_count; ogg_int32_t log_scale; + unsigned activity; int qti; int arg; /*Read the metrics for the next frame.*/ dup_count=oc_rc_unbuffer_val(&_enc->rc,4); log_scale=oc_rc_unbuffer_val(&_enc->rc,4); + activity=oc_rc_unbuffer_val(&_enc->rc,4); _enc->rc.cur_metrics.log_scale=log_scale; qti=(dup_count&0x80000000)>>31; _enc->rc.cur_metrics.dup_count=dup_count&0x7FFFFFFF; _enc->rc.cur_metrics.frame_type=qti; _enc->rc.twopass_force_kf=qti==OC_INTRA_FRAME; + _enc->activity_avg=_enc->rc.cur_metrics.activity_avg=activity; /*"Helpfully" set the dup count back to what it was in pass 1.*/ arg=_enc->rc.cur_metrics.dup_count; th_encode_ctl(_enc,TH_ENCCTL_SET_DUP_COUNT,&arg,sizeof(arg)); @@ -1070,8 +1076,8 @@ int oc_enc_rc_2pass_in(oc_enc_ctx *_enc,unsigned char *_buf,size_t _bytes){ else{ int frames_needed; /*We're using a finite buffer:*/ - frames_needed=OC_CLAMPI(0,_enc->rc.buf_delay - -(_enc->rc.scale_window_end-_enc->rc.scale_window0), + frames_needed=OC_MINI(_enc->rc.buf_delay-OC_MINI(_enc->rc.buf_delay, + _enc->rc.scale_window_end-_enc->rc.scale_window0), _enc->rc.frames_left[0]+_enc->rc.frames_left[1] -_enc->rc.nframes[0]-_enc->rc.nframes[1]); while(frames_needed>0){ @@ -1087,9 +1093,11 @@ int oc_enc_rc_2pass_in(oc_enc_ctx *_enc,unsigned char *_buf,size_t _bytes){ ogg_uint32_t dup_count; ogg_int32_t log_scale; int qti; + unsigned activity; /*Read the metrics for the next frame.*/ dup_count=oc_rc_unbuffer_val(&_enc->rc,4); log_scale=oc_rc_unbuffer_val(&_enc->rc,4); + activity=oc_rc_unbuffer_val(&_enc->rc,4); /*Add the to the circular buffer.*/ fmi=_enc->rc.frame_metrics_head+_enc->rc.nframe_metrics++; if(fmi>=_enc->rc.cframe_metrics)fmi-=_enc->rc.cframe_metrics; @@ -1098,6 +1106,7 @@ int oc_enc_rc_2pass_in(oc_enc_ctx *_enc,unsigned char *_buf,size_t _bytes){ qti=(dup_count&0x80000000)>>31; m->dup_count=dup_count&0x7FFFFFFF; m->frame_type=qti; + m->activity_avg=activity; /*And accumulate the statistics over the window.*/ _enc->rc.nframes[qti]++; _enc->rc.nframes[2]+=m->dup_count; @@ -1105,8 +1114,8 @@ int oc_enc_rc_2pass_in(oc_enc_ctx *_enc,unsigned char *_buf,size_t _bytes){ _enc->rc.scale_window_end+=m->dup_count+1; /*Compute an upper bound on the number of remaining packets needed for the current window.*/ - frames_needed=OC_CLAMPI(0,_enc->rc.buf_delay - -(_enc->rc.scale_window_end-_enc->rc.scale_window0), + frames_needed=OC_MINI(_enc->rc.buf_delay-OC_MINI(_enc->rc.buf_delay, + _enc->rc.scale_window_end-_enc->rc.scale_window0), _enc->rc.frames_left[0]+_enc->rc.frames_left[1] -_enc->rc.nframes[0]-_enc->rc.nframes[1]); /*Clear the buffer for the next frame.*/ @@ -1124,6 +1133,7 @@ int oc_enc_rc_2pass_in(oc_enc_ctx *_enc,unsigned char *_buf,size_t _bytes){ *(_enc->rc.frame_metrics+_enc->rc.frame_metrics_head); _enc->rc.twopass_force_kf= _enc->rc.cur_metrics.frame_type==OC_INTRA_FRAME; + _enc->activity_avg=_enc->rc.cur_metrics.activity_avg; /*"Helpfully" set the dup count back to what it was in pass 1.*/ arg=_enc->rc.cur_metrics.dup_count; th_encode_ctl(_enc,TH_ENCCTL_SET_DUP_COUNT,&arg,sizeof(arg)); diff --git a/thirdparty/libtheora/state.c b/thirdparty/libtheora/state.c index 42ed33a9a3..f4c6240387 100644 --- a/thirdparty/libtheora/state.c +++ b/thirdparty/libtheora/state.c @@ -11,25 +11,93 @@ ******************************************************************** function: - last mod: $Id: state.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ #include <stdlib.h> #include <string.h> -#include "internal.h" -#if defined(OC_X86_ASM) -#if defined(_MSC_VER) -# include "x86_vc/x86int.h" -#else -# include "x86/x86int.h" -#endif -#endif +#include "state.h" #if defined(OC_DUMP_IMAGES) # include <stdio.h> # include "png.h" +# include "zlib.h" #endif +/*The function used to fill in the chroma plane motion vectors for a macro + block when 4 different motion vectors are specified in the luma plane. + This version is for use with chroma decimated in the X and Y directions + (4:2:0). + _cbmvs: The chroma block-level motion vectors to fill in. + _lbmvs: The luma block-level motion vectors.*/ +static void oc_set_chroma_mvs00(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){ + int dx; + int dy; + dx=OC_MV_X(_lbmvs[0])+OC_MV_X(_lbmvs[1]) + +OC_MV_X(_lbmvs[2])+OC_MV_X(_lbmvs[3]); + dy=OC_MV_Y(_lbmvs[0])+OC_MV_Y(_lbmvs[1]) + +OC_MV_Y(_lbmvs[2])+OC_MV_Y(_lbmvs[3]); + _cbmvs[0]=OC_MV(OC_DIV_ROUND_POW2(dx,2,2),OC_DIV_ROUND_POW2(dy,2,2)); +} + +/*The function used to fill in the chroma plane motion vectors for a macro + block when 4 different motion vectors are specified in the luma plane. + This version is for use with chroma decimated in the Y direction. + _cbmvs: The chroma block-level motion vectors to fill in. + _lbmvs: The luma block-level motion vectors.*/ +static void oc_set_chroma_mvs01(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){ + int dx; + int dy; + dx=OC_MV_X(_lbmvs[0])+OC_MV_X(_lbmvs[2]); + dy=OC_MV_Y(_lbmvs[0])+OC_MV_Y(_lbmvs[2]); + _cbmvs[0]=OC_MV(OC_DIV_ROUND_POW2(dx,1,1),OC_DIV_ROUND_POW2(dy,1,1)); + dx=OC_MV_X(_lbmvs[1])+OC_MV_X(_lbmvs[3]); + dy=OC_MV_Y(_lbmvs[1])+OC_MV_Y(_lbmvs[3]); + _cbmvs[1]=OC_MV(OC_DIV_ROUND_POW2(dx,1,1),OC_DIV_ROUND_POW2(dy,1,1)); +} + +/*The function used to fill in the chroma plane motion vectors for a macro + block when 4 different motion vectors are specified in the luma plane. + This version is for use with chroma decimated in the X direction (4:2:2). + _cbmvs: The chroma block-level motion vectors to fill in. + _lbmvs: The luma block-level motion vectors.*/ +static void oc_set_chroma_mvs10(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){ + int dx; + int dy; + dx=OC_MV_X(_lbmvs[0])+OC_MV_X(_lbmvs[1]); + dy=OC_MV_Y(_lbmvs[0])+OC_MV_Y(_lbmvs[1]); + _cbmvs[0]=OC_MV(OC_DIV_ROUND_POW2(dx,1,1),OC_DIV_ROUND_POW2(dy,1,1)); + dx=OC_MV_X(_lbmvs[2])+OC_MV_X(_lbmvs[3]); + dy=OC_MV_Y(_lbmvs[2])+OC_MV_Y(_lbmvs[3]); + _cbmvs[2]=OC_MV(OC_DIV_ROUND_POW2(dx,1,1),OC_DIV_ROUND_POW2(dy,1,1)); +} + +/*The function used to fill in the chroma plane motion vectors for a macro + block when 4 different motion vectors are specified in the luma plane. + This version is for use with no chroma decimation (4:4:4). + _cbmvs: The chroma block-level motion vectors to fill in. + _lmbmv: The luma macro-block level motion vector to fill in for use in + prediction. + _lbmvs: The luma block-level motion vectors.*/ +static void oc_set_chroma_mvs11(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){ + _cbmvs[0]=_lbmvs[0]; + _cbmvs[1]=_lbmvs[1]; + _cbmvs[2]=_lbmvs[2]; + _cbmvs[3]=_lbmvs[3]; +} + +/*A table of functions used to fill in the chroma plane motion vectors for a + macro block when 4 different motion vectors are specified in the luma + plane.*/ +const oc_set_chroma_mvs_func OC_SET_CHROMA_MVS_TABLE[TH_PF_NFORMATS]={ + (oc_set_chroma_mvs_func)oc_set_chroma_mvs00, + (oc_set_chroma_mvs_func)oc_set_chroma_mvs01, + (oc_set_chroma_mvs_func)oc_set_chroma_mvs10, + (oc_set_chroma_mvs_func)oc_set_chroma_mvs11 +}; + + + /*Returns the fragment index of the top-left block in a macro block. This can be used to test whether or not the whole macro block is valid. _sb_map: The super block map. @@ -92,7 +160,7 @@ static void oc_sb_create_plane_mapping(oc_sb_map _sb_maps[], if(jmax>4)jmax=4; else if(jmax<=0)break; /*By default, set all fragment indices to -1.*/ - memset(_sb_maps[sbi][0],0xFF,sizeof(_sb_maps[sbi])); + memset(_sb_maps[sbi],0xFF,sizeof(_sb_maps[sbi])); /*Fill in the fragment map for this super block.*/ xfrag=yfrag+x; for(i=0;i<imax;i++){ @@ -186,10 +254,14 @@ static void oc_mb_fill_cmapping10(oc_mb_map_plane _mb_map[3], This version is for use with no chroma decimation (4:4:4). This uses the already filled-in luma plane values. _mb_map: The macro block map to fill. - _fplanes: The descriptions of the fragment planes.*/ + _fplanes: The descriptions of the fragment planes. + _xfrag0: The X location of the upper-left hand fragment in the luma plane. + _yfrag0: The Y location of the upper-left hand fragment in the luma plane.*/ static void oc_mb_fill_cmapping11(oc_mb_map_plane _mb_map[3], - const oc_fragment_plane _fplanes[3]){ + const oc_fragment_plane _fplanes[3],int _xfrag0,int _yfrag0){ int k; + (void)_xfrag0; + (void)_yfrag0; for(k=0;k<4;k++){ _mb_map[1][k]=_mb_map[0][k]+_fplanes[1].froffset; _mb_map[2][k]=_mb_map[0][k]+_fplanes[2].froffset; @@ -211,7 +283,7 @@ static const oc_mb_fill_cmapping_func OC_MB_FILL_CMAPPING_TABLE[4]={ oc_mb_fill_cmapping00, oc_mb_fill_cmapping01, oc_mb_fill_cmapping10, - (oc_mb_fill_cmapping_func)oc_mb_fill_cmapping11 + oc_mb_fill_cmapping11 }; /*Fills in the mapping from macro blocks to their corresponding fragment @@ -469,7 +541,7 @@ static void oc_state_frarray_clear(oc_theora_state *_state){ unrestricted motion vectors without special casing the boundary. If chroma is decimated in either direction, the padding is reduced by a factor of 2 on the appropriate sides. - _nrefs: The number of reference buffers to init; must be 3 or 4.*/ + _nrefs: The number of reference buffers to init; must be in the range 3...6.*/ static int oc_state_ref_bufs_init(oc_theora_state *_state,int _nrefs){ th_info *info; unsigned char *ref_frame_data; @@ -481,6 +553,7 @@ static int oc_state_ref_bufs_init(oc_theora_state *_state,int _nrefs){ int yheight; int chstride; int cheight; + ptrdiff_t align; ptrdiff_t yoffset; ptrdiff_t coffset; ptrdiff_t *frag_buf_offs; @@ -489,33 +562,38 @@ static int oc_state_ref_bufs_init(oc_theora_state *_state,int _nrefs){ int vdec; int rfi; int pli; - if(_nrefs<3||_nrefs>4)return TH_EINVAL; + if(_nrefs<3||_nrefs>6)return TH_EINVAL; info=&_state->info; /*Compute the image buffer parameters for each plane.*/ hdec=!(info->pixel_fmt&1); vdec=!(info->pixel_fmt&2); yhstride=info->frame_width+2*OC_UMV_PADDING; yheight=info->frame_height+2*OC_UMV_PADDING; - chstride=yhstride>>hdec; + /*Require 16-byte aligned rows in the chroma planes.*/ + chstride=(yhstride>>hdec)+15&~15; cheight=yheight>>vdec; yplane_sz=yhstride*(size_t)yheight; cplane_sz=chstride*(size_t)cheight; yoffset=OC_UMV_PADDING+OC_UMV_PADDING*(ptrdiff_t)yhstride; coffset=(OC_UMV_PADDING>>hdec)+(OC_UMV_PADDING>>vdec)*(ptrdiff_t)chstride; - ref_frame_sz=yplane_sz+2*cplane_sz; + /*Although we guarantee the rows of the chroma planes are a multiple of 16 + bytes, the initial padding on the first row may only be 8 bytes. + Compute the offset needed to the actual image data to a multiple of 16.*/ + align=-coffset&15; + ref_frame_sz=yplane_sz+2*cplane_sz+16; ref_frame_data_sz=_nrefs*ref_frame_sz; /*Check for overflow. The same caveats apply as for oc_state_frarray_init().*/ - if(yplane_sz/yhstride!=yheight||2*cplane_sz<cplane_sz|| + if(yplane_sz/yhstride!=(size_t)yheight||2*cplane_sz+16<cplane_sz|| ref_frame_sz<yplane_sz||ref_frame_data_sz/_nrefs!=ref_frame_sz){ return TH_EIMPL; } - ref_frame_data=_ogg_malloc(ref_frame_data_sz); + ref_frame_data=oc_aligned_malloc(ref_frame_data_sz,16); frag_buf_offs=_state->frag_buf_offs= _ogg_malloc(_state->nfrags*sizeof(*frag_buf_offs)); if(ref_frame_data==NULL||frag_buf_offs==NULL){ _ogg_free(frag_buf_offs); - _ogg_free(ref_frame_data); + oc_aligned_free(ref_frame_data); return TH_EFAULT; } /*Set up the width, height and stride for the image buffers.*/ @@ -532,15 +610,15 @@ static int oc_state_ref_bufs_init(oc_theora_state *_state,int _nrefs){ memcpy(_state->ref_frame_bufs[rfi],_state->ref_frame_bufs[0], sizeof(_state->ref_frame_bufs[0])); } + _state->ref_frame_handle=ref_frame_data; /*Set up the data pointers for the image buffers.*/ for(rfi=0;rfi<_nrefs;rfi++){ - _state->ref_frame_data[rfi]=ref_frame_data; _state->ref_frame_bufs[rfi][0].data=ref_frame_data+yoffset; - ref_frame_data+=yplane_sz; + ref_frame_data+=yplane_sz+align; _state->ref_frame_bufs[rfi][1].data=ref_frame_data+coffset; ref_frame_data+=cplane_sz; _state->ref_frame_bufs[rfi][2].data=ref_frame_data+coffset; - ref_frame_data+=cplane_sz; + ref_frame_data+=cplane_sz+(16-align); /*Flip the buffer upside down. This allows us to decode Theora's bottom-up frames in their natural order, yet return a top-down buffer with a positive stride to the user.*/ @@ -550,7 +628,7 @@ static int oc_state_ref_bufs_init(oc_theora_state *_state,int _nrefs){ _state->ref_ystride[0]=-yhstride; _state->ref_ystride[1]=_state->ref_ystride[2]=-chstride; /*Initialize the fragment buffer offsets.*/ - ref_frame_data=_state->ref_frame_data[0]; + ref_frame_data=_state->ref_frame_bufs[0][0].data; fragi=0; for(pli=0;pli<3;pli++){ th_img_plane *iplane; @@ -576,41 +654,44 @@ static int oc_state_ref_bufs_init(oc_theora_state *_state,int _nrefs){ vpix+=stride<<3; } } - /*Initialize the reference frame indices.*/ + /*Initialize the reference frame pointers and indices.*/ _state->ref_frame_idx[OC_FRAME_GOLD]= _state->ref_frame_idx[OC_FRAME_PREV]= - _state->ref_frame_idx[OC_FRAME_SELF]=-1; - _state->ref_frame_idx[OC_FRAME_IO]=_nrefs>3?3:-1; + _state->ref_frame_idx[OC_FRAME_GOLD_ORIG]= + _state->ref_frame_idx[OC_FRAME_PREV_ORIG]= + _state->ref_frame_idx[OC_FRAME_SELF]= + _state->ref_frame_idx[OC_FRAME_IO]=-1; + _state->ref_frame_data[OC_FRAME_GOLD]= + _state->ref_frame_data[OC_FRAME_PREV]= + _state->ref_frame_data[OC_FRAME_GOLD_ORIG]= + _state->ref_frame_data[OC_FRAME_PREV_ORIG]= + _state->ref_frame_data[OC_FRAME_SELF]= + _state->ref_frame_data[OC_FRAME_IO]=NULL; return 0; } static void oc_state_ref_bufs_clear(oc_theora_state *_state){ _ogg_free(_state->frag_buf_offs); - _ogg_free(_state->ref_frame_data[0]); + oc_aligned_free(_state->ref_frame_handle); } -void oc_state_vtable_init_c(oc_theora_state *_state){ +void oc_state_accel_init_c(oc_theora_state *_state){ + _state->cpu_flags=0; +#if defined(OC_STATE_USE_VTABLE) _state->opt_vtable.frag_copy=oc_frag_copy_c; + _state->opt_vtable.frag_copy_list=oc_frag_copy_list_c; _state->opt_vtable.frag_recon_intra=oc_frag_recon_intra_c; _state->opt_vtable.frag_recon_inter=oc_frag_recon_inter_c; _state->opt_vtable.frag_recon_inter2=oc_frag_recon_inter2_c; _state->opt_vtable.idct8x8=oc_idct8x8_c; _state->opt_vtable.state_frag_recon=oc_state_frag_recon_c; - _state->opt_vtable.state_frag_copy_list=oc_state_frag_copy_list_c; + _state->opt_vtable.loop_filter_init=oc_loop_filter_init_c; _state->opt_vtable.state_loop_filter_frag_rows= oc_state_loop_filter_frag_rows_c; _state->opt_vtable.restore_fpu=oc_restore_fpu_c; - _state->opt_data.dct_fzig_zag=OC_FZIG_ZAG; -} - -/*Initialize the accelerated function pointers.*/ -void oc_state_vtable_init(oc_theora_state *_state){ -#if defined(OC_X86_ASM) - oc_state_vtable_init_x86(_state); -#else - oc_state_vtable_init_c(_state); #endif + _state->opt_data.dct_fzig_zag=OC_FZIG_ZAG; } @@ -626,7 +707,8 @@ int oc_state_init(oc_theora_state *_state,const th_info *_info,int _nrefs){ how it is specified in the bitstream, because the Y axis is flipped in the bitstream. The displayable frame must fit inside the encoded frame. - The color space must be one known by the encoder.*/ + The color space must be one known by the encoder. + The framerate ratio must not contain a zero value.*/ if((_info->frame_width&0xF)||(_info->frame_height&0xF)|| _info->frame_width<=0||_info->frame_width>=0x100000|| _info->frame_height<=0||_info->frame_height>=0x100000|| @@ -639,7 +721,8 @@ int oc_state_init(oc_theora_state *_state,const th_info *_info,int _nrefs){ but there are a number of compilers which will mis-optimize this. It's better to live with the spurious warnings.*/ _info->colorspace<0||_info->colorspace>=TH_CS_NSPACES|| - _info->pixel_fmt<0||_info->pixel_fmt>=TH_PF_NFORMATS){ + _info->pixel_fmt<0||_info->pixel_fmt>=TH_PF_NFORMATS|| + _info->fps_numerator<1||_info->fps_denominator<1){ return TH_EINVAL; } memset(_state,0,sizeof(*_state)); @@ -648,7 +731,7 @@ int oc_state_init(oc_theora_state *_state,const th_info *_info,int _nrefs){ system.*/ _state->info.pic_y=_info->frame_height-_info->pic_height-_info->pic_y; _state->frame_type=OC_UNKWN_FRAME; - oc_state_vtable_init(_state); + oc_state_accel_init(_state); ret=oc_state_frarray_init(_state); if(ret>=0)ret=oc_state_ref_bufs_init(_state,_nrefs); if(ret<0){ @@ -758,11 +841,10 @@ void oc_state_borders_fill(oc_theora_state *_state,int _refi){ _offsets[1] is set if the motion vector has non-zero fractional components. _pli: The color plane index. - _dx: The X component of the motion vector. - _dy: The Y component of the motion vector. + _mv: The motion vector. Return: The number of offsets returned: 1 or 2.*/ int oc_state_get_mv_offsets(const oc_theora_state *_state,int _offsets[2], - int _pli,int _dx,int _dy){ + int _pli,oc_mv _mv){ /*Here is a brief description of how Theora handles motion vectors: Motion vector components are specified to half-pixel accuracy in undecimated directions of each plane, and quarter-pixel accuracy in @@ -785,21 +867,25 @@ int oc_state_get_mv_offsets(const oc_theora_state *_state,int _offsets[2], int xfrac; int yfrac; int offs; + int dx; + int dy; ystride=_state->ref_ystride[_pli]; /*These two variables decide whether we are in half- or quarter-pixel precision in each component.*/ xprec=1+(_pli!=0&&!(_state->info.pixel_fmt&1)); yprec=1+(_pli!=0&&!(_state->info.pixel_fmt&2)); + dx=OC_MV_X(_mv); + dy=OC_MV_Y(_mv); /*These two variables are either 0 if all the fractional bits are zero or -1 if any of them are non-zero.*/ - xfrac=OC_SIGNMASK(-(_dx&(xprec|1))); - yfrac=OC_SIGNMASK(-(_dy&(yprec|1))); - offs=(_dx>>xprec)+(_dy>>yprec)*ystride; + xfrac=OC_SIGNMASK(-(dx&(xprec|1))); + yfrac=OC_SIGNMASK(-(dy&(yprec|1))); + offs=(dx>>xprec)+(dy>>yprec)*ystride; if(xfrac||yfrac){ int xmask; int ymask; - xmask=OC_SIGNMASK(_dx); - ymask=OC_SIGNMASK(_dy); + xmask=OC_SIGNMASK(dx); + ymask=OC_SIGNMASK(dy); yfrac&=ystride; _offsets[0]=offs-(xfrac&xmask)+(yfrac&ymask); _offsets[1]=offs-(xfrac&~xmask)+(yfrac&~ymask); @@ -848,13 +934,17 @@ int oc_state_get_mv_offsets(const oc_theora_state *_state,int _offsets[2], int mx2; int my2; int offs; + int dx; + int dy; ystride=_state->ref_ystride[_pli]; qpy=_pli!=0&&!(_state->info.pixel_fmt&2); - my=OC_MVMAP[qpy][_dy+31]; - my2=OC_MVMAP2[qpy][_dy+31]; + dx=OC_MV_X(_mv); + dy=OC_MV_Y(_mv); + my=OC_MVMAP[qpy][dy+31]; + my2=OC_MVMAP2[qpy][dy+31]; qpx=_pli!=0&&!(_state->info.pixel_fmt&1); - mx=OC_MVMAP[qpx][_dx+31]; - mx2=OC_MVMAP2[qpx][_dx+31]; + mx=OC_MVMAP[qpx][dx+31]; + mx2=OC_MVMAP2[qpx][dx+31]; offs=my*ystride+mx; if(mx2||my2){ _offsets[1]=offs+my2*ystride+mx2; @@ -866,18 +956,12 @@ int oc_state_get_mv_offsets(const oc_theora_state *_state,int _offsets[2], #endif } -void oc_state_frag_recon(const oc_theora_state *_state,ptrdiff_t _fragi, - int _pli,ogg_int16_t _dct_coeffs[64],int _last_zzi,ogg_uint16_t _dc_quant){ - _state->opt_vtable.state_frag_recon(_state,_fragi,_pli,_dct_coeffs, - _last_zzi,_dc_quant); -} - void oc_state_frag_recon_c(const oc_theora_state *_state,ptrdiff_t _fragi, - int _pli,ogg_int16_t _dct_coeffs[64],int _last_zzi,ogg_uint16_t _dc_quant){ + int _pli,ogg_int16_t _dct_coeffs[128],int _last_zzi,ogg_uint16_t _dc_quant){ unsigned char *dst; ptrdiff_t frag_buf_off; int ystride; - int mb_mode; + int refi; /*Apply the inverse transform.*/ /*Special case only having a DC component.*/ if(_last_zzi<2){ @@ -887,69 +971,35 @@ void oc_state_frag_recon_c(const oc_theora_state *_state,ptrdiff_t _fragi, no iDCT rounding.*/ p=(ogg_int16_t)(_dct_coeffs[0]*(ogg_int32_t)_dc_quant+15>>5); /*LOOP VECTORIZES.*/ - for(ci=0;ci<64;ci++)_dct_coeffs[ci]=p; + for(ci=0;ci<64;ci++)_dct_coeffs[64+ci]=p; } else{ /*First, dequantize the DC coefficient.*/ _dct_coeffs[0]=(ogg_int16_t)(_dct_coeffs[0]*(int)_dc_quant); - oc_idct8x8(_state,_dct_coeffs,_last_zzi); + oc_idct8x8(_state,_dct_coeffs+64,_dct_coeffs,_last_zzi); } /*Fill in the target buffer.*/ frag_buf_off=_state->frag_buf_offs[_fragi]; - mb_mode=_state->frags[_fragi].mb_mode; + refi=_state->frags[_fragi].refi; ystride=_state->ref_ystride[_pli]; - dst=_state->ref_frame_data[_state->ref_frame_idx[OC_FRAME_SELF]]+frag_buf_off; - if(mb_mode==OC_MODE_INTRA)oc_frag_recon_intra(_state,dst,ystride,_dct_coeffs); + dst=_state->ref_frame_data[OC_FRAME_SELF]+frag_buf_off; + if(refi==OC_FRAME_SELF)oc_frag_recon_intra(_state,dst,ystride,_dct_coeffs+64); else{ const unsigned char *ref; int mvoffsets[2]; - ref= - _state->ref_frame_data[_state->ref_frame_idx[OC_FRAME_FOR_MODE(mb_mode)]] - +frag_buf_off; + ref=_state->ref_frame_data[refi]+frag_buf_off; if(oc_state_get_mv_offsets(_state,mvoffsets,_pli, - _state->frag_mvs[_fragi][0],_state->frag_mvs[_fragi][1])>1){ + _state->frag_mvs[_fragi])>1){ oc_frag_recon_inter2(_state, - dst,ref+mvoffsets[0],ref+mvoffsets[1],ystride,_dct_coeffs); + dst,ref+mvoffsets[0],ref+mvoffsets[1],ystride,_dct_coeffs+64); + } + else{ + oc_frag_recon_inter(_state,dst,ref+mvoffsets[0],ystride,_dct_coeffs+64); } - else oc_frag_recon_inter(_state,dst,ref+mvoffsets[0],ystride,_dct_coeffs); - } -} - -/*Copies the fragments specified by the lists of fragment indices from one - frame to another. - _fragis: A pointer to a list of fragment indices. - _nfragis: The number of fragment indices to copy. - _dst_frame: The reference frame to copy to. - _src_frame: The reference frame to copy from. - _pli: The color plane the fragments lie in.*/ -void oc_state_frag_copy_list(const oc_theora_state *_state, - const ptrdiff_t *_fragis,ptrdiff_t _nfragis, - int _dst_frame,int _src_frame,int _pli){ - _state->opt_vtable.state_frag_copy_list(_state,_fragis,_nfragis,_dst_frame, - _src_frame,_pli); -} - -void oc_state_frag_copy_list_c(const oc_theora_state *_state, - const ptrdiff_t *_fragis,ptrdiff_t _nfragis, - int _dst_frame,int _src_frame,int _pli){ - const ptrdiff_t *frag_buf_offs; - const unsigned char *src_frame_data; - unsigned char *dst_frame_data; - ptrdiff_t fragii; - int ystride; - dst_frame_data=_state->ref_frame_data[_state->ref_frame_idx[_dst_frame]]; - src_frame_data=_state->ref_frame_data[_state->ref_frame_idx[_src_frame]]; - ystride=_state->ref_ystride[_pli]; - frag_buf_offs=_state->frag_buf_offs; - for(fragii=0;fragii<_nfragis;fragii++){ - ptrdiff_t frag_buf_off; - frag_buf_off=frag_buf_offs[_fragis[fragii]]; - oc_frag_copy(_state,dst_frame_data+frag_buf_off, - src_frame_data+frag_buf_off,ystride); } } -static void loop_filter_h(unsigned char *_pix,int _ystride,int *_bv){ +static void loop_filter_h(unsigned char *_pix,int _ystride,signed char *_bv){ int y; _pix-=2; for(y=0;y<8;y++){ @@ -965,7 +1015,7 @@ static void loop_filter_h(unsigned char *_pix,int _ystride,int *_bv){ } } -static void loop_filter_v(unsigned char *_pix,int _ystride,int *_bv){ +static void loop_filter_v(unsigned char *_pix,int _ystride,signed char *_bv){ int x; _pix-=_ystride*2; for(x=0;x<8;x++){ @@ -982,20 +1032,16 @@ static void loop_filter_v(unsigned char *_pix,int _ystride,int *_bv){ /*Initialize the bounding values array used by the loop filter. _bv: Storage for the array. - Return: 0 on success, or a non-zero value if no filtering need be applied.*/ -int oc_state_loop_filter_init(oc_theora_state *_state,int _bv[256]){ - int flimit; + _flimit: The filter limit as defined in Section 7.10 of the spec.*/ +void oc_loop_filter_init_c(signed char _bv[256],int _flimit){ int i; - flimit=_state->loop_filter_limits[_state->qis[0]]; - if(flimit==0)return 1; memset(_bv,0,sizeof(_bv[0])*256); - for(i=0;i<flimit;i++){ - if(127-i-flimit>=0)_bv[127-i-flimit]=i-flimit; - _bv[127-i]=-i; - _bv[127+i]=i; - if(127+i+flimit<256)_bv[127+i+flimit]=flimit-i; + for(i=0;i<_flimit;i++){ + if(127-i-_flimit>=0)_bv[127-i-_flimit]=(signed char)(i-_flimit); + _bv[127-i]=(signed char)(-i); + _bv[127+i]=(signed char)(i); + if(127+i+_flimit<256)_bv[127+i+_flimit]=(signed char)(_flimit-i); } - return 0; } /*Apply the loop filter to a given set of fragment rows in the given plane. @@ -1006,14 +1052,8 @@ int oc_state_loop_filter_init(oc_theora_state *_state,int _bv[256]){ _pli: The color plane to filter. _fragy0: The Y coordinate of the first fragment row to filter. _fragy_end: The Y coordinate of the fragment row to stop filtering at.*/ -void oc_state_loop_filter_frag_rows(const oc_theora_state *_state,int _bv[256], - int _refi,int _pli,int _fragy0,int _fragy_end){ - _state->opt_vtable.state_loop_filter_frag_rows(_state,_bv,_refi,_pli, - _fragy0,_fragy_end); -} - -void oc_state_loop_filter_frag_rows_c(const oc_theora_state *_state,int *_bv, - int _refi,int _pli,int _fragy0,int _fragy_end){ +void oc_state_loop_filter_frag_rows_c(const oc_theora_state *_state, + signed char *_bv,int _refi,int _pli,int _fragy0,int _fragy_end){ const oc_fragment_plane *fplane; const oc_fragment *frags; const ptrdiff_t *frag_buf_offs; @@ -1030,7 +1070,7 @@ void oc_state_loop_filter_frag_rows_c(const oc_theora_state *_state,int *_bv, fragi_top=fplane->froffset; fragi_bot=fragi_top+fplane->nfrags; fragi0=fragi_top+_fragy0*(ptrdiff_t)nhfrags; - fragi0_end=fragi0+(_fragy_end-_fragy0)*(ptrdiff_t)nhfrags; + fragi0_end=fragi_top+_fragy_end*(ptrdiff_t)nhfrags; ystride=_state->ref_ystride[_pli]; frags=_state->frags; frag_buf_offs=_state->frag_buf_offs; diff --git a/thirdparty/libtheora/state.h b/thirdparty/libtheora/state.h new file mode 100644 index 0000000000..f176a53ce9 --- /dev/null +++ b/thirdparty/libtheora/state.h @@ -0,0 +1,552 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * + * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * + * * + ******************************************************************** + + function: + last mod: $Id: internal.h 17337 2010-07-19 16:08:54Z tterribe $ + + ********************************************************************/ +#if !defined(_state_H) +# define _state_H (1) +# include "internal.h" +# include "huffman.h" +# include "quant.h" + + + +/*A single quadrant of the map from a super block to fragment numbers.*/ +typedef ptrdiff_t oc_sb_map_quad[4]; +/*A map from a super block to fragment numbers.*/ +typedef oc_sb_map_quad oc_sb_map[4]; +/*A single plane of the map from a macro block to fragment numbers.*/ +typedef ptrdiff_t oc_mb_map_plane[4]; +/*A map from a macro block to fragment numbers.*/ +typedef oc_mb_map_plane oc_mb_map[3]; +/*A motion vector.*/ +typedef ogg_int16_t oc_mv; + +typedef struct oc_sb_flags oc_sb_flags; +typedef struct oc_border_info oc_border_info; +typedef struct oc_fragment oc_fragment; +typedef struct oc_fragment_plane oc_fragment_plane; +typedef struct oc_base_opt_vtable oc_base_opt_vtable; +typedef struct oc_base_opt_data oc_base_opt_data; +typedef struct oc_state_dispatch_vtable oc_state_dispatch_vtable; +typedef struct oc_theora_state oc_theora_state; + + + +/*Shared accelerated functions.*/ +# if defined(OC_X86_ASM) +# if defined(_MSC_VER) +# include "x86_vc/x86int.h" +# else +# include "x86/x86int.h" +# endif +# endif +# if defined(OC_ARM_ASM) +# include "arm/armint.h" +# endif +# if defined(OC_C64X_ASM) +# include "c64x/c64xint.h" +# endif + +# if !defined(oc_state_accel_init) +# define oc_state_accel_init oc_state_accel_init_c +# endif +# if defined(OC_STATE_USE_VTABLE) +# if !defined(oc_frag_copy) +# define oc_frag_copy(_state,_dst,_src,_ystride) \ + ((*(_state)->opt_vtable.frag_copy)(_dst,_src,_ystride)) +# endif +# if !defined(oc_frag_copy_list) +# define oc_frag_copy_list(_state,_dst_frame,_src_frame,_ystride, \ + _fragis,_nfragis,_frag_buf_offs) \ + ((*(_state)->opt_vtable.frag_copy_list)(_dst_frame,_src_frame,_ystride, \ + _fragis,_nfragis,_frag_buf_offs)) +# endif +# if !defined(oc_frag_recon_intra) +# define oc_frag_recon_intra(_state,_dst,_dst_ystride,_residue) \ + ((*(_state)->opt_vtable.frag_recon_intra)(_dst,_dst_ystride,_residue)) +# endif +# if !defined(oc_frag_recon_inter) +# define oc_frag_recon_inter(_state,_dst,_src,_ystride,_residue) \ + ((*(_state)->opt_vtable.frag_recon_inter)(_dst,_src,_ystride,_residue)) +# endif +# if !defined(oc_frag_recon_inter2) +# define oc_frag_recon_inter2(_state,_dst,_src1,_src2,_ystride,_residue) \ + ((*(_state)->opt_vtable.frag_recon_inter2)(_dst, \ + _src1,_src2,_ystride,_residue)) +# endif +# if !defined(oc_idct8x8) +# define oc_idct8x8(_state,_y,_x,_last_zzi) \ + ((*(_state)->opt_vtable.idct8x8)(_y,_x,_last_zzi)) +# endif +# if !defined(oc_state_frag_recon) +# define oc_state_frag_recon(_state,_fragi, \ + _pli,_dct_coeffs,_last_zzi,_dc_quant) \ + ((*(_state)->opt_vtable.state_frag_recon)(_state,_fragi, \ + _pli,_dct_coeffs,_last_zzi,_dc_quant)) +# endif +# if !defined(oc_loop_filter_init) +# define oc_loop_filter_init(_state,_bv,_flimit) \ + ((*(_state)->opt_vtable.loop_filter_init)(_bv,_flimit)) +# endif +# if !defined(oc_state_loop_filter_frag_rows) +# define oc_state_loop_filter_frag_rows(_state, \ + _bv,_refi,_pli,_fragy0,_fragy_end) \ + ((*(_state)->opt_vtable.state_loop_filter_frag_rows)(_state, \ + _bv,_refi,_pli,_fragy0,_fragy_end)) +# endif +# if !defined(oc_restore_fpu) +# define oc_restore_fpu(_state) \ + ((*(_state)->opt_vtable.restore_fpu)()) +# endif +# else +# if !defined(oc_frag_copy) +# define oc_frag_copy(_state,_dst,_src,_ystride) \ + oc_frag_copy_c(_dst,_src,_ystride) +# endif +# if !defined(oc_frag_copy_list) +# define oc_frag_copy_list(_state,_dst_frame,_src_frame,_ystride, \ + _fragis,_nfragis,_frag_buf_offs) \ + oc_frag_copy_list_c(_dst_frame,_src_frame,_ystride, \ + _fragis,_nfragis,_frag_buf_offs) +# endif +# if !defined(oc_frag_recon_intra) +# define oc_frag_recon_intra(_state,_dst,_dst_ystride,_residue) \ + oc_frag_recon_intra_c(_dst,_dst_ystride,_residue) +# endif +# if !defined(oc_frag_recon_inter) +# define oc_frag_recon_inter(_state,_dst,_src,_ystride,_residue) \ + oc_frag_recon_inter_c(_dst,_src,_ystride,_residue) +# endif +# if !defined(oc_frag_recon_inter2) +# define oc_frag_recon_inter2(_state,_dst,_src1,_src2,_ystride,_residue) \ + oc_frag_recon_inter2_c(_dst,_src1,_src2,_ystride,_residue) +# endif +# if !defined(oc_idct8x8) +# define oc_idct8x8(_state,_y,_x,_last_zzi) oc_idct8x8_c(_y,_x,_last_zzi) +# endif +# if !defined(oc_state_frag_recon) +# define oc_state_frag_recon oc_state_frag_recon_c +# endif +# if !defined(oc_loop_filter_init) +# define oc_loop_filter_init(_state,_bv,_flimit) \ + oc_loop_filter_init_c(_bv,_flimit) +# endif +# if !defined(oc_state_loop_filter_frag_rows) +# define oc_state_loop_filter_frag_rows oc_state_loop_filter_frag_rows_c +# endif +# if !defined(oc_restore_fpu) +# define oc_restore_fpu(_state) do{}while(0) +# endif +# endif + + + +/*A keyframe.*/ +# define OC_INTRA_FRAME (0) +/*A predicted frame.*/ +# define OC_INTER_FRAME (1) +/*A frame of unknown type (frame type decision has not yet been made).*/ +# define OC_UNKWN_FRAME (-1) + +/*The amount of padding to add to the reconstructed frame buffers on all + sides. + This is used to allow unrestricted motion vectors without special casing. + This must be a multiple of 2.*/ +# define OC_UMV_PADDING (16) + +/*Frame classification indices.*/ +/*The previous golden frame.*/ +# define OC_FRAME_GOLD (0) +/*The previous frame.*/ +# define OC_FRAME_PREV (1) +/*The current frame.*/ +# define OC_FRAME_SELF (2) +/*Used to mark uncoded fragments (for DC prediction).*/ +# define OC_FRAME_NONE (3) + +/*The input or output buffer.*/ +# define OC_FRAME_IO (3) +/*Uncompressed prev golden frame.*/ +# define OC_FRAME_GOLD_ORIG (4) +/*Uncompressed previous frame. */ +# define OC_FRAME_PREV_ORIG (5) + +/*Macroblock modes.*/ +/*Macro block is invalid: It is never coded.*/ +# define OC_MODE_INVALID (-1) +/*Encoded difference from the same macro block in the previous frame.*/ +# define OC_MODE_INTER_NOMV (0) +/*Encoded with no motion compensated prediction.*/ +# define OC_MODE_INTRA (1) +/*Encoded difference from the previous frame offset by the given motion + vector.*/ +# define OC_MODE_INTER_MV (2) +/*Encoded difference from the previous frame offset by the last coded motion + vector.*/ +# define OC_MODE_INTER_MV_LAST (3) +/*Encoded difference from the previous frame offset by the second to last + coded motion vector.*/ +# define OC_MODE_INTER_MV_LAST2 (4) +/*Encoded difference from the same macro block in the previous golden + frame.*/ +# define OC_MODE_GOLDEN_NOMV (5) +/*Encoded difference from the previous golden frame offset by the given motion + vector.*/ +# define OC_MODE_GOLDEN_MV (6) +/*Encoded difference from the previous frame offset by the individual motion + vectors given for each block.*/ +# define OC_MODE_INTER_MV_FOUR (7) +/*The number of (coded) modes.*/ +# define OC_NMODES (8) + +/*Determines the reference frame used for a given MB mode.*/ +# define OC_FRAME_FOR_MODE(_x) \ + OC_UNIBBLE_TABLE32(OC_FRAME_PREV,OC_FRAME_SELF,OC_FRAME_PREV,OC_FRAME_PREV, \ + OC_FRAME_PREV,OC_FRAME_GOLD,OC_FRAME_GOLD,OC_FRAME_PREV,(_x)) + +/*Constants for the packet state machine common between encoder and decoder.*/ + +/*Next packet to emit/read: Codec info header.*/ +# define OC_PACKET_INFO_HDR (-3) +/*Next packet to emit/read: Comment header.*/ +# define OC_PACKET_COMMENT_HDR (-2) +/*Next packet to emit/read: Codec setup header.*/ +# define OC_PACKET_SETUP_HDR (-1) +/*No more packets to emit/read.*/ +# define OC_PACKET_DONE (INT_MAX) + + + +#define OC_MV(_x,_y) ((oc_mv)((_x)&0xFF|(_y)<<8)) +#define OC_MV_X(_mv) ((signed char)(_mv)) +#define OC_MV_Y(_mv) ((_mv)>>8) +#define OC_MV_ADD(_mv1,_mv2) \ + OC_MV(OC_MV_X(_mv1)+OC_MV_X(_mv2), \ + OC_MV_Y(_mv1)+OC_MV_Y(_mv2)) +#define OC_MV_SUB(_mv1,_mv2) \ + OC_MV(OC_MV_X(_mv1)-OC_MV_X(_mv2), \ + OC_MV_Y(_mv1)-OC_MV_Y(_mv2)) + + + +/*Super blocks are 32x32 segments of pixels in a single color plane indexed + in image order. + Internally, super blocks are broken up into four quadrants, each of which + contains a 2x2 pattern of blocks, each of which is an 8x8 block of pixels. + Quadrants, and the blocks within them, are indexed in a special order called + a "Hilbert curve" within the super block. + + In order to differentiate between the Hilbert-curve indexing strategy and + the regular image order indexing strategy, blocks indexed in image order + are called "fragments". + Fragments are indexed in image order, left to right, then bottom to top, + from Y' plane to Cb plane to Cr plane. + + The co-located fragments in all image planes corresponding to the location + of a single quadrant of a luma plane super block form a macro block. + Thus there is only a single set of macro blocks for all planes, each of which + contains between 6 and 12 fragments, depending on the pixel format. + Therefore macro block information is kept in a separate set of arrays from + super blocks to avoid unused space in the other planes. + The lists are indexed in super block order. + That is, the macro block corresponding to the macro block mbi in (luma plane) + super block sbi is at index (sbi<<2|mbi). + Thus the number of macro blocks in each dimension is always twice the number + of super blocks, even when only an odd number fall inside the coded frame. + These "extra" macro blocks are just an artifact of our internal data layout, + and not part of the coded stream; they are flagged with a negative MB mode.*/ + + + +/*Super block information.*/ +struct oc_sb_flags{ + unsigned char coded_fully:1; + unsigned char coded_partially:1; + unsigned char quad_valid:4; +}; + + + +/*Information about a fragment which intersects the border of the displayable + region. + This marks which pixels belong to the displayable region.*/ +struct oc_border_info{ + /*A bit mask marking which pixels are in the displayable region. + Pixel (x,y) corresponds to bit (y<<3|x).*/ + ogg_int64_t mask; + /*The number of pixels in the displayable region. + This is always positive, and always less than 64.*/ + int npixels; +}; + + + +/*Fragment information.*/ +struct oc_fragment{ + /*A flag indicating whether or not this fragment is coded.*/ + unsigned coded:1; + /*A flag indicating that this entire fragment lies outside the displayable + region of the frame. + Note the contrast with an invalid macro block, which is outside the coded + frame, not just the displayable one. + There are no fragments outside the coded frame by construction.*/ + unsigned invalid:1; + /*The index of the quality index used for this fragment's AC coefficients.*/ + unsigned qii:4; + /*The index of the reference frame this fragment is predicted from.*/ + unsigned refi:2; + /*The mode of the macroblock this fragment belongs to.*/ + unsigned mb_mode:3; + /*The index of the associated border information for fragments which lie + partially outside the displayable region. + For fragments completely inside or outside this region, this is -1. + Note that the C standard requires an explicit signed keyword for bitfield + types, since some compilers may treat them as unsigned without it.*/ + signed int borderi:5; + /*The prediction-corrected DC component. + Note that the C standard requires an explicit signed keyword for bitfield + types, since some compilers may treat them as unsigned without it.*/ + signed int dc:16; +}; + + + +/*A description of each fragment plane.*/ +struct oc_fragment_plane{ + /*The number of fragments in the horizontal direction.*/ + int nhfrags; + /*The number of fragments in the vertical direction.*/ + int nvfrags; + /*The offset of the first fragment in the plane.*/ + ptrdiff_t froffset; + /*The total number of fragments in the plane.*/ + ptrdiff_t nfrags; + /*The number of super blocks in the horizontal direction.*/ + unsigned nhsbs; + /*The number of super blocks in the vertical direction.*/ + unsigned nvsbs; + /*The offset of the first super block in the plane.*/ + unsigned sboffset; + /*The total number of super blocks in the plane.*/ + unsigned nsbs; +}; + + +typedef void (*oc_state_loop_filter_frag_rows_func)( + const oc_theora_state *_state,signed char _bv[256],int _refi,int _pli, + int _fragy0,int _fragy_end); + +/*The shared (encoder and decoder) functions that have accelerated variants.*/ +struct oc_base_opt_vtable{ + void (*frag_copy)(unsigned char *_dst, + const unsigned char *_src,int _ystride); + void (*frag_copy_list)(unsigned char *_dst_frame, + const unsigned char *_src_frame,int _ystride, + const ptrdiff_t *_fragis,ptrdiff_t _nfragis,const ptrdiff_t *_frag_buf_offs); + void (*frag_recon_intra)(unsigned char *_dst,int _ystride, + const ogg_int16_t _residue[64]); + void (*frag_recon_inter)(unsigned char *_dst, + const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]); + void (*frag_recon_inter2)(unsigned char *_dst,const unsigned char *_src1, + const unsigned char *_src2,int _ystride,const ogg_int16_t _residue[64]); + void (*idct8x8)(ogg_int16_t _y[64],ogg_int16_t _x[64],int _last_zzi); + void (*state_frag_recon)(const oc_theora_state *_state,ptrdiff_t _fragi, + int _pli,ogg_int16_t _dct_coeffs[128],int _last_zzi,ogg_uint16_t _dc_quant); + void (*loop_filter_init)(signed char _bv[256],int _flimit); + oc_state_loop_filter_frag_rows_func state_loop_filter_frag_rows; + void (*restore_fpu)(void); +}; + +/*The shared (encoder and decoder) tables that vary according to which variants + of the above functions are used.*/ +struct oc_base_opt_data{ + const unsigned char *dct_fzig_zag; +}; + + +/*State information common to both the encoder and decoder.*/ +struct oc_theora_state{ + /*The stream information.*/ + th_info info; +# if defined(OC_STATE_USE_VTABLE) + /*Table for shared accelerated functions.*/ + oc_base_opt_vtable opt_vtable; +# endif + /*Table for shared data used by accelerated functions.*/ + oc_base_opt_data opt_data; + /*CPU flags to detect the presence of extended instruction sets.*/ + ogg_uint32_t cpu_flags; + /*The fragment plane descriptions.*/ + oc_fragment_plane fplanes[3]; + /*The list of fragments, indexed in image order.*/ + oc_fragment *frags; + /*The the offset into the reference frame buffer to the upper-left pixel of + each fragment.*/ + ptrdiff_t *frag_buf_offs; + /*The motion vector for each fragment.*/ + oc_mv *frag_mvs; + /*The total number of fragments in a single frame.*/ + ptrdiff_t nfrags; + /*The list of super block maps, indexed in image order.*/ + oc_sb_map *sb_maps; + /*The list of super block flags, indexed in image order.*/ + oc_sb_flags *sb_flags; + /*The total number of super blocks in a single frame.*/ + unsigned nsbs; + /*The fragments from each color plane that belong to each macro block. + Fragments are stored in image order (left to right then top to bottom). + When chroma components are decimated, the extra fragments have an index of + -1.*/ + oc_mb_map *mb_maps; + /*The list of macro block modes. + A negative number indicates the macro block lies entirely outside the + coded frame.*/ + signed char *mb_modes; + /*The number of macro blocks in the X direction.*/ + unsigned nhmbs; + /*The number of macro blocks in the Y direction.*/ + unsigned nvmbs; + /*The total number of macro blocks.*/ + size_t nmbs; + /*The list of coded fragments, in coded order. + Uncoded fragments are stored in reverse order from the end of the list.*/ + ptrdiff_t *coded_fragis; + /*The number of coded fragments in each plane.*/ + ptrdiff_t ncoded_fragis[3]; + /*The total number of coded fragments.*/ + ptrdiff_t ntotal_coded_fragis; + /*The actual buffers used for the reference frames.*/ + th_ycbcr_buffer ref_frame_bufs[6]; + /*The index of the buffers being used for each OC_FRAME_* reference frame.*/ + int ref_frame_idx[6]; + /*The storage for the reference frame buffers. + This is just ref_frame_bufs[ref_frame_idx[i]][0].data, but is cached here + for faster look-up.*/ + unsigned char *ref_frame_data[6]; + /*The handle used to allocate the reference frame buffers.*/ + unsigned char *ref_frame_handle; + /*The strides for each plane in the reference frames.*/ + int ref_ystride[3]; + /*The number of unique border patterns.*/ + int nborders; + /*The unique border patterns for all border fragments. + The borderi field of fragments which straddle the border indexes this + list.*/ + oc_border_info borders[16]; + /*The frame number of the last keyframe.*/ + ogg_int64_t keyframe_num; + /*The frame number of the current frame.*/ + ogg_int64_t curframe_num; + /*The granpos of the current frame.*/ + ogg_int64_t granpos; + /*The type of the current frame.*/ + signed char frame_type; + /*The bias to add to the frame count when computing granule positions.*/ + unsigned char granpos_bias; + /*The number of quality indices used in the current frame.*/ + unsigned char nqis; + /*The quality indices of the current frame.*/ + unsigned char qis[3]; + /*The dequantization tables, stored in zig-zag order, and indexed by + qi, pli, qti, and zzi.*/ + ogg_uint16_t *dequant_tables[64][3][2]; + OC_ALIGN16(oc_quant_table dequant_table_data[64][3][2]); + /*Loop filter strength parameters.*/ + unsigned char loop_filter_limits[64]; +}; + + + +/*The function type used to fill in the chroma plane motion vectors for a + macro block when 4 different motion vectors are specified in the luma + plane. + _cbmvs: The chroma block-level motion vectors to fill in. + _lmbmv: The luma macro-block level motion vector to fill in for use in + prediction. + _lbmvs: The luma block-level motion vectors.*/ +typedef void (*oc_set_chroma_mvs_func)(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]); + + + +/*A table of functions used to fill in the Cb,Cr plane motion vectors for a + macro block when 4 different motion vectors are specified in the luma + plane.*/ +extern const oc_set_chroma_mvs_func OC_SET_CHROMA_MVS_TABLE[TH_PF_NFORMATS]; + + + +int oc_state_init(oc_theora_state *_state,const th_info *_info,int _nrefs); +void oc_state_clear(oc_theora_state *_state); +void oc_state_accel_init_c(oc_theora_state *_state); +void oc_state_borders_fill_rows(oc_theora_state *_state,int _refi,int _pli, + int _y0,int _yend); +void oc_state_borders_fill_caps(oc_theora_state *_state,int _refi,int _pli); +void oc_state_borders_fill(oc_theora_state *_state,int _refi); +void oc_state_fill_buffer_ptrs(oc_theora_state *_state,int _buf_idx, + th_ycbcr_buffer _img); +int oc_state_mbi_for_pos(oc_theora_state *_state,int _mbx,int _mby); +int oc_state_get_mv_offsets(const oc_theora_state *_state,int _offsets[2], + int _pli,oc_mv _mv); + +void oc_loop_filter_init_c(signed char _bv[256],int _flimit); +void oc_state_loop_filter(oc_theora_state *_state,int _frame); +# if defined(OC_DUMP_IMAGES) +int oc_state_dump_frame(const oc_theora_state *_state,int _frame, + const char *_suf); +# endif + +/*Default pure-C implementations of shared accelerated functions.*/ +void oc_frag_copy_c(unsigned char *_dst, + const unsigned char *_src,int _src_ystride); +void oc_frag_copy_list_c(unsigned char *_dst_frame, + const unsigned char *_src_frame,int _ystride, + const ptrdiff_t *_fragis,ptrdiff_t _nfragis,const ptrdiff_t *_frag_buf_offs); +void oc_frag_recon_intra_c(unsigned char *_dst,int _dst_ystride, + const ogg_int16_t _residue[64]); +void oc_frag_recon_inter_c(unsigned char *_dst, + const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]); +void oc_frag_recon_inter2_c(unsigned char *_dst,const unsigned char *_src1, + const unsigned char *_src2,int _ystride,const ogg_int16_t _residue[64]); +void oc_idct8x8_c(ogg_int16_t _y[64],ogg_int16_t _x[64],int _last_zzi); +void oc_state_frag_recon_c(const oc_theora_state *_state,ptrdiff_t _fragi, + int _pli,ogg_int16_t _dct_coeffs[128],int _last_zzi,ogg_uint16_t _dc_quant); +void oc_state_loop_filter_frag_rows_c(const oc_theora_state *_state, + signed char _bv[256],int _refi,int _pli,int _fragy0,int _fragy_end); +void oc_restore_fpu_c(void); + +/*We need a way to call a few encoder functions without introducing a link-time + dependency into the decoder, while still allowing the old alpha API which + does not distinguish between encoder and decoder objects to be used. + We do this by placing a function table at the start of the encoder object + which can dispatch into the encoder library. + We do a similar thing for the decoder in case we ever decide to split off a + common base library.*/ +typedef void (*oc_state_clear_func)(theora_state *_th); +typedef int (*oc_state_control_func)(theora_state *th,int _req, + void *_buf,size_t _buf_sz); +typedef ogg_int64_t (*oc_state_granule_frame_func)(theora_state *_th, + ogg_int64_t _granulepos); +typedef double (*oc_state_granule_time_func)(theora_state *_th, + ogg_int64_t _granulepos); + + +struct oc_state_dispatch_vtable{ + oc_state_clear_func clear; + oc_state_control_func control; + oc_state_granule_frame_func granule_frame; + oc_state_granule_time_func granule_time; +}; + +#endif diff --git a/thirdparty/libtheora/theora/codec.h b/thirdparty/libtheora/theora/codec.h index 5c2669630c..29b8602325 100644 --- a/thirdparty/libtheora/theora/codec.h +++ b/thirdparty/libtheora/theora/codec.h @@ -16,11 +16,12 @@ ********************************************************************/ /**\mainpage - * + * * \section intro Introduction * - * This is the documentation for <tt>libtheora</tt> C API. - * The current reference + * This is the documentation for the <tt>libtheora</tt> C API. + * + * The \c libtheora package is the current reference * implementation for <a href="http://www.theora.org/">Theora</a>, a free, * patent-unencumbered video codec. * Theora is derived from On2's VP3 codec with additional features and @@ -30,29 +31,31 @@ * <a href="http://www.theora.org/doc/Theora.pdf">the Theora * specification</a>. * - * \subsection Organization + * \section Organization * - * The functions documented here are actually subdivided into three + * The functions documented here are divided between two * separate libraries: - * - <tt>libtheoraenc</tt> contains the encoder interface, + * - \c libtheoraenc contains the encoder interface, * described in \ref encfuncs. - * - <tt>libtheoradec</tt> contains the decoder interface and - * routines shared with the encoder. - * You must also link to this if you link to <tt>libtheoraenc</tt>. - * The routines in this library are described in \ref decfuncs and - * \ref basefuncs. - * - <tt>libtheora</tt> contains the \ref oldfuncs. + * - \c libtheoradec contains the decoder interface, + * described in \ref decfuncs, \n + * and additional \ref basefuncs. + * + * New code should link to \c libtheoradec. If using encoder + * features, it must also link to \c libtheoraenc. * - * New code should link to <tt>libtheoradec</tt> and, if using encoder - * features, <tt>libtheoraenc</tt>. Together these two export both - * the standard and the legacy API, so this is all that is needed by - * any code. The older <tt>libtheora</tt> library is provided just for - * compatibility with older build configurations. + * During initial development, prior to the 1.0 release, + * \c libtheora exported a different \ref oldfuncs which + * combined both encode and decode functions. + * In general, legacy API symbols can be indentified + * by their \c theora_ or \c OC_ namespace prefixes. + * The current API uses \c th_ or \c TH_ instead. * - * In general the recommended 1.x API symbols can be distinguished - * by their <tt>th_</tt> or <tt>TH_</tt> namespace prefix. - * The older, legacy API uses <tt>theora_</tt> or <tt>OC_</tt> - * prefixes instead. + * While deprecated, \c libtheoraenc and \c libtheoradec + * together export the legacy api as well at the one documented above. + * Likewise, the legacy \c libtheora included with this package + * exports the new 1.x API. Older code and build scripts can therefore + * but updated independently to the current scheme. */ /**\file @@ -168,7 +171,7 @@ typedef struct{ typedef th_img_plane th_ycbcr_buffer[3]; /**Theora bitstream information. - * This contains the basic playback parameters for a stream, and corresponds to + * This contains the basic playback parameters for a stream, and corresponds to * the initial 'info' header packet. * To initialize an encoder, the application fills in this structure and * passes it to th_encode_alloc(). @@ -317,7 +320,7 @@ typedef struct{ * In filling in this structure, th_decode_headerin() will null-terminate * the user_comment strings for safety. * However, the bitstream format itself treats them as 8-bit clean vectors, - * possibly containing null characters, and so the length array should be + * possibly containing null characters, so the length array should be * treated as their authoritative length. */ typedef struct th_comment{ @@ -448,7 +451,13 @@ typedef struct{ /**\defgroup basefuncs Functions Shared by Encode and Decode*/ /*@{*/ -/**\name Basic shared functions*/ +/**\name Basic shared functions + * These functions return information about the library itself, + * or provide high-level information about codec state + * and packet type. + * + * You must link to \c libtheoradec if you use any of the + * functions in this section.*/ /*@{*/ /**Retrieves a human-readable string to identify the library vendor and * version. @@ -510,7 +519,12 @@ extern int th_packet_iskeyframe(ogg_packet *_op); /*@}*/ -/**\name Functions for manipulating header data*/ +/**\name Functions for manipulating header data + * These functions manipulate the #th_info and #th_comment structures + * which describe video parameters and key-value metadata, respectively. + * + * You must link to \c libtheoradec if you use any of the + * functions in this section.*/ /*@{*/ /**Initializes a th_info structure. * This should be called on a freshly allocated #th_info structure before @@ -537,7 +551,7 @@ extern void th_comment_init(th_comment *_tc); * \param _tc The #th_comment struct to add the comment to. * \param _comment Must be a null-terminated UTF-8 string containing the * comment in "TAG=the value" form.*/ -extern void th_comment_add(th_comment *_tc, char *_comment); +extern void th_comment_add(th_comment *_tc,const char *_comment); /**Add a comment to an initialized #th_comment structure. * \note Neither th_comment_add() nor th_comment_add_tag() support * comments containing null values, although the bitstream format does @@ -545,10 +559,11 @@ extern void th_comment_add(th_comment *_tc, char *_comment); * To add such comments you will need to manipulate the #th_comment * structure directly. * \param _tc The #th_comment struct to add the comment to. - * \param _tag A null-terminated string containing the tag associated with + * \param _tag A null-terminated string containing the tag associated with * the comment. * \param _val The corresponding value as a null-terminated string.*/ -extern void th_comment_add_tag(th_comment *_tc,char *_tag,char *_val); +extern void th_comment_add_tag(th_comment *_tc,const char *_tag, + const char *_val); /**Look up a comment value by its tag. * \param _tc An initialized #th_comment structure. * \param _tag The tag to look up. @@ -564,15 +579,15 @@ extern void th_comment_add_tag(th_comment *_tc,char *_tag,char *_val); * It should not be modified or freed by the application, and * modifications to the structure may invalidate the pointer. * \retval NULL If no matching tag is found.*/ -extern char *th_comment_query(th_comment *_tc,char *_tag,int _count); +extern char *th_comment_query(th_comment *_tc,const char *_tag,int _count); /**Look up the number of instances of a tag. * Call this first when querying for a specific tag and then iterate over the * number of instances with separate calls to th_comment_query() to * retrieve all the values for that tag in order. * \param _tc An initialized #th_comment structure. * \param _tag The tag to look up. - * \return The number on instances of this particular tag.*/ -extern int th_comment_query_count(th_comment *_tc,char *_tag); + * \return The number of instances of this particular tag.*/ +extern int th_comment_query_count(th_comment *_tc,const char *_tag); /**Clears a #th_comment structure. * This should be called on a #th_comment structure after it is no longer * needed. diff --git a/thirdparty/libtheora/theora/theora.h b/thirdparty/libtheora/theora/theora.h index af6eb6f380..a729a76890 100644 --- a/thirdparty/libtheora/theora/theora.h +++ b/thirdparty/libtheora/theora/theora.h @@ -34,41 +34,41 @@ extern "C" * * \section intro Introduction * - * This is the documentation for the libtheora legacy C API, declared in + * This is the documentation for the libtheora legacy C API, declared in * the theora.h header, which describes the old interface used before * the 1.0 release. This API was widely deployed for several years and - * remains supported, but for new code we recommend the cleaner API + * remains supported, but for new code we recommend the cleaner API * declared in theoradec.h and theoraenc.h. * * libtheora is the reference implementation for * <a href="http://www.theora.org/">Theora</a>, a free video codec. * Theora is derived from On2's VP3 codec with improved integration with * Ogg multimedia formats by <a href="http://www.xiph.org/">Xiph.Org</a>. - * + * * \section overview Overview * - * This library will both decode and encode theora packets to/from raw YUV + * This library will both decode and encode theora packets to/from raw YUV * frames. In either case, the packets will most likely either come from or - * need to be embedded in an Ogg stream. Use - * <a href="http://xiph.org/ogg/">libogg</a> or + * need to be embedded in an Ogg stream. Use + * <a href="http://xiph.org/ogg/">libogg</a> or * <a href="http://www.annodex.net/software/liboggz/index.html">liboggz</a> * to extract/package these packets. * * \section decoding Decoding Process * * Decoding can be separated into the following steps: - * -# initialise theora_info and theora_comment structures using + * -# initialise theora_info and theora_comment structures using * theora_info_init() and theora_comment_init(): \verbatim theora_info info; theora_comment comment; - + theora_info_init(&info); theora_comment_init(&comment); \endverbatim - * -# retrieve header packets from Ogg stream (there should be 3) and decode - * into theora_info and theora_comment structures using - * theora_decode_header(). See \ref identification for more information on + * -# retrieve header packets from Ogg stream (there should be 3) and decode + * into theora_info and theora_comment structures using + * theora_decode_header(). See \ref identification for more information on * identifying which packets are theora packets. \verbatim int i; @@ -79,14 +79,14 @@ extern "C" } \endverbatim * -# initialise the decoder based on the information retrieved into the - * theora_info struct by theora_decode_header(). You will need a + * theora_info struct by theora_decode_header(). You will need a * theora_state struct. \verbatim theora_state state; - + theora_decode_init(&state, &info); \endverbatim - * -# pass in packets and retrieve decoded frames! See the yuv_buffer + * -# pass in packets and retrieve decoded frames! See the yuv_buffer * documentation for information on how to retrieve raw YUV data. \verbatim yuf_buffer buffer; @@ -96,20 +96,20 @@ extern "C" theora_decode_YUVout(&state, &buffer); } \endverbatim - * + * * * \subsection identification Identifying Theora Packets * - * All streams inside an Ogg file have a unique serial_no attached to the - * stream. Typically, you will want to - * - retrieve the serial_no for each b_o_s (beginning of stream) page - * encountered within the Ogg file; - * - test the first (only) packet on that page to determine if it is a theora + * All streams inside an Ogg file have a unique serial_no attached to the + * stream. Typically, you will want to + * - retrieve the serial_no for each b_o_s (beginning of stream) page + * encountered within the Ogg file; + * - test the first (only) packet on that page to determine if it is a theora * packet; - * - once you have found a theora b_o_s page then use the retrieved serial_no + * - once you have found a theora b_o_s page then use the retrieved serial_no * to identify future packets belonging to the same theora stream. - * - * Note that you \e cannot use theora_packet_isheader() to determine if a + * + * Note that you \e cannot use theora_packet_isheader() to determine if a * packet is a theora packet or not, as this function does not perform any * checking beyond whether a header bit is present. Instead, use the * theora_decode_header() function and check the return value; or examine the @@ -124,9 +124,9 @@ extern "C" * A YUV buffer for passing uncompressed frames to and from the codec. * This holds a Y'CbCr frame in planar format. The CbCr planes can be * subsampled and have their own separate dimensions and row stride - * offsets. Note that the strides may be negative in some + * offsets. Note that the strides may be negative in some * configurations. For theora the width and height of the largest plane - * must be a multiple of 16. The actual meaningful picture size and + * must be a multiple of 16. The actual meaningful picture size and * offset are stored in the theora_info structure; frames returned by * the decoder may need to be cropped for display. * @@ -135,8 +135,8 @@ extern "C" * are ordered from left to right. * * During decode, the yuv_buffer struct is allocated by the user, but all - * fields (including luma and chroma pointers) are filled by the library. - * These pointers address library-internal memory and their contents should + * fields (including luma and chroma pointers) are filled by the library. + * These pointers address library-internal memory and their contents should * not be modified. * * Conversely, during encode the user allocates the struct and fills out all @@ -179,14 +179,14 @@ typedef enum { OC_PF_420, /**< Chroma subsampling by 2 in each direction (4:2:0) */ OC_PF_RSVD, /**< Reserved value */ OC_PF_422, /**< Horizonatal chroma subsampling by 2 (4:2:2) */ - OC_PF_444, /**< No chroma subsampling at all (4:4:4) */ + OC_PF_444 /**< No chroma subsampling at all (4:4:4) */ } theora_pixelformat; /** * Theora bitstream info. * Contains the basic playback parameters for a stream, * corresponding to the initial 'info' header packet. - * + * * Encoded theora frames must be a multiple of 16 in width and height. * To handle other frame sizes, a crop rectangle is specified in * frame_height and frame_width, offset_x and * offset_y. The offset @@ -198,10 +198,10 @@ typedef enum { * fraction. Aspect ratio is also stored as a rational fraction, and * refers to the aspect ratio of the frame pixels, not of the * overall frame itself. - * + * * See <a href="http://svn.xiph.org/trunk/theora/examples/encoder_example.c"> * examples/encoder_example.c</a> for usage examples of the - * other paramters and good default settings for the encoder parameters. + * other parameters and good default settings for the encoder parameters. */ typedef struct { ogg_uint32_t width; /**< encoded frame width */ @@ -253,14 +253,14 @@ typedef struct{ } theora_state; -/** +/** * Comment header metadata. * * This structure holds the in-stream metadata corresponding to * the 'comment' header packet. * * Meta data is stored as a series of (tag, value) pairs, in - * length-encoded string vectors. The first occurence of the + * length-encoded string vectors. The first occurence of the * '=' character delimits the tag and value. A particular tag * may occur more than once. The character set encoding for * the strings is always UTF-8, but the tag names are limited @@ -285,7 +285,7 @@ typedef struct theora_comment{ /* \anchor decctlcodes_old * These are the available request codes for theora_control() * when called with a decoder instance. - * By convention decoder control codes are odd, to distinguish + * By convention decoder control codes are odd, to distinguish * them from \ref encctlcodes_old "encoder control codes" which * are even. * @@ -306,7 +306,7 @@ typedef struct theora_comment{ #define TH_DECCTL_GET_PPLEVEL_MAX (1) /**Set the post-processing level. - * Sets the level of post-processing to use when decoding the + * Sets the level of post-processing to use when decoding the * compressed stream. This must be a value between zero (off) * and the maximum returned by TH_DECCTL_GET_PPLEVEL_MAX. */ @@ -345,9 +345,9 @@ typedef struct theora_comment{ * \param[in] buf #th_quant_info * \retval OC_FAULT \a theora_state is <tt>NULL</tt>. * \retval OC_EINVAL Encoding has already begun, the quantization parameters - * are not acceptable to this version of the encoder, - * \a buf is <tt>NULL</tt> and \a buf_sz is not zero, - * or \a buf is non-<tt>NULL</tt> and \a buf_sz is + * are not acceptable to this version of the encoder, + * \a buf is <tt>NULL</tt> and \a buf_sz is not zero, + * or \a buf is non-<tt>NULL</tt> and \a buf_sz is * not <tt>sizeof(#th_quant_info)</tt>. * \retval OC_IMPL Not supported by this implementation.*/ #define TH_ENCCTL_SET_QUANT_PARAMS (2) @@ -424,7 +424,7 @@ typedef struct theora_comment{ #define OC_NEWPACKET -25 /**< Packet is an (ignorable) unhandled extension */ #define OC_DUPFRAME 1 /**< Packet is a dropped frame */ -/** +/** * Retrieve a human-readable string to identify the encoder vendor and version. * \returns A version string. */ @@ -462,7 +462,7 @@ extern int theora_encode_init(theora_state *th, theora_info *ti); extern int theora_encode_YUVin(theora_state *t, yuv_buffer *yuv); /** - * Request the next packet of encoded video. + * Request the next packet of encoded video. * The encoded data is placed in a user-provided ogg_packet structure. * \param t A theora_state handle previously initialized for encoding. * \param last_p whether this is the last packet the encoder should produce. @@ -496,7 +496,11 @@ extern int theora_encode_header(theora_state *t, ogg_packet *op); * \param op An ogg_packet structure to fill. libtheora will set all * elements of this structure, including a pointer to the encoded * comment data. The memory for the comment data is owned by - * libtheora. + * the application, and must be freed by it using _ogg_free(). + * On some systems (such as Windows when using dynamic linking), this + * may mean the free is executed in a different module from the + * malloc, which will crash; there is no way to free this memory on + * such systems. * \retval 0 Success */ extern int theora_encode_comment(theora_comment *tc, ogg_packet *op); @@ -581,8 +585,8 @@ extern int theora_decode_packetin(theora_state *th,ogg_packet *op); * \param th A theora_state handle previously initialized for decoding. * \param yuv A yuv_buffer in which libtheora should place the decoded data. * Note that the buffer struct itself is allocated by the user, but - * that the luma and chroma pointers will be filled in by the - * library. Also note that these luma and chroma regions should be + * that the luma and chroma pointers will be filled in by the + * library. Also note that these luma and chroma regions should be * considered read-only by the user. * \retval 0 Success */ @@ -617,22 +621,22 @@ extern int theora_packet_iskeyframe(ogg_packet *op); /** * Report the granulepos shift radix * - * When embedded in Ogg, Theora uses a two-part granulepos, + * When embedded in Ogg, Theora uses a two-part granulepos, * splitting the 64-bit field into two pieces. The more-significant * section represents the frame count at the last keyframe, * and the less-significant section represents the count of * frames since the last keyframe. In this way the overall * field is still non-decreasing with time, but usefully encodes * a pointer to the last keyframe, which is necessary for - * correctly restarting decode after a seek. + * correctly restarting decode after a seek. * * This function reports the number of bits used to represent * the distance to the last keyframe, and thus how the granulepos * field must be shifted or masked to obtain the two parts. - * + * * Since libtheora returns compressed data in an ogg_packet * structure, this may be generally useful even if the Theora - * packets are not being used in an Ogg container. + * packets are not being used in an Ogg container. * * \param ti A previously initialized theora_info struct * \returns The bit shift dividing the two granulepos fields @@ -644,7 +648,7 @@ int theora_granule_shift(theora_info *ti); /** * Convert a granulepos to an absolute frame index, starting at 0. * The granulepos is interpreted in the context of a given theora_state handle. - * + * * Note that while the granulepos encodes the frame count (i.e. starting * from 1) this call returns the frame index, starting from zero. Thus * One can calculate the presentation time by multiplying the index by @@ -670,9 +674,7 @@ extern ogg_int64_t theora_granule_frame(theora_state *th,ogg_int64_t granulepos) * This is the "end time" for the frame, or the latest time it should * be displayed. * It is not the presentation time. - * \retval -1. The given granulepos is undefined (i.e. negative), or - * \retval -1. The function has been disabled because floating - * point support is not available. + * \retval -1. The given granulepos is undefined (i.e. negative). */ extern double theora_granule_time(theora_state *th,ogg_int64_t granulepos); @@ -699,7 +701,7 @@ extern void theora_clear(theora_state *t); /** * Initialize an allocated theora_comment structure - * \param tc An allocated theora_comment structure + * \param tc An allocated theora_comment structure **/ extern void theora_comment_init(theora_comment *tc); @@ -720,7 +722,7 @@ extern void theora_comment_add(theora_comment *tc, char *comment); /** * Add a comment to an initialized theora_comment structure. * \param tc A previously initialized theora comment structure - * \param tag A null-terminated string containing the tag + * \param tag A null-terminated string containing the tag * associated with the comment. * \param value The corresponding value as a null-terminated string * @@ -752,9 +754,9 @@ extern char *theora_comment_query(theora_comment *tc, char *tag, int count); * \param tc An initialized theora_comment structure * \param tag The tag to look up * \returns The number on instances of a particular tag. - * + * * Call this first when querying for a specific tag and then interate - * over the number of instances with separate calls to + * over the number of instances with separate calls to * theora_comment_query() to retrieve all instances in order. **/ extern int theora_comment_query_count(theora_comment *tc, char *tag); @@ -769,7 +771,7 @@ extern void theora_comment_clear(theora_comment *tc); * This is used to provide advanced control the encoding process. * \param th A #theora_state handle. * \param req The control code to process. - * See \ref encctlcodes_old "the list of available + * See \ref encctlcodes_old "the list of available * control codes" for details. * \param buf The parameters for this control code. * \param buf_sz The size of the parameter buffer.*/ diff --git a/thirdparty/libtheora/theora/theoradec.h b/thirdparty/libtheora/theora/theoradec.h index b20f0e3a64..77bef81909 100644 --- a/thirdparty/libtheora/theora/theoradec.h +++ b/thirdparty/libtheora/theora/theoradec.h @@ -92,13 +92,17 @@ extern "C" { * <tt>sizeof(th_stripe_callback)</tt>.*/ #define TH_DECCTL_SET_STRIPE_CB (7) -/**Enables telemetry and sets the macroblock display mode */ +/**Sets the macroblock display mode. Set to 0 to disable displaying + * macroblocks.*/ #define TH_DECCTL_SET_TELEMETRY_MBMODE (9) -/**Enables telemetry and sets the motion vector display mode */ +/**Sets the motion vector display mode. Set to 0 to disable displaying motion + * vectors.*/ #define TH_DECCTL_SET_TELEMETRY_MV (11) -/**Enables telemetry and sets the adaptive quantization display mode */ +/**Sets the adaptive quantization display mode. Set to 0 to disable displaying + * adaptive quantization. */ #define TH_DECCTL_SET_TELEMETRY_QI (13) -/**Enables telemetry and sets the bitstream breakdown visualization mode */ +/**Sets the bitstream breakdown visualization mode. Set to 0 to disable + * displaying bitstream breakdown.*/ #define TH_DECCTL_SET_TELEMETRY_BITS (15) /*@}*/ @@ -171,7 +175,7 @@ typedef struct th_setup_info th_setup_info; /**\defgroup decfuncs Functions for Decoding*/ /*@{*/ /**\name Functions for decoding - * You must link to <tt>libtheoradec</tt> if you use any of the + * You must link to <tt>libtheoradec</tt> if you use any of the * functions in this section. * * The functions are listed in the order they are used in a typical decode. @@ -267,7 +271,10 @@ extern void th_setup_free(th_setup_info *_setup); * See \ref decctlcodes "the list of available control codes" * for details. * \param _buf The parameters for this control code. - * \param _buf_sz The size of the parameter buffer.*/ + * \param _buf_sz The size of the parameter buffer. + * \return Possible return values depend on the control code used. + * See \ref decctlcodes "the list of control codes" for + * specific values. Generally 0 indicates success.*/ extern int th_decode_ctl(th_dec_ctx *_dec,int _req,void *_buf, size_t _buf_sz); /**Submits a packet containing encoded video data to the decoder. @@ -283,7 +290,8 @@ extern int th_decode_ctl(th_dec_ctx *_dec,int _req,void *_buf, * \retval 0 Success. * A new decoded frame can be retrieved by calling * th_decode_ycbcr_out(). - * \retval TH_DUPFRAME The packet represented a dropped (0-byte) frame. + * \retval TH_DUPFRAME The packet represented a dropped frame (either a + * 0-byte frame or an INTER frame with no coded blocks). * The player can skip the call to th_decode_ycbcr_out(), * as the contents of the decoded frame buffer have not * changed. diff --git a/thirdparty/libtheora/theora/theoraenc.h b/thirdparty/libtheora/theora/theoraenc.h index fdf2ab21e2..79b1c2b880 100644 --- a/thirdparty/libtheora/theora/theoraenc.h +++ b/thirdparty/libtheora/theora/theoraenc.h @@ -43,7 +43,7 @@ extern "C" { * <tt>NULL</tt> may be specified to revert to the default tables. * * \param[in] _buf <tt>#th_huff_code[#TH_NHUFFMAN_TABLES][#TH_NDCT_TOKENS]</tt> - * \retval TH_EFAULT \a _enc_ctx is <tt>NULL</tt>. + * \retval TH_EFAULT \a _enc is <tt>NULL</tt>. * \retval TH_EINVAL Encoding has already begun or one or more of the given * tables is not full or prefix-free, \a _buf is * <tt>NULL</tt> and \a _buf_sz is not zero, or \a _buf is @@ -57,8 +57,8 @@ extern "C" { * <tt>NULL</tt> may be specified to revert to the default parameters. * * \param[in] _buf #th_quant_info - * \retval TH_EFAULT \a _enc_ctx is <tt>NULL</tt>. - * \retval TH_EINVAL Encoding has already begun, \a _buf is + * \retval TH_EFAULT \a _enc is <tt>NULL</tt>. + * \retval TH_EINVAL Encoding has already begun, \a _buf is * <tt>NULL</tt> and \a _buf_sz is not zero, * or \a _buf is non-<tt>NULL</tt> and * \a _buf_sz is not <tt>sizeof(#th_quant_info)</tt>. @@ -73,7 +73,7 @@ extern "C" { * \param[in] _buf <tt>ogg_uint32_t</tt>: The maximum distance between key * frames. * \param[out] _buf <tt>ogg_uint32_t</tt>: The actual maximum distance set. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>. + * \retval TH_EFAULT \a _enc or \a _buf is <tt>NULL</tt>. * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(ogg_uint32_t)</tt>. * \retval TH_EIMPL Not supported by this implementation.*/ #define TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE (4) @@ -101,7 +101,7 @@ extern "C" { * 4:2:0, the picture region is smaller than the full frame, * or if encoding has begun, preventing the quantization * tables and codebooks from being set. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>. + * \retval TH_EFAULT \a _enc or \a _buf is <tt>NULL</tt>. * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>. * \retval TH_EIMPL Not supported by this implementation.*/ #define TH_ENCCTL_SET_VP3_COMPATIBLE (10) @@ -114,7 +114,7 @@ extern "C" { * the current encoding mode (VBR vs. constant quality, etc.). * * \param[out] _buf <tt>int</tt>: The maximum encoding speed level. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>. + * \retval TH_EFAULT \a _enc or \a _buf is <tt>NULL</tt>. * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>. * \retval TH_EIMPL Not supported by this implementation in the current * encoding mode.*/ @@ -124,7 +124,7 @@ extern "C" { * * \param[in] _buf <tt>int</tt>: The new encoding speed level. * 0 is slowest, larger values use less CPU. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>. + * \retval TH_EFAULT \a _enc or \a _buf is <tt>NULL</tt>. * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>, or the * encoding speed level is out of bounds. * The maximum encoding speed level may be @@ -142,7 +142,7 @@ extern "C" { * * \param[out] _buf <tt>int</tt>: The current encoding speed level. * 0 is slowest, larger values use less CPU. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>. + * \retval TH_EFAULT \a _enc or \a _buf is <tt>NULL</tt>. * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>. * \retval TH_EIMPL Not supported by this implementation in the current * encoding mode.*/ @@ -162,7 +162,7 @@ extern "C" { * * \param[in] _buf <tt>int</tt>: The number of duplicates to produce. * If this is negative or zero, no duplicates will be produced. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>. + * \retval TH_EFAULT \a _enc or \a _buf is <tt>NULL</tt>. * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>, or the * number of duplicates is greater than or equal to the * maximum keyframe interval. @@ -187,7 +187,7 @@ extern "C" { * use. * - #TH_RATECTL_CAP_UNDERFLOW: Don't try to make up shortfalls * later. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>. + * \retval TH_EFAULT \a _enc or \a _buf is <tt>NULL</tt>. * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt> or rate control * is not enabled. * \retval TH_EIMPL Not supported by this implementation in the current @@ -211,7 +211,7 @@ extern "C" { * \param[in] _buf <tt>int</tt>: Requested size of the reservoir measured in * frames. * \param[out] _buf <tt>int</tt>: The actual size of the reservoir set. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>. + * \retval TH_EFAULT \a _enc or \a _buf is <tt>NULL</tt>. * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>, or rate control * is not enabled. The buffer has an implementation * defined minimum and maximum size and the value in _buf @@ -243,7 +243,7 @@ extern "C" { * application. * \retval >=0 The number of bytes of metric data available in the * returned buffer. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>. + * \retval TH_EFAULT \a _enc or \a _buf is <tt>NULL</tt>. * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(char *)</tt>, no target * bitrate has been set, or the first call was made after * the first frame was submitted for encoding. @@ -283,7 +283,7 @@ extern "C" { * of bytes consumed. * \retval >0 The number of bytes of metric data required/consumed. * \retval 0 No more data is required before the next frame. - * \retval TH_EFAULT \a _enc_ctx is <tt>NULL</tt>. + * \retval TH_EFAULT \a _enc is <tt>NULL</tt>. * \retval TH_EINVAL No target bitrate has been set, or the first call was * made after the first frame was submitted for * encoding. @@ -306,7 +306,7 @@ extern "C" { * \param[in] _buf <tt>int</tt>: The new target quality, in the range 0...63, * inclusive. * \retval 0 Success. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>. + * \retval TH_EFAULT \a _enc or \a _buf is <tt>NULL</tt>. * \retval TH_EINVAL A target bitrate has already been specified, or the * quality index was not in the range 0...63. * \retval TH_EIMPL Not supported by this implementation.*/ @@ -328,10 +328,54 @@ extern "C" { * * \param[in] _buf <tt>long</tt>: The new target bitrate, in bits per second. * \retval 0 Success. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>. + * \retval TH_EFAULT \a _enc or \a _buf is <tt>NULL</tt>. * \retval TH_EINVAL The target bitrate was not positive. - * \retval TH_EIMPL Not supported by this implementation.*/ + * A future version of this library may allow passing 0 + * to disabled rate-controlled mode and return to a + * quality-based mode, in which case this function will + * not return an error for that value. + * \retval TH_EIMPL Not supported by this implementation.*/ #define TH_ENCCTL_SET_BITRATE (30) +/**Sets the configuration to be compatible with that from the given setup + * header. + * This sets the Huffman codebooks and quantization parameters to match those + * found in the given setup header. + * This guarantees that packets encoded by this encoder will be decodable using + * a decoder configured with the passed-in setup header. + * It does <em>not</em> guarantee that th_encode_flushheader() will produce a + * bit-identical setup header, only that they will be compatible. + * If you need a bit-identical setup header, then use the one you passed into + * this command, and not the one returned by th_encode_flushheader(). + * + * This also does <em>not</em> enable or disable VP3 compatibility; that is not + * signaled in the setup header (or anywhere else in the encoded stream), and + * is controlled independently by the #TH_ENCCTL_SET_VP3_COMPATIBLE function. + * If you wish to enable VP3 compatibility mode <em>and</em> want the codebooks + * and quantization parameters to match the given setup header, you should + * enable VP3 compatibility before invoking this command, otherwise the + * codebooks and quantization parameters will be reset to the VP3 defaults. + * + * The current encoder does not support Huffman codebooks which do not contain + * codewords for all 32 tokens. + * Such codebooks are legal, according to the specification, but cannot be + * configured with this function. + * + * \param[in] _buf <tt>unsigned char[]</tt>: The encoded setup header to copy + * the configuration from. + * This should be the original, + * undecoded setup header packet, + * and <em>not</em> a #th_setup_info + * structure filled in by + * th_decode_headerin(). + * \retval TH_EFAULT \a _enc or \a _buf is <tt>NULL</tt>. + * \retval TH_EINVAL Encoding has already begun, so the codebooks and + * quantization parameters cannot be changed, or the + * data in the setup header was not supported by this + * encoder. + * \retval TH_EBADHEADER \a _buf did not contain a valid setup header packet. + * \retval TH_ENOTFORMAT \a _buf did not contain a Theora header at all. + * \retval TH_EIMPL Not supported by this implementation.*/ +#define TH_ENCCTL_SET_COMPAT_CONFIG (32) /*@}*/ @@ -342,7 +386,8 @@ extern "C" { /*@{*/ /**Drop frames to keep within bitrate buffer constraints. * This can have a severe impact on quality, but is the only way to ensure that - * bitrate targets are met at low rates during sudden bursts of activity.*/ + * bitrate targets are met at low rates during sudden bursts of activity. + * It is enabled by default.*/ #define TH_RATECTL_DROP_FRAMES (0x1) /**Ignore bitrate buffer overflows. * If the encoder uses so few bits that the reservoir of available bits @@ -350,14 +395,14 @@ extern "C" { * The encoder will not try to use these extra bits in future frames. * At high rates this may cause the result to be undersized, but allows a * client to play the stream using a finite buffer; it should normally be - * enabled.*/ + * enabled, which is the default.*/ #define TH_RATECTL_CAP_OVERFLOW (0x2) /**Ignore bitrate buffer underflows. * If the encoder uses so many bits that the reservoir of available bits * underflows, ignore the deficit. * The encoder will not try to make up these extra bits in future frames. * At low rates this may cause the result to be oversized; it should normally - * be disabled.*/ + * be disabled, which is the default.*/ #define TH_RATECTL_CAP_UNDERFLOW (0x4) /*@}*/ @@ -401,8 +446,8 @@ typedef struct th_enc_ctx th_enc_ctx; * packets. * - For each uncompressed frame: * - Submit the uncompressed frame via th_encode_ycbcr_in() - * - Repeatedly call th_encode_packetout() to retrieve any video data packets - * that are ready. + * - Repeatedly call th_encode_packetout() to retrieve any video + * data packets that are ready. * - Call th_encode_free() to release all encoder memory.*/ /*@{*/ /**Allocates an encoder instance. @@ -417,7 +462,10 @@ extern th_enc_ctx *th_encode_alloc(const th_info *_info); * See \ref encctlcodes "the list of available control codes" * for details. * \param _buf The parameters for this control code. - * \param _buf_sz The size of the parameter buffer.*/ + * \param _buf_sz The size of the parameter buffer. + * \return Possible return values depend on the control code used. + * See \ref encctlcodes "the list of control codes" for + * specific values. Generally 0 indicates success.*/ extern int th_encode_ctl(th_enc_ctx *_enc,int _req,void *_buf,size_t _buf_sz); /**Outputs the next header packet. * This should be called repeatedly after encoder initialization until it @@ -441,11 +489,25 @@ extern int th_encode_flushheader(th_enc_ctx *_enc, /**Submits an uncompressed frame to the encoder. * \param _enc A #th_enc_ctx handle. * \param _ycbcr A buffer of Y'CbCr data to encode. + * If the width and height of the buffer matches the frame size + * the encoder was initialized with, the encoder will only + * reference the portion inside the picture region. + * Any data outside this region will be ignored, and need not map + * to a valid address. + * Alternatively, you can pass a buffer equal to the size of the + * picture region, if this is less than the full frame size. + * When using subsampled chroma planes, odd picture sizes or odd + * picture offsets may require an unexpected chroma plane size, + * and their use is generally discouraged, as they will not be + * well-supported by players and other media frameworks. + * See Section 4.4 of + * <a href="http://www.theora.org/doc/Theora.pdf">the Theora + * specification</a> for details if you wish to use them anyway. * \retval 0 Success. * \retval TH_EFAULT \a _enc or \a _ycbcr is <tt>NULL</tt>. - * \retval TH_EINVAL The buffer size does not match the frame size the encoder - * was initialized with, or encoding has already - * completed.*/ + * \retval TH_EINVAL The buffer size matches neither the frame size nor the + * picture size the encoder was initialized with, or + * encoding has already completed.*/ extern int th_encode_ycbcr_in(th_enc_ctx *_enc,th_ycbcr_buffer _ycbcr); /**Retrieves encoded video data packets. * This should be called repeatedly after each frame is submitted to flush any diff --git a/thirdparty/libtheora/tokenize.c b/thirdparty/libtheora/tokenize.c index 60574c3594..57b7aa8da9 100644 --- a/thirdparty/libtheora/tokenize.c +++ b/thirdparty/libtheora/tokenize.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: tokenize.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ #include <stdlib.h> @@ -20,27 +20,26 @@ +static unsigned char OC_DCT_EOB_TOKEN[31]={ + 0,1,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 +}; + static int oc_make_eob_token(int _run_count){ - if(_run_count<4)return OC_DCT_EOB1_TOKEN+_run_count-1; - else{ - int cat; - cat=OC_ILOGNZ_32(_run_count)-3; - cat=OC_MINI(cat,3); - return OC_DCT_REPEAT_RUN0_TOKEN+cat; - } + return _run_count<32?OC_DCT_EOB_TOKEN[_run_count-1]:OC_DCT_REPEAT_RUN3_TOKEN; } +static unsigned char OC_DCT_EOB_EB[31]={ + 0,0,0,0,1,2,3,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 +}; + static int oc_make_eob_token_full(int _run_count,int *_eb){ - if(_run_count<4){ - *_eb=0; - return OC_DCT_EOB1_TOKEN+_run_count-1; + if(_run_count<32){ + *_eb=OC_DCT_EOB_EB[_run_count-1]; + return OC_DCT_EOB_TOKEN[_run_count-1]; } else{ - int cat; - cat=OC_ILOGNZ_32(_run_count)-3; - cat=OC_MINI(cat,3); - *_eb=_run_count-OC_BYTE_TABLE32(4,8,16,0,cat); - return OC_DCT_REPEAT_RUN0_TOKEN+cat; + *_eb=_run_count; + return OC_DCT_REPEAT_RUN3_TOKEN; } } @@ -49,86 +48,330 @@ static int oc_decode_eob_token(int _token,int _eb){ return (0x20820C41U>>_token*5&0x1F)+_eb; } -/*TODO: This is now only used during DCT tokenization, and never for runs; it - should be simplified.*/ -static int oc_make_dct_token_full(int _zzi,int _zzj,int _val,int *_eb){ - int neg; - int zero_run; - int token; - int eb; - neg=_val<0; - _val=abs(_val); - zero_run=_zzj-_zzi; - if(zero_run>0){ - int adj; - /*Implement a minor restriction on stack 1 so that we know during DC fixups - that extending a dctrun token from stack 1 will never overflow.*/ - adj=_zzi!=1; - if(_val<2&&zero_run<17+adj){ - if(zero_run<6){ - token=OC_DCT_RUN_CAT1A+zero_run-1; - eb=neg; - } - else if(zero_run<10){ - token=OC_DCT_RUN_CAT1B; - eb=zero_run-6+(neg<<2); - } - else{ - token=OC_DCT_RUN_CAT1C; - eb=zero_run-10+(neg<<3); - } - } - else if(_val<4&&zero_run<3+adj){ - if(zero_run<2){ - token=OC_DCT_RUN_CAT2A; - eb=_val-2+(neg<<1); - } - else{ - token=OC_DCT_RUN_CAT2B; - eb=zero_run-2+(_val-2<<1)+(neg<<2); - } - } - else{ - if(zero_run<9)token=OC_DCT_SHORT_ZRL_TOKEN; - else token=OC_DCT_ZRL_TOKEN; - eb=zero_run-1; - } - } - else if(_val<3){ - token=OC_ONE_TOKEN+(_val-1<<1)+neg; - eb=0; - } - else if(_val<7){ - token=OC_DCT_VAL_CAT2+_val-3; - eb=neg; - } - else if(_val<9){ - token=OC_DCT_VAL_CAT3; - eb=_val-7+(neg<<1); - } - else if(_val<13){ - token=OC_DCT_VAL_CAT4; - eb=_val-9+(neg<<2); - } - else if(_val<21){ - token=OC_DCT_VAL_CAT5; - eb=_val-13+(neg<<3); - } - else if(_val<37){ - token=OC_DCT_VAL_CAT6; - eb=_val-21+(neg<<4); - } - else if(_val<69){ - token=OC_DCT_VAL_CAT7; - eb=_val-37+(neg<<5); - } - else{ - token=OC_DCT_VAL_CAT8; - eb=_val-69+(neg<<9); - } - *_eb=eb; - return token; -} +/*Some tables for fast construction of value tokens.*/ + +static const unsigned char OC_DCT_VALUE_TOKEN[1161]={ + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,21,21,21,21,21,21,21,21, + 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, + 21,21,21,21,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, + 19,19,19,19,19,19,19,19,18,18,18,18,17,17,16,15,14,13,12,10, + 7, + 9,11,13,14,15,16,17,17,18,18,18,18,19,19,19,19,19,19,19,19, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21, + 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, + 21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22 +}; + +static const ogg_uint16_t OC_DCT_VALUE_EB[1161]={ + 1023,1022,1021,1020,1019,1018,1017,1016,1015,1014, + 1013,1012,1011,1010,1009,1008,1007,1006,1005,1004, + 1003,1002,1001,1000, 999, 998, 997, 996, 995, 994, + 993, 992, 991, 990, 989, 988, 987, 986, 985, 984, + 983, 982, 981, 980, 979, 978, 977, 976, 975, 974, + 973, 972, 971, 970, 969, 968, 967, 966, 965, 964, + 963, 962, 961, 960, 959, 958, 957, 956, 955, 954, + 953, 952, 951, 950, 949, 948, 947, 946, 945, 944, + 943, 942, 941, 940, 939, 938, 937, 936, 935, 934, + 933, 932, 931, 930, 929, 928, 927, 926, 925, 924, + 923, 922, 921, 920, 919, 918, 917, 916, 915, 914, + 913, 912, 911, 910, 909, 908, 907, 906, 905, 904, + 903, 902, 901, 900, 899, 898, 897, 896, 895, 894, + 893, 892, 891, 890, 889, 888, 887, 886, 885, 884, + 883, 882, 881, 880, 879, 878, 877, 876, 875, 874, + 873, 872, 871, 870, 869, 868, 867, 866, 865, 864, + 863, 862, 861, 860, 859, 858, 857, 856, 855, 854, + 853, 852, 851, 850, 849, 848, 847, 846, 845, 844, + 843, 842, 841, 840, 839, 838, 837, 836, 835, 834, + 833, 832, 831, 830, 829, 828, 827, 826, 825, 824, + 823, 822, 821, 820, 819, 818, 817, 816, 815, 814, + 813, 812, 811, 810, 809, 808, 807, 806, 805, 804, + 803, 802, 801, 800, 799, 798, 797, 796, 795, 794, + 793, 792, 791, 790, 789, 788, 787, 786, 785, 784, + 783, 782, 781, 780, 779, 778, 777, 776, 775, 774, + 773, 772, 771, 770, 769, 768, 767, 766, 765, 764, + 763, 762, 761, 760, 759, 758, 757, 756, 755, 754, + 753, 752, 751, 750, 749, 748, 747, 746, 745, 744, + 743, 742, 741, 740, 739, 738, 737, 736, 735, 734, + 733, 732, 731, 730, 729, 728, 727, 726, 725, 724, + 723, 722, 721, 720, 719, 718, 717, 716, 715, 714, + 713, 712, 711, 710, 709, 708, 707, 706, 705, 704, + 703, 702, 701, 700, 699, 698, 697, 696, 695, 694, + 693, 692, 691, 690, 689, 688, 687, 686, 685, 684, + 683, 682, 681, 680, 679, 678, 677, 676, 675, 674, + 673, 672, 671, 670, 669, 668, 667, 666, 665, 664, + 663, 662, 661, 660, 659, 658, 657, 656, 655, 654, + 653, 652, 651, 650, 649, 648, 647, 646, 645, 644, + 643, 642, 641, 640, 639, 638, 637, 636, 635, 634, + 633, 632, 631, 630, 629, 628, 627, 626, 625, 624, + 623, 622, 621, 620, 619, 618, 617, 616, 615, 614, + 613, 612, 611, 610, 609, 608, 607, 606, 605, 604, + 603, 602, 601, 600, 599, 598, 597, 596, 595, 594, + 593, 592, 591, 590, 589, 588, 587, 586, 585, 584, + 583, 582, 581, 580, 579, 578, 577, 576, 575, 574, + 573, 572, 571, 570, 569, 568, 567, 566, 565, 564, + 563, 562, 561, 560, 559, 558, 557, 556, 555, 554, + 553, 552, 551, 550, 549, 548, 547, 546, 545, 544, + 543, 542, 541, 540, 539, 538, 537, 536, 535, 534, + 533, 532, 531, 530, 529, 528, 527, 526, 525, 524, + 523, 522, 521, 520, 519, 518, 517, 516, 515, 514, + 513, 512, 63, 62, 61, 60, 59, 58, 57, 56, + 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, + 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, + 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, + 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, + 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, + 5, 4, 3, 2, 1, 1, 1, 1, 0, 0, + 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, + 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 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, 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, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, + 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, + 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, + 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, + 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, + 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, + 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, + 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, + 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, + 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, + 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, + 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, + 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, + 502, 503, 504, 505, 506, 507, 508, 509, 510, 511 +}; + +/*The first DCT coefficient that both has a smaller magnitude and gets coded + with a different token.*/ +static const ogg_int16_t OC_DCT_TRELLIS_ALT_VALUE[1161]={ + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -12, -12, -12, -12, -12, -12, -12, -12, -8, -8, + -8, -8, -6, -6, -5, -4, -3, -2, -1, 0, + 0, + 0, 1, 2, 3, 4, 5, 6, 6, 8, 8, + 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68 +}; + +#define OC_DCT_VALUE_TOKEN_PTR (OC_DCT_VALUE_TOKEN+580) +#define OC_DCT_VALUE_EB_PTR (OC_DCT_VALUE_EB+580) +#define OC_DCT_TRELLIS_ALT_VALUE_PTR (OC_DCT_TRELLIS_ALT_VALUE+580) + +/*Some tables for fast construction of combo tokens.*/ + +static const unsigned char OC_DCT_RUN_CAT1_TOKEN[17]={ + 23,24,25,26,27,28,28,28,28,29,29,29,29,29,29,29,29 +}; + +static const unsigned char OC_DCT_RUN_CAT1_EB[17][2]={ + {0,1},{0,1},{0, 1},{0, 1},{0, 1},{0, 4},{1, 5},{2, 6},{3,7}, + {0,8},{1,9},{2,10},{3,11},{4,12},{5,13},{6,14},{7,15} +}; + +static const unsigned char OC_DCT_RUN_CAT2_EB[3][2][2]={ + { {0,1},{2,3} },{ {0,2},{4,6} },{ {1,3},{5,7} } +}; /*Token logging to allow a few fragments of efficient rollback. Late SKIP analysis is tied up in the tokenization process, so we need to be @@ -211,10 +454,11 @@ struct oc_quant_token{ /*Tokenizes the AC coefficients, possibly adjusting the quantization, and then dequantizes and de-zig-zags the result. - The DC coefficient is not preserved; it should be restored by the caller.*/ + The AC coefficients of _idct must be pre-initialized to zero.*/ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, - ogg_int16_t *_qdct,const ogg_uint16_t *_dequant,const ogg_int16_t *_dct, - int _zzi,oc_token_checkpoint **_stack,int _acmin){ + ogg_int16_t *_idct,const ogg_int16_t *_qdct, + const ogg_uint16_t *_dequant,const ogg_int16_t *_dct, + int _zzi,oc_token_checkpoint **_stack,int _lambda,int _acmin){ oc_token_checkpoint *stack; ogg_int64_t zflags; ogg_int64_t nzflags; @@ -242,31 +486,29 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, d2_accum[0]=0; zzj=64; for(zzi=OC_MINI(_zzi,63);zzi>0;zzi--){ - ogg_int32_t lambda; ogg_uint32_t best_cost; int best_bits=best_bits; int best_next=best_next; int best_token=best_token; int best_eb=best_eb; int best_qc=best_qc; - int flush_bits; ogg_uint32_t d2; int dq; + int qc_m; int e; int c; int s; int tj; - lambda=_enc->lambda; qc=_qdct[zzi]; s=-(qc<0); - qc=qc+s^s; - c=_dct[OC_FZIG_ZAG[zzi]]; - if(qc<=1){ + qc_m=qc+s^s; + c=_dct[zzi]; + /*The hard case: try a zero run.*/ + if(qc_m<=1){ ogg_uint32_t sum_d2; int nzeros; int dc_reserve; - /*The hard case: try a zero run.*/ - if(!qc){ + if(!qc_m){ /*Skip runs that are already quantized to zeros. If we considered each zero coefficient in turn, we might theoretically find a better way to partition long zero runs (e.g., @@ -281,15 +523,14 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, d2=0; } else{ - c=c+s^s; d2=c*(ogg_int32_t)c; + c=c+s^s; } eob=eob_run[zzi]; nzeros=zzj-zzi; zzj&=63; sum_d2=d2+d2_accum[zzj]; d2_accum[zzi]=sum_d2; - flush_bits=eob>0?oc_token_bits(_enc,huffi,zzi,oc_make_eob_token(eob)):0; /*We reserve 1 spot for combo run tokens that start in the 1st AC stack to ensure they can be extended to include the DC coefficient if necessary; this greatly simplifies stack-rewriting later on.*/ @@ -297,7 +538,6 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, best_cost=0xFFFFFFFF; for(;;){ if(nzflags>>zzj&1){ - int cat; int val; int val_s; int zzk; @@ -306,11 +546,10 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, tk=next&1; zzk=next>>1; /*Try a pure zero run to this point.*/ - cat=nzeros+55>>6; - token=OC_DCT_SHORT_ZRL_TOKEN+cat; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); + token=OC_DCT_SHORT_ZRL_TOKEN+(nzeros+55>>6); + bits=oc_token_bits(_enc,huffi,zzi,token); d2=sum_d2-d2_accum[zzj]; - cost=d2+lambda*bits+tokens[zzj][1].cost; + cost=d2+_lambda*bits+tokens[zzj][1].cost; if(cost<=best_cost){ best_next=(zzj<<1)+1; best_token=token; @@ -319,25 +558,18 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, best_bits=bits+tokens[zzj][1].bits; best_qc=0; } - if(nzeros<16+dc_reserve){ + if(nzeros<17+dc_reserve){ val=_qdct[zzj]; val_s=-(val<0); val=val+val_s^val_s; if(val<=2){ /*Try a +/- 1 combo token.*/ - if(nzeros<6){ - token=OC_DCT_RUN_CAT1A+nzeros-1; - eb=-val_s; - } - else{ - cat=nzeros+54>>6; - token=OC_DCT_RUN_CAT1B+cat; - eb=(-val_s<<cat+2)+nzeros-6-(cat<<2); - } - e=(_dct[OC_FZIG_ZAG[zzj]]+val_s^val_s)-_dequant[zzj]; + token=OC_DCT_RUN_CAT1_TOKEN[nzeros-1]; + eb=OC_DCT_RUN_CAT1_EB[nzeros-1][-val_s]; + e=_dct[zzj]-(_dequant[zzj]+val_s^val_s); d2=e*(ogg_int32_t)e+sum_d2-d2_accum[zzj]; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits+tokens[zzk][tk].cost; + bits=oc_token_bits(_enc,huffi,zzi,token); + cost=d2+_lambda*bits+tokens[zzk][tk].cost; if(cost<=best_cost){ best_next=next; best_token=token; @@ -347,22 +579,23 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, best_qc=1+val_s^val_s; } } - if(nzeros<2+dc_reserve&&2<=val&&val<=4){ + if(nzeros<3+dc_reserve&&2<=val&&val<=4){ + int sval; /*Try a +/- 2/3 combo token.*/ - cat=nzeros>>1; - token=OC_DCT_RUN_CAT2A+cat; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - val=2+((val+val_s^val_s)>2); - e=(_dct[OC_FZIG_ZAG[zzj]]+val_s^val_s)-_dequant[zzj]*val; + token=OC_DCT_RUN_CAT2A+(nzeros>>1); + bits=oc_token_bits(_enc,huffi,zzi,token); + val=2+(val>2); + sval=val+val_s^val_s; + e=_dct[zzj]-_dequant[zzj]*sval; d2=e*(ogg_int32_t)e+sum_d2-d2_accum[zzj]; - cost=d2+lambda*bits+tokens[zzk][tk].cost; + cost=d2+_lambda*bits+tokens[zzk][tk].cost; if(cost<=best_cost){ best_cost=cost; best_bits=bits+tokens[zzk][tk].bits; best_next=next; best_token=token; - best_eb=(-val_s<<1+cat)+(val-2<<cat)+(nzeros-1>>1); - best_qc=val+val_s^val_s; + best_eb=OC_DCT_RUN_CAT2_EB[nzeros-1][-val_s][val-2]; + best_qc=sval; } } } @@ -378,10 +611,10 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, /*We made it all the way to the end of the block; try an EOB token.*/ if(eob<4095){ bits=oc_token_bits(_enc,huffi,zzi,oc_make_eob_token(eob+1)) - -flush_bits; + -(eob>0?oc_token_bits(_enc,huffi,zzi,oc_make_eob_token(eob)):0); } else bits=oc_token_bits(_enc,huffi,zzi,OC_DCT_EOB1_TOKEN); - cost=sum_d2+bits*lambda; + cost=sum_d2+bits*_lambda; /*If the best route so far is still a pure zero run to the end of the block, force coding it as an EOB. Even if it's not optimal for this block, it has a good chance of @@ -408,20 +641,20 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, tokens[zzi][0].bits=best_bits; tokens[zzi][0].qc=best_qc; zflags|=(ogg_int64_t)1<<zzi; - if(qc){ + if(qc_m){ dq=_dequant[zzi]; - if(zzi<_acmin)lambda=0; + if(zzi<_acmin)_lambda=0; e=dq-c; d2=e*(ogg_int32_t)e; token=OC_ONE_TOKEN-s; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); + bits=oc_token_bits(_enc,huffi,zzi,token); zzj=zzi+1&63; tj=best_flags>>zzj&1; next=(zzj<<1)+tj; tokens[zzi][1].next=(unsigned char)next; tokens[zzi][1].token=(signed char)token; tokens[zzi][1].eb=0; - tokens[zzi][1].cost=d2+lambda*bits+tokens[zzj][tj].cost; + tokens[zzi][1].cost=d2+_lambda*bits+tokens[zzj][tj].cost; tokens[zzi][1].bits=bits+tokens[zzj][tj].bits; tokens[zzi][1].qc=1+s^s; nzflags|=(ogg_int64_t)1<<zzi; @@ -430,200 +663,38 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, } } else{ + int alt_qc; eob=eob_run[zzi]; - if(zzi<_acmin)lambda=0; - c=c+s^s; + if(zzi<_acmin)_lambda=0; dq=_dequant[zzi]; /*No zero run can extend past this point.*/ d2_accum[zzi]=0; - flush_bits=eob>0?oc_token_bits(_enc,huffi,zzi,oc_make_eob_token(eob)):0; - if(qc<=2){ - e=2*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_TWO_TOKEN-s; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e-=dq; - d2=e*(ogg_int32_t)e; - token=OC_ONE_TOKEN-s; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_bits=bits; - best_cost=cost; - qc--; - } - best_eb=0; - } - else if(qc<=3){ - e=3*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT2; - best_eb=-s; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e-=dq; - d2=e*(ogg_int32_t)e; - token=OC_TWO_TOKEN-s; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_eb=0; - best_bits=bits; - best_cost=cost; - qc--; - } - } - else if(qc<=6){ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT2+qc-3; - best_eb=-s; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e-=dq; - d2=e*(ogg_int32_t)e; - token=best_token-1; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_bits=bits; - best_cost=cost; - qc--; - } - } - else if(qc<=8){ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT3; - best_eb=(-s<<1)+qc-7; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e=6*dq-c; - d2=e*(ogg_int32_t)e; - token=OC_DCT_VAL_CAT2+3; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_eb=-s; - best_bits=bits; - best_cost=cost; - qc=6; - } - } - else if(qc<=12){ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT4; - best_eb=(-s<<2)+qc-9; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e=8*dq-c; - d2=e*(ogg_int32_t)e; - token=best_token-1; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_eb=(-s<<1)+1; - best_bits=bits; - best_cost=cost; - qc=8; - } - } - else if(qc<=20){ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT5; - best_eb=(-s<<3)+qc-13; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e=12*dq-c; - d2=e*(ogg_int32_t)e; - token=best_token-1; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_eb=(-s<<2)+3; - best_bits=bits; - best_cost=cost; - qc=12; - } - } - else if(qc<=36){ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT6; - best_eb=(-s<<4)+qc-21; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e=20*dq-c; - d2=e*(ogg_int32_t)e; - token=best_token-1; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_eb=(-s<<3)+7; - best_bits=bits; - best_cost=cost; - qc=20; - } - } - else if(qc<=68){ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT7; - best_eb=(-s<<5)+qc-37; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e=36*dq-c; - d2=e*(ogg_int32_t)e; - token=best_token-1; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<best_cost){ - best_token=token; - best_eb=(-s<<4)+15; - best_bits=bits; - best_cost=cost; - qc=36; - } - } - else{ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT8; - best_eb=(-s<<9)+qc-69; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e=68*dq-c; - d2=e*(ogg_int32_t)e; - token=best_token-1; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<best_cost){ - best_token=token; - best_eb=(-s<<5)+31; - best_bits=bits; - best_cost=cost; - qc=68; - } + e=qc*dq-c; + d2=e*(ogg_int32_t)e; + best_token=*(OC_DCT_VALUE_TOKEN_PTR+qc); + best_bits=oc_token_bits(_enc,huffi,zzi,best_token); + best_cost=d2+_lambda*best_bits; + alt_qc=*(OC_DCT_TRELLIS_ALT_VALUE_PTR+qc); + e=alt_qc*dq-c; + d2=e*(ogg_int32_t)e; + token=*(OC_DCT_VALUE_TOKEN_PTR+alt_qc); + bits=oc_token_bits(_enc,huffi,zzi,token); + cost=d2+_lambda*bits; + if(cost<best_cost){ + best_token=token; + best_bits=bits; + best_cost=cost; + qc=alt_qc; } zzj=zzi+1&63; tj=best_flags>>zzj&1; next=(zzj<<1)+tj; tokens[zzi][1].next=(unsigned char)next; tokens[zzi][1].token=(signed char)best_token; - tokens[zzi][1].eb=best_eb; + tokens[zzi][1].eb=*(OC_DCT_VALUE_EB_PTR+qc); tokens[zzi][1].cost=best_cost+tokens[zzj][tj].cost; tokens[zzi][1].bits=best_bits+tokens[zzj][tj].bits; - tokens[zzi][1].qc=qc+s^s; + tokens[zzi][1].qc=qc; nzflags|=(ogg_int64_t)1<<zzi; best_flags|=(ogg_int64_t)1<<zzi; } @@ -631,9 +702,6 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, } /*Emit the tokens from the best path through the trellis.*/ stack=*_stack; - /*We blow away the first entry here so that things vectorize better. - The DC coefficient is not actually stored in the array yet.*/ - for(zzi=0;zzi<64;zzi++)_qdct[zzi]=0; dct_fzig_zag=_enc->state.opt_data.dct_fzig_zag; zzi=1; ti=best_flags>>1&1; @@ -643,12 +711,15 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, eob=eob_run[zzi]; if(tokens[zzi][ti].token<OC_NDCT_EOB_TOKEN_MAX){ if(++eob>=4095){ - oc_enc_eob_log(_enc,_pli,zzi,eob); + oc_enc_token_log(_enc,_pli,zzi,OC_DCT_REPEAT_RUN3_TOKEN,eob); eob=0; } eob_run[zzi]=eob; /*We don't include the actual EOB cost for this block in the return value. - It will be paid for by the fragment that terminates the EOB run.*/ + It is very likely to eventually be spread over several blocks, and + including it more harshly penalizes the first few blocks in a long EOB + run. + Omitting it here gives a small PSNR and SSIM gain.*/ bits-=tokens[zzi][ti].bits; zzi=_zzi; break; @@ -664,7 +735,7 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, zzj=(next>>1)-1&63; /*TODO: It may be worth saving the dequantized coefficient in the trellis above; we had to compute it to measure the error anyway.*/ - _qdct[dct_fzig_zag[zzj]]=(ogg_int16_t)(qc*(int)_dequant[zzj]); + _idct[dct_fzig_zag[zzj]]=(ogg_int16_t)(qc*(int)_dequant[zzj]); zzi=next>>1; ti=next&1; } @@ -673,6 +744,237 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, return bits; } +/*Simplistic R/D tokenizer. + The AC coefficients of _idct must be pre-initialized to zero. + This could be made more accurate by using more sophisticated + rate predictions for zeros. + It could be made faster by switching from R/D decisions to static + lambda-derived rounding biases.*/ +int oc_enc_tokenize_ac_fast(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, + ogg_int16_t *_idct,const ogg_int16_t *_qdct, + const ogg_uint16_t *_dequant,const ogg_int16_t *_dct, + int _zzi,oc_token_checkpoint **_stack,int _lambda,int _acmin){ + const unsigned char *dct_fzig_zag; + ogg_uint16_t *eob_run; + oc_token_checkpoint *stack; + int huffi; + int zzi; + int zzj; + int zzk; + int total_bits; + int zr[4]; + stack=*_stack; + total_bits=0; + /*The apparent bit-cost of coding a zero from observing the trellis + quantizer is pre-combined with lambda. + Four predictive cases are considered: the last optimized value is zero (+2) + or non-zero and the non-optimized value is zero (+1) or non-zero.*/ + zr[0]=3*_lambda>>1; + zr[1]=_lambda; + zr[2]=4*_lambda; + zr[3]=7*_lambda>>1; + eob_run=_enc->eob_run[_pli]; + dct_fzig_zag=_enc->state.opt_data.dct_fzig_zag; + huffi=_enc->huff_idxs[_enc->state.frame_type][1][_pli+1>>1]; + for(zzj=zzi=1;zzj<_zzi&&!_qdct[zzj];zzj++); + while(zzj<_zzi){ + int v; + int d0; + int d1; + int sign; + int k; + int eob; + int dq0; + int dq1; + int dd0; + int dd1; + int next_zero; + int eob_bits; + int dct_fzig_zzj; + dct_fzig_zzj=dct_fzig_zag[zzj]; + v=_dct[zzj]; + d0=_qdct[zzj]; + eob=eob_run[zzi]; + for(zzk=zzj+1;zzk<_zzi&&!_qdct[zzk];zzk++); + next_zero=zzk-zzj+62>>6; + dq0=d0*_dequant[zzj]; + dd0=dq0-v; + dd0*=dd0; + sign=-(d0<0); + k=d0+sign^sign; + d1=(k-(zzj>_acmin))+sign^sign; + dq1=d1*_dequant[zzj]; + dd1=dq1-v; + dd1*=dd1; + /*The cost of ending an eob run is included when the alternative is to + extend this eob run. + A per qi/zzi weight would probably be useful. + Including it in the overall tokenization cost was not helpful. + The same is true at the far end of the zero run plus token case.*/ + if(eob>0&&d1==0&&zzk==_zzi){ + eob_bits=oc_token_bits(_enc,huffi,zzi,OC_DCT_EOB1_TOKEN); + } + else eob_bits=0; + if(zzj==zzi){ + /*No active zero run.*/ + int best_token; + int best_eb; + int token; + int best_bits; + int bits; + int cost; + best_token=*(OC_DCT_VALUE_TOKEN_PTR+d0); + best_bits=oc_token_bits(_enc,huffi,zzi,best_token); + if(d1!=0){ + token=*(OC_DCT_VALUE_TOKEN_PTR+d1); + bits=oc_token_bits(_enc,huffi,zzi,token); + cost=dd1+(bits+eob_bits)*_lambda; + } + else{ + token=bits=0; + cost=dd1+zr[next_zero]; + } + if((dd0+(best_bits+eob_bits)*_lambda)>cost){ + _idct[dct_fzig_zzj]=dq1; + if(d1==0){ + zzj=zzk; + continue; + } + best_bits=bits; + best_token=token; + best_eb=*(OC_DCT_VALUE_EB_PTR+d1); + } + else{ + best_eb=*(OC_DCT_VALUE_EB_PTR+d0); + _idct[dct_fzig_zzj]=dq0; + } + oc_enc_tokenlog_checkpoint(_enc,stack++,_pli,zzi); + if(eob>0){ + oc_enc_eob_log(_enc,_pli,zzi,eob); + eob_run[zzi]=0; + } + oc_enc_token_log(_enc,_pli,zzi,best_token,best_eb); + total_bits+=best_bits; + } + else{ + int d; + int dc_reserve; + int best_token; + int best_eb; + int best_bits; + int best_cost; + int best_bits1; + int best_token1; + int best_eb1; + int zr_bits; + int eob2; + int eob_bits2; + int bits; + int token; + int nzeros; + nzeros=zzj-zzi; + dc_reserve=zzi+62>>6; + /*A zero run, followed by the value alone.*/ + best_token=best_token1=OC_DCT_SHORT_ZRL_TOKEN+(nzeros+55>>6); + best_eb=best_eb1=nzeros-1; + eob2=eob_run[zzj]; + eob_bits2=eob2>0?oc_token_bits(_enc,huffi,zzj,OC_DCT_EOB1_TOKEN):0; + zr_bits=oc_token_bits(_enc,huffi,zzi,best_token)+eob_bits2; + best_bits=zr_bits + +oc_token_bits(_enc,huffi,zzj,*(OC_DCT_VALUE_TOKEN_PTR+d0)); + d=d0; + best_bits1=0; + if(d1!=0){ + best_bits1=zr_bits + +oc_token_bits(_enc,huffi,zzj,*(OC_DCT_VALUE_TOKEN_PTR+d1)); + } + if(nzeros<17+dc_reserve){ + if(k<=2){ + /*+/- 1 combo token.*/ + token=OC_DCT_RUN_CAT1_TOKEN[nzeros-1]; + bits=oc_token_bits(_enc,huffi,zzi,token); + if(k==2&&bits<=best_bits1){ + best_bits1=bits; + best_token1=token; + best_eb1=OC_DCT_RUN_CAT1_EB[nzeros-1][-sign]; + } + if(k==1&&bits<=best_bits){ + best_bits=bits; + best_token=token; + best_eb=OC_DCT_RUN_CAT1_EB[nzeros-1][-sign]; + } + } + if(nzeros<3+dc_reserve&&2<=k&&k<=4){ + /*+/- 2/3 combo token.*/ + token=OC_DCT_RUN_CAT2A+(nzeros>>1); + bits=oc_token_bits(_enc,huffi,zzi,token); + if(k==4&&bits<=best_bits1){ + best_bits1=bits; + best_token1=token; + best_eb1=OC_DCT_RUN_CAT2_EB[nzeros-1][-sign][1]; + } + if(k!=4&&bits<=best_bits){ + best_bits=bits; + best_token=token; + best_eb=OC_DCT_RUN_CAT2_EB[nzeros-1][-sign][k-2]; + } + } + } + best_cost=dd0+(best_bits+eob_bits)*_lambda; + if(d1==0&&(dd1+zr[2+next_zero])<=best_cost){ + zzj=zzk; + continue; + } + if(d1!=0&&dd1+(best_bits1+eob_bits)*_lambda<best_cost){ + best_bits=best_bits1; + best_token=best_token1; + best_eb=best_eb1; + d=d1; + _idct[dct_fzig_zzj]=dq1; + } + else _idct[dct_fzig_zzj]=dq0; + oc_enc_tokenlog_checkpoint(_enc,stack++,_pli,zzi); + if(eob){ + oc_enc_eob_log(_enc,_pli,zzi,eob); + eob_run[zzi]=0; + } + oc_enc_token_log(_enc,_pli,zzi,best_token,best_eb); + /*If a zero run won vs. the combo token we still need to code this + value.*/ + if(best_token<=OC_DCT_ZRL_TOKEN){ + oc_enc_tokenlog_checkpoint(_enc,stack++,_pli,zzj); + if(eob2){ + oc_enc_eob_log(_enc,_pli,zzj,eob2); + /*The cost of any EOB run we disrupted is ignored because doing so + improved PSNR/SSIM by a small amount.*/ + best_bits-=eob_bits2; + eob_run[zzj]=0; + } + oc_enc_token_log(_enc,_pli,zzj, + *(OC_DCT_VALUE_TOKEN_PTR+d),*(OC_DCT_VALUE_EB_PTR+d)); + } + total_bits+=best_bits; + } + zzi=zzj+1; + zzj=zzk; + } + /*Code an EOB run to complete this block. + The cost of the EOB run is not included in the total as explained in + in a comment in the trellis tokenizer above.*/ + if(zzi<64){ + int eob; + eob=eob_run[zzi]+1; + oc_enc_tokenlog_checkpoint(_enc,stack++,_pli,zzi); + if(eob>=4095){ + oc_enc_token_log(_enc,_pli,zzi,OC_DCT_REPEAT_RUN3_TOKEN,eob); + eob=0; + } + eob_run[zzi]=eob; + } + *_stack=stack; + return total_bits; +} + void oc_enc_pred_dc_frag_rows(oc_enc_ctx *_enc, int _pli,int _fragy0,int _frag_yend){ const oc_fragment_plane *fplane; @@ -695,10 +997,10 @@ void oc_enc_pred_dc_frag_rows(oc_enc_ctx *_enc, predictor for the same reference frame.*/ for(fragx=0;fragx<nhfrags;fragx++,fragi++){ if(frags[fragi].coded){ - int ref; - ref=OC_FRAME_FOR_MODE(frags[fragi].mb_mode); - frag_dc[fragi]=(ogg_int16_t)(frags[fragi].dc-pred_last[ref]); - pred_last[ref]=frags[fragi].dc; + int refi; + refi=frags[fragi].refi; + frag_dc[fragi]=(ogg_int16_t)(frags[fragi].dc-pred_last[refi]); + pred_last[refi]=frags[fragi].dc; } } } @@ -710,27 +1012,24 @@ void oc_enc_pred_dc_frag_rows(oc_enc_ctx *_enc, u_frags=frags-nhfrags; l_ref=-1; ul_ref=-1; - u_ref=u_frags[fragi].coded?OC_FRAME_FOR_MODE(u_frags[fragi].mb_mode):-1; + u_ref=u_frags[fragi].refi; for(fragx=0;fragx<nhfrags;fragx++,fragi++){ int ur_ref; if(fragx+1>=nhfrags)ur_ref=-1; - else{ - ur_ref=u_frags[fragi+1].coded? - OC_FRAME_FOR_MODE(u_frags[fragi+1].mb_mode):-1; - } + else ur_ref=u_frags[fragi+1].refi; if(frags[fragi].coded){ int pred; - int ref; - ref=OC_FRAME_FOR_MODE(frags[fragi].mb_mode); + int refi; + refi=frags[fragi].refi; /*We break out a separate case based on which of our neighbors use the same reference frames. This is somewhat faster than trying to make a generic case which handles all of them, since it reduces lots of poorly predicted jumps to one switch statement, and also lets a number of the multiplications be optimized out by strength reduction.*/ - switch((l_ref==ref)|(ul_ref==ref)<<1| - (u_ref==ref)<<2|(ur_ref==ref)<<3){ - default:pred=pred_last[ref];break; + switch((l_ref==refi)|(ul_ref==refi)<<1| + (u_ref==refi)<<2|(ur_ref==refi)<<3){ + default:pred=pred_last[refi];break; case 1: case 3:pred=frags[fragi-1].dc;break; case 2:pred=u_frags[fragi-1].dc;break; @@ -764,8 +1063,8 @@ void oc_enc_pred_dc_frag_rows(oc_enc_ctx *_enc, }break; } frag_dc[fragi]=(ogg_int16_t)(frags[fragi].dc-pred); - pred_last[ref]=frags[fragi].dc; - l_ref=ref; + pred_last[refi]=frags[fragi].dc; + l_ref=refi; } else l_ref=-1; ul_ref=u_ref; @@ -850,9 +1149,8 @@ void oc_enc_tokenize_dc_frag_list(oc_enc_ctx *_enc,int _pli, ti0++; eob_run0=0; } - token=oc_make_dct_token_full(0,0,val,&eb); - dct_tokens0[ti0]=(unsigned char)token; - extra_bits0[ti0]=(ogg_uint16_t)eb; + dct_tokens0[ti0]=*(OC_DCT_VALUE_TOKEN_PTR+val); + extra_bits0[ti0]=*(OC_DCT_VALUE_EB_PTR+val); ti0++; } else{ @@ -863,9 +1161,8 @@ void oc_enc_tokenize_dc_frag_list(oc_enc_ctx *_enc,int _pli, /*We're in the middle of an active EOB run in stack 1. Move it to stack 0.*/ if(++eob_run0>=4095){ - token=oc_make_eob_token_full(eob_run0,&eb); - dct_tokens0[ti0]=(unsigned char)token; - extra_bits0[ti0]=(ogg_uint16_t)eb; + dct_tokens0[ti0]=OC_DCT_REPEAT_RUN3_TOKEN; + extra_bits0[ti0]=eob_run0; ti0++; eob_run0=0; } @@ -996,9 +1293,8 @@ void oc_enc_tokenize_dc_frag_list(oc_enc_ctx *_enc,int _pli, neobs1--; /*If we have more than 4095 EOBs outstanding in stack1, flush the run.*/ if(eob_run1-neobs1>=4095){ - token=oc_make_eob_token_full(4095,&eb); - dct_tokens1[ti1w]=(unsigned char)token; - extra_bits1[ti1w]=(ogg_uint16_t)eb; + dct_tokens1[ti1w]=OC_DCT_REPEAT_RUN3_TOKEN; + extra_bits1[ti1w]=4095; ti1w++; eob_run1-=4095; } diff --git a/thirdparty/libtheora/x86/mmxencfrag.c b/thirdparty/libtheora/x86/mmxencfrag.c index c79ff01fcc..cc9be8d867 100644 --- a/thirdparty/libtheora/x86/mmxencfrag.c +++ b/thirdparty/libtheora/x86/mmxencfrag.c @@ -65,7 +65,7 @@ unsigned oc_enc_frag_sad_mmxext(const unsigned char *_src, "paddw %%mm6,%%mm0\n\t" "paddw %%mm2,%%mm0\n\t" "movd %%mm0,%[ret]\n\t" - :[ret]"=a"(ret),[src]"+%r"(_src),[ref]"+r"(_ref),[ystride3]"=&r"(ystride3) + :[ret]"=a"(ret),[src]"+r"(_src),[ref]"+r"(_ref),[ystride3]"=&r"(ystride3) :[ystride]"r"((ptrdiff_t)_ystride) ); return (unsigned)ret; @@ -87,7 +87,9 @@ unsigned oc_enc_frag_sad_thresh_mmxext(const unsigned char *_src, The latter is exactly 1 too large when the low bit of two corresponding \ bytes is only set in one of them. \ Therefore we pxor the operands, pand to mask out the low bits, and psubb to \ - correct the output of pavgb.*/ \ + correct the output of pavgb. \ + TODO: This should be rewritten to compute ~pavgb(~a,~b) instead, which \ + schedules better; currently, however, this function is unused.*/ \ "movq %%mm0,%%mm6\n\t" \ "lea (%[ref1],%[ystride],2),%[ref1]\n\t" \ "pxor %%mm1,%%mm0\n\t" \ @@ -153,7 +155,7 @@ unsigned oc_enc_frag_sad2_thresh_mmxext(const unsigned char *_src, OC_SAD2_LOOP OC_SAD2_LOOP OC_SAD2_TAIL - :[ret]"=&a"(ret),[src]"+r"(_src),[ref1]"+%r"(_ref1),[ref2]"+r"(_ref2) + :[ret]"=&a"(ret),[src]"+r"(_src),[ref1]"+r"(_ref1),[ref2]"+r"(_ref2) :[ystride]"r"((ptrdiff_t)_ystride) ); return (unsigned)ret; @@ -163,54 +165,54 @@ unsigned oc_enc_frag_sad2_thresh_mmxext(const unsigned char *_src, 16-bit difference in %%mm0...%%mm7.*/ #define OC_LOAD_SUB_8x4(_off) \ "#OC_LOAD_SUB_8x4\n\t" \ - "movd "_off"(%[src]),%%mm0\n\t" \ - "movd "_off"(%[ref]),%%mm4\n\t" \ - "movd "_off"(%[src],%[src_ystride]),%%mm1\n\t" \ + "movd "#_off"(%[src]),%%mm0\n\t" \ + "movd "#_off"(%[ref]),%%mm4\n\t" \ + "movd "#_off"(%[src],%[src_ystride]),%%mm1\n\t" \ "lea (%[src],%[src_ystride],2),%[src]\n\t" \ - "movd "_off"(%[ref],%[ref_ystride]),%%mm5\n\t" \ + "movd "#_off"(%[ref],%[ref_ystride]),%%mm5\n\t" \ "lea (%[ref],%[ref_ystride],2),%[ref]\n\t" \ - "movd "_off"(%[src]),%%mm2\n\t" \ - "movd "_off"(%[ref]),%%mm7\n\t" \ - "movd "_off"(%[src],%[src_ystride]),%%mm3\n\t" \ - "movd "_off"(%[ref],%[ref_ystride]),%%mm6\n\t" \ + "movd "#_off"(%[src]),%%mm2\n\t" \ + "movd "#_off"(%[ref]),%%mm7\n\t" \ + "movd "#_off"(%[src],%[src_ystride]),%%mm3\n\t" \ + "movd "#_off"(%[ref],%[ref_ystride]),%%mm6\n\t" \ "punpcklbw %%mm4,%%mm0\n\t" \ "lea (%[src],%[src_ystride],2),%[src]\n\t" \ "punpcklbw %%mm4,%%mm4\n\t" \ "lea (%[ref],%[ref_ystride],2),%[ref]\n\t" \ "psubw %%mm4,%%mm0\n\t" \ - "movd "_off"(%[src]),%%mm4\n\t" \ - "movq %%mm0,"_off"*2(%[buf])\n\t" \ - "movd "_off"(%[ref]),%%mm0\n\t" \ + "movd "#_off"(%[src]),%%mm4\n\t" \ + "movq %%mm0,"OC_MEM_OFFS(_off*2,buf)"\n\t" \ + "movd "#_off"(%[ref]),%%mm0\n\t" \ "punpcklbw %%mm5,%%mm1\n\t" \ "punpcklbw %%mm5,%%mm5\n\t" \ "psubw %%mm5,%%mm1\n\t" \ - "movd "_off"(%[src],%[src_ystride]),%%mm5\n\t" \ + "movd "#_off"(%[src],%[src_ystride]),%%mm5\n\t" \ "punpcklbw %%mm7,%%mm2\n\t" \ "punpcklbw %%mm7,%%mm7\n\t" \ "psubw %%mm7,%%mm2\n\t" \ - "movd "_off"(%[ref],%[ref_ystride]),%%mm7\n\t" \ + "movd "#_off"(%[ref],%[ref_ystride]),%%mm7\n\t" \ "punpcklbw %%mm6,%%mm3\n\t" \ "lea (%[src],%[src_ystride],2),%[src]\n\t" \ "punpcklbw %%mm6,%%mm6\n\t" \ "psubw %%mm6,%%mm3\n\t" \ - "movd "_off"(%[src]),%%mm6\n\t" \ + "movd "#_off"(%[src]),%%mm6\n\t" \ "punpcklbw %%mm0,%%mm4\n\t" \ "lea (%[ref],%[ref_ystride],2),%[ref]\n\t" \ "punpcklbw %%mm0,%%mm0\n\t" \ "lea (%[src],%[src_ystride],2),%[src]\n\t" \ "psubw %%mm0,%%mm4\n\t" \ - "movd "_off"(%[ref]),%%mm0\n\t" \ + "movd "#_off"(%[ref]),%%mm0\n\t" \ "punpcklbw %%mm7,%%mm5\n\t" \ "neg %[src_ystride]\n\t" \ "punpcklbw %%mm7,%%mm7\n\t" \ "psubw %%mm7,%%mm5\n\t" \ - "movd "_off"(%[src],%[src_ystride]),%%mm7\n\t" \ + "movd "#_off"(%[src],%[src_ystride]),%%mm7\n\t" \ "punpcklbw %%mm0,%%mm6\n\t" \ "lea (%[ref],%[ref_ystride],2),%[ref]\n\t" \ "punpcklbw %%mm0,%%mm0\n\t" \ "neg %[ref_ystride]\n\t" \ "psubw %%mm0,%%mm6\n\t" \ - "movd "_off"(%[ref],%[ref_ystride]),%%mm0\n\t" \ + "movd "#_off"(%[ref],%[ref_ystride]),%%mm0\n\t" \ "lea (%[src],%[src_ystride],8),%[src]\n\t" \ "punpcklbw %%mm0,%%mm7\n\t" \ "neg %[src_ystride]\n\t" \ @@ -218,24 +220,24 @@ unsigned oc_enc_frag_sad2_thresh_mmxext(const unsigned char *_src, "lea (%[ref],%[ref_ystride],8),%[ref]\n\t" \ "psubw %%mm0,%%mm7\n\t" \ "neg %[ref_ystride]\n\t" \ - "movq "_off"*2(%[buf]),%%mm0\n\t" \ + "movq "OC_MEM_OFFS(_off*2,buf)",%%mm0\n\t" \ /*Load an 8x4 array of pixel values from %[src] into %%mm0...%%mm7.*/ #define OC_LOAD_8x4(_off) \ "#OC_LOAD_8x4\n\t" \ - "movd "_off"(%[src]),%%mm0\n\t" \ - "movd "_off"(%[src],%[ystride]),%%mm1\n\t" \ - "movd "_off"(%[src],%[ystride],2),%%mm2\n\t" \ + "movd "#_off"(%[src]),%%mm0\n\t" \ + "movd "#_off"(%[src],%[ystride]),%%mm1\n\t" \ + "movd "#_off"(%[src],%[ystride],2),%%mm2\n\t" \ "pxor %%mm7,%%mm7\n\t" \ - "movd "_off"(%[src],%[ystride3]),%%mm3\n\t" \ + "movd "#_off"(%[src],%[ystride3]),%%mm3\n\t" \ "punpcklbw %%mm7,%%mm0\n\t" \ - "movd "_off"(%[src4]),%%mm4\n\t" \ + "movd "#_off"(%[src4]),%%mm4\n\t" \ "punpcklbw %%mm7,%%mm1\n\t" \ - "movd "_off"(%[src4],%[ystride]),%%mm5\n\t" \ + "movd "#_off"(%[src4],%[ystride]),%%mm5\n\t" \ "punpcklbw %%mm7,%%mm2\n\t" \ - "movd "_off"(%[src4],%[ystride],2),%%mm6\n\t" \ + "movd "#_off"(%[src4],%[ystride],2),%%mm6\n\t" \ "punpcklbw %%mm7,%%mm3\n\t" \ - "movd "_off"(%[src4],%[ystride3]),%%mm7\n\t" \ + "movd "#_off"(%[src4],%[ystride3]),%%mm7\n\t" \ "punpcklbw %%mm4,%%mm4\n\t" \ "punpcklbw %%mm5,%%mm5\n\t" \ "psrlw $8,%%mm4\n\t" \ @@ -248,7 +250,7 @@ unsigned oc_enc_frag_sad2_thresh_mmxext(const unsigned char *_src, /*Performs the first two stages of an 8-point 1-D Hadamard transform. The transform is performed in place, except that outputs 0-3 are swapped with outputs 4-7. - Outputs 2, 3, 6 and 7 from the second stage are negated (which allows us to + Outputs 2, 3, 6, and 7 from the second stage are negated (which allows us to perform this stage in place with no temporary registers).*/ #define OC_HADAMARD_AB_8x4 \ "#OC_HADAMARD_AB_8x4\n\t" \ @@ -281,7 +283,7 @@ unsigned oc_enc_frag_sad2_thresh_mmxext(const unsigned char *_src, "psubw %%mm5,%%mm7\n\t" \ /*Performs the last stage of an 8-point 1-D Hadamard transform in place. - Ouputs 1, 3, 5, and 7 are negated (which allows us to perform this stage in + Outputs 1, 3, 5, and 7 are negated (which allows us to perform this stage in place with no temporary registers).*/ #define OC_HADAMARD_C_8x4 \ "#OC_HADAMARD_C_8x4\n\t" \ @@ -324,8 +326,8 @@ unsigned oc_enc_frag_sad2_thresh_mmxext(const unsigned char *_src, Even with pabsw, it would be (3+1)*8+7=39 instructions (with no spills). \ This implementation is only 26 (+4 for spilling registers).*/ \ "#OC_HADAMARD_C_ABS_ACCUM_A_8x4\n\t" \ - "movq %%mm7,"_r7"(%[buf])\n\t" \ - "movq %%mm6,"_r6"(%[buf])\n\t" \ + "movq %%mm7,"OC_MEM_OFFS(_r7,buf)"\n\t" \ + "movq %%mm6,"OC_MEM_OFFS(_r6,buf)"\n\t" \ /*mm7={0x7FFF}x4 \ mm0=max(abs(mm0),abs(mm1))-0x7FFF*/ \ "pcmpeqb %%mm7,%%mm7\n\t" \ @@ -343,14 +345,14 @@ unsigned oc_enc_frag_sad2_thresh_mmxext(const unsigned char *_src, "pmaxsw %%mm5,%%mm4\n\t" \ "paddw %%mm3,%%mm6\n\t" \ "paddw %%mm5,%%mm1\n\t" \ - "movq "_r7"(%[buf]),%%mm3\n\t" \ + "movq "OC_MEM_OFFS(_r7,buf)",%%mm3\n\t" \ /*Performs the second part of the final stage of the Hadamard transform and summing of absolute values.*/ #define OC_HADAMARD_C_ABS_ACCUM_B_8x4(_r6,_r7) \ "#OC_HADAMARD_C_ABS_ACCUM_B_8x4\n\t" \ "paddsw %%mm7,%%mm6\n\t" \ - "movq "_r6"(%[buf]),%%mm5\n\t" \ + "movq "OC_MEM_OFFS(_r6,buf)",%%mm5\n\t" \ "paddsw %%mm7,%%mm1\n\t" \ "psubw %%mm6,%%mm2\n\t" \ "psubw %%mm1,%%mm4\n\t" \ @@ -391,7 +393,7 @@ unsigned oc_enc_frag_sad2_thresh_mmxext(const unsigned char *_src, #define OC_TRANSPOSE_4x4x2(_off) \ "#OC_TRANSPOSE_4x4x2\n\t" \ /*First 4x4 transpose:*/ \ - "movq %%mm5,0x10+"_off"(%[buf])\n\t" \ + "movq %%mm5,"OC_MEM_OFFS(0x10+(_off),buf)"\n\t" \ /*mm0 = e3 e2 e1 e0 \ mm1 = f3 f2 f1 f0 \ mm2 = g3 g2 g1 g0 \ @@ -411,13 +413,13 @@ unsigned oc_enc_frag_sad2_thresh_mmxext(const unsigned char *_src, "punpckhdq %%mm2,%%mm1\n\t" \ "movq %%mm3,%%mm2\n\t" \ "punpckhdq %%mm5,%%mm3\n\t" \ - "movq %%mm0,0x40+"_off"(%[buf])\n\t" \ + "movq %%mm0,"OC_MEM_OFFS(0x40+(_off),buf)"\n\t" \ "punpckldq %%mm5,%%mm2\n\t" \ /*mm0 = h0 g0 f0 e0 \ mm1 = h1 g1 f1 e1 \ mm2 = h2 g2 f2 e2 \ mm3 = h3 g3 f3 e3*/ \ - "movq 0x10+"_off"(%[buf]),%%mm5\n\t" \ + "movq "OC_MEM_OFFS(0x10+(_off),buf)",%%mm5\n\t" \ /*Second 4x4 transpose:*/ \ /*mm4 = a3 a2 a1 a0 \ mm5 = b3 b2 b1 b0 \ @@ -425,11 +427,11 @@ unsigned oc_enc_frag_sad2_thresh_mmxext(const unsigned char *_src, mm7 = d3 d2 d1 d0*/ \ "movq %%mm6,%%mm0\n\t" \ "punpcklwd %%mm7,%%mm6\n\t" \ - "movq %%mm1,0x50+"_off"(%[buf])\n\t" \ + "movq %%mm1,"OC_MEM_OFFS(0x50+(_off),buf)"\n\t" \ "punpckhwd %%mm7,%%mm0\n\t" \ "movq %%mm4,%%mm7\n\t" \ "punpcklwd %%mm5,%%mm4\n\t" \ - "movq %%mm2,0x60+"_off"(%[buf])\n\t" \ + "movq %%mm2,"OC_MEM_OFFS(0x60+(_off),buf)"\n\t" \ "punpckhwd %%mm5,%%mm7\n\t" \ /*mm4 = b1 a1 b0 a0 \ mm7 = b3 a3 b2 a2 \ @@ -437,7 +439,7 @@ unsigned oc_enc_frag_sad2_thresh_mmxext(const unsigned char *_src, mm0 = d3 c3 d2 c2*/ \ "movq %%mm4,%%mm5\n\t" \ "punpckldq %%mm6,%%mm4\n\t" \ - "movq %%mm3,0x70+"_off"(%[buf])\n\t" \ + "movq %%mm3,"OC_MEM_OFFS(0x70+(_off),buf)"\n\t" \ "punpckhdq %%mm6,%%mm5\n\t" \ "movq %%mm7,%%mm6\n\t" \ "punpckhdq %%mm0,%%mm7\n\t" \ @@ -447,100 +449,102 @@ unsigned oc_enc_frag_sad2_thresh_mmxext(const unsigned char *_src, mm6 = d2 c2 b2 a2 \ mm7 = d3 c3 b3 a3*/ \ -static unsigned oc_int_frag_satd_thresh_mmxext(const unsigned char *_src, - int _src_ystride,const unsigned char *_ref,int _ref_ystride,unsigned _thresh){ - OC_ALIGN8(ogg_int16_t buf[64]); - ogg_int16_t *bufp; - unsigned ret; - unsigned ret2; - bufp=buf; +static unsigned oc_int_frag_satd_mmxext(int *_dc, + const unsigned char *_src,int _src_ystride, + const unsigned char *_ref,int _ref_ystride){ + OC_ALIGN8(ogg_int16_t buf[64]); + unsigned ret; + unsigned ret2; + int dc; __asm__ __volatile__( - OC_LOAD_SUB_8x4("0x00") + OC_LOAD_SUB_8x4(0x00) OC_HADAMARD_8x4 - OC_TRANSPOSE_4x4x2("0x00") + OC_TRANSPOSE_4x4x2(0x00) /*Finish swapping out this 8x4 block to make room for the next one. mm0...mm3 have been swapped out already.*/ - "movq %%mm4,0x00(%[buf])\n\t" - "movq %%mm5,0x10(%[buf])\n\t" - "movq %%mm6,0x20(%[buf])\n\t" - "movq %%mm7,0x30(%[buf])\n\t" - OC_LOAD_SUB_8x4("0x04") + "movq %%mm4,"OC_MEM_OFFS(0x00,buf)"\n\t" + "movq %%mm5,"OC_MEM_OFFS(0x10,buf)"\n\t" + "movq %%mm6,"OC_MEM_OFFS(0x20,buf)"\n\t" + "movq %%mm7,"OC_MEM_OFFS(0x30,buf)"\n\t" + OC_LOAD_SUB_8x4(0x04) OC_HADAMARD_8x4 - OC_TRANSPOSE_4x4x2("0x08") + OC_TRANSPOSE_4x4x2(0x08) /*Here the first 4x4 block of output from the last transpose is the second 4x4 block of input for the next transform. We have cleverly arranged that it already be in the appropriate place, so we only have to do half the loads.*/ - "movq 0x10(%[buf]),%%mm1\n\t" - "movq 0x20(%[buf]),%%mm2\n\t" - "movq 0x30(%[buf]),%%mm3\n\t" - "movq 0x00(%[buf]),%%mm0\n\t" - OC_HADAMARD_ABS_ACCUM_8x4("0x28","0x38") + "movq "OC_MEM_OFFS(0x10,buf)",%%mm1\n\t" + "movq "OC_MEM_OFFS(0x20,buf)",%%mm2\n\t" + "movq "OC_MEM_OFFS(0x30,buf)",%%mm3\n\t" + "movq "OC_MEM_OFFS(0x00,buf)",%%mm0\n\t" + /*We split out the stages here so we can save the DC coefficient in the + middle.*/ + OC_HADAMARD_AB_8x4 + OC_HADAMARD_C_ABS_ACCUM_A_8x4(0x28,0x38) + "movd %%mm1,%[dc]\n\t" + OC_HADAMARD_C_ABS_ACCUM_B_8x4(0x28,0x38) /*Up to this point, everything fit in 16 bits (8 input + 1 for the difference + 2*3 for the two 8-point 1-D Hadamards - 1 for the abs - 1 for the factor of two we dropped + 3 for the vertical accumulation). Now we finally have to promote things to dwords. We break this part out of OC_HADAMARD_ABS_ACCUM_8x4 to hide the long latency of pmaddwd by starting the next series of loads now.*/ - "mov %[thresh],%[ret2]\n\t" "pmaddwd %%mm7,%%mm0\n\t" - "movq 0x50(%[buf]),%%mm1\n\t" - "movq 0x58(%[buf]),%%mm5\n\t" + "movq "OC_MEM_OFFS(0x50,buf)",%%mm1\n\t" + "movq "OC_MEM_OFFS(0x58,buf)",%%mm5\n\t" "movq %%mm0,%%mm4\n\t" - "movq 0x60(%[buf]),%%mm2\n\t" + "movq "OC_MEM_OFFS(0x60,buf)",%%mm2\n\t" "punpckhdq %%mm0,%%mm0\n\t" - "movq 0x68(%[buf]),%%mm6\n\t" + "movq "OC_MEM_OFFS(0x68,buf)",%%mm6\n\t" "paddd %%mm0,%%mm4\n\t" - "movq 0x70(%[buf]),%%mm3\n\t" - "movd %%mm4,%[ret]\n\t" - "movq 0x78(%[buf]),%%mm7\n\t" - /*The sums produced by OC_HADAMARD_ABS_ACCUM_8x4 each have an extra 4 - added to them, and a factor of two removed; correct the final sum here.*/ - "lea -32(%[ret],%[ret]),%[ret]\n\t" - "movq 0x40(%[buf]),%%mm0\n\t" - "cmp %[ret2],%[ret]\n\t" - "movq 0x48(%[buf]),%%mm4\n\t" - "jae 1f\n\t" - OC_HADAMARD_ABS_ACCUM_8x4("0x68","0x78") + "movq "OC_MEM_OFFS(0x70,buf)",%%mm3\n\t" + "movd %%mm4,%[ret2]\n\t" + "movq "OC_MEM_OFFS(0x78,buf)",%%mm7\n\t" + "movq "OC_MEM_OFFS(0x40,buf)",%%mm0\n\t" + "movq "OC_MEM_OFFS(0x48,buf)",%%mm4\n\t" + OC_HADAMARD_ABS_ACCUM_8x4(0x68,0x78) "pmaddwd %%mm7,%%mm0\n\t" - /*There isn't much to stick in here to hide the latency this time, but the - alternative to pmaddwd is movq->punpcklwd->punpckhwd->paddd, whose - latency is even worse.*/ - "sub $32,%[ret]\n\t" + /*Subtract abs(dc) from 2*ret2.*/ + "movsx %w[dc],%[dc]\n\t" + "cdq\n\t" + "lea (%[ret],%[ret2],2),%[ret2]\n\t" "movq %%mm0,%%mm4\n\t" "punpckhdq %%mm0,%%mm0\n\t" + "xor %[dc],%[ret]\n\t" "paddd %%mm0,%%mm4\n\t" - "movd %%mm4,%[ret2]\n\t" - "lea (%[ret],%[ret2],2),%[ret]\n\t" - ".p2align 4,,15\n\t" - "1:\n\t" - /*Although it looks like we're using 7 registers here, gcc can alias %[ret] + /*The sums produced by OC_HADAMARD_ABS_ACCUM_8x4 each have an extra 4 + added to them, a factor of two removed, and the DC value included; + correct the final sum here.*/ + "sub %[ret],%[ret2]\n\t" + "movd %%mm4,%[ret]\n\t" + "lea -64(%[ret2],%[ret],2),%[ret]\n\t" + /*Although it looks like we're using 8 registers here, gcc can alias %[ret] and %[ret2] with some of the inputs, since for once we don't write to - them until after we're done using everything but %[buf] (which is also - listed as an output to ensure gcc _doesn't_ alias them against it).*/ + them until after we're done using everything but %[buf].*/ /*Note that _src_ystride and _ref_ystride must be given non-overlapping constraints, otherewise if gcc can prove they're equal it will allocate them to the same register (which is bad); _src and _ref face a similar problem, though those are never actually the same.*/ - :[ret]"=a"(ret),[ret2]"=r"(ret2),[buf]"+r"(bufp) + :[ret]"=d"(ret),[ret2]"=r"(ret2),[dc]"=a"(dc), + [buf]"=m"(OC_ARRAY_OPERAND(ogg_int16_t,buf,64)) :[src]"r"(_src),[src_ystride]"c"((ptrdiff_t)_src_ystride), - [ref]"r"(_ref),[ref_ystride]"d"((ptrdiff_t)_ref_ystride), - [thresh]"m"(_thresh) + [ref]"r"(_ref),[ref_ystride]"d"((ptrdiff_t)_ref_ystride) /*We have to use neg, so we actually clobber the condition codes for once (not to mention cmp, sub, and add).*/ :"cc" ); + *_dc=dc; return ret; } -unsigned oc_enc_frag_satd_thresh_mmxext(const unsigned char *_src, - const unsigned char *_ref,int _ystride,unsigned _thresh){ - return oc_int_frag_satd_thresh_mmxext(_src,_ystride,_ref,_ystride,_thresh); +unsigned oc_enc_frag_satd_mmxext(int *_dc,const unsigned char *_src, + const unsigned char *_ref,int _ystride){ + return oc_int_frag_satd_mmxext(_dc,_src,_ystride,_ref,_ystride); } /*Our internal implementation of frag_copy2 takes an extra stride parameter so - we can share code with oc_enc_frag_satd2_thresh_mmxext().*/ -static void oc_int_frag_copy2_mmxext(unsigned char *_dst,int _dst_ystride, + we can share code with oc_enc_frag_satd2_mmxext().*/ +void oc_int_frag_copy2_mmxext(unsigned char *_dst,int _dst_ystride, const unsigned char *_src1,const unsigned char *_src2,int _src_ystride){ __asm__ __volatile__( /*Load the first 3 rows.*/ @@ -649,55 +653,53 @@ static void oc_int_frag_copy2_mmxext(unsigned char *_dst,int _dst_ystride, "psubb %%mm4,%%mm2\n\t" /*%%mm2 (row 7) is done, write it out.*/ "movq %%mm2,(%[dst],%[dst_ystride])\n\t" - :[dst]"+r"(_dst),[src1]"+%r"(_src1),[src2]"+r"(_src2) + :[dst]"+r"(_dst),[src1]"+r"(_src1),[src2]"+r"(_src2) :[dst_ystride]"r"((ptrdiff_t)_dst_ystride), [src_ystride]"r"((ptrdiff_t)_src_ystride) :"memory" ); } -unsigned oc_enc_frag_satd2_thresh_mmxext(const unsigned char *_src, - const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, - unsigned _thresh){ +unsigned oc_enc_frag_satd2_mmxext(int *_dc,const unsigned char *_src, + const unsigned char *_ref1,const unsigned char *_ref2,int _ystride){ OC_ALIGN8(unsigned char ref[64]); oc_int_frag_copy2_mmxext(ref,8,_ref1,_ref2,_ystride); - return oc_int_frag_satd_thresh_mmxext(_src,_ystride,ref,8,_thresh); + return oc_int_frag_satd_mmxext(_dc,_src,_ystride,ref,8); } -unsigned oc_enc_frag_intra_satd_mmxext(const unsigned char *_src, - int _ystride){ - OC_ALIGN8(ogg_int16_t buf[64]); - ogg_int16_t *bufp; - unsigned ret; - unsigned ret2; - bufp=buf; +unsigned oc_enc_frag_intra_satd_mmxext(int *_dc, + const unsigned char *_src,int _ystride){ + OC_ALIGN8(ogg_int16_t buf[64]); + unsigned ret; + unsigned ret2; + int dc; __asm__ __volatile__( - OC_LOAD_8x4("0x00") + OC_LOAD_8x4(0x00) OC_HADAMARD_8x4 - OC_TRANSPOSE_4x4x2("0x00") + OC_TRANSPOSE_4x4x2(0x00) /*Finish swapping out this 8x4 block to make room for the next one. mm0...mm3 have been swapped out already.*/ - "movq %%mm4,0x00(%[buf])\n\t" - "movq %%mm5,0x10(%[buf])\n\t" - "movq %%mm6,0x20(%[buf])\n\t" - "movq %%mm7,0x30(%[buf])\n\t" - OC_LOAD_8x4("0x04") + "movq %%mm4,"OC_MEM_OFFS(0x00,buf)"\n\t" + "movq %%mm5,"OC_MEM_OFFS(0x10,buf)"\n\t" + "movq %%mm6,"OC_MEM_OFFS(0x20,buf)"\n\t" + "movq %%mm7,"OC_MEM_OFFS(0x30,buf)"\n\t" + OC_LOAD_8x4(0x04) OC_HADAMARD_8x4 - OC_TRANSPOSE_4x4x2("0x08") + OC_TRANSPOSE_4x4x2(0x08) /*Here the first 4x4 block of output from the last transpose is the second 4x4 block of input for the next transform. We have cleverly arranged that it already be in the appropriate place, so we only have to do half the loads.*/ - "movq 0x10(%[buf]),%%mm1\n\t" - "movq 0x20(%[buf]),%%mm2\n\t" - "movq 0x30(%[buf]),%%mm3\n\t" - "movq 0x00(%[buf]),%%mm0\n\t" + "movq "OC_MEM_OFFS(0x10,buf)",%%mm1\n\t" + "movq "OC_MEM_OFFS(0x20,buf)",%%mm2\n\t" + "movq "OC_MEM_OFFS(0x30,buf)",%%mm3\n\t" + "movq "OC_MEM_OFFS(0x00,buf)",%%mm0\n\t" /*We split out the stages here so we can save the DC coefficient in the middle.*/ OC_HADAMARD_AB_8x4 - OC_HADAMARD_C_ABS_ACCUM_A_8x4("0x28","0x38") - "movd %%mm1,%[ret]\n\t" - OC_HADAMARD_C_ABS_ACCUM_B_8x4("0x28","0x38") + OC_HADAMARD_C_ABS_ACCUM_A_8x4(0x28,0x38) + "movd %%mm1,%[dc]\n\t" + OC_HADAMARD_C_ABS_ACCUM_B_8x4(0x28,0x38) /*Up to this point, everything fit in 16 bits (8 input + 1 for the difference + 2*3 for the two 8-point 1-D Hadamards - 1 for the abs - 1 for the factor of two we dropped + 3 for the vertical accumulation). @@ -705,41 +707,43 @@ unsigned oc_enc_frag_intra_satd_mmxext(const unsigned char *_src, We break this part out of OC_HADAMARD_ABS_ACCUM_8x4 to hide the long latency of pmaddwd by starting the next series of loads now.*/ "pmaddwd %%mm7,%%mm0\n\t" - "movq 0x50(%[buf]),%%mm1\n\t" - "movq 0x58(%[buf]),%%mm5\n\t" - "movq 0x60(%[buf]),%%mm2\n\t" + "movq "OC_MEM_OFFS(0x50,buf)",%%mm1\n\t" + "movq "OC_MEM_OFFS(0x58,buf)",%%mm5\n\t" + "movq "OC_MEM_OFFS(0x60,buf)",%%mm2\n\t" "movq %%mm0,%%mm4\n\t" - "movq 0x68(%[buf]),%%mm6\n\t" + "movq "OC_MEM_OFFS(0x68,buf)",%%mm6\n\t" "punpckhdq %%mm0,%%mm0\n\t" - "movq 0x70(%[buf]),%%mm3\n\t" + "movq "OC_MEM_OFFS(0x70,buf)",%%mm3\n\t" "paddd %%mm0,%%mm4\n\t" - "movq 0x78(%[buf]),%%mm7\n\t" - "movd %%mm4,%[ret2]\n\t" - "movq 0x40(%[buf]),%%mm0\n\t" - "movq 0x48(%[buf]),%%mm4\n\t" - OC_HADAMARD_ABS_ACCUM_8x4("0x68","0x78") + "movq "OC_MEM_OFFS(0x78,buf)",%%mm7\n\t" + "movd %%mm4,%[ret]\n\t" + "movq "OC_MEM_OFFS(0x40,buf)",%%mm0\n\t" + "movq "OC_MEM_OFFS(0x48,buf)",%%mm4\n\t" + OC_HADAMARD_ABS_ACCUM_8x4(0x68,0x78) "pmaddwd %%mm7,%%mm0\n\t" /*We assume that the DC coefficient is always positive (which is true, because the input to the INTRA transform was not a difference).*/ - "movzx %w[ret],%[ret]\n\t" - "add %[ret2],%[ret2]\n\t" - "sub %[ret],%[ret2]\n\t" + "movzx %w[dc],%[dc]\n\t" + "add %[ret],%[ret]\n\t" + "sub %[dc],%[ret]\n\t" "movq %%mm0,%%mm4\n\t" "punpckhdq %%mm0,%%mm0\n\t" "paddd %%mm0,%%mm4\n\t" - "movd %%mm4,%[ret]\n\t" - "lea -64(%[ret2],%[ret],2),%[ret]\n\t" - /*Although it looks like we're using 7 registers here, gcc can alias %[ret] + "movd %%mm4,%[ret2]\n\t" + "lea -64(%[ret],%[ret2],2),%[ret]\n\t" + /*Although it looks like we're using 8 registers here, gcc can alias %[ret] and %[ret2] with some of the inputs, since for once we don't write to them until after we're done using everything but %[buf] (which is also listed as an output to ensure gcc _doesn't_ alias them against it).*/ - :[ret]"=a"(ret),[ret2]"=r"(ret2),[buf]"+r"(bufp) + :[ret]"=a"(ret),[ret2]"=r"(ret2),[dc]"=r"(dc), + [buf]"=m"(OC_ARRAY_OPERAND(ogg_int16_t,buf,64)) :[src]"r"(_src),[src4]"r"(_src+4*_ystride), [ystride]"r"((ptrdiff_t)_ystride),[ystride3]"r"((ptrdiff_t)3*_ystride) /*We have to use sub, so we actually clobber the condition codes for once (not to mention add).*/ :"cc" ); + *_dc=dc; return ret; } diff --git a/thirdparty/libtheora/x86/mmxfdct.c b/thirdparty/libtheora/x86/mmxfdct.c index 211875255e..17668358b8 100644 --- a/thirdparty/libtheora/x86/mmxfdct.c +++ b/thirdparty/libtheora/x86/mmxfdct.c @@ -12,6 +12,7 @@ /*MMX fDCT implementation for x86_32*/ /*$Id: fdct_ses2.c 14579 2008-03-12 06:42:40Z xiphmont $*/ #include "x86enc.h" +#include "x86zigzag.h" #if defined(OC_X86_ASM) @@ -462,8 +463,9 @@ mm7 = d3 c3 b3 a3*/ \ /*MMX implementation of the fDCT.*/ -void oc_enc_fdct8x8_mmx(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ - ptrdiff_t a; +void oc_enc_fdct8x8_mmxext(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ + OC_ALIGN8(ogg_int16_t buf[64]); + ptrdiff_t a; __asm__ __volatile__( /*Add two extra bits of working precision to improve accuracy; any more and we could overflow.*/ @@ -586,77 +588,88 @@ void oc_enc_fdct8x8_mmx(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ "movq 0x30(%[y]),%%mm3\n\t" OC_FDCT_STAGE1_8x4 OC_FDCT8x4("0x00","0x10","0x20","0x30","0x08","0x18","0x28","0x38") - OC_TRANSPOSE8x4("0x00","0x10","0x20","0x30","0x08","0x18","0x28","0x38") - /*mm0={-2}x4*/ - "pcmpeqw %%mm0,%%mm0\n\t" - "paddw %%mm0,%%mm0\n\t" - /*Round the results.*/ - "psubw %%mm0,%%mm1\n\t" - "psubw %%mm0,%%mm2\n\t" - "psraw $2,%%mm1\n\t" - "psubw %%mm0,%%mm3\n\t" - "movq %%mm1,0x18(%[y])\n\t" - "psraw $2,%%mm2\n\t" - "psubw %%mm0,%%mm4\n\t" - "movq 0x08(%[y]),%%mm1\n\t" - "psraw $2,%%mm3\n\t" - "psubw %%mm0,%%mm5\n\t" + /*mm2={-2}x4*/ + "pcmpeqw %%mm2,%%mm2\n\t" + "paddw %%mm2,%%mm2\n\t" + /*Round and store the results (no transpose).*/ + "movq 0x10(%[y]),%%mm7\n\t" + "psubw %%mm2,%%mm4\n\t" + "psubw %%mm2,%%mm6\n\t" "psraw $2,%%mm4\n\t" - "psubw %%mm0,%%mm6\n\t" - "psraw $2,%%mm5\n\t" - "psubw %%mm0,%%mm7\n\t" + "psubw %%mm2,%%mm0\n\t" + "movq %%mm4,"OC_MEM_OFFS(0x00,buf)"\n\t" + "movq 0x30(%[y]),%%mm4\n\t" "psraw $2,%%mm6\n\t" - "psubw %%mm0,%%mm1\n\t" + "psubw %%mm2,%%mm5\n\t" + "movq %%mm6,"OC_MEM_OFFS(0x20,buf)"\n\t" + "psraw $2,%%mm0\n\t" + "psubw %%mm2,%%mm3\n\t" + "movq %%mm0,"OC_MEM_OFFS(0x40,buf)"\n\t" + "psraw $2,%%mm5\n\t" + "psubw %%mm2,%%mm1\n\t" + "movq %%mm5,"OC_MEM_OFFS(0x50,buf)"\n\t" + "psraw $2,%%mm3\n\t" + "psubw %%mm2,%%mm7\n\t" + "movq %%mm3,"OC_MEM_OFFS(0x60,buf)"\n\t" + "psraw $2,%%mm1\n\t" + "psubw %%mm2,%%mm4\n\t" + "movq %%mm1,"OC_MEM_OFFS(0x70,buf)"\n\t" "psraw $2,%%mm7\n\t" + "movq %%mm7,"OC_MEM_OFFS(0x10,buf)"\n\t" + "psraw $2,%%mm4\n\t" + "movq %%mm4,"OC_MEM_OFFS(0x30,buf)"\n\t" + /*Load the next block.*/ "movq 0x40(%[y]),%%mm0\n\t" - "psraw $2,%%mm1\n\t" - "movq %%mm7,0x30(%[y])\n\t" "movq 0x78(%[y]),%%mm7\n\t" - "movq %%mm1,0x08(%[y])\n\t" "movq 0x50(%[y]),%%mm1\n\t" - "movq %%mm6,0x20(%[y])\n\t" "movq 0x68(%[y]),%%mm6\n\t" - "movq %%mm2,0x28(%[y])\n\t" "movq 0x60(%[y]),%%mm2\n\t" - "movq %%mm5,0x10(%[y])\n\t" "movq 0x58(%[y]),%%mm5\n\t" - "movq %%mm3,0x38(%[y])\n\t" "movq 0x70(%[y]),%%mm3\n\t" - "movq %%mm4,0x00(%[y])\n\t" "movq 0x48(%[y]),%%mm4\n\t" OC_FDCT_STAGE1_8x4 OC_FDCT8x4("0x40","0x50","0x60","0x70","0x48","0x58","0x68","0x78") - OC_TRANSPOSE8x4("0x40","0x50","0x60","0x70","0x48","0x58","0x68","0x78") - /*mm0={-2}x4*/ - "pcmpeqw %%mm0,%%mm0\n\t" - "paddw %%mm0,%%mm0\n\t" - /*Round the results.*/ - "psubw %%mm0,%%mm1\n\t" - "psubw %%mm0,%%mm2\n\t" - "psraw $2,%%mm1\n\t" - "psubw %%mm0,%%mm3\n\t" - "movq %%mm1,0x58(%[y])\n\t" - "psraw $2,%%mm2\n\t" - "psubw %%mm0,%%mm4\n\t" - "movq 0x48(%[y]),%%mm1\n\t" - "psraw $2,%%mm3\n\t" - "psubw %%mm0,%%mm5\n\t" - "movq %%mm2,0x68(%[y])\n\t" + /*mm2={-2}x4*/ + "pcmpeqw %%mm2,%%mm2\n\t" + "paddw %%mm2,%%mm2\n\t" + /*Round and store the results (no transpose).*/ + "movq 0x50(%[y]),%%mm7\n\t" + "psubw %%mm2,%%mm4\n\t" + "psubw %%mm2,%%mm6\n\t" "psraw $2,%%mm4\n\t" - "psubw %%mm0,%%mm6\n\t" - "movq %%mm3,0x78(%[y])\n\t" - "psraw $2,%%mm5\n\t" - "psubw %%mm0,%%mm7\n\t" - "movq %%mm4,0x40(%[y])\n\t" + "psubw %%mm2,%%mm0\n\t" + "movq %%mm4,"OC_MEM_OFFS(0x08,buf)"\n\t" + "movq 0x70(%[y]),%%mm4\n\t" "psraw $2,%%mm6\n\t" - "psubw %%mm0,%%mm1\n\t" - "movq %%mm5,0x50(%[y])\n\t" - "psraw $2,%%mm7\n\t" - "movq %%mm6,0x60(%[y])\n\t" + "psubw %%mm2,%%mm5\n\t" + "movq %%mm6,"OC_MEM_OFFS(0x28,buf)"\n\t" + "psraw $2,%%mm0\n\t" + "psubw %%mm2,%%mm3\n\t" + "movq %%mm0,"OC_MEM_OFFS(0x48,buf)"\n\t" + "psraw $2,%%mm5\n\t" + "psubw %%mm2,%%mm1\n\t" + "movq %%mm5,"OC_MEM_OFFS(0x58,buf)"\n\t" + "psraw $2,%%mm3\n\t" + "psubw %%mm2,%%mm7\n\t" + "movq %%mm3,"OC_MEM_OFFS(0x68,buf)"\n\t" "psraw $2,%%mm1\n\t" - "movq %%mm7,0x70(%[y])\n\t" - "movq %%mm1,0x48(%[y])\n\t" - :[a]"=&r"(a) + "psubw %%mm2,%%mm4\n\t" + "movq %%mm1,"OC_MEM_OFFS(0x78,buf)"\n\t" + "psraw $2,%%mm7\n\t" + "movq %%mm7,"OC_MEM_OFFS(0x18,buf)"\n\t" + "psraw $2,%%mm4\n\t" + "movq %%mm4,"OC_MEM_OFFS(0x38,buf)"\n\t" + /*Final transpose and zig-zag.*/ +#define OC_ZZ_LOAD_ROW_LO(_row,_reg) \ + "movq "OC_MEM_OFFS(16*_row,buf)","_reg"\n\t" \ + +#define OC_ZZ_LOAD_ROW_HI(_row,_reg) \ + "movq "OC_MEM_OFFS(16*_row+8,buf)","_reg"\n\t" \ + + OC_TRANSPOSE_ZIG_ZAG_MMXEXT +#undef OC_ZZ_LOAD_ROW_LO +#undef OC_ZZ_LOAD_ROW_HI + :[a]"=&r"(a),[buf]"=m"(OC_ARRAY_OPERAND(ogg_int16_t,buf,64)) :[y]"r"(_y),[x]"r"(_x) :"memory" ); diff --git a/thirdparty/libtheora/x86/mmxfrag.c b/thirdparty/libtheora/x86/mmxfrag.c index 2c732939c3..b3ec508956 100644 --- a/thirdparty/libtheora/x86/mmxfrag.c +++ b/thirdparty/libtheora/x86/mmxfrag.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: mmxfrag.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ @@ -22,17 +22,92 @@ The iteration each instruction belongs to is marked in the comments as #i.*/ #include <stddef.h> #include "x86int.h" -#include "mmxfrag.h" #if defined(OC_X86_ASM) /*Copies an 8x8 block of pixels from _src to _dst, assuming _ystride bytes between rows.*/ +# define OC_FRAG_COPY_MMX(_dst,_src,_ystride) \ + do{ \ + const unsigned char *src; \ + unsigned char *dst; \ + ptrdiff_t ystride3; \ + src=(_src); \ + dst=(_dst); \ + __asm__ __volatile__( \ + /*src+0*ystride*/ \ + "movq (%[src]),%%mm0\n\t" \ + /*src+1*ystride*/ \ + "movq (%[src],%[ystride]),%%mm1\n\t" \ + /*ystride3=ystride*3*/ \ + "lea (%[ystride],%[ystride],2),%[ystride3]\n\t" \ + /*src+2*ystride*/ \ + "movq (%[src],%[ystride],2),%%mm2\n\t" \ + /*src+3*ystride*/ \ + "movq (%[src],%[ystride3]),%%mm3\n\t" \ + /*dst+0*ystride*/ \ + "movq %%mm0,(%[dst])\n\t" \ + /*dst+1*ystride*/ \ + "movq %%mm1,(%[dst],%[ystride])\n\t" \ + /*Pointer to next 4.*/ \ + "lea (%[src],%[ystride],4),%[src]\n\t" \ + /*dst+2*ystride*/ \ + "movq %%mm2,(%[dst],%[ystride],2)\n\t" \ + /*dst+3*ystride*/ \ + "movq %%mm3,(%[dst],%[ystride3])\n\t" \ + /*Pointer to next 4.*/ \ + "lea (%[dst],%[ystride],4),%[dst]\n\t" \ + /*src+0*ystride*/ \ + "movq (%[src]),%%mm0\n\t" \ + /*src+1*ystride*/ \ + "movq (%[src],%[ystride]),%%mm1\n\t" \ + /*src+2*ystride*/ \ + "movq (%[src],%[ystride],2),%%mm2\n\t" \ + /*src+3*ystride*/ \ + "movq (%[src],%[ystride3]),%%mm3\n\t" \ + /*dst+0*ystride*/ \ + "movq %%mm0,(%[dst])\n\t" \ + /*dst+1*ystride*/ \ + "movq %%mm1,(%[dst],%[ystride])\n\t" \ + /*dst+2*ystride*/ \ + "movq %%mm2,(%[dst],%[ystride],2)\n\t" \ + /*dst+3*ystride*/ \ + "movq %%mm3,(%[dst],%[ystride3])\n\t" \ + :[dst]"+r"(dst),[src]"+r"(src),[ystride3]"=&r"(ystride3) \ + :[ystride]"r"((ptrdiff_t)(_ystride)) \ + :"memory" \ + ); \ + } \ + while(0) + +/*Copies an 8x8 block of pixels from _src to _dst, assuming _ystride bytes + between rows.*/ void oc_frag_copy_mmx(unsigned char *_dst, const unsigned char *_src,int _ystride){ OC_FRAG_COPY_MMX(_dst,_src,_ystride); } +/*Copies the fragments specified by the lists of fragment indices from one + frame to another. + _dst_frame: The reference frame to copy to. + _src_frame: The reference frame to copy from. + _ystride: The row stride of the reference frames. + _fragis: A pointer to a list of fragment indices. + _nfragis: The number of fragment indices to copy. + _frag_buf_offs: The offsets of fragments in the reference frames.*/ +void oc_frag_copy_list_mmx(unsigned char *_dst_frame, + const unsigned char *_src_frame,int _ystride, + const ptrdiff_t *_fragis,ptrdiff_t _nfragis,const ptrdiff_t *_frag_buf_offs){ + ptrdiff_t fragii; + for(fragii=0;fragii<_nfragis;fragii++){ + ptrdiff_t frag_buf_off; + frag_buf_off=_frag_buf_offs[_fragis[fragii]]; + OC_FRAG_COPY_MMX(_dst_frame+frag_buf_off, + _src_frame+frag_buf_off,_ystride); + } +} + + void oc_frag_recon_intra_mmx(unsigned char *_dst,int _ystride, const ogg_int16_t *_residue){ __asm__ __volatile__( @@ -280,7 +355,7 @@ void oc_frag_recon_inter2_mmx(unsigned char *_dst,const unsigned char *_src1, /*Advance dest ptr.*/ "lea (%[dst],%[ystride],2),%[dst]\n\t" :[dst]"+r"(_dst),[residue]"+r"(_residue), - [src1]"+%r"(_src1),[src2]"+r"(_src2) + [src1]"+r"(_src1),[src2]"+r"(_src2) :[ystride]"r"((ptrdiff_t)_ystride) :"memory" ); diff --git a/thirdparty/libtheora/x86/mmxfrag.h b/thirdparty/libtheora/x86/mmxfrag.h deleted file mode 100644 index a398427629..0000000000 --- a/thirdparty/libtheora/x86/mmxfrag.h +++ /dev/null @@ -1,64 +0,0 @@ -#if !defined(_x86_mmxfrag_H) -# define _x86_mmxfrag_H (1) -# include <stddef.h> -# include "x86int.h" - -#if defined(OC_X86_ASM) - -/*Copies an 8x8 block of pixels from _src to _dst, assuming _ystride bytes - between rows.*/ -#define OC_FRAG_COPY_MMX(_dst,_src,_ystride) \ - do{ \ - const unsigned char *src; \ - unsigned char *dst; \ - ptrdiff_t ystride3; \ - src=(_src); \ - dst=(_dst); \ - __asm__ __volatile__( \ - /*src+0*ystride*/ \ - "movq (%[src]),%%mm0\n\t" \ - /*src+1*ystride*/ \ - "movq (%[src],%[ystride]),%%mm1\n\t" \ - /*ystride3=ystride*3*/ \ - "lea (%[ystride],%[ystride],2),%[ystride3]\n\t" \ - /*src+2*ystride*/ \ - "movq (%[src],%[ystride],2),%%mm2\n\t" \ - /*src+3*ystride*/ \ - "movq (%[src],%[ystride3]),%%mm3\n\t" \ - /*dst+0*ystride*/ \ - "movq %%mm0,(%[dst])\n\t" \ - /*dst+1*ystride*/ \ - "movq %%mm1,(%[dst],%[ystride])\n\t" \ - /*Pointer to next 4.*/ \ - "lea (%[src],%[ystride],4),%[src]\n\t" \ - /*dst+2*ystride*/ \ - "movq %%mm2,(%[dst],%[ystride],2)\n\t" \ - /*dst+3*ystride*/ \ - "movq %%mm3,(%[dst],%[ystride3])\n\t" \ - /*Pointer to next 4.*/ \ - "lea (%[dst],%[ystride],4),%[dst]\n\t" \ - /*src+0*ystride*/ \ - "movq (%[src]),%%mm0\n\t" \ - /*src+1*ystride*/ \ - "movq (%[src],%[ystride]),%%mm1\n\t" \ - /*src+2*ystride*/ \ - "movq (%[src],%[ystride],2),%%mm2\n\t" \ - /*src+3*ystride*/ \ - "movq (%[src],%[ystride3]),%%mm3\n\t" \ - /*dst+0*ystride*/ \ - "movq %%mm0,(%[dst])\n\t" \ - /*dst+1*ystride*/ \ - "movq %%mm1,(%[dst],%[ystride])\n\t" \ - /*dst+2*ystride*/ \ - "movq %%mm2,(%[dst],%[ystride],2)\n\t" \ - /*dst+3*ystride*/ \ - "movq %%mm3,(%[dst],%[ystride3])\n\t" \ - :[dst]"+r"(dst),[src]"+r"(src),[ystride3]"=&r"(ystride3) \ - :[ystride]"r"((ptrdiff_t)(_ystride)) \ - :"memory" \ - ); \ - } \ - while(0) - -# endif -#endif diff --git a/thirdparty/libtheora/x86/mmxidct.c b/thirdparty/libtheora/x86/mmxidct.c index 76424e6364..b8e3077066 100644 --- a/thirdparty/libtheora/x86/mmxidct.c +++ b/thirdparty/libtheora/x86/mmxidct.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: mmxidct.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ @@ -30,89 +30,66 @@ -/*A table of constants used by the MMX routines.*/ -static const ogg_uint16_t __attribute__((aligned(8),used)) - OC_IDCT_CONSTS[(7+1)*4]={ - (ogg_uint16_t)OC_C1S7,(ogg_uint16_t)OC_C1S7, - (ogg_uint16_t)OC_C1S7,(ogg_uint16_t)OC_C1S7, - (ogg_uint16_t)OC_C2S6,(ogg_uint16_t)OC_C2S6, - (ogg_uint16_t)OC_C2S6,(ogg_uint16_t)OC_C2S6, - (ogg_uint16_t)OC_C3S5,(ogg_uint16_t)OC_C3S5, - (ogg_uint16_t)OC_C3S5,(ogg_uint16_t)OC_C3S5, - (ogg_uint16_t)OC_C4S4,(ogg_uint16_t)OC_C4S4, - (ogg_uint16_t)OC_C4S4,(ogg_uint16_t)OC_C4S4, - (ogg_uint16_t)OC_C5S3,(ogg_uint16_t)OC_C5S3, - (ogg_uint16_t)OC_C5S3,(ogg_uint16_t)OC_C5S3, - (ogg_uint16_t)OC_C6S2,(ogg_uint16_t)OC_C6S2, - (ogg_uint16_t)OC_C6S2,(ogg_uint16_t)OC_C6S2, - (ogg_uint16_t)OC_C7S1,(ogg_uint16_t)OC_C7S1, - (ogg_uint16_t)OC_C7S1,(ogg_uint16_t)OC_C7S1, - 8, 8, 8, 8 -}; - -/*Converts the expression in the argument to a string.*/ -#define OC_M2STR(_s) #_s - /*38 cycles*/ -#define OC_IDCT_BEGIN \ +#define OC_IDCT_BEGIN(_y,_x) \ "#OC_IDCT_BEGIN\n\t" \ - "movq "OC_I(3)",%%mm2\n\t" \ - "movq "OC_C(3)",%%mm6\n\t" \ + "movq "OC_I(3,_x)",%%mm2\n\t" \ + "movq "OC_MEM_OFFS(0x30,c)",%%mm6\n\t" \ "movq %%mm2,%%mm4\n\t" \ - "movq "OC_J(5)",%%mm7\n\t" \ + "movq "OC_J(5,_x)",%%mm7\n\t" \ "pmulhw %%mm6,%%mm4\n\t" \ - "movq "OC_C(5)",%%mm1\n\t" \ + "movq "OC_MEM_OFFS(0x50,c)",%%mm1\n\t" \ "pmulhw %%mm7,%%mm6\n\t" \ "movq %%mm1,%%mm5\n\t" \ "pmulhw %%mm2,%%mm1\n\t" \ - "movq "OC_I(1)",%%mm3\n\t" \ + "movq "OC_I(1,_x)",%%mm3\n\t" \ "pmulhw %%mm7,%%mm5\n\t" \ - "movq "OC_C(1)",%%mm0\n\t" \ + "movq "OC_MEM_OFFS(0x10,c)",%%mm0\n\t" \ "paddw %%mm2,%%mm4\n\t" \ "paddw %%mm7,%%mm6\n\t" \ "paddw %%mm1,%%mm2\n\t" \ - "movq "OC_J(7)",%%mm1\n\t" \ + "movq "OC_J(7,_x)",%%mm1\n\t" \ "paddw %%mm5,%%mm7\n\t" \ "movq %%mm0,%%mm5\n\t" \ "pmulhw %%mm3,%%mm0\n\t" \ "paddw %%mm7,%%mm4\n\t" \ "pmulhw %%mm1,%%mm5\n\t" \ - "movq "OC_C(7)",%%mm7\n\t" \ + "movq "OC_MEM_OFFS(0x70,c)",%%mm7\n\t" \ "psubw %%mm2,%%mm6\n\t" \ "paddw %%mm3,%%mm0\n\t" \ "pmulhw %%mm7,%%mm3\n\t" \ - "movq "OC_I(2)",%%mm2\n\t" \ + "movq "OC_I(2,_x)",%%mm2\n\t" \ "pmulhw %%mm1,%%mm7\n\t" \ "paddw %%mm1,%%mm5\n\t" \ "movq %%mm2,%%mm1\n\t" \ - "pmulhw "OC_C(2)",%%mm2\n\t" \ + "pmulhw "OC_MEM_OFFS(0x20,c)",%%mm2\n\t" \ "psubw %%mm5,%%mm3\n\t" \ - "movq "OC_J(6)",%%mm5\n\t" \ + "movq "OC_J(6,_x)",%%mm5\n\t" \ "paddw %%mm7,%%mm0\n\t" \ "movq %%mm5,%%mm7\n\t" \ "psubw %%mm4,%%mm0\n\t" \ - "pmulhw "OC_C(2)",%%mm5\n\t" \ + "pmulhw "OC_MEM_OFFS(0x20,c)",%%mm5\n\t" \ "paddw %%mm1,%%mm2\n\t" \ - "pmulhw "OC_C(6)",%%mm1\n\t" \ + "pmulhw "OC_MEM_OFFS(0x60,c)",%%mm1\n\t" \ "paddw %%mm4,%%mm4\n\t" \ "paddw %%mm0,%%mm4\n\t" \ "psubw %%mm6,%%mm3\n\t" \ "paddw %%mm7,%%mm5\n\t" \ "paddw %%mm6,%%mm6\n\t" \ - "pmulhw "OC_C(6)",%%mm7\n\t" \ + "pmulhw "OC_MEM_OFFS(0x60,c)",%%mm7\n\t" \ "paddw %%mm3,%%mm6\n\t" \ - "movq %%mm4,"OC_I(1)"\n\t" \ + "movq %%mm4,"OC_I(1,_y)"\n\t" \ "psubw %%mm5,%%mm1\n\t" \ - "movq "OC_C(4)",%%mm4\n\t" \ + "movq "OC_MEM_OFFS(0x40,c)",%%mm4\n\t" \ "movq %%mm3,%%mm5\n\t" \ "pmulhw %%mm4,%%mm3\n\t" \ "paddw %%mm2,%%mm7\n\t" \ - "movq %%mm6,"OC_I(2)"\n\t" \ + "movq %%mm6,"OC_I(2,_y)"\n\t" \ "movq %%mm0,%%mm2\n\t" \ - "movq "OC_I(0)",%%mm6\n\t" \ + "movq "OC_I(0,_x)",%%mm6\n\t" \ "pmulhw %%mm4,%%mm0\n\t" \ "paddw %%mm3,%%mm5\n\t" \ - "movq "OC_J(4)",%%mm3\n\t" \ + "movq "OC_J(4,_x)",%%mm3\n\t" \ "psubw %%mm1,%%mm5\n\t" \ "paddw %%mm0,%%mm2\n\t" \ "psubw %%mm3,%%mm6\n\t" \ @@ -126,18 +103,18 @@ static const ogg_uint16_t __attribute__((aligned(8),used)) "paddw %%mm0,%%mm6\n\t" \ "psubw %%mm2,%%mm6\n\t" \ "paddw %%mm2,%%mm2\n\t" \ - "movq "OC_I(1)",%%mm0\n\t" \ + "movq "OC_I(1,_y)",%%mm0\n\t" \ "paddw %%mm6,%%mm2\n\t" \ "paddw %%mm3,%%mm4\n\t" \ "psubw %%mm1,%%mm2\n\t" \ "#end OC_IDCT_BEGIN\n\t" \ /*38+8=46 cycles.*/ -#define OC_ROW_IDCT \ +#define OC_ROW_IDCT(_y,_x) \ "#OC_ROW_IDCT\n" \ - OC_IDCT_BEGIN \ + OC_IDCT_BEGIN(_y,_x) \ /*r3=D'*/ \ - "movq "OC_I(2)",%%mm3\n\t" \ + "movq "OC_I(2,_y)",%%mm3\n\t" \ /*r4=E'=E-G*/ \ "psubw %%mm7,%%mm4\n\t" \ /*r1=H'+H'*/ \ @@ -162,7 +139,7 @@ static const ogg_uint16_t __attribute__((aligned(8),used)) "psubw %%mm0,%%mm7\n\t" \ "paddw %%mm0,%%mm0\n\t" \ /*Save R1.*/ \ - "movq %%mm1,"OC_I(1)"\n\t" \ + "movq %%mm1,"OC_I(1,_y)"\n\t" \ /*r0=R0=G.+C.*/ \ "paddw %%mm7,%%mm0\n\t" \ "#end OC_ROW_IDCT\n\t" \ @@ -195,11 +172,11 @@ static const ogg_uint16_t __attribute__((aligned(8),used)) Since r1 is free at entry, we calculate the Js first.*/ /*19 cycles.*/ -#define OC_TRANSPOSE \ +#define OC_TRANSPOSE(_y) \ "#OC_TRANSPOSE\n\t" \ "movq %%mm4,%%mm1\n\t" \ "punpcklwd %%mm5,%%mm4\n\t" \ - "movq %%mm0,"OC_I(0)"\n\t" \ + "movq %%mm0,"OC_I(0,_y)"\n\t" \ "punpckhwd %%mm5,%%mm1\n\t" \ "movq %%mm6,%%mm0\n\t" \ "punpcklwd %%mm7,%%mm6\n\t" \ @@ -207,17 +184,17 @@ static const ogg_uint16_t __attribute__((aligned(8),used)) "punpckldq %%mm6,%%mm4\n\t" \ "punpckhdq %%mm6,%%mm5\n\t" \ "movq %%mm1,%%mm6\n\t" \ - "movq %%mm4,"OC_J(4)"\n\t" \ + "movq %%mm4,"OC_J(4,_y)"\n\t" \ "punpckhwd %%mm7,%%mm0\n\t" \ - "movq %%mm5,"OC_J(5)"\n\t" \ + "movq %%mm5,"OC_J(5,_y)"\n\t" \ "punpckhdq %%mm0,%%mm6\n\t" \ - "movq "OC_I(0)",%%mm4\n\t" \ + "movq "OC_I(0,_y)",%%mm4\n\t" \ "punpckldq %%mm0,%%mm1\n\t" \ - "movq "OC_I(1)",%%mm5\n\t" \ + "movq "OC_I(1,_y)",%%mm5\n\t" \ "movq %%mm4,%%mm0\n\t" \ - "movq %%mm6,"OC_J(7)"\n\t" \ + "movq %%mm6,"OC_J(7,_y)"\n\t" \ "punpcklwd %%mm5,%%mm0\n\t" \ - "movq %%mm1,"OC_J(6)"\n\t" \ + "movq %%mm1,"OC_J(6,_y)"\n\t" \ "punpckhwd %%mm5,%%mm4\n\t" \ "movq %%mm2,%%mm5\n\t" \ "punpcklwd %%mm3,%%mm2\n\t" \ @@ -225,20 +202,20 @@ static const ogg_uint16_t __attribute__((aligned(8),used)) "punpckldq %%mm2,%%mm0\n\t" \ "punpckhdq %%mm2,%%mm1\n\t" \ "movq %%mm4,%%mm2\n\t" \ - "movq %%mm0,"OC_I(0)"\n\t" \ + "movq %%mm0,"OC_I(0,_y)"\n\t" \ "punpckhwd %%mm3,%%mm5\n\t" \ - "movq %%mm1,"OC_I(1)"\n\t" \ + "movq %%mm1,"OC_I(1,_y)"\n\t" \ "punpckhdq %%mm5,%%mm4\n\t" \ "punpckldq %%mm5,%%mm2\n\t" \ - "movq %%mm4,"OC_I(3)"\n\t" \ - "movq %%mm2,"OC_I(2)"\n\t" \ + "movq %%mm4,"OC_I(3,_y)"\n\t" \ + "movq %%mm2,"OC_I(2,_y)"\n\t" \ "#end OC_TRANSPOSE\n\t" \ /*38+19=57 cycles.*/ -#define OC_COLUMN_IDCT \ +#define OC_COLUMN_IDCT(_y) \ "#OC_COLUMN_IDCT\n" \ - OC_IDCT_BEGIN \ - "paddw "OC_8",%%mm2\n\t" \ + OC_IDCT_BEGIN(_y,_y) \ + "paddw "OC_MEM_OFFS(0x00,c)",%%mm2\n\t" \ /*r1=H'+H'*/ \ "paddw %%mm1,%%mm1\n\t" \ /*r1=R1=A''+H'*/ \ @@ -250,18 +227,18 @@ static const ogg_uint16_t __attribute__((aligned(8),used)) /*r1=NR1*/ \ "psraw $4,%%mm1\n\t" \ /*r3=D'*/ \ - "movq "OC_I(2)",%%mm3\n\t" \ + "movq "OC_I(2,_y)",%%mm3\n\t" \ /*r7=G+G*/ \ "paddw %%mm7,%%mm7\n\t" \ /*Store NR2 at I(2).*/ \ - "movq %%mm2,"OC_I(2)"\n\t" \ + "movq %%mm2,"OC_I(2,_y)"\n\t" \ /*r7=G'=E+G*/ \ "paddw %%mm4,%%mm7\n\t" \ /*Store NR1 at I(1).*/ \ - "movq %%mm1,"OC_I(1)"\n\t" \ + "movq %%mm1,"OC_I(1,_y)"\n\t" \ /*r4=R4=E'-D'*/ \ "psubw %%mm3,%%mm4\n\t" \ - "paddw "OC_8",%%mm4\n\t" \ + "paddw "OC_MEM_OFFS(0x00,c)",%%mm4\n\t" \ /*r3=D'+D'*/ \ "paddw %%mm3,%%mm3\n\t" \ /*r3=R3=E'+D'*/ \ @@ -272,7 +249,7 @@ static const ogg_uint16_t __attribute__((aligned(8),used)) "psubw %%mm5,%%mm6\n\t" \ /*r3=NR3*/ \ "psraw $4,%%mm3\n\t" \ - "paddw "OC_8",%%mm6\n\t" \ + "paddw "OC_MEM_OFFS(0x00,c)",%%mm6\n\t" \ /*r5=B''+B''*/ \ "paddw %%mm5,%%mm5\n\t" \ /*r5=R5=F'+B''*/ \ @@ -280,14 +257,14 @@ static const ogg_uint16_t __attribute__((aligned(8),used)) /*r6=NR6*/ \ "psraw $4,%%mm6\n\t" \ /*Store NR4 at J(4).*/ \ - "movq %%mm4,"OC_J(4)"\n\t" \ + "movq %%mm4,"OC_J(4,_y)"\n\t" \ /*r5=NR5*/ \ "psraw $4,%%mm5\n\t" \ /*Store NR3 at I(3).*/ \ - "movq %%mm3,"OC_I(3)"\n\t" \ + "movq %%mm3,"OC_I(3,_y)"\n\t" \ /*r7=R7=G'-C'*/ \ "psubw %%mm0,%%mm7\n\t" \ - "paddw "OC_8",%%mm7\n\t" \ + "paddw "OC_MEM_OFFS(0x00,c)",%%mm7\n\t" \ /*r0=C'+C'*/ \ "paddw %%mm0,%%mm0\n\t" \ /*r0=R0=G'+C'*/ \ @@ -295,113 +272,121 @@ static const ogg_uint16_t __attribute__((aligned(8),used)) /*r7=NR7*/ \ "psraw $4,%%mm7\n\t" \ /*Store NR6 at J(6).*/ \ - "movq %%mm6,"OC_J(6)"\n\t" \ + "movq %%mm6,"OC_J(6,_y)"\n\t" \ /*r0=NR0*/ \ "psraw $4,%%mm0\n\t" \ /*Store NR5 at J(5).*/ \ - "movq %%mm5,"OC_J(5)"\n\t" \ + "movq %%mm5,"OC_J(5,_y)"\n\t" \ /*Store NR7 at J(7).*/ \ - "movq %%mm7,"OC_J(7)"\n\t" \ + "movq %%mm7,"OC_J(7,_y)"\n\t" \ /*Store NR0 at I(0).*/ \ - "movq %%mm0,"OC_I(0)"\n\t" \ + "movq %%mm0,"OC_I(0,_y)"\n\t" \ "#end OC_COLUMN_IDCT\n\t" \ -#define OC_MID(_m,_i) OC_M2STR(_m+(_i)*8)"(%[c])" -#define OC_C(_i) OC_MID(OC_COSINE_OFFSET,_i-1) -#define OC_8 OC_MID(OC_EIGHT_OFFSET,0) - -static void oc_idct8x8_slow(ogg_int16_t _y[64]){ +static void oc_idct8x8_slow_mmx(ogg_int16_t _y[64],ogg_int16_t _x[64]){ + int i; /*This routine accepts an 8x8 matrix, but in partially transposed form. Every 4x4 block is transposed.*/ __asm__ __volatile__( -#define OC_I(_k) OC_M2STR((_k*16))"(%[y])" -#define OC_J(_k) OC_M2STR(((_k-4)*16)+8)"(%[y])" - OC_ROW_IDCT - OC_TRANSPOSE +#define OC_I(_k,_y) OC_MEM_OFFS((_k)*16,_y) +#define OC_J(_k,_y) OC_MEM_OFFS(((_k)-4)*16+8,_y) + OC_ROW_IDCT(y,x) + OC_TRANSPOSE(y) #undef OC_I #undef OC_J -#define OC_I(_k) OC_M2STR((_k*16)+64)"(%[y])" -#define OC_J(_k) OC_M2STR(((_k-4)*16)+72)"(%[y])" - OC_ROW_IDCT - OC_TRANSPOSE +#define OC_I(_k,_y) OC_MEM_OFFS((_k)*16+64,_y) +#define OC_J(_k,_y) OC_MEM_OFFS(((_k)-4)*16+72,_y) + OC_ROW_IDCT(y,x) + OC_TRANSPOSE(y) #undef OC_I #undef OC_J -#define OC_I(_k) OC_M2STR((_k*16))"(%[y])" -#define OC_J(_k) OC_I(_k) - OC_COLUMN_IDCT +#define OC_I(_k,_y) OC_MEM_OFFS((_k)*16,_y) +#define OC_J(_k,_y) OC_I(_k,_y) + OC_COLUMN_IDCT(y) #undef OC_I #undef OC_J -#define OC_I(_k) OC_M2STR((_k*16)+8)"(%[y])" -#define OC_J(_k) OC_I(_k) - OC_COLUMN_IDCT +#define OC_I(_k,_y) OC_MEM_OFFS((_k)*16+8,_y) +#define OC_J(_k,_y) OC_I(_k,_y) + OC_COLUMN_IDCT(y) #undef OC_I #undef OC_J - : - :[y]"r"(_y),[c]"r"(OC_IDCT_CONSTS) + :[y]"=m"OC_ARRAY_OPERAND(ogg_int16_t,_y,64) + :[x]"m"OC_CONST_ARRAY_OPERAND(ogg_int16_t,_x,64), + [c]"m"OC_CONST_ARRAY_OPERAND(ogg_int16_t,OC_IDCT_CONSTS,128) ); + __asm__ __volatile__("pxor %%mm0,%%mm0\n\t"::); + for(i=0;i<4;i++){ + __asm__ __volatile__( + "movq %%mm0,"OC_MEM_OFFS(0x00,x)"\n\t" + "movq %%mm0,"OC_MEM_OFFS(0x08,x)"\n\t" + "movq %%mm0,"OC_MEM_OFFS(0x10,x)"\n\t" + "movq %%mm0,"OC_MEM_OFFS(0x18,x)"\n\t" + :[x]"=m"OC_ARRAY_OPERAND(ogg_int16_t,_x+16*i,16) + ); + } } /*25 cycles.*/ -#define OC_IDCT_BEGIN_10 \ +#define OC_IDCT_BEGIN_10(_y,_x) \ "#OC_IDCT_BEGIN_10\n\t" \ - "movq "OC_I(3)",%%mm2\n\t" \ + "movq "OC_I(3,_x)",%%mm2\n\t" \ "nop\n\t" \ - "movq "OC_C(3)",%%mm6\n\t" \ + "movq "OC_MEM_OFFS(0x30,c)",%%mm6\n\t" \ "movq %%mm2,%%mm4\n\t" \ - "movq "OC_C(5)",%%mm1\n\t" \ + "movq "OC_MEM_OFFS(0x50,c)",%%mm1\n\t" \ "pmulhw %%mm6,%%mm4\n\t" \ - "movq "OC_I(1)",%%mm3\n\t" \ + "movq "OC_I(1,_x)",%%mm3\n\t" \ "pmulhw %%mm2,%%mm1\n\t" \ - "movq "OC_C(1)",%%mm0\n\t" \ + "movq "OC_MEM_OFFS(0x10,c)",%%mm0\n\t" \ "paddw %%mm2,%%mm4\n\t" \ "pxor %%mm6,%%mm6\n\t" \ "paddw %%mm1,%%mm2\n\t" \ - "movq "OC_I(2)",%%mm5\n\t" \ + "movq "OC_I(2,_x)",%%mm5\n\t" \ "pmulhw %%mm3,%%mm0\n\t" \ "movq %%mm5,%%mm1\n\t" \ "paddw %%mm3,%%mm0\n\t" \ - "pmulhw "OC_C(7)",%%mm3\n\t" \ + "pmulhw "OC_MEM_OFFS(0x70,c)",%%mm3\n\t" \ "psubw %%mm2,%%mm6\n\t" \ - "pmulhw "OC_C(2)",%%mm5\n\t" \ + "pmulhw "OC_MEM_OFFS(0x20,c)",%%mm5\n\t" \ "psubw %%mm4,%%mm0\n\t" \ - "movq "OC_I(2)",%%mm7\n\t" \ + "movq "OC_I(2,_x)",%%mm7\n\t" \ "paddw %%mm4,%%mm4\n\t" \ "paddw %%mm5,%%mm7\n\t" \ "paddw %%mm0,%%mm4\n\t" \ - "pmulhw "OC_C(6)",%%mm1\n\t" \ + "pmulhw "OC_MEM_OFFS(0x60,c)",%%mm1\n\t" \ "psubw %%mm6,%%mm3\n\t" \ - "movq %%mm4,"OC_I(1)"\n\t" \ + "movq %%mm4,"OC_I(1,_y)"\n\t" \ "paddw %%mm6,%%mm6\n\t" \ - "movq "OC_C(4)",%%mm4\n\t" \ + "movq "OC_MEM_OFFS(0x40,c)",%%mm4\n\t" \ "paddw %%mm3,%%mm6\n\t" \ "movq %%mm3,%%mm5\n\t" \ "pmulhw %%mm4,%%mm3\n\t" \ - "movq %%mm6,"OC_I(2)"\n\t" \ + "movq %%mm6,"OC_I(2,_y)"\n\t" \ "movq %%mm0,%%mm2\n\t" \ - "movq "OC_I(0)",%%mm6\n\t" \ + "movq "OC_I(0,_x)",%%mm6\n\t" \ "pmulhw %%mm4,%%mm0\n\t" \ "paddw %%mm3,%%mm5\n\t" \ "paddw %%mm0,%%mm2\n\t" \ "psubw %%mm1,%%mm5\n\t" \ "pmulhw %%mm4,%%mm6\n\t" \ - "paddw "OC_I(0)",%%mm6\n\t" \ + "paddw "OC_I(0,_x)",%%mm6\n\t" \ "paddw %%mm1,%%mm1\n\t" \ "movq %%mm6,%%mm4\n\t" \ "paddw %%mm5,%%mm1\n\t" \ "psubw %%mm2,%%mm6\n\t" \ "paddw %%mm2,%%mm2\n\t" \ - "movq "OC_I(1)",%%mm0\n\t" \ + "movq "OC_I(1,_y)",%%mm0\n\t" \ "paddw %%mm6,%%mm2\n\t" \ "psubw %%mm1,%%mm2\n\t" \ "nop\n\t" \ "#end OC_IDCT_BEGIN_10\n\t" \ /*25+8=33 cycles.*/ -#define OC_ROW_IDCT_10 \ +#define OC_ROW_IDCT_10(_y,_x) \ "#OC_ROW_IDCT_10\n\t" \ - OC_IDCT_BEGIN_10 \ + OC_IDCT_BEGIN_10(_y,_x) \ /*r3=D'*/ \ - "movq "OC_I(2)",%%mm3\n\t" \ + "movq "OC_I(2,_y)",%%mm3\n\t" \ /*r4=E'=E-G*/ \ "psubw %%mm7,%%mm4\n\t" \ /*r1=H'+H'*/ \ @@ -426,16 +411,16 @@ static void oc_idct8x8_slow(ogg_int16_t _y[64]){ "psubw %%mm0,%%mm7\n\t" \ "paddw %%mm0,%%mm0\n\t" \ /*Save R1.*/ \ - "movq %%mm1,"OC_I(1)"\n\t" \ + "movq %%mm1,"OC_I(1,_y)"\n\t" \ /*r0=R0=G'+C'*/ \ "paddw %%mm7,%%mm0\n\t" \ "#end OC_ROW_IDCT_10\n\t" \ /*25+19=44 cycles'*/ -#define OC_COLUMN_IDCT_10 \ +#define OC_COLUMN_IDCT_10(_y) \ "#OC_COLUMN_IDCT_10\n\t" \ - OC_IDCT_BEGIN_10 \ - "paddw "OC_8",%%mm2\n\t" \ + OC_IDCT_BEGIN_10(_y,_y) \ + "paddw "OC_MEM_OFFS(0x00,c)",%%mm2\n\t" \ /*r1=H'+H'*/ \ "paddw %%mm1,%%mm1\n\t" \ /*r1=R1=A''+H'*/ \ @@ -447,18 +432,18 @@ static void oc_idct8x8_slow(ogg_int16_t _y[64]){ /*r1=NR1*/ \ "psraw $4,%%mm1\n\t" \ /*r3=D'*/ \ - "movq "OC_I(2)",%%mm3\n\t" \ + "movq "OC_I(2,_y)",%%mm3\n\t" \ /*r7=G+G*/ \ "paddw %%mm7,%%mm7\n\t" \ /*Store NR2 at I(2).*/ \ - "movq %%mm2,"OC_I(2)"\n\t" \ + "movq %%mm2,"OC_I(2,_y)"\n\t" \ /*r7=G'=E+G*/ \ "paddw %%mm4,%%mm7\n\t" \ /*Store NR1 at I(1).*/ \ - "movq %%mm1,"OC_I(1)"\n\t" \ + "movq %%mm1,"OC_I(1,_y)"\n\t" \ /*r4=R4=E'-D'*/ \ "psubw %%mm3,%%mm4\n\t" \ - "paddw "OC_8",%%mm4\n\t" \ + "paddw "OC_MEM_OFFS(0x00,c)",%%mm4\n\t" \ /*r3=D'+D'*/ \ "paddw %%mm3,%%mm3\n\t" \ /*r3=R3=E'+D'*/ \ @@ -469,7 +454,7 @@ static void oc_idct8x8_slow(ogg_int16_t _y[64]){ "psubw %%mm5,%%mm6\n\t" \ /*r3=NR3*/ \ "psraw $4,%%mm3\n\t" \ - "paddw "OC_8",%%mm6\n\t" \ + "paddw "OC_MEM_OFFS(0x00,c)",%%mm6\n\t" \ /*r5=B''+B''*/ \ "paddw %%mm5,%%mm5\n\t" \ /*r5=R5=F'+B''*/ \ @@ -477,14 +462,14 @@ static void oc_idct8x8_slow(ogg_int16_t _y[64]){ /*r6=NR6*/ \ "psraw $4,%%mm6\n\t" \ /*Store NR4 at J(4).*/ \ - "movq %%mm4,"OC_J(4)"\n\t" \ + "movq %%mm4,"OC_J(4,_y)"\n\t" \ /*r5=NR5*/ \ "psraw $4,%%mm5\n\t" \ /*Store NR3 at I(3).*/ \ - "movq %%mm3,"OC_I(3)"\n\t" \ + "movq %%mm3,"OC_I(3,_y)"\n\t" \ /*r7=R7=G'-C'*/ \ "psubw %%mm0,%%mm7\n\t" \ - "paddw "OC_8",%%mm7\n\t" \ + "paddw "OC_MEM_OFFS(0x00,c)",%%mm7\n\t" \ /*r0=C'+C'*/ \ "paddw %%mm0,%%mm0\n\t" \ /*r0=R0=G'+C'*/ \ @@ -492,46 +477,55 @@ static void oc_idct8x8_slow(ogg_int16_t _y[64]){ /*r7=NR7*/ \ "psraw $4,%%mm7\n\t" \ /*Store NR6 at J(6).*/ \ - "movq %%mm6,"OC_J(6)"\n\t" \ + "movq %%mm6,"OC_J(6,_y)"\n\t" \ /*r0=NR0*/ \ "psraw $4,%%mm0\n\t" \ /*Store NR5 at J(5).*/ \ - "movq %%mm5,"OC_J(5)"\n\t" \ + "movq %%mm5,"OC_J(5,_y)"\n\t" \ /*Store NR7 at J(7).*/ \ - "movq %%mm7,"OC_J(7)"\n\t" \ + "movq %%mm7,"OC_J(7,_y)"\n\t" \ /*Store NR0 at I(0).*/ \ - "movq %%mm0,"OC_I(0)"\n\t" \ + "movq %%mm0,"OC_I(0,_y)"\n\t" \ "#end OC_COLUMN_IDCT_10\n\t" \ -static void oc_idct8x8_10(ogg_int16_t _y[64]){ +static void oc_idct8x8_10_mmx(ogg_int16_t _y[64],ogg_int16_t _x[64]){ __asm__ __volatile__( -#define OC_I(_k) OC_M2STR((_k*16))"(%[y])" -#define OC_J(_k) OC_M2STR(((_k-4)*16)+8)"(%[y])" +#define OC_I(_k,_y) OC_MEM_OFFS((_k)*16,_y) +#define OC_J(_k,_y) OC_MEM_OFFS(((_k)-4)*16+8,_y) /*Done with dequant, descramble, and partial transpose. Now do the iDCT itself.*/ - OC_ROW_IDCT_10 - OC_TRANSPOSE + OC_ROW_IDCT_10(y,x) + OC_TRANSPOSE(y) #undef OC_I #undef OC_J -#define OC_I(_k) OC_M2STR((_k*16))"(%[y])" -#define OC_J(_k) OC_I(_k) - OC_COLUMN_IDCT_10 +#define OC_I(_k,_y) OC_MEM_OFFS((_k)*16,_y) +#define OC_J(_k,_y) OC_I(_k,_y) + OC_COLUMN_IDCT_10(y) #undef OC_I #undef OC_J -#define OC_I(_k) OC_M2STR((_k*16)+8)"(%[y])" -#define OC_J(_k) OC_I(_k) - OC_COLUMN_IDCT_10 +#define OC_I(_k,_y) OC_MEM_OFFS((_k)*16+8,_y) +#define OC_J(_k,_y) OC_I(_k,_y) + OC_COLUMN_IDCT_10(y) #undef OC_I #undef OC_J - : - :[y]"r"(_y),[c]"r"(OC_IDCT_CONSTS) + :[y]"=m"OC_ARRAY_OPERAND(ogg_int16_t,_y,64) + :[x]"m"OC_CONST_ARRAY_OPERAND(ogg_int16_t,_x,64), + [c]"m"OC_CONST_ARRAY_OPERAND(ogg_int16_t,OC_IDCT_CONSTS,128) + ); + __asm__ __volatile__( + "pxor %%mm0,%%mm0\n\t" + "movq %%mm0,"OC_MEM_OFFS(0x00,x)"\n\t" + "movq %%mm0,"OC_MEM_OFFS(0x10,x)"\n\t" + "movq %%mm0,"OC_MEM_OFFS(0x20,x)"\n\t" + "movq %%mm0,"OC_MEM_OFFS(0x30,x)"\n\t" + :[x]"+m"OC_ARRAY_OPERAND(ogg_int16_t,_x,28) ); } /*Performs an inverse 8x8 Type-II DCT transform. The input is assumed to be scaled by a factor of 4 relative to orthonormal version of the transform.*/ -void oc_idct8x8_mmx(ogg_int16_t _y[64],int _last_zzi){ +void oc_idct8x8_mmx(ogg_int16_t _y[64],ogg_int16_t _x[64],int _last_zzi){ /*_last_zzi is subtly different from an actual count of the number of coefficients we decoded for this block. It contains the value of zzi BEFORE the final token in the block was @@ -557,8 +551,8 @@ void oc_idct8x8_mmx(ogg_int16_t _y[64],int _last_zzi){ gets. Needless to say we inherited this approach from VP3.*/ /*Then perform the iDCT.*/ - if(_last_zzi<10)oc_idct8x8_10(_y); - else oc_idct8x8_slow(_y); + if(_last_zzi<=10)oc_idct8x8_10_mmx(_y,_x); + else oc_idct8x8_slow_mmx(_y,_x); } #endif diff --git a/thirdparty/libtheora/x86/mmxloop.h b/thirdparty/libtheora/x86/mmxloop.h index 2e870c795d..1f6090b567 100644 --- a/thirdparty/libtheora/x86/mmxloop.h +++ b/thirdparty/libtheora/x86/mmxloop.h @@ -9,88 +9,191 @@ On exit, mm1={b0+lflim(R_0,L),...,b7+lflim(R_7,L)} and mm2={c0-lflim(R_0,L),...,c7-lflim(R_7,L)}; mm0 and mm3 are clobbered.*/ #define OC_LOOP_FILTER8_MMX \ - "#OC_LOOP_FILTER8_MMX\n\t" \ - /*mm7=0*/ \ - "pxor %%mm7,%%mm7\n\t" \ - /*mm6:mm0={a0,...,a7}*/ \ - "movq %%mm0,%%mm6\n\t" \ - "punpcklbw %%mm7,%%mm0\n\t" \ - "punpckhbw %%mm7,%%mm6\n\t" \ - /*mm3:mm5={d0,...,d7}*/ \ - "movq %%mm3,%%mm5\n\t" \ - "punpcklbw %%mm7,%%mm3\n\t" \ - "punpckhbw %%mm7,%%mm5\n\t" \ - /*mm6:mm0={a0-d0,...,a7-d7}*/ \ - "psubw %%mm3,%%mm0\n\t" \ - "psubw %%mm5,%%mm6\n\t" \ - /*mm3:mm1={b0,...,b7}*/ \ - "movq %%mm1,%%mm3\n\t" \ - "punpcklbw %%mm7,%%mm1\n\t" \ - "movq %%mm2,%%mm4\n\t" \ - "punpckhbw %%mm7,%%mm3\n\t" \ - /*mm5:mm4={c0,...,c7}*/ \ - "movq %%mm2,%%mm5\n\t" \ - "punpcklbw %%mm7,%%mm4\n\t" \ - "punpckhbw %%mm7,%%mm5\n\t" \ - /*mm7={3}x4 \ - mm5:mm4={c0-b0,...,c7-b7}*/ \ - "pcmpeqw %%mm7,%%mm7\n\t" \ - "psubw %%mm1,%%mm4\n\t" \ - "psrlw $14,%%mm7\n\t" \ - "psubw %%mm3,%%mm5\n\t" \ - /*Scale by 3.*/ \ - "pmullw %%mm7,%%mm4\n\t" \ - "pmullw %%mm7,%%mm5\n\t" \ - /*mm7={4}x4 \ - mm5:mm4=f={a0-d0+3*(c0-b0),...,a7-d7+3*(c7-b7)}*/ \ - "psrlw $1,%%mm7\n\t" \ - "paddw %%mm0,%%mm4\n\t" \ - "psllw $2,%%mm7\n\t" \ - "movq (%[ll]),%%mm0\n\t" \ - "paddw %%mm6,%%mm5\n\t" \ - /*R_i has the range [-127,128], so we compute -R_i instead. \ - mm4=-R_i=-(f+4>>3)=0xFF^(f-4>>3)*/ \ - "psubw %%mm7,%%mm4\n\t" \ - "psubw %%mm7,%%mm5\n\t" \ - "psraw $3,%%mm4\n\t" \ - "psraw $3,%%mm5\n\t" \ - "pcmpeqb %%mm7,%%mm7\n\t" \ - "packsswb %%mm5,%%mm4\n\t" \ - "pxor %%mm6,%%mm6\n\t" \ - "pxor %%mm7,%%mm4\n\t" \ - "packuswb %%mm3,%%mm1\n\t" \ - /*Now compute lflim of -mm4 cf. Section 7.10 of the sepc.*/ \ - /*There's no unsigned byte+signed byte with unsigned saturation op code, so \ - we have to split things by sign (the other option is to work in 16 bits, \ - but working in 8 bits gives much better parallelism). \ - We compute abs(R_i), but save a mask of which terms were negative in mm6. \ - Then we compute mm4=abs(lflim(R_i,L))=min(abs(R_i),max(2*L-abs(R_i),0)). \ - Finally, we split mm4 into positive and negative pieces using the mask in \ - mm6, and add and subtract them as appropriate.*/ \ - /*mm4=abs(-R_i)*/ \ - /*mm7=255-2*L*/ \ - "pcmpgtb %%mm4,%%mm6\n\t" \ - "psubb %%mm0,%%mm7\n\t" \ - "pxor %%mm6,%%mm4\n\t" \ - "psubb %%mm0,%%mm7\n\t" \ - "psubb %%mm6,%%mm4\n\t" \ - /*mm7=255-max(2*L-abs(R_i),0)*/ \ - "paddusb %%mm4,%%mm7\n\t" \ - /*mm4=min(abs(R_i),max(2*L-abs(R_i),0))*/ \ - "paddusb %%mm7,%%mm4\n\t" \ - "psubusb %%mm7,%%mm4\n\t" \ - /*Now split mm4 by the original sign of -R_i.*/ \ - "movq %%mm4,%%mm5\n\t" \ - "pand %%mm6,%%mm4\n\t" \ - "pandn %%mm5,%%mm6\n\t" \ - /*mm1={b0+lflim(R_0,L),...,b7+lflim(R_7,L)}*/ \ - /*mm2={c0-lflim(R_0,L),...,c7-lflim(R_7,L)}*/ \ - "paddusb %%mm4,%%mm1\n\t" \ - "psubusb %%mm4,%%mm2\n\t" \ - "psubusb %%mm6,%%mm1\n\t" \ - "paddusb %%mm6,%%mm2\n\t" \ + "#OC_LOOP_FILTER8_MMX\n\t" \ + /*mm7=0*/ \ + "pxor %%mm7,%%mm7\n\t" \ + /*mm6:mm0={a0,...,a7}*/ \ + "movq %%mm0,%%mm6\n\t" \ + "punpcklbw %%mm7,%%mm0\n\t" \ + "punpckhbw %%mm7,%%mm6\n\t" \ + /*mm3:mm5={d0,...,d7}*/ \ + "movq %%mm3,%%mm5\n\t" \ + "punpcklbw %%mm7,%%mm3\n\t" \ + "punpckhbw %%mm7,%%mm5\n\t" \ + /*mm6:mm0={a0-d0,...,a7-d7}*/ \ + "psubw %%mm3,%%mm0\n\t" \ + "psubw %%mm5,%%mm6\n\t" \ + /*mm3:mm1={b0,...,b7}*/ \ + "movq %%mm1,%%mm3\n\t" \ + "punpcklbw %%mm7,%%mm1\n\t" \ + "movq %%mm2,%%mm4\n\t" \ + "punpckhbw %%mm7,%%mm3\n\t" \ + /*mm5:mm4={c0,...,c7}*/ \ + "movq %%mm2,%%mm5\n\t" \ + "punpcklbw %%mm7,%%mm4\n\t" \ + "punpckhbw %%mm7,%%mm5\n\t" \ + /*mm7={3}x4 \ + mm5:mm4={c0-b0,...,c7-b7}*/ \ + "pcmpeqw %%mm7,%%mm7\n\t" \ + "psubw %%mm1,%%mm4\n\t" \ + "psrlw $14,%%mm7\n\t" \ + "psubw %%mm3,%%mm5\n\t" \ + /*Scale by 3.*/ \ + "pmullw %%mm7,%%mm4\n\t" \ + "pmullw %%mm7,%%mm5\n\t" \ + /*mm7={4}x4 \ + mm5:mm4=f={a0-d0+3*(c0-b0),...,a7-d7+3*(c7-b7)}*/ \ + "psrlw $1,%%mm7\n\t" \ + "paddw %%mm0,%%mm4\n\t" \ + "psllw $2,%%mm7\n\t" \ + "movq (%[ll]),%%mm0\n\t" \ + "paddw %%mm6,%%mm5\n\t" \ + /*R_i has the range [-127,128], so we compute -R_i instead. \ + mm4=-R_i=-(f+4>>3)=0xFF^(f-4>>3)*/ \ + "psubw %%mm7,%%mm4\n\t" \ + "psubw %%mm7,%%mm5\n\t" \ + "psraw $3,%%mm4\n\t" \ + "psraw $3,%%mm5\n\t" \ + "pcmpeqb %%mm7,%%mm7\n\t" \ + "packsswb %%mm5,%%mm4\n\t" \ + "pxor %%mm6,%%mm6\n\t" \ + "pxor %%mm7,%%mm4\n\t" \ + "packuswb %%mm3,%%mm1\n\t" \ + /*Now compute lflim of -mm4 cf. Section 7.10 of the sepc.*/ \ + /*There's no unsigned byte+signed byte with unsigned saturation op code, so \ + we have to split things by sign (the other option is to work in 16 bits, \ + but working in 8 bits gives much better parallelism). \ + We compute abs(R_i), but save a mask of which terms were negative in mm6. \ + Then we compute mm4=abs(lflim(R_i,L))=min(abs(R_i),max(2*L-abs(R_i),0)). \ + Finally, we split mm4 into positive and negative pieces using the mask in \ + mm6, and add and subtract them as appropriate.*/ \ + /*mm4=abs(-R_i)*/ \ + /*mm7=255-2*L*/ \ + "pcmpgtb %%mm4,%%mm6\n\t" \ + "psubb %%mm0,%%mm7\n\t" \ + "pxor %%mm6,%%mm4\n\t" \ + "psubb %%mm0,%%mm7\n\t" \ + "psubb %%mm6,%%mm4\n\t" \ + /*mm7=255-max(2*L-abs(R_i),0)*/ \ + "paddusb %%mm4,%%mm7\n\t" \ + /*mm4=min(abs(R_i),max(2*L-abs(R_i),0))*/ \ + "paddusb %%mm7,%%mm4\n\t" \ + "psubusb %%mm7,%%mm4\n\t" \ + /*Now split mm4 by the original sign of -R_i.*/ \ + "movq %%mm4,%%mm5\n\t" \ + "pand %%mm6,%%mm4\n\t" \ + "pandn %%mm5,%%mm6\n\t" \ + /*mm1={b0+lflim(R_0,L),...,b7+lflim(R_7,L)}*/ \ + /*mm2={c0-lflim(R_0,L),...,c7-lflim(R_7,L)}*/ \ + "paddusb %%mm4,%%mm1\n\t" \ + "psubusb %%mm4,%%mm2\n\t" \ + "psubusb %%mm6,%%mm1\n\t" \ + "paddusb %%mm6,%%mm2\n\t" \ -#define OC_LOOP_FILTER_V_MMX(_pix,_ystride,_ll) \ +/*On entry, mm0={a0,...,a7}, mm1={b0,...,b7}, mm2={c0,...,c7}, mm3={d0,...d7}. + On exit, mm1={b0+lflim(R_0,L),...,b7+lflim(R_7,L)} and + mm2={c0-lflim(R_0,L),...,c7-lflim(R_7,L)}. + All other MMX registers are clobbered.*/ +#define OC_LOOP_FILTER8_MMXEXT \ + "#OC_LOOP_FILTER8_MMXEXT\n\t" \ + /*R_i=(a_i-3*b_i+3*c_i-d_i+4>>3) has the range [-127,128], so we compute \ + -R_i=(-a_i+3*b_i-3*c_i+d_i+3>>3) instead.*/ \ + /*This first part is based on the transformation \ + f = -(3*(c-b)+a-d+4>>3) \ + = -(3*(c+255-b)+(a+255-d)+4-1020>>3) \ + = -(3*(c+~b)+(a+~d)-1016>>3) \ + = 127-(3*(c+~b)+(a+~d)>>3) \ + = 128+~(3*(c+~b)+(a+~d)>>3) (mod 256). \ + Although pavgb(a,b) = (a+b+1>>1) (biased up), we rely heavily on the \ + fact that ~pavgb(~a,~b) = (a+b>>1) (biased down). \ + Using this, the last expression above can be computed in 8 bits of working \ + precision via: \ + u = ~pavgb(~b,c); \ + v = pavgb(b,~c); \ + This mask is 0 or 0xFF, and controls whether t is biased up or down: \ + m = u-v; \ + t = m^pavgb(m^~a,m^d); \ + f = 128+pavgb(pavgb(t,u),v); \ + This required some careful analysis to ensure that carries are propagated \ + correctly in all cases, but has been checked exhaustively.*/ \ + /*input (a, b, c, d, ., ., ., .)*/ \ + /*ff=0xFF; \ + u=b; \ + v=c; \ + ll=255-2*L;*/ \ + "pcmpeqb %%mm7,%%mm7\n\t" \ + "movq %%mm1,%%mm4\n\t" \ + "movq %%mm2,%%mm5\n\t" \ + "movq (%[ll]),%%mm6\n\t" \ + /*allocated u, v, ll, ff: (a, b, c, d, u, v, ll, ff)*/ \ + /*u^=ff; \ + v^=ff;*/ \ + "pxor %%mm7,%%mm4\n\t" \ + "pxor %%mm7,%%mm5\n\t" \ + /*allocated ll: (a, b, c, d, u, v, ll, ff)*/ \ + /*u=pavgb(u,c); \ + v=pavgb(v,b);*/ \ + "pavgb %%mm2,%%mm4\n\t" \ + "pavgb %%mm1,%%mm5\n\t" \ + /*u^=ff; \ + a^=ff;*/ \ + "pxor %%mm7,%%mm4\n\t" \ + "pxor %%mm7,%%mm0\n\t" \ + /*m=u-v;*/ \ + "psubb %%mm5,%%mm4\n\t" \ + /*freed u, allocated m: (a, b, c, d, m, v, ll, ff)*/ \ + /*a^=m; \ + d^=m;*/ \ + "pxor %%mm4,%%mm0\n\t" \ + "pxor %%mm4,%%mm3\n\t" \ + /*t=pavgb(a,d);*/ \ + "pavgb %%mm3,%%mm0\n\t" \ + "psllw $7,%%mm7\n\t" \ + /*freed a, d, ff, allocated t, of: (t, b, c, ., m, v, ll, of)*/ \ + /*t^=m; \ + u=m+v;*/ \ + "pxor %%mm4,%%mm0\n\t" \ + "paddb %%mm5,%%mm4\n\t" \ + /*freed t, m, allocated f, u: (f, b, c, ., u, v, ll, of)*/ \ + /*f=pavgb(f,u); \ + of=128;*/ \ + "pavgb %%mm4,%%mm0\n\t" \ + "packsswb %%mm7,%%mm7\n\t" \ + /*freed u, ff, allocated ll: (f, b, c, ., ll, v, ll, of)*/ \ + /*f=pavgb(f,v);*/ \ + "pavgb %%mm5,%%mm0\n\t" \ + "movq %%mm7,%%mm3\n\t" \ + "movq %%mm6,%%mm4\n\t" \ + /*freed v, allocated of: (f, b, c, of, ll, ., ll, of)*/ \ + /*Now compute lflim of R_i=-(128+mm0) cf. Section 7.10 of the sepc.*/ \ + /*There's no unsigned byte+signed byte with unsigned saturation op code, so \ + we have to split things by sign (the other option is to work in 16 bits, \ + but staying in 8 bits gives much better parallelism).*/ \ + /*Instead of adding the offset of 128 in mm3, we use it to split mm0. \ + This is the same number of instructions as computing a mask and splitting \ + after the lflim computation, but has shorter dependency chains.*/ \ + /*mm0=R_i<0?-R_i:0 (denoted abs(R_i<0))\ + mm3=R_i>0?R_i:0* (denoted abs(R_i>0))*/ \ + "psubusb %%mm0,%%mm3\n\t" \ + "psubusb %%mm7,%%mm0\n\t" \ + /*mm6=255-max(2*L-abs(R_i<0),0) \ + mm4=255-max(2*L-abs(R_i>0),0)*/ \ + "paddusb %%mm3,%%mm4\n\t" \ + "paddusb %%mm0,%%mm6\n\t" \ + /*mm0=min(abs(R_i<0),max(2*L-abs(R_i<0),0)) \ + mm3=min(abs(R_i>0),max(2*L-abs(R_i>0),0))*/ \ + "paddusb %%mm4,%%mm3\n\t" \ + "paddusb %%mm6,%%mm0\n\t" \ + "psubusb %%mm4,%%mm3\n\t" \ + "psubusb %%mm6,%%mm0\n\t" \ + /*mm1={b0+lflim(R_0,L),...,b7+lflim(R_7,L)}*/ \ + /*mm2={c0-lflim(R_0,L),...,c7-lflim(R_7,L)}*/ \ + "paddusb %%mm3,%%mm1\n\t" \ + "psubusb %%mm3,%%mm2\n\t" \ + "psubusb %%mm0,%%mm1\n\t" \ + "paddusb %%mm0,%%mm2\n\t" \ + +#define OC_LOOP_FILTER_V(_filter,_pix,_ystride,_ll) \ do{ \ ptrdiff_t ystride3__; \ __asm__ __volatile__( \ @@ -104,7 +207,7 @@ "movq (%[pix],%[ystride]),%%mm1\n\t" \ /*mm2={c0,...,c7}*/ \ "movq (%[pix],%[ystride],2),%%mm2\n\t" \ - OC_LOOP_FILTER8_MMX \ + _filter \ /*Write it back out.*/ \ "movq %%mm1,(%[pix],%[ystride])\n\t" \ "movq %%mm2,(%[pix],%[ystride],2)\n\t" \ @@ -116,7 +219,7 @@ } \ while(0) -#define OC_LOOP_FILTER_H_MMX(_pix,_ystride,_ll) \ +#define OC_LOOP_FILTER_H(_filter,_pix,_ystride,_ll) \ do{ \ unsigned char *pix__; \ ptrdiff_t ystride3__; \ @@ -174,7 +277,7 @@ "punpckldq %%mm5,%%mm2\n\t" \ /*mm3=d7 d6 d5 d4 d3 d2 d1 d0*/ \ "punpckhdq %%mm5,%%mm3\n\t" \ - OC_LOOP_FILTER8_MMX \ + _filter \ /*mm2={b0+R_0'',...,b7+R_7''}*/ \ "movq %%mm1,%%mm0\n\t" \ /*mm1={b0+R_0'',c0-R_0'',...,b3+R_3'',c3-R_3''}*/ \ diff --git a/thirdparty/libtheora/x86/mmxstate.c b/thirdparty/libtheora/x86/mmxstate.c index 808b0a789b..eebea14fba 100644 --- a/thirdparty/libtheora/x86/mmxstate.c +++ b/thirdparty/libtheora/x86/mmxstate.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: mmxstate.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ @@ -19,23 +19,23 @@ Originally written by Rudolf Marek.*/ #include <string.h> #include "x86int.h" -#include "mmxfrag.h" #include "mmxloop.h" #if defined(OC_X86_ASM) void oc_state_frag_recon_mmx(const oc_theora_state *_state,ptrdiff_t _fragi, - int _pli,ogg_int16_t _dct_coeffs[64],int _last_zzi,ogg_uint16_t _dc_quant){ + int _pli,ogg_int16_t _dct_coeffs[128],int _last_zzi,ogg_uint16_t _dc_quant){ unsigned char *dst; ptrdiff_t frag_buf_off; int ystride; - int mb_mode; + int refi; /*Apply the inverse transform.*/ /*Special case only having a DC component.*/ if(_last_zzi<2){ /*Note that this value must be unsigned, to keep the __asm__ block from sign-extending it when it puts it in a register.*/ ogg_uint16_t p; + int i; /*We round this dequant product (and not any of the others) because there's no iDCT rounding.*/ p=(ogg_int16_t)(_dct_coeffs[0]*(ogg_int32_t)_dc_quant+15>>5); @@ -47,81 +47,48 @@ void oc_state_frag_recon_mmx(const oc_theora_state *_state,ptrdiff_t _fragi, "punpcklwd %%mm0,%%mm0\n\t" /*mm0=AAAA AAAA AAAA AAAA*/ "punpckldq %%mm0,%%mm0\n\t" - "movq %%mm0,(%[y])\n\t" - "movq %%mm0,8(%[y])\n\t" - "movq %%mm0,16(%[y])\n\t" - "movq %%mm0,24(%[y])\n\t" - "movq %%mm0,32(%[y])\n\t" - "movq %%mm0,40(%[y])\n\t" - "movq %%mm0,48(%[y])\n\t" - "movq %%mm0,56(%[y])\n\t" - "movq %%mm0,64(%[y])\n\t" - "movq %%mm0,72(%[y])\n\t" - "movq %%mm0,80(%[y])\n\t" - "movq %%mm0,88(%[y])\n\t" - "movq %%mm0,96(%[y])\n\t" - "movq %%mm0,104(%[y])\n\t" - "movq %%mm0,112(%[y])\n\t" - "movq %%mm0,120(%[y])\n\t" : - :[y]"r"(_dct_coeffs),[p]"r"((unsigned)p) - :"memory" + :[p]"r"((unsigned)p) ); + for(i=0;i<4;i++){ + __asm__ __volatile__( + "movq %%mm0,"OC_MEM_OFFS(0x00,y)"\n\t" + "movq %%mm0,"OC_MEM_OFFS(0x08,y)"\n\t" + "movq %%mm0,"OC_MEM_OFFS(0x10,y)"\n\t" + "movq %%mm0,"OC_MEM_OFFS(0x18,y)"\n\t" + :[y]"=m"OC_ARRAY_OPERAND(ogg_int16_t,_dct_coeffs+64+16*i,16) + ); + } } else{ /*Dequantize the DC coefficient.*/ _dct_coeffs[0]=(ogg_int16_t)(_dct_coeffs[0]*(int)_dc_quant); - oc_idct8x8_mmx(_dct_coeffs,_last_zzi); + oc_idct8x8(_state,_dct_coeffs+64,_dct_coeffs,_last_zzi); } /*Fill in the target buffer.*/ frag_buf_off=_state->frag_buf_offs[_fragi]; - mb_mode=_state->frags[_fragi].mb_mode; + refi=_state->frags[_fragi].refi; ystride=_state->ref_ystride[_pli]; - dst=_state->ref_frame_data[_state->ref_frame_idx[OC_FRAME_SELF]]+frag_buf_off; - if(mb_mode==OC_MODE_INTRA)oc_frag_recon_intra_mmx(dst,ystride,_dct_coeffs); + dst=_state->ref_frame_data[OC_FRAME_SELF]+frag_buf_off; + if(refi==OC_FRAME_SELF)oc_frag_recon_intra_mmx(dst,ystride,_dct_coeffs+64); else{ const unsigned char *ref; int mvoffsets[2]; - ref= - _state->ref_frame_data[_state->ref_frame_idx[OC_FRAME_FOR_MODE(mb_mode)]] - +frag_buf_off; + ref=_state->ref_frame_data[refi]+frag_buf_off; if(oc_state_get_mv_offsets(_state,mvoffsets,_pli, - _state->frag_mvs[_fragi][0],_state->frag_mvs[_fragi][1])>1){ + _state->frag_mvs[_fragi])>1){ oc_frag_recon_inter2_mmx(dst,ref+mvoffsets[0],ref+mvoffsets[1],ystride, - _dct_coeffs); + _dct_coeffs+64); } - else oc_frag_recon_inter_mmx(dst,ref+mvoffsets[0],ystride,_dct_coeffs); + else oc_frag_recon_inter_mmx(dst,ref+mvoffsets[0],ystride,_dct_coeffs+64); } } /*We copy these entire function to inline the actual MMX routines so that we use only a single indirect call.*/ -/*Copies the fragments specified by the lists of fragment indices from one - frame to another. - _fragis: A pointer to a list of fragment indices. - _nfragis: The number of fragment indices to copy. - _dst_frame: The reference frame to copy to. - _src_frame: The reference frame to copy from. - _pli: The color plane the fragments lie in.*/ -void oc_state_frag_copy_list_mmx(const oc_theora_state *_state, - const ptrdiff_t *_fragis,ptrdiff_t _nfragis, - int _dst_frame,int _src_frame,int _pli){ - const ptrdiff_t *frag_buf_offs; - const unsigned char *src_frame_data; - unsigned char *dst_frame_data; - ptrdiff_t fragii; - int ystride; - dst_frame_data=_state->ref_frame_data[_state->ref_frame_idx[_dst_frame]]; - src_frame_data=_state->ref_frame_data[_state->ref_frame_idx[_src_frame]]; - ystride=_state->ref_ystride[_pli]; - frag_buf_offs=_state->frag_buf_offs; - for(fragii=0;fragii<_nfragis;fragii++){ - ptrdiff_t frag_buf_off; - frag_buf_off=frag_buf_offs[_fragis[fragii]]; - OC_FRAG_COPY_MMX(dst_frame_data+frag_buf_off, - src_frame_data+frag_buf_off,ystride); - } +void oc_loop_filter_init_mmx(signed char _bv[256],int _flimit){ + memset(_bv,_flimit,8); } /*Apply the loop filter to a given set of fragment rows in the given plane. @@ -133,7 +100,7 @@ void oc_state_frag_copy_list_mmx(const oc_theora_state *_state, _fragy0: The Y coordinate of the first fragment row to filter. _fragy_end: The Y coordinate of the fragment row to stop filtering at.*/ void oc_state_loop_filter_frag_rows_mmx(const oc_theora_state *_state, - int _bv[256],int _refi,int _pli,int _fragy0,int _fragy_end){ + signed char _bv[256],int _refi,int _pli,int _fragy0,int _fragy_end){ OC_ALIGN8(unsigned char ll[8]); const oc_fragment_plane *fplane; const oc_fragment *frags; @@ -170,13 +137,84 @@ void oc_state_loop_filter_frag_rows_mmx(const oc_theora_state *_state, if(frags[fragi].coded){ unsigned char *ref; ref=ref_frame_data+frag_buf_offs[fragi]; - if(fragi>fragi0)OC_LOOP_FILTER_H_MMX(ref,ystride,ll); - if(fragi0>fragi_top)OC_LOOP_FILTER_V_MMX(ref,ystride,ll); + if(fragi>fragi0){ + OC_LOOP_FILTER_H(OC_LOOP_FILTER8_MMX,ref,ystride,ll); + } + if(fragi0>fragi_top){ + OC_LOOP_FILTER_V(OC_LOOP_FILTER8_MMX,ref,ystride,ll); + } + if(fragi+1<fragi_end&&!frags[fragi+1].coded){ + OC_LOOP_FILTER_H(OC_LOOP_FILTER8_MMX,ref+8,ystride,ll); + } + if(fragi+nhfrags<fragi_bot&&!frags[fragi+nhfrags].coded){ + OC_LOOP_FILTER_V(OC_LOOP_FILTER8_MMX,ref+(ystride<<3),ystride,ll); + } + } + fragi++; + } + fragi0+=nhfrags; + } +} + +void oc_loop_filter_init_mmxext(signed char _bv[256],int _flimit){ + memset(_bv,~(_flimit<<1),8); +} + +/*Apply the loop filter to a given set of fragment rows in the given plane. + The filter may be run on the bottom edge, affecting pixels in the next row of + fragments, so this row also needs to be available. + _bv: The bounding values array. + _refi: The index of the frame buffer to filter. + _pli: The color plane to filter. + _fragy0: The Y coordinate of the first fragment row to filter. + _fragy_end: The Y coordinate of the fragment row to stop filtering at.*/ +void oc_state_loop_filter_frag_rows_mmxext(const oc_theora_state *_state, + signed char _bv[256],int _refi,int _pli,int _fragy0,int _fragy_end){ + const oc_fragment_plane *fplane; + const oc_fragment *frags; + const ptrdiff_t *frag_buf_offs; + unsigned char *ref_frame_data; + ptrdiff_t fragi_top; + ptrdiff_t fragi_bot; + ptrdiff_t fragi0; + ptrdiff_t fragi0_end; + int ystride; + int nhfrags; + fplane=_state->fplanes+_pli; + nhfrags=fplane->nhfrags; + fragi_top=fplane->froffset; + fragi_bot=fragi_top+fplane->nfrags; + fragi0=fragi_top+_fragy0*(ptrdiff_t)nhfrags; + fragi0_end=fragi_top+_fragy_end*(ptrdiff_t)nhfrags; + ystride=_state->ref_ystride[_pli]; + frags=_state->frags; + frag_buf_offs=_state->frag_buf_offs; + ref_frame_data=_state->ref_frame_data[_refi]; + /*The following loops are constructed somewhat non-intuitively on purpose. + The main idea is: if a block boundary has at least one coded fragment on + it, the filter is applied to it. + However, the order that the filters are applied in matters, and VP3 chose + the somewhat strange ordering used below.*/ + while(fragi0<fragi0_end){ + ptrdiff_t fragi; + ptrdiff_t fragi_end; + fragi=fragi0; + fragi_end=fragi+nhfrags; + while(fragi<fragi_end){ + if(frags[fragi].coded){ + unsigned char *ref; + ref=ref_frame_data+frag_buf_offs[fragi]; + if(fragi>fragi0){ + OC_LOOP_FILTER_H(OC_LOOP_FILTER8_MMXEXT,ref,ystride,_bv); + } + if(fragi0>fragi_top){ + OC_LOOP_FILTER_V(OC_LOOP_FILTER8_MMXEXT,ref,ystride,_bv); + } if(fragi+1<fragi_end&&!frags[fragi+1].coded){ - OC_LOOP_FILTER_H_MMX(ref+8,ystride,ll); + OC_LOOP_FILTER_H(OC_LOOP_FILTER8_MMXEXT,ref+8,ystride,_bv); } if(fragi+nhfrags<fragi_bot&&!frags[fragi+nhfrags].coded){ - OC_LOOP_FILTER_V_MMX(ref+(ystride<<3),ystride,ll); + OC_LOOP_FILTER_V(OC_LOOP_FILTER8_MMXEXT,ref+(ystride<<3),ystride,_bv); } } fragi++; diff --git a/thirdparty/libtheora/x86/sse2encfrag.c b/thirdparty/libtheora/x86/sse2encfrag.c new file mode 100644 index 0000000000..43aeb17711 --- /dev/null +++ b/thirdparty/libtheora/x86/sse2encfrag.c @@ -0,0 +1,501 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: + last mod: $Id: dsp_mmx.c 14579 2008-03-12 06:42:40Z xiphmont $ + + ********************************************************************/ +#include <stddef.h> +#include "x86enc.h" +#include "sse2trans.h" + +#if defined(OC_X86_ASM) + +/*Load a 4x8 array of pixels values from %[src] and %[ref] and compute their + 16-bit differences. + On output, these are stored in _m0, xmm1, xmm2, and xmm3. + xmm4 and xmm5 are clobbered.*/ +#define OC_LOAD_SUB_4x8(_m0) \ + "#OC_LOAD_SUB_4x8\n\t" \ + /*Load the first three rows.*/ \ + "movq (%[src]),"_m0"\n\t" \ + "movq (%[ref]),%%xmm4\n\t" \ + "movq (%[src],%[ystride]),%%xmm1\n\t" \ + "movq (%[ref],%[ystride]),%%xmm3\n\t" \ + "movq (%[src],%[ystride],2),%%xmm2\n\t" \ + "movq (%[ref],%[ystride],2),%%xmm5\n\t" \ + /*Unpack and subtract.*/ \ + "punpcklbw %%xmm4,"_m0"\n\t" \ + "punpcklbw %%xmm4,%%xmm4\n\t" \ + "punpcklbw %%xmm3,%%xmm1\n\t" \ + "punpcklbw %%xmm3,%%xmm3\n\t" \ + "psubw %%xmm4,"_m0"\n\t" \ + "psubw %%xmm3,%%xmm1\n\t" \ + /*Load the last row.*/ \ + "movq (%[src],%[ystride3]),%%xmm3\n\t" \ + "movq (%[ref],%[ystride3]),%%xmm4\n\t" \ + /*Unpack, subtract, and advance the pointers.*/ \ + "punpcklbw %%xmm5,%%xmm2\n\t" \ + "punpcklbw %%xmm5,%%xmm5\n\t" \ + "lea (%[src],%[ystride],4),%[src]\n\t" \ + "psubw %%xmm5,%%xmm2\n\t" \ + "punpcklbw %%xmm4,%%xmm3\n\t" \ + "punpcklbw %%xmm4,%%xmm4\n\t" \ + "lea (%[ref],%[ystride],4),%[ref]\n\t" \ + "psubw %%xmm4,%%xmm3\n\t" \ + +/*Square and accumulate four rows of differences in _m0, xmm1, xmm2, and xmm3. + On output, xmm0 contains the sum of two of the rows, and the other two are + added to xmm7.*/ +#define OC_SSD_4x8(_m0) \ + "pmaddwd "_m0","_m0"\n\t" \ + "pmaddwd %%xmm1,%%xmm1\n\t" \ + "pmaddwd %%xmm2,%%xmm2\n\t" \ + "pmaddwd %%xmm3,%%xmm3\n\t" \ + "paddd %%xmm1,"_m0"\n\t" \ + "paddd %%xmm3,%%xmm2\n\t" \ + "paddd %%xmm2,%%xmm7\n\t" \ + +unsigned oc_enc_frag_ssd_sse2(const unsigned char *_src, + const unsigned char *_ref,int _ystride){ + unsigned ret; + __asm__ __volatile__( + OC_LOAD_SUB_4x8("%%xmm7") + OC_SSD_4x8("%%xmm7") + OC_LOAD_SUB_4x8("%%xmm0") + OC_SSD_4x8("%%xmm0") + "paddd %%xmm0,%%xmm7\n\t" + "movdqa %%xmm7,%%xmm6\n\t" + "punpckhqdq %%xmm7,%%xmm7\n\t" + "paddd %%xmm6,%%xmm7\n\t" + "pshufd $1,%%xmm7,%%xmm6\n\t" + "paddd %%xmm6,%%xmm7\n\t" + "movd %%xmm7,%[ret]\n\t" + :[ret]"=a"(ret) + :[src]"r"(_src),[ref]"r"(_ref),[ystride]"r"((ptrdiff_t)_ystride), + [ystride3]"r"((ptrdiff_t)_ystride*3) + ); + return ret; +} + +static const unsigned char __attribute__((aligned(16))) OC_MASK_CONSTS[8]={ + 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 +}; + +/*Load a 2x8 array of pixels values from %[src] and %[ref] and compute their + horizontal sums as well as their 16-bit differences subject to a mask. + %%xmm5 must contain OC_MASK_CONSTS[0...7] and %%xmm6 must contain 0.*/ +#define OC_LOAD_SUB_MASK_2x8 \ + "#OC_LOAD_SUB_MASK_2x8\n\t" \ + /*Start the loads and expand the next 8 bits of the mask.*/ \ + "shl $8,%[m]\n\t" \ + "movq (%[src]),%%xmm0\n\t" \ + "mov %h[m],%b[m]\n\t" \ + "movq (%[ref]),%%xmm2\n\t" \ + "movd %[m],%%xmm4\n\t" \ + "shr $8,%[m]\n\t" \ + "pshuflw $0x00,%%xmm4,%%xmm4\n\t" \ + "mov %h[m],%b[m]\n\t" \ + "pand %%xmm6,%%xmm4\n\t" \ + "pcmpeqb %%xmm6,%%xmm4\n\t" \ + /*Perform the masking.*/ \ + "pand %%xmm4,%%xmm0\n\t" \ + "pand %%xmm4,%%xmm2\n\t" \ + /*Finish the loads while unpacking the first set of rows, and expand the next + 8 bits of the mask.*/ \ + "movd %[m],%%xmm4\n\t" \ + "movq (%[src],%[ystride]),%%xmm1\n\t" \ + "pshuflw $0x00,%%xmm4,%%xmm4\n\t" \ + "movq (%[ref],%[ystride]),%%xmm3\n\t" \ + "pand %%xmm6,%%xmm4\n\t" \ + "punpcklbw %%xmm2,%%xmm0\n\t" \ + "pcmpeqb %%xmm6,%%xmm4\n\t" \ + "punpcklbw %%xmm2,%%xmm2\n\t" \ + /*Mask and unpack the second set of rows.*/ \ + "pand %%xmm4,%%xmm1\n\t" \ + "pand %%xmm4,%%xmm3\n\t" \ + "punpcklbw %%xmm3,%%xmm1\n\t" \ + "punpcklbw %%xmm3,%%xmm3\n\t" \ + "psubw %%xmm2,%%xmm0\n\t" \ + "psubw %%xmm3,%%xmm1\n\t" \ + +unsigned oc_enc_frag_border_ssd_sse2(const unsigned char *_src, + const unsigned char *_ref,int _ystride,ogg_int64_t _mask){ + ptrdiff_t ystride; + unsigned ret; + int i; + ystride=_ystride; + __asm__ __volatile__( + "pxor %%xmm7,%%xmm7\n\t" + "movq %[c],%%xmm6\n\t" + : + :[c]"m"(OC_CONST_ARRAY_OPERAND(unsigned char,OC_MASK_CONSTS,8)) + ); + for(i=0;i<4;i++){ + unsigned m; + m=_mask&0xFFFF; + _mask>>=16; + if(m){ + __asm__ __volatile__( + OC_LOAD_SUB_MASK_2x8 + "pmaddwd %%xmm0,%%xmm0\n\t" + "pmaddwd %%xmm1,%%xmm1\n\t" + "paddd %%xmm0,%%xmm7\n\t" + "paddd %%xmm1,%%xmm7\n\t" + :[src]"+r"(_src),[ref]"+r"(_ref),[ystride]"+r"(ystride),[m]"+Q"(m) + ); + } + _src+=2*ystride; + _ref+=2*ystride; + } + __asm__ __volatile__( + "movdqa %%xmm7,%%xmm6\n\t" + "punpckhqdq %%xmm7,%%xmm7\n\t" + "paddd %%xmm6,%%xmm7\n\t" + "pshufd $1,%%xmm7,%%xmm6\n\t" + "paddd %%xmm6,%%xmm7\n\t" + "movd %%xmm7,%[ret]\n\t" + :[ret]"=a"(ret) + ); + return ret; +} + + +/*Load an 8x8 array of pixel values from %[src] and %[ref] and compute their + 16-bit difference in %%xmm0...%%xmm7.*/ +#define OC_LOAD_SUB_8x8 \ + "#OC_LOAD_SUB_8x8\n\t" \ + "movq (%[src]),%%xmm0\n\t" \ + "movq (%[ref]),%%xmm4\n\t" \ + "movq (%[src],%[src_ystride]),%%xmm1\n\t" \ + "lea (%[src],%[src_ystride],2),%[src]\n\t" \ + "movq (%[ref],%[ref_ystride]),%%xmm5\n\t" \ + "lea (%[ref],%[ref_ystride],2),%[ref]\n\t" \ + "movq (%[src]),%%xmm2\n\t" \ + "movq (%[ref]),%%xmm7\n\t" \ + "movq (%[src],%[src_ystride]),%%xmm3\n\t" \ + "movq (%[ref],%[ref_ystride]),%%xmm6\n\t" \ + "punpcklbw %%xmm4,%%xmm0\n\t" \ + "lea (%[src],%[src_ystride],2),%[src]\n\t" \ + "punpcklbw %%xmm4,%%xmm4\n\t" \ + "lea (%[ref],%[ref_ystride],2),%[ref]\n\t" \ + "psubw %%xmm4,%%xmm0\n\t" \ + "movq (%[src]),%%xmm4\n\t" \ + "movdqa %%xmm0,"OC_MEM_OFFS(0x00,buf)"\n\t" \ + "movq (%[ref]),%%xmm0\n\t" \ + "punpcklbw %%xmm5,%%xmm1\n\t" \ + "punpcklbw %%xmm5,%%xmm5\n\t" \ + "psubw %%xmm5,%%xmm1\n\t" \ + "movq (%[src],%[src_ystride]),%%xmm5\n\t" \ + "punpcklbw %%xmm7,%%xmm2\n\t" \ + "punpcklbw %%xmm7,%%xmm7\n\t" \ + "psubw %%xmm7,%%xmm2\n\t" \ + "movq (%[ref],%[ref_ystride]),%%xmm7\n\t" \ + "punpcklbw %%xmm6,%%xmm3\n\t" \ + "lea (%[src],%[src_ystride],2),%[src]\n\t" \ + "punpcklbw %%xmm6,%%xmm6\n\t" \ + "psubw %%xmm6,%%xmm3\n\t" \ + "movq (%[src]),%%xmm6\n\t" \ + "punpcklbw %%xmm0,%%xmm4\n\t" \ + "lea (%[ref],%[ref_ystride],2),%[ref]\n\t" \ + "punpcklbw %%xmm0,%%xmm0\n\t" \ + "lea (%[src],%[src_ystride],2),%[src]\n\t" \ + "psubw %%xmm0,%%xmm4\n\t" \ + "movq (%[ref]),%%xmm0\n\t" \ + "punpcklbw %%xmm7,%%xmm5\n\t" \ + "neg %[src_ystride]\n\t" \ + "punpcklbw %%xmm7,%%xmm7\n\t" \ + "psubw %%xmm7,%%xmm5\n\t" \ + "movq (%[src],%[src_ystride]),%%xmm7\n\t" \ + "punpcklbw %%xmm0,%%xmm6\n\t" \ + "lea (%[ref],%[ref_ystride],2),%[ref]\n\t" \ + "punpcklbw %%xmm0,%%xmm0\n\t" \ + "neg %[ref_ystride]\n\t" \ + "psubw %%xmm0,%%xmm6\n\t" \ + "movq (%[ref],%[ref_ystride]),%%xmm0\n\t" \ + "punpcklbw %%xmm0,%%xmm7\n\t" \ + "punpcklbw %%xmm0,%%xmm0\n\t" \ + "psubw %%xmm0,%%xmm7\n\t" \ + "movdqa "OC_MEM_OFFS(0x00,buf)",%%xmm0\n\t" \ + +/*Load an 8x8 array of pixel values from %[src] into %%xmm0...%%xmm7.*/ +#define OC_LOAD_8x8 \ + "#OC_LOAD_8x8\n\t" \ + "movq (%[src]),%%xmm0\n\t" \ + "movq (%[src],%[ystride]),%%xmm1\n\t" \ + "movq (%[src],%[ystride],2),%%xmm2\n\t" \ + "pxor %%xmm7,%%xmm7\n\t" \ + "movq (%[src],%[ystride3]),%%xmm3\n\t" \ + "punpcklbw %%xmm7,%%xmm0\n\t" \ + "movq (%[src4]),%%xmm4\n\t" \ + "punpcklbw %%xmm7,%%xmm1\n\t" \ + "movq (%[src4],%[ystride]),%%xmm5\n\t" \ + "punpcklbw %%xmm7,%%xmm2\n\t" \ + "movq (%[src4],%[ystride],2),%%xmm6\n\t" \ + "punpcklbw %%xmm7,%%xmm3\n\t" \ + "movq (%[src4],%[ystride3]),%%xmm7\n\t" \ + "punpcklbw %%xmm4,%%xmm4\n\t" \ + "punpcklbw %%xmm5,%%xmm5\n\t" \ + "psrlw $8,%%xmm4\n\t" \ + "psrlw $8,%%xmm5\n\t" \ + "punpcklbw %%xmm6,%%xmm6\n\t" \ + "punpcklbw %%xmm7,%%xmm7\n\t" \ + "psrlw $8,%%xmm6\n\t" \ + "psrlw $8,%%xmm7\n\t" \ + +/*Performs the first two stages of an 8-point 1-D Hadamard transform in place. + Outputs 1, 3, 4, and 5 from the second stage are negated (which allows us to + perform this stage in place with no temporary registers).*/ +#define OC_HADAMARD_AB_8x8 \ + "#OC_HADAMARD_AB_8x8\n\t" \ + /*Stage A:*/ \ + "paddw %%xmm5,%%xmm1\n\t" \ + "paddw %%xmm6,%%xmm2\n\t" \ + "paddw %%xmm5,%%xmm5\n\t" \ + "paddw %%xmm6,%%xmm6\n\t" \ + "psubw %%xmm1,%%xmm5\n\t" \ + "psubw %%xmm2,%%xmm6\n\t" \ + "paddw %%xmm7,%%xmm3\n\t" \ + "paddw %%xmm4,%%xmm0\n\t" \ + "paddw %%xmm7,%%xmm7\n\t" \ + "paddw %%xmm4,%%xmm4\n\t" \ + "psubw %%xmm3,%%xmm7\n\t" \ + "psubw %%xmm0,%%xmm4\n\t" \ + /*Stage B:*/ \ + "paddw %%xmm2,%%xmm0\n\t" \ + "paddw %%xmm3,%%xmm1\n\t" \ + "paddw %%xmm6,%%xmm4\n\t" \ + "paddw %%xmm7,%%xmm5\n\t" \ + "paddw %%xmm2,%%xmm2\n\t" \ + "paddw %%xmm3,%%xmm3\n\t" \ + "paddw %%xmm6,%%xmm6\n\t" \ + "paddw %%xmm7,%%xmm7\n\t" \ + "psubw %%xmm0,%%xmm2\n\t" \ + "psubw %%xmm1,%%xmm3\n\t" \ + "psubw %%xmm4,%%xmm6\n\t" \ + "psubw %%xmm5,%%xmm7\n\t" \ + +/*Performs the last stage of an 8-point 1-D Hadamard transform in place. + Outputs 1, 3, 5, and 7 are negated (which allows us to perform this stage in + place with no temporary registers).*/ +#define OC_HADAMARD_C_8x8 \ + "#OC_HADAMARD_C_8x8\n\t" \ + /*Stage C:*/ \ + "paddw %%xmm1,%%xmm0\n\t" \ + "paddw %%xmm3,%%xmm2\n\t" \ + "paddw %%xmm5,%%xmm4\n\t" \ + "paddw %%xmm7,%%xmm6\n\t" \ + "paddw %%xmm1,%%xmm1\n\t" \ + "paddw %%xmm3,%%xmm3\n\t" \ + "paddw %%xmm5,%%xmm5\n\t" \ + "paddw %%xmm7,%%xmm7\n\t" \ + "psubw %%xmm0,%%xmm1\n\t" \ + "psubw %%xmm2,%%xmm3\n\t" \ + "psubw %%xmm4,%%xmm5\n\t" \ + "psubw %%xmm6,%%xmm7\n\t" \ + +/*Performs an 8-point 1-D Hadamard transform in place. + Outputs 1, 2, 4, and 7 are negated (which allows us to perform the transform + in place with no temporary registers).*/ +#define OC_HADAMARD_8x8 \ + OC_HADAMARD_AB_8x8 \ + OC_HADAMARD_C_8x8 \ + +/*Performs the first part of the final stage of the Hadamard transform and + summing of absolute values. + At the end of this part, %%xmm1 will contain the DC coefficient of the + transform.*/ +#define OC_HADAMARD_C_ABS_ACCUM_A_8x8 \ + /*We use the fact that \ + (abs(a+b)+abs(a-b))/2=max(abs(a),abs(b)) \ + to merge the final butterfly with the abs and the first stage of \ + accumulation. \ + Thus we can avoid using pabsw, which is not available until SSSE3. \ + Emulating pabsw takes 3 instructions, so the straightforward SSE2 \ + implementation would be (3+3)*8+7=55 instructions (+4 for spilling \ + registers). \ + Even with pabsw, it would be (3+1)*8+7=39 instructions (with no spills). \ + This implementation is only 26 (+4 for spilling registers).*/ \ + "#OC_HADAMARD_C_ABS_ACCUM_A_8x8\n\t" \ + "movdqa %%xmm7,"OC_MEM_OFFS(0x10,buf)"\n\t" \ + "movdqa %%xmm6,"OC_MEM_OFFS(0x00,buf)"\n\t" \ + /*xmm7={0x7FFF}x4 \ + xmm4=max(abs(xmm4),abs(xmm5))-0x7FFF*/ \ + "pcmpeqb %%xmm7,%%xmm7\n\t" \ + "movdqa %%xmm4,%%xmm6\n\t" \ + "psrlw $1,%%xmm7\n\t" \ + "paddw %%xmm5,%%xmm6\n\t" \ + "pmaxsw %%xmm5,%%xmm4\n\t" \ + "paddsw %%xmm7,%%xmm6\n\t" \ + "psubw %%xmm6,%%xmm4\n\t" \ + /*xmm2=max(abs(xmm2),abs(xmm3))-0x7FFF \ + xmm0=max(abs(xmm0),abs(xmm1))-0x7FFF*/ \ + "movdqa %%xmm2,%%xmm6\n\t" \ + "movdqa %%xmm0,%%xmm5\n\t" \ + "pmaxsw %%xmm3,%%xmm2\n\t" \ + "pmaxsw %%xmm1,%%xmm0\n\t" \ + "paddw %%xmm3,%%xmm6\n\t" \ + "movdqa "OC_MEM_OFFS(0x10,buf)",%%xmm3\n\t" \ + "paddw %%xmm5,%%xmm1\n\t" \ + "movdqa "OC_MEM_OFFS(0x00,buf)",%%xmm5\n\t" \ + +/*Performs the second part of the final stage of the Hadamard transform and + summing of absolute values.*/ +#define OC_HADAMARD_C_ABS_ACCUM_B_8x8 \ + "#OC_HADAMARD_C_ABS_ACCUM_B_8x8\n\t" \ + "paddsw %%xmm7,%%xmm6\n\t" \ + "paddsw %%xmm7,%%xmm1\n\t" \ + "psubw %%xmm6,%%xmm2\n\t" \ + "psubw %%xmm1,%%xmm0\n\t" \ + /*xmm7={1}x4 (needed for the horizontal add that follows) \ + xmm0+=xmm2+xmm4+max(abs(xmm3),abs(xmm5))-0x7FFF*/ \ + "movdqa %%xmm3,%%xmm6\n\t" \ + "pmaxsw %%xmm5,%%xmm3\n\t" \ + "paddw %%xmm2,%%xmm0\n\t" \ + "paddw %%xmm5,%%xmm6\n\t" \ + "paddw %%xmm4,%%xmm0\n\t" \ + "paddsw %%xmm7,%%xmm6\n\t" \ + "paddw %%xmm3,%%xmm0\n\t" \ + "psrlw $14,%%xmm7\n\t" \ + "psubw %%xmm6,%%xmm0\n\t" \ + +/*Performs the last stage of an 8-point 1-D Hadamard transform, takes the + absolute value of each component, and accumulates everything into xmm0.*/ +#define OC_HADAMARD_C_ABS_ACCUM_8x8 \ + OC_HADAMARD_C_ABS_ACCUM_A_8x8 \ + OC_HADAMARD_C_ABS_ACCUM_B_8x8 \ + +/*Performs an 8-point 1-D Hadamard transform, takes the absolute value of each + component, and accumulates everything into xmm0. + Note that xmm0 will have an extra 4 added to each column, and that after + removing this value, the remainder will be half the conventional value.*/ +#define OC_HADAMARD_ABS_ACCUM_8x8 \ + OC_HADAMARD_AB_8x8 \ + OC_HADAMARD_C_ABS_ACCUM_8x8 + +static unsigned oc_int_frag_satd_sse2(int *_dc, + const unsigned char *_src,int _src_ystride, + const unsigned char *_ref,int _ref_ystride){ + OC_ALIGN16(ogg_int16_t buf[16]); + unsigned ret; + unsigned ret2; + int dc; + __asm__ __volatile__( + OC_LOAD_SUB_8x8 + OC_HADAMARD_8x8 + OC_TRANSPOSE_8x8 + /*We split out the stages here so we can save the DC coefficient in the + middle.*/ + OC_HADAMARD_AB_8x8 + OC_HADAMARD_C_ABS_ACCUM_A_8x8 + "movd %%xmm1,%[dc]\n\t" + OC_HADAMARD_C_ABS_ACCUM_B_8x8 + /*Up to this point, everything fit in 16 bits (8 input + 1 for the + difference + 2*3 for the two 8-point 1-D Hadamards - 1 for the abs - 1 + for the factor of two we dropped + 3 for the vertical accumulation). + Now we finally have to promote things to dwords. + We break this part out of OC_HADAMARD_ABS_ACCUM_8x8 to hide the long + latency of pmaddwd by starting to compute abs(dc) here.*/ + "pmaddwd %%xmm7,%%xmm0\n\t" + "movsx %w[dc],%[dc]\n\t" + "cdq\n\t" + "movdqa %%xmm0,%%xmm1\n\t" + "punpckhqdq %%xmm0,%%xmm0\n\t" + "paddd %%xmm1,%%xmm0\n\t" + "pshuflw $0xE,%%xmm0,%%xmm1\n\t" + "paddd %%xmm1,%%xmm0\n\t" + "movd %%xmm0,%[ret]\n\t" + /*The sums produced by OC_HADAMARD_ABS_ACCUM_8x8 each have an extra 4 + added to them, a factor of two removed, and the DC value included; + correct the final sum here.*/ + "lea -64(%[ret2],%[ret],2),%[ret]\n\t" + "xor %[dc],%[ret2]\n\t" + "sub %[ret2],%[ret]\n\t" + /*Although it looks like we're using 7 registers here, gcc can alias %[ret] + and %[dc] with some of the inputs, since for once we don't write to + them until after we're done using everything but %[buf].*/ + /*Note that _src_ystride and _ref_ystride must be given non-overlapping + constraints, otherewise if gcc can prove they're equal it will allocate + them to the same register (which is bad); _src and _ref face a similar + problem. + All four are destructively modified, but if we list them as output + constraints, gcc can't alias them with other outputs.*/ + :[ret]"=r"(ret),[ret2]"=d"(ret2),[dc]"=a"(dc), + [buf]"=m"(OC_ARRAY_OPERAND(ogg_int16_t,buf,16)) + :[src]"S"(_src),[src_ystride]"c"((ptrdiff_t)_src_ystride), + [ref]"a"(_ref),[ref_ystride]"d"((ptrdiff_t)_ref_ystride) + /*We have to use neg, so we actually clobber the condition codes for once + (not to mention sub, and add).*/ + :"cc" + ); + *_dc=dc; + return ret; +} + +unsigned oc_enc_frag_satd_sse2(int *_dc,const unsigned char *_src, + const unsigned char *_ref,int _ystride){ + return oc_int_frag_satd_sse2(_dc,_src,_ystride,_ref,_ystride); +} + +unsigned oc_enc_frag_satd2_sse2(int *_dc,const unsigned char *_src, + const unsigned char *_ref1,const unsigned char *_ref2,int _ystride){ + OC_ALIGN8(unsigned char ref[64]); + oc_int_frag_copy2_mmxext(ref,8,_ref1,_ref2,_ystride); + return oc_int_frag_satd_sse2(_dc,_src,_ystride,ref,8); +} + +unsigned oc_enc_frag_intra_satd_sse2(int *_dc, + const unsigned char *_src,int _ystride){ + OC_ALIGN16(ogg_int16_t buf[16]); + unsigned ret; + int dc; + __asm__ __volatile__( + OC_LOAD_8x8 + OC_HADAMARD_8x8 + OC_TRANSPOSE_8x8 + /*We split out the stages here so we can save the DC coefficient in the + middle.*/ + OC_HADAMARD_AB_8x8 + OC_HADAMARD_C_ABS_ACCUM_A_8x8 + "movd %%xmm1,%[dc]\n\t" + OC_HADAMARD_C_ABS_ACCUM_B_8x8 + /*Up to this point, everything fit in 16 bits (8 input + 1 for the + difference + 2*3 for the two 8-point 1-D Hadamards - 1 for the abs - 1 + for the factor of two we dropped + 3 for the vertical accumulation). + Now we finally have to promote things to dwords.*/ + "pmaddwd %%xmm7,%%xmm0\n\t" + /*We assume that the DC coefficient is always positive (which is true, + because the input to the INTRA transform was not a difference).*/ + "movzx %w[dc],%[dc]\n\t" + "movdqa %%xmm0,%%xmm1\n\t" + "punpckhqdq %%xmm0,%%xmm0\n\t" + "paddd %%xmm1,%%xmm0\n\t" + "pshuflw $0xE,%%xmm0,%%xmm1\n\t" + "paddd %%xmm1,%%xmm0\n\t" + "movd %%xmm0,%[ret]\n\t" + "lea -64(%[ret],%[ret]),%[ret]\n\t" + "sub %[dc],%[ret]\n\t" + /*Although it looks like we're using 7 registers here, gcc can alias %[ret] + and %[dc] with some of the inputs, since for once we don't write to + them until after we're done using everything but %[buf].*/ + :[ret]"=a"(ret),[dc]"=r"(dc), + [buf]"=m"(OC_ARRAY_OPERAND(ogg_int16_t,buf,16)) + :[src]"r"(_src),[src4]"r"(_src+4*_ystride), + [ystride]"r"((ptrdiff_t)_ystride),[ystride3]"r"((ptrdiff_t)3*_ystride) + /*We have to use sub, so we actually clobber the condition codes for once.*/ + :"cc" + ); + *_dc=dc; + return ret; +} + +#endif diff --git a/thirdparty/libtheora/x86/sse2fdct.c b/thirdparty/libtheora/x86/sse2fdct.c index 86c17d68b1..64c1d27372 100644 --- a/thirdparty/libtheora/x86/sse2fdct.c +++ b/thirdparty/libtheora/x86/sse2fdct.c @@ -13,12 +13,14 @@ /*$Id: fdct_ses2.c 14579 2008-03-12 06:42:40Z xiphmont $*/ #include <stddef.h> #include "x86enc.h" +#include "x86zigzag.h" +#include "sse2trans.h" #if defined(OC_X86_64_ASM) -# define OC_FDCT8x8 \ +# define OC_FDCT_8x8 \ /*Note: xmm15={0}x8 and xmm14={-1}x8.*/ \ - "#OC_FDCT8x8\n\t" \ + "#OC_FDCT_8x8\n\t" \ /*Stage 1:*/ \ "movdqa %%xmm0,%%xmm11\n\t" \ "movdqa %%xmm1,%%xmm10\n\t" \ @@ -349,81 +351,6 @@ "psubw %%xmm14,%%xmm10\n\t" \ "paddw %%xmm10,%%xmm7\n\t " \ -# define OC_TRANSPOSE8x8 \ - "#OC_TRANSPOSE8x8\n\t" \ - "movdqa %%xmm4,%%xmm8\n\t" \ - /*xmm4 = f3 e3 f2 e2 f1 e1 f0 e0*/ \ - "punpcklwd %%xmm5,%%xmm4\n\t" \ - /*xmm8 = f7 e7 f6 e6 f5 e5 f4 e4*/ \ - "punpckhwd %%xmm5,%%xmm8\n\t" \ - /*xmm5 is free.*/ \ - "movdqa %%xmm0,%%xmm5\n\t" \ - /*xmm0 = b3 a3 b2 a2 b1 a1 b0 a0*/ \ - "punpcklwd %%xmm1,%%xmm0\n\t" \ - /*xmm5 = b7 a7 b6 a6 b5 a5 b4 a4*/ \ - "punpckhwd %%xmm1,%%xmm5\n\t" \ - /*xmm1 is free.*/ \ - "movdqa %%xmm6,%%xmm1\n\t" \ - /*xmm6 = h3 g3 h2 g2 h1 g1 h0 g0*/ \ - "punpcklwd %%xmm7,%%xmm6\n\t" \ - /*xmm1 = h7 g7 h6 g6 h5 g5 h4 g4*/ \ - "punpckhwd %%xmm7,%%xmm1\n\t" \ - /*xmm7 is free.*/ \ - "movdqa %%xmm2,%%xmm7\n\t" \ - /*xmm7 = d3 c3 d2 c2 d1 c1 d0 c0*/ \ - "punpcklwd %%xmm3,%%xmm7\n\t" \ - /*xmm2 = d7 c7 d6 c6 d5 c5 d4 c4*/ \ - "punpckhwd %%xmm3,%%xmm2\n\t" \ - /*xmm3 is free.*/ \ - "movdqa %%xmm0,%%xmm3\n\t" \ - /*xmm0 = d1 c1 b1 a1 d0 c0 b0 a0*/ \ - "punpckldq %%xmm7,%%xmm0\n\t" \ - /*xmm3 = d3 c3 b3 a3 d2 c2 b2 a2*/ \ - "punpckhdq %%xmm7,%%xmm3\n\t" \ - /*xmm7 is free.*/ \ - "movdqa %%xmm5,%%xmm7\n\t" \ - /*xmm5 = d5 c5 b5 a5 d4 c4 b4 a4*/ \ - "punpckldq %%xmm2,%%xmm5\n\t" \ - /*xmm7 = d7 c7 b7 a7 d6 c6 b6 a6*/ \ - "punpckhdq %%xmm2,%%xmm7\n\t" \ - /*xmm2 is free.*/ \ - "movdqa %%xmm4,%%xmm2\n\t" \ - /*xmm2 = h1 g1 f1 e1 h0 g0 f0 e0*/ \ - "punpckldq %%xmm6,%%xmm2\n\t" \ - /*xmm4 = h3 g3 f3 e3 h2 g2 f2 e2*/ \ - "punpckhdq %%xmm6,%%xmm4\n\t" \ - /*xmm6 is free.*/ \ - "movdqa %%xmm8,%%xmm6\n\t" \ - /*xmm6 = h5 g5 f5 e5 h4 g4 f4 e4*/ \ - "punpckldq %%xmm1,%%xmm6\n\t" \ - /*xmm8 = h7 g7 f7 e7 h6 g6 f6 e6*/ \ - "punpckhdq %%xmm1,%%xmm8\n\t" \ - /*xmm1 is free.*/ \ - "movdqa %%xmm0,%%xmm1\n\t" \ - /*xmm0 = h0 g0 f0 e0 d0 c0 b0 a0*/ \ - "punpcklqdq %%xmm2,%%xmm0\n\t" \ - /*xmm1 = h1 g1 f1 e1 d1 c1 b1 a1*/ \ - "punpckhqdq %%xmm2,%%xmm1\n\t" \ - /*xmm2 is free.*/ \ - "movdqa %%xmm3,%%xmm2\n\t" \ - /*xmm2 = h2 g2 f2 e2 d2 c2 b2 a2*/ \ - "punpcklqdq %%xmm4,%%xmm2\n\t" \ - /*xmm3 = h3 g3 f3 e3 d3 c3 b3 a3*/ \ - "punpckhqdq %%xmm4,%%xmm3\n\t" \ - /*xmm4 is free.*/ \ - "movdqa %%xmm5,%%xmm4\n\t" \ - /*xmm4 = h4 g4 f4 e4 d4 c4 b4 a4*/ \ - "punpcklqdq %%xmm6,%%xmm4\n\t" \ - /*xmm5 = h5 g5 f5 e5 d5 c5 b5 a5*/ \ - "punpckhqdq %%xmm6,%%xmm5\n\t" \ - /*xmm6 is free.*/ \ - "movdqa %%xmm7,%%xmm6\n\t" \ - /*xmm6 = h6 g6 f6 e6 d6 c6 b6 a6*/ \ - "punpcklqdq %%xmm8,%%xmm6\n\t" \ - /*xmm7 = h7 g7 f7 e7 d7 c7 b7 a7*/ \ - "punpckhqdq %%xmm8,%%xmm7\n\t" \ - /*xmm8 is free.*/ \ - /*SSE2 implementation of the fDCT for x86-64 only. Because of the 8 extra XMM registers on x86-64, this version can operate without any temporary stack access at all.*/ @@ -482,12 +409,10 @@ void oc_enc_fdct8x8_x86_64sse2(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ /*xmm1=_x[15...8]-{0,0,0,0,0,0,0,1}*/ "psubw %%xmm9,%%xmm1\n\t" /*Transform columns.*/ - OC_FDCT8x8 + OC_FDCT_8x8 /*Transform rows.*/ - OC_TRANSPOSE8x8 - OC_FDCT8x8 - /*TODO: zig-zag ordering?*/ - OC_TRANSPOSE8x8 + OC_TRANSPOSE_8x8 + OC_FDCT_8x8 /*xmm14={-2,-2,-2,-2,-2,-2,-2,-2}*/ "paddw %%xmm14,%%xmm14\n\t" "psubw %%xmm14,%%xmm0\n\t" @@ -506,15 +431,19 @@ void oc_enc_fdct8x8_x86_64sse2(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ "psubw %%xmm14,%%xmm7\n\t" "psraw $2,%%xmm6\n\t" "psraw $2,%%xmm7\n\t" - /*Store the result.*/ - "movdqa %%xmm0,0x00(%[y])\n\t" - "movdqa %%xmm1,0x10(%[y])\n\t" - "movdqa %%xmm2,0x20(%[y])\n\t" - "movdqa %%xmm3,0x30(%[y])\n\t" - "movdqa %%xmm4,0x40(%[y])\n\t" - "movdqa %%xmm5,0x50(%[y])\n\t" - "movdqa %%xmm6,0x60(%[y])\n\t" - "movdqa %%xmm7,0x70(%[y])\n\t" + /*Transpose, zig-zag, and store the result.*/ + /*We could probably do better using SSSE3's palignr, but re-using MMXEXT + version will do for now.*/ +#define OC_ZZ_LOAD_ROW_LO(_row,_reg) \ + "movdq2q %%xmm"#_row","_reg"\n\t" \ + +#define OC_ZZ_LOAD_ROW_HI(_row,_reg) \ + "punpckhqdq %%xmm"#_row",%%xmm"#_row"\n\t" \ + "movdq2q %%xmm"#_row","_reg"\n\t" \ + + OC_TRANSPOSE_ZIG_ZAG_MMXEXT +#undef OC_ZZ_LOAD_ROW_LO +#undef OC_ZZ_LOAD_ROW_HI :[a]"=&r"(a) :[y]"r"(_y),[x]"r"(_x) :"memory" diff --git a/thirdparty/libtheora/x86/sse2idct.c b/thirdparty/libtheora/x86/sse2idct.c new file mode 100644 index 0000000000..4597ab074f --- /dev/null +++ b/thirdparty/libtheora/x86/sse2idct.c @@ -0,0 +1,456 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * + * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * + * * + ******************************************************************** + + function: + last mod: $Id: mmxidct.c 16503 2009-08-22 18:14:02Z giles $ + + ********************************************************************/ + +/*SSE2 acceleration of Theora's iDCT.*/ +#include "x86int.h" +#include "sse2trans.h" +#include "../dct.h" + +#if defined(OC_X86_ASM) + +/*A table of constants used by the MMX routines.*/ +const unsigned short __attribute__((aligned(16),used)) OC_IDCT_CONSTS[64]={ + 8, 8, 8, 8, 8, 8, 8, 8, + OC_C1S7,OC_C1S7,OC_C1S7,OC_C1S7,OC_C1S7,OC_C1S7,OC_C1S7,OC_C1S7, + OC_C2S6,OC_C2S6,OC_C2S6,OC_C2S6,OC_C2S6,OC_C2S6,OC_C2S6,OC_C2S6, + OC_C3S5,OC_C3S5,OC_C3S5,OC_C3S5,OC_C3S5,OC_C3S5,OC_C3S5,OC_C3S5, + OC_C4S4,OC_C4S4,OC_C4S4,OC_C4S4,OC_C4S4,OC_C4S4,OC_C4S4,OC_C4S4, + OC_C5S3,OC_C5S3,OC_C5S3,OC_C5S3,OC_C5S3,OC_C5S3,OC_C5S3,OC_C5S3, + OC_C6S2,OC_C6S2,OC_C6S2,OC_C6S2,OC_C6S2,OC_C6S2,OC_C6S2,OC_C6S2, + OC_C7S1,OC_C7S1,OC_C7S1,OC_C7S1,OC_C7S1,OC_C7S1,OC_C7S1,OC_C7S1 +}; + + +/*Performs the first three stages of the iDCT. + xmm2, xmm6, xmm3, and xmm5 must contain the corresponding rows of the input + (accessed in that order). + The remaining rows must be in _x at their corresponding locations. + On output, xmm7 down to xmm4 contain rows 0 through 3, and xmm0 up to xmm3 + contain rows 4 through 7.*/ +#define OC_IDCT_8x8_ABC(_x) \ + "#OC_IDCT_8x8_ABC\n\t" \ + /*Stage 1:*/ \ + /*2-3 rotation by 6pi/16. \ + xmm4=xmm7=C6, xmm0=xmm1=C2, xmm2=X2, xmm6=X6.*/ \ + "movdqa "OC_MEM_OFFS(0x20,c)",%%xmm1\n\t" \ + "movdqa "OC_MEM_OFFS(0x60,c)",%%xmm4\n\t" \ + "movdqa %%xmm1,%%xmm0\n\t" \ + "pmulhw %%xmm2,%%xmm1\n\t" \ + "movdqa %%xmm4,%%xmm7\n\t" \ + "pmulhw %%xmm6,%%xmm0\n\t" \ + "pmulhw %%xmm2,%%xmm7\n\t" \ + "pmulhw %%xmm6,%%xmm4\n\t" \ + "paddw %%xmm6,%%xmm0\n\t" \ + "movdqa "OC_MEM_OFFS(0x30,c)",%%xmm6\n\t" \ + "paddw %%xmm1,%%xmm2\n\t" \ + "psubw %%xmm0,%%xmm7\n\t" \ + "movdqa %%xmm7,"OC_MEM_OFFS(0x00,buf)"\n\t" \ + "paddw %%xmm4,%%xmm2\n\t" \ + "movdqa "OC_MEM_OFFS(0x50,c)",%%xmm4\n\t" \ + "movdqa %%xmm2,"OC_MEM_OFFS(0x10,buf)"\n\t" \ + /*5-6 rotation by 3pi/16. \ + xmm4=xmm2=C5, xmm1=xmm6=C3, xmm3=X3, xmm5=X5.*/ \ + "movdqa %%xmm4,%%xmm2\n\t" \ + "movdqa %%xmm6,%%xmm1\n\t" \ + "pmulhw %%xmm3,%%xmm4\n\t" \ + "pmulhw %%xmm5,%%xmm1\n\t" \ + "pmulhw %%xmm3,%%xmm6\n\t" \ + "pmulhw %%xmm5,%%xmm2\n\t" \ + "paddw %%xmm3,%%xmm4\n\t" \ + "paddw %%xmm5,%%xmm3\n\t" \ + "paddw %%xmm6,%%xmm3\n\t" \ + "movdqa "OC_MEM_OFFS(0x70,_x)",%%xmm6\n\t" \ + "paddw %%xmm5,%%xmm1\n\t" \ + "movdqa "OC_MEM_OFFS(0x10,_x)",%%xmm5\n\t" \ + "paddw %%xmm3,%%xmm2\n\t" \ + "movdqa "OC_MEM_OFFS(0x70,c)",%%xmm3\n\t" \ + "psubw %%xmm4,%%xmm1\n\t" \ + "movdqa "OC_MEM_OFFS(0x10,c)",%%xmm4\n\t" \ + /*4-7 rotation by 7pi/16. \ + xmm4=xmm7=C1, xmm3=xmm0=C7, xmm5=X1, xmm6=X7.*/ \ + "movdqa %%xmm3,%%xmm0\n\t" \ + "movdqa %%xmm4,%%xmm7\n\t" \ + "pmulhw %%xmm5,%%xmm3\n\t" \ + "pmulhw %%xmm5,%%xmm7\n\t" \ + "pmulhw %%xmm6,%%xmm4\n\t" \ + "pmulhw %%xmm6,%%xmm0\n\t" \ + "paddw %%xmm6,%%xmm4\n\t" \ + "movdqa "OC_MEM_OFFS(0x40,_x)",%%xmm6\n\t" \ + "paddw %%xmm5,%%xmm7\n\t" \ + "psubw %%xmm4,%%xmm3\n\t" \ + "movdqa "OC_MEM_OFFS(0x40,c)",%%xmm4\n\t" \ + "paddw %%xmm7,%%xmm0\n\t" \ + "movdqa "OC_MEM_OFFS(0x00,_x)",%%xmm7\n\t" \ + /*0-1 butterfly. \ + xmm4=xmm5=C4, xmm7=X0, xmm6=X4.*/ \ + "paddw %%xmm7,%%xmm6\n\t" \ + "movdqa %%xmm4,%%xmm5\n\t" \ + "pmulhw %%xmm6,%%xmm4\n\t" \ + "paddw %%xmm7,%%xmm7\n\t" \ + "psubw %%xmm6,%%xmm7\n\t" \ + "paddw %%xmm6,%%xmm4\n\t" \ + /*Stage 2:*/ \ + /*4-5 butterfly: xmm3=t[4], xmm1=t[5] \ + 7-6 butterfly: xmm2=t[6], xmm0=t[7]*/ \ + "movdqa %%xmm3,%%xmm6\n\t" \ + "paddw %%xmm1,%%xmm3\n\t" \ + "psubw %%xmm1,%%xmm6\n\t" \ + "movdqa %%xmm5,%%xmm1\n\t" \ + "pmulhw %%xmm7,%%xmm5\n\t" \ + "paddw %%xmm7,%%xmm5\n\t" \ + "movdqa %%xmm0,%%xmm7\n\t" \ + "paddw %%xmm2,%%xmm0\n\t" \ + "psubw %%xmm2,%%xmm7\n\t" \ + "movdqa %%xmm1,%%xmm2\n\t" \ + "pmulhw %%xmm6,%%xmm1\n\t" \ + "pmulhw %%xmm7,%%xmm2\n\t" \ + "paddw %%xmm6,%%xmm1\n\t" \ + "movdqa "OC_MEM_OFFS(0x00,buf)",%%xmm6\n\t" \ + "paddw %%xmm7,%%xmm2\n\t" \ + "movdqa "OC_MEM_OFFS(0x10,buf)",%%xmm7\n\t" \ + /*Stage 3: \ + 6-5 butterfly: xmm1=t[5], xmm2=t[6] -> xmm1=t[6]+t[5], xmm2=t[6]-t[5] \ + 0-3 butterfly: xmm4=t[0], xmm7=t[3] -> xmm7=t[0]+t[3], xmm4=t[0]-t[3] \ + 1-2 butterfly: xmm5=t[1], xmm6=t[2] -> xmm6=t[1]+t[2], xmm5=t[1]-t[2]*/ \ + "paddw %%xmm2,%%xmm1\n\t" \ + "paddw %%xmm5,%%xmm6\n\t" \ + "paddw %%xmm4,%%xmm7\n\t" \ + "paddw %%xmm2,%%xmm2\n\t" \ + "paddw %%xmm4,%%xmm4\n\t" \ + "paddw %%xmm5,%%xmm5\n\t" \ + "psubw %%xmm1,%%xmm2\n\t" \ + "psubw %%xmm7,%%xmm4\n\t" \ + "psubw %%xmm6,%%xmm5\n\t" \ + +/*Performs the last stage of the iDCT. + On input, xmm7 down to xmm4 contain rows 0 through 3, and xmm0 up to xmm3 + contain rows 4 through 7. + On output, xmm0 through xmm7 contain the corresponding rows.*/ +#define OC_IDCT_8x8_D \ + "#OC_IDCT_8x8_D\n\t" \ + /*Stage 4: \ + 0-7 butterfly: xmm7=t[0], xmm0=t[7] -> xmm0=t[0]+t[7], xmm7=t[0]-t[7] \ + 1-6 butterfly: xmm6=t[1], xmm1=t[6] -> xmm1=t[1]+t[6], xmm6=t[1]-t[6] \ + 2-5 butterfly: xmm5=t[2], xmm2=t[5] -> xmm2=t[2]+t[5], xmm5=t[2]-t[5] \ + 3-4 butterfly: xmm4=t[3], xmm3=t[4] -> xmm3=t[3]+t[4], xmm4=t[3]-t[4]*/ \ + "psubw %%xmm0,%%xmm7\n\t" \ + "psubw %%xmm1,%%xmm6\n\t" \ + "psubw %%xmm2,%%xmm5\n\t" \ + "psubw %%xmm3,%%xmm4\n\t" \ + "paddw %%xmm0,%%xmm0\n\t" \ + "paddw %%xmm1,%%xmm1\n\t" \ + "paddw %%xmm2,%%xmm2\n\t" \ + "paddw %%xmm3,%%xmm3\n\t" \ + "paddw %%xmm7,%%xmm0\n\t" \ + "paddw %%xmm6,%%xmm1\n\t" \ + "paddw %%xmm5,%%xmm2\n\t" \ + "paddw %%xmm4,%%xmm3\n\t" \ + +/*Performs the last stage of the iDCT. + On input, xmm7 down to xmm4 contain rows 0 through 3, and xmm0 up to xmm3 + contain rows 4 through 7. + On output, xmm0 through xmm7 contain the corresponding rows.*/ +#define OC_IDCT_8x8_D_STORE \ + "#OC_IDCT_8x8_D_STORE\n\t" \ + /*Stage 4: \ + 0-7 butterfly: xmm7=t[0], xmm0=t[7] -> xmm0=t[0]+t[7], xmm7=t[0]-t[7] \ + 1-6 butterfly: xmm6=t[1], xmm1=t[6] -> xmm1=t[1]+t[6], xmm6=t[1]-t[6] \ + 2-5 butterfly: xmm5=t[2], xmm2=t[5] -> xmm2=t[2]+t[5], xmm5=t[2]-t[5] \ + 3-4 butterfly: xmm4=t[3], xmm3=t[4] -> xmm3=t[3]+t[4], xmm4=t[3]-t[4]*/ \ + "psubw %%xmm3,%%xmm4\n\t" \ + "movdqa %%xmm4,"OC_MEM_OFFS(0x40,y)"\n\t" \ + "movdqa "OC_MEM_OFFS(0x00,c)",%%xmm4\n\t" \ + "psubw %%xmm0,%%xmm7\n\t" \ + "psubw %%xmm1,%%xmm6\n\t" \ + "psubw %%xmm2,%%xmm5\n\t" \ + "paddw %%xmm4,%%xmm7\n\t" \ + "paddw %%xmm4,%%xmm6\n\t" \ + "paddw %%xmm4,%%xmm5\n\t" \ + "paddw "OC_MEM_OFFS(0x40,y)",%%xmm4\n\t" \ + "paddw %%xmm0,%%xmm0\n\t" \ + "paddw %%xmm1,%%xmm1\n\t" \ + "paddw %%xmm2,%%xmm2\n\t" \ + "paddw %%xmm3,%%xmm3\n\t" \ + "paddw %%xmm7,%%xmm0\n\t" \ + "paddw %%xmm6,%%xmm1\n\t" \ + "psraw $4,%%xmm0\n\t" \ + "paddw %%xmm5,%%xmm2\n\t" \ + "movdqa %%xmm0,"OC_MEM_OFFS(0x00,y)"\n\t" \ + "psraw $4,%%xmm1\n\t" \ + "paddw %%xmm4,%%xmm3\n\t" \ + "movdqa %%xmm1,"OC_MEM_OFFS(0x10,y)"\n\t" \ + "psraw $4,%%xmm2\n\t" \ + "movdqa %%xmm2,"OC_MEM_OFFS(0x20,y)"\n\t" \ + "psraw $4,%%xmm3\n\t" \ + "movdqa %%xmm3,"OC_MEM_OFFS(0x30,y)"\n\t" \ + "psraw $4,%%xmm4\n\t" \ + "movdqa %%xmm4,"OC_MEM_OFFS(0x40,y)"\n\t" \ + "psraw $4,%%xmm5\n\t" \ + "movdqa %%xmm5,"OC_MEM_OFFS(0x50,y)"\n\t" \ + "psraw $4,%%xmm6\n\t" \ + "movdqa %%xmm6,"OC_MEM_OFFS(0x60,y)"\n\t" \ + "psraw $4,%%xmm7\n\t" \ + "movdqa %%xmm7,"OC_MEM_OFFS(0x70,y)"\n\t" \ + +static void oc_idct8x8_slow_sse2(ogg_int16_t _y[64],ogg_int16_t _x[64]){ + OC_ALIGN16(ogg_int16_t buf[16]); + int i; + /*This routine accepts an 8x8 matrix pre-transposed.*/ + __asm__ __volatile__( + /*Load rows 2, 3, 5, and 6 for the first stage of the iDCT.*/ + "movdqa "OC_MEM_OFFS(0x20,x)",%%xmm2\n\t" + "movdqa "OC_MEM_OFFS(0x60,x)",%%xmm6\n\t" + "movdqa "OC_MEM_OFFS(0x30,x)",%%xmm3\n\t" + "movdqa "OC_MEM_OFFS(0x50,x)",%%xmm5\n\t" + OC_IDCT_8x8_ABC(x) + OC_IDCT_8x8_D + OC_TRANSPOSE_8x8 + /*Clear out rows 0, 1, 4, and 7 for the first stage of the iDCT.*/ + "movdqa %%xmm7,"OC_MEM_OFFS(0x70,y)"\n\t" + "movdqa %%xmm4,"OC_MEM_OFFS(0x40,y)"\n\t" + "movdqa %%xmm1,"OC_MEM_OFFS(0x10,y)"\n\t" + "movdqa %%xmm0,"OC_MEM_OFFS(0x00,y)"\n\t" + OC_IDCT_8x8_ABC(y) + OC_IDCT_8x8_D_STORE + :[buf]"=m"(OC_ARRAY_OPERAND(ogg_int16_t,buf,16)), + [y]"=m"(OC_ARRAY_OPERAND(ogg_int16_t,_y,64)) + :[x]"m"(OC_CONST_ARRAY_OPERAND(ogg_int16_t,_x,64)), + [c]"m"(OC_CONST_ARRAY_OPERAND(ogg_int16_t,OC_IDCT_CONSTS,128)) + ); + __asm__ __volatile__("pxor %%xmm0,%%xmm0\n\t"::); + /*Clear input data for next block (decoder only).*/ + for(i=0;i<2;i++){ + __asm__ __volatile__( + "movdqa %%xmm0,"OC_MEM_OFFS(0x00,x)"\n\t" + "movdqa %%xmm0,"OC_MEM_OFFS(0x10,x)"\n\t" + "movdqa %%xmm0,"OC_MEM_OFFS(0x20,x)"\n\t" + "movdqa %%xmm0,"OC_MEM_OFFS(0x30,x)"\n\t" + :[x]"=m"(OC_ARRAY_OPERAND(ogg_int16_t,_x+i*32,32)) + ); + } +} + +/*For the first step of the 10-coefficient version of the 8x8 iDCT, we only + need to work with four columns at a time. + Doing this in MMX is faster on processors with a 64-bit data path.*/ +#define OC_IDCT_8x8_10_MMX \ + "#OC_IDCT_8x8_10_MMX\n\t" \ + /*Stage 1:*/ \ + /*2-3 rotation by 6pi/16. \ + mm7=C6, mm6=C2, mm2=X2, X6=0.*/ \ + "movq "OC_MEM_OFFS(0x60,c)",%%mm7\n\t" \ + "movq "OC_MEM_OFFS(0x20,c)",%%mm6\n\t" \ + "pmulhw %%mm2,%%mm6\n\t" \ + "pmulhw %%mm2,%%mm7\n\t" \ + "movq "OC_MEM_OFFS(0x50,c)",%%mm5\n\t" \ + "paddw %%mm6,%%mm2\n\t" \ + "movq %%mm2,"OC_MEM_OFFS(0x10,buf)"\n\t" \ + "movq "OC_MEM_OFFS(0x30,c)",%%mm2\n\t" \ + "movq %%mm7,"OC_MEM_OFFS(0x00,buf)"\n\t" \ + /*5-6 rotation by 3pi/16. \ + mm5=C5, mm2=C3, mm3=X3, X5=0.*/ \ + "pmulhw %%mm3,%%mm5\n\t" \ + "pmulhw %%mm3,%%mm2\n\t" \ + "movq "OC_MEM_OFFS(0x10,c)",%%mm7\n\t" \ + "paddw %%mm3,%%mm5\n\t" \ + "paddw %%mm3,%%mm2\n\t" \ + "movq "OC_MEM_OFFS(0x70,c)",%%mm3\n\t" \ + /*4-7 rotation by 7pi/16. \ + mm7=C1, mm3=C7, mm1=X1, X7=0.*/ \ + "pmulhw %%mm1,%%mm3\n\t" \ + "pmulhw %%mm1,%%mm7\n\t" \ + "movq "OC_MEM_OFFS(0x40,c)",%%mm4\n\t" \ + "movq %%mm3,%%mm6\n\t" \ + "paddw %%mm1,%%mm7\n\t" \ + /*0-1 butterfly. \ + mm4=C4, mm0=X0, X4=0.*/ \ + /*Stage 2:*/ \ + /*4-5 butterfly: mm3=t[4], mm5=t[5] \ + 7-6 butterfly: mm2=t[6], mm7=t[7]*/ \ + "psubw %%mm5,%%mm3\n\t" \ + "paddw %%mm5,%%mm6\n\t" \ + "movq %%mm4,%%mm1\n\t" \ + "pmulhw %%mm0,%%mm4\n\t" \ + "paddw %%mm0,%%mm4\n\t" \ + "movq %%mm7,%%mm0\n\t" \ + "movq %%mm4,%%mm5\n\t" \ + "paddw %%mm2,%%mm0\n\t" \ + "psubw %%mm2,%%mm7\n\t" \ + "movq %%mm1,%%mm2\n\t" \ + "pmulhw %%mm6,%%mm1\n\t" \ + "pmulhw %%mm7,%%mm2\n\t" \ + "paddw %%mm6,%%mm1\n\t" \ + "movq "OC_MEM_OFFS(0x00,buf)",%%mm6\n\t" \ + "paddw %%mm7,%%mm2\n\t" \ + "movq "OC_MEM_OFFS(0x10,buf)",%%mm7\n\t" \ + /*Stage 3: \ + 6-5 butterfly: mm1=t[5], mm2=t[6] -> mm1=t[6]+t[5], mm2=t[6]-t[5] \ + 0-3 butterfly: mm4=t[0], mm7=t[3] -> mm7=t[0]+t[3], mm4=t[0]-t[3] \ + 1-2 butterfly: mm5=t[1], mm6=t[2] -> mm6=t[1]+t[2], mm5=t[1]-t[2]*/ \ + "paddw %%mm2,%%mm1\n\t" \ + "paddw %%mm5,%%mm6\n\t" \ + "paddw %%mm4,%%mm7\n\t" \ + "paddw %%mm2,%%mm2\n\t" \ + "paddw %%mm4,%%mm4\n\t" \ + "paddw %%mm5,%%mm5\n\t" \ + "psubw %%mm1,%%mm2\n\t" \ + "psubw %%mm7,%%mm4\n\t" \ + "psubw %%mm6,%%mm5\n\t" \ + /*Stage 4: \ + 0-7 butterfly: mm7=t[0], mm0=t[7] -> mm0=t[0]+t[7], mm7=t[0]-t[7] \ + 1-6 butterfly: mm6=t[1], mm1=t[6] -> mm1=t[1]+t[6], mm6=t[1]-t[6] \ + 2-5 butterfly: mm5=t[2], mm2=t[5] -> mm2=t[2]+t[5], mm5=t[2]-t[5] \ + 3-4 butterfly: mm4=t[3], mm3=t[4] -> mm3=t[3]+t[4], mm4=t[3]-t[4]*/ \ + "psubw %%mm0,%%mm7\n\t" \ + "psubw %%mm1,%%mm6\n\t" \ + "psubw %%mm2,%%mm5\n\t" \ + "psubw %%mm3,%%mm4\n\t" \ + "paddw %%mm0,%%mm0\n\t" \ + "paddw %%mm1,%%mm1\n\t" \ + "paddw %%mm2,%%mm2\n\t" \ + "paddw %%mm3,%%mm3\n\t" \ + "paddw %%mm7,%%mm0\n\t" \ + "paddw %%mm6,%%mm1\n\t" \ + "paddw %%mm5,%%mm2\n\t" \ + "paddw %%mm4,%%mm3\n\t" \ + +#define OC_IDCT_8x8_10_ABC \ + "#OC_IDCT_8x8_10_ABC\n\t" \ + /*Stage 1:*/ \ + /*2-3 rotation by 6pi/16. \ + xmm7=C6, xmm6=C2, xmm2=X2, X6=0.*/ \ + "movdqa "OC_MEM_OFFS(0x60,c)",%%xmm7\n\t" \ + "movdqa "OC_MEM_OFFS(0x20,c)",%%xmm6\n\t" \ + "pmulhw %%xmm2,%%xmm6\n\t" \ + "pmulhw %%xmm2,%%xmm7\n\t" \ + "movdqa "OC_MEM_OFFS(0x50,c)",%%xmm5\n\t" \ + "paddw %%xmm6,%%xmm2\n\t" \ + "movdqa %%xmm2,"OC_MEM_OFFS(0x10,buf)"\n\t" \ + "movdqa "OC_MEM_OFFS(0x30,c)",%%xmm2\n\t" \ + "movdqa %%xmm7,"OC_MEM_OFFS(0x00,buf)"\n\t" \ + /*5-6 rotation by 3pi/16. \ + xmm5=C5, xmm2=C3, xmm3=X3, X5=0.*/ \ + "pmulhw %%xmm3,%%xmm5\n\t" \ + "pmulhw %%xmm3,%%xmm2\n\t" \ + "movdqa "OC_MEM_OFFS(0x10,c)",%%xmm7\n\t" \ + "paddw %%xmm3,%%xmm5\n\t" \ + "paddw %%xmm3,%%xmm2\n\t" \ + "movdqa "OC_MEM_OFFS(0x70,c)",%%xmm3\n\t" \ + /*4-7 rotation by 7pi/16. \ + xmm7=C1, xmm3=C7, xmm1=X1, X7=0.*/ \ + "pmulhw %%xmm1,%%xmm3\n\t" \ + "pmulhw %%xmm1,%%xmm7\n\t" \ + "movdqa "OC_MEM_OFFS(0x40,c)",%%xmm4\n\t" \ + "movdqa %%xmm3,%%xmm6\n\t" \ + "paddw %%xmm1,%%xmm7\n\t" \ + /*0-1 butterfly. \ + xmm4=C4, xmm0=X0, X4=0.*/ \ + /*Stage 2:*/ \ + /*4-5 butterfly: xmm3=t[4], xmm5=t[5] \ + 7-6 butterfly: xmm2=t[6], xmm7=t[7]*/ \ + "psubw %%xmm5,%%xmm3\n\t" \ + "paddw %%xmm5,%%xmm6\n\t" \ + "movdqa %%xmm4,%%xmm1\n\t" \ + "pmulhw %%xmm0,%%xmm4\n\t" \ + "paddw %%xmm0,%%xmm4\n\t" \ + "movdqa %%xmm7,%%xmm0\n\t" \ + "movdqa %%xmm4,%%xmm5\n\t" \ + "paddw %%xmm2,%%xmm0\n\t" \ + "psubw %%xmm2,%%xmm7\n\t" \ + "movdqa %%xmm1,%%xmm2\n\t" \ + "pmulhw %%xmm6,%%xmm1\n\t" \ + "pmulhw %%xmm7,%%xmm2\n\t" \ + "paddw %%xmm6,%%xmm1\n\t" \ + "movdqa "OC_MEM_OFFS(0x00,buf)",%%xmm6\n\t" \ + "paddw %%xmm7,%%xmm2\n\t" \ + "movdqa "OC_MEM_OFFS(0x10,buf)",%%xmm7\n\t" \ + /*Stage 3: \ + 6-5 butterfly: xmm1=t[5], xmm2=t[6] -> xmm1=t[6]+t[5], xmm2=t[6]-t[5] \ + 0-3 butterfly: xmm4=t[0], xmm7=t[3] -> xmm7=t[0]+t[3], xmm4=t[0]-t[3] \ + 1-2 butterfly: xmm5=t[1], xmm6=t[2] -> xmm6=t[1]+t[2], xmm5=t[1]-t[2]*/ \ + "paddw %%xmm2,%%xmm1\n\t" \ + "paddw %%xmm5,%%xmm6\n\t" \ + "paddw %%xmm4,%%xmm7\n\t" \ + "paddw %%xmm2,%%xmm2\n\t" \ + "paddw %%xmm4,%%xmm4\n\t" \ + "paddw %%xmm5,%%xmm5\n\t" \ + "psubw %%xmm1,%%xmm2\n\t" \ + "psubw %%xmm7,%%xmm4\n\t" \ + "psubw %%xmm6,%%xmm5\n\t" \ + +static void oc_idct8x8_10_sse2(ogg_int16_t _y[64],ogg_int16_t _x[64]){ + OC_ALIGN16(ogg_int16_t buf[16]); + /*This routine accepts an 8x8 matrix pre-transposed.*/ + __asm__ __volatile__( + "movq "OC_MEM_OFFS(0x20,x)",%%mm2\n\t" + "movq "OC_MEM_OFFS(0x30,x)",%%mm3\n\t" + "movq "OC_MEM_OFFS(0x10,x)",%%mm1\n\t" + "movq "OC_MEM_OFFS(0x00,x)",%%mm0\n\t" + OC_IDCT_8x8_10_MMX + OC_TRANSPOSE_8x4_MMX2SSE + OC_IDCT_8x8_10_ABC + OC_IDCT_8x8_D_STORE + :[buf]"=m"(OC_ARRAY_OPERAND(short,buf,16)), + [y]"=m"(OC_ARRAY_OPERAND(ogg_int16_t,_y,64)) + :[x]"m"OC_CONST_ARRAY_OPERAND(ogg_int16_t,_x,64), + [c]"m"(OC_CONST_ARRAY_OPERAND(ogg_int16_t,OC_IDCT_CONSTS,128)) + ); + /*Clear input data for next block (decoder only).*/ + __asm__ __volatile__( + "pxor %%mm0,%%mm0\n\t" + "movq %%mm0,"OC_MEM_OFFS(0x00,x)"\n\t" + "movq %%mm0,"OC_MEM_OFFS(0x10,x)"\n\t" + "movq %%mm0,"OC_MEM_OFFS(0x20,x)"\n\t" + "movq %%mm0,"OC_MEM_OFFS(0x30,x)"\n\t" + :[x]"+m"(OC_ARRAY_OPERAND(ogg_int16_t,_x,28)) + ); +} + +/*Performs an inverse 8x8 Type-II DCT transform. + The input is assumed to be scaled by a factor of 4 relative to orthonormal + version of the transform.*/ +void oc_idct8x8_sse2(ogg_int16_t _y[64],ogg_int16_t _x[64],int _last_zzi){ + /*_last_zzi is subtly different from an actual count of the number of + coefficients we decoded for this block. + It contains the value of zzi BEFORE the final token in the block was + decoded. + In most cases this is an EOB token (the continuation of an EOB run from a + previous block counts), and so this is the same as the coefficient count. + However, in the case that the last token was NOT an EOB token, but filled + the block up with exactly 64 coefficients, _last_zzi will be less than 64. + Provided the last token was not a pure zero run, the minimum value it can + be is 46, and so that doesn't affect any of the cases in this routine. + However, if the last token WAS a pure zero run of length 63, then _last_zzi + will be 1 while the number of coefficients decoded is 64. + Thus, we will trigger the following special case, where the real + coefficient count would not. + Note also that a zero run of length 64 will give _last_zzi a value of 0, + but we still process the DC coefficient, which might have a non-zero value + due to DC prediction. + Although convoluted, this is arguably the correct behavior: it allows us to + use a smaller transform when the block ends with a long zero run instead + of a normal EOB token. + It could be smarter... multiple separate zero runs at the end of a block + will fool it, but an encoder that generates these really deserves what it + gets. + Needless to say we inherited this approach from VP3.*/ + /*Then perform the iDCT.*/ + if(_last_zzi<=10)oc_idct8x8_10_sse2(_y,_x); + else oc_idct8x8_slow_sse2(_y,_x); +} + +#endif diff --git a/thirdparty/libtheora/x86/sse2trans.h b/thirdparty/libtheora/x86/sse2trans.h new file mode 100644 index 0000000000..e76da5140b --- /dev/null +++ b/thirdparty/libtheora/x86/sse2trans.h @@ -0,0 +1,242 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * + * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * + * * + ******************************************************************** + + function: + last mod: $Id: sse2trans.h 15675 2009-02-06 09:43:27Z tterribe $ + + ********************************************************************/ + +#if !defined(_x86_sse2trans_H) +# define _x86_sse2trans_H (1) +# include "x86int.h" + +# if defined(OC_X86_64_ASM) +/*On x86-64 we can transpose in-place without spilling registers. + By clever choices of the order to apply the butterflies and the order of + their outputs, we can take the rows in order and output the columns in order + without any extra operations and using just one temporary register.*/ +# define OC_TRANSPOSE_8x8 \ + "#OC_TRANSPOSE_8x8\n\t" \ + "movdqa %%xmm4,%%xmm8\n\t" \ + /*xmm4 = f3 e3 f2 e2 f1 e1 f0 e0*/ \ + "punpcklwd %%xmm5,%%xmm4\n\t" \ + /*xmm8 = f7 e7 f6 e6 f5 e5 f4 e4*/ \ + "punpckhwd %%xmm5,%%xmm8\n\t" \ + /*xmm5 is free.*/ \ + "movdqa %%xmm0,%%xmm5\n\t" \ + /*xmm0 = b3 a3 b2 a2 b1 a1 b0 a0*/ \ + "punpcklwd %%xmm1,%%xmm0\n\t" \ + /*xmm5 = b7 a7 b6 a6 b5 a5 b4 a4*/ \ + "punpckhwd %%xmm1,%%xmm5\n\t" \ + /*xmm1 is free.*/ \ + "movdqa %%xmm6,%%xmm1\n\t" \ + /*xmm6 = h3 g3 h2 g2 h1 g1 h0 g0*/ \ + "punpcklwd %%xmm7,%%xmm6\n\t" \ + /*xmm1 = h7 g7 h6 g6 h5 g5 h4 g4*/ \ + "punpckhwd %%xmm7,%%xmm1\n\t" \ + /*xmm7 is free.*/ \ + "movdqa %%xmm2,%%xmm7\n\t" \ + /*xmm2 = d7 c7 d6 c6 d5 c5 d4 c4*/ \ + "punpckhwd %%xmm3,%%xmm2\n\t" \ + /*xmm7 = d3 c3 d2 c2 d1 c1 d0 c0*/ \ + "punpcklwd %%xmm3,%%xmm7\n\t" \ + /*xmm3 is free.*/ \ + "movdqa %%xmm0,%%xmm3\n\t" \ + /*xmm0 = d1 c1 b1 a1 d0 c0 b0 a0*/ \ + "punpckldq %%xmm7,%%xmm0\n\t" \ + /*xmm3 = d3 c3 b3 a3 d2 c2 b2 a2*/ \ + "punpckhdq %%xmm7,%%xmm3\n\t" \ + /*xmm7 is free.*/ \ + "movdqa %%xmm5,%%xmm7\n\t" \ + /*xmm5 = d5 c5 b5 a5 d4 c4 b4 a4*/ \ + "punpckldq %%xmm2,%%xmm5\n\t" \ + /*xmm7 = d7 c7 b7 a7 d6 c6 b6 a6*/ \ + "punpckhdq %%xmm2,%%xmm7\n\t" \ + /*xmm2 is free.*/ \ + "movdqa %%xmm4,%%xmm2\n\t" \ + /*xmm4 = h3 g3 f3 e3 h2 g2 f2 e2*/ \ + "punpckhdq %%xmm6,%%xmm4\n\t" \ + /*xmm2 = h1 g1 f1 e1 h0 g0 f0 e0*/ \ + "punpckldq %%xmm6,%%xmm2\n\t" \ + /*xmm6 is free.*/ \ + "movdqa %%xmm8,%%xmm6\n\t" \ + /*xmm6 = h5 g5 f5 e5 h4 g4 f4 e4*/ \ + "punpckldq %%xmm1,%%xmm6\n\t" \ + /*xmm8 = h7 g7 f7 e7 h6 g6 f6 e6*/ \ + "punpckhdq %%xmm1,%%xmm8\n\t" \ + /*xmm1 is free.*/ \ + "movdqa %%xmm0,%%xmm1\n\t" \ + /*xmm0 = h0 g0 f0 e0 d0 c0 b0 a0*/ \ + "punpcklqdq %%xmm2,%%xmm0\n\t" \ + /*xmm1 = h1 g1 f1 e1 d1 c1 b1 a1*/ \ + "punpckhqdq %%xmm2,%%xmm1\n\t" \ + /*xmm2 is free.*/ \ + "movdqa %%xmm3,%%xmm2\n\t" \ + /*xmm3 = h3 g3 f3 e3 d3 c3 b3 a3*/ \ + "punpckhqdq %%xmm4,%%xmm3\n\t" \ + /*xmm2 = h2 g2 f2 e2 d2 c2 b2 a2*/ \ + "punpcklqdq %%xmm4,%%xmm2\n\t" \ + /*xmm4 is free.*/ \ + "movdqa %%xmm5,%%xmm4\n\t" \ + /*xmm5 = h5 g5 f5 e5 d5 c5 b5 a5*/ \ + "punpckhqdq %%xmm6,%%xmm5\n\t" \ + /*xmm4 = h4 g4 f4 e4 d4 c4 b4 a4*/ \ + "punpcklqdq %%xmm6,%%xmm4\n\t" \ + /*xmm6 is free.*/ \ + "movdqa %%xmm7,%%xmm6\n\t" \ + /*xmm7 = h7 g7 f7 e7 d7 c7 b7 a7*/ \ + "punpckhqdq %%xmm8,%%xmm7\n\t" \ + /*xmm6 = h6 g6 f6 e6 d6 c6 b6 a6*/ \ + "punpcklqdq %%xmm8,%%xmm6\n\t" \ + /*xmm8 is free.*/ \ + +# else +/*Otherwise, we need to spill some values to %[buf] temporarily. + Again, the butterflies are carefully arranged to get the columns to come out + in order, minimizing register spills and maximizing the delay between a load + and when the value loaded is actually used.*/ +# define OC_TRANSPOSE_8x8 \ + "#OC_TRANSPOSE_8x8\n\t" \ + /*buf[0] = a7 a6 a5 a4 a3 a2 a1 a0*/ \ + "movdqa %%xmm0,"OC_MEM_OFFS(0x00,buf)"\n\t" \ + /*xmm0 is free.*/ \ + "movdqa %%xmm2,%%xmm0\n\t" \ + /*xmm2 = d7 c7 d6 c6 d5 c5 d4 c4*/ \ + "punpckhwd %%xmm3,%%xmm2\n\t" \ + /*xmm0 = d3 c3 d2 c2 d1 c1 d0 c0*/ \ + "punpcklwd %%xmm3,%%xmm0\n\t" \ + /*xmm3 = a7 a6 a5 a4 a3 a2 a1 a0*/ \ + "movdqa "OC_MEM_OFFS(0x00,buf)",%%xmm3\n\t" \ + /*buf[1] = d7 c7 d6 c6 d5 c5 d4 c4*/ \ + "movdqa %%xmm2,"OC_MEM_OFFS(0x10,buf)"\n\t" \ + /*xmm2 is free.*/ \ + "movdqa %%xmm6,%%xmm2\n\t" \ + /*xmm6 = h3 g3 h2 g2 h1 g1 h0 g0*/ \ + "punpcklwd %%xmm7,%%xmm6\n\t" \ + /*xmm2 = h7 g7 h6 g6 h5 g5 h4 g4*/ \ + "punpckhwd %%xmm7,%%xmm2\n\t" \ + /*xmm7 is free.*/ \ + "movdqa %%xmm4,%%xmm7\n\t" \ + /*xmm4 = f3 e3 f2 e2 f1 e1 f0 e0*/ \ + "punpcklwd %%xmm5,%%xmm4\n\t" \ + /*xmm7 = f7 e7 f6 e6 f5 e5 f4 e4*/ \ + "punpckhwd %%xmm5,%%xmm7\n\t" \ + /*xmm5 is free.*/ \ + "movdqa %%xmm3,%%xmm5\n\t" \ + /*xmm3 = b3 a3 b2 a2 b1 a1 b0 a0*/ \ + "punpcklwd %%xmm1,%%xmm3\n\t" \ + /*xmm5 = b7 a7 b6 a6 b5 a5 b4 a4*/ \ + "punpckhwd %%xmm1,%%xmm5\n\t" \ + /*xmm1 is free.*/ \ + "movdqa %%xmm7,%%xmm1\n\t" \ + /*xmm7 = h5 g5 f5 e5 h4 g4 f4 e4*/ \ + "punpckldq %%xmm2,%%xmm7\n\t" \ + /*xmm1 = h7 g7 f7 e7 h6 g6 f6 e6*/ \ + "punpckhdq %%xmm2,%%xmm1\n\t" \ + /*xmm2 = d7 c7 d6 c6 d5 c5 d4 c4*/ \ + "movdqa "OC_MEM_OFFS(0x10,buf)",%%xmm2\n\t" \ + /*buf[0] = h7 g7 f7 e7 h6 g6 f6 e6*/ \ + "movdqa %%xmm1,"OC_MEM_OFFS(0x00,buf)"\n\t" \ + /*xmm1 is free.*/ \ + "movdqa %%xmm3,%%xmm1\n\t" \ + /*xmm3 = d3 c3 b3 a3 d2 c2 b2 a2*/ \ + "punpckhdq %%xmm0,%%xmm3\n\t" \ + /*xmm1 = d1 c1 b1 a1 d0 c0 b0 a0*/ \ + "punpckldq %%xmm0,%%xmm1\n\t" \ + /*xmm0 is free.*/ \ + "movdqa %%xmm4,%%xmm0\n\t" \ + /*xmm4 = h3 g3 f3 e3 h2 g2 f2 e2*/ \ + "punpckhdq %%xmm6,%%xmm4\n\t" \ + /*xmm0 = h1 g1 f1 e1 h0 g0 f0 e0*/ \ + "punpckldq %%xmm6,%%xmm0\n\t" \ + /*xmm6 is free.*/ \ + "movdqa %%xmm5,%%xmm6\n\t" \ + /*xmm5 = d5 c5 b5 a5 d4 c4 b4 a4*/ \ + "punpckldq %%xmm2,%%xmm5\n\t" \ + /*xmm6 = d7 c7 b7 a7 d6 c6 b6 a6*/ \ + "punpckhdq %%xmm2,%%xmm6\n\t" \ + /*xmm2 is free.*/ \ + "movdqa %%xmm1,%%xmm2\n\t" \ + /*xmm1 = h1 g1 f1 e1 d1 c1 b1 a1*/ \ + "punpckhqdq %%xmm0,%%xmm1\n\t" \ + /*xmm2 = h0 g0 f0 e0 d0 c0 b0 a0*/ \ + "punpcklqdq %%xmm0,%%xmm2\n\t" \ + /*xmm0 = h7 g7 f7 e7 h6 g6 f6 e6*/ \ + "movdqa "OC_MEM_OFFS(0x00,buf)",%%xmm0\n\t" \ + /*buf[1] = h0 g0 f0 e0 d0 c0 b0 a0*/ \ + "movdqa %%xmm2,"OC_MEM_OFFS(0x10,buf)"\n\t" \ + /*xmm2 is free.*/ \ + "movdqa %%xmm3,%%xmm2\n\t" \ + /*xmm3 = h3 g3 f3 e3 d3 c3 b3 a3*/ \ + "punpckhqdq %%xmm4,%%xmm3\n\t" \ + /*xmm2 = h2 g2 f2 e2 d2 c2 b2 a2*/ \ + "punpcklqdq %%xmm4,%%xmm2\n\t" \ + /*xmm4 is free.*/ \ + "movdqa %%xmm5,%%xmm4\n\t" \ + /*xmm5 = h5 g5 f5 e5 d5 c5 b5 a5*/ \ + "punpckhqdq %%xmm7,%%xmm5\n\t" \ + /*xmm4 = h4 g4 f4 e4 d4 c4 b4 a4*/ \ + "punpcklqdq %%xmm7,%%xmm4\n\t" \ + /*xmm7 is free.*/ \ + "movdqa %%xmm6,%%xmm7\n\t" \ + /*xmm6 = h6 g6 f6 e6 d6 c6 b6 a6*/ \ + "punpcklqdq %%xmm0,%%xmm6\n\t" \ + /*xmm7 = h7 g7 f7 e7 d7 c7 b7 a7*/ \ + "punpckhqdq %%xmm0,%%xmm7\n\t" \ + /*xmm0 = h0 g0 f0 e0 d0 c0 b0 a0*/ \ + "movdqa "OC_MEM_OFFS(0x10,buf)",%%xmm0\n\t" \ + +# endif + +/*Transpose 4 values in each of 8 MMX registers into 8 values in the first + four SSE registers. + No need to be clever here; we have plenty of room.*/ +# define OC_TRANSPOSE_8x4_MMX2SSE \ + "#OC_TRANSPOSE_8x4_MMX2SSE\n\t" \ + "movq2dq %%mm0,%%xmm0\n\t" \ + "movq2dq %%mm1,%%xmm1\n\t" \ + /*xmmA = b3 a3 b2 a2 b1 a1 b0 a0*/ \ + "punpcklwd %%xmm1,%%xmm0\n\t" \ + "movq2dq %%mm2,%%xmm3\n\t" \ + "movq2dq %%mm3,%%xmm2\n\t" \ + /*xmmC = d3 c3 d2 c2 d1 c1 d0 c0*/ \ + "punpcklwd %%xmm2,%%xmm3\n\t" \ + "movq2dq %%mm4,%%xmm4\n\t" \ + "movq2dq %%mm5,%%xmm5\n\t" \ + /*xmmE = f3 e3 f2 e2 f1 e1 f0 e0*/ \ + "punpcklwd %%xmm5,%%xmm4\n\t" \ + "movq2dq %%mm6,%%xmm7\n\t" \ + "movq2dq %%mm7,%%xmm6\n\t" \ + /*xmmG = h3 g3 h2 g2 h1 g1 h0 g0*/ \ + "punpcklwd %%xmm6,%%xmm7\n\t" \ + "movdqa %%xmm0,%%xmm2\n\t" \ + /*xmm0 = d1 c1 b1 a1 d0 c0 b0 a0*/ \ + "punpckldq %%xmm3,%%xmm0\n\t" \ + /*xmm2 = d3 c3 b3 a3 d2 c2 b2 a2*/ \ + "punpckhdq %%xmm3,%%xmm2\n\t" \ + "movdqa %%xmm4,%%xmm5\n\t" \ + /*xmm4 = h1 g1 f1 e1 h0 g0 f0 e0*/ \ + "punpckldq %%xmm7,%%xmm4\n\t" \ + /*xmm3 = h3 g3 f3 e3 h2 g2 f2 e2*/ \ + "punpckhdq %%xmm7,%%xmm5\n\t" \ + "movdqa %%xmm0,%%xmm1\n\t" \ + /*xmm0 = h0 g0 f0 e0 d0 c0 b0 a0*/ \ + "punpcklqdq %%xmm4,%%xmm0\n\t" \ + /*xmm1 = h1 g1 f1 e1 d1 c1 b1 a1*/ \ + "punpckhqdq %%xmm4,%%xmm1\n\t" \ + "movdqa %%xmm2,%%xmm3\n\t" \ + /*xmm2 = h2 g2 f2 e2 d2 c2 b2 a2*/ \ + "punpcklqdq %%xmm5,%%xmm2\n\t" \ + /*xmm3 = h3 g3 f3 e3 d3 c3 b3 a3*/ \ + "punpckhqdq %%xmm5,%%xmm3\n\t" \ + +#endif diff --git a/thirdparty/libtheora/x86/x86cpu.c b/thirdparty/libtheora/x86/x86cpu.c new file mode 100644 index 0000000000..49fd76d0ac --- /dev/null +++ b/thirdparty/libtheora/x86/x86cpu.c @@ -0,0 +1,182 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * + * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * + * * + ******************************************************************** + + CPU capability detection for x86 processors. + Originally written by Rudolf Marek. + + function: + last mod: $Id$ + + ********************************************************************/ + +#include "x86cpu.h" + +#if !defined(OC_X86_ASM) +ogg_uint32_t oc_cpu_flags_get(void){ + return 0; +} +#else +# if defined(__amd64__)||defined(__x86_64__) +/*On x86-64, gcc seems to be able to figure out how to save %rbx for us when + compiling with -fPIC.*/ +# define cpuid(_op,_eax,_ebx,_ecx,_edx) \ + __asm__ __volatile__( \ + "cpuid\n\t" \ + :[eax]"=a"(_eax),[ebx]"=b"(_ebx),[ecx]"=c"(_ecx),[edx]"=d"(_edx) \ + :"a"(_op) \ + :"cc" \ + ) +# else +/*On x86-32, not so much.*/ +# define cpuid(_op,_eax,_ebx,_ecx,_edx) \ + __asm__ __volatile__( \ + "xchgl %%ebx,%[ebx]\n\t" \ + "cpuid\n\t" \ + "xchgl %%ebx,%[ebx]\n\t" \ + :[eax]"=a"(_eax),[ebx]"=r"(_ebx),[ecx]"=c"(_ecx),[edx]"=d"(_edx) \ + :"a"(_op) \ + :"cc" \ + ) +# endif + +static ogg_uint32_t oc_parse_intel_flags(ogg_uint32_t _edx,ogg_uint32_t _ecx){ + ogg_uint32_t flags; + /*If there isn't even MMX, give up.*/ + if(!(_edx&0x00800000))return 0; + flags=OC_CPU_X86_MMX; + if(_edx&0x02000000)flags|=OC_CPU_X86_MMXEXT|OC_CPU_X86_SSE; + if(_edx&0x04000000)flags|=OC_CPU_X86_SSE2; + if(_ecx&0x00000001)flags|=OC_CPU_X86_PNI; + if(_ecx&0x00000100)flags|=OC_CPU_X86_SSSE3; + if(_ecx&0x00080000)flags|=OC_CPU_X86_SSE4_1; + if(_ecx&0x00100000)flags|=OC_CPU_X86_SSE4_2; + return flags; +} + +static ogg_uint32_t oc_parse_amd_flags(ogg_uint32_t _edx,ogg_uint32_t _ecx){ + ogg_uint32_t flags; + /*If there isn't even MMX, give up.*/ + if(!(_edx&0x00800000))return 0; + flags=OC_CPU_X86_MMX; + if(_edx&0x00400000)flags|=OC_CPU_X86_MMXEXT; + if(_edx&0x80000000)flags|=OC_CPU_X86_3DNOW; + if(_edx&0x40000000)flags|=OC_CPU_X86_3DNOWEXT; + if(_ecx&0x00000040)flags|=OC_CPU_X86_SSE4A; + if(_ecx&0x00000800)flags|=OC_CPU_X86_SSE5; + return flags; +} + +ogg_uint32_t oc_cpu_flags_get(void){ + ogg_uint32_t flags; + ogg_uint32_t eax; + ogg_uint32_t ebx; + ogg_uint32_t ecx; + ogg_uint32_t edx; +# if !defined(__amd64__)&&!defined(__x86_64__) + /*Not all x86-32 chips support cpuid, so we have to check.*/ + __asm__ __volatile__( + "pushfl\n\t" + "pushfl\n\t" + "popl %[a]\n\t" + "movl %[a],%[b]\n\t" + "xorl $0x200000,%[a]\n\t" + "pushl %[a]\n\t" + "popfl\n\t" + "pushfl\n\t" + "popl %[a]\n\t" + "popfl\n\t" + :[a]"=r"(eax),[b]"=r"(ebx) + : + :"cc" + ); + /*No cpuid.*/ + if(eax==ebx)return 0; +# endif + cpuid(0,eax,ebx,ecx,edx); + /* l e t n I e n i u n e G*/ + if(ecx==0x6C65746E&&edx==0x49656E69&&ebx==0x756E6547|| + /* 6 8 x M T e n i u n e G*/ + ecx==0x3638784D&&edx==0x54656E69&&ebx==0x756E6547){ + int family; + int model; + /*Intel, Transmeta (tested with Crusoe TM5800):*/ + cpuid(1,eax,ebx,ecx,edx); + flags=oc_parse_intel_flags(edx,ecx); + family=(eax>>8)&0xF; + model=(eax>>4)&0xF; + /*The SSE unit on the Pentium M and Core Duo is much slower than the MMX + unit, so don't use it.*/ + if(family==6&&(model==9||model==13||model==14)){ + flags&=~(OC_CPU_X86_SSE2|OC_CPU_X86_PNI); + } + } + /* D M A c i t n e h t u A*/ + else if(ecx==0x444D4163&&edx==0x69746E65&&ebx==0x68747541|| + /* C S N y b e d o e G*/ + ecx==0x43534e20&&edx==0x79622065&&ebx==0x646f6547){ + /*AMD, Geode:*/ + cpuid(0x80000000,eax,ebx,ecx,edx); + if(eax<0x80000001)flags=0; + else{ + cpuid(0x80000001,eax,ebx,ecx,edx); + flags=oc_parse_amd_flags(edx,ecx); + } + /*Also check for SSE.*/ + cpuid(1,eax,ebx,ecx,edx); + flags|=oc_parse_intel_flags(edx,ecx); + } + /*Technically some VIA chips can be configured in the BIOS to return any + string here the user wants. + There is a special detection method that can be used to identify such + processors, but in my opinion, if the user really wants to change it, they + deserve what they get.*/ + /* s l u a H r u a t n e C*/ + else if(ecx==0x736C7561&&edx==0x48727561&&ebx==0x746E6543){ + /*VIA:*/ + /*I only have documentation for the C7 (Esther) and Isaiah (forthcoming) + chips (thanks to the engineers from Centaur Technology who provided it). + These chips support Intel-like cpuid info. + The C3-2 (Nehemiah) cores appear to, as well.*/ + cpuid(1,eax,ebx,ecx,edx); + flags=oc_parse_intel_flags(edx,ecx); + if(eax>=0x80000001){ + /*The (non-Nehemiah) C3 processors support AMD-like cpuid info. + We need to check this even if the Intel test succeeds to pick up 3DNow! + support on these processors. + Unlike actual AMD processors, we cannot _rely_ on this info, since + some cores (e.g., the 693 stepping of the Nehemiah) claim to support + this function, yet return edx=0, despite the Intel test indicating + MMX support. + Therefore the features detected here are strictly added to those + detected by the Intel test.*/ + /*TODO: How about earlier chips?*/ + cpuid(0x80000001,eax,ebx,ecx,edx); + /*Note: As of the C7, this function returns Intel-style extended feature + flags, not AMD-style. + Currently, this only defines bits 11, 20, and 29 (0x20100800), which + do not conflict with any of the AMD flags we inspect. + For the remaining bits, Intel tells us, "Do not count on their value", + but VIA assures us that they will all be zero (at least on the C7 and + Isaiah chips). + In the (unlikely) event a future processor uses bits 18, 19, 30, or 31 + (0xC0C00000) for something else, we will have to add code to detect + the model to decide when it is appropriate to inspect them.*/ + flags|=oc_parse_amd_flags(edx,ecx); + } + } + else{ + /*Implement me.*/ + flags=0; + } + return flags; +} +#endif diff --git a/thirdparty/libtheora/cpu.h b/thirdparty/libtheora/x86/x86cpu.h index a43c957a39..e0192d52e2 100644 --- a/thirdparty/libtheora/cpu.h +++ b/thirdparty/libtheora/x86/x86cpu.h @@ -10,13 +10,13 @@ * * ******************************************************************** function: - last mod: $Id: cpu.h 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ -#if !defined(_x86_cpu_H) -# define _x86_cpu_H (1) -#include "internal.h" +#if !defined(_x86_x86cpu_H) +# define _x86_x86cpu_H (1) +#include "../internal.h" #define OC_CPU_X86_MMX (1<<0) #define OC_CPU_X86_3DNOW (1<<1) @@ -31,4 +31,6 @@ #define OC_CPU_X86_SSE4A (1<<10) #define OC_CPU_X86_SSE5 (1<<11) +ogg_uint32_t oc_cpu_flags_get(void); + #endif diff --git a/thirdparty/libtheora/x86/x86enc.c b/thirdparty/libtheora/x86/x86enc.c index 43b7be3ea3..ffa9c14a42 100644 --- a/thirdparty/libtheora/x86/x86enc.c +++ b/thirdparty/libtheora/x86/x86enc.c @@ -18,32 +18,46 @@ #if defined(OC_X86_ASM) -#include "../cpu.c" - -void oc_enc_vtable_init_x86(oc_enc_ctx *_enc){ +void oc_enc_accel_init_x86(oc_enc_ctx *_enc){ ogg_uint32_t cpu_flags; - cpu_flags=oc_cpu_flags_get(); - oc_enc_vtable_init_c(_enc); + cpu_flags=_enc->state.cpu_flags; + oc_enc_accel_init_c(_enc); +# if defined(OC_ENC_USE_VTABLE) if(cpu_flags&OC_CPU_X86_MMX){ _enc->opt_vtable.frag_sub=oc_enc_frag_sub_mmx; _enc->opt_vtable.frag_sub_128=oc_enc_frag_sub_128_mmx; _enc->opt_vtable.frag_recon_intra=oc_frag_recon_intra_mmx; _enc->opt_vtable.frag_recon_inter=oc_frag_recon_inter_mmx; - _enc->opt_vtable.fdct8x8=oc_enc_fdct8x8_mmx; } if(cpu_flags&OC_CPU_X86_MMXEXT){ _enc->opt_vtable.frag_sad=oc_enc_frag_sad_mmxext; _enc->opt_vtable.frag_sad_thresh=oc_enc_frag_sad_thresh_mmxext; _enc->opt_vtable.frag_sad2_thresh=oc_enc_frag_sad2_thresh_mmxext; - _enc->opt_vtable.frag_satd_thresh=oc_enc_frag_satd_thresh_mmxext; - _enc->opt_vtable.frag_satd2_thresh=oc_enc_frag_satd2_thresh_mmxext; + _enc->opt_vtable.frag_satd=oc_enc_frag_satd_mmxext; + _enc->opt_vtable.frag_satd2=oc_enc_frag_satd2_mmxext; _enc->opt_vtable.frag_intra_satd=oc_enc_frag_intra_satd_mmxext; _enc->opt_vtable.frag_copy2=oc_enc_frag_copy2_mmxext; + _enc->opt_vtable.fdct8x8=oc_enc_fdct8x8_mmxext; } if(cpu_flags&OC_CPU_X86_SSE2){ -# if defined(OC_X86_64_ASM) - /*_enc->opt_vtable.fdct8x8=oc_enc_fdct8x8_x86_64sse2;*/ +# if defined(OC_X86_64_ASM) + _enc->opt_vtable.fdct8x8=oc_enc_fdct8x8_x86_64sse2; +# endif + _enc->opt_vtable.frag_ssd=oc_enc_frag_ssd_sse2; + _enc->opt_vtable.frag_border_ssd=oc_enc_frag_border_ssd_sse2; + _enc->opt_vtable.frag_satd=oc_enc_frag_satd_sse2; + _enc->opt_vtable.frag_satd2=oc_enc_frag_satd2_sse2; + _enc->opt_vtable.frag_intra_satd=oc_enc_frag_intra_satd_sse2; + _enc->opt_vtable.enquant_table_init=oc_enc_enquant_table_init_x86; + _enc->opt_vtable.enquant_table_fixup=oc_enc_enquant_table_fixup_x86; + _enc->opt_vtable.quantize=oc_enc_quantize_sse2; +# else + (void) cpu_flags; # endif + _enc->opt_data.enquant_table_size=128*sizeof(ogg_uint16_t); + _enc->opt_data.enquant_table_alignment=16; +# if defined(OC_ENC_USE_VTABLE) } +# endif } #endif diff --git a/thirdparty/libtheora/x86/x86enc.h b/thirdparty/libtheora/x86/x86enc.h index 06c3908bcd..c258247d67 100644 --- a/thirdparty/libtheora/x86/x86enc.h +++ b/thirdparty/libtheora/x86/x86enc.h @@ -17,11 +17,62 @@ #if !defined(_x86_x86enc_H) # define _x86_x86enc_H (1) -# include "../encint.h" # include "x86int.h" -void oc_enc_vtable_init_x86(oc_enc_ctx *_enc); +# if defined(OC_X86_ASM) +# define oc_enc_accel_init oc_enc_accel_init_x86 +# if defined(OC_X86_64_ASM) +/*x86-64 guarantees SIMD support up through at least SSE2. + If the best routine we have available only needs SSE2 (which at the moment + covers all of them), then we can avoid runtime detection and the indirect + call.*/ +# define oc_enc_frag_sub(_enc,_diff,_x,_y,_stride) \ + oc_enc_frag_sub_mmx(_diff,_x,_y,_stride) +# define oc_enc_frag_sub_128(_enc,_diff,_x,_stride) \ + oc_enc_frag_sub_128_mmx(_diff,_x,_stride) +# define oc_enc_frag_sad(_enc,_src,_ref,_ystride) \ + oc_enc_frag_sad_mmxext(_src,_ref,_ystride) +# define oc_enc_frag_sad_thresh(_enc,_src,_ref,_ystride,_thresh) \ + oc_enc_frag_sad_thresh_mmxext(_src,_ref,_ystride,_thresh) +# define oc_enc_frag_sad2_thresh(_enc,_src,_ref1,_ref2,_ystride,_thresh) \ + oc_enc_frag_sad2_thresh_mmxext(_src,_ref1,_ref2,_ystride,_thresh) +# define oc_enc_frag_satd(_enc,_dc,_src,_ref,_ystride) \ + oc_enc_frag_satd_sse2(_dc,_src,_ref,_ystride) +# define oc_enc_frag_satd2(_enc,_dc,_src,_ref1,_ref2,_ystride) \ + oc_enc_frag_satd2_sse2(_dc,_src,_ref1,_ref2,_ystride) +# define oc_enc_frag_intra_satd(_enc,_dc,_src,_ystride) \ + oc_enc_frag_intra_satd_sse2(_dc,_src,_ystride) +# define oc_enc_frag_ssd(_enc,_src,_ref,_ystride) \ + oc_enc_frag_ssd_sse2(_src,_ref,_ystride) +# define oc_enc_frag_border_ssd(_enc,_src,_ref,_ystride,_mask) \ + oc_enc_frag_border_ssd_sse2(_src,_ref,_ystride,_mask) +# define oc_enc_frag_copy2(_enc,_dst,_src1,_src2,_ystride) \ + oc_int_frag_copy2_mmxext(_dst,_ystride,_src1,_src2,_ystride) +# define oc_enc_enquant_table_init(_enc,_enquant,_dequant) \ + oc_enc_enquant_table_init_x86(_enquant,_dequant) +# define oc_enc_enquant_table_fixup(_enc,_enquant,_nqis) \ + oc_enc_enquant_table_fixup_x86(_enquant,_nqis) +# define oc_enc_quantize(_enc,_qdct,_dct,_dequant,_enquant) \ + oc_enc_quantize_sse2(_qdct,_dct,_dequant,_enquant) +# define oc_enc_frag_recon_intra(_enc,_dst,_ystride,_residue) \ + oc_frag_recon_intra_mmx(_dst,_ystride,_residue) +# define oc_enc_frag_recon_inter(_enc,_dst,_src,_ystride,_residue) \ + oc_frag_recon_inter_mmx(_dst,_src,_ystride,_residue) +# define oc_enc_fdct8x8(_enc,_y,_x) \ + oc_enc_fdct8x8_x86_64sse2(_y,_x) +# else +# define OC_ENC_USE_VTABLE (1) +# endif +# endif + +# include "../encint.h" +void oc_enc_accel_init_x86(oc_enc_ctx *_enc); + +void oc_enc_frag_sub_mmx(ogg_int16_t _diff[64], + const unsigned char *_x,const unsigned char *_y,int _stride); +void oc_enc_frag_sub_128_mmx(ogg_int16_t _diff[64], + const unsigned char *_x,int _stride); unsigned oc_enc_frag_sad_mmxext(const unsigned char *_src, const unsigned char *_ref,int _ystride); unsigned oc_enc_frag_sad_thresh_mmxext(const unsigned char *_src, @@ -29,19 +80,35 @@ unsigned oc_enc_frag_sad_thresh_mmxext(const unsigned char *_src, unsigned oc_enc_frag_sad2_thresh_mmxext(const unsigned char *_src, const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, unsigned _thresh); -unsigned oc_enc_frag_satd_thresh_mmxext(const unsigned char *_src, - const unsigned char *_ref,int _ystride,unsigned _thresh); -unsigned oc_enc_frag_satd2_thresh_mmxext(const unsigned char *_src, - const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, - unsigned _thresh); -unsigned oc_enc_frag_intra_satd_mmxext(const unsigned char *_src,int _ystride); -void oc_enc_frag_sub_mmx(ogg_int16_t _diff[64], - const unsigned char *_x,const unsigned char *_y,int _stride); -void oc_enc_frag_sub_128_mmx(ogg_int16_t _diff[64], - const unsigned char *_x,int _stride); +unsigned oc_enc_frag_satd_mmxext(int *_dc,const unsigned char *_src, + const unsigned char *_ref,int _ystride); +unsigned oc_enc_frag_satd_sse2(int *_dc,const unsigned char *_src, + const unsigned char *_ref,int _ystride); +unsigned oc_enc_frag_satd2_mmxext(int *_dc,const unsigned char *_src, + const unsigned char *_ref1,const unsigned char *_ref2,int _ystride); +unsigned oc_enc_frag_satd2_sse2(int *_dc,const unsigned char *_src, + const unsigned char *_ref1,const unsigned char *_ref2,int _ystride); +unsigned oc_enc_frag_intra_satd_mmxext(int *_dc, + const unsigned char *_src,int _ystride); +unsigned oc_enc_frag_intra_satd_sse2(int *_dc, + const unsigned char *_src,int _ystride); +unsigned oc_enc_frag_ssd_sse2(const unsigned char *_src, + const unsigned char *_ref,int _ystride); +unsigned oc_enc_frag_border_ssd_sse2(const unsigned char *_src, + const unsigned char *_ref,int _ystride,ogg_int64_t _mask); +void oc_int_frag_copy2_mmxext(unsigned char *_dst,int _dst_ystride, + const unsigned char *_src1,const unsigned char *_src2,int _src_ystride); void oc_enc_frag_copy2_mmxext(unsigned char *_dst, const unsigned char *_src1,const unsigned char *_src2,int _ystride); -void oc_enc_fdct8x8_mmx(ogg_int16_t _y[64],const ogg_int16_t _x[64]); +void oc_enc_enquant_table_init_x86(void *_enquant, + const ogg_uint16_t _dequant[64]); +void oc_enc_enquant_table_fixup_x86(void *_enquant[3][3][2],int _nqis); +int oc_enc_quantize_sse2(ogg_int16_t _qdct[64],const ogg_int16_t _dct[64], + const ogg_uint16_t _dequant[64],const void *_enquant); +void oc_enc_fdct8x8_mmxext(ogg_int16_t _y[64],const ogg_int16_t _x[64]); + +# if defined(OC_X86_64_ASM) void oc_enc_fdct8x8_x86_64sse2(ogg_int16_t _y[64],const ogg_int16_t _x[64]); +# endif #endif diff --git a/thirdparty/libtheora/x86/x86enquant.c b/thirdparty/libtheora/x86/x86enquant.c new file mode 100644 index 0000000000..39477ecc21 --- /dev/null +++ b/thirdparty/libtheora/x86/x86enquant.c @@ -0,0 +1,149 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * + * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * + * * + ******************************************************************** + + function: + last mod: $Id: mmxstate.c 17247 2010-05-28 05:35:32Z tterribe $ + + ********************************************************************/ + +#include "x86enc.h" + +#if defined(OC_X86_ASM) + + + +/*The default enquant table is not quite suitable for SIMD purposes. + First, the m and l parameters need to be separated so that an entire row full + of m's or l's can be loaded at a time. + Second, x86 SIMD has no element-wise arithmetic right-shift, so we have to + emulate one with a multiply. + Therefore we translate the shift count into a scale factor.*/ +void oc_enc_enquant_table_init_x86(void *_enquant, + const ogg_uint16_t _dequant[64]){ + ogg_int16_t *m; + ogg_int16_t *l; + int zzi; + m=(ogg_int16_t *)_enquant; + l=m+64; + for(zzi=0;zzi<64;zzi++){ + oc_iquant q; + oc_iquant_init(&q,_dequant[zzi]); + m[zzi]=q.m; + /*q.l must be at least 2 for this to work; fortunately, once all the scale + factors are baked in, the minimum quantizer is much larger than that.*/ + l[zzi]=1<<16-q.l; + } +} + +void oc_enc_enquant_table_fixup_x86(void *_enquant[3][3][2],int _nqis){ + int pli; + int qii; + int qti; + for(pli=0;pli<3;pli++)for(qii=1;qii<_nqis;qii++)for(qti=0;qti<2;qti++){ + ((ogg_int16_t *)_enquant[pli][qii][qti])[0]= + ((ogg_int16_t *)_enquant[pli][0][qti])[0]; + ((ogg_int16_t *)_enquant[pli][qii][qti])[64]= + ((ogg_int16_t *)_enquant[pli][0][qti])[64]; + } +} + +int oc_enc_quantize_sse2(ogg_int16_t _qdct[64],const ogg_int16_t _dct[64], + const ogg_uint16_t _dequant[64],const void *_enquant){ + ptrdiff_t r; + __asm__ __volatile__( + "xor %[r],%[r]\n\t" + /*Loop through two rows at a time.*/ + ".p2align 4\n\t" + "0:\n\t" + /*Load the first two rows of the data and the quant matrices.*/ + "movdqa 0x00(%[dct],%[r]),%%xmm0\n\t" + "movdqa 0x10(%[dct],%[r]),%%xmm1\n\t" + "movdqa 0x00(%[dq],%[r]),%%xmm2\n\t" + "movdqa 0x10(%[dq],%[r]),%%xmm3\n\t" + "movdqa 0x00(%[q],%[r]),%%xmm4\n\t" + "movdqa 0x10(%[q],%[r]),%%xmm5\n\t" + /*Double the input and propagate its sign to the rounding factor. + Using SSSE3's psignw would help here, but we need the mask later anyway.*/ + "movdqa %%xmm0,%%xmm6\n\t" + "psraw $15,%%xmm0\n\t" + "movdqa %%xmm1,%%xmm7\n\t" + "paddw %%xmm6,%%xmm6\n\t" + "psraw $15,%%xmm1\n\t" + "paddw %%xmm7,%%xmm7\n\t" + "paddw %%xmm0,%%xmm2\n\t" + "paddw %%xmm1,%%xmm3\n\t" + "pxor %%xmm0,%%xmm2\n\t" + "pxor %%xmm1,%%xmm3\n\t" + /*Add the rounding factor and perform the first multiply.*/ + "paddw %%xmm2,%%xmm6\n\t" + "paddw %%xmm3,%%xmm7\n\t" + "pmulhw %%xmm6,%%xmm4\n\t" + "pmulhw %%xmm7,%%xmm5\n\t" + "movdqa 0x80(%[q],%[r]),%%xmm2\n\t" + "movdqa 0x90(%[q],%[r]),%%xmm3\n\t" + "paddw %%xmm4,%%xmm6\n\t" + "paddw %%xmm5,%%xmm7\n\t" + /*Emulate an element-wise right-shift via a second multiply.*/ + "pmulhw %%xmm2,%%xmm6\n\t" + "pmulhw %%xmm3,%%xmm7\n\t" + "add $32,%[r]\n\t" + "cmp $96,%[r]\n\t" + /*Correct for the sign.*/ + "psubw %%xmm0,%%xmm6\n\t" + "psubw %%xmm1,%%xmm7\n\t" + /*Save the result.*/ + "movdqa %%xmm6,-0x20(%[qdct],%[r])\n\t" + "movdqa %%xmm7,-0x10(%[qdct],%[r])\n\t" + "jle 0b\n\t" + /*Now find the location of the last non-zero value.*/ + "movdqa 0x50(%[qdct]),%%xmm5\n\t" + "movdqa 0x40(%[qdct]),%%xmm4\n\t" + "packsswb %%xmm7,%%xmm6\n\t" + "packsswb %%xmm5,%%xmm4\n\t" + "pxor %%xmm0,%%xmm0\n\t" + "mov $-1,%k[dq]\n\t" + "pcmpeqb %%xmm0,%%xmm6\n\t" + "pcmpeqb %%xmm0,%%xmm4\n\t" + "pmovmskb %%xmm6,%k[q]\n\t" + "pmovmskb %%xmm4,%k[r]\n\t" + "shl $16,%k[q]\n\t" + "or %k[r],%k[q]\n\t" + "mov $32,%[r]\n\t" + /*We have to use xor here instead of not in order to set the flags.*/ + "xor %k[dq],%k[q]\n\t" + "jnz 1f\n\t" + "movdqa 0x30(%[qdct]),%%xmm7\n\t" + "movdqa 0x20(%[qdct]),%%xmm6\n\t" + "movdqa 0x10(%[qdct]),%%xmm5\n\t" + "movdqa 0x00(%[qdct]),%%xmm4\n\t" + "packsswb %%xmm7,%%xmm6\n\t" + "packsswb %%xmm5,%%xmm4\n\t" + "pcmpeqb %%xmm0,%%xmm6\n\t" + "pcmpeqb %%xmm0,%%xmm4\n\t" + "pmovmskb %%xmm6,%k[q]\n\t" + "pmovmskb %%xmm4,%k[r]\n\t" + "shl $16,%k[q]\n\t" + "or %k[r],%k[q]\n\t" + "xor %[r],%[r]\n\t" + "not %k[q]\n\t" + "or $1,%k[q]\n\t" + "1:\n\t" + "bsr %k[q],%k[q]\n\t" + "add %k[q],%k[r]\n\t" + :[r]"=&a"(r),[q]"+r"(_enquant),[dq]"+r"(_dequant) + :[dct]"r"(_dct),[qdct]"r"(_qdct) + :"cc","memory" + ); + return (int)r; +} + +#endif diff --git a/thirdparty/libtheora/x86/x86int.h b/thirdparty/libtheora/x86/x86int.h index ede724f5aa..ceb2dbb0ec 100644 --- a/thirdparty/libtheora/x86/x86int.h +++ b/thirdparty/libtheora/x86/x86int.h @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: x86int.h 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ @@ -19,24 +19,104 @@ # define _x86_x86int_H (1) # include "../internal.h" -void oc_state_vtable_init_x86(oc_theora_state *_state); +# if defined(OC_X86_ASM) +# define oc_state_accel_init oc_state_accel_init_x86 +# if defined(OC_X86_64_ASM) +/*x86-64 guarantees SIMD support up through at least SSE2. + If the best routine we have available only needs SSE2 (which at the moment + covers all of them), then we can avoid runtime detection and the indirect + call.*/ +# define oc_frag_copy(_state,_dst,_src,_ystride) \ + oc_frag_copy_mmx(_dst,_src,_ystride) +# define oc_frag_copy_list(_state,_dst_frame,_src_frame,_ystride, \ + _fragis,_nfragis,_frag_buf_offs) \ + oc_frag_copy_list_mmx(_dst_frame,_src_frame,_ystride, \ + _fragis,_nfragis,_frag_buf_offs) +# define oc_frag_recon_intra(_state,_dst,_ystride,_residue) \ + oc_frag_recon_intra_mmx(_dst,_ystride,_residue) +# define oc_frag_recon_inter(_state,_dst,_src,_ystride,_residue) \ + oc_frag_recon_inter_mmx(_dst,_src,_ystride,_residue) +# define oc_frag_recon_inter2(_state,_dst,_src1,_src2,_ystride,_residue) \ + oc_frag_recon_inter2_mmx(_dst,_src1,_src2,_ystride,_residue) +# define oc_idct8x8(_state,_y,_x,_last_zzi) \ + oc_idct8x8_sse2(_y,_x,_last_zzi) +# define oc_state_frag_recon oc_state_frag_recon_mmx +# define oc_loop_filter_init(_state,_bv,_flimit) \ + oc_loop_filter_init_mmxext(_bv,_flimit) +# define oc_state_loop_filter_frag_rows oc_state_loop_filter_frag_rows_mmxext +# define oc_restore_fpu(_state) \ + oc_restore_fpu_mmx() +# else +# define OC_STATE_USE_VTABLE (1) +# endif +# endif + +# include "../state.h" +# include "x86cpu.h" + +/*Converts the expression in the argument to a string.*/ +#define OC_M2STR(_s) #_s + +/*Memory operands do not always include an offset. + To avoid warnings, we force an offset with %H (which adds 8).*/ +# if __GNUC_PREREQ(4,0) +# define OC_MEM_OFFS(_offs,_name) \ + OC_M2STR(_offs-8+%H[_name]) +# endif +/*If your gcc version does't support %H, then you get to suffer the warnings. + Note that Apple's gas breaks on things like _offs+(%esp): it throws away the + whole offset, instead of substituting in 0 for the missing operand to +.*/ +# if !defined(OC_MEM_OFFS) +# define OC_MEM_OFFS(_offs,_name) \ + OC_M2STR(_offs+%[_name]) +# endif + +/*Declare an array operand with an exact size. + This tells gcc we're going to clobber this memory region, without having to + clobber all of "memory" and lets us access local buffers directly using the + stack pointer, without allocating a separate register to point to them.*/ +#define OC_ARRAY_OPERAND(_type,_ptr,_size) \ + (*({ \ + struct{_type array_value__[(_size)];} *array_addr__=(void *)(_ptr); \ + array_addr__; \ + })) + +/*Declare an array operand with an exact size. + This tells gcc we're going to clobber this memory region, without having to + clobber all of "memory" and lets us access local buffers directly using the + stack pointer, without allocating a separate register to point to them.*/ +#define OC_CONST_ARRAY_OPERAND(_type,_ptr,_size) \ + (*({ \ + const struct{_type array_value__[(_size)];} *array_addr__= \ + (const void *)(_ptr); \ + array_addr__; \ + })) + +extern const unsigned short __attribute__((aligned(16))) OC_IDCT_CONSTS[64]; + +void oc_state_accel_init_x86(oc_theora_state *_state); void oc_frag_copy_mmx(unsigned char *_dst, const unsigned char *_src,int _ystride); +void oc_frag_copy_list_mmx(unsigned char *_dst_frame, + const unsigned char *_src_frame,int _ystride, + const ptrdiff_t *_fragis,ptrdiff_t _nfragis,const ptrdiff_t *_frag_buf_offs); void oc_frag_recon_intra_mmx(unsigned char *_dst,int _ystride, const ogg_int16_t *_residue); void oc_frag_recon_inter_mmx(unsigned char *_dst, const unsigned char *_src,int _ystride,const ogg_int16_t *_residue); void oc_frag_recon_inter2_mmx(unsigned char *_dst,const unsigned char *_src1, const unsigned char *_src2,int _ystride,const ogg_int16_t *_residue); -void oc_idct8x8_mmx(ogg_int16_t _y[64],int _last_zzi); +void oc_idct8x8_mmx(ogg_int16_t _y[64],ogg_int16_t _x[64],int _last_zzi); +void oc_idct8x8_sse2(ogg_int16_t _y[64],ogg_int16_t _x[64],int _last_zzi); void oc_state_frag_recon_mmx(const oc_theora_state *_state,ptrdiff_t _fragi, - int _pli,ogg_int16_t _dct_coeffs[64],int _last_zzi,ogg_uint16_t _dc_quant); -void oc_state_frag_copy_list_mmx(const oc_theora_state *_state, - const ptrdiff_t *_fragis,ptrdiff_t _nfragis, - int _dst_frame,int _src_frame,int _pli); + int _pli,ogg_int16_t _dct_coeffs[128],int _last_zzi,ogg_uint16_t _dc_quant); +void oc_loop_filter_init_mmx(signed char _bv[256],int _flimit); +void oc_loop_filter_init_mmxext(signed char _bv[256],int _flimit); void oc_state_loop_filter_frag_rows_mmx(const oc_theora_state *_state, - int _bv[256],int _refi,int _pli,int _fragy0,int _fragy_end); + signed char _bv[256],int _refi,int _pli,int _fragy0,int _fragy_end); +void oc_state_loop_filter_frag_rows_mmxext(const oc_theora_state *_state, + signed char _bv[256],int _refi,int _pli,int _fragy0,int _fragy_end); void oc_restore_fpu_mmx(void); #endif diff --git a/thirdparty/libtheora/x86/x86state.c b/thirdparty/libtheora/x86/x86state.c index a786bec284..9f8bceb534 100644 --- a/thirdparty/libtheora/x86/x86state.c +++ b/thirdparty/libtheora/x86/x86state.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: x86state.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ @@ -19,8 +19,7 @@ #if defined(OC_X86_ASM) -#include "../cpu.c" - +#if defined(OC_STATE_USE_VTABLE) /*This table has been modified from OC_FZIG_ZAG by baking a 4x4 transpose into each quadrant of the destination.*/ static const unsigned char OC_FZIG_ZAG_MMX[128]={ @@ -39,24 +38,60 @@ static const unsigned char OC_FZIG_ZAG_MMX[128]={ 64,64,64,64,64,64,64,64, 64,64,64,64,64,64,64,64, 64,64,64,64,64,64,64,64, + 64,64,64,64,64,64,64,64 +}; +#endif + +/*This table has been modified from OC_FZIG_ZAG by baking an 8x8 transpose into + the destination.*/ +static const unsigned char OC_FZIG_ZAG_SSE2[128]={ + 0, 8, 1, 2, 9,16,24,17, + 10, 3, 4,11,18,25,32,40, + 33,26,19,12, 5, 6,13,20, + 27,34,41,48,56,49,42,35, + 28,21,14, 7,15,22,29,36, + 43,50,57,58,51,44,37,30, + 23,31,38,45,52,59,60,53, + 46,39,47,54,61,62,55,63, + 64,64,64,64,64,64,64,64, + 64,64,64,64,64,64,64,64, 64,64,64,64,64,64,64,64, + 64,64,64,64,64,64,64,64, + 64,64,64,64,64,64,64,64, + 64,64,64,64,64,64,64,64, + 64,64,64,64,64,64,64,64, + 64,64,64,64,64,64,64,64 }; -void oc_state_vtable_init_x86(oc_theora_state *_state){ +void oc_state_accel_init_x86(oc_theora_state *_state){ + oc_state_accel_init_c(_state); _state->cpu_flags=oc_cpu_flags_get(); +# if defined(OC_STATE_USE_VTABLE) if(_state->cpu_flags&OC_CPU_X86_MMX){ _state->opt_vtable.frag_copy=oc_frag_copy_mmx; + _state->opt_vtable.frag_copy_list=oc_frag_copy_list_mmx; _state->opt_vtable.frag_recon_intra=oc_frag_recon_intra_mmx; _state->opt_vtable.frag_recon_inter=oc_frag_recon_inter_mmx; _state->opt_vtable.frag_recon_inter2=oc_frag_recon_inter2_mmx; _state->opt_vtable.idct8x8=oc_idct8x8_mmx; _state->opt_vtable.state_frag_recon=oc_state_frag_recon_mmx; - _state->opt_vtable.state_frag_copy_list=oc_state_frag_copy_list_mmx; + _state->opt_vtable.loop_filter_init=oc_loop_filter_init_mmx; _state->opt_vtable.state_loop_filter_frag_rows= oc_state_loop_filter_frag_rows_mmx; _state->opt_vtable.restore_fpu=oc_restore_fpu_mmx; _state->opt_data.dct_fzig_zag=OC_FZIG_ZAG_MMX; } - else oc_state_vtable_init_c(_state); + if(_state->cpu_flags&OC_CPU_X86_MMXEXT){ + _state->opt_vtable.loop_filter_init=oc_loop_filter_init_mmxext; + _state->opt_vtable.state_loop_filter_frag_rows= + oc_state_loop_filter_frag_rows_mmxext; + } + if(_state->cpu_flags&OC_CPU_X86_SSE2){ + _state->opt_vtable.idct8x8=oc_idct8x8_sse2; +# endif + _state->opt_data.dct_fzig_zag=OC_FZIG_ZAG_SSE2; +# if defined(OC_STATE_USE_VTABLE) + } +# endif } #endif diff --git a/thirdparty/libtheora/x86/x86zigzag.h b/thirdparty/libtheora/x86/x86zigzag.h new file mode 100644 index 0000000000..fb21e0bb43 --- /dev/null +++ b/thirdparty/libtheora/x86/x86zigzag.h @@ -0,0 +1,244 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * + * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * + * * + ******************************************************************** + + function: + last mod: $Id: sse2trans.h 15675 2009-02-06 09:43:27Z tterribe $ + + ********************************************************************/ + +#if !defined(_x86_x86zigzag_H) +# define _x86_x86zigzag_H (1) +# include "x86enc.h" + + +/*Converts DCT coefficients from transposed order into zig-zag scan order and + stores them in %[y]. + This relies on two macros to load the contents of each row: + OC_ZZ_LOAD_ROW_LO(row,"reg") and OC_ZZ_LOAD_ROW_HI(row,"reg"), which load + the first four and second four entries of each row into the specified + register, respectively. + OC_ZZ_LOAD_ROW_LO must be called before OC_ZZ_LOAD_ROW_HI for the same row + (because when the rows are already in SSE2 registers, loading the high half + destructively modifies the register). + The index of each output element in the original 64-element array should wind + up in the following 8x8 matrix (the letters indicate the order we compute + each 4-tuple below): + A 0 8 1 2 9 16 24 17 B + C 10 3 4 11 18 25 32 40 E + F 33 26 19 12 5 6 13 20 D + G 27 34 41 48 56 49 42 35 I + L 28 21 14 7 15 22 29 36 M + H 43 50 57 58 51 44 37 30 O + N 23 31 38 45 52 59 60 53 J + P 46 39 47 54 61 62 55 63 K + The order of the coefficients within each tuple is reversed in the comments + below to reflect the usual MSB to LSB notation.*/ +#define OC_TRANSPOSE_ZIG_ZAG_MMXEXT \ + OC_ZZ_LOAD_ROW_LO(0,"%%mm0") /*mm0=03 02 01 00*/ \ + OC_ZZ_LOAD_ROW_LO(1,"%%mm1") /*mm1=11 10 09 08*/ \ + OC_ZZ_LOAD_ROW_LO(2,"%%mm2") /*mm2=19 18 17 16*/ \ + OC_ZZ_LOAD_ROW_LO(3,"%%mm3") /*mm3=27 26 25 24*/ \ + OC_ZZ_LOAD_ROW_HI(0,"%%mm4") /*mm4=07 06 05 04*/ \ + OC_ZZ_LOAD_ROW_HI(1,"%%mm5") /*mm5=15 14 13 12*/ \ + OC_ZZ_LOAD_ROW_HI(2,"%%mm6") /*mm6=23 22 21 20*/ \ + "movq %%mm0,%%mm7\n\t" /*mm7=03 02 01 00*/ \ + "punpckhdq %%mm1,%%mm0\n\t" /*mm0=11 10 03 02*/ \ + "pshufw $0x39,%%mm4,%%mm4\n\t" /*mm4=04 07 06 05*/ \ + "punpcklwd %%mm0,%%mm1\n\t" /*mm1=03 09 02 08*/ \ + "pshufw $0x39,%%mm5,%%mm5\n\t" /*mm5=12 15 14 13*/ \ + "punpcklwd %%mm1,%%mm7\n\t" /*mm7=02 01 08 00 *A*/ \ + "movq %%mm7,0x00(%[y])\n\t" \ + "punpckhwd %%mm4,%%mm1\n\t" /*mm1=04 03 07 09*/ \ + "movq %%mm2,%%mm7\n\t" /*mm7=19 18 17 16*/ \ + "punpckhdq %%mm1,%%mm0\n\t" /*mm0=04 03 11 10*/ \ + "punpckhwd %%mm5,%%mm7\n\t" /*mm7=12 19 15 18*/ \ + "punpcklwd %%mm3,%%mm1\n\t" /*mm1=25 07 24 09*/ \ + "punpcklwd %%mm6,%%mm5\n\t" /*mm5=21 14 20 13*/ \ + "punpcklwd %%mm2,%%mm1\n\t" /*mm1=17 24 16 09 *B*/ \ + OC_ZZ_LOAD_ROW_LO(4,"%%mm2") /*mm2=35 34 33 32*/ \ + "movq %%mm1,0x08(%[y])\n\t" \ + OC_ZZ_LOAD_ROW_LO(5,"%%mm1") /*mm1=43 42 41 40*/ \ + "pshufw $0x78,%%mm0,%%mm0\n\t" /*mm0=11 04 03 10 *C*/ \ + "movq %%mm0,0x10(%[y])\n\t" \ + "punpckhdq %%mm4,%%mm6\n\t" /*mm6=?? 07 23 22*/ \ + "punpckldq %%mm5,%%mm4\n\t" /*mm4=20 13 06 05 *D*/ \ + "movq %%mm4,0x28(%[y])\n\t" \ + "psrlq $16,%%mm3\n\t" /*mm3=.. 27 26 25*/ \ + "pshufw $0x0E,%%mm2,%%mm0\n\t" /*mm0=?? ?? 35 34*/ \ + "movq %%mm7,%%mm4\n\t" /*mm4=12 19 15 18*/ \ + "punpcklwd %%mm3,%%mm2\n\t" /*mm2=26 33 25 32*/ \ + "punpcklwd %%mm1,%%mm4\n\t" /*mm4=41 15 40 18*/ \ + "punpckhwd %%mm1,%%mm3\n\t" /*mm3=43 .. 42 27*/ \ + "punpckldq %%mm2,%%mm4\n\t" /*mm4=25 32 40 18*/ \ + "punpcklwd %%mm0,%%mm3\n\t" /*mm3=35 42 34 27*/ \ + OC_ZZ_LOAD_ROW_LO(6,"%%mm0") /*mm0=51 50 49 48*/ \ + "pshufw $0x6C,%%mm4,%%mm4\n\t" /*mm4=40 32 25 18 *E*/ \ + "movq %%mm4,0x18(%[y])\n\t" \ + OC_ZZ_LOAD_ROW_LO(7,"%%mm4") /*mm4=59 58 57 56*/ \ + "punpckhdq %%mm7,%%mm2\n\t" /*mm2=12 19 26 33 *F*/ \ + "movq %%mm2,0x20(%[y])\n\t" \ + "pshufw $0xD0,%%mm1,%%mm1\n\t" /*mm1=43 41 ?? ??*/ \ + "pshufw $0x87,%%mm0,%%mm0\n\t" /*mm0=50 48 49 51*/ \ + "movq %%mm3,%%mm2\n\t" /*mm2=35 42 34 27*/ \ + "punpckhwd %%mm0,%%mm1\n\t" /*mm1=50 43 48 41*/ \ + "pshufw $0x93,%%mm4,%%mm4\n\t" /*mm4=58 57 56 59*/ \ + "punpckldq %%mm1,%%mm3\n\t" /*mm3=48 41 34 27 *G*/ \ + "movq %%mm3,0x30(%[y])\n\t" \ + "punpckhdq %%mm4,%%mm1\n\t" /*mm1=58 57 50 43 *H*/ \ + "movq %%mm1,0x50(%[y])\n\t" \ + OC_ZZ_LOAD_ROW_HI(7,"%%mm1") /*mm1=63 62 61 60*/ \ + "punpcklwd %%mm0,%%mm4\n\t" /*mm4=49 56 51 59*/ \ + OC_ZZ_LOAD_ROW_HI(6,"%%mm0") /*mm0=55 54 53 52*/ \ + "psllq $16,%%mm6\n\t" /*mm6=07 23 22 ..*/ \ + "movq %%mm4,%%mm3\n\t" /*mm3=49 56 51 59*/ \ + "punpckhdq %%mm2,%%mm4\n\t" /*mm4=35 42 49 56 *I*/ \ + OC_ZZ_LOAD_ROW_HI(3,"%%mm2") /*mm2=31 30 29 28*/ \ + "movq %%mm4,0x38(%[y])\n\t" \ + "punpcklwd %%mm1,%%mm3\n\t" /*mm3=61 51 60 59*/ \ + "punpcklwd %%mm6,%%mm7\n\t" /*mm7=22 15 .. ??*/ \ + "movq %%mm3,%%mm4\n\t" /*mm4=61 51 60 59*/ \ + "punpcklwd %%mm0,%%mm3\n\t" /*mm3=53 60 52 59*/ \ + "punpckhwd %%mm0,%%mm4\n\t" /*mm4=55 61 54 51*/ \ + OC_ZZ_LOAD_ROW_HI(4,"%%mm0") /*mm0=39 38 37 36*/ \ + "pshufw $0xE1,%%mm3,%%mm3\n\t" /*mm3=53 60 59 52 *J*/ \ + "movq %%mm3,0x68(%[y])\n\t" \ + "movq %%mm4,%%mm3\n\t" /*mm3=?? ?? 54 51*/ \ + "pshufw $0x39,%%mm2,%%mm2\n\t" /*mm2=28 31 30 29*/ \ + "punpckhwd %%mm1,%%mm4\n\t" /*mm4=63 55 62 61 *K*/ \ + OC_ZZ_LOAD_ROW_HI(5,"%%mm1") /*mm1=47 46 45 44*/ \ + "movq %%mm4,0x78(%[y])\n\t" \ + "punpckhwd %%mm2,%%mm6\n\t" /*mm6=28 07 31 23*/ \ + "punpcklwd %%mm0,%%mm2\n\t" /*mm2=37 30 36 29*/ \ + "punpckhdq %%mm6,%%mm5\n\t" /*mm5=28 07 21 14*/ \ + "pshufw $0x4B,%%mm2,%%mm2\n\t" /*mm2=36 29 30 37*/ \ + "pshufw $0x87,%%mm5,%%mm5\n\t" /*mm5=07 14 21 28 *L*/ \ + "movq %%mm5,0x40(%[y])\n\t" \ + "punpckhdq %%mm2,%%mm7\n\t" /*mm7=36 29 22 15 *M*/ \ + "movq %%mm7,0x48(%[y])\n\t" \ + "pshufw $0x9C,%%mm1,%%mm1\n\t" /*mm1=46 45 47 44*/ \ + "punpckhwd %%mm1,%%mm0\n\t" /*mm0=46 39 45 38*/ \ + "punpcklwd %%mm1,%%mm3\n\t" /*mm3=47 54 44 51*/ \ + "punpckldq %%mm0,%%mm6\n\t" /*mm6=45 38 31 23 *N*/ \ + "movq %%mm6,0x60(%[y])\n\t" \ + "punpckhdq %%mm3,%%mm0\n\t" /*mm0=47 54 46 39*/ \ + "punpckldq %%mm2,%%mm3\n\t" /*mm3=30 37 44 51 *O*/ \ + "movq %%mm3,0x58(%[y])\n\t" \ + "pshufw $0xB1,%%mm0,%%mm0\n\t" /*mm0=54 47 39 46 *P*/ \ + "movq %%mm0,0x70(%[y])\n\t" \ + +/*Converts DCT coefficients in %[dct] from natural order into zig-zag scan + order and stores them in %[qdct]. + The index of each output element in the original 64-element array should wind + up in the following 8x8 matrix (the letters indicate the order we compute + each 4-tuple below): + A 0 1 8 16 9 2 3 10 B + C 17 24 32 25 18 11 4 5 D + E 12 19 26 33 40 48 41 34 I + H 27 20 13 6 7 14 21 28 G + K 35 42 49 56 57 50 43 36 J + F 29 22 15 23 30 37 44 51 M + P 58 59 52 45 38 31 39 46 L + N 53 60 61 54 47 55 62 63 O + The order of the coefficients within each tuple is reversed in the comments + below to reflect the usual MSB to LSB notation.*/ +#define OC_ZIG_ZAG_MMXEXT \ + "movq 0x00(%[dct]),%%mm0\n\t" /*mm0=03 02 01 00*/ \ + "movq 0x08(%[dct]),%%mm1\n\t" /*mm1=07 06 05 04*/ \ + "movq 0x10(%[dct]),%%mm2\n\t" /*mm2=11 10 09 08*/ \ + "movq 0x20(%[dct]),%%mm3\n\t" /*mm3=19 18 17 16*/ \ + "movq 0x30(%[dct]),%%mm4\n\t" /*mm4=27 26 25 24*/ \ + "movq 0x40(%[dct]),%%mm5\n\t" /*mm5=35 34 33 32*/ \ + "movq %%mm2,%%mm7\n\t" /*mm7=11 10 09 08*/ \ + "punpcklwd %%mm3,%%mm2\n\t" /*mm2=17 09 16 08*/ \ + "movq %%mm0,%%mm6\n\t" /*mm6=03 02 01 00*/ \ + "punpckldq %%mm2,%%mm0\n\t" /*mm0=16 08 01 00 *A*/ \ + "movq %%mm0,0x00(%[qdct])\n\t" \ + "movq 0x18(%[dct]),%%mm0\n\t" /*mm0=15 14 13 12*/ \ + "punpckhdq %%mm6,%%mm6\n\t" /*mm6=03 02 03 02*/ \ + "psrlq $16,%%mm7\n\t" /*mm7=.. 11 10 09*/ \ + "punpckldq %%mm7,%%mm6\n\t" /*mm6=10 09 03 02*/ \ + "punpckhwd %%mm7,%%mm3\n\t" /*mm3=.. 19 11 18*/ \ + "pshufw $0xD2,%%mm6,%%mm6\n\t" /*mm6=10 03 02 09 *B*/ \ + "movq %%mm6,0x08(%[qdct])\n\t" \ + "psrlq $48,%%mm2\n\t" /*mm2=.. .. .. 17*/ \ + "movq %%mm1,%%mm6\n\t" /*mm6=07 06 05 04*/ \ + "punpcklwd %%mm5,%%mm2\n\t" /*mm2=33 .. 32 17*/ \ + "movq %%mm3,%%mm7\n\t" /*mm7=.. 19 11 18*/ \ + "punpckldq %%mm1,%%mm3\n\t" /*mm3=05 04 11 18 *C*/ \ + "por %%mm2,%%mm7\n\t" /*mm7=33 19 ?? ??*/ \ + "punpcklwd %%mm4,%%mm2\n\t" /*mm2=25 32 24 17 *D**/ \ + "movq %%mm2,0x10(%[qdct])\n\t" \ + "movq %%mm3,0x18(%[qdct])\n\t" \ + "movq 0x28(%[dct]),%%mm2\n\t" /*mm2=23 22 21 20*/ \ + "movq 0x38(%[dct]),%%mm1\n\t" /*mm1=31 30 29 28*/ \ + "pshufw $0x9C,%%mm0,%%mm3\n\t" /*mm3=14 13 15 12*/ \ + "punpckhdq %%mm7,%%mm7\n\t" /*mm7=33 19 33 19*/ \ + "punpckhwd %%mm3,%%mm6\n\t" /*mm6=14 07 13 06*/ \ + "punpckldq %%mm0,%%mm0\n\t" /*mm0=13 12 13 12*/ \ + "punpcklwd %%mm1,%%mm3\n\t" /*mm3=29 15 28 12*/ \ + "punpckhwd %%mm4,%%mm0\n\t" /*mm0=27 13 26 12*/ \ + "pshufw $0xB4,%%mm3,%%mm3\n\t" /*mm3=15 29 28 12*/ \ + "psrlq $48,%%mm4\n\t" /*mm4=.. .. .. 27*/ \ + "punpcklwd %%mm7,%%mm0\n\t" /*mm0=33 26 19 12 *E*/ \ + "punpcklwd %%mm1,%%mm4\n\t" /*mm4=29 .. 28 27*/ \ + "punpckhwd %%mm2,%%mm3\n\t" /*mm3=23 15 22 29 *F*/ \ + "movq %%mm0,0x20(%[qdct])\n\t" \ + "movq %%mm3,0x50(%[qdct])\n\t" \ + "movq 0x60(%[dct]),%%mm3\n\t" /*mm3=51 50 49 48*/ \ + "movq 0x70(%[dct]),%%mm7\n\t" /*mm7=59 58 57 56*/ \ + "movq 0x50(%[dct]),%%mm0\n\t" /*mm0=43 42 41 40*/ \ + "punpcklwd %%mm4,%%mm2\n\t" /*mm2=28 21 27 20*/ \ + "psrlq $32,%%mm5\n\t" /*mm5=.. .. 35 34*/ \ + "movq %%mm2,%%mm4\n\t" /*mm4=28 21 27 20*/ \ + "punpckldq %%mm6,%%mm2\n\t" /*mm2=13 06 27 20*/ \ + "punpckhdq %%mm4,%%mm6\n\t" /*mm6=28 21 14 07 *G*/ \ + "movq %%mm3,%%mm4\n\t" /*mm4=51 50 49 48*/ \ + "pshufw $0xB1,%%mm2,%%mm2\n\t" /*mm2=06 13 20 27 *H*/ \ + "movq %%mm2,0x30(%[qdct])\n\t" \ + "movq %%mm6,0x38(%[qdct])\n\t" \ + "movq 0x48(%[dct]),%%mm2\n\t" /*mm2=39 38 37 36*/ \ + "punpcklwd %%mm5,%%mm4\n\t" /*mm4=35 49 34 48*/ \ + "movq 0x58(%[dct]),%%mm5\n\t" /*mm5=47 46 45 44*/ \ + "punpckldq %%mm7,%%mm6\n\t" /*mm6=57 56 14 07*/ \ + "psrlq $32,%%mm3\n\t" /*mm3=.. .. 51 50*/ \ + "punpckhwd %%mm0,%%mm6\n\t" /*mm6=43 57 42 56*/ \ + "punpcklwd %%mm4,%%mm0\n\t" /*mm0=34 41 48 40 *I*/ \ + "pshufw $0x4E,%%mm6,%%mm6\n\t" /*mm6=42 56 43 57*/ \ + "movq %%mm0,0x28(%[qdct])\n\t" \ + "punpcklwd %%mm2,%%mm3\n\t" /*mm3=37 51 36 50*/ \ + "punpckhwd %%mm6,%%mm4\n\t" /*mm4=42 35 56 49*/ \ + "punpcklwd %%mm3,%%mm6\n\t" /*mm6=36 43 50 57 *J*/ \ + "pshufw $0x4E,%%mm4,%%mm4\n\t" /*mm4=56 49 42 35 *K*/ \ + "movq %%mm4,0x40(%[qdct])\n\t" \ + "movq %%mm6,0x48(%[qdct])\n\t" \ + "movq 0x68(%[dct]),%%mm6\n\t" /*mm6=55 54 53 52*/ \ + "movq 0x78(%[dct]),%%mm0\n\t" /*mm0=63 62 61 60*/ \ + "psrlq $32,%%mm1\n\t" /*mm1=.. .. 31 30*/ \ + "pshufw $0xD8,%%mm5,%%mm5\n\t" /*mm5=47 45 46 44*/ \ + "pshufw $0x0B,%%mm3,%%mm3\n\t" /*mm3=50 50 51 37*/ \ + "punpcklwd %%mm5,%%mm1\n\t" /*mm1=46 31 44 30*/ \ + "pshufw $0xC9,%%mm6,%%mm6\n\t" /*mm6=55 52 54 53*/ \ + "punpckhwd %%mm1,%%mm2\n\t" /*mm2=46 39 31 38 *L*/ \ + "punpcklwd %%mm3,%%mm1\n\t" /*mm1=51 44 37 30 *M*/ \ + "movq %%mm2,0x68(%[qdct])\n\t" \ + "movq %%mm1,0x58(%[qdct])\n\t" \ + "punpckhwd %%mm6,%%mm5\n\t" /*mm5=55 47 52 45*/ \ + "punpckldq %%mm0,%%mm6\n\t" /*mm6=61 60 54 53*/ \ + "pshufw $0x10,%%mm5,%%mm4\n\t" /*mm4=45 52 45 45*/ \ + "pshufw $0x78,%%mm6,%%mm6\n\t" /*mm6=53 60 61 54 *N*/ \ + "punpckhdq %%mm0,%%mm5\n\t" /*mm5=63 62 55 47 *O*/ \ + "punpckhdq %%mm4,%%mm7\n\t" /*mm7=45 52 59 58 *P*/ \ + "movq %%mm6,0x70(%[qdct])\n\t" \ + "movq %%mm5,0x78(%[qdct])\n\t" \ + "movq %%mm7,0x60(%[qdct])\n\t" \ + +#endif diff --git a/thirdparty/libtheora/x86_vc/mmxencfrag.c b/thirdparty/libtheora/x86_vc/mmxencfrag.c index 94f1d06513..a6be819135 100644 --- a/thirdparty/libtheora/x86_vc/mmxencfrag.c +++ b/thirdparty/libtheora/x86_vc/mmxencfrag.c @@ -266,7 +266,7 @@ unsigned oc_enc_frag_sad2_thresh_mmxext(const unsigned char *_src, /*Performs the first two stages of an 8-point 1-D Hadamard transform. The transform is performed in place, except that outputs 0-3 are swapped with outputs 4-7. - Outputs 2, 3, 6 and 7 from the second stage are negated (which allows us to + Outputs 2, 3, 6, and 7 from the second stage are negated (which allows us to perform this stage in place with no temporary registers).*/ #define OC_HADAMARD_AB_8x4 __asm{ \ /*Stage A: \ @@ -299,7 +299,7 @@ unsigned oc_enc_frag_sad2_thresh_mmxext(const unsigned char *_src, } /*Performs the last stage of an 8-point 1-D Hadamard transform in place. - Ouputs 1, 3, 5, and 7 are negated (which allows us to perform this stage in + Outputs 1, 3, 5, and 7 are negated (which allows us to perform this stage in place with no temporary registers).*/ #define OC_HADAMARD_C_8x4 __asm{ \ /*Stage C:*/ \ @@ -468,12 +468,14 @@ unsigned oc_enc_frag_sad2_thresh_mmxext(const unsigned char *_src, mm7 = d3 c3 b3 a3*/ \ } -static unsigned oc_int_frag_satd_thresh_mmxext(const unsigned char *_src, - int _src_ystride,const unsigned char *_ref,int _ref_ystride,unsigned _thresh){ - OC_ALIGN8(ogg_int16_t buf[64]); - ogg_int16_t *bufp; - unsigned ret1; - unsigned ret2; +static unsigned oc_int_frag_satd_mmxext(int *_dc, + const unsigned char *_src,int _src_ystride, + const unsigned char *_ref,int _ref_ystride){ + OC_ALIGN8(ogg_int16_t buf[64]); + ogg_int16_t *bufp; + unsigned ret; + unsigned ret2; + int dc; bufp=buf; __asm{ #define SRC esi @@ -481,8 +483,10 @@ static unsigned oc_int_frag_satd_thresh_mmxext(const unsigned char *_src, #define SRC_YSTRIDE ecx #define REF_YSTRIDE edx #define BUF edi -#define RET eax -#define RET2 edx +#define RET edx +#define RET2 ecx +#define DC eax +#define DC_WORD ax mov SRC,_src mov SRC_YSTRIDE,_src_ystride mov REF,_ref @@ -508,14 +512,18 @@ static unsigned oc_int_frag_satd_thresh_mmxext(const unsigned char *_src, movq mm2,[0x20+BUF] movq mm3,[0x30+BUF] movq mm0,[0x00+BUF] - OC_HADAMARD_ABS_ACCUM_8x4(0x28,0x38) + /*We split out the stages here so we can save the DC coefficient in the + middle.*/ + OC_HADAMARD_AB_8x4 + OC_HADAMARD_C_ABS_ACCUM_A_8x4(0x28,0x38) + movd DC,mm1 + OC_HADAMARD_C_ABS_ACCUM_B_8x4(0x28,0x38) /*Up to this point, everything fit in 16 bits (8 input + 1 for the difference + 2*3 for the two 8-point 1-D Hadamards - 1 for the abs - 1 for the factor of two we dropped + 3 for the vertical accumulation). Now we finally have to promote things to dwords. We break this part out of OC_HADAMARD_ABS_ACCUM_8x4 to hide the long latency of pmaddwd by starting the next series of loads now.*/ - mov RET2,_thresh pmaddwd mm0,mm7 movq mm1,[0x50+BUF] movq mm5,[0x58+BUF] @@ -525,29 +533,28 @@ static unsigned oc_int_frag_satd_thresh_mmxext(const unsigned char *_src, movq mm6,[0x68+BUF] paddd mm4,mm0 movq mm3,[0x70+BUF] - movd RET,mm4 + movd RET2,mm4 movq mm7,[0x78+BUF] - /*The sums produced by OC_HADAMARD_ABS_ACCUM_8x4 each have an extra 4 - added to them, and a factor of two removed; correct the final sum here.*/ - lea RET,[RET+RET-32] movq mm0,[0x40+BUF] - cmp RET,RET2 movq mm4,[0x48+BUF] - jae at_end OC_HADAMARD_ABS_ACCUM_8x4(0x68,0x78) pmaddwd mm0,mm7 - /*There isn't much to stick in here to hide the latency this time, but the - alternative to pmaddwd is movq->punpcklwd->punpckhwd->paddd, whose - latency is even worse.*/ - sub RET,32 + /*Subtract abs(dc) from 2*ret2.*/ + movsx DC,DC_WORD + cdq + lea RET2,[RET+RET2*2] movq mm4,mm0 punpckhdq mm0,mm0 + xor RET,DC paddd mm4,mm0 - movd RET2,mm4 - lea RET,[RET+RET2*2] - align 16 -at_end: - mov ret1,RET + /*The sums produced by OC_HADAMARD_ABS_ACCUM_8x4 each have an extra 4 + added to them, a factor of two removed, and the DC value included; + correct the final sum here.*/ + sub RET2,RET + movd RET,mm4 + lea RET,[RET2+RET*2-64] + mov ret,RET + mov dc,DC #undef SRC #undef REF #undef SRC_YSTRIDE @@ -555,18 +562,21 @@ at_end: #undef BUF #undef RET #undef RET2 +#undef DC +#undef DC_WORD } - return ret1; + *_dc=dc; + return ret; } -unsigned oc_enc_frag_satd_thresh_mmxext(const unsigned char *_src, - const unsigned char *_ref,int _ystride,unsigned _thresh){ - return oc_int_frag_satd_thresh_mmxext(_src,_ystride,_ref,_ystride,_thresh); +unsigned oc_enc_frag_satd_mmxext(int *_dc,const unsigned char *_src, + const unsigned char *_ref,int _ystride){ + return oc_int_frag_satd_mmxext(_dc,_src,_ystride,_ref,_ystride); } /*Our internal implementation of frag_copy2 takes an extra stride parameter so - we can share code with oc_enc_frag_satd2_thresh_mmxext().*/ + we can share code with oc_enc_frag_satd2_mmxext().*/ static void oc_int_frag_copy2_mmxext(unsigned char *_dst,int _dst_ystride, const unsigned char *_src1,const unsigned char *_src2,int _src_ystride){ __asm{ @@ -694,30 +704,31 @@ static void oc_int_frag_copy2_mmxext(unsigned char *_dst,int _dst_ystride, } } -unsigned oc_enc_frag_satd2_thresh_mmxext(const unsigned char *_src, - const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, - unsigned _thresh){ +unsigned oc_enc_frag_satd2_mmxext(int *_dc,const unsigned char *_src, + const unsigned char *_ref1,const unsigned char *_ref2,int _ystride){ OC_ALIGN8(unsigned char ref[64]); oc_int_frag_copy2_mmxext(ref,8,_ref1,_ref2,_ystride); - return oc_int_frag_satd_thresh_mmxext(_src,_ystride,ref,8,_thresh); + return oc_int_frag_satd_mmxext(_dc,_src,_ystride,ref,8); } -unsigned oc_enc_frag_intra_satd_mmxext(const unsigned char *_src, +unsigned oc_enc_frag_intra_satd_mmxext(int *_dc,const unsigned char *_src, int _ystride){ - OC_ALIGN8(ogg_int16_t buf[64]); - ogg_int16_t *bufp; - unsigned ret1; - unsigned ret2; + OC_ALIGN8(ogg_int16_t buf[64]); + ogg_int16_t *bufp; + unsigned ret1; + unsigned ret2; + int dc; bufp=buf; __asm{ #define SRC eax #define SRC4 esi #define BUF edi -#define RET eax -#define RET_WORD ax -#define RET2 ecx #define YSTRIDE edx #define YSTRIDE3 ecx +#define RET eax +#define RET2 ecx +#define DC edx +#define DC_WORD dx mov SRC,_src mov BUF,bufp mov YSTRIDE,_ystride @@ -749,7 +760,7 @@ unsigned oc_enc_frag_intra_satd_mmxext(const unsigned char *_src, middle.*/ OC_HADAMARD_AB_8x4 OC_HADAMARD_C_ABS_ACCUM_A_8x4(0x28,0x38) - movd RET,mm1 + movd DC,mm1 OC_HADAMARD_C_ABS_ACCUM_B_8x4(0x28,0x38) /*Up to this point, everything fit in 16 bits (8 input + 1 for the difference + 2*3 for the two 8-point 1-D Hadamards - 1 for the abs - 1 @@ -767,31 +778,34 @@ unsigned oc_enc_frag_intra_satd_mmxext(const unsigned char *_src, movq mm3,[0x70+BUF] paddd mm4,mm0 movq mm7,[0x78+BUF] - movd RET2,mm4 + movd RET,mm4 movq mm0,[0x40+BUF] movq mm4,[0x48+BUF] OC_HADAMARD_ABS_ACCUM_8x4(0x68,0x78) pmaddwd mm0,mm7 /*We assume that the DC coefficient is always positive (which is true, because the input to the INTRA transform was not a difference).*/ - movzx RET,RET_WORD - add RET2,RET2 - sub RET2,RET + movzx DC,DC_WORD + add RET,RET + sub RET,DC movq mm4,mm0 punpckhdq mm0,mm0 paddd mm4,mm0 - movd RET,mm4 - lea RET,[-64+RET2+RET*2] + movd RET2,mm4 + lea RET,[-64+RET+RET2*2] + mov [dc],DC mov [ret1],RET #undef SRC #undef SRC4 #undef BUF -#undef RET -#undef RET_WORD -#undef RET2 #undef YSTRIDE #undef YSTRIDE3 +#undef RET +#undef RET2 +#undef DC +#undef DC_WORD } + *_dc=dc; return ret1; } diff --git a/thirdparty/libtheora/x86_vc/mmxfdct.c b/thirdparty/libtheora/x86_vc/mmxfdct.c index d908ce2413..c9ee530ea2 100644 --- a/thirdparty/libtheora/x86_vc/mmxfdct.c +++ b/thirdparty/libtheora/x86_vc/mmxfdct.c @@ -12,6 +12,7 @@ /*MMX fDCT implementation for x86_32*/ /*$Id: fdct_ses2.c 14579 2008-03-12 06:42:40Z xiphmont $*/ #include "x86enc.h" +#include "x86zigzag.h" #if defined(OC_X86_ASM) @@ -462,18 +463,22 @@ } /*MMX implementation of the fDCT.*/ -void oc_enc_fdct8x8_mmx(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ - ptrdiff_t a; +void oc_enc_fdct8x8_mmxext(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ + OC_ALIGN8(ogg_int16_t buf[64]); + ogg_int16_t *bufp; + bufp=buf; __asm{ +#define X edx #define Y eax #define A ecx -#define X edx +#define BUF esi /*Add two extra bits of working precision to improve accuracy; any more and we could overflow.*/ /*We also add biases to correct for some systematic error that remains in the full fDCT->iDCT round trip.*/ mov X, _x mov Y, _y + mov BUF, bufp movq mm0,[0x00+X] movq mm1,[0x10+X] movq mm2,[0x20+X] @@ -591,79 +596,90 @@ void oc_enc_fdct8x8_mmx(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ movq mm3,[0x30+Y] OC_FDCT_STAGE1_8x4 OC_FDCT8x4(0x00,0x10,0x20,0x30,0x08,0x18,0x28,0x38) - OC_TRANSPOSE8x4(0x00,0x10,0x20,0x30,0x08,0x18,0x28,0x38) /*mm0={-2}x4*/ - pcmpeqw mm0,mm0 - paddw mm0,mm0 - /*Round the results.*/ - psubw mm1,mm0 - psubw mm2,mm0 - psraw mm1,2 - psubw mm3,mm0 - movq [0x18+Y],mm1 - psraw mm2,2 - psubw mm4,mm0 - movq mm1,[0x08+Y] - psraw mm3,2 - psubw mm5,mm0 + pcmpeqw mm2,mm2 + paddw mm2,mm2 + /*Round and store the results (no transpose).*/ + movq mm7,[Y+0x10] + psubw mm4,mm2 + psubw mm6,mm2 psraw mm4,2 - psubw mm6,mm0 - psraw mm5,2 - psubw mm7,mm0 + psubw mm0,mm2 + movq [BUF+0x00],mm4 + movq mm4,[Y+0x30] psraw mm6,2 - psubw mm1,mm0 + psubw mm5,mm2 + movq [BUF+0x20],mm6 + psraw mm0,2 + psubw mm3,mm2 + movq [BUF+0x40],mm0 + psraw mm5,2 + psubw mm1,mm2 + movq [BUF+0x50],mm5 + psraw mm3,2 + psubw mm7,mm2 + movq [BUF+0x60],mm3 + psraw mm1,2 + psubw mm4,mm2 + movq [BUF+0x70],mm1 psraw mm7,2 + movq [BUF+0x10],mm7 + psraw mm4,2 + movq [BUF+0x30],mm4 + /*Load the next block.*/ movq mm0,[0x40+Y] - psraw mm1,2 - movq [0x30+Y],mm7 movq mm7,[0x78+Y] - movq [0x08+Y],mm1 movq mm1,[0x50+Y] - movq [0x20+Y],mm6 movq mm6,[0x68+Y] - movq [0x28+Y],mm2 movq mm2,[0x60+Y] - movq [0x10+Y],mm5 movq mm5,[0x58+Y] - movq [0x38+Y],mm3 movq mm3,[0x70+Y] - movq [0x00+Y],mm4 movq mm4,[0x48+Y] OC_FDCT_STAGE1_8x4 OC_FDCT8x4(0x40,0x50,0x60,0x70,0x48,0x58,0x68,0x78) - OC_TRANSPOSE8x4(0x40,0x50,0x60,0x70,0x48,0x58,0x68,0x78) /*mm0={-2}x4*/ - pcmpeqw mm0,mm0 - paddw mm0,mm0 - /*Round the results.*/ - psubw mm1,mm0 - psubw mm2,mm0 - psraw mm1,2 - psubw mm3,mm0 - movq [0x58+Y],mm1 - psraw mm2,2 - psubw mm4,mm0 - movq mm1,[0x48+Y] - psraw mm3,2 - psubw mm5,mm0 - movq [0x68+Y],mm2 + pcmpeqw mm2,mm2 + paddw mm2,mm2 + /*Round and store the results (no transpose).*/ + movq mm7,[Y+0x50] + psubw mm4,mm2 + psubw mm6,mm2 psraw mm4,2 - psubw mm6,mm0 - movq [0x78+Y],mm3 - psraw mm5,2 - psubw mm7,mm0 - movq [0x40+Y],mm4 + psubw mm0,mm2 + movq [BUF+0x08],mm4 + movq mm4,[Y+0x70] psraw mm6,2 - psubw mm1,mm0 - movq [0x50+Y],mm5 - psraw mm7,2 - movq [0x60+Y],mm6 + psubw mm5,mm2 + movq [BUF+0x28],mm6 + psraw mm0,2 + psubw mm3,mm2 + movq [BUF+0x48],mm0 + psraw mm5,2 + psubw mm1,mm2 + movq [BUF+0x58],mm5 + psraw mm3,2 + psubw mm7,mm2 + movq [BUF+0x68],mm3 psraw mm1,2 - movq [0x70+Y],mm7 - movq [0x48+Y],mm1 + psubw mm4,mm2 + movq [BUF+0x78],mm1 + psraw mm7,2 + movq [BUF+0x18],mm7 + psraw mm4,2 + movq [BUF+0x38],mm4 +#define OC_ZZ_LOAD_ROW_LO(_row,_reg) \ + __asm movq _reg,[BUF+16*(_row)] \ + +#define OC_ZZ_LOAD_ROW_HI(_row,_reg) \ + __asm movq _reg,[BUF+16*(_row)+8] \ + + OC_TRANSPOSE_ZIG_ZAG_MMXEXT +#undef OC_ZZ_LOAD_ROW_LO +#undef OC_ZZ_LOAD_ROW_HI +#undef X #undef Y #undef A -#undef X +#undef BUF } } diff --git a/thirdparty/libtheora/x86_vc/mmxfrag.c b/thirdparty/libtheora/x86_vc/mmxfrag.c index 4eb2084dc6..248312ff90 100644 --- a/thirdparty/libtheora/x86_vc/mmxfrag.c +++ b/thirdparty/libtheora/x86_vc/mmxfrag.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: mmxfrag.c 16578 2009-09-25 19:50:48Z cristianadam $ + last mod: $Id$ ********************************************************************/ @@ -22,12 +22,63 @@ The iteration each instruction belongs to is marked in the comments as #i.*/ #include <stddef.h> #include "x86int.h" -#include "mmxfrag.h" #if defined(OC_X86_ASM) /*Copies an 8x8 block of pixels from _src to _dst, assuming _ystride bytes between rows.*/ +# define OC_FRAG_COPY_MMX(_dst,_src,_ystride) \ + do{ \ + const unsigned char *src; \ + unsigned char *dst; \ + src=(_src); \ + dst=(_dst); \ + __asm mov SRC,src \ + __asm mov DST,dst \ + __asm mov YSTRIDE,_ystride \ + /*src+0*ystride*/ \ + __asm movq mm0,[SRC] \ + /*src+1*ystride*/ \ + __asm movq mm1,[SRC+YSTRIDE] \ + /*ystride3=ystride*3*/ \ + __asm lea YSTRIDE3,[YSTRIDE+YSTRIDE*2] \ + /*src+2*ystride*/ \ + __asm movq mm2,[SRC+YSTRIDE*2] \ + /*src+3*ystride*/ \ + __asm movq mm3,[SRC+YSTRIDE3] \ + /*dst+0*ystride*/ \ + __asm movq [DST],mm0 \ + /*dst+1*ystride*/ \ + __asm movq [DST+YSTRIDE],mm1 \ + /*Pointer to next 4.*/ \ + __asm lea SRC,[SRC+YSTRIDE*4] \ + /*dst+2*ystride*/ \ + __asm movq [DST+YSTRIDE*2],mm2 \ + /*dst+3*ystride*/ \ + __asm movq [DST+YSTRIDE3],mm3 \ + /*Pointer to next 4.*/ \ + __asm lea DST,[DST+YSTRIDE*4] \ + /*src+0*ystride*/ \ + __asm movq mm0,[SRC] \ + /*src+1*ystride*/ \ + __asm movq mm1,[SRC+YSTRIDE] \ + /*src+2*ystride*/ \ + __asm movq mm2,[SRC+YSTRIDE*2] \ + /*src+3*ystride*/ \ + __asm movq mm3,[SRC+YSTRIDE3] \ + /*dst+0*ystride*/ \ + __asm movq [DST],mm0 \ + /*dst+1*ystride*/ \ + __asm movq [DST+YSTRIDE],mm1 \ + /*dst+2*ystride*/ \ + __asm movq [DST+YSTRIDE*2],mm2 \ + /*dst+3*ystride*/ \ + __asm movq [DST+YSTRIDE3],mm3 \ + } \ + while(0) + +/*Copies an 8x8 block of pixels from _src to _dst, assuming _ystride bytes + between rows.*/ void oc_frag_copy_mmx(unsigned char *_dst, const unsigned char *_src,int _ystride){ #define SRC edx @@ -41,6 +92,34 @@ void oc_frag_copy_mmx(unsigned char *_dst, #undef YSTRIDE3 } +/*Copies the fragments specified by the lists of fragment indices from one + frame to another. + _dst_frame: The reference frame to copy to. + _src_frame: The reference frame to copy from. + _ystride: The row stride of the reference frames. + _fragis: A pointer to a list of fragment indices. + _nfragis: The number of fragment indices to copy. + _frag_buf_offs: The offsets of fragments in the reference frames.*/ +void oc_frag_copy_list_mmx(unsigned char *_dst_frame, + const unsigned char *_src_frame,int _ystride, + const ptrdiff_t *_fragis,ptrdiff_t _nfragis,const ptrdiff_t *_frag_buf_offs){ + ptrdiff_t fragii; + for(fragii=0;fragii<_nfragis;fragii++){ + ptrdiff_t frag_buf_off; + frag_buf_off=_frag_buf_offs[_fragis[fragii]]; +#define SRC edx +#define DST eax +#define YSTRIDE ecx +#define YSTRIDE3 edi + OC_FRAG_COPY_MMX(_dst_frame+frag_buf_off, + _src_frame+frag_buf_off,_ystride); +#undef SRC +#undef DST +#undef YSTRIDE +#undef YSTRIDE3 + } +} + void oc_frag_recon_intra_mmx(unsigned char *_dst,int _ystride, const ogg_int16_t *_residue){ __asm{ diff --git a/thirdparty/libtheora/x86_vc/mmxfrag.h b/thirdparty/libtheora/x86_vc/mmxfrag.h deleted file mode 100644 index 45ee93e777..0000000000 --- a/thirdparty/libtheora/x86_vc/mmxfrag.h +++ /dev/null @@ -1,61 +0,0 @@ -#if !defined(_x86_vc_mmxfrag_H) -# define _x86_vc_mmxfrag_H (1) -# include <stddef.h> -# include "x86int.h" - -#if defined(OC_X86_ASM) - -/*Copies an 8x8 block of pixels from _src to _dst, assuming _ystride bytes - between rows.*/ -#define OC_FRAG_COPY_MMX(_dst,_src,_ystride) \ - do{ \ - const unsigned char *src; \ - unsigned char *dst; \ - src=(_src); \ - dst=(_dst); \ - __asm mov SRC,src \ - __asm mov DST,dst \ - __asm mov YSTRIDE,_ystride \ - /*src+0*ystride*/ \ - __asm movq mm0,[SRC] \ - /*src+1*ystride*/ \ - __asm movq mm1,[SRC+YSTRIDE] \ - /*ystride3=ystride*3*/ \ - __asm lea YSTRIDE3,[YSTRIDE+YSTRIDE*2] \ - /*src+2*ystride*/ \ - __asm movq mm2,[SRC+YSTRIDE*2] \ - /*src+3*ystride*/ \ - __asm movq mm3,[SRC+YSTRIDE3] \ - /*dst+0*ystride*/ \ - __asm movq [DST],mm0 \ - /*dst+1*ystride*/ \ - __asm movq [DST+YSTRIDE],mm1 \ - /*Pointer to next 4.*/ \ - __asm lea SRC,[SRC+YSTRIDE*4] \ - /*dst+2*ystride*/ \ - __asm movq [DST+YSTRIDE*2],mm2 \ - /*dst+3*ystride*/ \ - __asm movq [DST+YSTRIDE3],mm3 \ - /*Pointer to next 4.*/ \ - __asm lea DST,[DST+YSTRIDE*4] \ - /*src+0*ystride*/ \ - __asm movq mm0,[SRC] \ - /*src+1*ystride*/ \ - __asm movq mm1,[SRC+YSTRIDE] \ - /*src+2*ystride*/ \ - __asm movq mm2,[SRC+YSTRIDE*2] \ - /*src+3*ystride*/ \ - __asm movq mm3,[SRC+YSTRIDE3] \ - /*dst+0*ystride*/ \ - __asm movq [DST],mm0 \ - /*dst+1*ystride*/ \ - __asm movq [DST+YSTRIDE],mm1 \ - /*dst+2*ystride*/ \ - __asm movq [DST+YSTRIDE*2],mm2 \ - /*dst+3*ystride*/ \ - __asm movq [DST+YSTRIDE3],mm3 \ - } \ - while(0) - -# endif -#endif diff --git a/thirdparty/libtheora/x86_vc/mmxidct.c b/thirdparty/libtheora/x86_vc/mmxidct.c index 8f5ff6803c..55e00aedcf 100644 --- a/thirdparty/libtheora/x86_vc/mmxidct.c +++ b/thirdparty/libtheora/x86_vc/mmxidct.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: mmxidct.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ @@ -24,15 +24,15 @@ /*These are offsets into the table of constants below.*/ /*7 rows of cosines, in order: pi/16 * (1 ... 7).*/ -#define OC_COSINE_OFFSET (0) +#define OC_COSINE_OFFSET (8) /*A row of 8's.*/ -#define OC_EIGHT_OFFSET (56) +#define OC_EIGHT_OFFSET (0) /*A table of constants used by the MMX routines.*/ -static const __declspec(align(16))ogg_uint16_t - OC_IDCT_CONSTS[(7+1)*4]={ +static const OC_ALIGN16(ogg_uint16_t) OC_IDCT_CONSTS[(1+7)*4]={ + 8, 8, 8, 8, (ogg_uint16_t)OC_C1S7,(ogg_uint16_t)OC_C1S7, (ogg_uint16_t)OC_C1S7,(ogg_uint16_t)OC_C1S7, (ogg_uint16_t)OC_C2S6,(ogg_uint16_t)OC_C2S6, @@ -46,28 +46,27 @@ static const __declspec(align(16))ogg_uint16_t (ogg_uint16_t)OC_C6S2,(ogg_uint16_t)OC_C6S2, (ogg_uint16_t)OC_C6S2,(ogg_uint16_t)OC_C6S2, (ogg_uint16_t)OC_C7S1,(ogg_uint16_t)OC_C7S1, - (ogg_uint16_t)OC_C7S1,(ogg_uint16_t)OC_C7S1, - 8, 8, 8, 8 + (ogg_uint16_t)OC_C7S1,(ogg_uint16_t)OC_C7S1 }; /*38 cycles*/ -#define OC_IDCT_BEGIN __asm{ \ - __asm movq mm2,OC_I(3) \ +#define OC_IDCT_BEGIN(_y,_x) __asm{ \ + __asm movq mm2,OC_I(3,_x) \ __asm movq mm6,OC_C(3) \ __asm movq mm4,mm2 \ - __asm movq mm7,OC_J(5) \ + __asm movq mm7,OC_J(5,_x) \ __asm pmulhw mm4,mm6 \ __asm movq mm1,OC_C(5) \ __asm pmulhw mm6,mm7 \ __asm movq mm5,mm1 \ __asm pmulhw mm1,mm2 \ - __asm movq mm3,OC_I(1) \ + __asm movq mm3,OC_I(1,_x) \ __asm pmulhw mm5,mm7 \ __asm movq mm0,OC_C(1) \ __asm paddw mm4,mm2 \ __asm paddw mm6,mm7 \ __asm paddw mm2,mm1 \ - __asm movq mm1,OC_J(7) \ + __asm movq mm1,OC_J(7,_x) \ __asm paddw mm7,mm5 \ __asm movq mm5,mm0 \ __asm pmulhw mm0,mm3 \ @@ -77,13 +76,13 @@ static const __declspec(align(16))ogg_uint16_t __asm psubw mm6,mm2 \ __asm paddw mm0,mm3 \ __asm pmulhw mm3,mm7 \ - __asm movq mm2,OC_I(2) \ + __asm movq mm2,OC_I(2,_x) \ __asm pmulhw mm7,mm1 \ __asm paddw mm5,mm1 \ __asm movq mm1,mm2 \ __asm pmulhw mm2,OC_C(2) \ __asm psubw mm3,mm5 \ - __asm movq mm5,OC_J(6) \ + __asm movq mm5,OC_J(6,_x) \ __asm paddw mm0,mm7 \ __asm movq mm7,mm5 \ __asm psubw mm0,mm4 \ @@ -97,18 +96,18 @@ static const __declspec(align(16))ogg_uint16_t __asm paddw mm6,mm6 \ __asm pmulhw mm7,OC_C(6) \ __asm paddw mm6,mm3 \ - __asm movq OC_I(1),mm4 \ + __asm movq OC_I(1,_y),mm4 \ __asm psubw mm1,mm5 \ __asm movq mm4,OC_C(4) \ __asm movq mm5,mm3 \ __asm pmulhw mm3,mm4 \ __asm paddw mm7,mm2 \ - __asm movq OC_I(2),mm6 \ + __asm movq OC_I(2,_y),mm6 \ __asm movq mm2,mm0 \ - __asm movq mm6,OC_I(0) \ + __asm movq mm6,OC_I(0,_x) \ __asm pmulhw mm0,mm4 \ __asm paddw mm5,mm3 \ - __asm movq mm3,OC_J(4) \ + __asm movq mm3,OC_J(4,_x) \ __asm psubw mm5,mm1 \ __asm paddw mm2,mm0 \ __asm psubw mm6,mm3 \ @@ -122,17 +121,17 @@ static const __declspec(align(16))ogg_uint16_t __asm paddw mm6,mm0 \ __asm psubw mm6,mm2 \ __asm paddw mm2,mm2 \ - __asm movq mm0,OC_I(1) \ + __asm movq mm0,OC_I(1,_y) \ __asm paddw mm2,mm6 \ __asm paddw mm4,mm3 \ __asm psubw mm2,mm1 \ } /*38+8=46 cycles.*/ -#define OC_ROW_IDCT __asm{ \ - OC_IDCT_BEGIN \ +#define OC_ROW_IDCT(_y,_x) __asm{ \ + OC_IDCT_BEGIN(_y,_x) \ /*r3=D'*/ \ - __asm movq mm3,OC_I(2) \ + __asm movq mm3,OC_I(2,_y) \ /*r4=E'=E-G*/ \ __asm psubw mm4,mm7 \ /*r1=H'+H'*/ \ @@ -157,7 +156,7 @@ static const __declspec(align(16))ogg_uint16_t __asm psubw mm7,mm0 \ __asm paddw mm0,mm0 \ /*Save R1.*/ \ - __asm movq OC_I(1),mm1 \ + __asm movq OC_I(1,_y),mm1 \ /*r0=R0=G.+C.*/ \ __asm paddw mm0,mm7 \ } @@ -190,10 +189,10 @@ static const __declspec(align(16))ogg_uint16_t Since r1 is free at entry, we calculate the Js first.*/ /*19 cycles.*/ -#define OC_TRANSPOSE __asm{ \ +#define OC_TRANSPOSE(_y) __asm{ \ __asm movq mm1,mm4 \ __asm punpcklwd mm4,mm5 \ - __asm movq OC_I(0),mm0 \ + __asm movq OC_I(0,_y),mm0 \ __asm punpckhwd mm1,mm5 \ __asm movq mm0,mm6 \ __asm punpcklwd mm6,mm7 \ @@ -201,17 +200,17 @@ static const __declspec(align(16))ogg_uint16_t __asm punpckldq mm4,mm6 \ __asm punpckhdq mm5,mm6 \ __asm movq mm6,mm1 \ - __asm movq OC_J(4),mm4 \ + __asm movq OC_J(4,_y),mm4 \ __asm punpckhwd mm0,mm7 \ - __asm movq OC_J(5),mm5 \ + __asm movq OC_J(5,_y),mm5 \ __asm punpckhdq mm6,mm0 \ - __asm movq mm4,OC_I(0) \ + __asm movq mm4,OC_I(0,_y) \ __asm punpckldq mm1,mm0 \ - __asm movq mm5,OC_I(1) \ + __asm movq mm5,OC_I(1,_y) \ __asm movq mm0,mm4 \ - __asm movq OC_J(7),mm6 \ + __asm movq OC_J(7,_y),mm6 \ __asm punpcklwd mm0,mm5 \ - __asm movq OC_J(6),mm1 \ + __asm movq OC_J(6,_y),mm1 \ __asm punpckhwd mm4,mm5 \ __asm movq mm5,mm2 \ __asm punpcklwd mm2,mm3 \ @@ -219,18 +218,18 @@ static const __declspec(align(16))ogg_uint16_t __asm punpckldq mm0,mm2 \ __asm punpckhdq mm1,mm2 \ __asm movq mm2,mm4 \ - __asm movq OC_I(0),mm0 \ + __asm movq OC_I(0,_y),mm0 \ __asm punpckhwd mm5,mm3 \ - __asm movq OC_I(1),mm1 \ + __asm movq OC_I(1,_y),mm1 \ __asm punpckhdq mm4,mm5 \ __asm punpckldq mm2,mm5 \ - __asm movq OC_I(3),mm4 \ - __asm movq OC_I(2),mm2 \ + __asm movq OC_I(3,_y),mm4 \ + __asm movq OC_I(2,_y),mm2 \ } /*38+19=57 cycles.*/ -#define OC_COLUMN_IDCT __asm{ \ - OC_IDCT_BEGIN \ +#define OC_COLUMN_IDCT(_y) __asm{ \ + OC_IDCT_BEGIN(_y,_y) \ __asm paddw mm2,OC_8 \ /*r1=H'+H'*/ \ __asm paddw mm1,mm1 \ @@ -243,15 +242,15 @@ static const __declspec(align(16))ogg_uint16_t /*r1=NR1*/ \ __asm psraw mm1,4 \ /*r3=D'*/ \ - __asm movq mm3,OC_I(2) \ + __asm movq mm3,OC_I(2,_y) \ /*r7=G+G*/ \ __asm paddw mm7,mm7 \ /*Store NR2 at I(2).*/ \ - __asm movq OC_I(2),mm2 \ + __asm movq OC_I(2,_y),mm2 \ /*r7=G'=E+G*/ \ __asm paddw mm7,mm4 \ /*Store NR1 at I(1).*/ \ - __asm movq OC_I(1),mm1 \ + __asm movq OC_I(1,_y),mm1 \ /*r4=R4=E'-D'*/ \ __asm psubw mm4,mm3 \ __asm paddw mm4,OC_8 \ @@ -273,11 +272,11 @@ static const __declspec(align(16))ogg_uint16_t /*r6=NR6*/ \ __asm psraw mm6,4 \ /*Store NR4 at J(4).*/ \ - __asm movq OC_J(4),mm4 \ + __asm movq OC_J(4,_y),mm4 \ /*r5=NR5*/ \ __asm psraw mm5,4 \ /*Store NR3 at I(3).*/ \ - __asm movq OC_I(3),mm3 \ + __asm movq OC_I(3,_y),mm3 \ /*r7=R7=G'-C'*/ \ __asm psubw mm7,mm0 \ __asm paddw mm7,OC_8 \ @@ -288,71 +287,89 @@ static const __declspec(align(16))ogg_uint16_t /*r7=NR7*/ \ __asm psraw mm7,4 \ /*Store NR6 at J(6).*/ \ - __asm movq OC_J(6),mm6 \ + __asm movq OC_J(6,_y),mm6 \ /*r0=NR0*/ \ __asm psraw mm0,4 \ /*Store NR5 at J(5).*/ \ - __asm movq OC_J(5),mm5 \ + __asm movq OC_J(5,_y),mm5 \ /*Store NR7 at J(7).*/ \ - __asm movq OC_J(7),mm7 \ + __asm movq OC_J(7,_y),mm7 \ /*Store NR0 at I(0).*/ \ - __asm movq OC_I(0),mm0 \ + __asm movq OC_I(0,_y),mm0 \ } #define OC_MID(_m,_i) [CONSTS+_m+(_i)*8] #define OC_C(_i) OC_MID(OC_COSINE_OFFSET,_i-1) #define OC_8 OC_MID(OC_EIGHT_OFFSET,0) -static void oc_idct8x8_slow(ogg_int16_t _y[64]){ +static void oc_idct8x8_slow(ogg_int16_t _y[64],ogg_int16_t _x[64]){ + int i; /*This routine accepts an 8x8 matrix, but in partially transposed form. Every 4x4 block is transposed.*/ __asm{ #define CONSTS eax #define Y edx +#define X ecx mov CONSTS,offset OC_IDCT_CONSTS mov Y,_y -#define OC_I(_k) [Y+_k*16] -#define OC_J(_k) [Y+(_k-4)*16+8] - OC_ROW_IDCT - OC_TRANSPOSE + mov X,_x +#define OC_I(_k,_y) [(_y)+(_k)*16] +#define OC_J(_k,_y) [(_y)+((_k)-4)*16+8] + OC_ROW_IDCT(Y,X) + OC_TRANSPOSE(Y) #undef OC_I #undef OC_J -#define OC_I(_k) [Y+(_k*16)+64] -#define OC_J(_k) [Y+(_k-4)*16+72] - OC_ROW_IDCT - OC_TRANSPOSE +#define OC_I(_k,_y) [(_y)+(_k)*16+64] +#define OC_J(_k,_y) [(_y)+((_k)-4)*16+72] + OC_ROW_IDCT(Y,X) + OC_TRANSPOSE(Y) #undef OC_I #undef OC_J -#define OC_I(_k) [Y+_k*16] -#define OC_J(_k) OC_I(_k) - OC_COLUMN_IDCT +#define OC_I(_k,_y) [(_y)+(_k)*16] +#define OC_J(_k,_y) OC_I(_k,_y) + OC_COLUMN_IDCT(Y) #undef OC_I #undef OC_J -#define OC_I(_k) [Y+_k*16+8] -#define OC_J(_k) OC_I(_k) - OC_COLUMN_IDCT +#define OC_I(_k,_y) [(_y)+(_k)*16+8] +#define OC_J(_k,_y) OC_I(_k,_y) + OC_COLUMN_IDCT(Y) #undef OC_I #undef OC_J #undef CONSTS #undef Y +#undef X + } + __asm pxor mm0,mm0; + for(i=0;i<4;i++){ + ogg_int16_t *x; + x=_x+16*i; +#define X ecx + __asm{ + mov X,x + movq [X+0x00],mm0 + movq [X+0x08],mm0 + movq [X+0x10],mm0 + movq [X+0x18],mm0 + } +#undef X } } /*25 cycles.*/ -#define OC_IDCT_BEGIN_10 __asm{ \ - __asm movq mm2,OC_I(3) \ +#define OC_IDCT_BEGIN_10(_y,_x) __asm{ \ + __asm movq mm2,OC_I(3,_x) \ __asm nop \ __asm movq mm6,OC_C(3) \ __asm movq mm4,mm2 \ __asm movq mm1,OC_C(5) \ __asm pmulhw mm4,mm6 \ - __asm movq mm3,OC_I(1) \ + __asm movq mm3,OC_I(1,_x) \ __asm pmulhw mm1,mm2 \ __asm movq mm0,OC_C(1) \ __asm paddw mm4,mm2 \ __asm pxor mm6,mm6 \ __asm paddw mm2,mm1 \ - __asm movq mm5,OC_I(2) \ + __asm movq mm5,OC_I(2,_x) \ __asm pmulhw mm0,mm3 \ __asm movq mm1,mm5 \ __asm paddw mm0,mm3 \ @@ -360,43 +377,43 @@ static void oc_idct8x8_slow(ogg_int16_t _y[64]){ __asm psubw mm6,mm2 \ __asm pmulhw mm5,OC_C(2) \ __asm psubw mm0,mm4 \ - __asm movq mm7,OC_I(2) \ + __asm movq mm7,OC_I(2,_x) \ __asm paddw mm4,mm4 \ __asm paddw mm7,mm5 \ __asm paddw mm4,mm0 \ __asm pmulhw mm1,OC_C(6) \ __asm psubw mm3,mm6 \ - __asm movq OC_I(1),mm4 \ + __asm movq OC_I(1,_y),mm4 \ __asm paddw mm6,mm6 \ __asm movq mm4,OC_C(4) \ __asm paddw mm6,mm3 \ __asm movq mm5,mm3 \ __asm pmulhw mm3,mm4 \ - __asm movq OC_I(2),mm6 \ + __asm movq OC_I(2,_y),mm6 \ __asm movq mm2,mm0 \ - __asm movq mm6,OC_I(0) \ + __asm movq mm6,OC_I(0,_x) \ __asm pmulhw mm0,mm4 \ __asm paddw mm5,mm3 \ __asm paddw mm2,mm0 \ __asm psubw mm5,mm1 \ __asm pmulhw mm6,mm4 \ - __asm paddw mm6,OC_I(0) \ + __asm paddw mm6,OC_I(0,_x) \ __asm paddw mm1,mm1 \ __asm movq mm4,mm6 \ __asm paddw mm1,mm5 \ __asm psubw mm6,mm2 \ __asm paddw mm2,mm2 \ - __asm movq mm0,OC_I(1) \ + __asm movq mm0,OC_I(1,_y) \ __asm paddw mm2,mm6 \ __asm psubw mm2,mm1 \ __asm nop \ } /*25+8=33 cycles.*/ -#define OC_ROW_IDCT_10 __asm{ \ - OC_IDCT_BEGIN_10 \ +#define OC_ROW_IDCT_10(_y,_x) __asm{ \ + OC_IDCT_BEGIN_10(_y,_x) \ /*r3=D'*/ \ - __asm movq mm3,OC_I(2) \ + __asm movq mm3,OC_I(2,_y) \ /*r4=E'=E-G*/ \ __asm psubw mm4,mm7 \ /*r1=H'+H'*/ \ @@ -421,14 +438,14 @@ static void oc_idct8x8_slow(ogg_int16_t _y[64]){ __asm psubw mm7,mm0 \ __asm paddw mm0,mm0 \ /*Save R1.*/ \ - __asm movq OC_I(1),mm1 \ + __asm movq OC_I(1,_y),mm1 \ /*r0=R0=G'+C'*/ \ __asm paddw mm0,mm7 \ } /*25+19=44 cycles'*/ -#define OC_COLUMN_IDCT_10 __asm{ \ - OC_IDCT_BEGIN_10 \ +#define OC_COLUMN_IDCT_10(_y) __asm{ \ + OC_IDCT_BEGIN_10(_y,_y) \ __asm paddw mm2,OC_8 \ /*r1=H'+H'*/ \ __asm paddw mm1,mm1 \ @@ -441,15 +458,15 @@ static void oc_idct8x8_slow(ogg_int16_t _y[64]){ /*r1=NR1*/ \ __asm psraw mm1,4 \ /*r3=D'*/ \ - __asm movq mm3,OC_I(2) \ + __asm movq mm3,OC_I(2,_y) \ /*r7=G+G*/ \ __asm paddw mm7,mm7 \ /*Store NR2 at I(2).*/ \ - __asm movq OC_I(2),mm2 \ + __asm movq OC_I(2,_y),mm2 \ /*r7=G'=E+G*/ \ __asm paddw mm7,mm4 \ /*Store NR1 at I(1).*/ \ - __asm movq OC_I(1),mm1 \ + __asm movq OC_I(1,_y),mm1 \ /*r4=R4=E'-D'*/ \ __asm psubw mm4,mm3 \ __asm paddw mm4,OC_8 \ @@ -471,11 +488,11 @@ static void oc_idct8x8_slow(ogg_int16_t _y[64]){ /*r6=NR6*/ \ __asm psraw mm6,4 \ /*Store NR4 at J(4).*/ \ - __asm movq OC_J(4),mm4 \ + __asm movq OC_J(4,_y),mm4 \ /*r5=NR5*/ \ __asm psraw mm5,4 \ /*Store NR3 at I(3).*/ \ - __asm movq OC_I(3),mm3 \ + __asm movq OC_I(3,_y),mm3 \ /*r7=R7=G'-C'*/ \ __asm psubw mm7,mm0 \ __asm paddw mm7,OC_8 \ @@ -486,50 +503,63 @@ static void oc_idct8x8_slow(ogg_int16_t _y[64]){ /*r7=NR7*/ \ __asm psraw mm7,4 \ /*Store NR6 at J(6).*/ \ - __asm movq OC_J(6),mm6 \ + __asm movq OC_J(6,_y),mm6 \ /*r0=NR0*/ \ __asm psraw mm0,4 \ /*Store NR5 at J(5).*/ \ - __asm movq OC_J(5),mm5 \ + __asm movq OC_J(5,_y),mm5 \ /*Store NR7 at J(7).*/ \ - __asm movq OC_J(7),mm7 \ + __asm movq OC_J(7,_y),mm7 \ /*Store NR0 at I(0).*/ \ - __asm movq OC_I(0),mm0 \ + __asm movq OC_I(0,_y),mm0 \ } -static void oc_idct8x8_10(ogg_int16_t _y[64]){ +static void oc_idct8x8_10(ogg_int16_t _y[64],ogg_int16_t _x[64]){ __asm{ #define CONSTS eax #define Y edx +#define X ecx mov CONSTS,offset OC_IDCT_CONSTS mov Y,_y -#define OC_I(_k) [Y+_k*16] -#define OC_J(_k) [Y+(_k-4)*16+8] + mov X,_x +#define OC_I(_k,_y) [(_y)+(_k)*16] +#define OC_J(_k,_y) [(_y)+((_k)-4)*16+8] /*Done with dequant, descramble, and partial transpose. Now do the iDCT itself.*/ - OC_ROW_IDCT_10 - OC_TRANSPOSE + OC_ROW_IDCT_10(Y,X) + OC_TRANSPOSE(Y) #undef OC_I #undef OC_J -#define OC_I(_k) [Y+_k*16] -#define OC_J(_k) OC_I(_k) - OC_COLUMN_IDCT_10 +#define OC_I(_k,_y) [(_y)+(_k)*16] +#define OC_J(_k,_y) OC_I(_k,_y) + OC_COLUMN_IDCT_10(Y) #undef OC_I #undef OC_J -#define OC_I(_k) [Y+_k*16+8] -#define OC_J(_k) OC_I(_k) - OC_COLUMN_IDCT_10 +#define OC_I(_k,_y) [(_y)+(_k)*16+8] +#define OC_J(_k,_y) OC_I(_k,_y) + OC_COLUMN_IDCT_10(Y) #undef OC_I #undef OC_J #undef CONSTS #undef Y +#undef X + } +#define X ecx + __asm{ + pxor mm0,mm0; + mov X,_x + movq [X+0x00],mm0 + movq [X+0x10],mm0 + movq [X+0x20],mm0 + movq [X+0x30],mm0 } +#undef X } /*Performs an inverse 8x8 Type-II DCT transform. The input is assumed to be scaled by a factor of 4 relative to orthonormal version of the transform.*/ -void oc_idct8x8_mmx(ogg_int16_t _y[64],int _last_zzi){ +void oc_idct8x8_mmx(ogg_int16_t _y[64],ogg_int16_t _x[64],int _last_zzi){ /*_last_zzi is subtly different from an actual count of the number of coefficients we decoded for this block. It contains the value of zzi BEFORE the final token in the block was @@ -555,8 +585,8 @@ void oc_idct8x8_mmx(ogg_int16_t _y[64],int _last_zzi){ gets. Needless to say we inherited this approach from VP3.*/ /*Perform the iDCT.*/ - if(_last_zzi<10)oc_idct8x8_10(_y); - else oc_idct8x8_slow(_y); + if(_last_zzi<=10)oc_idct8x8_10(_y,_x); + else oc_idct8x8_slow(_y,_x); } #endif diff --git a/thirdparty/libtheora/x86_vc/mmxstate.c b/thirdparty/libtheora/x86_vc/mmxstate.c index 73bd1981cf..f532ee1b6f 100644 --- a/thirdparty/libtheora/x86_vc/mmxstate.c +++ b/thirdparty/libtheora/x86_vc/mmxstate.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: mmxstate.c 16584 2009-09-26 19:35:55Z tterribe $ + last mod: $Id$ ********************************************************************/ @@ -19,17 +19,16 @@ Originally written by Rudolf Marek.*/ #include <string.h> #include "x86int.h" -#include "mmxfrag.h" #include "mmxloop.h" #if defined(OC_X86_ASM) void oc_state_frag_recon_mmx(const oc_theora_state *_state,ptrdiff_t _fragi, - int _pli,ogg_int16_t _dct_coeffs[64],int _last_zzi,ogg_uint16_t _dc_quant){ + int _pli,ogg_int16_t _dct_coeffs[128],int _last_zzi,ogg_uint16_t _dc_quant){ unsigned char *dst; ptrdiff_t frag_buf_off; int ystride; - int mb_mode; + int refi; /*Apply the inverse transform.*/ /*Special case only having a DC component.*/ if(_last_zzi<2){ @@ -45,6 +44,7 @@ void oc_state_frag_recon_mmx(const oc_theora_state *_state,ptrdiff_t _fragi, #define P ecx mov Y,_dct_coeffs movzx P,p + lea Y,[Y+128] /*mm0=0000 0000 0000 AAAA*/ movd mm0,P /*mm0=0000 0000 AAAA AAAA*/ @@ -74,65 +74,32 @@ void oc_state_frag_recon_mmx(const oc_theora_state *_state,ptrdiff_t _fragi, else{ /*Dequantize the DC coefficient.*/ _dct_coeffs[0]=(ogg_int16_t)(_dct_coeffs[0]*(int)_dc_quant); - oc_idct8x8_mmx(_dct_coeffs,_last_zzi); + oc_idct8x8_mmx(_dct_coeffs+64,_dct_coeffs,_last_zzi); } /*Fill in the target buffer.*/ frag_buf_off=_state->frag_buf_offs[_fragi]; - mb_mode=_state->frags[_fragi].mb_mode; + refi=_state->frags[_fragi].refi; ystride=_state->ref_ystride[_pli]; - dst=_state->ref_frame_data[_state->ref_frame_idx[OC_FRAME_SELF]]+frag_buf_off; - if(mb_mode==OC_MODE_INTRA)oc_frag_recon_intra_mmx(dst,ystride,_dct_coeffs); + dst=_state->ref_frame_data[OC_FRAME_SELF]+frag_buf_off; + if(refi==OC_FRAME_SELF)oc_frag_recon_intra_mmx(dst,ystride,_dct_coeffs+64); else{ const unsigned char *ref; int mvoffsets[2]; - ref= - _state->ref_frame_data[_state->ref_frame_idx[OC_FRAME_FOR_MODE(mb_mode)]] - +frag_buf_off; + ref=_state->ref_frame_data[refi]+frag_buf_off; if(oc_state_get_mv_offsets(_state,mvoffsets,_pli, - _state->frag_mvs[_fragi][0],_state->frag_mvs[_fragi][1])>1){ + _state->frag_mvs[_fragi])>1){ oc_frag_recon_inter2_mmx(dst,ref+mvoffsets[0],ref+mvoffsets[1],ystride, - _dct_coeffs); + _dct_coeffs+64); } - else oc_frag_recon_inter_mmx(dst,ref+mvoffsets[0],ystride,_dct_coeffs); + else oc_frag_recon_inter_mmx(dst,ref+mvoffsets[0],ystride,_dct_coeffs+64); } } /*We copy these entire function to inline the actual MMX routines so that we use only a single indirect call.*/ -/*Copies the fragments specified by the lists of fragment indices from one - frame to another. - _fragis: A pointer to a list of fragment indices. - _nfragis: The number of fragment indices to copy. - _dst_frame: The reference frame to copy to. - _src_frame: The reference frame to copy from. - _pli: The color plane the fragments lie in.*/ -void oc_state_frag_copy_list_mmx(const oc_theora_state *_state, - const ptrdiff_t *_fragis,ptrdiff_t _nfragis, - int _dst_frame,int _src_frame,int _pli){ - const ptrdiff_t *frag_buf_offs; - const unsigned char *src_frame_data; - unsigned char *dst_frame_data; - ptrdiff_t fragii; - int ystride; - dst_frame_data=_state->ref_frame_data[_state->ref_frame_idx[_dst_frame]]; - src_frame_data=_state->ref_frame_data[_state->ref_frame_idx[_src_frame]]; - ystride=_state->ref_ystride[_pli]; - frag_buf_offs=_state->frag_buf_offs; - for(fragii=0;fragii<_nfragis;fragii++){ - ptrdiff_t frag_buf_off; - frag_buf_off=frag_buf_offs[_fragis[fragii]]; -#define SRC edx -#define DST eax -#define YSTRIDE ecx -#define YSTRIDE3 edi - OC_FRAG_COPY_MMX(dst_frame_data+frag_buf_off, - src_frame_data+frag_buf_off,ystride); -#undef SRC -#undef DST -#undef YSTRIDE -#undef YSTRIDE3 - } +void oc_loop_filter_init_mmx(signed char _bv[256],int _flimit){ + memset(_bv,~(_flimit<<1),8); } /*Apply the loop filter to a given set of fragment rows in the given plane. @@ -144,8 +111,7 @@ void oc_state_frag_copy_list_mmx(const oc_theora_state *_state, _fragy0: The Y coordinate of the first fragment row to filter. _fragy_end: The Y coordinate of the fragment row to stop filtering at.*/ void oc_state_loop_filter_frag_rows_mmx(const oc_theora_state *_state, - int _bv[256],int _refi,int _pli,int _fragy0,int _fragy_end){ - OC_ALIGN8(unsigned char ll[8]); + signed char _bv[256],int _refi,int _pli,int _fragy0,int _fragy_end){ const oc_fragment_plane *fplane; const oc_fragment *frags; const ptrdiff_t *frag_buf_offs; @@ -156,13 +122,12 @@ void oc_state_loop_filter_frag_rows_mmx(const oc_theora_state *_state, ptrdiff_t fragi0_end; int ystride; int nhfrags; - memset(ll,_state->loop_filter_limits[_state->qis[0]],sizeof(ll)); fplane=_state->fplanes+_pli; nhfrags=fplane->nhfrags; fragi_top=fplane->froffset; fragi_bot=fragi_top+fplane->nfrags; fragi0=fragi_top+_fragy0*(ptrdiff_t)nhfrags; - fragi0_end=fragi0+(_fragy_end-_fragy0)*(ptrdiff_t)nhfrags; + fragi0_end=fragi_top+_fragy_end*(ptrdiff_t)nhfrags; ystride=_state->ref_ystride[_pli]; frags=_state->frags; frag_buf_offs=_state->frag_buf_offs; @@ -187,13 +152,13 @@ void oc_state_loop_filter_frag_rows_mmx(const oc_theora_state *_state, #define LL edx #define D esi #define D_WORD si - if(fragi>fragi0)OC_LOOP_FILTER_H_MMX(ref,ystride,ll); - if(fragi0>fragi_top)OC_LOOP_FILTER_V_MMX(ref,ystride,ll); + if(fragi>fragi0)OC_LOOP_FILTER_H_MMX(ref,ystride,_bv); + if(fragi0>fragi_top)OC_LOOP_FILTER_V_MMX(ref,ystride,_bv); if(fragi+1<fragi_end&&!frags[fragi+1].coded){ - OC_LOOP_FILTER_H_MMX(ref+8,ystride,ll); + OC_LOOP_FILTER_H_MMX(ref+8,ystride,_bv); } if(fragi+nhfrags<fragi_bot&&!frags[fragi+nhfrags].coded){ - OC_LOOP_FILTER_V_MMX(ref+(ystride<<3),ystride,ll); + OC_LOOP_FILTER_V_MMX(ref+(ystride<<3),ystride,_bv); } #undef PIX #undef YSTRIDE3 diff --git a/thirdparty/libtheora/cpu.c b/thirdparty/libtheora/x86_vc/x86cpu.c index a863aad7f3..6a1d8d850c 100644 --- a/thirdparty/libtheora/cpu.c +++ b/thirdparty/libtheora/x86_vc/x86cpu.c @@ -14,41 +14,17 @@ Originally written by Rudolf Marek. function: - last mod: $Id: cpu.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ -#include "cpu.h" +#include "x86cpu.h" #if !defined(OC_X86_ASM) -static ogg_uint32_t oc_cpu_flags_get(void){ +ogg_uint32_t oc_cpu_flags_get(void){ return 0; } #else -# if !defined(_MSC_VER) -# if defined(__amd64__)||defined(__x86_64__) -/*On x86-64, gcc seems to be able to figure out how to save %rbx for us when - compiling with -fPIC.*/ -# define cpuid(_op,_eax,_ebx,_ecx,_edx) \ - __asm__ __volatile__( \ - "cpuid\n\t" \ - :[eax]"=a"(_eax),[ebx]"=b"(_ebx),[ecx]"=c"(_ecx),[edx]"=d"(_edx) \ - :"a"(_op) \ - :"cc" \ - ) -# else -/*On x86-32, not so much.*/ -# define cpuid(_op,_eax,_ebx,_ecx,_edx) \ - __asm__ __volatile__( \ - "xchgl %%ebx,%[ebx]\n\t" \ - "cpuid\n\t" \ - "xchgl %%ebx,%[ebx]\n\t" \ - :[eax]"=a"(_eax),[ebx]"=r"(_ebx),[ecx]"=c"(_ecx),[edx]"=d"(_edx) \ - :"a"(_op) \ - :"cc" \ - ) -# endif -# else /*Why does MSVC need this complicated rigamarole? At this point I honestly do not care.*/ @@ -95,7 +71,6 @@ static void oc_detect_cpuid_helper(ogg_uint32_t *_eax,ogg_uint32_t *_ebx){ mov [ecx],ebx } } -# endif static ogg_uint32_t oc_parse_intel_flags(ogg_uint32_t _edx,ogg_uint32_t _ecx){ ogg_uint32_t flags; @@ -124,7 +99,7 @@ static ogg_uint32_t oc_parse_amd_flags(ogg_uint32_t _edx,ogg_uint32_t _ecx){ return flags; } -static ogg_uint32_t oc_cpu_flags_get(void){ +ogg_uint32_t oc_cpu_flags_get(void){ ogg_uint32_t flags; ogg_uint32_t eax; ogg_uint32_t ebx; @@ -132,25 +107,7 @@ static ogg_uint32_t oc_cpu_flags_get(void){ ogg_uint32_t edx; # if !defined(__amd64__)&&!defined(__x86_64__) /*Not all x86-32 chips support cpuid, so we have to check.*/ -# if !defined(_MSC_VER) - __asm__ __volatile__( - "pushfl\n\t" - "pushfl\n\t" - "popl %[a]\n\t" - "movl %[a],%[b]\n\t" - "xorl $0x200000,%[a]\n\t" - "pushl %[a]\n\t" - "popfl\n\t" - "pushfl\n\t" - "popl %[a]\n\t" - "popfl\n\t" - :[a]"=r"(eax),[b]"=r"(ebx) - : - :"cc" - ); -# else oc_detect_cpuid_helper(&eax,&ebx); -# endif /*No cpuid.*/ if(eax==ebx)return 0; # endif @@ -159,9 +116,18 @@ static ogg_uint32_t oc_cpu_flags_get(void){ if(ecx==0x6C65746E&&edx==0x49656E69&&ebx==0x756E6547|| /* 6 8 x M T e n i u n e G*/ ecx==0x3638784D&&edx==0x54656E69&&ebx==0x756E6547){ + int family; + int model; /*Intel, Transmeta (tested with Crusoe TM5800):*/ cpuid(1,eax,ebx,ecx,edx); flags=oc_parse_intel_flags(edx,ecx); + family=(eax>>8)&0xF; + model=(eax>>4)&0xF; + /*The SSE unit on the Pentium M and Core Duo is much slower than the MMX + unit, so don't use it.*/ + if(family==6&&(model==9||model==13||model==14)){ + flags&=~(OC_CPU_X86_SSE2|OC_CPU_X86_PNI); + } } /* D M A c i t n e h t u A*/ else if(ecx==0x444D4163&&edx==0x69746E65&&ebx==0x68747541|| diff --git a/thirdparty/libtheora/x86_vc/x86cpu.h b/thirdparty/libtheora/x86_vc/x86cpu.h new file mode 100644 index 0000000000..eea261d448 --- /dev/null +++ b/thirdparty/libtheora/x86_vc/x86cpu.h @@ -0,0 +1,36 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * + * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * + * * + ******************************************************************** + function: + last mod: $Id$ + + ********************************************************************/ + +#if !defined(_x86_vc_x86cpu_H) +# define _x86_vc_x86cpu_H (1) +#include "../internal.h" + +#define OC_CPU_X86_MMX (1<<0) +#define OC_CPU_X86_3DNOW (1<<1) +#define OC_CPU_X86_3DNOWEXT (1<<2) +#define OC_CPU_X86_MMXEXT (1<<3) +#define OC_CPU_X86_SSE (1<<4) +#define OC_CPU_X86_SSE2 (1<<5) +#define OC_CPU_X86_PNI (1<<6) +#define OC_CPU_X86_SSSE3 (1<<7) +#define OC_CPU_X86_SSE4_1 (1<<8) +#define OC_CPU_X86_SSE4_2 (1<<9) +#define OC_CPU_X86_SSE4A (1<<10) +#define OC_CPU_X86_SSE5 (1<<11) + +ogg_uint32_t oc_cpu_flags_get(void); + +#endif diff --git a/thirdparty/libtheora/x86_vc/x86enc.c b/thirdparty/libtheora/x86_vc/x86enc.c index e1960e1f0b..e9d59e85e3 100644 --- a/thirdparty/libtheora/x86_vc/x86enc.c +++ b/thirdparty/libtheora/x86_vc/x86enc.c @@ -18,27 +18,25 @@ #if defined(OC_X86_ASM) -#include "../cpu.c" - -void oc_enc_vtable_init_x86(oc_enc_ctx *_enc){ +void oc_enc_accel_init_x86(oc_enc_ctx *_enc){ ogg_uint32_t cpu_flags; - cpu_flags=oc_cpu_flags_get(); - oc_enc_vtable_init_c(_enc); + cpu_flags=_enc->state.cpu_flags; + oc_enc_accel_init_c(_enc); if(cpu_flags&OC_CPU_X86_MMX){ _enc->opt_vtable.frag_sub=oc_enc_frag_sub_mmx; _enc->opt_vtable.frag_sub_128=oc_enc_frag_sub_128_mmx; _enc->opt_vtable.frag_recon_intra=oc_frag_recon_intra_mmx; _enc->opt_vtable.frag_recon_inter=oc_frag_recon_inter_mmx; - _enc->opt_vtable.fdct8x8=oc_enc_fdct8x8_mmx; } if(cpu_flags&OC_CPU_X86_MMXEXT){ _enc->opt_vtable.frag_sad=oc_enc_frag_sad_mmxext; _enc->opt_vtable.frag_sad_thresh=oc_enc_frag_sad_thresh_mmxext; _enc->opt_vtable.frag_sad2_thresh=oc_enc_frag_sad2_thresh_mmxext; - _enc->opt_vtable.frag_satd_thresh=oc_enc_frag_satd_thresh_mmxext; - _enc->opt_vtable.frag_satd2_thresh=oc_enc_frag_satd2_thresh_mmxext; + _enc->opt_vtable.frag_satd=oc_enc_frag_satd_mmxext; + _enc->opt_vtable.frag_satd2=oc_enc_frag_satd2_mmxext; _enc->opt_vtable.frag_intra_satd=oc_enc_frag_intra_satd_mmxext; _enc->opt_vtable.frag_copy2=oc_enc_frag_copy2_mmxext; + _enc->opt_vtable.fdct8x8=oc_enc_fdct8x8_mmxext; } if(cpu_flags&OC_CPU_X86_SSE2){ # if defined(OC_X86_64_ASM) diff --git a/thirdparty/libtheora/x86_vc/x86enc.h b/thirdparty/libtheora/x86_vc/x86enc.h index 581484641f..885406a54d 100644 --- a/thirdparty/libtheora/x86_vc/x86enc.h +++ b/thirdparty/libtheora/x86_vc/x86enc.h @@ -17,10 +17,14 @@ #if !defined(_x86_vc_x86enc_H) # define _x86_vc_x86enc_H (1) -# include "../encint.h" # include "x86int.h" +# if defined(OC_X86_ASM) +# define oc_enc_accel_init oc_enc_accel_init_x86 +# define OC_ENC_USE_VTABLE (1) +# endif +# include "../encint.h" -void oc_enc_vtable_init_x86(oc_enc_ctx *_enc); +void oc_enc_accel_init_x86(oc_enc_ctx *_enc); unsigned oc_enc_frag_sad_mmxext(const unsigned char *_src, const unsigned char *_ref,int _ystride); @@ -29,19 +33,19 @@ unsigned oc_enc_frag_sad_thresh_mmxext(const unsigned char *_src, unsigned oc_enc_frag_sad2_thresh_mmxext(const unsigned char *_src, const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, unsigned _thresh); -unsigned oc_enc_frag_satd_thresh_mmxext(const unsigned char *_src, - const unsigned char *_ref,int _ystride,unsigned _thresh); -unsigned oc_enc_frag_satd2_thresh_mmxext(const unsigned char *_src, - const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, - unsigned _thresh); -unsigned oc_enc_frag_intra_satd_mmxext(const unsigned char *_src,int _ystride); +unsigned oc_enc_frag_satd_mmxext(unsigned *_dc,const unsigned char *_src, + const unsigned char *_ref,int _ystride); +unsigned oc_enc_frag_satd2_mmxext(unsigned *_dc,const unsigned char *_src, + const unsigned char *_ref1,const unsigned char *_ref2,int _ystride); +unsigned oc_enc_frag_intra_satd_mmxext(unsigned *_dc, + const unsigned char *_src,int _ystride); void oc_enc_frag_sub_mmx(ogg_int16_t _diff[64], const unsigned char *_x,const unsigned char *_y,int _stride); void oc_enc_frag_sub_128_mmx(ogg_int16_t _diff[64], const unsigned char *_x,int _stride); void oc_enc_frag_copy2_mmxext(unsigned char *_dst, const unsigned char *_src1,const unsigned char *_src2,int _ystride); -void oc_enc_fdct8x8_mmx(ogg_int16_t _y[64],const ogg_int16_t _x[64]); +void oc_enc_fdct8x8_mmxext(ogg_int16_t _y[64],const ogg_int16_t _x[64]); void oc_enc_fdct8x8_x86_64sse2(ogg_int16_t _y[64],const ogg_int16_t _x[64]); #endif diff --git a/thirdparty/libtheora/x86_vc/x86int.h b/thirdparty/libtheora/x86_vc/x86int.h index 4cca485311..318a09dca0 100644 --- a/thirdparty/libtheora/x86_vc/x86int.h +++ b/thirdparty/libtheora/x86_vc/x86int.h @@ -11,32 +11,39 @@ ******************************************************************** function: - last mod: $Id: x86int.h 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ #if !defined(_x86_vc_x86int_H) # define _x86_vc_x86int_H (1) # include "../internal.h" +# if defined(OC_X86_ASM) +# define oc_state_accel_init oc_state_accel_init_x86 +# define OC_STATE_USE_VTABLE (1) +# endif +# include "../state.h" +# include "x86cpu.h" -void oc_state_vtable_init_x86(oc_theora_state *_state); +void oc_state_accel_init_x86(oc_theora_state *_state); void oc_frag_copy_mmx(unsigned char *_dst, const unsigned char *_src,int _ystride); +void oc_frag_copy_list_mmx(unsigned char *_dst_frame, + const unsigned char *_src_frame,int _ystride, + const ptrdiff_t *_fragis,ptrdiff_t _nfragis,const ptrdiff_t *_frag_buf_offs); void oc_frag_recon_intra_mmx(unsigned char *_dst,int _ystride, const ogg_int16_t *_residue); void oc_frag_recon_inter_mmx(unsigned char *_dst, const unsigned char *_src,int _ystride,const ogg_int16_t *_residue); void oc_frag_recon_inter2_mmx(unsigned char *_dst,const unsigned char *_src1, const unsigned char *_src2,int _ystride,const ogg_int16_t *_residue); -void oc_idct8x8_mmx(ogg_int16_t _y[64],int _last_zzi); +void oc_idct8x8_mmx(ogg_int16_t _y[64],ogg_int16_t _x[64],int _last_zzi); void oc_state_frag_recon_mmx(const oc_theora_state *_state,ptrdiff_t _fragi, - int _pli,ogg_int16_t _dct_coeffs[64],int _last_zzi,ogg_uint16_t _dc_quant); -void oc_state_frag_copy_list_mmx(const oc_theora_state *_state, - const ptrdiff_t *_fragis,ptrdiff_t _nfragis, - int _dst_frame,int _src_frame,int _pli); + int _pli,ogg_int16_t _dct_coeffs[128],int _last_zzi,ogg_uint16_t _dc_quant); +void oc_loop_filter_init_mmx(signed char _bv[256],int _flimit); void oc_state_loop_filter_frag_rows_mmx(const oc_theora_state *_state, - int _bv[256],int _refi,int _pli,int _fragy0,int _fragy_end); + signed char _bv[256],int _refi,int _pli,int _fragy0,int _fragy_end); void oc_restore_fpu_mmx(void); #endif diff --git a/thirdparty/libtheora/x86_vc/x86state.c b/thirdparty/libtheora/x86_vc/x86state.c index a786bec284..fa3a0d42fc 100644 --- a/thirdparty/libtheora/x86_vc/x86state.c +++ b/thirdparty/libtheora/x86_vc/x86state.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: x86state.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ @@ -19,8 +19,6 @@ #if defined(OC_X86_ASM) -#include "../cpu.c" - /*This table has been modified from OC_FZIG_ZAG by baking a 4x4 transpose into each quadrant of the destination.*/ static const unsigned char OC_FZIG_ZAG_MMX[128]={ @@ -42,21 +40,22 @@ static const unsigned char OC_FZIG_ZAG_MMX[128]={ 64,64,64,64,64,64,64,64, }; -void oc_state_vtable_init_x86(oc_theora_state *_state){ +void oc_state_accel_init_x86(oc_theora_state *_state){ _state->cpu_flags=oc_cpu_flags_get(); if(_state->cpu_flags&OC_CPU_X86_MMX){ _state->opt_vtable.frag_copy=oc_frag_copy_mmx; + _state->opt_vtable.frag_copy_list=oc_frag_copy_list_mmx; _state->opt_vtable.frag_recon_intra=oc_frag_recon_intra_mmx; _state->opt_vtable.frag_recon_inter=oc_frag_recon_inter_mmx; _state->opt_vtable.frag_recon_inter2=oc_frag_recon_inter2_mmx; _state->opt_vtable.idct8x8=oc_idct8x8_mmx; _state->opt_vtable.state_frag_recon=oc_state_frag_recon_mmx; - _state->opt_vtable.state_frag_copy_list=oc_state_frag_copy_list_mmx; + _state->opt_vtable.loop_filter_init=oc_loop_filter_init_mmx; _state->opt_vtable.state_loop_filter_frag_rows= oc_state_loop_filter_frag_rows_mmx; _state->opt_vtable.restore_fpu=oc_restore_fpu_mmx; _state->opt_data.dct_fzig_zag=OC_FZIG_ZAG_MMX; } - else oc_state_vtable_init_c(_state); + else oc_state_accel_init_c(_state); } #endif diff --git a/thirdparty/libtheora/x86_vc/x86zigzag.h b/thirdparty/libtheora/x86_vc/x86zigzag.h new file mode 100644 index 0000000000..26f5ed2ea5 --- /dev/null +++ b/thirdparty/libtheora/x86_vc/x86zigzag.h @@ -0,0 +1,244 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * + * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * + * * + ******************************************************************** + + function: + last mod: $Id: sse2trans.h 15675 2009-02-06 09:43:27Z tterribe $ + + ********************************************************************/ + +#if !defined(_x86_vc_x86zigzag_H) +# define _x86_vc_x86zigzag_H (1) +# include "x86enc.h" + + +/*Converts DCT coefficients from transposed order into zig-zag scan order and + stores them in Y. + This relies on two macros to load the contents of each row: + OC_ZZ_LOAD_ROW_LO(row,reg) and OC_ZZ_LOAD_ROW_HI(row,reg), which load the + first four and second four entries of each row into the specified register, + respectively. + OC_ZZ_LOAD_ROW_LO must be called before OC_ZZ_LOAD_ROW_HI for the same row + (because when the rows are already in SSE2 registers, loading the high half + destructively modifies the register). + The index of each output element in the original 64-element array should wind + up in the following 8x8 matrix (the letters indicate the order we compute + each 4-tuple below): + A 0 8 1 2 9 16 24 17 B + C 10 3 4 11 18 25 32 40 E + F 33 26 19 12 5 6 13 20 D + G 27 34 41 48 56 49 42 35 I + L 28 21 14 7 15 22 29 36 M + H 43 50 57 58 51 44 37 30 O + N 23 31 38 45 52 59 60 53 J + P 46 39 47 54 61 62 55 63 K + The order of the coefficients within each tuple is reversed in the comments + below to reflect the usual MSB to LSB notation.*/ +#define OC_TRANSPOSE_ZIG_ZAG_MMXEXT \ + OC_ZZ_LOAD_ROW_LO(0,mm0) /*mm0=03 02 01 00*/ \ + OC_ZZ_LOAD_ROW_LO(1,mm1) /*mm1=11 10 09 08*/ \ + OC_ZZ_LOAD_ROW_LO(2,mm2) /*mm2=19 18 17 16*/ \ + OC_ZZ_LOAD_ROW_LO(3,mm3) /*mm3=27 26 25 24*/ \ + OC_ZZ_LOAD_ROW_HI(0,mm4) /*mm4=07 06 05 04*/ \ + OC_ZZ_LOAD_ROW_HI(1,mm5) /*mm5=15 14 13 12*/ \ + OC_ZZ_LOAD_ROW_HI(2,mm6) /*mm6=23 22 21 20*/ \ + __asm movq mm7,mm0 /*mm7=03 02 01 00*/ \ + __asm punpckhdq mm0,mm1 /*mm0=11 10 03 02*/ \ + __asm pshufw mm4,mm4,0x39 /*mm4=04 07 06 05*/ \ + __asm punpcklwd mm1,mm0 /*mm1=03 09 02 08*/ \ + __asm pshufw mm5,mm5,0x39 /*mm5=12 15 14 13*/ \ + __asm punpcklwd mm7,mm1 /*mm7=02 01 08 00 *A*/ \ + __asm movq [Y+0x00],mm7 \ + __asm punpckhwd mm1,mm4 /*mm1=04 03 07 09*/ \ + __asm movq mm7,mm2 /*mm7=19 18 17 16*/ \ + __asm punpckhdq mm0,mm1 /*mm0=04 03 11 10*/ \ + __asm punpckhwd mm7,mm5 /*mm7=12 19 15 18*/ \ + __asm punpcklwd mm1,mm3 /*mm1=25 07 24 09*/ \ + __asm punpcklwd mm5,mm6 /*mm5=21 14 20 13*/ \ + __asm punpcklwd mm1,mm2 /*mm1=17 24 16 09 *B*/ \ + OC_ZZ_LOAD_ROW_LO(4,mm2) /*mm2=35 34 33 32*/ \ + __asm movq [Y+0x08],mm1 \ + OC_ZZ_LOAD_ROW_LO(5,mm1) /*mm1=43 42 41 40*/ \ + __asm pshufw mm0,mm0,0x78 /*mm0=11 04 03 10 *C*/ \ + __asm movq [Y+0x10],mm0 \ + __asm punpckhdq mm6,mm4 /*mm6=?? 07 23 22*/ \ + __asm punpckldq mm4,mm5 /*mm4=20 13 06 05 *D*/ \ + __asm movq [Y+0x28],mm4 \ + __asm psrlq mm3,16 /*mm3=.. 27 26 25*/ \ + __asm pshufw mm0,mm2,0x0E /*mm0=?? ?? 35 34*/ \ + __asm movq mm4,mm7 /*mm4=12 19 15 18*/ \ + __asm punpcklwd mm2,mm3 /*mm2=26 33 25 32*/ \ + __asm punpcklwd mm4,mm1 /*mm4=41 15 40 18*/ \ + __asm punpckhwd mm3,mm1 /*mm3=43 .. 42 27*/ \ + __asm punpckldq mm4,mm2 /*mm4=25 32 40 18*/ \ + __asm punpcklwd mm3,mm0 /*mm3=35 42 34 27*/ \ + OC_ZZ_LOAD_ROW_LO(6,mm0) /*mm0=51 50 49 48*/ \ + __asm pshufw mm4,mm4,0x6C /*mm4=40 32 25 18 *E*/ \ + __asm movq [Y+0x18],mm4 \ + OC_ZZ_LOAD_ROW_LO(7,mm4) /*mm4=59 58 57 56*/ \ + __asm punpckhdq mm2,mm7 /*mm2=12 19 26 33 *F*/ \ + __asm movq [Y+0x20],mm2 \ + __asm pshufw mm1,mm1,0xD0 /*mm1=43 41 ?? ??*/ \ + __asm pshufw mm0,mm0,0x87 /*mm0=50 48 49 51*/ \ + __asm movq mm2,mm3 /*mm2=35 42 34 27*/ \ + __asm punpckhwd mm1,mm0 /*mm1=50 43 48 41*/ \ + __asm pshufw mm4,mm4,0x93 /*mm4=58 57 56 59*/ \ + __asm punpckldq mm3,mm1 /*mm3=48 41 34 27 *G*/ \ + __asm movq [Y+0x30],mm3 \ + __asm punpckhdq mm1,mm4 /*mm1=58 57 50 43 *H*/ \ + __asm movq [Y+0x50],mm1 \ + OC_ZZ_LOAD_ROW_HI(7,mm1) /*mm1=63 62 61 60*/ \ + __asm punpcklwd mm4,mm0 /*mm4=49 56 51 59*/ \ + OC_ZZ_LOAD_ROW_HI(6,mm0) /*mm0=55 54 53 52*/ \ + __asm psllq mm6,16 /*mm6=07 23 22 ..*/ \ + __asm movq mm3,mm4 /*mm3=49 56 51 59*/ \ + __asm punpckhdq mm4,mm2 /*mm4=35 42 49 56 *I*/ \ + OC_ZZ_LOAD_ROW_HI(3,mm2) /*mm2=31 30 29 28*/ \ + __asm movq [Y+0x38],mm4 \ + __asm punpcklwd mm3,mm1 /*mm3=61 51 60 59*/ \ + __asm punpcklwd mm7,mm6 /*mm7=22 15 .. ??*/ \ + __asm movq mm4,mm3 /*mm4=61 51 60 59*/ \ + __asm punpcklwd mm3,mm0 /*mm3=53 60 52 59*/ \ + __asm punpckhwd mm4,mm0 /*mm4=55 61 54 51*/ \ + OC_ZZ_LOAD_ROW_HI(4,mm0) /*mm0=39 38 37 36*/ \ + __asm pshufw mm3,mm3,0xE1 /*mm3=53 60 59 52 *J*/ \ + __asm movq [Y+0x68],mm3 \ + __asm movq mm3,mm4 /*mm3=?? ?? 54 51*/ \ + __asm pshufw mm2,mm2,0x39 /*mm2=28 31 30 29*/ \ + __asm punpckhwd mm4,mm1 /*mm4=63 55 62 61 *K*/ \ + OC_ZZ_LOAD_ROW_HI(5,mm1) /*mm1=47 46 45 44*/ \ + __asm movq [Y+0x78],mm4 \ + __asm punpckhwd mm6,mm2 /*mm6=28 07 31 23*/ \ + __asm punpcklwd mm2,mm0 /*mm2=37 30 36 29*/ \ + __asm punpckhdq mm5,mm6 /*mm5=28 07 21 14*/ \ + __asm pshufw mm2,mm2,0x4B /*mm2=36 29 30 37*/ \ + __asm pshufw mm5,mm5,0x87 /*mm5=07 14 21 28 *L*/ \ + __asm movq [Y+0x40],mm5 \ + __asm punpckhdq mm7,mm2 /*mm7=36 29 22 15 *M*/ \ + __asm movq [Y+0x48],mm7 \ + __asm pshufw mm1,mm1,0x9C /*mm1=46 45 47 44*/ \ + __asm punpckhwd mm0,mm1 /*mm0=46 39 45 38*/ \ + __asm punpcklwd mm3,mm1 /*mm3=47 54 44 51*/ \ + __asm punpckldq mm6,mm0 /*mm6=45 38 31 23 *N*/ \ + __asm movq [Y+0x60],mm6 \ + __asm punpckhdq mm0,mm3 /*mm0=47 54 46 39*/ \ + __asm punpckldq mm3,mm2 /*mm3=30 37 44 51 *O*/ \ + __asm movq [Y+0x58],mm3 \ + __asm pshufw mm0,mm0,0xB1 /*mm0=54 47 39 46 *P*/ \ + __asm movq [Y+0x70],mm0 \ + +/*Converts DCT coefficients in %[dct] from natural order into zig-zag scan + order and stores them in %[qdct]. + The index of each output element in the original 64-element array should wind + up in the following 8x8 matrix (the letters indicate the order we compute + each 4-tuple below): + A 0 1 8 16 9 2 3 10 B + C 17 24 32 25 18 11 4 5 D + E 12 19 26 33 40 48 41 34 I + H 27 20 13 6 7 14 21 28 G + K 35 42 49 56 57 50 43 36 J + F 29 22 15 23 30 37 44 51 M + P 58 59 52 45 38 31 39 46 L + N 53 60 61 54 47 55 62 63 O + The order of the coefficients within each tuple is reversed in the comments + below to reflect the usual MSB to LSB notation.*/ +#define OC_ZIG_ZAG_MMXEXT \ + "movq 0x00(%[dct]),%%mm0\n\t" /*mm0=03 02 01 00*/ \ + "movq 0x08(%[dct]),%%mm1\n\t" /*mm1=07 06 05 04*/ \ + "movq 0x10(%[dct]),%%mm2\n\t" /*mm2=11 10 09 08*/ \ + "movq 0x20(%[dct]),%%mm3\n\t" /*mm3=19 18 17 16*/ \ + "movq 0x30(%[dct]),%%mm4\n\t" /*mm4=27 26 25 24*/ \ + "movq 0x40(%[dct]),%%mm5\n\t" /*mm5=35 34 33 32*/ \ + "movq %%mm2,%%mm7\n\t" /*mm7=11 10 09 08*/ \ + "punpcklwd %%mm3,%%mm2\n\t" /*mm2=17 09 16 08*/ \ + "movq %%mm0,%%mm6\n\t" /*mm6=03 02 01 00*/ \ + "punpckldq %%mm2,%%mm0\n\t" /*mm0=16 08 01 00 *A*/ \ + "movq %%mm0,0x00(%[qdct])\n\t" \ + "movq 0x18(%[dct]),%%mm0\n\t" /*mm0=15 14 13 12*/ \ + "punpckhdq %%mm6,%%mm6\n\t" /*mm6=03 02 03 02*/ \ + "psrlq $16,%%mm7\n\t" /*mm7=.. 11 10 09*/ \ + "punpckldq %%mm7,%%mm6\n\t" /*mm6=10 09 03 02*/ \ + "punpckhwd %%mm7,%%mm3\n\t" /*mm3=.. 19 11 18*/ \ + "pshufw $0xD2,%%mm6,%%mm6\n\t" /*mm6=10 03 02 09 *B*/ \ + "movq %%mm6,0x08(%[qdct])\n\t" \ + "psrlq $48,%%mm2\n\t" /*mm2=.. .. .. 17*/ \ + "movq %%mm1,%%mm6\n\t" /*mm6=07 06 05 04*/ \ + "punpcklwd %%mm5,%%mm2\n\t" /*mm2=33 .. 32 17*/ \ + "movq %%mm3,%%mm7\n\t" /*mm7=.. 19 11 18*/ \ + "punpckldq %%mm1,%%mm3\n\t" /*mm3=05 04 11 18 *C*/ \ + "por %%mm2,%%mm7\n\t" /*mm7=33 19 ?? ??*/ \ + "punpcklwd %%mm4,%%mm2\n\t" /*mm2=25 32 24 17 *D**/ \ + "movq %%mm2,0x10(%[qdct])\n\t" \ + "movq %%mm3,0x18(%[qdct])\n\t" \ + "movq 0x28(%[dct]),%%mm2\n\t" /*mm2=23 22 21 20*/ \ + "movq 0x38(%[dct]),%%mm1\n\t" /*mm1=31 30 29 28*/ \ + "pshufw $0x9C,%%mm0,%%mm3\n\t" /*mm3=14 13 15 12*/ \ + "punpckhdq %%mm7,%%mm7\n\t" /*mm7=33 19 33 19*/ \ + "punpckhwd %%mm3,%%mm6\n\t" /*mm6=14 07 13 06*/ \ + "punpckldq %%mm0,%%mm0\n\t" /*mm0=13 12 13 12*/ \ + "punpcklwd %%mm1,%%mm3\n\t" /*mm3=29 15 28 12*/ \ + "punpckhwd %%mm4,%%mm0\n\t" /*mm0=27 13 26 12*/ \ + "pshufw $0xB4,%%mm3,%%mm3\n\t" /*mm3=15 29 28 12*/ \ + "psrlq $48,%%mm4\n\t" /*mm4=.. .. .. 27*/ \ + "punpcklwd %%mm7,%%mm0\n\t" /*mm0=33 26 19 12 *E*/ \ + "punpcklwd %%mm1,%%mm4\n\t" /*mm4=29 .. 28 27*/ \ + "punpckhwd %%mm2,%%mm3\n\t" /*mm3=23 15 22 29 *F*/ \ + "movq %%mm0,0x20(%[qdct])\n\t" \ + "movq %%mm3,0x50(%[qdct])\n\t" \ + "movq 0x60(%[dct]),%%mm3\n\t" /*mm3=51 50 49 48*/ \ + "movq 0x70(%[dct]),%%mm7\n\t" /*mm7=59 58 57 56*/ \ + "movq 0x50(%[dct]),%%mm0\n\t" /*mm0=43 42 41 40*/ \ + "punpcklwd %%mm4,%%mm2\n\t" /*mm2=28 21 27 20*/ \ + "psrlq $32,%%mm5\n\t" /*mm5=.. .. 35 34*/ \ + "movq %%mm2,%%mm4\n\t" /*mm4=28 21 27 20*/ \ + "punpckldq %%mm6,%%mm2\n\t" /*mm2=13 06 27 20*/ \ + "punpckhdq %%mm4,%%mm6\n\t" /*mm6=28 21 14 07 *G*/ \ + "movq %%mm3,%%mm4\n\t" /*mm4=51 50 49 48*/ \ + "pshufw $0xB1,%%mm2,%%mm2\n\t" /*mm2=06 13 20 27 *H*/ \ + "movq %%mm2,0x30(%[qdct])\n\t" \ + "movq %%mm6,0x38(%[qdct])\n\t" \ + "movq 0x48(%[dct]),%%mm2\n\t" /*mm2=39 38 37 36*/ \ + "punpcklwd %%mm5,%%mm4\n\t" /*mm4=35 49 34 48*/ \ + "movq 0x58(%[dct]),%%mm5\n\t" /*mm5=47 46 45 44*/ \ + "punpckldq %%mm7,%%mm6\n\t" /*mm6=57 56 14 07*/ \ + "psrlq $32,%%mm3\n\t" /*mm3=.. .. 51 50*/ \ + "punpckhwd %%mm0,%%mm6\n\t" /*mm6=43 57 42 56*/ \ + "punpcklwd %%mm4,%%mm0\n\t" /*mm0=34 41 48 40 *I*/ \ + "pshufw $0x4E,%%mm6,%%mm6\n\t" /*mm6=42 56 43 57*/ \ + "movq %%mm0,0x28(%[qdct])\n\t" \ + "punpcklwd %%mm2,%%mm3\n\t" /*mm3=37 51 36 50*/ \ + "punpckhwd %%mm6,%%mm4\n\t" /*mm4=42 35 56 49*/ \ + "punpcklwd %%mm3,%%mm6\n\t" /*mm6=36 43 50 57 *J*/ \ + "pshufw $0x4E,%%mm4,%%mm4\n\t" /*mm4=56 49 42 35 *K*/ \ + "movq %%mm4,0x40(%[qdct])\n\t" \ + "movq %%mm6,0x48(%[qdct])\n\t" \ + "movq 0x68(%[dct]),%%mm6\n\t" /*mm6=55 54 53 52*/ \ + "movq 0x78(%[dct]),%%mm0\n\t" /*mm0=63 62 61 60*/ \ + "psrlq $32,%%mm1\n\t" /*mm1=.. .. 31 30*/ \ + "pshufw $0xD8,%%mm5,%%mm5\n\t" /*mm5=47 45 46 44*/ \ + "pshufw $0x0B,%%mm3,%%mm3\n\t" /*mm3=50 50 51 37*/ \ + "punpcklwd %%mm5,%%mm1\n\t" /*mm1=46 31 44 30*/ \ + "pshufw $0xC9,%%mm6,%%mm6\n\t" /*mm6=55 52 54 53*/ \ + "punpckhwd %%mm1,%%mm2\n\t" /*mm2=46 39 31 38 *L*/ \ + "punpcklwd %%mm3,%%mm1\n\t" /*mm1=51 44 37 30 *M*/ \ + "movq %%mm2,0x68(%[qdct])\n\t" \ + "movq %%mm1,0x58(%[qdct])\n\t" \ + "punpckhwd %%mm6,%%mm5\n\t" /*mm5=55 47 52 45*/ \ + "punpckldq %%mm0,%%mm6\n\t" /*mm6=61 60 54 53*/ \ + "pshufw $0x10,%%mm5,%%mm4\n\t" /*mm4=45 52 45 45*/ \ + "pshufw $0x78,%%mm6,%%mm6\n\t" /*mm6=53 60 61 54 *N*/ \ + "punpckhdq %%mm0,%%mm5\n\t" /*mm5=63 62 55 47 *O*/ \ + "punpckhdq %%mm4,%%mm7\n\t" /*mm7=45 52 59 58 *P*/ \ + "movq %%mm6,0x70(%[qdct])\n\t" \ + "movq %%mm5,0x78(%[qdct])\n\t" \ + "movq %%mm7,0x60(%[qdct])\n\t" \ + +#endif diff --git a/thirdparty/libwebp/AUTHORS b/thirdparty/libwebp/AUTHORS index 3efcbe25b6..2f0c537d1c 100644 --- a/thirdparty/libwebp/AUTHORS +++ b/thirdparty/libwebp/AUTHORS @@ -11,11 +11,13 @@ Contributors: - Djordje Pesut (djordje dot pesut at imgtec dot com) - Frank Barchard (fbarchard at google dot com) - Hui Su (huisu at google dot com) +- H. Vetinari (h dot vetinari at gmx dot com) - Ilya Kurdyukov (jpegqs at gmail dot com) - Ingvar Stepanyan (rreverser at google dot com) - James Zern (jzern at google dot com) - Jan Engelhardt (jengelh at medozas dot de) - Jehan (jehan at girinstud dot io) +- Jeremy Maitin-Shepard (jbms at google dot com) - Johann Koenig (johann dot koenig at duck dot com) - Jovan Zelincevic (jovan dot zelincevic at imgtec dot com) - Jyrki Alakuijala (jyrki at google dot com) diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv.c b/thirdparty/libwebp/sharpyuv/sharpyuv.c index 8b3ab7216b..7de34fb0b2 100644 --- a/thirdparty/libwebp/sharpyuv/sharpyuv.c +++ b/thirdparty/libwebp/sharpyuv/sharpyuv.c @@ -15,16 +15,22 @@ #include <assert.h> #include <limits.h> -#include <math.h> +#include <stddef.h> #include <stdlib.h> #include <string.h> #include "src/webp/types.h" -#include "src/dsp/cpu.h" +#include "sharpyuv/sharpyuv_cpu.h" #include "sharpyuv/sharpyuv_dsp.h" #include "sharpyuv/sharpyuv_gamma.h" //------------------------------------------------------------------------------ + +int SharpYuvGetVersion(void) { + return SHARPYUV_VERSION; +} + +//------------------------------------------------------------------------------ // Sharp RGB->YUV conversion static const int kNumIterations = 4; @@ -414,24 +420,45 @@ static int DoSharpArgbToYuv(const uint8_t* r_ptr, const uint8_t* g_ptr, } #undef SAFE_ALLOC +#if defined(WEBP_USE_THREAD) && !defined(_WIN32) +#include <pthread.h> // NOLINT + +#define LOCK_ACCESS \ + static pthread_mutex_t sharpyuv_lock = PTHREAD_MUTEX_INITIALIZER; \ + if (pthread_mutex_lock(&sharpyuv_lock)) return +#define UNLOCK_ACCESS_AND_RETURN \ + do { \ + (void)pthread_mutex_unlock(&sharpyuv_lock); \ + return; \ + } while (0) +#else // !(defined(WEBP_USE_THREAD) && !defined(_WIN32)) +#define LOCK_ACCESS do {} while (0) +#define UNLOCK_ACCESS_AND_RETURN return +#endif // defined(WEBP_USE_THREAD) && !defined(_WIN32) + // Hidden exported init function. -// By default SharpYuvConvert calls it with NULL. If needed, users can declare -// it as extern and call it with a VP8CPUInfo function. -extern void SharpYuvInit(VP8CPUInfo cpu_info_func); +// By default SharpYuvConvert calls it with SharpYuvGetCPUInfo. If needed, +// users can declare it as extern and call it with an alternate VP8CPUInfo +// function. +SHARPYUV_EXTERN void SharpYuvInit(VP8CPUInfo cpu_info_func); void SharpYuvInit(VP8CPUInfo cpu_info_func) { static volatile VP8CPUInfo sharpyuv_last_cpuinfo_used = (VP8CPUInfo)&sharpyuv_last_cpuinfo_used; - const int initialized = - (sharpyuv_last_cpuinfo_used != (VP8CPUInfo)&sharpyuv_last_cpuinfo_used); - if (cpu_info_func == NULL && initialized) return; - if (sharpyuv_last_cpuinfo_used == cpu_info_func) return; - - SharpYuvInitDsp(cpu_info_func); - if (!initialized) { - SharpYuvInitGammaTables(); + LOCK_ACCESS; + // Only update SharpYuvGetCPUInfo when called from external code to avoid a + // race on reading the value in SharpYuvConvert(). + if (cpu_info_func != (VP8CPUInfo)&SharpYuvGetCPUInfo) { + SharpYuvGetCPUInfo = cpu_info_func; + } + if (sharpyuv_last_cpuinfo_used == SharpYuvGetCPUInfo) { + UNLOCK_ACCESS_AND_RETURN; } - sharpyuv_last_cpuinfo_used = cpu_info_func; + SharpYuvInitDsp(); + SharpYuvInitGammaTables(); + + sharpyuv_last_cpuinfo_used = SharpYuvGetCPUInfo; + UNLOCK_ACCESS_AND_RETURN; } int SharpYuvConvert(const void* r_ptr, const void* g_ptr, @@ -467,7 +494,8 @@ int SharpYuvConvert(const void* r_ptr, const void* g_ptr, // Stride should be even for uint16_t buffers. return 0; } - SharpYuvInit(NULL); + // The address of the function pointer is used to avoid a read race. + SharpYuvInit((VP8CPUInfo)&SharpYuvGetCPUInfo); // Add scaling factor to go from rgb_bit_depth to yuv_bit_depth, to the // rgb->yuv conversion matrix. diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv.h b/thirdparty/libwebp/sharpyuv/sharpyuv.h index 9386ea2185..181b20a0bc 100644 --- a/thirdparty/libwebp/sharpyuv/sharpyuv.h +++ b/thirdparty/libwebp/sharpyuv/sharpyuv.h @@ -12,15 +12,31 @@ #ifndef WEBP_SHARPYUV_SHARPYUV_H_ #define WEBP_SHARPYUV_SHARPYUV_H_ -#include <inttypes.h> - #ifdef __cplusplus extern "C" { #endif +#ifndef SHARPYUV_EXTERN +#ifdef WEBP_EXTERN +#define SHARPYUV_EXTERN WEBP_EXTERN +#else +// This explicitly marks library functions and allows for changing the +// signature for e.g., Windows DLL builds. +#if defined(__GNUC__) && __GNUC__ >= 4 +#define SHARPYUV_EXTERN extern __attribute__((visibility("default"))) +#else +#if defined(_MSC_VER) && defined(WEBP_DLL) +#define SHARPYUV_EXTERN __declspec(dllexport) +#else +#define SHARPYUV_EXTERN extern +#endif /* _MSC_VER && WEBP_DLL */ +#endif /* __GNUC__ >= 4 */ +#endif /* WEBP_EXTERN */ +#endif /* SHARPYUV_EXTERN */ + // SharpYUV API version following the convention from semver.org #define SHARPYUV_VERSION_MAJOR 0 -#define SHARPYUV_VERSION_MINOR 1 +#define SHARPYUV_VERSION_MINOR 2 #define SHARPYUV_VERSION_PATCH 0 // Version as a uint32_t. The major number is the high 8 bits. // The minor number is the middle 8 bits. The patch number is the low 16 bits. @@ -30,6 +46,10 @@ extern "C" { SHARPYUV_MAKE_VERSION(SHARPYUV_VERSION_MAJOR, SHARPYUV_VERSION_MINOR, \ SHARPYUV_VERSION_PATCH) +// Returns the library's version number, packed in hexadecimal. See +// SHARPYUV_VERSION. +SHARPYUV_EXTERN int SharpYuvGetVersion(void); + // RGB to YUV conversion matrix, in 16 bit fixed point. // y = rgb_to_y[0] * r + rgb_to_y[1] * g + rgb_to_y[2] * b + rgb_to_y[3] // u = rgb_to_u[0] * r + rgb_to_u[1] * g + rgb_to_u[2] * b + rgb_to_u[3] @@ -65,11 +85,13 @@ typedef struct { // adjacent pixels on the y, u and v channels. If yuv_bit_depth > 8, they // should be multiples of 2. // width, height: width and height of the image in pixels -int SharpYuvConvert(const void* r_ptr, const void* g_ptr, const void* b_ptr, - int rgb_step, int rgb_stride, int rgb_bit_depth, - void* y_ptr, int y_stride, void* u_ptr, int u_stride, - void* v_ptr, int v_stride, int yuv_bit_depth, int width, - int height, const SharpYuvConversionMatrix* yuv_matrix); +SHARPYUV_EXTERN int SharpYuvConvert(const void* r_ptr, const void* g_ptr, + const void* b_ptr, int rgb_step, + int rgb_stride, int rgb_bit_depth, + void* y_ptr, int y_stride, void* u_ptr, + int u_stride, void* v_ptr, int v_stride, + int yuv_bit_depth, int width, int height, + const SharpYuvConversionMatrix* yuv_matrix); // TODO(b/194336375): Add YUV444 to YUV420 conversion. Maybe also add 422 // support (it's rarely used in practice, especially for images). diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_cpu.c b/thirdparty/libwebp/sharpyuv/sharpyuv_cpu.c new file mode 100644 index 0000000000..29425a0c49 --- /dev/null +++ b/thirdparty/libwebp/sharpyuv/sharpyuv_cpu.c @@ -0,0 +1,14 @@ +// Copyright 2022 Google Inc. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the COPYING file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +// ----------------------------------------------------------------------------- +// +#include "sharpyuv/sharpyuv_cpu.h" + +// Include src/dsp/cpu.c to create SharpYuvGetCPUInfo from VP8GetCPUInfo. The +// function pointer is renamed in sharpyuv_cpu.h. +#include "src/dsp/cpu.c" diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_cpu.h b/thirdparty/libwebp/sharpyuv/sharpyuv_cpu.h new file mode 100644 index 0000000000..176ca3eb16 --- /dev/null +++ b/thirdparty/libwebp/sharpyuv/sharpyuv_cpu.h @@ -0,0 +1,22 @@ +// Copyright 2022 Google Inc. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the COPYING file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +// ----------------------------------------------------------------------------- +// +#ifndef WEBP_SHARPYUV_SHARPYUV_CPU_H_ +#define WEBP_SHARPYUV_SHARPYUV_CPU_H_ + +#include "sharpyuv/sharpyuv.h" + +// Avoid exporting SharpYuvGetCPUInfo in shared object / DLL builds. +// SharpYuvInit() replaces the use of the function pointer. +#undef WEBP_EXTERN +#define WEBP_EXTERN extern +#define VP8GetCPUInfo SharpYuvGetCPUInfo +#include "src/dsp/cpu.h" + +#endif // WEBP_SHARPYUV_SHARPYUV_CPU_H_ diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_csp.c b/thirdparty/libwebp/sharpyuv/sharpyuv_csp.c index 5334fa64fa..0ad22be945 100644 --- a/thirdparty/libwebp/sharpyuv/sharpyuv_csp.c +++ b/thirdparty/libwebp/sharpyuv/sharpyuv_csp.c @@ -13,7 +13,7 @@ #include <assert.h> #include <math.h> -#include <string.h> +#include <stddef.h> static int ToFixed16(float f) { return (int)floor(f * (1 << 16) + 0.5f); } diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_csp.h b/thirdparty/libwebp/sharpyuv/sharpyuv_csp.h index 63c99ef5cd..3214e3ac60 100644 --- a/thirdparty/libwebp/sharpyuv/sharpyuv_csp.h +++ b/thirdparty/libwebp/sharpyuv/sharpyuv_csp.h @@ -35,8 +35,9 @@ typedef struct { } SharpYuvColorSpace; // Fills in 'matrix' for the given YUVColorSpace. -void SharpYuvComputeConversionMatrix(const SharpYuvColorSpace* yuv_color_space, - SharpYuvConversionMatrix* matrix); +SHARPYUV_EXTERN void SharpYuvComputeConversionMatrix( + const SharpYuvColorSpace* yuv_color_space, + SharpYuvConversionMatrix* matrix); // Enums for precomputed conversion matrices. typedef enum { @@ -49,7 +50,7 @@ typedef enum { } SharpYuvMatrixType; // Returns a pointer to a matrix for one of the predefined colorspaces. -const SharpYuvConversionMatrix* SharpYuvGetConversionMatrix( +SHARPYUV_EXTERN const SharpYuvConversionMatrix* SharpYuvGetConversionMatrix( SharpYuvMatrixType matrix_type); #ifdef __cplusplus diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_dsp.c b/thirdparty/libwebp/sharpyuv/sharpyuv_dsp.c index 956fa7ce55..31c272c408 100644 --- a/thirdparty/libwebp/sharpyuv/sharpyuv_dsp.c +++ b/thirdparty/libwebp/sharpyuv/sharpyuv_dsp.c @@ -16,7 +16,7 @@ #include <assert.h> #include <stdlib.h> -#include "src/dsp/cpu.h" +#include "sharpyuv/sharpyuv_cpu.h" //----------------------------------------------------------------------------- @@ -75,23 +75,24 @@ void (*SharpYuvFilterRow)(const int16_t* A, const int16_t* B, int len, extern void InitSharpYuvSSE2(void); extern void InitSharpYuvNEON(void); -void SharpYuvInitDsp(VP8CPUInfo cpu_info_func) { - (void)cpu_info_func; - +void SharpYuvInitDsp(void) { #if !WEBP_NEON_OMIT_C_CODE SharpYuvUpdateY = SharpYuvUpdateY_C; SharpYuvUpdateRGB = SharpYuvUpdateRGB_C; SharpYuvFilterRow = SharpYuvFilterRow_C; #endif + if (SharpYuvGetCPUInfo != NULL) { #if defined(WEBP_HAVE_SSE2) - if (cpu_info_func == NULL || cpu_info_func(kSSE2)) { - InitSharpYuvSSE2(); - } + if (SharpYuvGetCPUInfo(kSSE2)) { + InitSharpYuvSSE2(); + } #endif // WEBP_HAVE_SSE2 + } #if defined(WEBP_HAVE_NEON) - if (WEBP_NEON_OMIT_C_CODE || cpu_info_func == NULL || cpu_info_func(kNEON)) { + if (WEBP_NEON_OMIT_C_CODE || + (SharpYuvGetCPUInfo != NULL && SharpYuvGetCPUInfo(kNEON))) { InitSharpYuvNEON(); } #endif // WEBP_HAVE_NEON diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_dsp.h b/thirdparty/libwebp/sharpyuv/sharpyuv_dsp.h index e561d8d3d0..805fbadbf6 100644 --- a/thirdparty/libwebp/sharpyuv/sharpyuv_dsp.h +++ b/thirdparty/libwebp/sharpyuv/sharpyuv_dsp.h @@ -12,9 +12,8 @@ #ifndef WEBP_SHARPYUV_SHARPYUV_DSP_H_ #define WEBP_SHARPYUV_SHARPYUV_DSP_H_ -#include <stdint.h> - -#include "src/dsp/cpu.h" +#include "sharpyuv/sharpyuv_cpu.h" +#include "src/webp/types.h" extern uint64_t (*SharpYuvUpdateY)(const uint16_t* src, const uint16_t* ref, uint16_t* dst, int len, int bit_depth); @@ -24,6 +23,6 @@ extern void (*SharpYuvFilterRow)(const int16_t* A, const int16_t* B, int len, const uint16_t* best_y, uint16_t* out, int bit_depth); -void SharpYuvInitDsp(VP8CPUInfo cpu_info_func); +void SharpYuvInitDsp(void); #endif // WEBP_SHARPYUV_SHARPYUV_DSP_H_ diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_gamma.c b/thirdparty/libwebp/sharpyuv/sharpyuv_gamma.c index 05b5436f83..20ab2da6bc 100644 --- a/thirdparty/libwebp/sharpyuv/sharpyuv_gamma.c +++ b/thirdparty/libwebp/sharpyuv/sharpyuv_gamma.c @@ -13,7 +13,6 @@ #include <assert.h> #include <math.h> -#include <stdint.h> #include "src/webp/types.h" diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_gamma.h b/thirdparty/libwebp/sharpyuv/sharpyuv_gamma.h index 2f1a3ff4a0..d13aff59e1 100644 --- a/thirdparty/libwebp/sharpyuv/sharpyuv_gamma.h +++ b/thirdparty/libwebp/sharpyuv/sharpyuv_gamma.h @@ -12,7 +12,7 @@ #ifndef WEBP_SHARPYUV_SHARPYUV_GAMMA_H_ #define WEBP_SHARPYUV_SHARPYUV_GAMMA_H_ -#include <stdint.h> +#include "src/webp/types.h" #ifdef __cplusplus extern "C" { diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_neon.c b/thirdparty/libwebp/sharpyuv/sharpyuv_neon.c index 5cf6aaffb0..5840914865 100644 --- a/thirdparty/libwebp/sharpyuv/sharpyuv_neon.c +++ b/thirdparty/libwebp/sharpyuv/sharpyuv_neon.c @@ -17,11 +17,6 @@ #include <assert.h> #include <stdlib.h> #include <arm_neon.h> -#endif - -extern void InitSharpYuvNEON(void); - -#if defined(WEBP_USE_NEON) static uint16_t clip_NEON(int v, int max) { return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v; @@ -169,6 +164,8 @@ static void SharpYuvFilterRow_NEON(const int16_t* A, const int16_t* B, int len, //------------------------------------------------------------------------------ +extern void InitSharpYuvNEON(void); + WEBP_TSAN_IGNORE_FUNCTION void InitSharpYuvNEON(void) { SharpYuvUpdateY = SharpYuvUpdateY_NEON; SharpYuvUpdateRGB = SharpYuvUpdateRGB_NEON; @@ -177,6 +174,8 @@ WEBP_TSAN_IGNORE_FUNCTION void InitSharpYuvNEON(void) { #else // !WEBP_USE_NEON +extern void InitSharpYuvNEON(void); + void InitSharpYuvNEON(void) {} #endif // WEBP_USE_NEON diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_sse2.c b/thirdparty/libwebp/sharpyuv/sharpyuv_sse2.c index 1943873748..9744d1bb6c 100644 --- a/thirdparty/libwebp/sharpyuv/sharpyuv_sse2.c +++ b/thirdparty/libwebp/sharpyuv/sharpyuv_sse2.c @@ -16,11 +16,6 @@ #if defined(WEBP_USE_SSE2) #include <stdlib.h> #include <emmintrin.h> -#endif - -extern void InitSharpYuvSSE2(void); - -#if defined(WEBP_USE_SSE2) static uint16_t clip_SSE2(int v, int max) { return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v; @@ -199,6 +194,8 @@ WEBP_TSAN_IGNORE_FUNCTION void InitSharpYuvSSE2(void) { } #else // !WEBP_USE_SSE2 +extern void InitSharpYuvSSE2(void); + void InitSharpYuvSSE2(void) {} #endif // WEBP_USE_SSE2 diff --git a/thirdparty/libwebp/src/dec/vp8i_dec.h b/thirdparty/libwebp/src/dec/vp8i_dec.h index 30c1bd3ef9..83791ecd25 100644 --- a/thirdparty/libwebp/src/dec/vp8i_dec.h +++ b/thirdparty/libwebp/src/dec/vp8i_dec.h @@ -31,8 +31,8 @@ extern "C" { // version numbers #define DEC_MAJ_VERSION 1 -#define DEC_MIN_VERSION 2 -#define DEC_REV_VERSION 4 +#define DEC_MIN_VERSION 3 +#define DEC_REV_VERSION 0 // YUV-cache parameters. Cache is 32-bytes wide (= one cacheline). // Constraints are: We need to store one 16x16 block of luma samples (y), diff --git a/thirdparty/libwebp/src/dec/vp8l_dec.c b/thirdparty/libwebp/src/dec/vp8l_dec.c index 1348055128..c0ea0181e5 100644 --- a/thirdparty/libwebp/src/dec/vp8l_dec.c +++ b/thirdparty/libwebp/src/dec/vp8l_dec.c @@ -1336,7 +1336,7 @@ static int ReadTransform(int* const xsize, int const* ysize, ok = ok && ExpandColorMap(num_colors, transform); break; } - case SUBTRACT_GREEN: + case SUBTRACT_GREEN_TRANSFORM: break; default: assert(0); // can't happen diff --git a/thirdparty/libwebp/src/dec/webp_dec.c b/thirdparty/libwebp/src/dec/webp_dec.c index 77a54c55d2..3f4f7bb659 100644 --- a/thirdparty/libwebp/src/dec/webp_dec.c +++ b/thirdparty/libwebp/src/dec/webp_dec.c @@ -179,7 +179,7 @@ static VP8StatusCode ParseOptionalChunks(const uint8_t** const data, return VP8_STATUS_BITSTREAM_ERROR; // Not a valid chunk size. } // For odd-sized chunk-payload, there's one byte padding at the end. - disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1; + disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1u; total_size += disk_chunk_size; // Check that total bytes skipped so far does not exceed riff_size. diff --git a/thirdparty/libwebp/src/demux/demux.c b/thirdparty/libwebp/src/demux/demux.c index 41387ec2d6..324e5eb993 100644 --- a/thirdparty/libwebp/src/demux/demux.c +++ b/thirdparty/libwebp/src/demux/demux.c @@ -24,8 +24,8 @@ #include "src/webp/format_constants.h" #define DMUX_MAJ_VERSION 1 -#define DMUX_MIN_VERSION 2 -#define DMUX_REV_VERSION 4 +#define DMUX_MIN_VERSION 3 +#define DMUX_REV_VERSION 0 typedef struct { size_t start_; // start location of the data diff --git a/thirdparty/libwebp/src/dsp/alpha_processing_sse2.c b/thirdparty/libwebp/src/dsp/alpha_processing_sse2.c index a5f8c9f7c7..f0843d0feb 100644 --- a/thirdparty/libwebp/src/dsp/alpha_processing_sse2.c +++ b/thirdparty/libwebp/src/dsp/alpha_processing_sse2.c @@ -26,8 +26,8 @@ static int DispatchAlpha_SSE2(const uint8_t* WEBP_RESTRICT alpha, uint32_t alpha_and = 0xff; int i, j; const __m128i zero = _mm_setzero_si128(); - const __m128i rgb_mask = _mm_set1_epi32(0xffffff00u); // to preserve RGB - const __m128i all_0xff = _mm_set_epi32(0, 0, ~0u, ~0u); + const __m128i rgb_mask = _mm_set1_epi32((int)0xffffff00); // to preserve RGB + const __m128i all_0xff = _mm_set_epi32(0, 0, ~0, ~0); __m128i all_alphas = all_0xff; // We must be able to access 3 extra bytes after the last written byte @@ -106,8 +106,8 @@ static int ExtractAlpha_SSE2(const uint8_t* WEBP_RESTRICT argb, int argb_stride, // value is not 0xff if any of the alpha[] is not equal to 0xff. uint32_t alpha_and = 0xff; int i, j; - const __m128i a_mask = _mm_set1_epi32(0xffu); // to preserve alpha - const __m128i all_0xff = _mm_set_epi32(0, 0, ~0u, ~0u); + const __m128i a_mask = _mm_set1_epi32(0xff); // to preserve alpha + const __m128i all_0xff = _mm_set_epi32(0, 0, ~0, ~0); __m128i all_alphas = all_0xff; // We must be able to access 3 extra bytes after the last written byte @@ -178,7 +178,7 @@ static int ExtractAlpha_SSE2(const uint8_t* WEBP_RESTRICT argb, int argb_stride, static void ApplyAlphaMultiply_SSE2(uint8_t* rgba, int alpha_first, int w, int h, int stride) { const __m128i zero = _mm_setzero_si128(); - const __m128i kMult = _mm_set1_epi16(0x8081u); + const __m128i kMult = _mm_set1_epi16((short)0x8081); const __m128i kMask = _mm_set_epi16(0, 0xff, 0xff, 0, 0, 0xff, 0xff, 0); const int kSpan = 4; while (h-- > 0) { @@ -267,7 +267,7 @@ static int HasAlpha32b_SSE2(const uint8_t* src, int length) { } static void AlphaReplace_SSE2(uint32_t* src, int length, uint32_t color) { - const __m128i m_color = _mm_set1_epi32(color); + const __m128i m_color = _mm_set1_epi32((int)color); const __m128i zero = _mm_setzero_si128(); int i = 0; for (; i + 8 <= length; i += 8) { diff --git a/thirdparty/libwebp/src/dsp/alpha_processing_sse41.c b/thirdparty/libwebp/src/dsp/alpha_processing_sse41.c index cdf877ce49..1156ac3417 100644 --- a/thirdparty/libwebp/src/dsp/alpha_processing_sse41.c +++ b/thirdparty/libwebp/src/dsp/alpha_processing_sse41.c @@ -26,7 +26,7 @@ static int ExtractAlpha_SSE41(const uint8_t* WEBP_RESTRICT argb, // value is not 0xff if any of the alpha[] is not equal to 0xff. uint32_t alpha_and = 0xff; int i, j; - const __m128i all_0xff = _mm_set1_epi32(~0u); + const __m128i all_0xff = _mm_set1_epi32(~0); __m128i all_alphas = all_0xff; // We must be able to access 3 extra bytes after the last written byte diff --git a/thirdparty/libwebp/src/dsp/cpu.c b/thirdparty/libwebp/src/dsp/cpu.c index a4ba7f2cb7..62de73f750 100644 --- a/thirdparty/libwebp/src/dsp/cpu.c +++ b/thirdparty/libwebp/src/dsp/cpu.c @@ -212,7 +212,7 @@ VP8CPUInfo VP8GetCPUInfo = wasmCPUInfo; #elif defined(WEBP_HAVE_NEON) // In most cases this function doesn't check for NEON support (it's assumed by // the configuration), but enables turning off NEON at runtime, for testing -// purposes, by setting VP8DecGetCPUInfo = NULL. +// purposes, by setting VP8GetCPUInfo = NULL. static int armCPUInfo(CPUFeature feature) { if (feature != kNEON) return 0; #if defined(__linux__) && defined(WEBP_HAVE_NEON_RTCD) diff --git a/thirdparty/libwebp/src/dsp/cpu.h b/thirdparty/libwebp/src/dsp/cpu.h index 57a40d87d4..be80727c0d 100644 --- a/thirdparty/libwebp/src/dsp/cpu.h +++ b/thirdparty/libwebp/src/dsp/cpu.h @@ -14,6 +14,8 @@ #ifndef WEBP_DSP_CPU_H_ #define WEBP_DSP_CPU_H_ +#include <stddef.h> + #ifdef HAVE_CONFIG_H #include "src/webp/config.h" #endif diff --git a/thirdparty/libwebp/src/dsp/dec_sse2.c b/thirdparty/libwebp/src/dsp/dec_sse2.c index 873aa59e8a..01e6bcb636 100644 --- a/thirdparty/libwebp/src/dsp/dec_sse2.c +++ b/thirdparty/libwebp/src/dsp/dec_sse2.c @@ -158,10 +158,10 @@ static void Transform_SSE2(const int16_t* in, uint8_t* dst, int do_two) { dst3 = _mm_loadl_epi64((__m128i*)(dst + 3 * BPS)); } else { // Load four bytes/pixels per line. - dst0 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 0 * BPS)); - dst1 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 1 * BPS)); - dst2 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 2 * BPS)); - dst3 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 3 * BPS)); + dst0 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 0 * BPS)); + dst1 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 1 * BPS)); + dst2 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 2 * BPS)); + dst3 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 3 * BPS)); } // Convert to 16b. dst0 = _mm_unpacklo_epi8(dst0, zero); @@ -187,10 +187,10 @@ static void Transform_SSE2(const int16_t* in, uint8_t* dst, int do_two) { _mm_storel_epi64((__m128i*)(dst + 3 * BPS), dst3); } else { // Store four bytes/pixels per line. - WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0)); - WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1)); - WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2)); - WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3)); + WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0)); + WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1)); + WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2)); + WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3)); } } } @@ -213,10 +213,10 @@ static void TransformAC3(const int16_t* in, uint8_t* dst) { const __m128i m3 = _mm_subs_epi16(B, d4); const __m128i zero = _mm_setzero_si128(); // Load the source pixels. - __m128i dst0 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 0 * BPS)); - __m128i dst1 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 1 * BPS)); - __m128i dst2 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 2 * BPS)); - __m128i dst3 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 3 * BPS)); + __m128i dst0 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 0 * BPS)); + __m128i dst1 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 1 * BPS)); + __m128i dst2 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 2 * BPS)); + __m128i dst3 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 3 * BPS)); // Convert to 16b. dst0 = _mm_unpacklo_epi8(dst0, zero); dst1 = _mm_unpacklo_epi8(dst1, zero); @@ -233,10 +233,10 @@ static void TransformAC3(const int16_t* in, uint8_t* dst) { dst2 = _mm_packus_epi16(dst2, dst2); dst3 = _mm_packus_epi16(dst3, dst3); // Store the results. - WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0)); - WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1)); - WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2)); - WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3)); + WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0)); + WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1)); + WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2)); + WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3)); } #undef MUL #endif // USE_TRANSFORM_AC3 @@ -477,11 +477,11 @@ static WEBP_INLINE void Load8x4_SSE2(const uint8_t* const b, int stride, // A0 = 63 62 61 60 23 22 21 20 43 42 41 40 03 02 01 00 // A1 = 73 72 71 70 33 32 31 30 53 52 51 50 13 12 11 10 const __m128i A0 = _mm_set_epi32( - WebPMemToUint32(&b[6 * stride]), WebPMemToUint32(&b[2 * stride]), - WebPMemToUint32(&b[4 * stride]), WebPMemToUint32(&b[0 * stride])); + WebPMemToInt32(&b[6 * stride]), WebPMemToInt32(&b[2 * stride]), + WebPMemToInt32(&b[4 * stride]), WebPMemToInt32(&b[0 * stride])); const __m128i A1 = _mm_set_epi32( - WebPMemToUint32(&b[7 * stride]), WebPMemToUint32(&b[3 * stride]), - WebPMemToUint32(&b[5 * stride]), WebPMemToUint32(&b[1 * stride])); + WebPMemToInt32(&b[7 * stride]), WebPMemToInt32(&b[3 * stride]), + WebPMemToInt32(&b[5 * stride]), WebPMemToInt32(&b[1 * stride])); // B0 = 53 43 52 42 51 41 50 40 13 03 12 02 11 01 10 00 // B1 = 73 63 72 62 71 61 70 60 33 23 32 22 31 21 30 20 @@ -540,7 +540,7 @@ static WEBP_INLINE void Store4x4_SSE2(__m128i* const x, uint8_t* dst, int stride) { int i; for (i = 0; i < 4; ++i, dst += stride) { - WebPUint32ToMem(dst, _mm_cvtsi128_si32(*x)); + WebPInt32ToMem(dst, _mm_cvtsi128_si32(*x)); *x = _mm_srli_si128(*x, 4); } } @@ -908,10 +908,10 @@ static void VE4_SSE2(uint8_t* dst) { // vertical const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGH00), one); const __m128i b = _mm_subs_epu8(a, lsb); const __m128i avg = _mm_avg_epu8(b, BCDEFGH0); - const uint32_t vals = _mm_cvtsi128_si32(avg); + const int vals = _mm_cvtsi128_si32(avg); int i; for (i = 0; i < 4; ++i) { - WebPUint32ToMem(dst + i * BPS, vals); + WebPInt32ToMem(dst + i * BPS, vals); } } @@ -925,10 +925,10 @@ static void LD4_SSE2(uint8_t* dst) { // Down-Left const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGHH0), one); const __m128i avg2 = _mm_subs_epu8(avg1, lsb); const __m128i abcdefg = _mm_avg_epu8(avg2, BCDEFGH0); - WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcdefg )); - WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1))); - WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2))); - WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3))); + WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcdefg )); + WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1))); + WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2))); + WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3))); } static void VR4_SSE2(uint8_t* dst) { // Vertical-Right @@ -946,10 +946,10 @@ static void VR4_SSE2(uint8_t* dst) { // Vertical-Right const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one); const __m128i avg2 = _mm_subs_epu8(avg1, lsb); const __m128i efgh = _mm_avg_epu8(avg2, XABCD); - WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcd )); - WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( efgh )); - WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1))); - WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1))); + WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcd )); + WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( efgh )); + WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1))); + WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1))); // these two are hard to implement in SSE2, so we keep the C-version: DST(0, 2) = AVG3(J, I, X); @@ -970,11 +970,12 @@ static void VL4_SSE2(uint8_t* dst) { // Vertical-Left const __m128i abbc = _mm_or_si128(ab, bc); const __m128i lsb2 = _mm_and_si128(abbc, lsb1); const __m128i avg4 = _mm_subs_epu8(avg3, lsb2); - const uint32_t extra_out = _mm_cvtsi128_si32(_mm_srli_si128(avg4, 4)); - WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( avg1 )); - WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( avg4 )); - WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1))); - WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1))); + const uint32_t extra_out = + (uint32_t)_mm_cvtsi128_si32(_mm_srli_si128(avg4, 4)); + WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( avg1 )); + WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( avg4 )); + WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1))); + WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1))); // these two are hard to get and irregular DST(3, 2) = (extra_out >> 0) & 0xff; @@ -990,7 +991,7 @@ static void RD4_SSE2(uint8_t* dst) { // Down-right const uint32_t K = dst[-1 + 2 * BPS]; const uint32_t L = dst[-1 + 3 * BPS]; const __m128i LKJI_____ = - _mm_cvtsi32_si128(L | (K << 8) | (J << 16) | (I << 24)); + _mm_cvtsi32_si128((int)(L | (K << 8) | (J << 16) | (I << 24))); const __m128i LKJIXABCD = _mm_or_si128(LKJI_____, ____XABCD); const __m128i KJIXABCD_ = _mm_srli_si128(LKJIXABCD, 1); const __m128i JIXABCD__ = _mm_srli_si128(LKJIXABCD, 2); @@ -998,10 +999,10 @@ static void RD4_SSE2(uint8_t* dst) { // Down-right const __m128i lsb = _mm_and_si128(_mm_xor_si128(JIXABCD__, LKJIXABCD), one); const __m128i avg2 = _mm_subs_epu8(avg1, lsb); const __m128i abcdefg = _mm_avg_epu8(avg2, KJIXABCD_); - WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32( abcdefg )); - WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1))); - WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2))); - WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3))); + WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32( abcdefg )); + WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1))); + WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2))); + WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3))); } #undef DST @@ -1015,13 +1016,13 @@ static WEBP_INLINE void TrueMotion_SSE2(uint8_t* dst, int size) { const __m128i zero = _mm_setzero_si128(); int y; if (size == 4) { - const __m128i top_values = _mm_cvtsi32_si128(WebPMemToUint32(top)); + const __m128i top_values = _mm_cvtsi32_si128(WebPMemToInt32(top)); const __m128i top_base = _mm_unpacklo_epi8(top_values, zero); for (y = 0; y < 4; ++y, dst += BPS) { const int val = dst[-1] - top[-1]; const __m128i base = _mm_set1_epi16(val); const __m128i out = _mm_packus_epi16(_mm_add_epi16(base, top_base), zero); - WebPUint32ToMem(dst, _mm_cvtsi128_si32(out)); + WebPInt32ToMem(dst, _mm_cvtsi128_si32(out)); } } else if (size == 8) { const __m128i top_values = _mm_loadl_epi64((const __m128i*)top); @@ -1062,7 +1063,7 @@ static void VE16_SSE2(uint8_t* dst) { static void HE16_SSE2(uint8_t* dst) { // horizontal int j; for (j = 16; j > 0; --j) { - const __m128i values = _mm_set1_epi8(dst[-1]); + const __m128i values = _mm_set1_epi8((char)dst[-1]); _mm_storeu_si128((__m128i*)dst, values); dst += BPS; } @@ -1070,7 +1071,7 @@ static void HE16_SSE2(uint8_t* dst) { // horizontal static WEBP_INLINE void Put16_SSE2(uint8_t v, uint8_t* dst) { int j; - const __m128i values = _mm_set1_epi8(v); + const __m128i values = _mm_set1_epi8((char)v); for (j = 0; j < 16; ++j) { _mm_storeu_si128((__m128i*)(dst + j * BPS), values); } @@ -1130,7 +1131,7 @@ static void VE8uv_SSE2(uint8_t* dst) { // vertical // helper for chroma-DC predictions static WEBP_INLINE void Put8x8uv_SSE2(uint8_t v, uint8_t* dst) { int j; - const __m128i values = _mm_set1_epi8(v); + const __m128i values = _mm_set1_epi8((char)v); for (j = 0; j < 8; ++j) { _mm_storel_epi64((__m128i*)(dst + j * BPS), values); } diff --git a/thirdparty/libwebp/src/dsp/dec_sse41.c b/thirdparty/libwebp/src/dsp/dec_sse41.c index 8f18506d54..08a3630272 100644 --- a/thirdparty/libwebp/src/dsp/dec_sse41.c +++ b/thirdparty/libwebp/src/dsp/dec_sse41.c @@ -23,7 +23,7 @@ static void HE16_SSE41(uint8_t* dst) { // horizontal int j; const __m128i kShuffle3 = _mm_set1_epi8(3); for (j = 16; j > 0; --j) { - const __m128i in = _mm_cvtsi32_si128(WebPMemToUint32(dst - 4)); + const __m128i in = _mm_cvtsi32_si128(WebPMemToInt32(dst - 4)); const __m128i values = _mm_shuffle_epi8(in, kShuffle3); _mm_storeu_si128((__m128i*)dst, values); dst += BPS; diff --git a/thirdparty/libwebp/src/dsp/enc_neon.c b/thirdparty/libwebp/src/dsp/enc_neon.c index 601962ba76..3a04111c55 100644 --- a/thirdparty/libwebp/src/dsp/enc_neon.c +++ b/thirdparty/libwebp/src/dsp/enc_neon.c @@ -764,9 +764,14 @@ static WEBP_INLINE void AccumulateSSE16_NEON(const uint8_t* const a, // Horizontal sum of all four uint32_t values in 'sum'. static int SumToInt_NEON(uint32x4_t sum) { +#if defined(__aarch64__) + return (int)vaddvq_u32(sum); +#else const uint64x2_t sum2 = vpaddlq_u32(sum); - const uint64_t sum3 = vgetq_lane_u64(sum2, 0) + vgetq_lane_u64(sum2, 1); - return (int)sum3; + const uint32x2_t sum3 = vadd_u32(vreinterpret_u32_u64(vget_low_u64(sum2)), + vreinterpret_u32_u64(vget_high_u64(sum2))); + return (int)vget_lane_u32(sum3, 0); +#endif } static int SSE16x16_NEON(const uint8_t* a, const uint8_t* b) { diff --git a/thirdparty/libwebp/src/dsp/enc_sse2.c b/thirdparty/libwebp/src/dsp/enc_sse2.c index b2e78ed941..1d1055668f 100644 --- a/thirdparty/libwebp/src/dsp/enc_sse2.c +++ b/thirdparty/libwebp/src/dsp/enc_sse2.c @@ -156,10 +156,10 @@ static void ITransform_SSE2(const uint8_t* ref, const int16_t* in, uint8_t* dst, ref3 = _mm_loadl_epi64((const __m128i*)&ref[3 * BPS]); } else { // Load four bytes/pixels per line. - ref0 = _mm_cvtsi32_si128(WebPMemToUint32(&ref[0 * BPS])); - ref1 = _mm_cvtsi32_si128(WebPMemToUint32(&ref[1 * BPS])); - ref2 = _mm_cvtsi32_si128(WebPMemToUint32(&ref[2 * BPS])); - ref3 = _mm_cvtsi32_si128(WebPMemToUint32(&ref[3 * BPS])); + ref0 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[0 * BPS])); + ref1 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[1 * BPS])); + ref2 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[2 * BPS])); + ref3 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[3 * BPS])); } // Convert to 16b. ref0 = _mm_unpacklo_epi8(ref0, zero); @@ -185,10 +185,10 @@ static void ITransform_SSE2(const uint8_t* ref, const int16_t* in, uint8_t* dst, _mm_storel_epi64((__m128i*)&dst[3 * BPS], ref3); } else { // Store four bytes/pixels per line. - WebPUint32ToMem(&dst[0 * BPS], _mm_cvtsi128_si32(ref0)); - WebPUint32ToMem(&dst[1 * BPS], _mm_cvtsi128_si32(ref1)); - WebPUint32ToMem(&dst[2 * BPS], _mm_cvtsi128_si32(ref2)); - WebPUint32ToMem(&dst[3 * BPS], _mm_cvtsi128_si32(ref3)); + WebPInt32ToMem(&dst[0 * BPS], _mm_cvtsi128_si32(ref0)); + WebPInt32ToMem(&dst[1 * BPS], _mm_cvtsi128_si32(ref1)); + WebPInt32ToMem(&dst[2 * BPS], _mm_cvtsi128_si32(ref2)); + WebPInt32ToMem(&dst[3 * BPS], _mm_cvtsi128_si32(ref3)); } } } @@ -481,7 +481,7 @@ static void CollectHistogram_SSE2(const uint8_t* ref, const uint8_t* pred, // helper for chroma-DC predictions static WEBP_INLINE void Put8x8uv_SSE2(uint8_t v, uint8_t* dst) { int j; - const __m128i values = _mm_set1_epi8(v); + const __m128i values = _mm_set1_epi8((char)v); for (j = 0; j < 8; ++j) { _mm_storel_epi64((__m128i*)(dst + j * BPS), values); } @@ -489,7 +489,7 @@ static WEBP_INLINE void Put8x8uv_SSE2(uint8_t v, uint8_t* dst) { static WEBP_INLINE void Put16_SSE2(uint8_t v, uint8_t* dst) { int j; - const __m128i values = _mm_set1_epi8(v); + const __m128i values = _mm_set1_epi8((char)v); for (j = 0; j < 16; ++j) { _mm_store_si128((__m128i*)(dst + j * BPS), values); } @@ -540,7 +540,7 @@ static WEBP_INLINE void VerticalPred_SSE2(uint8_t* dst, static WEBP_INLINE void HE8uv_SSE2(uint8_t* dst, const uint8_t* left) { int j; for (j = 0; j < 8; ++j) { - const __m128i values = _mm_set1_epi8(left[j]); + const __m128i values = _mm_set1_epi8((char)left[j]); _mm_storel_epi64((__m128i*)dst, values); dst += BPS; } @@ -549,7 +549,7 @@ static WEBP_INLINE void HE8uv_SSE2(uint8_t* dst, const uint8_t* left) { static WEBP_INLINE void HE16_SSE2(uint8_t* dst, const uint8_t* left) { int j; for (j = 0; j < 16; ++j) { - const __m128i values = _mm_set1_epi8(left[j]); + const __m128i values = _mm_set1_epi8((char)left[j]); _mm_store_si128((__m128i*)dst, values); dst += BPS; } @@ -722,10 +722,10 @@ static WEBP_INLINE void VE4_SSE2(uint8_t* dst, const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGH00), one); const __m128i b = _mm_subs_epu8(a, lsb); const __m128i avg = _mm_avg_epu8(b, BCDEFGH0); - const uint32_t vals = _mm_cvtsi128_si32(avg); + const int vals = _mm_cvtsi128_si32(avg); int i; for (i = 0; i < 4; ++i) { - WebPUint32ToMem(dst + i * BPS, vals); + WebPInt32ToMem(dst + i * BPS, vals); } } @@ -760,10 +760,10 @@ static WEBP_INLINE void LD4_SSE2(uint8_t* dst, const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGHH0), one); const __m128i avg2 = _mm_subs_epu8(avg1, lsb); const __m128i abcdefg = _mm_avg_epu8(avg2, BCDEFGH0); - WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcdefg )); - WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1))); - WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2))); - WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3))); + WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcdefg )); + WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1))); + WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2))); + WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3))); } static WEBP_INLINE void VR4_SSE2(uint8_t* dst, @@ -782,10 +782,10 @@ static WEBP_INLINE void VR4_SSE2(uint8_t* dst, const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one); const __m128i avg2 = _mm_subs_epu8(avg1, lsb); const __m128i efgh = _mm_avg_epu8(avg2, XABCD); - WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcd )); - WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( efgh )); - WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1))); - WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1))); + WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcd )); + WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( efgh )); + WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1))); + WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1))); // these two are hard to implement in SSE2, so we keep the C-version: DST(0, 2) = AVG3(J, I, X); @@ -807,11 +807,12 @@ static WEBP_INLINE void VL4_SSE2(uint8_t* dst, const __m128i abbc = _mm_or_si128(ab, bc); const __m128i lsb2 = _mm_and_si128(abbc, lsb1); const __m128i avg4 = _mm_subs_epu8(avg3, lsb2); - const uint32_t extra_out = _mm_cvtsi128_si32(_mm_srli_si128(avg4, 4)); - WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( avg1 )); - WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( avg4 )); - WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1))); - WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1))); + const uint32_t extra_out = + (uint32_t)_mm_cvtsi128_si32(_mm_srli_si128(avg4, 4)); + WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( avg1 )); + WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( avg4 )); + WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1))); + WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1))); // these two are hard to get and irregular DST(3, 2) = (extra_out >> 0) & 0xff; @@ -829,10 +830,10 @@ static WEBP_INLINE void RD4_SSE2(uint8_t* dst, const __m128i lsb = _mm_and_si128(_mm_xor_si128(JIXABCD__, LKJIXABCD), one); const __m128i avg2 = _mm_subs_epu8(avg1, lsb); const __m128i abcdefg = _mm_avg_epu8(avg2, KJIXABCD_); - WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32( abcdefg )); - WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1))); - WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2))); - WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3))); + WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32( abcdefg )); + WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1))); + WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2))); + WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3))); } static WEBP_INLINE void HU4_SSE2(uint8_t* dst, const uint8_t* top) { @@ -875,14 +876,14 @@ static WEBP_INLINE void HD4_SSE2(uint8_t* dst, const uint8_t* top) { static WEBP_INLINE void TM4_SSE2(uint8_t* dst, const uint8_t* top) { const __m128i zero = _mm_setzero_si128(); - const __m128i top_values = _mm_cvtsi32_si128(WebPMemToUint32(top)); + const __m128i top_values = _mm_cvtsi32_si128(WebPMemToInt32(top)); const __m128i top_base = _mm_unpacklo_epi8(top_values, zero); int y; for (y = 0; y < 4; ++y, dst += BPS) { const int val = top[-2 - y] - top[-1]; const __m128i base = _mm_set1_epi16(val); const __m128i out = _mm_packus_epi16(_mm_add_epi16(base, top_base), zero); - WebPUint32ToMem(dst, _mm_cvtsi128_si32(out)); + WebPInt32ToMem(dst, _mm_cvtsi128_si32(out)); } } diff --git a/thirdparty/libwebp/src/dsp/lossless.c b/thirdparty/libwebp/src/dsp/lossless.c index 84a54296fd..fb86e58d4a 100644 --- a/thirdparty/libwebp/src/dsp/lossless.c +++ b/thirdparty/libwebp/src/dsp/lossless.c @@ -49,7 +49,7 @@ static WEBP_INLINE uint32_t Clip255(uint32_t a) { } static WEBP_INLINE int AddSubtractComponentFull(int a, int b, int c) { - return Clip255(a + b - c); + return Clip255((uint32_t)(a + b - c)); } static WEBP_INLINE uint32_t ClampedAddSubtractFull(uint32_t c0, uint32_t c1, @@ -66,7 +66,7 @@ static WEBP_INLINE uint32_t ClampedAddSubtractFull(uint32_t c0, uint32_t c1, } static WEBP_INLINE int AddSubtractComponentHalf(int a, int b) { - return Clip255(a + (a - b) / 2); + return Clip255((uint32_t)(a + (a - b) / 2)); } static WEBP_INLINE uint32_t ClampedAddSubtractHalf(uint32_t c0, uint32_t c1, @@ -293,10 +293,10 @@ void VP8LTransformColorInverse_C(const VP8LMultipliers* const m, const uint32_t red = argb >> 16; int new_red = red & 0xff; int new_blue = argb & 0xff; - new_red += ColorTransformDelta(m->green_to_red_, green); + new_red += ColorTransformDelta((int8_t)m->green_to_red_, green); new_red &= 0xff; - new_blue += ColorTransformDelta(m->green_to_blue_, green); - new_blue += ColorTransformDelta(m->red_to_blue_, (int8_t)new_red); + new_blue += ColorTransformDelta((int8_t)m->green_to_blue_, green); + new_blue += ColorTransformDelta((int8_t)m->red_to_blue_, (int8_t)new_red); new_blue &= 0xff; dst[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue); } @@ -395,7 +395,7 @@ void VP8LInverseTransform(const VP8LTransform* const transform, assert(row_start < row_end); assert(row_end <= transform->ysize_); switch (transform->type_) { - case SUBTRACT_GREEN: + case SUBTRACT_GREEN_TRANSFORM: VP8LAddGreenToBlueAndRed(in, (row_end - row_start) * width, out); break; case PREDICTOR_TRANSFORM: diff --git a/thirdparty/libwebp/src/dsp/lossless_enc.c b/thirdparty/libwebp/src/dsp/lossless_enc.c index de6c4ace5f..b1f9f26d72 100644 --- a/thirdparty/libwebp/src/dsp/lossless_enc.c +++ b/thirdparty/libwebp/src/dsp/lossless_enc.c @@ -522,11 +522,11 @@ static void GetCombinedEntropyUnrefined_C(const uint32_t X[], void VP8LSubtractGreenFromBlueAndRed_C(uint32_t* argb_data, int num_pixels) { int i; for (i = 0; i < num_pixels; ++i) { - const int argb = argb_data[i]; + const int argb = (int)argb_data[i]; const int green = (argb >> 8) & 0xff; const uint32_t new_r = (((argb >> 16) & 0xff) - green) & 0xff; const uint32_t new_b = (((argb >> 0) & 0xff) - green) & 0xff; - argb_data[i] = (argb & 0xff00ff00u) | (new_r << 16) | new_b; + argb_data[i] = ((uint32_t)argb & 0xff00ff00u) | (new_r << 16) | new_b; } } @@ -547,10 +547,10 @@ void VP8LTransformColor_C(const VP8LMultipliers* const m, uint32_t* data, const int8_t red = U32ToS8(argb >> 16); int new_red = red & 0xff; int new_blue = argb & 0xff; - new_red -= ColorTransformDelta(m->green_to_red_, green); + new_red -= ColorTransformDelta((int8_t)m->green_to_red_, green); new_red &= 0xff; - new_blue -= ColorTransformDelta(m->green_to_blue_, green); - new_blue -= ColorTransformDelta(m->red_to_blue_, red); + new_blue -= ColorTransformDelta((int8_t)m->green_to_blue_, green); + new_blue -= ColorTransformDelta((int8_t)m->red_to_blue_, red); new_blue &= 0xff; data[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue); } @@ -560,7 +560,7 @@ static WEBP_INLINE uint8_t TransformColorRed(uint8_t green_to_red, uint32_t argb) { const int8_t green = U32ToS8(argb >> 8); int new_red = argb >> 16; - new_red -= ColorTransformDelta(green_to_red, green); + new_red -= ColorTransformDelta((int8_t)green_to_red, green); return (new_red & 0xff); } @@ -569,9 +569,9 @@ static WEBP_INLINE uint8_t TransformColorBlue(uint8_t green_to_blue, uint32_t argb) { const int8_t green = U32ToS8(argb >> 8); const int8_t red = U32ToS8(argb >> 16); - uint8_t new_blue = argb & 0xff; - new_blue -= ColorTransformDelta(green_to_blue, green); - new_blue -= ColorTransformDelta(red_to_blue, red); + int new_blue = argb & 0xff; + new_blue -= ColorTransformDelta((int8_t)green_to_blue, green); + new_blue -= ColorTransformDelta((int8_t)red_to_blue, red); return (new_blue & 0xff); } diff --git a/thirdparty/libwebp/src/dsp/lossless_enc_sse2.c b/thirdparty/libwebp/src/dsp/lossless_enc_sse2.c index 948001a3d5..66cbaab772 100644 --- a/thirdparty/libwebp/src/dsp/lossless_enc_sse2.c +++ b/thirdparty/libwebp/src/dsp/lossless_enc_sse2.c @@ -54,8 +54,8 @@ static void TransformColor_SSE2(const VP8LMultipliers* const m, const __m128i mults_rb = MK_CST_16(CST_5b(m->green_to_red_), CST_5b(m->green_to_blue_)); const __m128i mults_b2 = MK_CST_16(CST_5b(m->red_to_blue_), 0); - const __m128i mask_ag = _mm_set1_epi32(0xff00ff00); // alpha-green masks - const __m128i mask_rb = _mm_set1_epi32(0x00ff00ff); // red-blue masks + const __m128i mask_ag = _mm_set1_epi32((int)0xff00ff00); // alpha-green masks + const __m128i mask_rb = _mm_set1_epi32(0x00ff00ff); // red-blue masks int i; for (i = 0; i + 4 <= num_pixels; i += 4) { const __m128i in = _mm_loadu_si128((__m128i*)&argb_data[i]); // argb @@ -376,7 +376,7 @@ static void BundleColorMap_SSE2(const uint8_t* const row, int width, int xbits, break; } case 2: { - const __m128i mask_or = _mm_set1_epi32(0xff000000); + const __m128i mask_or = _mm_set1_epi32((int)0xff000000); const __m128i mul_cst = _mm_set1_epi16(0x0104); const __m128i mask_mul = _mm_set1_epi16(0x0f00); for (x = 0; x + 16 <= width; x += 16, dst += 4) { @@ -427,7 +427,7 @@ static WEBP_INLINE void Average2_m128i(const __m128i* const a0, static void PredictorSub0_SSE2(const uint32_t* in, const uint32_t* upper, int num_pixels, uint32_t* out) { int i; - const __m128i black = _mm_set1_epi32(ARGB_BLACK); + const __m128i black = _mm_set1_epi32((int)ARGB_BLACK); for (i = 0; i + 4 <= num_pixels; i += 4) { const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]); const __m128i res = _mm_sub_epi8(src, black); diff --git a/thirdparty/libwebp/src/dsp/lossless_sse2.c b/thirdparty/libwebp/src/dsp/lossless_sse2.c index 396cb0bdfc..4b6a532c23 100644 --- a/thirdparty/libwebp/src/dsp/lossless_sse2.c +++ b/thirdparty/libwebp/src/dsp/lossless_sse2.c @@ -27,23 +27,22 @@ static WEBP_INLINE uint32_t ClampedAddSubtractFull_SSE2(uint32_t c0, uint32_t c1, uint32_t c2) { const __m128i zero = _mm_setzero_si128(); - const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c0), zero); - const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c1), zero); - const __m128i C2 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c2), zero); + const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c0), zero); + const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c1), zero); + const __m128i C2 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c2), zero); const __m128i V1 = _mm_add_epi16(C0, C1); const __m128i V2 = _mm_sub_epi16(V1, C2); const __m128i b = _mm_packus_epi16(V2, V2); - const uint32_t output = _mm_cvtsi128_si32(b); - return output; + return (uint32_t)_mm_cvtsi128_si32(b); } static WEBP_INLINE uint32_t ClampedAddSubtractHalf_SSE2(uint32_t c0, uint32_t c1, uint32_t c2) { const __m128i zero = _mm_setzero_si128(); - const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c0), zero); - const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c1), zero); - const __m128i B0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c2), zero); + const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c0), zero); + const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c1), zero); + const __m128i B0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c2), zero); const __m128i avg = _mm_add_epi16(C1, C0); const __m128i A0 = _mm_srli_epi16(avg, 1); const __m128i A1 = _mm_sub_epi16(A0, B0); @@ -52,16 +51,15 @@ static WEBP_INLINE uint32_t ClampedAddSubtractHalf_SSE2(uint32_t c0, const __m128i A3 = _mm_srai_epi16(A2, 1); const __m128i A4 = _mm_add_epi16(A0, A3); const __m128i A5 = _mm_packus_epi16(A4, A4); - const uint32_t output = _mm_cvtsi128_si32(A5); - return output; + return (uint32_t)_mm_cvtsi128_si32(A5); } static WEBP_INLINE uint32_t Select_SSE2(uint32_t a, uint32_t b, uint32_t c) { int pa_minus_pb; const __m128i zero = _mm_setzero_si128(); - const __m128i A0 = _mm_cvtsi32_si128(a); - const __m128i B0 = _mm_cvtsi32_si128(b); - const __m128i C0 = _mm_cvtsi32_si128(c); + const __m128i A0 = _mm_cvtsi32_si128((int)a); + const __m128i B0 = _mm_cvtsi32_si128((int)b); + const __m128i C0 = _mm_cvtsi32_si128((int)c); const __m128i AC0 = _mm_subs_epu8(A0, C0); const __m128i CA0 = _mm_subs_epu8(C0, A0); const __m128i BC0 = _mm_subs_epu8(B0, C0); @@ -94,8 +92,8 @@ static WEBP_INLINE void Average2_uint32_SSE2(const uint32_t a0, __m128i* const avg) { // (a + b) >> 1 = ((a + b + 1) >> 1) - ((a ^ b) & 1) const __m128i ones = _mm_set1_epi8(1); - const __m128i A0 = _mm_cvtsi32_si128(a0); - const __m128i A1 = _mm_cvtsi32_si128(a1); + const __m128i A0 = _mm_cvtsi32_si128((int)a0); + const __m128i A1 = _mm_cvtsi32_si128((int)a1); const __m128i avg1 = _mm_avg_epu8(A0, A1); const __m128i one = _mm_and_si128(_mm_xor_si128(A0, A1), ones); *avg = _mm_sub_epi8(avg1, one); @@ -103,8 +101,8 @@ static WEBP_INLINE void Average2_uint32_SSE2(const uint32_t a0, static WEBP_INLINE __m128i Average2_uint32_16_SSE2(uint32_t a0, uint32_t a1) { const __m128i zero = _mm_setzero_si128(); - const __m128i A0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(a0), zero); - const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(a1), zero); + const __m128i A0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)a0), zero); + const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)a1), zero); const __m128i sum = _mm_add_epi16(A1, A0); return _mm_srli_epi16(sum, 1); } @@ -112,19 +110,18 @@ static WEBP_INLINE __m128i Average2_uint32_16_SSE2(uint32_t a0, uint32_t a1) { static WEBP_INLINE uint32_t Average2_SSE2(uint32_t a0, uint32_t a1) { __m128i output; Average2_uint32_SSE2(a0, a1, &output); - return _mm_cvtsi128_si32(output); + return (uint32_t)_mm_cvtsi128_si32(output); } static WEBP_INLINE uint32_t Average3_SSE2(uint32_t a0, uint32_t a1, uint32_t a2) { const __m128i zero = _mm_setzero_si128(); const __m128i avg1 = Average2_uint32_16_SSE2(a0, a2); - const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(a1), zero); + const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)a1), zero); const __m128i sum = _mm_add_epi16(avg1, A1); const __m128i avg2 = _mm_srli_epi16(sum, 1); const __m128i A2 = _mm_packus_epi16(avg2, avg2); - const uint32_t output = _mm_cvtsi128_si32(A2); - return output; + return (uint32_t)_mm_cvtsi128_si32(A2); } static WEBP_INLINE uint32_t Average4_SSE2(uint32_t a0, uint32_t a1, @@ -134,8 +131,7 @@ static WEBP_INLINE uint32_t Average4_SSE2(uint32_t a0, uint32_t a1, const __m128i sum = _mm_add_epi16(avg2, avg1); const __m128i avg3 = _mm_srli_epi16(sum, 1); const __m128i A0 = _mm_packus_epi16(avg3, avg3); - const uint32_t output = _mm_cvtsi128_si32(A0); - return output; + return (uint32_t)_mm_cvtsi128_si32(A0); } static uint32_t Predictor5_SSE2(const uint32_t* const left, @@ -192,7 +188,7 @@ static uint32_t Predictor13_SSE2(const uint32_t* const left, static void PredictorAdd0_SSE2(const uint32_t* in, const uint32_t* upper, int num_pixels, uint32_t* out) { int i; - const __m128i black = _mm_set1_epi32(ARGB_BLACK); + const __m128i black = _mm_set1_epi32((int)ARGB_BLACK); for (i = 0; i + 4 <= num_pixels; i += 4) { const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]); const __m128i res = _mm_add_epi8(src, black); @@ -208,7 +204,7 @@ static void PredictorAdd0_SSE2(const uint32_t* in, const uint32_t* upper, static void PredictorAdd1_SSE2(const uint32_t* in, const uint32_t* upper, int num_pixels, uint32_t* out) { int i; - __m128i prev = _mm_set1_epi32(out[-1]); + __m128i prev = _mm_set1_epi32((int)out[-1]); for (i = 0; i + 4 <= num_pixels; i += 4) { // a | b | c | d const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]); @@ -285,12 +281,12 @@ GENERATE_PREDICTOR_2(9, upper[i + 1]) #undef GENERATE_PREDICTOR_2 // Predictor10: average of (average of (L,TL), average of (T, TR)). -#define DO_PRED10(OUT) do { \ - __m128i avgLTL, avg; \ - Average2_m128i(&L, &TL, &avgLTL); \ - Average2_m128i(&avgTTR, &avgLTL, &avg); \ - L = _mm_add_epi8(avg, src); \ - out[i + (OUT)] = _mm_cvtsi128_si32(L); \ +#define DO_PRED10(OUT) do { \ + __m128i avgLTL, avg; \ + Average2_m128i(&L, &TL, &avgLTL); \ + Average2_m128i(&avgTTR, &avgLTL, &avg); \ + L = _mm_add_epi8(avg, src); \ + out[i + (OUT)] = (uint32_t)_mm_cvtsi128_si32(L); \ } while (0) #define DO_PRED10_SHIFT do { \ @@ -303,7 +299,7 @@ GENERATE_PREDICTOR_2(9, upper[i + 1]) static void PredictorAdd10_SSE2(const uint32_t* in, const uint32_t* upper, int num_pixels, uint32_t* out) { int i; - __m128i L = _mm_cvtsi32_si128(out[-1]); + __m128i L = _mm_cvtsi32_si128((int)out[-1]); for (i = 0; i + 4 <= num_pixels; i += 4) { __m128i src = _mm_loadu_si128((const __m128i*)&in[i]); __m128i TL = _mm_loadu_si128((const __m128i*)&upper[i - 1]); @@ -336,7 +332,7 @@ static void PredictorAdd10_SSE2(const uint32_t* in, const uint32_t* upper, const __m128i B = _mm_andnot_si128(mask, T); \ const __m128i pred = _mm_or_si128(A, B); /* pred = (pa > b)? L : T*/ \ L = _mm_add_epi8(src, pred); \ - out[i + (OUT)] = _mm_cvtsi128_si32(L); \ + out[i + (OUT)] = (uint32_t)_mm_cvtsi128_si32(L); \ } while (0) #define DO_PRED11_SHIFT do { \ @@ -351,7 +347,7 @@ static void PredictorAdd11_SSE2(const uint32_t* in, const uint32_t* upper, int num_pixels, uint32_t* out) { int i; __m128i pa; - __m128i L = _mm_cvtsi32_si128(out[-1]); + __m128i L = _mm_cvtsi32_si128((int)out[-1]); for (i = 0; i + 4 <= num_pixels; i += 4) { __m128i T = _mm_loadu_si128((const __m128i*)&upper[i]); __m128i TL = _mm_loadu_si128((const __m128i*)&upper[i - 1]); @@ -384,12 +380,12 @@ static void PredictorAdd11_SSE2(const uint32_t* in, const uint32_t* upper, #undef DO_PRED11_SHIFT // Predictor12: ClampedAddSubtractFull. -#define DO_PRED12(DIFF, LANE, OUT) do { \ - const __m128i all = _mm_add_epi16(L, (DIFF)); \ - const __m128i alls = _mm_packus_epi16(all, all); \ - const __m128i res = _mm_add_epi8(src, alls); \ - out[i + (OUT)] = _mm_cvtsi128_si32(res); \ - L = _mm_unpacklo_epi8(res, zero); \ +#define DO_PRED12(DIFF, LANE, OUT) do { \ + const __m128i all = _mm_add_epi16(L, (DIFF)); \ + const __m128i alls = _mm_packus_epi16(all, all); \ + const __m128i res = _mm_add_epi8(src, alls); \ + out[i + (OUT)] = (uint32_t)_mm_cvtsi128_si32(res); \ + L = _mm_unpacklo_epi8(res, zero); \ } while (0) #define DO_PRED12_SHIFT(DIFF, LANE) do { \ @@ -402,7 +398,7 @@ static void PredictorAdd12_SSE2(const uint32_t* in, const uint32_t* upper, int num_pixels, uint32_t* out) { int i; const __m128i zero = _mm_setzero_si128(); - const __m128i L8 = _mm_cvtsi32_si128(out[-1]); + const __m128i L8 = _mm_cvtsi32_si128((int)out[-1]); __m128i L = _mm_unpacklo_epi8(L8, zero); for (i = 0; i + 4 <= num_pixels; i += 4) { // Load 4 pixels at a time. @@ -468,7 +464,7 @@ static void TransformColorInverse_SSE2(const VP8LMultipliers* const m, const __m128i mults_b2 = MK_CST_16(CST(red_to_blue_), 0); #undef MK_CST_16 #undef CST - const __m128i mask_ag = _mm_set1_epi32(0xff00ff00); // alpha-green masks + const __m128i mask_ag = _mm_set1_epi32((int)0xff00ff00); // alpha-green masks int i; for (i = 0; i + 4 <= num_pixels; i += 4) { const __m128i in = _mm_loadu_si128((const __m128i*)&src[i]); // argb @@ -532,7 +528,7 @@ static void ConvertBGRAToRGB_SSE2(const uint32_t* src, int num_pixels, static void ConvertBGRAToRGBA_SSE2(const uint32_t* src, int num_pixels, uint8_t* dst) { - const __m128i red_blue_mask = _mm_set1_epi32(0x00ff00ffu); + const __m128i red_blue_mask = _mm_set1_epi32(0x00ff00ff); const __m128i* in = (const __m128i*)src; __m128i* out = (__m128i*)dst; while (num_pixels >= 8) { @@ -561,7 +557,7 @@ static void ConvertBGRAToRGBA_SSE2(const uint32_t* src, static void ConvertBGRAToRGBA4444_SSE2(const uint32_t* src, int num_pixels, uint8_t* dst) { const __m128i mask_0x0f = _mm_set1_epi8(0x0f); - const __m128i mask_0xf0 = _mm_set1_epi8(0xf0); + const __m128i mask_0xf0 = _mm_set1_epi8((char)0xf0); const __m128i* in = (const __m128i*)src; __m128i* out = (__m128i*)dst; while (num_pixels >= 8) { @@ -596,8 +592,8 @@ static void ConvertBGRAToRGBA4444_SSE2(const uint32_t* src, static void ConvertBGRAToRGB565_SSE2(const uint32_t* src, int num_pixels, uint8_t* dst) { - const __m128i mask_0xe0 = _mm_set1_epi8(0xe0); - const __m128i mask_0xf8 = _mm_set1_epi8(0xf8); + const __m128i mask_0xe0 = _mm_set1_epi8((char)0xe0); + const __m128i mask_0xf8 = _mm_set1_epi8((char)0xf8); const __m128i mask_0x07 = _mm_set1_epi8(0x07); const __m128i* in = (const __m128i*)src; __m128i* out = (__m128i*)dst; diff --git a/thirdparty/libwebp/src/dsp/lossless_sse41.c b/thirdparty/libwebp/src/dsp/lossless_sse41.c index b0d6daa7fe..bb7ce7611f 100644 --- a/thirdparty/libwebp/src/dsp/lossless_sse41.c +++ b/thirdparty/libwebp/src/dsp/lossless_sse41.c @@ -25,11 +25,12 @@ static void TransformColorInverse_SSE41(const VP8LMultipliers* const m, int num_pixels, uint32_t* dst) { // sign-extended multiplying constants, pre-shifted by 5. #define CST(X) (((int16_t)(m->X << 8)) >> 5) // sign-extend - const __m128i mults_rb = _mm_set1_epi32((uint32_t)CST(green_to_red_) << 16 | - (CST(green_to_blue_) & 0xffff)); + const __m128i mults_rb = + _mm_set1_epi32((int)((uint32_t)CST(green_to_red_) << 16 | + (CST(green_to_blue_) & 0xffff))); const __m128i mults_b2 = _mm_set1_epi32(CST(red_to_blue_)); #undef CST - const __m128i mask_ag = _mm_set1_epi32(0xff00ff00); + const __m128i mask_ag = _mm_set1_epi32((int)0xff00ff00); const __m128i perm1 = _mm_setr_epi8(-1, 1, -1, 1, -1, 5, -1, 5, -1, 9, -1, 9, -1, 13, -1, 13); const __m128i perm2 = _mm_setr_epi8(-1, 2, -1, -1, -1, 6, -1, -1, diff --git a/thirdparty/libwebp/src/dsp/quant.h b/thirdparty/libwebp/src/dsp/quant.h index 5e8dba8d19..fc099bf9d6 100644 --- a/thirdparty/libwebp/src/dsp/quant.h +++ b/thirdparty/libwebp/src/dsp/quant.h @@ -21,10 +21,15 @@ #define IsFlat IsFlat_NEON -static uint32x2_t horizontal_add_uint32x4(const uint32x4_t a) { +static uint32_t horizontal_add_uint32x4(const uint32x4_t a) { +#if defined(__aarch64__) + return vaddvq_u32(a); +#else const uint64x2_t b = vpaddlq_u32(a); - return vadd_u32(vreinterpret_u32_u64(vget_low_u64(b)), - vreinterpret_u32_u64(vget_high_u64(b))); + const uint32x2_t c = vadd_u32(vreinterpret_u32_u64(vget_low_u64(b)), + vreinterpret_u32_u64(vget_high_u64(b))); + return vget_lane_u32(c, 0); +#endif } static WEBP_INLINE int IsFlat(const int16_t* levels, int num_blocks, @@ -45,7 +50,7 @@ static WEBP_INLINE int IsFlat(const int16_t* levels, int num_blocks, levels += 16; } - return thresh >= (int32_t)vget_lane_u32(horizontal_add_uint32x4(sum), 0); + return thresh >= (int)horizontal_add_uint32x4(sum); } #else diff --git a/thirdparty/libwebp/src/dsp/rescaler_sse2.c b/thirdparty/libwebp/src/dsp/rescaler_sse2.c index d7effea16e..3f18e94e93 100644 --- a/thirdparty/libwebp/src/dsp/rescaler_sse2.c +++ b/thirdparty/libwebp/src/dsp/rescaler_sse2.c @@ -85,7 +85,7 @@ static void RescalerImportRowExpand_SSE2(WebPRescaler* const wrk, const __m128i mult = _mm_cvtsi32_si128(((x_add - accum) << 16) | accum); const __m128i out = _mm_madd_epi16(cur_pixels, mult); assert(sizeof(*frow) == sizeof(uint32_t)); - WebPUint32ToMem((uint8_t*)frow, _mm_cvtsi128_si32(out)); + WebPInt32ToMem((uint8_t*)frow, _mm_cvtsi128_si32(out)); frow += 1; if (frow >= frow_end) break; accum -= wrk->x_sub; @@ -132,7 +132,7 @@ static void RescalerImportRowShrink_SSE2(WebPRescaler* const wrk, __m128i base = zero; accum += wrk->x_add; while (accum > 0) { - const __m128i A = _mm_cvtsi32_si128(WebPMemToUint32(src)); + const __m128i A = _mm_cvtsi32_si128(WebPMemToInt32(src)); src += 4; base = _mm_unpacklo_epi8(A, zero); // To avoid overflow, we need: base * x_add / x_sub < 32768 @@ -198,7 +198,7 @@ static WEBP_INLINE void ProcessRow_SSE2(const __m128i* const A0, const __m128i* const mult, uint8_t* const dst) { const __m128i rounder = _mm_set_epi32(0, ROUNDER, 0, ROUNDER); - const __m128i mask = _mm_set_epi32(0xffffffffu, 0, 0xffffffffu, 0); + const __m128i mask = _mm_set_epi32(~0, 0, ~0, 0); const __m128i B0 = _mm_mul_epu32(*A0, *mult); const __m128i B1 = _mm_mul_epu32(*A1, *mult); const __m128i B2 = _mm_mul_epu32(*A2, *mult); diff --git a/thirdparty/libwebp/src/dsp/upsampling_sse2.c b/thirdparty/libwebp/src/dsp/upsampling_sse2.c index 340f1e2ac2..08b6d0b1cf 100644 --- a/thirdparty/libwebp/src/dsp/upsampling_sse2.c +++ b/thirdparty/libwebp/src/dsp/upsampling_sse2.c @@ -121,7 +121,7 @@ static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y, \ int uv_pos, pos; \ /* 16byte-aligned array to cache reconstructed u and v */ \ uint8_t uv_buf[14 * 32 + 15] = { 0 }; \ - uint8_t* const r_u = (uint8_t*)((uintptr_t)(uv_buf + 15) & ~15); \ + uint8_t* const r_u = (uint8_t*)((uintptr_t)(uv_buf + 15) & ~(uintptr_t)15); \ uint8_t* const r_v = r_u + 32; \ \ assert(top_y != NULL); \ diff --git a/thirdparty/libwebp/src/dsp/yuv_sse2.c b/thirdparty/libwebp/src/dsp/yuv_sse2.c index 970bbb7884..01a48f9af2 100644 --- a/thirdparty/libwebp/src/dsp/yuv_sse2.c +++ b/thirdparty/libwebp/src/dsp/yuv_sse2.c @@ -15,10 +15,12 @@ #if defined(WEBP_USE_SSE2) -#include "src/dsp/common_sse2.h" #include <stdlib.h> #include <emmintrin.h> +#include "src/dsp/common_sse2.h" +#include "src/utils/utils.h" + //----------------------------------------------------------------------------- // Convert spans of 32 pixels to various RGB formats for the fancy upsampler. @@ -74,7 +76,7 @@ static WEBP_INLINE __m128i Load_HI_16_SSE2(const uint8_t* src) { // Load and replicate the U/V samples static WEBP_INLINE __m128i Load_UV_HI_8_SSE2(const uint8_t* src) { const __m128i zero = _mm_setzero_si128(); - const __m128i tmp0 = _mm_cvtsi32_si128(*(const uint32_t*)src); + const __m128i tmp0 = _mm_cvtsi32_si128(WebPMemToInt32(src)); const __m128i tmp1 = _mm_unpacklo_epi8(zero, tmp0); return _mm_unpacklo_epi16(tmp1, tmp1); // replicate samples } @@ -130,7 +132,7 @@ static WEBP_INLINE void PackAndStore4444_SSE2(const __m128i* const R, const __m128i rg0 = _mm_packus_epi16(*B, *A); const __m128i ba0 = _mm_packus_epi16(*R, *G); #endif - const __m128i mask_0xf0 = _mm_set1_epi8(0xf0); + const __m128i mask_0xf0 = _mm_set1_epi8((char)0xf0); const __m128i rb1 = _mm_unpacklo_epi8(rg0, ba0); // rbrbrbrbrb... const __m128i ga1 = _mm_unpackhi_epi8(rg0, ba0); // gagagagaga... const __m128i rb2 = _mm_and_si128(rb1, mask_0xf0); @@ -147,9 +149,10 @@ static WEBP_INLINE void PackAndStore565_SSE2(const __m128i* const R, const __m128i r0 = _mm_packus_epi16(*R, *R); const __m128i g0 = _mm_packus_epi16(*G, *G); const __m128i b0 = _mm_packus_epi16(*B, *B); - const __m128i r1 = _mm_and_si128(r0, _mm_set1_epi8(0xf8)); + const __m128i r1 = _mm_and_si128(r0, _mm_set1_epi8((char)0xf8)); const __m128i b1 = _mm_and_si128(_mm_srli_epi16(b0, 3), _mm_set1_epi8(0x1f)); - const __m128i g1 = _mm_srli_epi16(_mm_and_si128(g0, _mm_set1_epi8(0xe0)), 5); + const __m128i g1 = + _mm_srli_epi16(_mm_and_si128(g0, _mm_set1_epi8((char)0xe0)), 5); const __m128i g2 = _mm_slli_epi16(_mm_and_si128(g0, _mm_set1_epi8(0x1c)), 3); const __m128i rg = _mm_or_si128(r1, g1); const __m128i gb = _mm_or_si128(g2, b1); diff --git a/thirdparty/libwebp/src/dsp/yuv_sse41.c b/thirdparty/libwebp/src/dsp/yuv_sse41.c index 579d1f7402..f79b802e47 100644 --- a/thirdparty/libwebp/src/dsp/yuv_sse41.c +++ b/thirdparty/libwebp/src/dsp/yuv_sse41.c @@ -15,10 +15,12 @@ #if defined(WEBP_USE_SSE41) -#include "src/dsp/common_sse41.h" #include <stdlib.h> #include <smmintrin.h> +#include "src/dsp/common_sse41.h" +#include "src/utils/utils.h" + //----------------------------------------------------------------------------- // Convert spans of 32 pixels to various RGB formats for the fancy upsampler. @@ -74,7 +76,7 @@ static WEBP_INLINE __m128i Load_HI_16_SSE41(const uint8_t* src) { // Load and replicate the U/V samples static WEBP_INLINE __m128i Load_UV_HI_8_SSE41(const uint8_t* src) { const __m128i zero = _mm_setzero_si128(); - const __m128i tmp0 = _mm_cvtsi32_si128(*(const uint32_t*)src); + const __m128i tmp0 = _mm_cvtsi32_si128(WebPMemToInt32(src)); const __m128i tmp1 = _mm_unpacklo_epi8(zero, tmp0); return _mm_unpacklo_epi16(tmp1, tmp1); // replicate samples } diff --git a/thirdparty/libwebp/src/enc/analysis_enc.c b/thirdparty/libwebp/src/enc/analysis_enc.c index ebb784261c..a0001ac034 100644 --- a/thirdparty/libwebp/src/enc/analysis_enc.c +++ b/thirdparty/libwebp/src/enc/analysis_enc.c @@ -391,12 +391,14 @@ static int DoSegmentsJob(void* arg1, void* arg2) { return ok; } +#ifdef WEBP_USE_THREAD static void MergeJobs(const SegmentJob* const src, SegmentJob* const dst) { int i; for (i = 0; i <= MAX_ALPHA; ++i) dst->alphas[i] += src->alphas[i]; dst->alpha += src->alpha; dst->uv_alpha += src->uv_alpha; } +#endif // initialize the job struct with some tasks to perform static void InitSegmentJob(VP8Encoder* const enc, SegmentJob* const job, @@ -425,10 +427,10 @@ int VP8EncAnalyze(VP8Encoder* const enc) { (enc->method_ <= 1); // for method 0 - 1, we need preds_[] to be filled. if (do_segments) { const int last_row = enc->mb_h_; - // We give a little more than a half work to the main thread. - const int split_row = (9 * last_row + 15) >> 4; const int total_mb = last_row * enc->mb_w_; #ifdef WEBP_USE_THREAD + // We give a little more than a half work to the main thread. + const int split_row = (9 * last_row + 15) >> 4; const int kMinSplitRow = 2; // minimal rows needed for mt to be worth it const int do_mt = (enc->thread_level_ > 0) && (split_row >= kMinSplitRow); #else @@ -438,6 +440,7 @@ int VP8EncAnalyze(VP8Encoder* const enc) { WebPGetWorkerInterface(); SegmentJob main_job; if (do_mt) { +#ifdef WEBP_USE_THREAD SegmentJob side_job; // Note the use of '&' instead of '&&' because we must call the functions // no matter what. @@ -455,6 +458,7 @@ int VP8EncAnalyze(VP8Encoder* const enc) { } worker_interface->End(&side_job.worker); if (ok) MergeJobs(&side_job, &main_job); // merge results together +#endif // WEBP_USE_THREAD } else { // Even for single-thread case, we use the generic Worker tools. InitSegmentJob(enc, &main_job, 0, last_row); diff --git a/thirdparty/libwebp/src/enc/picture_csp_enc.c b/thirdparty/libwebp/src/enc/picture_csp_enc.c index fabebcf202..78c8ca479b 100644 --- a/thirdparty/libwebp/src/enc/picture_csp_enc.c +++ b/thirdparty/libwebp/src/enc/picture_csp_enc.c @@ -69,10 +69,12 @@ static int CheckNonOpaque(const uint8_t* alpha, int width, int height, int WebPPictureHasTransparency(const WebPPicture* picture) { if (picture == NULL) return 0; if (picture->use_argb) { - const int alpha_offset = ALPHA_OFFSET; - return CheckNonOpaque((const uint8_t*)picture->argb + alpha_offset, - picture->width, picture->height, - 4, picture->argb_stride * sizeof(*picture->argb)); + if (picture->argb != NULL) { + return CheckNonOpaque((const uint8_t*)picture->argb + ALPHA_OFFSET, + picture->width, picture->height, + 4, picture->argb_stride * sizeof(*picture->argb)); + } + return 0; } return CheckNonOpaque(picture->a, picture->width, picture->height, 1, picture->a_stride); @@ -170,21 +172,6 @@ static const int kMinDimensionIterativeConversion = 4; //------------------------------------------------------------------------------ // Main function -extern void SharpYuvInit(VP8CPUInfo cpu_info_func); - -static void SafeInitSharpYuv(void) { -#if defined(WEBP_USE_THREAD) && !defined(_WIN32) - static pthread_mutex_t initsharpyuv_lock = PTHREAD_MUTEX_INITIALIZER; - if (pthread_mutex_lock(&initsharpyuv_lock)) return; -#endif - - SharpYuvInit(VP8GetCPUInfo); - -#if defined(WEBP_USE_THREAD) && !defined(_WIN32) - (void)pthread_mutex_unlock(&initsharpyuv_lock); -#endif -} - static int PreprocessARGB(const uint8_t* r_ptr, const uint8_t* g_ptr, const uint8_t* b_ptr, @@ -481,6 +468,8 @@ static WEBP_INLINE void ConvertRowsToUV(const uint16_t* rgb, } } +extern void SharpYuvInit(VP8CPUInfo cpu_info_func); + static int ImportYUVAFromRGBA(const uint8_t* r_ptr, const uint8_t* g_ptr, const uint8_t* b_ptr, @@ -516,7 +505,7 @@ static int ImportYUVAFromRGBA(const uint8_t* r_ptr, } if (use_iterative_conversion) { - SafeInitSharpYuv(); + SharpYuvInit(VP8GetCPUInfo); if (!PreprocessARGB(r_ptr, g_ptr, b_ptr, step, rgb_stride, picture)) { return 0; } diff --git a/thirdparty/libwebp/src/enc/vp8i_enc.h b/thirdparty/libwebp/src/enc/vp8i_enc.h index 71f76702ae..c9927c47d8 100644 --- a/thirdparty/libwebp/src/enc/vp8i_enc.h +++ b/thirdparty/libwebp/src/enc/vp8i_enc.h @@ -31,8 +31,8 @@ extern "C" { // version numbers #define ENC_MAJ_VERSION 1 -#define ENC_MIN_VERSION 2 -#define ENC_REV_VERSION 4 +#define ENC_MIN_VERSION 3 +#define ENC_REV_VERSION 0 enum { MAX_LF_LEVELS = 64, // Maximum loop filter level MAX_VARIABLE_LEVEL = 67, // last (inclusive) level with variable cost diff --git a/thirdparty/libwebp/src/enc/vp8l_enc.c b/thirdparty/libwebp/src/enc/vp8l_enc.c index 2b345df610..0b07e529a9 100644 --- a/thirdparty/libwebp/src/enc/vp8l_enc.c +++ b/thirdparty/libwebp/src/enc/vp8l_enc.c @@ -361,10 +361,11 @@ typedef enum { kHistoTotal // Must be last. } HistoIx; -static void AddSingleSubGreen(int p, uint32_t* const r, uint32_t* const b) { - const int green = p >> 8; // The upper bits are masked away later. - ++r[((p >> 16) - green) & 0xff]; - ++b[((p >> 0) - green) & 0xff]; +static void AddSingleSubGreen(uint32_t p, + uint32_t* const r, uint32_t* const b) { + const int green = (int)p >> 8; // The upper bits are masked away later. + ++r[(((int)p >> 16) - green) & 0xff]; + ++b[(((int)p >> 0) - green) & 0xff]; } static void AddSingle(uint32_t p, @@ -1354,7 +1355,7 @@ static int EncodeImageInternal( static void ApplySubtractGreen(VP8LEncoder* const enc, int width, int height, VP8LBitWriter* const bw) { VP8LPutBits(bw, TRANSFORM_PRESENT, 1); - VP8LPutBits(bw, SUBTRACT_GREEN, 2); + VP8LPutBits(bw, SUBTRACT_GREEN_TRANSFORM, 2); VP8LSubtractGreenFromBlueAndRed(enc->argb_, width * height); } diff --git a/thirdparty/libwebp/src/mux/muxi.h b/thirdparty/libwebp/src/mux/muxi.h index 0f4af1784d..7929138c44 100644 --- a/thirdparty/libwebp/src/mux/muxi.h +++ b/thirdparty/libwebp/src/mux/muxi.h @@ -28,8 +28,8 @@ extern "C" { // Defines and constants. #define MUX_MAJ_VERSION 1 -#define MUX_MIN_VERSION 2 -#define MUX_REV_VERSION 4 +#define MUX_MIN_VERSION 3 +#define MUX_REV_VERSION 0 // Chunk object. typedef struct WebPChunk WebPChunk; diff --git a/thirdparty/libwebp/src/utils/bit_reader_inl_utils.h b/thirdparty/libwebp/src/utils/bit_reader_inl_utils.h index 404b9a6d8c..24f3af7b54 100644 --- a/thirdparty/libwebp/src/utils/bit_reader_inl_utils.h +++ b/thirdparty/libwebp/src/utils/bit_reader_inl_utils.h @@ -148,9 +148,9 @@ int VP8GetSigned(VP8BitReader* WEBP_RESTRICT const br, int v, const range_t value = (range_t)(br->value_ >> pos); const int32_t mask = (int32_t)(split - value) >> 31; // -1 or 0 br->bits_ -= 1; - br->range_ += mask; + br->range_ += (range_t)mask; br->range_ |= 1; - br->value_ -= (bit_t)((split + 1) & mask) << pos; + br->value_ -= (bit_t)((split + 1) & (uint32_t)mask) << pos; BT_TRACK(br); return (v ^ mask) - mask; } diff --git a/thirdparty/libwebp/src/utils/huffman_utils.c b/thirdparty/libwebp/src/utils/huffman_utils.c index 0cba0fbb7d..90c2fbf7c1 100644 --- a/thirdparty/libwebp/src/utils/huffman_utils.c +++ b/thirdparty/libwebp/src/utils/huffman_utils.c @@ -142,7 +142,7 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits, { int step; // step size to replicate values in current table - uint32_t low = -1; // low bits for current root entry + uint32_t low = 0xffffffffu; // low bits for current root entry uint32_t mask = total_size - 1; // mask for low bits uint32_t key = 0; // reversed prefix code int num_nodes = 1; // number of Huffman tree nodes diff --git a/thirdparty/libwebp/src/utils/utils.h b/thirdparty/libwebp/src/utils/utils.h index ef04f108fe..c5ee873357 100644 --- a/thirdparty/libwebp/src/utils/utils.h +++ b/thirdparty/libwebp/src/utils/utils.h @@ -64,7 +64,8 @@ WEBP_EXTERN void WebPSafeFree(void* const ptr); // Alignment #define WEBP_ALIGN_CST 31 -#define WEBP_ALIGN(PTR) (((uintptr_t)(PTR) + WEBP_ALIGN_CST) & ~WEBP_ALIGN_CST) +#define WEBP_ALIGN(PTR) (((uintptr_t)(PTR) + WEBP_ALIGN_CST) & \ + ~(uintptr_t)WEBP_ALIGN_CST) #include <string.h> // memcpy() is the safe way of moving potentially unaligned 32b memory. @@ -73,10 +74,19 @@ static WEBP_INLINE uint32_t WebPMemToUint32(const uint8_t* const ptr) { memcpy(&A, ptr, sizeof(A)); return A; } + +static WEBP_INLINE int32_t WebPMemToInt32(const uint8_t* const ptr) { + return (int32_t)WebPMemToUint32(ptr); +} + static WEBP_INLINE void WebPUint32ToMem(uint8_t* const ptr, uint32_t val) { memcpy(ptr, &val, sizeof(val)); } +static WEBP_INLINE void WebPInt32ToMem(uint8_t* const ptr, int val) { + WebPUint32ToMem(ptr, (uint32_t)val); +} + //------------------------------------------------------------------------------ // Reading/writing data. diff --git a/thirdparty/libwebp/src/webp/format_constants.h b/thirdparty/libwebp/src/webp/format_constants.h index eca6981a47..999035c5d2 100644 --- a/thirdparty/libwebp/src/webp/format_constants.h +++ b/thirdparty/libwebp/src/webp/format_constants.h @@ -55,7 +55,7 @@ typedef enum { PREDICTOR_TRANSFORM = 0, CROSS_COLOR_TRANSFORM = 1, - SUBTRACT_GREEN = 2, + SUBTRACT_GREEN_TRANSFORM = 2, COLOR_INDEXING_TRANSFORM = 3 } VP8LImageTransformType; diff --git a/thirdparty/libwebp/src/webp/types.h b/thirdparty/libwebp/src/webp/types.h index 47f7f2b007..f255432e41 100644 --- a/thirdparty/libwebp/src/webp/types.h +++ b/thirdparty/libwebp/src/webp/types.h @@ -42,7 +42,11 @@ typedef long long int int64_t; # if defined(__GNUC__) && __GNUC__ >= 4 # define WEBP_EXTERN extern __attribute__ ((visibility ("default"))) # else -# define WEBP_EXTERN extern +# if defined(_MSC_VER) && defined(WEBP_DLL) +# define WEBP_EXTERN __declspec(dllexport) +# else +# define WEBP_EXTERN extern +# endif # endif /* __GNUC__ >= 4 */ #endif /* WEBP_EXTERN */ diff --git a/thirdparty/linuxbsd_headers/README.md b/thirdparty/linuxbsd_headers/README.md new file mode 100644 index 0000000000..af902aa97a --- /dev/null +++ b/thirdparty/linuxbsd_headers/README.md @@ -0,0 +1,69 @@ +# Linux/BSD headers + +Please keep categories (`##` level) listed alphabetically and matching their +respective folder names. Use two empty lines to separate categories for +readability. + + +## ALSA + +- Upstream: https://www.alsa-project.org/ +- Version: 1.1.3-5 +- License: LPGL-2.1+ + +Patches in the `patches` directory should be re-applied after updates. + +## dbus + +- Upstream: https://www.freedesktop.org/wiki/software/dbus/ +- Version: 1.12.2 +- License: AFL-2.1 + + +## fontconfig + +- Upstream: https://www.freedesktop.org/wiki/software/fontconfig/ +- Version: 2.12.6 +- License: fontconfig + + +## pulse + +- Upstream: http://pulseaudio.org/ +- Version: 1.11.1 +- License: LPGL-2.1+ + + +# speechd + +- Upstream: https://www.freebsoft.org/pub/projects/speechd/ +- Version: 0.8.8 +- License: LPGL-2.1+ + + +# udev + +- Upstream: https://www.freedesktop.org/wiki/software/systemd/ +- Version: 237 +- License: LPGL-2.1+ + + +## X11 + +- Upstream: https://x.org/wiki/ +- Version: + * Xcursor: 1.2.0 + * Xext: 1.3.5 + * Xinerama: 1.1.4 + * Xi: 1.7.10 + * Xlib: 1.6.9 + * Xrandr: 1.5.2 + * Xrender: 0.9.10 +- License: MIT + + +## xkbcommon + +- Upstream: https://xkbcommon.org/ +- Version: 1.4.0 +- License: MIT diff --git a/thirdparty/linuxbsd_headers/X11/X.h b/thirdparty/linuxbsd_headers/X11/X.h new file mode 100644 index 0000000000..4df7d22e95 --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/X.h @@ -0,0 +1,717 @@ +/* Definitions for the X window system likely to be used by applications */ + +#ifndef X_H +#define X_H + +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#define X_PROTOCOL 11 /* current protocol version */ +#define X_PROTOCOL_REVISION 0 /* current minor version */ + +/* Resources */ + +/* + * _XSERVER64 must ONLY be defined when compiling X server sources on + * systems where unsigned long is not 32 bits, must NOT be used in + * client or library code. + */ +#ifndef _XSERVER64 +# ifndef _XTYPEDEF_XID +# define _XTYPEDEF_XID +typedef unsigned long XID; +# endif +# ifndef _XTYPEDEF_MASK +# define _XTYPEDEF_MASK +typedef unsigned long Mask; +# endif +# ifndef _XTYPEDEF_ATOM +# define _XTYPEDEF_ATOM +typedef unsigned long Atom; /* Also in Xdefs.h */ +# endif +typedef unsigned long VisualID; +typedef unsigned long Time; +#else +# include <X11/Xmd.h> +# ifndef _XTYPEDEF_XID +# define _XTYPEDEF_XID +typedef CARD32 XID; +# endif +# ifndef _XTYPEDEF_MASK +# define _XTYPEDEF_MASK +typedef CARD32 Mask; +# endif +# ifndef _XTYPEDEF_ATOM +# define _XTYPEDEF_ATOM +typedef CARD32 Atom; +# endif +typedef CARD32 VisualID; +typedef CARD32 Time; +#endif + +typedef XID Window; +typedef XID Drawable; +#ifndef _XTYPEDEF_FONT +# define _XTYPEDEF_FONT +typedef XID Font; +#endif +typedef XID Pixmap; +typedef XID Cursor; +typedef XID Colormap; +typedef XID GContext; +typedef XID KeySym; + +typedef unsigned char KeyCode; + +/***************************************************************** + * RESERVED RESOURCE AND CONSTANT DEFINITIONS + *****************************************************************/ + +#ifndef None +#define None 0L /* universal null resource or null atom */ +#endif + +#define ParentRelative 1L /* background pixmap in CreateWindow + and ChangeWindowAttributes */ + +#define CopyFromParent 0L /* border pixmap in CreateWindow + and ChangeWindowAttributes + special VisualID and special window + class passed to CreateWindow */ + +#define PointerWindow 0L /* destination window in SendEvent */ +#define InputFocus 1L /* destination window in SendEvent */ + +#define PointerRoot 1L /* focus window in SetInputFocus */ + +#define AnyPropertyType 0L /* special Atom, passed to GetProperty */ + +#define AnyKey 0L /* special Key Code, passed to GrabKey */ + +#define AnyButton 0L /* special Button Code, passed to GrabButton */ + +#define AllTemporary 0L /* special Resource ID passed to KillClient */ + +#define CurrentTime 0L /* special Time */ + +#define NoSymbol 0L /* special KeySym */ + +/***************************************************************** + * EVENT DEFINITIONS + *****************************************************************/ + +/* Input Event Masks. Used as event-mask window attribute and as arguments + to Grab requests. Not to be confused with event names. */ + +#define NoEventMask 0L +#define KeyPressMask (1L<<0) +#define KeyReleaseMask (1L<<1) +#define ButtonPressMask (1L<<2) +#define ButtonReleaseMask (1L<<3) +#define EnterWindowMask (1L<<4) +#define LeaveWindowMask (1L<<5) +#define PointerMotionMask (1L<<6) +#define PointerMotionHintMask (1L<<7) +#define Button1MotionMask (1L<<8) +#define Button2MotionMask (1L<<9) +#define Button3MotionMask (1L<<10) +#define Button4MotionMask (1L<<11) +#define Button5MotionMask (1L<<12) +#define ButtonMotionMask (1L<<13) +#define KeymapStateMask (1L<<14) +#define ExposureMask (1L<<15) +#define VisibilityChangeMask (1L<<16) +#define StructureNotifyMask (1L<<17) +#define ResizeRedirectMask (1L<<18) +#define SubstructureNotifyMask (1L<<19) +#define SubstructureRedirectMask (1L<<20) +#define FocusChangeMask (1L<<21) +#define PropertyChangeMask (1L<<22) +#define ColormapChangeMask (1L<<23) +#define OwnerGrabButtonMask (1L<<24) + +/* Event names. Used in "type" field in XEvent structures. Not to be +confused with event masks above. They start from 2 because 0 and 1 +are reserved in the protocol for errors and replies. */ + +#define KeyPress 2 +#define KeyRelease 3 +#define ButtonPress 4 +#define ButtonRelease 5 +#define MotionNotify 6 +#define EnterNotify 7 +#define LeaveNotify 8 +#define FocusIn 9 +#define FocusOut 10 +#define KeymapNotify 11 +#define Expose 12 +#define GraphicsExpose 13 +#define NoExpose 14 +#define VisibilityNotify 15 +#define CreateNotify 16 +#define DestroyNotify 17 +#define UnmapNotify 18 +#define MapNotify 19 +#define MapRequest 20 +#define ReparentNotify 21 +#define ConfigureNotify 22 +#define ConfigureRequest 23 +#define GravityNotify 24 +#define ResizeRequest 25 +#define CirculateNotify 26 +#define CirculateRequest 27 +#define PropertyNotify 28 +#define SelectionClear 29 +#define SelectionRequest 30 +#define SelectionNotify 31 +#define ColormapNotify 32 +#define ClientMessage 33 +#define MappingNotify 34 +#define GenericEvent 35 +#define LASTEvent 36 /* must be bigger than any event # */ + + +/* Key masks. Used as modifiers to GrabButton and GrabKey, results of QueryPointer, + state in various key-, mouse-, and button-related events. */ + +#define ShiftMask (1<<0) +#define LockMask (1<<1) +#define ControlMask (1<<2) +#define Mod1Mask (1<<3) +#define Mod2Mask (1<<4) +#define Mod3Mask (1<<5) +#define Mod4Mask (1<<6) +#define Mod5Mask (1<<7) + +/* modifier names. Used to build a SetModifierMapping request or + to read a GetModifierMapping request. These correspond to the + masks defined above. */ +#define ShiftMapIndex 0 +#define LockMapIndex 1 +#define ControlMapIndex 2 +#define Mod1MapIndex 3 +#define Mod2MapIndex 4 +#define Mod3MapIndex 5 +#define Mod4MapIndex 6 +#define Mod5MapIndex 7 + + +/* button masks. Used in same manner as Key masks above. Not to be confused + with button names below. */ + +#define Button1Mask (1<<8) +#define Button2Mask (1<<9) +#define Button3Mask (1<<10) +#define Button4Mask (1<<11) +#define Button5Mask (1<<12) + +#define AnyModifier (1<<15) /* used in GrabButton, GrabKey */ + + +/* button names. Used as arguments to GrabButton and as detail in ButtonPress + and ButtonRelease events. Not to be confused with button masks above. + Note that 0 is already defined above as "AnyButton". */ + +#define Button1 1 +#define Button2 2 +#define Button3 3 +#define Button4 4 +#define Button5 5 + +/* Notify modes */ + +#define NotifyNormal 0 +#define NotifyGrab 1 +#define NotifyUngrab 2 +#define NotifyWhileGrabbed 3 + +#define NotifyHint 1 /* for MotionNotify events */ + +/* Notify detail */ + +#define NotifyAncestor 0 +#define NotifyVirtual 1 +#define NotifyInferior 2 +#define NotifyNonlinear 3 +#define NotifyNonlinearVirtual 4 +#define NotifyPointer 5 +#define NotifyPointerRoot 6 +#define NotifyDetailNone 7 + +/* Visibility notify */ + +#define VisibilityUnobscured 0 +#define VisibilityPartiallyObscured 1 +#define VisibilityFullyObscured 2 + +/* Circulation request */ + +#define PlaceOnTop 0 +#define PlaceOnBottom 1 + +/* protocol families */ + +#define FamilyInternet 0 /* IPv4 */ +#define FamilyDECnet 1 +#define FamilyChaos 2 +#define FamilyInternet6 6 /* IPv6 */ + +/* authentication families not tied to a specific protocol */ +#define FamilyServerInterpreted 5 + +/* Property notification */ + +#define PropertyNewValue 0 +#define PropertyDelete 1 + +/* Color Map notification */ + +#define ColormapUninstalled 0 +#define ColormapInstalled 1 + +/* GrabPointer, GrabButton, GrabKeyboard, GrabKey Modes */ + +#define GrabModeSync 0 +#define GrabModeAsync 1 + +/* GrabPointer, GrabKeyboard reply status */ + +#define GrabSuccess 0 +#define AlreadyGrabbed 1 +#define GrabInvalidTime 2 +#define GrabNotViewable 3 +#define GrabFrozen 4 + +/* AllowEvents modes */ + +#define AsyncPointer 0 +#define SyncPointer 1 +#define ReplayPointer 2 +#define AsyncKeyboard 3 +#define SyncKeyboard 4 +#define ReplayKeyboard 5 +#define AsyncBoth 6 +#define SyncBoth 7 + +/* Used in SetInputFocus, GetInputFocus */ + +#define RevertToNone (int)None +#define RevertToPointerRoot (int)PointerRoot +#define RevertToParent 2 + +/***************************************************************** + * ERROR CODES + *****************************************************************/ + +#define Success 0 /* everything's okay */ +#define BadRequest 1 /* bad request code */ +#define BadValue 2 /* int parameter out of range */ +#define BadWindow 3 /* parameter not a Window */ +#define BadPixmap 4 /* parameter not a Pixmap */ +#define BadAtom 5 /* parameter not an Atom */ +#define BadCursor 6 /* parameter not a Cursor */ +#define BadFont 7 /* parameter not a Font */ +#define BadMatch 8 /* parameter mismatch */ +#define BadDrawable 9 /* parameter not a Pixmap or Window */ +#define BadAccess 10 /* depending on context: + - key/button already grabbed + - attempt to free an illegal + cmap entry + - attempt to store into a read-only + color map entry. + - attempt to modify the access control + list from other than the local host. + */ +#define BadAlloc 11 /* insufficient resources */ +#define BadColor 12 /* no such colormap */ +#define BadGC 13 /* parameter not a GC */ +#define BadIDChoice 14 /* choice not in range or already used */ +#define BadName 15 /* font or color name doesn't exist */ +#define BadLength 16 /* Request length incorrect */ +#define BadImplementation 17 /* server is defective */ + +#define FirstExtensionError 128 +#define LastExtensionError 255 + +/***************************************************************** + * WINDOW DEFINITIONS + *****************************************************************/ + +/* Window classes used by CreateWindow */ +/* Note that CopyFromParent is already defined as 0 above */ + +#define InputOutput 1 +#define InputOnly 2 + +/* Window attributes for CreateWindow and ChangeWindowAttributes */ + +#define CWBackPixmap (1L<<0) +#define CWBackPixel (1L<<1) +#define CWBorderPixmap (1L<<2) +#define CWBorderPixel (1L<<3) +#define CWBitGravity (1L<<4) +#define CWWinGravity (1L<<5) +#define CWBackingStore (1L<<6) +#define CWBackingPlanes (1L<<7) +#define CWBackingPixel (1L<<8) +#define CWOverrideRedirect (1L<<9) +#define CWSaveUnder (1L<<10) +#define CWEventMask (1L<<11) +#define CWDontPropagate (1L<<12) +#define CWColormap (1L<<13) +#define CWCursor (1L<<14) + +/* ConfigureWindow structure */ + +#define CWX (1<<0) +#define CWY (1<<1) +#define CWWidth (1<<2) +#define CWHeight (1<<3) +#define CWBorderWidth (1<<4) +#define CWSibling (1<<5) +#define CWStackMode (1<<6) + + +/* Bit Gravity */ + +#define ForgetGravity 0 +#define NorthWestGravity 1 +#define NorthGravity 2 +#define NorthEastGravity 3 +#define WestGravity 4 +#define CenterGravity 5 +#define EastGravity 6 +#define SouthWestGravity 7 +#define SouthGravity 8 +#define SouthEastGravity 9 +#define StaticGravity 10 + +/* Window gravity + bit gravity above */ + +#define UnmapGravity 0 + +/* Used in CreateWindow for backing-store hint */ + +#define NotUseful 0 +#define WhenMapped 1 +#define Always 2 + +/* Used in GetWindowAttributes reply */ + +#define IsUnmapped 0 +#define IsUnviewable 1 +#define IsViewable 2 + +/* Used in ChangeSaveSet */ + +#define SetModeInsert 0 +#define SetModeDelete 1 + +/* Used in ChangeCloseDownMode */ + +#define DestroyAll 0 +#define RetainPermanent 1 +#define RetainTemporary 2 + +/* Window stacking method (in configureWindow) */ + +#define Above 0 +#define Below 1 +#define TopIf 2 +#define BottomIf 3 +#define Opposite 4 + +/* Circulation direction */ + +#define RaiseLowest 0 +#define LowerHighest 1 + +/* Property modes */ + +#define PropModeReplace 0 +#define PropModePrepend 1 +#define PropModeAppend 2 + +/***************************************************************** + * GRAPHICS DEFINITIONS + *****************************************************************/ + +/* graphics functions, as in GC.alu */ + +#define GXclear 0x0 /* 0 */ +#define GXand 0x1 /* src AND dst */ +#define GXandReverse 0x2 /* src AND NOT dst */ +#define GXcopy 0x3 /* src */ +#define GXandInverted 0x4 /* NOT src AND dst */ +#define GXnoop 0x5 /* dst */ +#define GXxor 0x6 /* src XOR dst */ +#define GXor 0x7 /* src OR dst */ +#define GXnor 0x8 /* NOT src AND NOT dst */ +#define GXequiv 0x9 /* NOT src XOR dst */ +#define GXinvert 0xa /* NOT dst */ +#define GXorReverse 0xb /* src OR NOT dst */ +#define GXcopyInverted 0xc /* NOT src */ +#define GXorInverted 0xd /* NOT src OR dst */ +#define GXnand 0xe /* NOT src OR NOT dst */ +#define GXset 0xf /* 1 */ + +/* LineStyle */ + +#define LineSolid 0 +#define LineOnOffDash 1 +#define LineDoubleDash 2 + +/* capStyle */ + +#define CapNotLast 0 +#define CapButt 1 +#define CapRound 2 +#define CapProjecting 3 + +/* joinStyle */ + +#define JoinMiter 0 +#define JoinRound 1 +#define JoinBevel 2 + +/* fillStyle */ + +#define FillSolid 0 +#define FillTiled 1 +#define FillStippled 2 +#define FillOpaqueStippled 3 + +/* fillRule */ + +#define EvenOddRule 0 +#define WindingRule 1 + +/* subwindow mode */ + +#define ClipByChildren 0 +#define IncludeInferiors 1 + +/* SetClipRectangles ordering */ + +#define Unsorted 0 +#define YSorted 1 +#define YXSorted 2 +#define YXBanded 3 + +/* CoordinateMode for drawing routines */ + +#define CoordModeOrigin 0 /* relative to the origin */ +#define CoordModePrevious 1 /* relative to previous point */ + +/* Polygon shapes */ + +#define Complex 0 /* paths may intersect */ +#define Nonconvex 1 /* no paths intersect, but not convex */ +#define Convex 2 /* wholly convex */ + +/* Arc modes for PolyFillArc */ + +#define ArcChord 0 /* join endpoints of arc */ +#define ArcPieSlice 1 /* join endpoints to center of arc */ + +/* GC components: masks used in CreateGC, CopyGC, ChangeGC, OR'ed into + GC.stateChanges */ + +#define GCFunction (1L<<0) +#define GCPlaneMask (1L<<1) +#define GCForeground (1L<<2) +#define GCBackground (1L<<3) +#define GCLineWidth (1L<<4) +#define GCLineStyle (1L<<5) +#define GCCapStyle (1L<<6) +#define GCJoinStyle (1L<<7) +#define GCFillStyle (1L<<8) +#define GCFillRule (1L<<9) +#define GCTile (1L<<10) +#define GCStipple (1L<<11) +#define GCTileStipXOrigin (1L<<12) +#define GCTileStipYOrigin (1L<<13) +#define GCFont (1L<<14) +#define GCSubwindowMode (1L<<15) +#define GCGraphicsExposures (1L<<16) +#define GCClipXOrigin (1L<<17) +#define GCClipYOrigin (1L<<18) +#define GCClipMask (1L<<19) +#define GCDashOffset (1L<<20) +#define GCDashList (1L<<21) +#define GCArcMode (1L<<22) + +#define GCLastBit 22 +/***************************************************************** + * FONTS + *****************************************************************/ + +/* used in QueryFont -- draw direction */ + +#define FontLeftToRight 0 +#define FontRightToLeft 1 + +#define FontChange 255 + +/***************************************************************** + * IMAGING + *****************************************************************/ + +/* ImageFormat -- PutImage, GetImage */ + +#define XYBitmap 0 /* depth 1, XYFormat */ +#define XYPixmap 1 /* depth == drawable depth */ +#define ZPixmap 2 /* depth == drawable depth */ + +/***************************************************************** + * COLOR MAP STUFF + *****************************************************************/ + +/* For CreateColormap */ + +#define AllocNone 0 /* create map with no entries */ +#define AllocAll 1 /* allocate entire map writeable */ + + +/* Flags used in StoreNamedColor, StoreColors */ + +#define DoRed (1<<0) +#define DoGreen (1<<1) +#define DoBlue (1<<2) + +/***************************************************************** + * CURSOR STUFF + *****************************************************************/ + +/* QueryBestSize Class */ + +#define CursorShape 0 /* largest size that can be displayed */ +#define TileShape 1 /* size tiled fastest */ +#define StippleShape 2 /* size stippled fastest */ + +/***************************************************************** + * KEYBOARD/POINTER STUFF + *****************************************************************/ + +#define AutoRepeatModeOff 0 +#define AutoRepeatModeOn 1 +#define AutoRepeatModeDefault 2 + +#define LedModeOff 0 +#define LedModeOn 1 + +/* masks for ChangeKeyboardControl */ + +#define KBKeyClickPercent (1L<<0) +#define KBBellPercent (1L<<1) +#define KBBellPitch (1L<<2) +#define KBBellDuration (1L<<3) +#define KBLed (1L<<4) +#define KBLedMode (1L<<5) +#define KBKey (1L<<6) +#define KBAutoRepeatMode (1L<<7) + +#define MappingSuccess 0 +#define MappingBusy 1 +#define MappingFailed 2 + +#define MappingModifier 0 +#define MappingKeyboard 1 +#define MappingPointer 2 + +/***************************************************************** + * SCREEN SAVER STUFF + *****************************************************************/ + +#define DontPreferBlanking 0 +#define PreferBlanking 1 +#define DefaultBlanking 2 + +#define DisableScreenSaver 0 +#define DisableScreenInterval 0 + +#define DontAllowExposures 0 +#define AllowExposures 1 +#define DefaultExposures 2 + +/* for ForceScreenSaver */ + +#define ScreenSaverReset 0 +#define ScreenSaverActive 1 + +/***************************************************************** + * HOSTS AND CONNECTIONS + *****************************************************************/ + +/* for ChangeHosts */ + +#define HostInsert 0 +#define HostDelete 1 + +/* for ChangeAccessControl */ + +#define EnableAccess 1 +#define DisableAccess 0 + +/* Display classes used in opening the connection + * Note that the statically allocated ones are even numbered and the + * dynamically changeable ones are odd numbered */ + +#define StaticGray 0 +#define GrayScale 1 +#define StaticColor 2 +#define PseudoColor 3 +#define TrueColor 4 +#define DirectColor 5 + + +/* Byte order used in imageByteOrder and bitmapBitOrder */ + +#define LSBFirst 0 +#define MSBFirst 1 + +#endif /* X_H */ diff --git a/thirdparty/linuxbsd_headers/X11/XF86keysym.h b/thirdparty/linuxbsd_headers/X11/XF86keysym.h new file mode 100644 index 0000000000..c242e42f5f --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/XF86keysym.h @@ -0,0 +1,467 @@ +/* + * XFree86 vendor specific keysyms. + * + * The XFree86 keysym range is 0x10080001 - 0x1008FFFF. + * + * The XF86 set of keysyms is a catch-all set of defines for keysyms found + * on various multimedia keyboards. Originally specific to XFree86 they have + * been been adopted over time and are considered a "standard" part of X + * keysym definitions. + * XFree86 never properly commented these keysyms, so we have done our + * best to explain the semantic meaning of these keys. + * + * XFree86 has removed their mail archives of the period, that might have + * shed more light on some of these definitions. Until/unless we resurrect + * these archives, these are from memory and usage. + */ + +/* + * ModeLock + * + * This one is old, and not really used any more since XKB offers this + * functionality. + */ + +#define XF86XK_ModeLock 0x1008FF01 /* Mode Switch Lock */ + +/* Backlight controls. */ +#define XF86XK_MonBrightnessUp 0x1008FF02 /* Monitor/panel brightness */ +#define XF86XK_MonBrightnessDown 0x1008FF03 /* Monitor/panel brightness */ +#define XF86XK_KbdLightOnOff 0x1008FF04 /* Keyboards may be lit */ +#define XF86XK_KbdBrightnessUp 0x1008FF05 /* Keyboards may be lit */ +#define XF86XK_KbdBrightnessDown 0x1008FF06 /* Keyboards may be lit */ +#define XF86XK_MonBrightnessCycle 0x1008FF07 /* Monitor/panel brightness */ + +/* + * Keys found on some "Internet" keyboards. + */ +#define XF86XK_Standby 0x1008FF10 /* System into standby mode */ +#define XF86XK_AudioLowerVolume 0x1008FF11 /* Volume control down */ +#define XF86XK_AudioMute 0x1008FF12 /* Mute sound from the system */ +#define XF86XK_AudioRaiseVolume 0x1008FF13 /* Volume control up */ +#define XF86XK_AudioPlay 0x1008FF14 /* Start playing of audio > */ +#define XF86XK_AudioStop 0x1008FF15 /* Stop playing audio */ +#define XF86XK_AudioPrev 0x1008FF16 /* Previous track */ +#define XF86XK_AudioNext 0x1008FF17 /* Next track */ +#define XF86XK_HomePage 0x1008FF18 /* Display user's home page */ +#define XF86XK_Mail 0x1008FF19 /* Invoke user's mail program */ +#define XF86XK_Start 0x1008FF1A /* Start application */ +#define XF86XK_Search 0x1008FF1B /* Search */ +#define XF86XK_AudioRecord 0x1008FF1C /* Record audio application */ + +/* These are sometimes found on PDA's (e.g. Palm, PocketPC or elsewhere) */ +#define XF86XK_Calculator 0x1008FF1D /* Invoke calculator program */ +#define XF86XK_Memo 0x1008FF1E /* Invoke Memo taking program */ +#define XF86XK_ToDoList 0x1008FF1F /* Invoke To Do List program */ +#define XF86XK_Calendar 0x1008FF20 /* Invoke Calendar program */ +#define XF86XK_PowerDown 0x1008FF21 /* Deep sleep the system */ +#define XF86XK_ContrastAdjust 0x1008FF22 /* Adjust screen contrast */ +#define XF86XK_RockerUp 0x1008FF23 /* Rocker switches exist up */ +#define XF86XK_RockerDown 0x1008FF24 /* and down */ +#define XF86XK_RockerEnter 0x1008FF25 /* and let you press them */ + +/* Some more "Internet" keyboard symbols */ +#define XF86XK_Back 0x1008FF26 /* Like back on a browser */ +#define XF86XK_Forward 0x1008FF27 /* Like forward on a browser */ +#define XF86XK_Stop 0x1008FF28 /* Stop current operation */ +#define XF86XK_Refresh 0x1008FF29 /* Refresh the page */ +#define XF86XK_PowerOff 0x1008FF2A /* Power off system entirely */ +#define XF86XK_WakeUp 0x1008FF2B /* Wake up system from sleep */ +#define XF86XK_Eject 0x1008FF2C /* Eject device (e.g. DVD) */ +#define XF86XK_ScreenSaver 0x1008FF2D /* Invoke screensaver */ +#define XF86XK_WWW 0x1008FF2E /* Invoke web browser */ +#define XF86XK_Sleep 0x1008FF2F /* Put system to sleep */ +#define XF86XK_Favorites 0x1008FF30 /* Show favorite locations */ +#define XF86XK_AudioPause 0x1008FF31 /* Pause audio playing */ +#define XF86XK_AudioMedia 0x1008FF32 /* Launch media collection app */ +#define XF86XK_MyComputer 0x1008FF33 /* Display "My Computer" window */ +#define XF86XK_VendorHome 0x1008FF34 /* Display vendor home web site */ +#define XF86XK_LightBulb 0x1008FF35 /* Light bulb keys exist */ +#define XF86XK_Shop 0x1008FF36 /* Display shopping web site */ +#define XF86XK_History 0x1008FF37 /* Show history of web surfing */ +#define XF86XK_OpenURL 0x1008FF38 /* Open selected URL */ +#define XF86XK_AddFavorite 0x1008FF39 /* Add URL to favorites list */ +#define XF86XK_HotLinks 0x1008FF3A /* Show "hot" links */ +#define XF86XK_BrightnessAdjust 0x1008FF3B /* Invoke brightness adj. UI */ +#define XF86XK_Finance 0x1008FF3C /* Display financial site */ +#define XF86XK_Community 0x1008FF3D /* Display user's community */ +#define XF86XK_AudioRewind 0x1008FF3E /* "rewind" audio track */ +#define XF86XK_BackForward 0x1008FF3F /* ??? */ +#define XF86XK_Launch0 0x1008FF40 /* Launch Application */ +#define XF86XK_Launch1 0x1008FF41 /* Launch Application */ +#define XF86XK_Launch2 0x1008FF42 /* Launch Application */ +#define XF86XK_Launch3 0x1008FF43 /* Launch Application */ +#define XF86XK_Launch4 0x1008FF44 /* Launch Application */ +#define XF86XK_Launch5 0x1008FF45 /* Launch Application */ +#define XF86XK_Launch6 0x1008FF46 /* Launch Application */ +#define XF86XK_Launch7 0x1008FF47 /* Launch Application */ +#define XF86XK_Launch8 0x1008FF48 /* Launch Application */ +#define XF86XK_Launch9 0x1008FF49 /* Launch Application */ +#define XF86XK_LaunchA 0x1008FF4A /* Launch Application */ +#define XF86XK_LaunchB 0x1008FF4B /* Launch Application */ +#define XF86XK_LaunchC 0x1008FF4C /* Launch Application */ +#define XF86XK_LaunchD 0x1008FF4D /* Launch Application */ +#define XF86XK_LaunchE 0x1008FF4E /* Launch Application */ +#define XF86XK_LaunchF 0x1008FF4F /* Launch Application */ + +#define XF86XK_ApplicationLeft 0x1008FF50 /* switch to application, left */ +#define XF86XK_ApplicationRight 0x1008FF51 /* switch to application, right*/ +#define XF86XK_Book 0x1008FF52 /* Launch bookreader */ +#define XF86XK_CD 0x1008FF53 /* Launch CD/DVD player */ +#define XF86XK_Calculater 0x1008FF54 /* Launch Calculater */ +#define XF86XK_Clear 0x1008FF55 /* Clear window, screen */ +#define XF86XK_Close 0x1008FF56 /* Close window */ +#define XF86XK_Copy 0x1008FF57 /* Copy selection */ +#define XF86XK_Cut 0x1008FF58 /* Cut selection */ +#define XF86XK_Display 0x1008FF59 /* Output switch key */ +#define XF86XK_DOS 0x1008FF5A /* Launch DOS (emulation) */ +#define XF86XK_Documents 0x1008FF5B /* Open documents window */ +#define XF86XK_Excel 0x1008FF5C /* Launch spread sheet */ +#define XF86XK_Explorer 0x1008FF5D /* Launch file explorer */ +#define XF86XK_Game 0x1008FF5E /* Launch game */ +#define XF86XK_Go 0x1008FF5F /* Go to URL */ +#define XF86XK_iTouch 0x1008FF60 /* Logitech iTouch- don't use */ +#define XF86XK_LogOff 0x1008FF61 /* Log off system */ +#define XF86XK_Market 0x1008FF62 /* ?? */ +#define XF86XK_Meeting 0x1008FF63 /* enter meeting in calendar */ +#define XF86XK_MenuKB 0x1008FF65 /* distinguish keyboard from PB */ +#define XF86XK_MenuPB 0x1008FF66 /* distinguish PB from keyboard */ +#define XF86XK_MySites 0x1008FF67 /* Favourites */ +#define XF86XK_New 0x1008FF68 /* New (folder, document... */ +#define XF86XK_News 0x1008FF69 /* News */ +#define XF86XK_OfficeHome 0x1008FF6A /* Office home (old Staroffice)*/ +#define XF86XK_Open 0x1008FF6B /* Open */ +#define XF86XK_Option 0x1008FF6C /* ?? */ +#define XF86XK_Paste 0x1008FF6D /* Paste */ +#define XF86XK_Phone 0x1008FF6E /* Launch phone; dial number */ +#define XF86XK_Q 0x1008FF70 /* Compaq's Q - don't use */ +#define XF86XK_Reply 0x1008FF72 /* Reply e.g., mail */ +#define XF86XK_Reload 0x1008FF73 /* Reload web page, file, etc. */ +#define XF86XK_RotateWindows 0x1008FF74 /* Rotate windows e.g. xrandr */ +#define XF86XK_RotationPB 0x1008FF75 /* don't use */ +#define XF86XK_RotationKB 0x1008FF76 /* don't use */ +#define XF86XK_Save 0x1008FF77 /* Save (file, document, state */ +#define XF86XK_ScrollUp 0x1008FF78 /* Scroll window/contents up */ +#define XF86XK_ScrollDown 0x1008FF79 /* Scrool window/contentd down */ +#define XF86XK_ScrollClick 0x1008FF7A /* Use XKB mousekeys instead */ +#define XF86XK_Send 0x1008FF7B /* Send mail, file, object */ +#define XF86XK_Spell 0x1008FF7C /* Spell checker */ +#define XF86XK_SplitScreen 0x1008FF7D /* Split window or screen */ +#define XF86XK_Support 0x1008FF7E /* Get support (??) */ +#define XF86XK_TaskPane 0x1008FF7F /* Show tasks */ +#define XF86XK_Terminal 0x1008FF80 /* Launch terminal emulator */ +#define XF86XK_Tools 0x1008FF81 /* toolbox of desktop/app. */ +#define XF86XK_Travel 0x1008FF82 /* ?? */ +#define XF86XK_UserPB 0x1008FF84 /* ?? */ +#define XF86XK_User1KB 0x1008FF85 /* ?? */ +#define XF86XK_User2KB 0x1008FF86 /* ?? */ +#define XF86XK_Video 0x1008FF87 /* Launch video player */ +#define XF86XK_WheelButton 0x1008FF88 /* button from a mouse wheel */ +#define XF86XK_Word 0x1008FF89 /* Launch word processor */ +#define XF86XK_Xfer 0x1008FF8A +#define XF86XK_ZoomIn 0x1008FF8B /* zoom in view, map, etc. */ +#define XF86XK_ZoomOut 0x1008FF8C /* zoom out view, map, etc. */ + +#define XF86XK_Away 0x1008FF8D /* mark yourself as away */ +#define XF86XK_Messenger 0x1008FF8E /* as in instant messaging */ +#define XF86XK_WebCam 0x1008FF8F /* Launch web camera app. */ +#define XF86XK_MailForward 0x1008FF90 /* Forward in mail */ +#define XF86XK_Pictures 0x1008FF91 /* Show pictures */ +#define XF86XK_Music 0x1008FF92 /* Launch music application */ + +#define XF86XK_Battery 0x1008FF93 /* Display battery information */ +#define XF86XK_Bluetooth 0x1008FF94 /* Enable/disable Bluetooth */ +#define XF86XK_WLAN 0x1008FF95 /* Enable/disable WLAN */ +#define XF86XK_UWB 0x1008FF96 /* Enable/disable UWB */ + +#define XF86XK_AudioForward 0x1008FF97 /* fast-forward audio track */ +#define XF86XK_AudioRepeat 0x1008FF98 /* toggle repeat mode */ +#define XF86XK_AudioRandomPlay 0x1008FF99 /* toggle shuffle mode */ +#define XF86XK_Subtitle 0x1008FF9A /* cycle through subtitle */ +#define XF86XK_AudioCycleTrack 0x1008FF9B /* cycle through audio tracks */ +#define XF86XK_CycleAngle 0x1008FF9C /* cycle through angles */ +#define XF86XK_FrameBack 0x1008FF9D /* video: go one frame back */ +#define XF86XK_FrameForward 0x1008FF9E /* video: go one frame forward */ +#define XF86XK_Time 0x1008FF9F /* display, or shows an entry for time seeking */ +#define XF86XK_Select 0x1008FFA0 /* Select button on joypads and remotes */ +#define XF86XK_View 0x1008FFA1 /* Show a view options/properties */ +#define XF86XK_TopMenu 0x1008FFA2 /* Go to a top-level menu in a video */ + +#define XF86XK_Red 0x1008FFA3 /* Red button */ +#define XF86XK_Green 0x1008FFA4 /* Green button */ +#define XF86XK_Yellow 0x1008FFA5 /* Yellow button */ +#define XF86XK_Blue 0x1008FFA6 /* Blue button */ + +#define XF86XK_Suspend 0x1008FFA7 /* Sleep to RAM */ +#define XF86XK_Hibernate 0x1008FFA8 /* Sleep to disk */ +#define XF86XK_TouchpadToggle 0x1008FFA9 /* Toggle between touchpad/trackstick */ +#define XF86XK_TouchpadOn 0x1008FFB0 /* The touchpad got switched on */ +#define XF86XK_TouchpadOff 0x1008FFB1 /* The touchpad got switched off */ + +#define XF86XK_AudioMicMute 0x1008FFB2 /* Mute the Mic from the system */ + +#define XF86XK_Keyboard 0x1008FFB3 /* User defined keyboard related action */ + +#define XF86XK_WWAN 0x1008FFB4 /* Toggle WWAN (LTE, UMTS, etc.) radio */ +#define XF86XK_RFKill 0x1008FFB5 /* Toggle radios on/off */ + +#define XF86XK_AudioPreset 0x1008FFB6 /* Select equalizer preset, e.g. theatre-mode */ + +#define XF86XK_RotationLockToggle 0x1008FFB7 /* Toggle screen rotation lock on/off */ + +#define XF86XK_FullScreen 0x1008FFB8 /* Toggle fullscreen */ + +/* Keys for special action keys (hot keys) */ +/* Virtual terminals on some operating systems */ +#define XF86XK_Switch_VT_1 0x1008FE01 +#define XF86XK_Switch_VT_2 0x1008FE02 +#define XF86XK_Switch_VT_3 0x1008FE03 +#define XF86XK_Switch_VT_4 0x1008FE04 +#define XF86XK_Switch_VT_5 0x1008FE05 +#define XF86XK_Switch_VT_6 0x1008FE06 +#define XF86XK_Switch_VT_7 0x1008FE07 +#define XF86XK_Switch_VT_8 0x1008FE08 +#define XF86XK_Switch_VT_9 0x1008FE09 +#define XF86XK_Switch_VT_10 0x1008FE0A +#define XF86XK_Switch_VT_11 0x1008FE0B +#define XF86XK_Switch_VT_12 0x1008FE0C + +#define XF86XK_Ungrab 0x1008FE20 /* force ungrab */ +#define XF86XK_ClearGrab 0x1008FE21 /* kill application with grab */ +#define XF86XK_Next_VMode 0x1008FE22 /* next video mode available */ +#define XF86XK_Prev_VMode 0x1008FE23 /* prev. video mode available */ +#define XF86XK_LogWindowTree 0x1008FE24 /* print window tree to log */ +#define XF86XK_LogGrabInfo 0x1008FE25 /* print all active grabs to log */ + + +/* + * Reserved range for evdev symbols: 0x10081000-0x10081FFF + * + * Key syms within this range must match the Linux kernel + * input-event-codes.h file in the format: + * XF86XK_CamelCaseKernelName _EVDEVK(kernel value) + * For example, the kernel + * #define KEY_MACRO_RECORD_START 0x2b0 + * effectively ends up as: + * #define XF86XK_MacroRecordStart 0x100812b0 + * + * For historical reasons, some keysyms within the reserved range will be + * missing, most notably all "normal" keys that are mapped through default + * XKB layouts (e.g. KEY_Q). + * + * CamelCasing is done with a human control as last authority, e.g. see VOD + * instead of Vod for the Video on Demand key. + * + * The format for #defines is strict: + * + * #define XF86XK_FOO<tab...>_EVDEVK(0xABC)<tab><tab> |* kver KEY_FOO *| + * + * Where + * - alignment by tabs + * - the _EVDEVK macro must be used + * - the hex code must be in uppercase hex + * - the kernel version (kver) is in the form v5.10 + * - kver and key name are within a slash-star comment (a pipe is used in + * this example for technical reasons) + * These #defines are parsed by scripts. Do not stray from the given format. + * + * Where the evdev keycode is mapped to a different symbol, please add a + * comment line starting with Use: but otherwise the same format, e.g. + * Use: XF86XK_RotationLockToggle _EVDEVK(0x231) v4.16 KEY_ROTATE_LOCK_TOGGLE + * + */ +#define _EVDEVK(_v) (0x10081000 + _v) +/* Use: XF86XK_Eject _EVDEVK(0x0A2) KEY_EJECTCLOSECD */ +/* Use: XF86XK_New _EVDEVK(0x0B5) v2.6.14 KEY_NEW */ +/* Use: XK_Redo _EVDEVK(0x0B6) v2.6.14 KEY_REDO */ +/* KEY_DASHBOARD has been mapped to LaunchB in xkeyboard-config since 2011 */ +/* Use: XF86XK_LaunchB _EVDEVK(0x0CC) v2.6.28 KEY_DASHBOARD */ +/* Use: XF86XK_Display _EVDEVK(0x0E3) v2.6.12 KEY_SWITCHVIDEOMODE */ +/* Use: XF86XK_KbdLightOnOff _EVDEVK(0x0E4) v2.6.12 KEY_KBDILLUMTOGGLE */ +/* Use: XF86XK_KbdBrightnessDown _EVDEVK(0x0E5) v2.6.12 KEY_KBDILLUMDOWN */ +/* Use: XF86XK_KbdBrightnessUp _EVDEVK(0x0E6) v2.6.12 KEY_KBDILLUMUP */ +/* Use: XF86XK_Send _EVDEVK(0x0E7) v2.6.14 KEY_SEND */ +/* Use: XF86XK_Reply _EVDEVK(0x0E8) v2.6.14 KEY_REPLY */ +/* Use: XF86XK_MailForward _EVDEVK(0x0E9) v2.6.14 KEY_FORWARDMAIL */ +/* Use: XF86XK_Save _EVDEVK(0x0EA) v2.6.14 KEY_SAVE */ +/* Use: XF86XK_Documents _EVDEVK(0x0EB) v2.6.14 KEY_DOCUMENTS */ +/* Use: XF86XK_Battery _EVDEVK(0x0EC) v2.6.17 KEY_BATTERY */ +/* Use: XF86XK_Bluetooth _EVDEVK(0x0ED) v2.6.19 KEY_BLUETOOTH */ +/* Use: XF86XK_WLAN _EVDEVK(0x0EE) v2.6.19 KEY_WLAN */ +/* Use: XF86XK_UWB _EVDEVK(0x0EF) v2.6.24 KEY_UWB */ +/* Use: XF86XK_Next_VMode _EVDEVK(0x0F1) v2.6.23 KEY_VIDEO_NEXT */ +/* Use: XF86XK_Prev_VMode _EVDEVK(0x0F2) v2.6.23 KEY_VIDEO_PREV */ +/* Use: XF86XK_MonBrightnessCycle _EVDEVK(0x0F3) v2.6.23 KEY_BRIGHTNESS_CYCLE */ +#define XF86XK_BrightnessAuto _EVDEVK(0x0F4) /* v3.16 KEY_BRIGHTNESS_AUTO */ +#define XF86XK_DisplayOff _EVDEVK(0x0F5) /* v2.6.23 KEY_DISPLAY_OFF */ +/* Use: XF86XK_WWAN _EVDEVK(0x0F6) v3.13 KEY_WWAN */ +/* Use: XF86XK_RFKill _EVDEVK(0x0F7) v2.6.33 KEY_RFKILL */ +/* Use: XF86XK_AudioMicMute _EVDEVK(0x0F8) v3.1 KEY_MICMUTE */ +#define XF86XK_Info _EVDEVK(0x166) /* KEY_INFO */ +/* Use: XF86XK_CycleAngle _EVDEVK(0x173) KEY_ANGLE */ +/* Use: XF86XK_FullScreen _EVDEVK(0x174) v5.1 KEY_FULL_SCREEN */ +#define XF86XK_AspectRatio _EVDEVK(0x177) /* v5.1 KEY_ASPECT_RATIO */ +#define XF86XK_DVD _EVDEVK(0x185) /* KEY_DVD */ +#define XF86XK_Audio _EVDEVK(0x188) /* KEY_AUDIO */ +/* Use: XF86XK_Video _EVDEVK(0x189) KEY_VIDEO */ +/* Use: XF86XK_Calendar _EVDEVK(0x18D) KEY_CALENDAR */ +#define XF86XK_ChannelUp _EVDEVK(0x192) /* KEY_CHANNELUP */ +#define XF86XK_ChannelDown _EVDEVK(0x193) /* KEY_CHANNELDOWN */ +/* Use: XF86XK_AudioRandomPlay _EVDEVK(0x19A) KEY_SHUFFLE */ +#define XF86XK_Break _EVDEVK(0x19B) /* KEY_BREAK */ +#define XF86XK_VideoPhone _EVDEVK(0x1A0) /* v2.6.20 KEY_VIDEOPHONE */ +/* Use: XF86XK_Game _EVDEVK(0x1A1) v2.6.20 KEY_GAMES */ +/* Use: XF86XK_ZoomIn _EVDEVK(0x1A2) v2.6.20 KEY_ZOOMIN */ +/* Use: XF86XK_ZoomOut _EVDEVK(0x1A3) v2.6.20 KEY_ZOOMOUT */ +#define XF86XK_ZoomReset _EVDEVK(0x1A4) /* v2.6.20 KEY_ZOOMRESET */ +/* Use: XF86XK_Word _EVDEVK(0x1A5) v2.6.20 KEY_WORDPROCESSOR */ +#define XF86XK_Editor _EVDEVK(0x1A6) /* v2.6.20 KEY_EDITOR */ +/* Use: XF86XK_Excel _EVDEVK(0x1A7) v2.6.20 KEY_SPREADSHEET */ +#define XF86XK_GraphicsEditor _EVDEVK(0x1A8) /* v2.6.20 KEY_GRAPHICSEDITOR */ +#define XF86XK_Presentation _EVDEVK(0x1A9) /* v2.6.20 KEY_PRESENTATION */ +#define XF86XK_Database _EVDEVK(0x1AA) /* v2.6.20 KEY_DATABASE */ +/* Use: XF86XK_News _EVDEVK(0x1AB) v2.6.20 KEY_NEWS */ +#define XF86XK_Voicemail _EVDEVK(0x1AC) /* v2.6.20 KEY_VOICEMAIL */ +#define XF86XK_Addressbook _EVDEVK(0x1AD) /* v2.6.20 KEY_ADDRESSBOOK */ +/* Use: XF86XK_Messenger _EVDEVK(0x1AE) v2.6.20 KEY_MESSENGER */ +#define XF86XK_DisplayToggle _EVDEVK(0x1AF) /* v2.6.20 KEY_DISPLAYTOGGLE */ +#define XF86XK_SpellCheck _EVDEVK(0x1B0) /* v2.6.24 KEY_SPELLCHECK */ +/* Use: XF86XK_LogOff _EVDEVK(0x1B1) v2.6.24 KEY_LOGOFF */ +/* Use: XK_dollar _EVDEVK(0x1B2) v2.6.24 KEY_DOLLAR */ +/* Use: XK_EuroSign _EVDEVK(0x1B3) v2.6.24 KEY_EURO */ +/* Use: XF86XK_FrameBack _EVDEVK(0x1B4) v2.6.24 KEY_FRAMEBACK */ +/* Use: XF86XK_FrameForward _EVDEVK(0x1B5) v2.6.24 KEY_FRAMEFORWARD */ +#define XF86XK_ContextMenu _EVDEVK(0x1B6) /* v2.6.24 KEY_CONTEXT_MENU */ +#define XF86XK_MediaRepeat _EVDEVK(0x1B7) /* v2.6.26 KEY_MEDIA_REPEAT */ +#define XF86XK_10ChannelsUp _EVDEVK(0x1B8) /* v2.6.38 KEY_10CHANNELSUP */ +#define XF86XK_10ChannelsDown _EVDEVK(0x1B9) /* v2.6.38 KEY_10CHANNELSDOWN */ +#define XF86XK_Images _EVDEVK(0x1BA) /* v2.6.39 KEY_IMAGES */ +#define XF86XK_NotificationCenter _EVDEVK(0x1BC) /* v5.10 KEY_NOTIFICATION_CENTER */ +#define XF86XK_PickupPhone _EVDEVK(0x1BD) /* v5.10 KEY_PICKUP_PHONE */ +#define XF86XK_HangupPhone _EVDEVK(0x1BE) /* v5.10 KEY_HANGUP_PHONE */ +#define XF86XK_Fn _EVDEVK(0x1D0) /* KEY_FN */ +#define XF86XK_Fn_Esc _EVDEVK(0x1D1) /* KEY_FN_ESC */ +#define XF86XK_FnRightShift _EVDEVK(0x1E5) /* v5.10 KEY_FN_RIGHT_SHIFT */ +/* Use: XK_braille_dot_1 _EVDEVK(0x1F1) v2.6.17 KEY_BRL_DOT1 */ +/* Use: XK_braille_dot_2 _EVDEVK(0x1F2) v2.6.17 KEY_BRL_DOT2 */ +/* Use: XK_braille_dot_3 _EVDEVK(0x1F3) v2.6.17 KEY_BRL_DOT3 */ +/* Use: XK_braille_dot_4 _EVDEVK(0x1F4) v2.6.17 KEY_BRL_DOT4 */ +/* Use: XK_braille_dot_5 _EVDEVK(0x1F5) v2.6.17 KEY_BRL_DOT5 */ +/* Use: XK_braille_dot_6 _EVDEVK(0x1F6) v2.6.17 KEY_BRL_DOT6 */ +/* Use: XK_braille_dot_7 _EVDEVK(0x1F7) v2.6.17 KEY_BRL_DOT7 */ +/* Use: XK_braille_dot_8 _EVDEVK(0x1F8) v2.6.17 KEY_BRL_DOT8 */ +/* Use: XK_braille_dot_9 _EVDEVK(0x1F9) v2.6.23 KEY_BRL_DOT9 */ +/* Use: XK_braille_dot_1 _EVDEVK(0x1FA) v2.6.23 KEY_BRL_DOT10 */ +#define XF86XK_Numeric0 _EVDEVK(0x200) /* v2.6.28 KEY_NUMERIC_0 */ +#define XF86XK_Numeric1 _EVDEVK(0x201) /* v2.6.28 KEY_NUMERIC_1 */ +#define XF86XK_Numeric2 _EVDEVK(0x202) /* v2.6.28 KEY_NUMERIC_2 */ +#define XF86XK_Numeric3 _EVDEVK(0x203) /* v2.6.28 KEY_NUMERIC_3 */ +#define XF86XK_Numeric4 _EVDEVK(0x204) /* v2.6.28 KEY_NUMERIC_4 */ +#define XF86XK_Numeric5 _EVDEVK(0x205) /* v2.6.28 KEY_NUMERIC_5 */ +#define XF86XK_Numeric6 _EVDEVK(0x206) /* v2.6.28 KEY_NUMERIC_6 */ +#define XF86XK_Numeric7 _EVDEVK(0x207) /* v2.6.28 KEY_NUMERIC_7 */ +#define XF86XK_Numeric8 _EVDEVK(0x208) /* v2.6.28 KEY_NUMERIC_8 */ +#define XF86XK_Numeric9 _EVDEVK(0x209) /* v2.6.28 KEY_NUMERIC_9 */ +#define XF86XK_NumericStar _EVDEVK(0x20A) /* v2.6.28 KEY_NUMERIC_STAR */ +#define XF86XK_NumericPound _EVDEVK(0x20B) /* v2.6.28 KEY_NUMERIC_POUND */ +#define XF86XK_NumericA _EVDEVK(0x20C) /* v4.1 KEY_NUMERIC_A */ +#define XF86XK_NumericB _EVDEVK(0x20D) /* v4.1 KEY_NUMERIC_B */ +#define XF86XK_NumericC _EVDEVK(0x20E) /* v4.1 KEY_NUMERIC_C */ +#define XF86XK_NumericD _EVDEVK(0x20F) /* v4.1 KEY_NUMERIC_D */ +#define XF86XK_CameraFocus _EVDEVK(0x210) /* v2.6.33 KEY_CAMERA_FOCUS */ +#define XF86XK_WPSButton _EVDEVK(0x211) /* v2.6.34 KEY_WPS_BUTTON */ +/* Use: XF86XK_TouchpadToggle _EVDEVK(0x212) v2.6.37 KEY_TOUCHPAD_TOGGLE */ +/* Use: XF86XK_TouchpadOn _EVDEVK(0x213) v2.6.37 KEY_TOUCHPAD_ON */ +/* Use: XF86XK_TouchpadOff _EVDEVK(0x214) v2.6.37 KEY_TOUCHPAD_OFF */ +#define XF86XK_CameraZoomIn _EVDEVK(0x215) /* v2.6.39 KEY_CAMERA_ZOOMIN */ +#define XF86XK_CameraZoomOut _EVDEVK(0x216) /* v2.6.39 KEY_CAMERA_ZOOMOUT */ +#define XF86XK_CameraUp _EVDEVK(0x217) /* v2.6.39 KEY_CAMERA_UP */ +#define XF86XK_CameraDown _EVDEVK(0x218) /* v2.6.39 KEY_CAMERA_DOWN */ +#define XF86XK_CameraLeft _EVDEVK(0x219) /* v2.6.39 KEY_CAMERA_LEFT */ +#define XF86XK_CameraRight _EVDEVK(0x21A) /* v2.6.39 KEY_CAMERA_RIGHT */ +#define XF86XK_AttendantOn _EVDEVK(0x21B) /* v3.10 KEY_ATTENDANT_ON */ +#define XF86XK_AttendantOff _EVDEVK(0x21C) /* v3.10 KEY_ATTENDANT_OFF */ +#define XF86XK_AttendantToggle _EVDEVK(0x21D) /* v3.10 KEY_ATTENDANT_TOGGLE */ +#define XF86XK_LightsToggle _EVDEVK(0x21E) /* v3.10 KEY_LIGHTS_TOGGLE */ +#define XF86XK_ALSToggle _EVDEVK(0x230) /* v3.13 KEY_ALS_TOGGLE */ +/* Use: XF86XK_RotationLockToggle _EVDEVK(0x231) v4.16 KEY_ROTATE_LOCK_TOGGLE */ +#define XF86XK_Buttonconfig _EVDEVK(0x240) /* v3.16 KEY_BUTTONCONFIG */ +#define XF86XK_Taskmanager _EVDEVK(0x241) /* v3.16 KEY_TASKMANAGER */ +#define XF86XK_Journal _EVDEVK(0x242) /* v3.16 KEY_JOURNAL */ +#define XF86XK_ControlPanel _EVDEVK(0x243) /* v3.16 KEY_CONTROLPANEL */ +#define XF86XK_AppSelect _EVDEVK(0x244) /* v3.16 KEY_APPSELECT */ +#define XF86XK_Screensaver _EVDEVK(0x245) /* v3.16 KEY_SCREENSAVER */ +#define XF86XK_VoiceCommand _EVDEVK(0x246) /* v3.16 KEY_VOICECOMMAND */ +#define XF86XK_Assistant _EVDEVK(0x247) /* v4.13 KEY_ASSISTANT */ +/* Use: XK_ISO_Next_Group _EVDEVK(0x248) v5.2 KEY_KBD_LAYOUT_NEXT */ +#define XF86XK_BrightnessMin _EVDEVK(0x250) /* v3.16 KEY_BRIGHTNESS_MIN */ +#define XF86XK_BrightnessMax _EVDEVK(0x251) /* v3.16 KEY_BRIGHTNESS_MAX */ +#define XF86XK_KbdInputAssistPrev _EVDEVK(0x260) /* v3.18 KEY_KBDINPUTASSIST_PREV */ +#define XF86XK_KbdInputAssistNext _EVDEVK(0x261) /* v3.18 KEY_KBDINPUTASSIST_NEXT */ +#define XF86XK_KbdInputAssistPrevgroup _EVDEVK(0x262) /* v3.18 KEY_KBDINPUTASSIST_PREVGROUP */ +#define XF86XK_KbdInputAssistNextgroup _EVDEVK(0x263) /* v3.18 KEY_KBDINPUTASSIST_NEXTGROUP */ +#define XF86XK_KbdInputAssistAccept _EVDEVK(0x264) /* v3.18 KEY_KBDINPUTASSIST_ACCEPT */ +#define XF86XK_KbdInputAssistCancel _EVDEVK(0x265) /* v3.18 KEY_KBDINPUTASSIST_CANCEL */ +#define XF86XK_RightUp _EVDEVK(0x266) /* v4.7 KEY_RIGHT_UP */ +#define XF86XK_RightDown _EVDEVK(0x267) /* v4.7 KEY_RIGHT_DOWN */ +#define XF86XK_LeftUp _EVDEVK(0x268) /* v4.7 KEY_LEFT_UP */ +#define XF86XK_LeftDown _EVDEVK(0x269) /* v4.7 KEY_LEFT_DOWN */ +#define XF86XK_RootMenu _EVDEVK(0x26A) /* v4.7 KEY_ROOT_MENU */ +#define XF86XK_MediaTopMenu _EVDEVK(0x26B) /* v4.7 KEY_MEDIA_TOP_MENU */ +#define XF86XK_Numeric11 _EVDEVK(0x26C) /* v4.7 KEY_NUMERIC_11 */ +#define XF86XK_Numeric12 _EVDEVK(0x26D) /* v4.7 KEY_NUMERIC_12 */ +#define XF86XK_AudioDesc _EVDEVK(0x26E) /* v4.7 KEY_AUDIO_DESC */ +#define XF86XK_3DMode _EVDEVK(0x26F) /* v4.7 KEY_3D_MODE */ +#define XF86XK_NextFavorite _EVDEVK(0x270) /* v4.7 KEY_NEXT_FAVORITE */ +#define XF86XK_StopRecord _EVDEVK(0x271) /* v4.7 KEY_STOP_RECORD */ +#define XF86XK_PauseRecord _EVDEVK(0x272) /* v4.7 KEY_PAUSE_RECORD */ +#define XF86XK_VOD _EVDEVK(0x273) /* v4.7 KEY_VOD */ +#define XF86XK_Unmute _EVDEVK(0x274) /* v4.7 KEY_UNMUTE */ +#define XF86XK_FastReverse _EVDEVK(0x275) /* v4.7 KEY_FASTREVERSE */ +#define XF86XK_SlowReverse _EVDEVK(0x276) /* v4.7 KEY_SLOWREVERSE */ +#define XF86XK_Data _EVDEVK(0x277) /* v4.7 KEY_DATA */ +#define XF86XK_OnScreenKeyboard _EVDEVK(0x278) /* v4.12 KEY_ONSCREEN_KEYBOARD */ +#define XF86XK_PrivacyScreenToggle _EVDEVK(0x279) /* v5.5 KEY_PRIVACY_SCREEN_TOGGLE */ +#define XF86XK_SelectiveScreenshot _EVDEVK(0x27A) /* v5.6 KEY_SELECTIVE_SCREENSHOT */ +#define XF86XK_Macro1 _EVDEVK(0x290) /* v5.5 KEY_MACRO1 */ +#define XF86XK_Macro2 _EVDEVK(0x291) /* v5.5 KEY_MACRO2 */ +#define XF86XK_Macro3 _EVDEVK(0x292) /* v5.5 KEY_MACRO3 */ +#define XF86XK_Macro4 _EVDEVK(0x293) /* v5.5 KEY_MACRO4 */ +#define XF86XK_Macro5 _EVDEVK(0x294) /* v5.5 KEY_MACRO5 */ +#define XF86XK_Macro6 _EVDEVK(0x295) /* v5.5 KEY_MACRO6 */ +#define XF86XK_Macro7 _EVDEVK(0x296) /* v5.5 KEY_MACRO7 */ +#define XF86XK_Macro8 _EVDEVK(0x297) /* v5.5 KEY_MACRO8 */ +#define XF86XK_Macro9 _EVDEVK(0x298) /* v5.5 KEY_MACRO9 */ +#define XF86XK_Macro10 _EVDEVK(0x299) /* v5.5 KEY_MACRO10 */ +#define XF86XK_Macro11 _EVDEVK(0x29A) /* v5.5 KEY_MACRO11 */ +#define XF86XK_Macro12 _EVDEVK(0x29B) /* v5.5 KEY_MACRO12 */ +#define XF86XK_Macro13 _EVDEVK(0x29C) /* v5.5 KEY_MACRO13 */ +#define XF86XK_Macro14 _EVDEVK(0x29D) /* v5.5 KEY_MACRO14 */ +#define XF86XK_Macro15 _EVDEVK(0x29E) /* v5.5 KEY_MACRO15 */ +#define XF86XK_Macro16 _EVDEVK(0x29F) /* v5.5 KEY_MACRO16 */ +#define XF86XK_Macro17 _EVDEVK(0x2A0) /* v5.5 KEY_MACRO17 */ +#define XF86XK_Macro18 _EVDEVK(0x2A1) /* v5.5 KEY_MACRO18 */ +#define XF86XK_Macro19 _EVDEVK(0x2A2) /* v5.5 KEY_MACRO19 */ +#define XF86XK_Macro20 _EVDEVK(0x2A3) /* v5.5 KEY_MACRO20 */ +#define XF86XK_Macro21 _EVDEVK(0x2A4) /* v5.5 KEY_MACRO21 */ +#define XF86XK_Macro22 _EVDEVK(0x2A5) /* v5.5 KEY_MACRO22 */ +#define XF86XK_Macro23 _EVDEVK(0x2A6) /* v5.5 KEY_MACRO23 */ +#define XF86XK_Macro24 _EVDEVK(0x2A7) /* v5.5 KEY_MACRO24 */ +#define XF86XK_Macro25 _EVDEVK(0x2A8) /* v5.5 KEY_MACRO25 */ +#define XF86XK_Macro26 _EVDEVK(0x2A9) /* v5.5 KEY_MACRO26 */ +#define XF86XK_Macro27 _EVDEVK(0x2AA) /* v5.5 KEY_MACRO27 */ +#define XF86XK_Macro28 _EVDEVK(0x2AB) /* v5.5 KEY_MACRO28 */ +#define XF86XK_Macro29 _EVDEVK(0x2AC) /* v5.5 KEY_MACRO29 */ +#define XF86XK_Macro30 _EVDEVK(0x2AD) /* v5.5 KEY_MACRO30 */ +#define XF86XK_MacroRecordStart _EVDEVK(0x2B0) /* v5.5 KEY_MACRO_RECORD_START */ +#define XF86XK_MacroRecordStop _EVDEVK(0x2B1) /* v5.5 KEY_MACRO_RECORD_STOP */ +#define XF86XK_MacroPresetCycle _EVDEVK(0x2B2) /* v5.5 KEY_MACRO_PRESET_CYCLE */ +#define XF86XK_MacroPreset1 _EVDEVK(0x2B3) /* v5.5 KEY_MACRO_PRESET1 */ +#define XF86XK_MacroPreset2 _EVDEVK(0x2B4) /* v5.5 KEY_MACRO_PRESET2 */ +#define XF86XK_MacroPreset3 _EVDEVK(0x2B5) /* v5.5 KEY_MACRO_PRESET3 */ +#define XF86XK_KbdLcdMenu1 _EVDEVK(0x2B8) /* v5.5 KEY_KBD_LCD_MENU1 */ +#define XF86XK_KbdLcdMenu2 _EVDEVK(0x2B9) /* v5.5 KEY_KBD_LCD_MENU2 */ +#define XF86XK_KbdLcdMenu3 _EVDEVK(0x2BA) /* v5.5 KEY_KBD_LCD_MENU3 */ +#define XF86XK_KbdLcdMenu4 _EVDEVK(0x2BB) /* v5.5 KEY_KBD_LCD_MENU4 */ +#define XF86XK_KbdLcdMenu5 _EVDEVK(0x2BC) /* v5.5 KEY_KBD_LCD_MENU5 */ +#undef _EVDEVK diff --git a/thirdparty/linuxbsd_headers/X11/XKBlib.h b/thirdparty/linuxbsd_headers/X11/XKBlib.h new file mode 100644 index 0000000000..dd532b2241 --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/XKBlib.h @@ -0,0 +1,1149 @@ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +Permission to use, copy, modify, and distribute this +software and its documentation for any purpose and without +fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright +notice and this permission notice appear in supporting +documentation, and that the name of Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL +DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH +THE USE OR PERFORMANCE OF THIS SOFTWARE. + +********************************************************/ + +#ifndef _X11_XKBLIB_H_ +#define _X11_XKBLIB_H_ + +#include <X11/Xlib.h> +#include <X11/extensions/XKBstr.h> + +typedef struct _XkbAnyEvent { + int type; /* XkbAnyEvent */ + unsigned long serial; /* # of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display * display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XKB event minor code */ + unsigned int device; /* device ID */ +} XkbAnyEvent; + +typedef struct _XkbNewKeyboardNotify { + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display * display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbNewKeyboardNotify */ + int device; /* device ID */ + int old_device; /* device ID of previous keyboard */ + int min_key_code; /* minimum key code */ + int max_key_code; /* maximum key code */ + int old_min_key_code;/* min key code of previous kbd */ + int old_max_key_code;/* max key code of previous kbd */ + unsigned int changed; /* changed aspects of the keyboard */ + char req_major; /* major and minor opcode of req */ + char req_minor; /* that caused change, if applicable */ +} XkbNewKeyboardNotifyEvent; + +typedef struct _XkbMapNotifyEvent { + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request */ + Display * display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbMapNotify */ + int device; /* device ID */ + unsigned int changed; /* fields which have been changed */ + unsigned int flags; /* reserved */ + int first_type; /* first changed key type */ + int num_types; /* number of changed key types */ + KeyCode min_key_code; + KeyCode max_key_code; + KeyCode first_key_sym; + KeyCode first_key_act; + KeyCode first_key_behavior; + KeyCode first_key_explicit; + KeyCode first_modmap_key; + KeyCode first_vmodmap_key; + int num_key_syms; + int num_key_acts; + int num_key_behaviors; + int num_key_explicit; + int num_modmap_keys; + int num_vmodmap_keys; + unsigned int vmods; /* mask of changed virtual mods */ +} XkbMapNotifyEvent; + +typedef struct _XkbStateNotifyEvent { + int type; /* XkbAnyEvent */ + unsigned long serial; /* # of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display * display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbStateNotify */ + int device; /* device ID */ + unsigned int changed; /* mask of changed state components */ + int group; /* keyboard group */ + int base_group; /* base keyboard group */ + int latched_group; /* latched keyboard group */ + int locked_group; /* locked keyboard group */ + unsigned int mods; /* modifier state */ + unsigned int base_mods; /* base modifier state */ + unsigned int latched_mods; /* latched modifiers */ + unsigned int locked_mods; /* locked modifiers */ + int compat_state; /* compatibility state */ + unsigned char grab_mods; /* mods used for grabs */ + unsigned char compat_grab_mods;/* grab mods for non-XKB clients */ + unsigned char lookup_mods; /* mods sent to clients */ + unsigned char compat_lookup_mods; /* mods sent to non-XKB clients */ + int ptr_buttons; /* pointer button state */ + KeyCode keycode; /* keycode that caused the change */ + char event_type; /* KeyPress or KeyRelease */ + char req_major; /* Major opcode of request */ + char req_minor; /* Minor opcode of request */ +} XkbStateNotifyEvent; + +typedef struct _XkbControlsNotify { + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display * display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbControlsNotify */ + int device; /* device ID */ + unsigned int changed_ctrls; /* controls with changed sub-values */ + unsigned int enabled_ctrls; /* controls currently enabled */ + unsigned int enabled_ctrl_changes;/* controls just {en,dis}abled */ + int num_groups; /* total groups on keyboard */ + KeyCode keycode; /* key that caused change or 0 */ + char event_type; /* type of event that caused change */ + char req_major; /* if keycode==0, major and minor */ + char req_minor; /* opcode of req that caused change */ +} XkbControlsNotifyEvent; + +typedef struct _XkbIndicatorNotify { + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display * display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbIndicatorNotify */ + int device; /* device ID */ + unsigned int changed; /* indicators with new state or map */ + unsigned int state; /* current state of all indicators */ +} XkbIndicatorNotifyEvent; + +typedef struct _XkbNamesNotify { + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display * display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbNamesNotify */ + int device; /* device ID */ + unsigned int changed; /* names that have changed */ + int first_type; /* first key type with new name */ + int num_types; /* number of key types with new names */ + int first_lvl; /* first key type new new level names */ + int num_lvls; /* # of key types w/new level names */ + int num_aliases; /* total number of key aliases*/ + int num_radio_groups;/* total number of radio groups */ + unsigned int changed_vmods; /* virtual modifiers with new names */ + unsigned int changed_groups; /* groups with new names */ + unsigned int changed_indicators;/* indicators with new names */ + int first_key; /* first key with new name */ + int num_keys; /* number of keys with new names */ +} XkbNamesNotifyEvent; + +typedef struct _XkbCompatMapNotify { + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display * display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbCompatMapNotify */ + int device; /* device ID */ + unsigned int changed_groups; /* groups with new compat maps */ + int first_si; /* first new symbol interp */ + int num_si; /* number of new symbol interps */ + int num_total_si; /* total # of symbol interps */ +} XkbCompatMapNotifyEvent; + +typedef struct _XkbBellNotify { + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display * display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbBellNotify */ + int device; /* device ID */ + int percent; /* requested volume as a % of maximum */ + int pitch; /* requested pitch in Hz */ + int duration; /* requested duration in useconds */ + int bell_class; /* (input extension) feedback class */ + int bell_id; /* (input extension) ID of feedback */ + Atom name; /* "name" of requested bell */ + Window window; /* window associated with event */ + Bool event_only; /* "event only" requested */ +} XkbBellNotifyEvent; + +typedef struct _XkbActionMessage { + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display * display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbActionMessage */ + int device; /* device ID */ + KeyCode keycode; /* key that generated the event */ + Bool press; /* true if act caused by key press */ + Bool key_event_follows;/* true if key event also generated */ + int group; /* effective group */ + unsigned int mods; /* effective mods */ + char message[XkbActionMessageLength+1]; + /* message -- leave space for NUL */ +} XkbActionMessageEvent; + +typedef struct _XkbAccessXNotify { + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display * display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbAccessXNotify */ + int device; /* device ID */ + int detail; /* XkbAXN_* */ + int keycode; /* key of event */ + int sk_delay; /* current slow keys delay */ + int debounce_delay; /* current debounce delay */ +} XkbAccessXNotifyEvent; + +typedef struct _XkbExtensionDeviceNotify { + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display * display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbExtensionDeviceNotify */ + int device; /* device ID */ + unsigned int reason; /* reason for the event */ + unsigned int supported; /* mask of supported features */ + unsigned int unsupported; /* mask of unsupported features */ + /* that some app tried to use */ + int first_btn; /* first button that changed */ + int num_btns; /* range of buttons changed */ + unsigned int leds_defined; /* indicators with names or maps */ + unsigned int led_state; /* current state of the indicators */ + int led_class; /* feedback class for led changes */ + int led_id; /* feedback id for led changes */ +} XkbExtensionDeviceNotifyEvent; + +typedef union _XkbEvent { + int type; + XkbAnyEvent any; + XkbNewKeyboardNotifyEvent new_kbd; + XkbMapNotifyEvent map; + XkbStateNotifyEvent state; + XkbControlsNotifyEvent ctrls; + XkbIndicatorNotifyEvent indicators; + XkbNamesNotifyEvent names; + XkbCompatMapNotifyEvent compat; + XkbBellNotifyEvent bell; + XkbActionMessageEvent message; + XkbAccessXNotifyEvent accessx; + XkbExtensionDeviceNotifyEvent device; + XEvent core; +} XkbEvent; + +typedef struct _XkbKbdDpyState XkbKbdDpyStateRec,*XkbKbdDpyStatePtr; + + /* XkbOpenDisplay error codes */ +#define XkbOD_Success 0 +#define XkbOD_BadLibraryVersion 1 +#define XkbOD_ConnectionRefused 2 +#define XkbOD_NonXkbServer 3 +#define XkbOD_BadServerVersion 4 + + /* Values for XlibFlags */ +#define XkbLC_ForceLatin1Lookup (1<<0) +#define XkbLC_ConsumeLookupMods (1<<1) +#define XkbLC_AlwaysConsumeShiftAndLock (1<<2) +#define XkbLC_IgnoreNewKeyboards (1<<3) +#define XkbLC_ControlFallback (1<<4) +#define XkbLC_ConsumeKeysOnComposeFail (1<<29) +#define XkbLC_ComposeLED (1<<30) +#define XkbLC_BeepOnComposeFail (1<<31) + +#define XkbLC_AllComposeControls (0xc0000000) +#define XkbLC_AllControls (0xc000001f) + +_XFUNCPROTOBEGIN + +extern Bool XkbIgnoreExtension( + Bool /* ignore */ +); + +extern Display *XkbOpenDisplay( + char * /* name */, + int * /* ev_rtrn */, + int * /* err_rtrn */, + int * /* major_rtrn */, + int * /* minor_rtrn */, + int * /* reason */ +); + +extern Bool XkbQueryExtension( + Display * /* dpy */, + int * /* opcodeReturn */, + int * /* eventBaseReturn */, + int * /* errorBaseReturn */, + int * /* majorRtrn */, + int * /* minorRtrn */ +); + +extern Bool XkbUseExtension( + Display * /* dpy */, + int * /* major_rtrn */, + int * /* minor_rtrn */ +); + +extern Bool XkbLibraryVersion( + int * /* libMajorRtrn */, + int * /* libMinorRtrn */ +); + +extern unsigned int XkbSetXlibControls( + Display* /* dpy */, + unsigned int /* affect */, + unsigned int /* values */ +); + +extern unsigned int XkbGetXlibControls( + Display* /* dpy */ +); + +extern unsigned int XkbXlibControlsImplemented(void); + +typedef Atom (*XkbInternAtomFunc)( + Display * /* dpy */, + _Xconst char * /* name */, + Bool /* only_if_exists */ +); + +typedef char * (*XkbGetAtomNameFunc)( + Display * /* dpy */, + Atom /* atom */ +); + +extern void XkbSetAtomFuncs( + XkbInternAtomFunc /* getAtom */, + XkbGetAtomNameFunc /* getName */ +); + +extern KeySym XkbKeycodeToKeysym( + Display * /* dpy */, +#if NeedWidePrototypes + unsigned int /* kc */, +#else + KeyCode /* kc */, +#endif + int /* group */, + int /* level */ +); + +extern unsigned int XkbKeysymToModifiers( + Display * /* dpy */, + KeySym /* ks */ +); + +extern Bool XkbLookupKeySym( + Display * /* dpy */, + KeyCode /* keycode */, + unsigned int /* modifiers */, + unsigned int * /* modifiers_return */, + KeySym * /* keysym_return */ +); + +extern int XkbLookupKeyBinding( + Display * /* dpy */, + KeySym /* sym_rtrn */, + unsigned int /* mods */, + char * /* buffer */, + int /* nbytes */, + int * /* extra_rtrn */ +); + +extern Bool XkbTranslateKeyCode( + XkbDescPtr /* xkb */, + KeyCode /* keycode */, + unsigned int /* modifiers */, + unsigned int * /* modifiers_return */, + KeySym * /* keysym_return */ +); + +extern int XkbTranslateKeySym( + Display * /* dpy */, + KeySym * /* sym_return */, + unsigned int /* modifiers */, + char * /* buffer */, + int /* nbytes */, + int * /* extra_rtrn */ +); + +extern Bool XkbSetAutoRepeatRate( + Display * /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* delay */, + unsigned int /* interval */ +); + +extern Bool XkbGetAutoRepeatRate( + Display * /* dpy */, + unsigned int /* deviceSpec */, + unsigned int * /* delayRtrn */, + unsigned int * /* intervalRtrn */ +); + +extern Bool XkbChangeEnabledControls( + Display * /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* affect */, + unsigned int /* values */ +); + +extern Bool XkbDeviceBell( + Display * /* dpy */, + Window /* win */, + int /* deviceSpec */, + int /* bellClass */, + int /* bellID */, + int /* percent */, + Atom /* name */ +); + +extern Bool XkbForceDeviceBell( + Display * /* dpy */, + int /* deviceSpec */, + int /* bellClass */, + int /* bellID */, + int /* percent */ +); + +extern Bool XkbDeviceBellEvent( + Display * /* dpy */, + Window /* win */, + int /* deviceSpec */, + int /* bellClass */, + int /* bellID */, + int /* percent */, + Atom /* name */ +); + +extern Bool XkbBell( + Display * /* dpy */, + Window /* win */, + int /* percent */, + Atom /* name */ +); + +extern Bool XkbForceBell( + Display * /* dpy */, + int /* percent */ +); + +extern Bool XkbBellEvent( + Display * /* dpy */, + Window /* win */, + int /* percent */, + Atom /* name */ +); + +extern Bool XkbSelectEvents( + Display * /* dpy */, + unsigned int /* deviceID */, + unsigned int /* affect */, + unsigned int /* values */ +); + +extern Bool XkbSelectEventDetails( + Display * /* dpy */, + unsigned int /* deviceID */, + unsigned int /* eventType */, + unsigned long /* affect */, + unsigned long /* details */ +); + +extern void XkbNoteMapChanges( + XkbMapChangesPtr /* old */, + XkbMapNotifyEvent * /* new */, + unsigned int /* wanted */ +); + +extern void XkbNoteNameChanges( + XkbNameChangesPtr /* old */, + XkbNamesNotifyEvent * /* new */, + unsigned int /* wanted */ +); + +extern Status XkbGetIndicatorState( + Display * /* dpy */, + unsigned int /* deviceSpec */, + unsigned int * /* pStateRtrn */ +); + +extern Status XkbGetDeviceIndicatorState( + Display * /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* ledClass */, + unsigned int /* ledID */, + unsigned int * /* pStateRtrn */ +); + +extern Status XkbGetIndicatorMap( + Display * /* dpy */, + unsigned long /* which */, + XkbDescPtr /* desc */ +); + +extern Bool XkbSetIndicatorMap( + Display * /* dpy */, + unsigned long /* which */, + XkbDescPtr /* desc */ +); + +#define XkbNoteIndicatorMapChanges(o,n,w) \ + ((o)->map_changes|=((n)->map_changes&(w))) +#define XkbNoteIndicatorStateChanges(o,n,w)\ + ((o)->state_changes|=((n)->state_changes&(w))) +#define XkbGetIndicatorMapChanges(d,x,c) \ + (XkbGetIndicatorMap((d),(c)->map_changes,x)) +#define XkbChangeIndicatorMaps(d,x,c) \ + (XkbSetIndicatorMap((d),(c)->map_changes,x)) + +extern Bool XkbGetNamedIndicator( + Display * /* dpy */, + Atom /* name */, + int * /* pNdxRtrn */, + Bool * /* pStateRtrn */, + XkbIndicatorMapPtr /* pMapRtrn */, + Bool * /* pRealRtrn */ +); + +extern Bool XkbGetNamedDeviceIndicator( + Display * /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* ledClass */, + unsigned int /* ledID */, + Atom /* name */, + int * /* pNdxRtrn */, + Bool * /* pStateRtrn */, + XkbIndicatorMapPtr /* pMapRtrn */, + Bool * /* pRealRtrn */ +); + +extern Bool XkbSetNamedIndicator( + Display * /* dpy */, + Atom /* name */, + Bool /* changeState */, + Bool /* state */, + Bool /* createNewMap */, + XkbIndicatorMapPtr /* pMap */ +); + +extern Bool XkbSetNamedDeviceIndicator( + Display * /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* ledClass */, + unsigned int /* ledID */, + Atom /* name */, + Bool /* changeState */, + Bool /* state */, + Bool /* createNewMap */, + XkbIndicatorMapPtr /* pMap */ +); + +extern Bool XkbLockModifiers( + Display * /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* affect */, + unsigned int /* values */ +); + +extern Bool XkbLatchModifiers( + Display * /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* affect */, + unsigned int /* values */ +); + +extern Bool XkbLockGroup( + Display * /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* group */ +); + +extern Bool XkbLatchGroup( + Display * /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* group */ +); + +extern Bool XkbSetServerInternalMods( + Display * /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* affectReal */, + unsigned int /* realValues */, + unsigned int /* affectVirtual */, + unsigned int /* virtualValues */ +); + +extern Bool XkbSetIgnoreLockMods( + Display * /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* affectReal */, + unsigned int /* realValues */, + unsigned int /* affectVirtual */, + unsigned int /* virtualValues */ +); + + +extern Bool XkbVirtualModsToReal( + XkbDescPtr /* xkb */, + unsigned int /* virtual_mask */, + unsigned int * /* mask_rtrn */ +); + +extern Bool XkbComputeEffectiveMap( + XkbDescPtr /* xkb */, + XkbKeyTypePtr /* type */, + unsigned char * /* map_rtrn */ +); + +extern Status XkbInitCanonicalKeyTypes( + XkbDescPtr /* xkb */, + unsigned int /* which */, + int /* keypadVMod */ +); + +extern XkbDescPtr XkbAllocKeyboard( + void +); + +extern void XkbFreeKeyboard( + XkbDescPtr /* xkb */, + unsigned int /* which */, + Bool /* freeDesc */ +); + +extern Status XkbAllocClientMap( + XkbDescPtr /* xkb */, + unsigned int /* which */, + unsigned int /* nTypes */ +); + +extern Status XkbAllocServerMap( + XkbDescPtr /* xkb */, + unsigned int /* which */, + unsigned int /* nActions */ +); + +extern void XkbFreeClientMap( + XkbDescPtr /* xkb */, + unsigned int /* what */, + Bool /* freeMap */ +); + +extern void XkbFreeServerMap( + XkbDescPtr /* xkb */, + unsigned int /* what */, + Bool /* freeMap */ +); + +extern XkbKeyTypePtr XkbAddKeyType( + XkbDescPtr /* xkb */, + Atom /* name */, + int /* map_count */, + Bool /* want_preserve */, + int /* num_lvls */ +); + +extern Status XkbAllocIndicatorMaps( + XkbDescPtr /* xkb */ +); + +extern void XkbFreeIndicatorMaps( + XkbDescPtr /* xkb */ +); + +extern XkbDescPtr XkbGetMap( + Display * /* dpy */, + unsigned int /* which */, + unsigned int /* deviceSpec */ +); + +extern Status XkbGetUpdatedMap( + Display * /* dpy */, + unsigned int /* which */, + XkbDescPtr /* desc */ +); + +extern Status XkbGetMapChanges( + Display * /* dpy */, + XkbDescPtr /* xkb */, + XkbMapChangesPtr /* changes */ +); + + +extern Status XkbRefreshKeyboardMapping( + XkbMapNotifyEvent * /* event */ +); + +extern Status XkbGetKeyTypes( + Display * /* dpy */, + unsigned int /* first */, + unsigned int /* num */, + XkbDescPtr /* xkb */ +); + +extern Status XkbGetKeySyms( + Display * /* dpy */, + unsigned int /* first */, + unsigned int /* num */, + XkbDescPtr /* xkb */ +); + +extern Status XkbGetKeyActions( + Display * /* dpy */, + unsigned int /* first */, + unsigned int /* num */, + XkbDescPtr /* xkb */ +); + +extern Status XkbGetKeyBehaviors( + Display * /* dpy */, + unsigned int /* firstKey */, + unsigned int /* nKeys */, + XkbDescPtr /* desc */ +); + +extern Status XkbGetVirtualMods( + Display * /* dpy */, + unsigned int /* which */, + XkbDescPtr /* desc */ +); + +extern Status XkbGetKeyExplicitComponents( + Display * /* dpy */, + unsigned int /* firstKey */, + unsigned int /* nKeys */, + XkbDescPtr /* desc */ +); + +extern Status XkbGetKeyModifierMap( + Display * /* dpy */, + unsigned int /* firstKey */, + unsigned int /* nKeys */, + XkbDescPtr /* desc */ +); + +extern Status XkbGetKeyVirtualModMap( + Display * /* dpy */, + unsigned int /* first */, + unsigned int /* num */, + XkbDescPtr /* xkb */ +); + +extern Status XkbAllocControls( + XkbDescPtr /* xkb */, + unsigned int /* which*/ +); + +extern void XkbFreeControls( + XkbDescPtr /* xkb */, + unsigned int /* which */, + Bool /* freeMap */ +); + +extern Status XkbGetControls( + Display * /* dpy */, + unsigned long /* which */, + XkbDescPtr /* desc */ +); + +extern Bool XkbSetControls( + Display * /* dpy */, + unsigned long /* which */, + XkbDescPtr /* desc */ +); + +extern void XkbNoteControlsChanges( + XkbControlsChangesPtr /* old */, + XkbControlsNotifyEvent * /* new */, + unsigned int /* wanted */ +); + +#define XkbGetControlsChanges(d,x,c) XkbGetControls(d,(c)->changed_ctrls,x) +#define XkbChangeControls(d,x,c) XkbSetControls(d,(c)->changed_ctrls,x) + +extern Status XkbAllocCompatMap( + XkbDescPtr /* xkb */, + unsigned int /* which */, + unsigned int /* nInterpret */ +); + +extern void XkbFreeCompatMap( + XkbDescPtr /* xkb */, + unsigned int /* which */, + Bool /* freeMap */ +); + +extern Status XkbGetCompatMap( + Display * /* dpy */, + unsigned int /* which */, + XkbDescPtr /* xkb */ +); + +extern Bool XkbSetCompatMap( + Display * /* dpy */, + unsigned int /* which */, + XkbDescPtr /* xkb */, + Bool /* updateActions */ +); + +extern XkbSymInterpretPtr XkbAddSymInterpret( + XkbDescPtr /* xkb */, + XkbSymInterpretPtr /* si */, + Bool /* updateMap */, + XkbChangesPtr /* changes */ +); + +extern Status XkbAllocNames( + XkbDescPtr /* xkb */, + unsigned int /* which */, + int /* nTotalRG */, + int /* nTotalAliases */ +); + +extern Status XkbGetNames( + Display * /* dpy */, + unsigned int /* which */, + XkbDescPtr /* desc */ +); + +extern Bool XkbSetNames( + Display * /* dpy */, + unsigned int /* which */, + unsigned int /* firstType */, + unsigned int /* nTypes */, + XkbDescPtr /* desc */ +); + +extern Bool XkbChangeNames( + Display * /* dpy */, + XkbDescPtr /* xkb */, + XkbNameChangesPtr /* changes */ +); + +extern void XkbFreeNames( + XkbDescPtr /* xkb */, + unsigned int /* which */, + Bool /* freeMap */ +); + + +extern Status XkbGetState( + Display * /* dpy */, + unsigned int /* deviceSpec */, + XkbStatePtr /* rtrnState */ +); + +extern Bool XkbSetMap( + Display * /* dpy */, + unsigned int /* which */, + XkbDescPtr /* desc */ +); + +extern Bool XkbChangeMap( + Display* /* dpy */, + XkbDescPtr /* desc */, + XkbMapChangesPtr /* changes */ +); + +extern Bool XkbSetDetectableAutoRepeat( + Display * /* dpy */, + Bool /* detectable */, + Bool * /* supported */ +); + +extern Bool XkbGetDetectableAutoRepeat( + Display * /* dpy */, + Bool * /* supported */ +); + +extern Bool XkbSetAutoResetControls( + Display * /* dpy */, + unsigned int /* changes */, + unsigned int * /* auto_ctrls */, + unsigned int * /* auto_values */ +); + +extern Bool XkbGetAutoResetControls( + Display * /* dpy */, + unsigned int * /* auto_ctrls */, + unsigned int * /* auto_ctrl_values */ +); + +extern Bool XkbSetPerClientControls( + Display * /* dpy */, + unsigned int /* change */, + unsigned int * /* values */ +); + +extern Bool XkbGetPerClientControls( + Display * /* dpy */, + unsigned int * /* ctrls */ +); + +extern Status XkbCopyKeyType( + XkbKeyTypePtr /* from */, + XkbKeyTypePtr /* into */ +); + +extern Status XkbCopyKeyTypes( + XkbKeyTypePtr /* from */, + XkbKeyTypePtr /* into */, + int /* num_types */ +); + +extern Status XkbResizeKeyType( + XkbDescPtr /* xkb */, + int /* type_ndx */, + int /* map_count */, + Bool /* want_preserve */, + int /* new_num_lvls */ +); + +extern KeySym *XkbResizeKeySyms( + XkbDescPtr /* desc */, + int /* forKey */, + int /* symsNeeded */ +); + +extern XkbAction *XkbResizeKeyActions( + XkbDescPtr /* desc */, + int /* forKey */, + int /* actsNeeded */ +); + +extern Status XkbChangeTypesOfKey( + XkbDescPtr /* xkb */, + int /* key */, + int /* num_groups */, + unsigned int /* groups */, + int * /* newTypes */, + XkbMapChangesPtr /* pChanges */ +); + +extern Status XkbChangeKeycodeRange( + XkbDescPtr /* xkb */, + int /* minKC */, + int /* maxKC */, + XkbChangesPtr /* changes */ +); + +/***====================================================================***/ + +extern XkbComponentListPtr XkbListComponents( + Display * /* dpy */, + unsigned int /* deviceSpec */, + XkbComponentNamesPtr /* ptrns */, + int * /* max_inout */ +); + +extern void XkbFreeComponentList( + XkbComponentListPtr /* list */ +); + +extern XkbDescPtr XkbGetKeyboard( + Display * /* dpy */, + unsigned int /* which */, + unsigned int /* deviceSpec */ +); + +extern XkbDescPtr XkbGetKeyboardByName( + Display * /* dpy */, + unsigned int /* deviceSpec */, + XkbComponentNamesPtr /* names */, + unsigned int /* want */, + unsigned int /* need */, + Bool /* load */ +); + +/***====================================================================***/ + +extern int XkbKeyTypesForCoreSymbols( /* returns # of groups */ + XkbDescPtr /* xkb */, /* keyboard device */ + int /* map_width */, /* width of core KeySym array */ + KeySym * /* core_syms */, /* always mapWidth symbols */ + unsigned int /* protected */, /* explicit key types */ + int * /* types_inout */, /* always four type indices */ + KeySym * /* xkb_syms_rtrn */ /* must have enough space */ +); + +extern Bool XkbApplyCompatMapToKey( /* False only on error */ + XkbDescPtr /* xkb */, /* keymap to be edited */ + KeyCode /* key */, /* key to be updated */ + XkbChangesPtr /* changes */ /* resulting changes to map */ +); + +extern Bool XkbUpdateMapFromCore( /* False only on error */ + XkbDescPtr /* xkb */, /* XKB keyboard to be edited */ + KeyCode /* first_key */, /* first changed key */ + int /* num_keys */, /* number of changed keys */ + int /* map_width */, /* width of core keymap */ + KeySym * /* core_keysyms */, /* symbols from core keymap */ + XkbChangesPtr /* changes */ /* resulting changes */ +); + +/***====================================================================***/ + +extern XkbDeviceLedInfoPtr XkbAddDeviceLedInfo( + XkbDeviceInfoPtr /* devi */, + unsigned int /* ledClass */, + unsigned int /* ledId */ +); + +extern Status XkbResizeDeviceButtonActions( + XkbDeviceInfoPtr /* devi */, + unsigned int /* newTotal */ +); + +extern XkbDeviceInfoPtr XkbAllocDeviceInfo( + unsigned int /* deviceSpec */, + unsigned int /* nButtons */, + unsigned int /* szLeds */ +); + +extern void XkbFreeDeviceInfo( + XkbDeviceInfoPtr /* devi */, + unsigned int /* which */, + Bool /* freeDevI */ +); + +extern void XkbNoteDeviceChanges( + XkbDeviceChangesPtr /* old */, + XkbExtensionDeviceNotifyEvent * /* new */, + unsigned int /* wanted */ +); + +extern XkbDeviceInfoPtr XkbGetDeviceInfo( + Display * /* dpy */, + unsigned int /* which */, + unsigned int /* deviceSpec */, + unsigned int /* ledClass */, + unsigned int /* ledID */ +); + +extern Status XkbGetDeviceInfoChanges( + Display * /* dpy */, + XkbDeviceInfoPtr /* devi */, + XkbDeviceChangesPtr /* changes */ +); + +extern Status XkbGetDeviceButtonActions( + Display * /* dpy */, + XkbDeviceInfoPtr /* devi */, + Bool /* all */, + unsigned int /* first */, + unsigned int /* nBtns */ +); + +extern Status XkbGetDeviceLedInfo( + Display * /* dpy */, + XkbDeviceInfoPtr /* devi */, + unsigned int /* ledClass (class, XIDflt, XIAll) */, + unsigned int /* ledId (id, XIDflt, XIAll) */, + unsigned int /* which (XkbXI_Indicator{Names,Map}Mask */ +); + +extern Bool XkbSetDeviceInfo( + Display * /* dpy */, + unsigned int /* which */, + XkbDeviceInfoPtr /* devi */ +); + +extern Bool XkbChangeDeviceInfo( + Display* /* dpy */, + XkbDeviceInfoPtr /* desc */, + XkbDeviceChangesPtr /* changes */ +); + +extern Bool XkbSetDeviceLedInfo( + Display * /* dpy */, + XkbDeviceInfoPtr /* devi */, + unsigned int /* ledClass */, + unsigned int /* ledID */, + unsigned int /* which */ +); + +extern Bool XkbSetDeviceButtonActions( + Display * /* dpy */, + XkbDeviceInfoPtr /* devi */, + unsigned int /* first */, + unsigned int /* nBtns */ +); + +/***====================================================================***/ + +extern char XkbToControl( + char /* c */ +); + +/***====================================================================***/ + +extern Bool XkbSetDebuggingFlags( + Display * /* dpy */, + unsigned int /* mask */, + unsigned int /* flags */, + char * /* msg */, + unsigned int /* ctrls_mask */, + unsigned int /* ctrls */, + unsigned int * /* rtrn_flags */, + unsigned int * /* rtrn_ctrls */ +); + +extern Bool XkbApplyVirtualModChanges( + XkbDescPtr /* xkb */, + unsigned int /* changed */, + XkbChangesPtr /* changes */ +); + +extern Bool XkbUpdateActionVirtualMods( + XkbDescPtr /* xkb */, + XkbAction * /* act */, + unsigned int /* changed */ +); + +extern void XkbUpdateKeyTypeVirtualMods( + XkbDescPtr /* xkb */, + XkbKeyTypePtr /* type */, + unsigned int /* changed */, + XkbChangesPtr /* changes */ +); + +_XFUNCPROTOEND + +#endif /* _X11_XKBLIB_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/Xatom.h b/thirdparty/linuxbsd_headers/X11/Xatom.h new file mode 100644 index 0000000000..485a4236db --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/Xatom.h @@ -0,0 +1,79 @@ +#ifndef XATOM_H +#define XATOM_H 1 + +/* THIS IS A GENERATED FILE + * + * Do not change! Changing this file implies a protocol change! + */ + +#define XA_PRIMARY ((Atom) 1) +#define XA_SECONDARY ((Atom) 2) +#define XA_ARC ((Atom) 3) +#define XA_ATOM ((Atom) 4) +#define XA_BITMAP ((Atom) 5) +#define XA_CARDINAL ((Atom) 6) +#define XA_COLORMAP ((Atom) 7) +#define XA_CURSOR ((Atom) 8) +#define XA_CUT_BUFFER0 ((Atom) 9) +#define XA_CUT_BUFFER1 ((Atom) 10) +#define XA_CUT_BUFFER2 ((Atom) 11) +#define XA_CUT_BUFFER3 ((Atom) 12) +#define XA_CUT_BUFFER4 ((Atom) 13) +#define XA_CUT_BUFFER5 ((Atom) 14) +#define XA_CUT_BUFFER6 ((Atom) 15) +#define XA_CUT_BUFFER7 ((Atom) 16) +#define XA_DRAWABLE ((Atom) 17) +#define XA_FONT ((Atom) 18) +#define XA_INTEGER ((Atom) 19) +#define XA_PIXMAP ((Atom) 20) +#define XA_POINT ((Atom) 21) +#define XA_RECTANGLE ((Atom) 22) +#define XA_RESOURCE_MANAGER ((Atom) 23) +#define XA_RGB_COLOR_MAP ((Atom) 24) +#define XA_RGB_BEST_MAP ((Atom) 25) +#define XA_RGB_BLUE_MAP ((Atom) 26) +#define XA_RGB_DEFAULT_MAP ((Atom) 27) +#define XA_RGB_GRAY_MAP ((Atom) 28) +#define XA_RGB_GREEN_MAP ((Atom) 29) +#define XA_RGB_RED_MAP ((Atom) 30) +#define XA_STRING ((Atom) 31) +#define XA_VISUALID ((Atom) 32) +#define XA_WINDOW ((Atom) 33) +#define XA_WM_COMMAND ((Atom) 34) +#define XA_WM_HINTS ((Atom) 35) +#define XA_WM_CLIENT_MACHINE ((Atom) 36) +#define XA_WM_ICON_NAME ((Atom) 37) +#define XA_WM_ICON_SIZE ((Atom) 38) +#define XA_WM_NAME ((Atom) 39) +#define XA_WM_NORMAL_HINTS ((Atom) 40) +#define XA_WM_SIZE_HINTS ((Atom) 41) +#define XA_WM_ZOOM_HINTS ((Atom) 42) +#define XA_MIN_SPACE ((Atom) 43) +#define XA_NORM_SPACE ((Atom) 44) +#define XA_MAX_SPACE ((Atom) 45) +#define XA_END_SPACE ((Atom) 46) +#define XA_SUPERSCRIPT_X ((Atom) 47) +#define XA_SUPERSCRIPT_Y ((Atom) 48) +#define XA_SUBSCRIPT_X ((Atom) 49) +#define XA_SUBSCRIPT_Y ((Atom) 50) +#define XA_UNDERLINE_POSITION ((Atom) 51) +#define XA_UNDERLINE_THICKNESS ((Atom) 52) +#define XA_STRIKEOUT_ASCENT ((Atom) 53) +#define XA_STRIKEOUT_DESCENT ((Atom) 54) +#define XA_ITALIC_ANGLE ((Atom) 55) +#define XA_X_HEIGHT ((Atom) 56) +#define XA_QUAD_WIDTH ((Atom) 57) +#define XA_WEIGHT ((Atom) 58) +#define XA_POINT_SIZE ((Atom) 59) +#define XA_RESOLUTION ((Atom) 60) +#define XA_COPYRIGHT ((Atom) 61) +#define XA_NOTICE ((Atom) 62) +#define XA_FONT_NAME ((Atom) 63) +#define XA_FAMILY_NAME ((Atom) 64) +#define XA_FULL_NAME ((Atom) 65) +#define XA_CAP_HEIGHT ((Atom) 66) +#define XA_WM_CLASS ((Atom) 67) +#define XA_WM_TRANSIENT_FOR ((Atom) 68) + +#define XA_LAST_PREDEFINED ((Atom) 68) +#endif /* XATOM_H */ diff --git a/thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h b/thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h new file mode 100644 index 0000000000..79dd0349a7 --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h @@ -0,0 +1,500 @@ +/* include/X11/Xcursor/Xcursor.h. Generated from Xcursor.h.in by configure. */ +/* + * Copyright © 2002 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _XCURSOR_H_ +#define _XCURSOR_H_ +#include <stdio.h> +#include <X11/Xfuncproto.h> +#include <X11/Xlib.h> + +typedef int XcursorBool; +typedef unsigned int XcursorUInt; + +typedef XcursorUInt XcursorDim; +typedef XcursorUInt XcursorPixel; + +#define XcursorTrue 1 +#define XcursorFalse 0 + +/* + * Cursor files start with a header. The header + * contains a magic number, a version number and a + * table of contents which has type and offset information + * for the remaining tables in the file. + * + * File minor versions increment for compatible changes + * File major versions increment for incompatible changes (never, we hope) + * + * Chunks of the same type are always upward compatible. Incompatible + * changes are made with new chunk types; the old data can remain under + * the old type. Upward compatible changes can add header data as the + * header lengths are specified in the file. + * + * File: + * FileHeader + * LISTofChunk + * + * FileHeader: + * CARD32 magic magic number + * CARD32 header bytes in file header + * CARD32 version file version + * CARD32 ntoc number of toc entries + * LISTofFileToc toc table of contents + * + * FileToc: + * CARD32 type entry type + * CARD32 subtype entry subtype (size for images) + * CARD32 position absolute file position + */ + +#define XCURSOR_MAGIC 0x72756358 /* "Xcur" LSBFirst */ + +/* + * Current Xcursor version number. Will be substituted by configure + * from the version in the libXcursor configure.ac file. + */ + +#define XCURSOR_LIB_MAJOR 1 +#define XCURSOR_LIB_MINOR 2 +#define XCURSOR_LIB_REVISION 0 +#define XCURSOR_LIB_VERSION ((XCURSOR_LIB_MAJOR * 10000) + \ + (XCURSOR_LIB_MINOR * 100) + \ + (XCURSOR_LIB_REVISION)) + +/* + * This version number is stored in cursor files; changes to the + * file format require updating this version number + */ +#define XCURSOR_FILE_MAJOR 1 +#define XCURSOR_FILE_MINOR 0 +#define XCURSOR_FILE_VERSION ((XCURSOR_FILE_MAJOR << 16) | (XCURSOR_FILE_MINOR)) +#define XCURSOR_FILE_HEADER_LEN (4 * 4) +#define XCURSOR_FILE_TOC_LEN (3 * 4) + +typedef struct _XcursorFileToc { + XcursorUInt type; /* chunk type */ + XcursorUInt subtype; /* subtype (size for images) */ + XcursorUInt position; /* absolute position in file */ +} XcursorFileToc; + +typedef struct _XcursorFileHeader { + XcursorUInt magic; /* magic number */ + XcursorUInt header; /* byte length of header */ + XcursorUInt version; /* file version number */ + XcursorUInt ntoc; /* number of toc entries */ + XcursorFileToc *tocs; /* table of contents */ +} XcursorFileHeader; + +/* + * The rest of the file is a list of chunks, each tagged by type + * and version. + * + * Chunk: + * ChunkHeader + * <extra type-specific header fields> + * <type-specific data> + * + * ChunkHeader: + * CARD32 header bytes in chunk header + type header + * CARD32 type chunk type + * CARD32 subtype chunk subtype + * CARD32 version chunk type version + */ + +#define XCURSOR_CHUNK_HEADER_LEN (4 * 4) + +typedef struct _XcursorChunkHeader { + XcursorUInt header; /* bytes in chunk header */ + XcursorUInt type; /* chunk type */ + XcursorUInt subtype; /* chunk subtype (size for images) */ + XcursorUInt version; /* version of this type */ +} XcursorChunkHeader; + +/* + * Here's a list of the known chunk types + */ + +/* + * Comments consist of a 4-byte length field followed by + * UTF-8 encoded text + * + * Comment: + * ChunkHeader header chunk header + * CARD32 length bytes in text + * LISTofCARD8 text UTF-8 encoded text + */ + +#define XCURSOR_COMMENT_TYPE 0xfffe0001 +#define XCURSOR_COMMENT_VERSION 1 +#define XCURSOR_COMMENT_HEADER_LEN (XCURSOR_CHUNK_HEADER_LEN + (1 *4)) +#define XCURSOR_COMMENT_COPYRIGHT 1 +#define XCURSOR_COMMENT_LICENSE 2 +#define XCURSOR_COMMENT_OTHER 3 +#define XCURSOR_COMMENT_MAX_LEN 0x100000 + +typedef struct _XcursorComment { + XcursorUInt version; + XcursorUInt comment_type; + char *comment; +} XcursorComment; + +/* + * Each cursor image occupies a separate image chunk. + * The length of the image header follows the chunk header + * so that future versions can extend the header without + * breaking older applications + * + * Image: + * ChunkHeader header chunk header + * CARD32 width actual width + * CARD32 height actual height + * CARD32 xhot hot spot x + * CARD32 yhot hot spot y + * CARD32 delay animation delay + * LISTofCARD32 pixels ARGB pixels + */ + +#define XCURSOR_IMAGE_TYPE 0xfffd0002 +#define XCURSOR_IMAGE_VERSION 1 +#define XCURSOR_IMAGE_HEADER_LEN (XCURSOR_CHUNK_HEADER_LEN + (5*4)) +#define XCURSOR_IMAGE_MAX_SIZE 0x7fff /* 32767x32767 max cursor size */ + +typedef struct _XcursorImage { + XcursorUInt version; /* version of the image data */ + XcursorDim size; /* nominal size for matching */ + XcursorDim width; /* actual width */ + XcursorDim height; /* actual height */ + XcursorDim xhot; /* hot spot x (must be inside image) */ + XcursorDim yhot; /* hot spot y (must be inside image) */ + XcursorUInt delay; /* animation delay to next frame (ms) */ + XcursorPixel *pixels; /* pointer to pixels */ +} XcursorImage; + +/* + * Other data structures exposed by the library API + */ +typedef struct _XcursorImages { + int nimage; /* number of images */ + XcursorImage **images; /* array of XcursorImage pointers */ + char *name; /* name used to load images */ +} XcursorImages; + +typedef struct _XcursorCursors { + Display *dpy; /* Display holding cursors */ + int ref; /* reference count */ + int ncursor; /* number of cursors */ + Cursor *cursors; /* array of cursors */ +} XcursorCursors; + +typedef struct _XcursorAnimate { + XcursorCursors *cursors; /* list of cursors to use */ + int sequence; /* which cursor is next */ +} XcursorAnimate; + +typedef struct _XcursorFile XcursorFile; + +struct _XcursorFile { + void *closure; + int (*read) (XcursorFile *file, unsigned char *buf, int len); + int (*write) (XcursorFile *file, unsigned char *buf, int len); + int (*seek) (XcursorFile *file, long offset, int whence); +}; + +typedef struct _XcursorComments { + int ncomment; /* number of comments */ + XcursorComment **comments; /* array of XcursorComment pointers */ +} XcursorComments; + +#define XCURSOR_CORE_THEME "core" + +_XFUNCPROTOBEGIN + +/* + * Manage Image objects + */ +XcursorImage * +XcursorImageCreate (int width, int height); + +void +XcursorImageDestroy (XcursorImage *image); + +/* + * Manage Images objects + */ +XcursorImages * +XcursorImagesCreate (int size); + +void +XcursorImagesDestroy (XcursorImages *images); + +void +XcursorImagesSetName (XcursorImages *images, const char *name); + +/* + * Manage Cursor objects + */ +XcursorCursors * +XcursorCursorsCreate (Display *dpy, int size); + +void +XcursorCursorsDestroy (XcursorCursors *cursors); + +/* + * Manage Animate objects + */ +XcursorAnimate * +XcursorAnimateCreate (XcursorCursors *cursors); + +void +XcursorAnimateDestroy (XcursorAnimate *animate); + +Cursor +XcursorAnimateNext (XcursorAnimate *animate); + +/* + * Manage Comment objects + */ +XcursorComment * +XcursorCommentCreate (XcursorUInt comment_type, int length); + +void +XcursorCommentDestroy (XcursorComment *comment); + +XcursorComments * +XcursorCommentsCreate (int size); + +void +XcursorCommentsDestroy (XcursorComments *comments); + +/* + * XcursorFile/Image APIs + */ +XcursorImage * +XcursorXcFileLoadImage (XcursorFile *file, int size); + +XcursorImages * +XcursorXcFileLoadImages (XcursorFile *file, int size); + +XcursorImages * +XcursorXcFileLoadAllImages (XcursorFile *file); + +XcursorBool +XcursorXcFileLoad (XcursorFile *file, + XcursorComments **commentsp, + XcursorImages **imagesp); + +XcursorBool +XcursorXcFileSave (XcursorFile *file, + const XcursorComments *comments, + const XcursorImages *images); + +/* + * FILE/Image APIs + */ +XcursorImage * +XcursorFileLoadImage (FILE *file, int size); + +XcursorImages * +XcursorFileLoadImages (FILE *file, int size); + +XcursorImages * +XcursorFileLoadAllImages (FILE *file); + +XcursorBool +XcursorFileLoad (FILE *file, + XcursorComments **commentsp, + XcursorImages **imagesp); + +XcursorBool +XcursorFileSaveImages (FILE *file, const XcursorImages *images); + +XcursorBool +XcursorFileSave (FILE * file, + const XcursorComments *comments, + const XcursorImages *images); + +/* + * Filename/Image APIs + */ +XcursorImage * +XcursorFilenameLoadImage (const char *filename, int size); + +XcursorImages * +XcursorFilenameLoadImages (const char *filename, int size); + +XcursorImages * +XcursorFilenameLoadAllImages (const char *filename); + +XcursorBool +XcursorFilenameLoad (const char *file, + XcursorComments **commentsp, + XcursorImages **imagesp); + +XcursorBool +XcursorFilenameSaveImages (const char *filename, const XcursorImages *images); + +XcursorBool +XcursorFilenameSave (const char *file, + const XcursorComments *comments, + const XcursorImages *images); + +/* + * Library/Image APIs + */ +XcursorImage * +XcursorLibraryLoadImage (const char *library, const char *theme, int size); + +XcursorImages * +XcursorLibraryLoadImages (const char *library, const char *theme, int size); + +/* + * Library/shape API + */ + +const char * +XcursorLibraryPath (void); + +int +XcursorLibraryShape (const char *library); + +/* + * Image/Cursor APIs + */ + +Cursor +XcursorImageLoadCursor (Display *dpy, const XcursorImage *image); + +XcursorCursors * +XcursorImagesLoadCursors (Display *dpy, const XcursorImages *images); + +Cursor +XcursorImagesLoadCursor (Display *dpy, const XcursorImages *images); + +/* + * Filename/Cursor APIs + */ +Cursor +XcursorFilenameLoadCursor (Display *dpy, const char *file); + +XcursorCursors * +XcursorFilenameLoadCursors (Display *dpy, const char *file); + +/* + * Library/Cursor APIs + */ +Cursor +XcursorLibraryLoadCursor (Display *dpy, const char *file); + +XcursorCursors * +XcursorLibraryLoadCursors (Display *dpy, const char *file); + +/* + * Shape/Image APIs + */ + +XcursorImage * +XcursorShapeLoadImage (unsigned int shape, const char *theme, int size); + +XcursorImages * +XcursorShapeLoadImages (unsigned int shape, const char *theme, int size); + +/* + * Shape/Cursor APIs + */ +Cursor +XcursorShapeLoadCursor (Display *dpy, unsigned int shape); + +XcursorCursors * +XcursorShapeLoadCursors (Display *dpy, unsigned int shape); + +/* + * This is the function called by Xlib when attempting to + * load cursors from XCreateGlyphCursor. The interface must + * not change as Xlib loads 'libXcursor.so' instead of + * a specific major version + */ +Cursor +XcursorTryShapeCursor (Display *dpy, + Font source_font, + Font mask_font, + unsigned int source_char, + unsigned int mask_char, + XColor _Xconst *foreground, + XColor _Xconst *background); + +void +XcursorNoticeCreateBitmap (Display *dpy, + Pixmap pid, + unsigned int width, + unsigned int height); + +void +XcursorNoticePutBitmap (Display *dpy, + Drawable draw, + XImage *image); + +Cursor +XcursorTryShapeBitmapCursor (Display *dpy, + Pixmap source, + Pixmap mask, + XColor *foreground, + XColor *background, + unsigned int x, + unsigned int y); + +#define XCURSOR_BITMAP_HASH_SIZE 16 + +void +XcursorImageHash (XImage *image, + unsigned char hash[XCURSOR_BITMAP_HASH_SIZE]); + +/* + * Display information APIs + */ +XcursorBool +XcursorSupportsARGB (Display *dpy); + +XcursorBool +XcursorSupportsAnim (Display *dpy); + +XcursorBool +XcursorSetDefaultSize (Display *dpy, int size); + +int +XcursorGetDefaultSize (Display *dpy); + +XcursorBool +XcursorSetTheme (Display *dpy, const char *theme); + +char * +XcursorGetTheme (Display *dpy); + +XcursorBool +XcursorGetThemeCore (Display *dpy); + +XcursorBool +XcursorSetThemeCore (Display *dpy, XcursorBool theme_core); + +_XFUNCPROTOEND + +#endif diff --git a/thirdparty/linuxbsd_headers/X11/Xdefs.h b/thirdparty/linuxbsd_headers/X11/Xdefs.h new file mode 100644 index 0000000000..f58946dfba --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/Xdefs.h @@ -0,0 +1,108 @@ +/*********************************************************** + +Copyright (c) 1999 The XFree86 Project Inc. + +All Rights Reserved. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The XFree86 Project +Inc. shall not be used in advertising or otherwise to promote the +sale, use or other dealings in this Software without prior written +authorization from The XFree86 Project Inc.. + +*/ + +/** + ** Types definitions shared between server and clients + **/ + +#ifndef _XDEFS_H +#define _XDEFS_H + +#ifdef _XSERVER64 +#include <X11/Xmd.h> +#endif + +#ifndef _XTYPEDEF_ATOM +# define _XTYPEDEF_ATOM +# ifndef _XSERVER64 +typedef unsigned long Atom; +# else +typedef CARD32 Atom; +# endif +#endif + +#ifndef Bool +# ifndef _XTYPEDEF_BOOL +# define _XTYPEDEF_BOOL +typedef int Bool; +# endif +#endif + +#ifndef _XTYPEDEF_POINTER +# define _XTYPEDEF_POINTER +typedef void *pointer; +#endif + +#ifndef _XTYPEDEF_CLIENTPTR +typedef struct _Client *ClientPtr; +# define _XTYPEDEF_CLIENTPTR +#endif + +#ifndef _XTYPEDEF_XID +# define _XTYPEDEF_XID +# ifndef _XSERVER64 +typedef unsigned long XID; +# else +typedef CARD32 XID; +# endif +#endif + +#ifndef _XTYPEDEF_MASK +# define _XTYPEDEF_MASK +# ifndef _XSERVER64 +typedef unsigned long Mask; +# else +typedef CARD32 Mask; +# endif +#endif + +#ifndef _XTYPEDEF_FONTPTR +# define _XTYPEDEF_FONTPTR +typedef struct _Font *FontPtr; /* also in fonts/include/font.h */ +#endif + +#ifndef _XTYPEDEF_FONT +# define _XTYPEDEF_FONT +typedef XID Font; +#endif + +#ifndef _XTYPEDEF_FSID +# ifndef _XSERVER64 +typedef unsigned long FSID; +# else +typedef CARD32 FSID; +# endif +#endif + +typedef FSID AccContext; + +/* OS independent time value + XXX Should probably go in Xos.h */ +typedef struct timeval **OSTimePtr; + + +typedef void (* BlockHandlerProcPtr)(void * /* blockData */, + OSTimePtr /* pTimeout */, + void * /* pReadmask */); + +#endif diff --git a/thirdparty/linuxbsd_headers/X11/Xfuncproto.h b/thirdparty/linuxbsd_headers/X11/Xfuncproto.h new file mode 100644 index 0000000000..f689073602 --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/Xfuncproto.h @@ -0,0 +1,229 @@ +/* + * +Copyright 1989, 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + */ + +/* Definitions to make function prototypes manageable */ + +#ifndef _XFUNCPROTO_H_ +#define _XFUNCPROTO_H_ + +#ifndef NeedFunctionPrototypes +#define NeedFunctionPrototypes 1 +#endif /* NeedFunctionPrototypes */ + +#ifndef NeedVarargsPrototypes +#define NeedVarargsPrototypes 1 +#endif /* NeedVarargsPrototypes */ + +#if NeedFunctionPrototypes + +#ifndef NeedNestedPrototypes +#define NeedNestedPrototypes 1 +#endif /* NeedNestedPrototypes */ + +#ifndef _Xconst +#define _Xconst const +#endif /* _Xconst */ + +/* Function prototype configuration (see configure for more info) */ +#if !defined(NARROWPROTO) && \ + (defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) +#define NARROWPROTO +#endif +#ifndef FUNCPROTO +#define FUNCPROTO 15 +#endif + +#ifndef NeedWidePrototypes +#ifdef NARROWPROTO +#define NeedWidePrototypes 0 +#else +#define NeedWidePrototypes 1 /* default to make interropt. easier */ +#endif +#endif /* NeedWidePrototypes */ + +#endif /* NeedFunctionPrototypes */ + +#ifndef _XFUNCPROTOBEGIN +#if defined(__cplusplus) || defined(c_plusplus) /* for C++ V2.0 */ +#define _XFUNCPROTOBEGIN extern "C" { /* do not leave open across includes */ +#define _XFUNCPROTOEND } +#else +#define _XFUNCPROTOBEGIN +#define _XFUNCPROTOEND +#endif +#endif /* _XFUNCPROTOBEGIN */ + +/* http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute */ +#ifndef __has_attribute +# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ +#endif +#ifndef __has_feature +# define __has_feature(x) 0 /* Compatibility with non-clang compilers. */ +#endif +#ifndef __has_extension +# define __has_extension(x) 0 /* Compatibility with non-clang compilers. */ +#endif + +/* Added in X11R6.9, so available in any version of modular xproto */ +#if __has_attribute(__sentinel__) || (defined(__GNUC__) && (__GNUC__ >= 4)) +# define _X_SENTINEL(x) __attribute__ ((__sentinel__(x))) +#else +# define _X_SENTINEL(x) +#endif /* GNUC >= 4 */ + +/* Added in X11R6.9, so available in any version of modular xproto */ +#if (__has_attribute(visibility) || (defined(__GNUC__) && (__GNUC__ >= 4))) \ + && !defined(__CYGWIN__) && !defined(__MINGW32__) +# define _X_EXPORT __attribute__((visibility("default"))) +# define _X_HIDDEN __attribute__((visibility("hidden"))) +# define _X_INTERNAL __attribute__((visibility("internal"))) +#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) +# define _X_EXPORT __global +# define _X_HIDDEN __hidden +# define _X_INTERNAL __hidden +#else /* not gcc >= 4 and not Sun Studio >= 8 */ +# define _X_EXPORT +# define _X_HIDDEN +# define _X_INTERNAL +#endif /* GNUC >= 4 */ + +/* Branch prediction hints for individual conditionals */ +/* requires xproto >= 7.0.9 */ +#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 303) +# define _X_LIKELY(x) __builtin_expect(!!(x), 1) +# define _X_UNLIKELY(x) __builtin_expect(!!(x), 0) +#else /* not gcc >= 3.3 */ +# define _X_LIKELY(x) (x) +# define _X_UNLIKELY(x) (x) +#endif + +/* Bulk branch prediction hints via marking error path functions as "cold" */ +/* requires xproto >= 7.0.25 */ +#if __has_attribute(__cold__) || \ + (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 403)) /* 4.3+ */ +# define _X_COLD __attribute__((__cold__)) +#else +# define _X_COLD /* nothing */ +#endif + +/* Added in X11R6.9, so available in any version of modular xproto */ +#if __has_attribute(deprecated) \ + || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 301)) \ + || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5130)) +# define _X_DEPRECATED __attribute__((deprecated)) +#else /* not gcc >= 3.1 */ +# define _X_DEPRECATED +#endif + +/* requires xproto >= 7.0.30 */ +#if __has_extension(attribute_deprecated_with_message) || \ + (defined(__GNUC__) && ((__GNUC__ >= 5) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)))) +# define _X_DEPRECATED_MSG(_msg) __attribute__((deprecated(_msg))) +#else +# define _X_DEPRECATED_MSG(_msg) _X_DEPRECATED +#endif + +/* requires xproto >= 7.0.17 */ +#if __has_attribute(noreturn) \ + || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \ + || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) +# define _X_NORETURN __attribute((noreturn)) +#else +# define _X_NORETURN +#endif /* GNUC */ + +/* Added in X11R6.9, so available in any version of modular xproto */ +#if __has_attribute(__format__) \ + || defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203) +# define _X_ATTRIBUTE_PRINTF(x,y) __attribute__((__format__(__printf__,x,y))) +#else /* not gcc >= 2.3 */ +# define _X_ATTRIBUTE_PRINTF(x,y) +#endif + +/* requires xproto >= 7.0.22 - since this uses either gcc or C99 variable + argument macros, must be only used inside #ifdef _X_NONNULL guards, as + many legacy X clients are compiled in C89 mode still. */ +#if __has_attribute(nonnull) \ + && defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L) /* C99 */ +#define _X_NONNULL(...) __attribute__((nonnull(__VA_ARGS__))) +#elif __has_attribute(nonnull) \ + || defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 303) +#define _X_NONNULL(args...) __attribute__((nonnull(args))) +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L) /* C99 */ +#define _X_NONNULL(...) /* */ +#endif + +/* requires xproto >= 7.0.22 */ +#if __has_attribute(__unused__) \ + || defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205) +#define _X_UNUSED __attribute__((__unused__)) +#else +#define _X_UNUSED /* */ +#endif + +/* C99 keyword "inline" or equivalent extensions in pre-C99 compilers */ +/* requires xproto >= 7.0.9 + (introduced in 7.0.8 but didn't support all compilers until 7.0.9) */ +#if defined(inline) /* assume autoconf set it correctly */ || \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L)) /* C99 */ || \ + (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)) +# define _X_INLINE inline +#elif defined(__GNUC__) && !defined(__STRICT_ANSI__) /* gcc w/C89+extensions */ +# define _X_INLINE __inline__ +#else +# define _X_INLINE +#endif + +/* C99 keyword "restrict" or equivalent extensions in pre-C99 compilers */ +/* requires xproto >= 7.0.21 */ +#ifndef _X_RESTRICT_KYWD +# if defined(restrict) /* assume autoconf set it correctly */ || \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L) /* C99 */ \ + && !defined(__cplusplus)) /* Workaround g++ issue on Solaris */ +# define _X_RESTRICT_KYWD restrict +# elif defined(__GNUC__) && !defined(__STRICT_ANSI__) /* gcc w/C89+extensions */ +# define _X_RESTRICT_KYWD __restrict__ +# else +# define _X_RESTRICT_KYWD +# endif +#endif + +/* requires xproto >= 7.0.30 */ +#if __has_attribute(no_sanitize_thread) +# define _X_NOTSAN __attribute__((no_sanitize_thread)) +#else +# define _X_NOTSAN +#endif + +/* Mark a char array/pointer as not containing a NUL-terminated string */ +/* requires xproto >= 7.0.33 */ +#if __has_attribute(nonstring) +# define _X_NONSTRING __attribute__((nonstring)) +#else +# define _X_NONSTRING +#endif + +#endif /* _XFUNCPROTO_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/Xfuncs.h b/thirdparty/linuxbsd_headers/X11/Xfuncs.h new file mode 100644 index 0000000000..b23c283107 --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/Xfuncs.h @@ -0,0 +1,69 @@ +/* + * +Copyright 1990, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + */ + +#ifndef _XFUNCS_H_ +# define _XFUNCS_H_ + +# include <X11/Xosdefs.h> + +/* the old Xfuncs.h, for pre-R6 */ +# if !(defined(XFree86LOADER) && defined(IN_MODULE)) + +# ifdef X_USEBFUNCS +void bcopy(); +void bzero(); +int bcmp(); +# else +# if defined(SYSV) && !defined(__SCO__) && !defined(__sun) && !defined(__UNIXWARE__) && !defined(_AIX) +# include <memory.h> +void bcopy(); +# define bzero(b,len) memset(b, 0, len) +# define bcmp(b1,b2,len) memcmp(b1, b2, len) +# else +# include <string.h> +# if defined(__SCO__) || defined(__sun) || defined(__UNIXWARE__) || defined(__CYGWIN__) || defined(_AIX) || defined(__APPLE__) +# include <strings.h> +# endif +# define _XFUNCS_H_INCLUDED_STRING_H +# endif +# endif /* X_USEBFUNCS */ + +/* the new Xfuncs.h */ + +/* the ANSI C way */ +# ifndef _XFUNCS_H_INCLUDED_STRING_H +# include <string.h> +# endif +# undef bzero +# define bzero(b,len) memset(b,0,len) + +# if defined WIN32 && defined __MINGW32__ +# define bcopy(b1,b2,len) memmove(b2, b1, (size_t)(len)) +# endif + +# endif /* !(defined(XFree86LOADER) && defined(IN_MODULE)) */ + +#endif /* _XFUNCS_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/Xlib.h b/thirdparty/linuxbsd_headers/X11/Xlib.h new file mode 100644 index 0000000000..f62fb4707f --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/Xlib.h @@ -0,0 +1,4025 @@ +/* + +Copyright 1985, 1986, 1987, 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + + +/* + * Xlib.h - Header definition and support file for the C subroutine + * interface library (Xlib) to the X Window System Protocol (V11). + * Structures and symbols starting with "_" are private to the library. + */ +#ifndef _X11_XLIB_H_ +#define _X11_XLIB_H_ + +#define XlibSpecificationRelease 6 + +#include <sys/types.h> + +#if defined(__SCO__) || defined(__UNIXWARE__) +#include <stdint.h> +#endif + +#include <X11/X.h> + +/* applications should not depend on these two headers being included! */ +#include <X11/Xfuncproto.h> +#include <X11/Xosdefs.h> + +#ifndef X_WCHAR +#include <stddef.h> +#else +#ifdef __UNIXOS2__ +#include <stdlib.h> +#else +/* replace this with #include or typedef appropriate for your system */ +typedef unsigned long wchar_t; +#endif +#endif + + +extern int +_Xmblen( + char *str, + int len + ); + +/* API mentioning "UTF8" or "utf8" is an XFree86 extension, introduced in + November 2000. Its presence is indicated through the following macro. */ +#define X_HAVE_UTF8_STRING 1 + +/* The Xlib structs are full of implicit padding to properly align members. + We can't clean that up without breaking ABI, so tell clang not to bother + complaining about it. */ +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +typedef char *XPointer; + +#define Bool int +#define Status int +#define True 1 +#define False 0 + +#define QueuedAlready 0 +#define QueuedAfterReading 1 +#define QueuedAfterFlush 2 + +#define ConnectionNumber(dpy) (((_XPrivDisplay)(dpy))->fd) +#define RootWindow(dpy, scr) (ScreenOfDisplay(dpy,scr)->root) +#define DefaultScreen(dpy) (((_XPrivDisplay)(dpy))->default_screen) +#define DefaultRootWindow(dpy) (ScreenOfDisplay(dpy,DefaultScreen(dpy))->root) +#define DefaultVisual(dpy, scr) (ScreenOfDisplay(dpy,scr)->root_visual) +#define DefaultGC(dpy, scr) (ScreenOfDisplay(dpy,scr)->default_gc) +#define BlackPixel(dpy, scr) (ScreenOfDisplay(dpy,scr)->black_pixel) +#define WhitePixel(dpy, scr) (ScreenOfDisplay(dpy,scr)->white_pixel) +#define AllPlanes ((unsigned long)~0L) +#define QLength(dpy) (((_XPrivDisplay)(dpy))->qlen) +#define DisplayWidth(dpy, scr) (ScreenOfDisplay(dpy,scr)->width) +#define DisplayHeight(dpy, scr) (ScreenOfDisplay(dpy,scr)->height) +#define DisplayWidthMM(dpy, scr)(ScreenOfDisplay(dpy,scr)->mwidth) +#define DisplayHeightMM(dpy, scr)(ScreenOfDisplay(dpy,scr)->mheight) +#define DisplayPlanes(dpy, scr) (ScreenOfDisplay(dpy,scr)->root_depth) +#define DisplayCells(dpy, scr) (DefaultVisual(dpy,scr)->map_entries) +#define ScreenCount(dpy) (((_XPrivDisplay)(dpy))->nscreens) +#define ServerVendor(dpy) (((_XPrivDisplay)(dpy))->vendor) +#define ProtocolVersion(dpy) (((_XPrivDisplay)(dpy))->proto_major_version) +#define ProtocolRevision(dpy) (((_XPrivDisplay)(dpy))->proto_minor_version) +#define VendorRelease(dpy) (((_XPrivDisplay)(dpy))->release) +#define DisplayString(dpy) (((_XPrivDisplay)(dpy))->display_name) +#define DefaultDepth(dpy, scr) (ScreenOfDisplay(dpy,scr)->root_depth) +#define DefaultColormap(dpy, scr)(ScreenOfDisplay(dpy,scr)->cmap) +#define BitmapUnit(dpy) (((_XPrivDisplay)(dpy))->bitmap_unit) +#define BitmapBitOrder(dpy) (((_XPrivDisplay)(dpy))->bitmap_bit_order) +#define BitmapPad(dpy) (((_XPrivDisplay)(dpy))->bitmap_pad) +#define ImageByteOrder(dpy) (((_XPrivDisplay)(dpy))->byte_order) +#define NextRequest(dpy) (((_XPrivDisplay)(dpy))->request + 1) +#define LastKnownRequestProcessed(dpy) (((_XPrivDisplay)(dpy))->last_request_read) + +/* macros for screen oriented applications (toolkit) */ +#define ScreenOfDisplay(dpy, scr)(&((_XPrivDisplay)(dpy))->screens[scr]) +#define DefaultScreenOfDisplay(dpy) ScreenOfDisplay(dpy,DefaultScreen(dpy)) +#define DisplayOfScreen(s) ((s)->display) +#define RootWindowOfScreen(s) ((s)->root) +#define BlackPixelOfScreen(s) ((s)->black_pixel) +#define WhitePixelOfScreen(s) ((s)->white_pixel) +#define DefaultColormapOfScreen(s)((s)->cmap) +#define DefaultDepthOfScreen(s) ((s)->root_depth) +#define DefaultGCOfScreen(s) ((s)->default_gc) +#define DefaultVisualOfScreen(s)((s)->root_visual) +#define WidthOfScreen(s) ((s)->width) +#define HeightOfScreen(s) ((s)->height) +#define WidthMMOfScreen(s) ((s)->mwidth) +#define HeightMMOfScreen(s) ((s)->mheight) +#define PlanesOfScreen(s) ((s)->root_depth) +#define CellsOfScreen(s) (DefaultVisualOfScreen((s))->map_entries) +#define MinCmapsOfScreen(s) ((s)->min_maps) +#define MaxCmapsOfScreen(s) ((s)->max_maps) +#define DoesSaveUnders(s) ((s)->save_unders) +#define DoesBackingStore(s) ((s)->backing_store) +#define EventMaskOfScreen(s) ((s)->root_input_mask) + +/* + * Extensions need a way to hang private data on some structures. + */ +typedef struct _XExtData { + int number; /* number returned by XRegisterExtension */ + struct _XExtData *next; /* next item on list of data for structure */ + int (*free_private)( /* called to free private storage */ + struct _XExtData *extension + ); + XPointer private_data; /* data private to this extension. */ +} XExtData; + +/* + * This file contains structures used by the extension mechanism. + */ +typedef struct { /* public to extension, cannot be changed */ + int extension; /* extension number */ + int major_opcode; /* major op-code assigned by server */ + int first_event; /* first event number for the extension */ + int first_error; /* first error number for the extension */ +} XExtCodes; + +/* + * Data structure for retrieving info about pixmap formats. + */ + +typedef struct { + int depth; + int bits_per_pixel; + int scanline_pad; +} XPixmapFormatValues; + + +/* + * Data structure for setting graphics context. + */ +typedef struct { + int function; /* logical operation */ + unsigned long plane_mask;/* plane mask */ + unsigned long foreground;/* foreground pixel */ + unsigned long background;/* background pixel */ + int line_width; /* line width */ + int line_style; /* LineSolid, LineOnOffDash, LineDoubleDash */ + int cap_style; /* CapNotLast, CapButt, + CapRound, CapProjecting */ + int join_style; /* JoinMiter, JoinRound, JoinBevel */ + int fill_style; /* FillSolid, FillTiled, + FillStippled, FillOpaqueStippled */ + int fill_rule; /* EvenOddRule, WindingRule */ + int arc_mode; /* ArcChord, ArcPieSlice */ + Pixmap tile; /* tile pixmap for tiling operations */ + Pixmap stipple; /* stipple 1 plane pixmap for stippling */ + int ts_x_origin; /* offset for tile or stipple operations */ + int ts_y_origin; + Font font; /* default text font for text operations */ + int subwindow_mode; /* ClipByChildren, IncludeInferiors */ + Bool graphics_exposures;/* boolean, should exposures be generated */ + int clip_x_origin; /* origin for clipping */ + int clip_y_origin; + Pixmap clip_mask; /* bitmap clipping; other calls for rects */ + int dash_offset; /* patterned/dashed line information */ + char dashes; +} XGCValues; + +/* + * Graphics context. The contents of this structure are implementation + * dependent. A GC should be treated as opaque by application code. + */ + +typedef struct _XGC +#ifdef XLIB_ILLEGAL_ACCESS +{ + XExtData *ext_data; /* hook for extension to hang data */ + GContext gid; /* protocol ID for graphics context */ + /* there is more to this structure, but it is private to Xlib */ +} +#endif +*GC; + +/* + * Visual structure; contains information about colormapping possible. + */ +typedef struct { + XExtData *ext_data; /* hook for extension to hang data */ + VisualID visualid; /* visual id of this visual */ +#if defined(__cplusplus) || defined(c_plusplus) + int c_class; /* C++ class of screen (monochrome, etc.) */ +#else + int class; /* class of screen (monochrome, etc.) */ +#endif + unsigned long red_mask, green_mask, blue_mask; /* mask values */ + int bits_per_rgb; /* log base 2 of distinct color values */ + int map_entries; /* color map entries */ +} Visual; + +/* + * Depth structure; contains information for each possible depth. + */ +typedef struct { + int depth; /* this depth (Z) of the depth */ + int nvisuals; /* number of Visual types at this depth */ + Visual *visuals; /* list of visuals possible at this depth */ +} Depth; + +/* + * Information about the screen. The contents of this structure are + * implementation dependent. A Screen should be treated as opaque + * by application code. + */ + +struct _XDisplay; /* Forward declare before use for C++ */ + +typedef struct { + XExtData *ext_data; /* hook for extension to hang data */ + struct _XDisplay *display;/* back pointer to display structure */ + Window root; /* Root window id. */ + int width, height; /* width and height of screen */ + int mwidth, mheight; /* width and height of in millimeters */ + int ndepths; /* number of depths possible */ + Depth *depths; /* list of allowable depths on the screen */ + int root_depth; /* bits per pixel */ + Visual *root_visual; /* root visual */ + GC default_gc; /* GC for the root root visual */ + Colormap cmap; /* default color map */ + unsigned long white_pixel; + unsigned long black_pixel; /* White and Black pixel values */ + int max_maps, min_maps; /* max and min color maps */ + int backing_store; /* Never, WhenMapped, Always */ + Bool save_unders; + long root_input_mask; /* initial root input mask */ +} Screen; + +/* + * Format structure; describes ZFormat data the screen will understand. + */ +typedef struct { + XExtData *ext_data; /* hook for extension to hang data */ + int depth; /* depth of this image format */ + int bits_per_pixel; /* bits/pixel at this depth */ + int scanline_pad; /* scanline must padded to this multiple */ +} ScreenFormat; + +/* + * Data structure for setting window attributes. + */ +typedef struct { + Pixmap background_pixmap; /* background or None or ParentRelative */ + unsigned long background_pixel; /* background pixel */ + Pixmap border_pixmap; /* border of the window */ + unsigned long border_pixel; /* border pixel value */ + int bit_gravity; /* one of bit gravity values */ + int win_gravity; /* one of the window gravity values */ + int backing_store; /* NotUseful, WhenMapped, Always */ + unsigned long backing_planes;/* planes to be preserved if possible */ + unsigned long backing_pixel;/* value to use in restoring planes */ + Bool save_under; /* should bits under be saved? (popups) */ + long event_mask; /* set of events that should be saved */ + long do_not_propagate_mask; /* set of events that should not propagate */ + Bool override_redirect; /* boolean value for override-redirect */ + Colormap colormap; /* color map to be associated with window */ + Cursor cursor; /* cursor to be displayed (or None) */ +} XSetWindowAttributes; + +typedef struct { + int x, y; /* location of window */ + int width, height; /* width and height of window */ + int border_width; /* border width of window */ + int depth; /* depth of window */ + Visual *visual; /* the associated visual structure */ + Window root; /* root of screen containing window */ +#if defined(__cplusplus) || defined(c_plusplus) + int c_class; /* C++ InputOutput, InputOnly*/ +#else + int class; /* InputOutput, InputOnly*/ +#endif + int bit_gravity; /* one of bit gravity values */ + int win_gravity; /* one of the window gravity values */ + int backing_store; /* NotUseful, WhenMapped, Always */ + unsigned long backing_planes;/* planes to be preserved if possible */ + unsigned long backing_pixel;/* value to be used when restoring planes */ + Bool save_under; /* boolean, should bits under be saved? */ + Colormap colormap; /* color map to be associated with window */ + Bool map_installed; /* boolean, is color map currently installed*/ + int map_state; /* IsUnmapped, IsUnviewable, IsViewable */ + long all_event_masks; /* set of events all people have interest in*/ + long your_event_mask; /* my event mask */ + long do_not_propagate_mask; /* set of events that should not propagate */ + Bool override_redirect; /* boolean value for override-redirect */ + Screen *screen; /* back pointer to correct screen */ +} XWindowAttributes; + +/* + * Data structure for host setting; getting routines. + * + */ + +typedef struct { + int family; /* for example FamilyInternet */ + int length; /* length of address, in bytes */ + char *address; /* pointer to where to find the bytes */ +} XHostAddress; + +/* + * Data structure for ServerFamilyInterpreted addresses in host routines + */ +typedef struct { + int typelength; /* length of type string, in bytes */ + int valuelength; /* length of value string, in bytes */ + char *type; /* pointer to where to find the type string */ + char *value; /* pointer to where to find the address */ +} XServerInterpretedAddress; + +/* + * Data structure for "image" data, used by image manipulation routines. + */ +typedef struct _XImage { + int width, height; /* size of image */ + int xoffset; /* number of pixels offset in X direction */ + int format; /* XYBitmap, XYPixmap, ZPixmap */ + char *data; /* pointer to image data */ + int byte_order; /* data byte order, LSBFirst, MSBFirst */ + int bitmap_unit; /* quant. of scanline 8, 16, 32 */ + int bitmap_bit_order; /* LSBFirst, MSBFirst */ + int bitmap_pad; /* 8, 16, 32 either XY or ZPixmap */ + int depth; /* depth of image */ + int bytes_per_line; /* accelerator to next line */ + int bits_per_pixel; /* bits per pixel (ZPixmap) */ + unsigned long red_mask; /* bits in z arrangement */ + unsigned long green_mask; + unsigned long blue_mask; + XPointer obdata; /* hook for the object routines to hang on */ + struct funcs { /* image manipulation routines */ + struct _XImage *(*create_image)( + struct _XDisplay* /* display */, + Visual* /* visual */, + unsigned int /* depth */, + int /* format */, + int /* offset */, + char* /* data */, + unsigned int /* width */, + unsigned int /* height */, + int /* bitmap_pad */, + int /* bytes_per_line */); + int (*destroy_image) (struct _XImage *); + unsigned long (*get_pixel) (struct _XImage *, int, int); + int (*put_pixel) (struct _XImage *, int, int, unsigned long); + struct _XImage *(*sub_image)(struct _XImage *, int, int, unsigned int, unsigned int); + int (*add_pixel) (struct _XImage *, long); + } f; +} XImage; + +/* + * Data structure for XReconfigureWindow + */ +typedef struct { + int x, y; + int width, height; + int border_width; + Window sibling; + int stack_mode; +} XWindowChanges; + +/* + * Data structure used by color operations + */ +typedef struct { + unsigned long pixel; + unsigned short red, green, blue; + char flags; /* do_red, do_green, do_blue */ + char pad; +} XColor; + +/* + * Data structures for graphics operations. On most machines, these are + * congruent with the wire protocol structures, so reformatting the data + * can be avoided on these architectures. + */ +typedef struct { + short x1, y1, x2, y2; +} XSegment; + +typedef struct { + short x, y; +} XPoint; + +typedef struct { + short x, y; + unsigned short width, height; +} XRectangle; + +typedef struct { + short x, y; + unsigned short width, height; + short angle1, angle2; +} XArc; + + +/* Data structure for XChangeKeyboardControl */ + +typedef struct { + int key_click_percent; + int bell_percent; + int bell_pitch; + int bell_duration; + int led; + int led_mode; + int key; + int auto_repeat_mode; /* On, Off, Default */ +} XKeyboardControl; + +/* Data structure for XGetKeyboardControl */ + +typedef struct { + int key_click_percent; + int bell_percent; + unsigned int bell_pitch, bell_duration; + unsigned long led_mask; + int global_auto_repeat; + char auto_repeats[32]; +} XKeyboardState; + +/* Data structure for XGetMotionEvents. */ + +typedef struct { + Time time; + short x, y; +} XTimeCoord; + +/* Data structure for X{Set,Get}ModifierMapping */ + +typedef struct { + int max_keypermod; /* The server's max # of keys per modifier */ + KeyCode *modifiermap; /* An 8 by max_keypermod array of modifiers */ +} XModifierKeymap; + + +/* + * Display datatype maintaining display specific data. + * The contents of this structure are implementation dependent. + * A Display should be treated as opaque by application code. + */ +#ifndef XLIB_ILLEGAL_ACCESS +typedef struct _XDisplay Display; +#endif + +struct _XPrivate; /* Forward declare before use for C++ */ +struct _XrmHashBucketRec; + +typedef struct +#ifdef XLIB_ILLEGAL_ACCESS +_XDisplay +#endif +{ + XExtData *ext_data; /* hook for extension to hang data */ + struct _XPrivate *private1; + int fd; /* Network socket. */ + int private2; + int proto_major_version;/* major version of server's X protocol */ + int proto_minor_version;/* minor version of servers X protocol */ + char *vendor; /* vendor of the server hardware */ + XID private3; + XID private4; + XID private5; + int private6; + XID (*resource_alloc)( /* allocator function */ + struct _XDisplay* + ); + int byte_order; /* screen byte order, LSBFirst, MSBFirst */ + int bitmap_unit; /* padding and data requirements */ + int bitmap_pad; /* padding requirements on bitmaps */ + int bitmap_bit_order; /* LeastSignificant or MostSignificant */ + int nformats; /* number of pixmap formats in list */ + ScreenFormat *pixmap_format; /* pixmap format list */ + int private8; + int release; /* release of the server */ + struct _XPrivate *private9, *private10; + int qlen; /* Length of input event queue */ + unsigned long last_request_read; /* seq number of last event read */ + unsigned long request; /* sequence number of last request. */ + XPointer private11; + XPointer private12; + XPointer private13; + XPointer private14; + unsigned max_request_size; /* maximum number 32 bit words in request*/ + struct _XrmHashBucketRec *db; + int (*private15)( + struct _XDisplay* + ); + char *display_name; /* "host:display" string used on this connect*/ + int default_screen; /* default screen for operations */ + int nscreens; /* number of screens on this server*/ + Screen *screens; /* pointer to list of screens */ + unsigned long motion_buffer; /* size of motion buffer */ + unsigned long private16; + int min_keycode; /* minimum defined keycode */ + int max_keycode; /* maximum defined keycode */ + XPointer private17; + XPointer private18; + int private19; + char *xdefaults; /* contents of defaults from server */ + /* there is more to this structure, but it is private to Xlib */ +} +#ifdef XLIB_ILLEGAL_ACCESS +Display, +#endif +*_XPrivDisplay; + +#undef _XEVENT_ +#ifndef _XEVENT_ +/* + * Definitions of specific events. + */ +typedef struct { + int type; /* of event */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* "event" window it is reported relative to */ + Window root; /* root window that the event occurred on */ + Window subwindow; /* child window */ + Time time; /* milliseconds */ + int x, y; /* pointer x, y coordinates in event window */ + int x_root, y_root; /* coordinates relative to root */ + unsigned int state; /* key or button mask */ + unsigned int keycode; /* detail */ + Bool same_screen; /* same screen flag */ +} XKeyEvent; +typedef XKeyEvent XKeyPressedEvent; +typedef XKeyEvent XKeyReleasedEvent; + +typedef struct { + int type; /* of event */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* "event" window it is reported relative to */ + Window root; /* root window that the event occurred on */ + Window subwindow; /* child window */ + Time time; /* milliseconds */ + int x, y; /* pointer x, y coordinates in event window */ + int x_root, y_root; /* coordinates relative to root */ + unsigned int state; /* key or button mask */ + unsigned int button; /* detail */ + Bool same_screen; /* same screen flag */ +} XButtonEvent; +typedef XButtonEvent XButtonPressedEvent; +typedef XButtonEvent XButtonReleasedEvent; + +typedef struct { + int type; /* of event */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* "event" window reported relative to */ + Window root; /* root window that the event occurred on */ + Window subwindow; /* child window */ + Time time; /* milliseconds */ + int x, y; /* pointer x, y coordinates in event window */ + int x_root, y_root; /* coordinates relative to root */ + unsigned int state; /* key or button mask */ + char is_hint; /* detail */ + Bool same_screen; /* same screen flag */ +} XMotionEvent; +typedef XMotionEvent XPointerMovedEvent; + +typedef struct { + int type; /* of event */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* "event" window reported relative to */ + Window root; /* root window that the event occurred on */ + Window subwindow; /* child window */ + Time time; /* milliseconds */ + int x, y; /* pointer x, y coordinates in event window */ + int x_root, y_root; /* coordinates relative to root */ + int mode; /* NotifyNormal, NotifyGrab, NotifyUngrab */ + int detail; + /* + * NotifyAncestor, NotifyVirtual, NotifyInferior, + * NotifyNonlinear,NotifyNonlinearVirtual + */ + Bool same_screen; /* same screen flag */ + Bool focus; /* boolean focus */ + unsigned int state; /* key or button mask */ +} XCrossingEvent; +typedef XCrossingEvent XEnterWindowEvent; +typedef XCrossingEvent XLeaveWindowEvent; + +typedef struct { + int type; /* FocusIn or FocusOut */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window of event */ + int mode; /* NotifyNormal, NotifyWhileGrabbed, + NotifyGrab, NotifyUngrab */ + int detail; + /* + * NotifyAncestor, NotifyVirtual, NotifyInferior, + * NotifyNonlinear,NotifyNonlinearVirtual, NotifyPointer, + * NotifyPointerRoot, NotifyDetailNone + */ +} XFocusChangeEvent; +typedef XFocusChangeEvent XFocusInEvent; +typedef XFocusChangeEvent XFocusOutEvent; + +/* generated on EnterWindow and FocusIn when KeyMapState selected */ +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; + char key_vector[32]; +} XKeymapEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; + int x, y; + int width, height; + int count; /* if non-zero, at least this many more */ +} XExposeEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Drawable drawable; + int x, y; + int width, height; + int count; /* if non-zero, at least this many more */ + int major_code; /* core is CopyArea or CopyPlane */ + int minor_code; /* not defined in the core */ +} XGraphicsExposeEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Drawable drawable; + int major_code; /* core is CopyArea or CopyPlane */ + int minor_code; /* not defined in the core */ +} XNoExposeEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; + int state; /* Visibility state */ +} XVisibilityEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window parent; /* parent of the window */ + Window window; /* window id of window created */ + int x, y; /* window location */ + int width, height; /* size of window */ + int border_width; /* border width */ + Bool override_redirect; /* creation should be overridden */ +} XCreateWindowEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window event; + Window window; +} XDestroyWindowEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window event; + Window window; + Bool from_configure; +} XUnmapEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window event; + Window window; + Bool override_redirect; /* boolean, is override set... */ +} XMapEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window parent; + Window window; +} XMapRequestEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window event; + Window window; + Window parent; + int x, y; + Bool override_redirect; +} XReparentEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window event; + Window window; + int x, y; + int width, height; + int border_width; + Window above; + Bool override_redirect; +} XConfigureEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window event; + Window window; + int x, y; +} XGravityEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; + int width, height; +} XResizeRequestEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window parent; + Window window; + int x, y; + int width, height; + int border_width; + Window above; + int detail; /* Above, Below, TopIf, BottomIf, Opposite */ + unsigned long value_mask; +} XConfigureRequestEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window event; + Window window; + int place; /* PlaceOnTop, PlaceOnBottom */ +} XCirculateEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window parent; + Window window; + int place; /* PlaceOnTop, PlaceOnBottom */ +} XCirculateRequestEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; + Atom atom; + Time time; + int state; /* NewValue, Deleted */ +} XPropertyEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; + Atom selection; + Time time; +} XSelectionClearEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window owner; + Window requestor; + Atom selection; + Atom target; + Atom property; + Time time; +} XSelectionRequestEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window requestor; + Atom selection; + Atom target; + Atom property; /* ATOM or None */ + Time time; +} XSelectionEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; + Colormap colormap; /* COLORMAP or None */ +#if defined(__cplusplus) || defined(c_plusplus) + Bool c_new; /* C++ */ +#else + Bool new; +#endif + int state; /* ColormapInstalled, ColormapUninstalled */ +} XColormapEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; + Atom message_type; + int format; + union { + char b[20]; + short s[10]; + long l[5]; + } data; +} XClientMessageEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* unused */ + int request; /* one of MappingModifier, MappingKeyboard, + MappingPointer */ + int first_keycode; /* first keycode */ + int count; /* defines range of change w. first_keycode*/ +} XMappingEvent; + +typedef struct { + int type; + Display *display; /* Display the event was read from */ + XID resourceid; /* resource id */ + unsigned long serial; /* serial number of failed request */ + unsigned char error_code; /* error code of failed request */ + unsigned char request_code; /* Major op-code of failed request */ + unsigned char minor_code; /* Minor op-code of failed request */ +} XErrorEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display;/* Display the event was read from */ + Window window; /* window on which event was requested in event mask */ +} XAnyEvent; + + +/*************************************************************** + * + * GenericEvent. This event is the standard event for all newer extensions. + */ + +typedef struct + { + int type; /* of event. Always GenericEvent */ + unsigned long serial; /* # of last request processed */ + Bool send_event; /* true if from SendEvent request */ + Display *display; /* Display the event was read from */ + int extension; /* major opcode of extension that caused the event */ + int evtype; /* actual event type. */ + } XGenericEvent; + +typedef struct { + int type; /* of event. Always GenericEvent */ + unsigned long serial; /* # of last request processed */ + Bool send_event; /* true if from SendEvent request */ + Display *display; /* Display the event was read from */ + int extension; /* major opcode of extension that caused the event */ + int evtype; /* actual event type. */ + unsigned int cookie; + void *data; +} XGenericEventCookie; + +/* + * this union is defined so Xlib can always use the same sized + * event structure internally, to avoid memory fragmentation. + */ +typedef union _XEvent { + int type; /* must not be changed; first element */ + XAnyEvent xany; + XKeyEvent xkey; + XButtonEvent xbutton; + XMotionEvent xmotion; + XCrossingEvent xcrossing; + XFocusChangeEvent xfocus; + XExposeEvent xexpose; + XGraphicsExposeEvent xgraphicsexpose; + XNoExposeEvent xnoexpose; + XVisibilityEvent xvisibility; + XCreateWindowEvent xcreatewindow; + XDestroyWindowEvent xdestroywindow; + XUnmapEvent xunmap; + XMapEvent xmap; + XMapRequestEvent xmaprequest; + XReparentEvent xreparent; + XConfigureEvent xconfigure; + XGravityEvent xgravity; + XResizeRequestEvent xresizerequest; + XConfigureRequestEvent xconfigurerequest; + XCirculateEvent xcirculate; + XCirculateRequestEvent xcirculaterequest; + XPropertyEvent xproperty; + XSelectionClearEvent xselectionclear; + XSelectionRequestEvent xselectionrequest; + XSelectionEvent xselection; + XColormapEvent xcolormap; + XClientMessageEvent xclient; + XMappingEvent xmapping; + XErrorEvent xerror; + XKeymapEvent xkeymap; + XGenericEvent xgeneric; + XGenericEventCookie xcookie; + long pad[24]; +} XEvent; +#endif + +#define XAllocID(dpy) ((*((_XPrivDisplay)(dpy))->resource_alloc)((dpy))) + +/* + * per character font metric information. + */ +typedef struct { + short lbearing; /* origin to left edge of raster */ + short rbearing; /* origin to right edge of raster */ + short width; /* advance to next char's origin */ + short ascent; /* baseline to top edge of raster */ + short descent; /* baseline to bottom edge of raster */ + unsigned short attributes; /* per char flags (not predefined) */ +} XCharStruct; + +/* + * To allow arbitrary information with fonts, there are additional properties + * returned. + */ +typedef struct { + Atom name; + unsigned long card32; +} XFontProp; + +typedef struct { + XExtData *ext_data; /* hook for extension to hang data */ + Font fid; /* Font id for this font */ + unsigned direction; /* hint about direction the font is painted */ + unsigned min_char_or_byte2;/* first character */ + unsigned max_char_or_byte2;/* last character */ + unsigned min_byte1; /* first row that exists */ + unsigned max_byte1; /* last row that exists */ + Bool all_chars_exist;/* flag if all characters have non-zero size*/ + unsigned default_char; /* char to print for undefined character */ + int n_properties; /* how many properties there are */ + XFontProp *properties; /* pointer to array of additional properties*/ + XCharStruct min_bounds; /* minimum bounds over all existing char*/ + XCharStruct max_bounds; /* maximum bounds over all existing char*/ + XCharStruct *per_char; /* first_char to last_char information */ + int ascent; /* log. extent above baseline for spacing */ + int descent; /* log. descent below baseline for spacing */ +} XFontStruct; + +/* + * PolyText routines take these as arguments. + */ +typedef struct { + char *chars; /* pointer to string */ + int nchars; /* number of characters */ + int delta; /* delta between strings */ + Font font; /* font to print it in, None don't change */ +} XTextItem; + +typedef struct { /* normal 16 bit characters are two bytes */ + unsigned char byte1; + unsigned char byte2; +} XChar2b; + +typedef struct { + XChar2b *chars; /* two byte characters */ + int nchars; /* number of characters */ + int delta; /* delta between strings */ + Font font; /* font to print it in, None don't change */ +} XTextItem16; + + +typedef union { Display *display; + GC gc; + Visual *visual; + Screen *screen; + ScreenFormat *pixmap_format; + XFontStruct *font; } XEDataObject; + +typedef struct { + XRectangle max_ink_extent; + XRectangle max_logical_extent; +} XFontSetExtents; + +/* unused: +typedef void (*XOMProc)(); + */ + +typedef struct _XOM *XOM; +typedef struct _XOC *XOC, *XFontSet; + +typedef struct { + char *chars; + int nchars; + int delta; + XFontSet font_set; +} XmbTextItem; + +typedef struct { + wchar_t *chars; + int nchars; + int delta; + XFontSet font_set; +} XwcTextItem; + +#define XNRequiredCharSet "requiredCharSet" +#define XNQueryOrientation "queryOrientation" +#define XNBaseFontName "baseFontName" +#define XNOMAutomatic "omAutomatic" +#define XNMissingCharSet "missingCharSet" +#define XNDefaultString "defaultString" +#define XNOrientation "orientation" +#define XNDirectionalDependentDrawing "directionalDependentDrawing" +#define XNContextualDrawing "contextualDrawing" +#define XNFontInfo "fontInfo" + +typedef struct { + int charset_count; + char **charset_list; +} XOMCharSetList; + +typedef enum { + XOMOrientation_LTR_TTB, + XOMOrientation_RTL_TTB, + XOMOrientation_TTB_LTR, + XOMOrientation_TTB_RTL, + XOMOrientation_Context +} XOrientation; + +typedef struct { + int num_orientation; + XOrientation *orientation; /* Input Text description */ +} XOMOrientation; + +typedef struct { + int num_font; + XFontStruct **font_struct_list; + char **font_name_list; +} XOMFontInfo; + +typedef struct _XIM *XIM; +typedef struct _XIC *XIC; + +typedef void (*XIMProc)( + XIM, + XPointer, + XPointer +); + +typedef Bool (*XICProc)( + XIC, + XPointer, + XPointer +); + +typedef void (*XIDProc)( + Display*, + XPointer, + XPointer +); + +typedef unsigned long XIMStyle; + +typedef struct { + unsigned short count_styles; + XIMStyle *supported_styles; +} XIMStyles; + +#define XIMPreeditArea 0x0001L +#define XIMPreeditCallbacks 0x0002L +#define XIMPreeditPosition 0x0004L +#define XIMPreeditNothing 0x0008L +#define XIMPreeditNone 0x0010L +#define XIMStatusArea 0x0100L +#define XIMStatusCallbacks 0x0200L +#define XIMStatusNothing 0x0400L +#define XIMStatusNone 0x0800L + +#define XNVaNestedList "XNVaNestedList" +#define XNQueryInputStyle "queryInputStyle" +#define XNClientWindow "clientWindow" +#define XNInputStyle "inputStyle" +#define XNFocusWindow "focusWindow" +#define XNResourceName "resourceName" +#define XNResourceClass "resourceClass" +#define XNGeometryCallback "geometryCallback" +#define XNDestroyCallback "destroyCallback" +#define XNFilterEvents "filterEvents" +#define XNPreeditStartCallback "preeditStartCallback" +#define XNPreeditDoneCallback "preeditDoneCallback" +#define XNPreeditDrawCallback "preeditDrawCallback" +#define XNPreeditCaretCallback "preeditCaretCallback" +#define XNPreeditStateNotifyCallback "preeditStateNotifyCallback" +#define XNPreeditAttributes "preeditAttributes" +#define XNStatusStartCallback "statusStartCallback" +#define XNStatusDoneCallback "statusDoneCallback" +#define XNStatusDrawCallback "statusDrawCallback" +#define XNStatusAttributes "statusAttributes" +#define XNArea "area" +#define XNAreaNeeded "areaNeeded" +#define XNSpotLocation "spotLocation" +#define XNColormap "colorMap" +#define XNStdColormap "stdColorMap" +#define XNForeground "foreground" +#define XNBackground "background" +#define XNBackgroundPixmap "backgroundPixmap" +#define XNFontSet "fontSet" +#define XNLineSpace "lineSpace" +#define XNCursor "cursor" + +#define XNQueryIMValuesList "queryIMValuesList" +#define XNQueryICValuesList "queryICValuesList" +#define XNVisiblePosition "visiblePosition" +#define XNR6PreeditCallback "r6PreeditCallback" +#define XNStringConversionCallback "stringConversionCallback" +#define XNStringConversion "stringConversion" +#define XNResetState "resetState" +#define XNHotKey "hotKey" +#define XNHotKeyState "hotKeyState" +#define XNPreeditState "preeditState" +#define XNSeparatorofNestedList "separatorofNestedList" + +#define XBufferOverflow -1 +#define XLookupNone 1 +#define XLookupChars 2 +#define XLookupKeySym 3 +#define XLookupBoth 4 + +typedef void *XVaNestedList; + +typedef struct { + XPointer client_data; + XIMProc callback; +} XIMCallback; + +typedef struct { + XPointer client_data; + XICProc callback; +} XICCallback; + +typedef unsigned long XIMFeedback; + +#define XIMReverse 1L +#define XIMUnderline (1L<<1) +#define XIMHighlight (1L<<2) +#define XIMPrimary (1L<<5) +#define XIMSecondary (1L<<6) +#define XIMTertiary (1L<<7) +#define XIMVisibleToForward (1L<<8) +#define XIMVisibleToBackword (1L<<9) +#define XIMVisibleToCenter (1L<<10) + +typedef struct _XIMText { + unsigned short length; + XIMFeedback *feedback; + Bool encoding_is_wchar; + union { + char *multi_byte; + wchar_t *wide_char; + } string; +} XIMText; + +typedef unsigned long XIMPreeditState; + +#define XIMPreeditUnKnown 0L +#define XIMPreeditEnable 1L +#define XIMPreeditDisable (1L<<1) + +typedef struct _XIMPreeditStateNotifyCallbackStruct { + XIMPreeditState state; +} XIMPreeditStateNotifyCallbackStruct; + +typedef unsigned long XIMResetState; + +#define XIMInitialState 1L +#define XIMPreserveState (1L<<1) + +typedef unsigned long XIMStringConversionFeedback; + +#define XIMStringConversionLeftEdge (0x00000001) +#define XIMStringConversionRightEdge (0x00000002) +#define XIMStringConversionTopEdge (0x00000004) +#define XIMStringConversionBottomEdge (0x00000008) +#define XIMStringConversionConcealed (0x00000010) +#define XIMStringConversionWrapped (0x00000020) + +typedef struct _XIMStringConversionText { + unsigned short length; + XIMStringConversionFeedback *feedback; + Bool encoding_is_wchar; + union { + char *mbs; + wchar_t *wcs; + } string; +} XIMStringConversionText; + +typedef unsigned short XIMStringConversionPosition; + +typedef unsigned short XIMStringConversionType; + +#define XIMStringConversionBuffer (0x0001) +#define XIMStringConversionLine (0x0002) +#define XIMStringConversionWord (0x0003) +#define XIMStringConversionChar (0x0004) + +typedef unsigned short XIMStringConversionOperation; + +#define XIMStringConversionSubstitution (0x0001) +#define XIMStringConversionRetrieval (0x0002) + +typedef enum { + XIMForwardChar, XIMBackwardChar, + XIMForwardWord, XIMBackwardWord, + XIMCaretUp, XIMCaretDown, + XIMNextLine, XIMPreviousLine, + XIMLineStart, XIMLineEnd, + XIMAbsolutePosition, + XIMDontChange +} XIMCaretDirection; + +typedef struct _XIMStringConversionCallbackStruct { + XIMStringConversionPosition position; + XIMCaretDirection direction; + XIMStringConversionOperation operation; + unsigned short factor; + XIMStringConversionText *text; +} XIMStringConversionCallbackStruct; + +typedef struct _XIMPreeditDrawCallbackStruct { + int caret; /* Cursor offset within pre-edit string */ + int chg_first; /* Starting change position */ + int chg_length; /* Length of the change in character count */ + XIMText *text; +} XIMPreeditDrawCallbackStruct; + +typedef enum { + XIMIsInvisible, /* Disable caret feedback */ + XIMIsPrimary, /* UI defined caret feedback */ + XIMIsSecondary /* UI defined caret feedback */ +} XIMCaretStyle; + +typedef struct _XIMPreeditCaretCallbackStruct { + int position; /* Caret offset within pre-edit string */ + XIMCaretDirection direction; /* Caret moves direction */ + XIMCaretStyle style; /* Feedback of the caret */ +} XIMPreeditCaretCallbackStruct; + +typedef enum { + XIMTextType, + XIMBitmapType +} XIMStatusDataType; + +typedef struct _XIMStatusDrawCallbackStruct { + XIMStatusDataType type; + union { + XIMText *text; + Pixmap bitmap; + } data; +} XIMStatusDrawCallbackStruct; + +typedef struct _XIMHotKeyTrigger { + KeySym keysym; + int modifier; + int modifier_mask; +} XIMHotKeyTrigger; + +typedef struct _XIMHotKeyTriggers { + int num_hot_key; + XIMHotKeyTrigger *key; +} XIMHotKeyTriggers; + +typedef unsigned long XIMHotKeyState; + +#define XIMHotKeyStateON (0x0001L) +#define XIMHotKeyStateOFF (0x0002L) + +typedef struct { + unsigned short count_values; + char **supported_values; +} XIMValuesList; + +_XFUNCPROTOBEGIN + +#if defined(WIN32) && !defined(_XLIBINT_) +#define _Xdebug (*_Xdebug_p) +#endif + +extern int _Xdebug; + +extern XFontStruct *XLoadQueryFont( + Display* /* display */, + _Xconst char* /* name */ +); + +extern XFontStruct *XQueryFont( + Display* /* display */, + XID /* font_ID */ +); + + +extern XTimeCoord *XGetMotionEvents( + Display* /* display */, + Window /* w */, + Time /* start */, + Time /* stop */, + int* /* nevents_return */ +); + +extern XModifierKeymap *XDeleteModifiermapEntry( + XModifierKeymap* /* modmap */, +#if NeedWidePrototypes + unsigned int /* keycode_entry */, +#else + KeyCode /* keycode_entry */, +#endif + int /* modifier */ +); + +extern XModifierKeymap *XGetModifierMapping( + Display* /* display */ +); + +extern XModifierKeymap *XInsertModifiermapEntry( + XModifierKeymap* /* modmap */, +#if NeedWidePrototypes + unsigned int /* keycode_entry */, +#else + KeyCode /* keycode_entry */, +#endif + int /* modifier */ +); + +extern XModifierKeymap *XNewModifiermap( + int /* max_keys_per_mod */ +); + +extern XImage *XCreateImage( + Display* /* display */, + Visual* /* visual */, + unsigned int /* depth */, + int /* format */, + int /* offset */, + char* /* data */, + unsigned int /* width */, + unsigned int /* height */, + int /* bitmap_pad */, + int /* bytes_per_line */ +); +extern Status XInitImage( + XImage* /* image */ +); +extern XImage *XGetImage( + Display* /* display */, + Drawable /* d */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */, + unsigned long /* plane_mask */, + int /* format */ +); +extern XImage *XGetSubImage( + Display* /* display */, + Drawable /* d */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */, + unsigned long /* plane_mask */, + int /* format */, + XImage* /* dest_image */, + int /* dest_x */, + int /* dest_y */ +); + +/* + * X function declarations. + */ +extern Display *XOpenDisplay( + _Xconst char* /* display_name */ +); + +extern void XrmInitialize( + void +); + +extern char *XFetchBytes( + Display* /* display */, + int* /* nbytes_return */ +); +extern char *XFetchBuffer( + Display* /* display */, + int* /* nbytes_return */, + int /* buffer */ +); +extern char *XGetAtomName( + Display* /* display */, + Atom /* atom */ +); +extern Status XGetAtomNames( + Display* /* dpy */, + Atom* /* atoms */, + int /* count */, + char** /* names_return */ +); +extern char *XGetDefault( + Display* /* display */, + _Xconst char* /* program */, + _Xconst char* /* option */ +); +extern char *XDisplayName( + _Xconst char* /* string */ +); +extern char *XKeysymToString( + KeySym /* keysym */ +); + +extern int (*XSynchronize( + Display* /* display */, + Bool /* onoff */ +))( + Display* /* display */ +); +extern int (*XSetAfterFunction( + Display* /* display */, + int (*) ( + Display* /* display */ + ) /* procedure */ +))( + Display* /* display */ +); +extern Atom XInternAtom( + Display* /* display */, + _Xconst char* /* atom_name */, + Bool /* only_if_exists */ +); +extern Status XInternAtoms( + Display* /* dpy */, + char** /* names */, + int /* count */, + Bool /* onlyIfExists */, + Atom* /* atoms_return */ +); +extern Colormap XCopyColormapAndFree( + Display* /* display */, + Colormap /* colormap */ +); +extern Colormap XCreateColormap( + Display* /* display */, + Window /* w */, + Visual* /* visual */, + int /* alloc */ +); +extern Cursor XCreatePixmapCursor( + Display* /* display */, + Pixmap /* source */, + Pixmap /* mask */, + XColor* /* foreground_color */, + XColor* /* background_color */, + unsigned int /* x */, + unsigned int /* y */ +); +extern Cursor XCreateGlyphCursor( + Display* /* display */, + Font /* source_font */, + Font /* mask_font */, + unsigned int /* source_char */, + unsigned int /* mask_char */, + XColor _Xconst * /* foreground_color */, + XColor _Xconst * /* background_color */ +); +extern Cursor XCreateFontCursor( + Display* /* display */, + unsigned int /* shape */ +); +extern Font XLoadFont( + Display* /* display */, + _Xconst char* /* name */ +); +extern GC XCreateGC( + Display* /* display */, + Drawable /* d */, + unsigned long /* valuemask */, + XGCValues* /* values */ +); +extern GContext XGContextFromGC( + GC /* gc */ +); +extern void XFlushGC( + Display* /* display */, + GC /* gc */ +); +extern Pixmap XCreatePixmap( + Display* /* display */, + Drawable /* d */, + unsigned int /* width */, + unsigned int /* height */, + unsigned int /* depth */ +); +extern Pixmap XCreateBitmapFromData( + Display* /* display */, + Drawable /* d */, + _Xconst char* /* data */, + unsigned int /* width */, + unsigned int /* height */ +); +extern Pixmap XCreatePixmapFromBitmapData( + Display* /* display */, + Drawable /* d */, + char* /* data */, + unsigned int /* width */, + unsigned int /* height */, + unsigned long /* fg */, + unsigned long /* bg */, + unsigned int /* depth */ +); +extern Window XCreateSimpleWindow( + Display* /* display */, + Window /* parent */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */, + unsigned int /* border_width */, + unsigned long /* border */, + unsigned long /* background */ +); +extern Window XGetSelectionOwner( + Display* /* display */, + Atom /* selection */ +); +extern Window XCreateWindow( + Display* /* display */, + Window /* parent */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */, + unsigned int /* border_width */, + int /* depth */, + unsigned int /* class */, + Visual* /* visual */, + unsigned long /* valuemask */, + XSetWindowAttributes* /* attributes */ +); +extern Colormap *XListInstalledColormaps( + Display* /* display */, + Window /* w */, + int* /* num_return */ +); +extern char **XListFonts( + Display* /* display */, + _Xconst char* /* pattern */, + int /* maxnames */, + int* /* actual_count_return */ +); +extern char **XListFontsWithInfo( + Display* /* display */, + _Xconst char* /* pattern */, + int /* maxnames */, + int* /* count_return */, + XFontStruct** /* info_return */ +); +extern char **XGetFontPath( + Display* /* display */, + int* /* npaths_return */ +); +extern char **XListExtensions( + Display* /* display */, + int* /* nextensions_return */ +); +extern Atom *XListProperties( + Display* /* display */, + Window /* w */, + int* /* num_prop_return */ +); +extern XHostAddress *XListHosts( + Display* /* display */, + int* /* nhosts_return */, + Bool* /* state_return */ +); +_X_DEPRECATED +extern KeySym XKeycodeToKeysym( + Display* /* display */, +#if NeedWidePrototypes + unsigned int /* keycode */, +#else + KeyCode /* keycode */, +#endif + int /* index */ +); +extern KeySym XLookupKeysym( + XKeyEvent* /* key_event */, + int /* index */ +); +extern KeySym *XGetKeyboardMapping( + Display* /* display */, +#if NeedWidePrototypes + unsigned int /* first_keycode */, +#else + KeyCode /* first_keycode */, +#endif + int /* keycode_count */, + int* /* keysyms_per_keycode_return */ +); +extern KeySym XStringToKeysym( + _Xconst char* /* string */ +); +extern long XMaxRequestSize( + Display* /* display */ +); +extern long XExtendedMaxRequestSize( + Display* /* display */ +); +extern char *XResourceManagerString( + Display* /* display */ +); +extern char *XScreenResourceString( + Screen* /* screen */ +); +extern unsigned long XDisplayMotionBufferSize( + Display* /* display */ +); +extern VisualID XVisualIDFromVisual( + Visual* /* visual */ +); + +/* multithread routines */ + +extern Status XInitThreads( + void +); + +extern void XLockDisplay( + Display* /* display */ +); + +extern void XUnlockDisplay( + Display* /* display */ +); + +/* routines for dealing with extensions */ + +extern XExtCodes *XInitExtension( + Display* /* display */, + _Xconst char* /* name */ +); + +extern XExtCodes *XAddExtension( + Display* /* display */ +); +extern XExtData *XFindOnExtensionList( + XExtData** /* structure */, + int /* number */ +); +extern XExtData **XEHeadOfExtensionList( + XEDataObject /* object */ +); + +/* these are routines for which there are also macros */ +extern Window XRootWindow( + Display* /* display */, + int /* screen_number */ +); +extern Window XDefaultRootWindow( + Display* /* display */ +); +extern Window XRootWindowOfScreen( + Screen* /* screen */ +); +extern Visual *XDefaultVisual( + Display* /* display */, + int /* screen_number */ +); +extern Visual *XDefaultVisualOfScreen( + Screen* /* screen */ +); +extern GC XDefaultGC( + Display* /* display */, + int /* screen_number */ +); +extern GC XDefaultGCOfScreen( + Screen* /* screen */ +); +extern unsigned long XBlackPixel( + Display* /* display */, + int /* screen_number */ +); +extern unsigned long XWhitePixel( + Display* /* display */, + int /* screen_number */ +); +extern unsigned long XAllPlanes( + void +); +extern unsigned long XBlackPixelOfScreen( + Screen* /* screen */ +); +extern unsigned long XWhitePixelOfScreen( + Screen* /* screen */ +); +extern unsigned long XNextRequest( + Display* /* display */ +); +extern unsigned long XLastKnownRequestProcessed( + Display* /* display */ +); +extern char *XServerVendor( + Display* /* display */ +); +extern char *XDisplayString( + Display* /* display */ +); +extern Colormap XDefaultColormap( + Display* /* display */, + int /* screen_number */ +); +extern Colormap XDefaultColormapOfScreen( + Screen* /* screen */ +); +extern Display *XDisplayOfScreen( + Screen* /* screen */ +); +extern Screen *XScreenOfDisplay( + Display* /* display */, + int /* screen_number */ +); +extern Screen *XDefaultScreenOfDisplay( + Display* /* display */ +); +extern long XEventMaskOfScreen( + Screen* /* screen */ +); + +extern int XScreenNumberOfScreen( + Screen* /* screen */ +); + +typedef int (*XErrorHandler) ( /* WARNING, this type not in Xlib spec */ + Display* /* display */, + XErrorEvent* /* error_event */ +); + +extern XErrorHandler XSetErrorHandler ( + XErrorHandler /* handler */ +); + + +typedef int (*XIOErrorHandler) ( /* WARNING, this type not in Xlib spec */ + Display* /* display */ +); + +extern XIOErrorHandler XSetIOErrorHandler ( + XIOErrorHandler /* handler */ +); + +typedef void (*XIOErrorExitHandler) ( /* WARNING, this type not in Xlib spec */ + Display*, /* display */ + void* /* user_data */ +); + +extern void XSetIOErrorExitHandler ( + Display*, /* display */ + XIOErrorExitHandler, /* handler */ + void* /* user_data */ +); + +extern XPixmapFormatValues *XListPixmapFormats( + Display* /* display */, + int* /* count_return */ +); +extern int *XListDepths( + Display* /* display */, + int /* screen_number */, + int* /* count_return */ +); + +/* ICCCM routines for things that don't require special include files; */ +/* other declarations are given in Xutil.h */ +extern Status XReconfigureWMWindow( + Display* /* display */, + Window /* w */, + int /* screen_number */, + unsigned int /* mask */, + XWindowChanges* /* changes */ +); + +extern Status XGetWMProtocols( + Display* /* display */, + Window /* w */, + Atom** /* protocols_return */, + int* /* count_return */ +); +extern Status XSetWMProtocols( + Display* /* display */, + Window /* w */, + Atom* /* protocols */, + int /* count */ +); +extern Status XIconifyWindow( + Display* /* display */, + Window /* w */, + int /* screen_number */ +); +extern Status XWithdrawWindow( + Display* /* display */, + Window /* w */, + int /* screen_number */ +); +extern Status XGetCommand( + Display* /* display */, + Window /* w */, + char*** /* argv_return */, + int* /* argc_return */ +); +extern Status XGetWMColormapWindows( + Display* /* display */, + Window /* w */, + Window** /* windows_return */, + int* /* count_return */ +); +extern Status XSetWMColormapWindows( + Display* /* display */, + Window /* w */, + Window* /* colormap_windows */, + int /* count */ +); +extern void XFreeStringList( + char** /* list */ +); +extern int XSetTransientForHint( + Display* /* display */, + Window /* w */, + Window /* prop_window */ +); + +/* The following are given in alphabetical order */ + +extern int XActivateScreenSaver( + Display* /* display */ +); + +extern int XAddHost( + Display* /* display */, + XHostAddress* /* host */ +); + +extern int XAddHosts( + Display* /* display */, + XHostAddress* /* hosts */, + int /* num_hosts */ +); + +extern int XAddToExtensionList( + struct _XExtData** /* structure */, + XExtData* /* ext_data */ +); + +extern int XAddToSaveSet( + Display* /* display */, + Window /* w */ +); + +extern Status XAllocColor( + Display* /* display */, + Colormap /* colormap */, + XColor* /* screen_in_out */ +); + +extern Status XAllocColorCells( + Display* /* display */, + Colormap /* colormap */, + Bool /* contig */, + unsigned long* /* plane_masks_return */, + unsigned int /* nplanes */, + unsigned long* /* pixels_return */, + unsigned int /* npixels */ +); + +extern Status XAllocColorPlanes( + Display* /* display */, + Colormap /* colormap */, + Bool /* contig */, + unsigned long* /* pixels_return */, + int /* ncolors */, + int /* nreds */, + int /* ngreens */, + int /* nblues */, + unsigned long* /* rmask_return */, + unsigned long* /* gmask_return */, + unsigned long* /* bmask_return */ +); + +extern Status XAllocNamedColor( + Display* /* display */, + Colormap /* colormap */, + _Xconst char* /* color_name */, + XColor* /* screen_def_return */, + XColor* /* exact_def_return */ +); + +extern int XAllowEvents( + Display* /* display */, + int /* event_mode */, + Time /* time */ +); + +extern int XAutoRepeatOff( + Display* /* display */ +); + +extern int XAutoRepeatOn( + Display* /* display */ +); + +extern int XBell( + Display* /* display */, + int /* percent */ +); + +extern int XBitmapBitOrder( + Display* /* display */ +); + +extern int XBitmapPad( + Display* /* display */ +); + +extern int XBitmapUnit( + Display* /* display */ +); + +extern int XCellsOfScreen( + Screen* /* screen */ +); + +extern int XChangeActivePointerGrab( + Display* /* display */, + unsigned int /* event_mask */, + Cursor /* cursor */, + Time /* time */ +); + +extern int XChangeGC( + Display* /* display */, + GC /* gc */, + unsigned long /* valuemask */, + XGCValues* /* values */ +); + +extern int XChangeKeyboardControl( + Display* /* display */, + unsigned long /* value_mask */, + XKeyboardControl* /* values */ +); + +extern int XChangeKeyboardMapping( + Display* /* display */, + int /* first_keycode */, + int /* keysyms_per_keycode */, + KeySym* /* keysyms */, + int /* num_codes */ +); + +extern int XChangePointerControl( + Display* /* display */, + Bool /* do_accel */, + Bool /* do_threshold */, + int /* accel_numerator */, + int /* accel_denominator */, + int /* threshold */ +); + +extern int XChangeProperty( + Display* /* display */, + Window /* w */, + Atom /* property */, + Atom /* type */, + int /* format */, + int /* mode */, + _Xconst unsigned char* /* data */, + int /* nelements */ +); + +extern int XChangeSaveSet( + Display* /* display */, + Window /* w */, + int /* change_mode */ +); + +extern int XChangeWindowAttributes( + Display* /* display */, + Window /* w */, + unsigned long /* valuemask */, + XSetWindowAttributes* /* attributes */ +); + +extern Bool XCheckIfEvent( + Display* /* display */, + XEvent* /* event_return */, + Bool (*) ( + Display* /* display */, + XEvent* /* event */, + XPointer /* arg */ + ) /* predicate */, + XPointer /* arg */ +); + +extern Bool XCheckMaskEvent( + Display* /* display */, + long /* event_mask */, + XEvent* /* event_return */ +); + +extern Bool XCheckTypedEvent( + Display* /* display */, + int /* event_type */, + XEvent* /* event_return */ +); + +extern Bool XCheckTypedWindowEvent( + Display* /* display */, + Window /* w */, + int /* event_type */, + XEvent* /* event_return */ +); + +extern Bool XCheckWindowEvent( + Display* /* display */, + Window /* w */, + long /* event_mask */, + XEvent* /* event_return */ +); + +extern int XCirculateSubwindows( + Display* /* display */, + Window /* w */, + int /* direction */ +); + +extern int XCirculateSubwindowsDown( + Display* /* display */, + Window /* w */ +); + +extern int XCirculateSubwindowsUp( + Display* /* display */, + Window /* w */ +); + +extern int XClearArea( + Display* /* display */, + Window /* w */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */, + Bool /* exposures */ +); + +extern int XClearWindow( + Display* /* display */, + Window /* w */ +); + +extern int XCloseDisplay( + Display* /* display */ +); + +extern int XConfigureWindow( + Display* /* display */, + Window /* w */, + unsigned int /* value_mask */, + XWindowChanges* /* values */ +); + +extern int XConnectionNumber( + Display* /* display */ +); + +extern int XConvertSelection( + Display* /* display */, + Atom /* selection */, + Atom /* target */, + Atom /* property */, + Window /* requestor */, + Time /* time */ +); + +extern int XCopyArea( + Display* /* display */, + Drawable /* src */, + Drawable /* dest */, + GC /* gc */, + int /* src_x */, + int /* src_y */, + unsigned int /* width */, + unsigned int /* height */, + int /* dest_x */, + int /* dest_y */ +); + +extern int XCopyGC( + Display* /* display */, + GC /* src */, + unsigned long /* valuemask */, + GC /* dest */ +); + +extern int XCopyPlane( + Display* /* display */, + Drawable /* src */, + Drawable /* dest */, + GC /* gc */, + int /* src_x */, + int /* src_y */, + unsigned int /* width */, + unsigned int /* height */, + int /* dest_x */, + int /* dest_y */, + unsigned long /* plane */ +); + +extern int XDefaultDepth( + Display* /* display */, + int /* screen_number */ +); + +extern int XDefaultDepthOfScreen( + Screen* /* screen */ +); + +extern int XDefaultScreen( + Display* /* display */ +); + +extern int XDefineCursor( + Display* /* display */, + Window /* w */, + Cursor /* cursor */ +); + +extern int XDeleteProperty( + Display* /* display */, + Window /* w */, + Atom /* property */ +); + +extern int XDestroyWindow( + Display* /* display */, + Window /* w */ +); + +extern int XDestroySubwindows( + Display* /* display */, + Window /* w */ +); + +extern int XDoesBackingStore( + Screen* /* screen */ +); + +extern Bool XDoesSaveUnders( + Screen* /* screen */ +); + +extern int XDisableAccessControl( + Display* /* display */ +); + + +extern int XDisplayCells( + Display* /* display */, + int /* screen_number */ +); + +extern int XDisplayHeight( + Display* /* display */, + int /* screen_number */ +); + +extern int XDisplayHeightMM( + Display* /* display */, + int /* screen_number */ +); + +extern int XDisplayKeycodes( + Display* /* display */, + int* /* min_keycodes_return */, + int* /* max_keycodes_return */ +); + +extern int XDisplayPlanes( + Display* /* display */, + int /* screen_number */ +); + +extern int XDisplayWidth( + Display* /* display */, + int /* screen_number */ +); + +extern int XDisplayWidthMM( + Display* /* display */, + int /* screen_number */ +); + +extern int XDrawArc( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */, + int /* angle1 */, + int /* angle2 */ +); + +extern int XDrawArcs( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + XArc* /* arcs */, + int /* narcs */ +); + +extern int XDrawImageString( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst char* /* string */, + int /* length */ +); + +extern int XDrawImageString16( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst XChar2b* /* string */, + int /* length */ +); + +extern int XDrawLine( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x1 */, + int /* y1 */, + int /* x2 */, + int /* y2 */ +); + +extern int XDrawLines( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + XPoint* /* points */, + int /* npoints */, + int /* mode */ +); + +extern int XDrawPoint( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */ +); + +extern int XDrawPoints( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + XPoint* /* points */, + int /* npoints */, + int /* mode */ +); + +extern int XDrawRectangle( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */ +); + +extern int XDrawRectangles( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + XRectangle* /* rectangles */, + int /* nrectangles */ +); + +extern int XDrawSegments( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + XSegment* /* segments */, + int /* nsegments */ +); + +extern int XDrawString( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst char* /* string */, + int /* length */ +); + +extern int XDrawString16( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst XChar2b* /* string */, + int /* length */ +); + +extern int XDrawText( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + XTextItem* /* items */, + int /* nitems */ +); + +extern int XDrawText16( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + XTextItem16* /* items */, + int /* nitems */ +); + +extern int XEnableAccessControl( + Display* /* display */ +); + +extern int XEventsQueued( + Display* /* display */, + int /* mode */ +); + +extern Status XFetchName( + Display* /* display */, + Window /* w */, + char** /* window_name_return */ +); + +extern int XFillArc( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */, + int /* angle1 */, + int /* angle2 */ +); + +extern int XFillArcs( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + XArc* /* arcs */, + int /* narcs */ +); + +extern int XFillPolygon( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + XPoint* /* points */, + int /* npoints */, + int /* shape */, + int /* mode */ +); + +extern int XFillRectangle( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */ +); + +extern int XFillRectangles( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + XRectangle* /* rectangles */, + int /* nrectangles */ +); + +extern int XFlush( + Display* /* display */ +); + +extern int XForceScreenSaver( + Display* /* display */, + int /* mode */ +); + +extern int XFree( + void* /* data */ +); + +extern int XFreeColormap( + Display* /* display */, + Colormap /* colormap */ +); + +extern int XFreeColors( + Display* /* display */, + Colormap /* colormap */, + unsigned long* /* pixels */, + int /* npixels */, + unsigned long /* planes */ +); + +extern int XFreeCursor( + Display* /* display */, + Cursor /* cursor */ +); + +extern int XFreeExtensionList( + char** /* list */ +); + +extern int XFreeFont( + Display* /* display */, + XFontStruct* /* font_struct */ +); + +extern int XFreeFontInfo( + char** /* names */, + XFontStruct* /* free_info */, + int /* actual_count */ +); + +extern int XFreeFontNames( + char** /* list */ +); + +extern int XFreeFontPath( + char** /* list */ +); + +extern int XFreeGC( + Display* /* display */, + GC /* gc */ +); + +extern int XFreeModifiermap( + XModifierKeymap* /* modmap */ +); + +extern int XFreePixmap( + Display* /* display */, + Pixmap /* pixmap */ +); + +extern int XGeometry( + Display* /* display */, + int /* screen */, + _Xconst char* /* position */, + _Xconst char* /* default_position */, + unsigned int /* bwidth */, + unsigned int /* fwidth */, + unsigned int /* fheight */, + int /* xadder */, + int /* yadder */, + int* /* x_return */, + int* /* y_return */, + int* /* width_return */, + int* /* height_return */ +); + +extern int XGetErrorDatabaseText( + Display* /* display */, + _Xconst char* /* name */, + _Xconst char* /* message */, + _Xconst char* /* default_string */, + char* /* buffer_return */, + int /* length */ +); + +extern int XGetErrorText( + Display* /* display */, + int /* code */, + char* /* buffer_return */, + int /* length */ +); + +extern Bool XGetFontProperty( + XFontStruct* /* font_struct */, + Atom /* atom */, + unsigned long* /* value_return */ +); + +extern Status XGetGCValues( + Display* /* display */, + GC /* gc */, + unsigned long /* valuemask */, + XGCValues* /* values_return */ +); + +extern Status XGetGeometry( + Display* /* display */, + Drawable /* d */, + Window* /* root_return */, + int* /* x_return */, + int* /* y_return */, + unsigned int* /* width_return */, + unsigned int* /* height_return */, + unsigned int* /* border_width_return */, + unsigned int* /* depth_return */ +); + +extern Status XGetIconName( + Display* /* display */, + Window /* w */, + char** /* icon_name_return */ +); + +extern int XGetInputFocus( + Display* /* display */, + Window* /* focus_return */, + int* /* revert_to_return */ +); + +extern int XGetKeyboardControl( + Display* /* display */, + XKeyboardState* /* values_return */ +); + +extern int XGetPointerControl( + Display* /* display */, + int* /* accel_numerator_return */, + int* /* accel_denominator_return */, + int* /* threshold_return */ +); + +extern int XGetPointerMapping( + Display* /* display */, + unsigned char* /* map_return */, + int /* nmap */ +); + +extern int XGetScreenSaver( + Display* /* display */, + int* /* timeout_return */, + int* /* interval_return */, + int* /* prefer_blanking_return */, + int* /* allow_exposures_return */ +); + +extern Status XGetTransientForHint( + Display* /* display */, + Window /* w */, + Window* /* prop_window_return */ +); + +extern int XGetWindowProperty( + Display* /* display */, + Window /* w */, + Atom /* property */, + long /* long_offset */, + long /* long_length */, + Bool /* delete */, + Atom /* req_type */, + Atom* /* actual_type_return */, + int* /* actual_format_return */, + unsigned long* /* nitems_return */, + unsigned long* /* bytes_after_return */, + unsigned char** /* prop_return */ +); + +extern Status XGetWindowAttributes( + Display* /* display */, + Window /* w */, + XWindowAttributes* /* window_attributes_return */ +); + +extern int XGrabButton( + Display* /* display */, + unsigned int /* button */, + unsigned int /* modifiers */, + Window /* grab_window */, + Bool /* owner_events */, + unsigned int /* event_mask */, + int /* pointer_mode */, + int /* keyboard_mode */, + Window /* confine_to */, + Cursor /* cursor */ +); + +extern int XGrabKey( + Display* /* display */, + int /* keycode */, + unsigned int /* modifiers */, + Window /* grab_window */, + Bool /* owner_events */, + int /* pointer_mode */, + int /* keyboard_mode */ +); + +extern int XGrabKeyboard( + Display* /* display */, + Window /* grab_window */, + Bool /* owner_events */, + int /* pointer_mode */, + int /* keyboard_mode */, + Time /* time */ +); + +extern int XGrabPointer( + Display* /* display */, + Window /* grab_window */, + Bool /* owner_events */, + unsigned int /* event_mask */, + int /* pointer_mode */, + int /* keyboard_mode */, + Window /* confine_to */, + Cursor /* cursor */, + Time /* time */ +); + +extern int XGrabServer( + Display* /* display */ +); + +extern int XHeightMMOfScreen( + Screen* /* screen */ +); + +extern int XHeightOfScreen( + Screen* /* screen */ +); + +extern int XIfEvent( + Display* /* display */, + XEvent* /* event_return */, + Bool (*) ( + Display* /* display */, + XEvent* /* event */, + XPointer /* arg */ + ) /* predicate */, + XPointer /* arg */ +); + +extern int XImageByteOrder( + Display* /* display */ +); + +extern int XInstallColormap( + Display* /* display */, + Colormap /* colormap */ +); + +extern KeyCode XKeysymToKeycode( + Display* /* display */, + KeySym /* keysym */ +); + +extern int XKillClient( + Display* /* display */, + XID /* resource */ +); + +extern Status XLookupColor( + Display* /* display */, + Colormap /* colormap */, + _Xconst char* /* color_name */, + XColor* /* exact_def_return */, + XColor* /* screen_def_return */ +); + +extern int XLowerWindow( + Display* /* display */, + Window /* w */ +); + +extern int XMapRaised( + Display* /* display */, + Window /* w */ +); + +extern int XMapSubwindows( + Display* /* display */, + Window /* w */ +); + +extern int XMapWindow( + Display* /* display */, + Window /* w */ +); + +extern int XMaskEvent( + Display* /* display */, + long /* event_mask */, + XEvent* /* event_return */ +); + +extern int XMaxCmapsOfScreen( + Screen* /* screen */ +); + +extern int XMinCmapsOfScreen( + Screen* /* screen */ +); + +extern int XMoveResizeWindow( + Display* /* display */, + Window /* w */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */ +); + +extern int XMoveWindow( + Display* /* display */, + Window /* w */, + int /* x */, + int /* y */ +); + +extern int XNextEvent( + Display* /* display */, + XEvent* /* event_return */ +); + +extern int XNoOp( + Display* /* display */ +); + +extern Status XParseColor( + Display* /* display */, + Colormap /* colormap */, + _Xconst char* /* spec */, + XColor* /* exact_def_return */ +); + +extern int XParseGeometry( + _Xconst char* /* parsestring */, + int* /* x_return */, + int* /* y_return */, + unsigned int* /* width_return */, + unsigned int* /* height_return */ +); + +extern int XPeekEvent( + Display* /* display */, + XEvent* /* event_return */ +); + +extern int XPeekIfEvent( + Display* /* display */, + XEvent* /* event_return */, + Bool (*) ( + Display* /* display */, + XEvent* /* event */, + XPointer /* arg */ + ) /* predicate */, + XPointer /* arg */ +); + +extern int XPending( + Display* /* display */ +); + +extern int XPlanesOfScreen( + Screen* /* screen */ +); + +extern int XProtocolRevision( + Display* /* display */ +); + +extern int XProtocolVersion( + Display* /* display */ +); + + +extern int XPutBackEvent( + Display* /* display */, + XEvent* /* event */ +); + +extern int XPutImage( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + XImage* /* image */, + int /* src_x */, + int /* src_y */, + int /* dest_x */, + int /* dest_y */, + unsigned int /* width */, + unsigned int /* height */ +); + +extern int XQLength( + Display* /* display */ +); + +extern Status XQueryBestCursor( + Display* /* display */, + Drawable /* d */, + unsigned int /* width */, + unsigned int /* height */, + unsigned int* /* width_return */, + unsigned int* /* height_return */ +); + +extern Status XQueryBestSize( + Display* /* display */, + int /* class */, + Drawable /* which_screen */, + unsigned int /* width */, + unsigned int /* height */, + unsigned int* /* width_return */, + unsigned int* /* height_return */ +); + +extern Status XQueryBestStipple( + Display* /* display */, + Drawable /* which_screen */, + unsigned int /* width */, + unsigned int /* height */, + unsigned int* /* width_return */, + unsigned int* /* height_return */ +); + +extern Status XQueryBestTile( + Display* /* display */, + Drawable /* which_screen */, + unsigned int /* width */, + unsigned int /* height */, + unsigned int* /* width_return */, + unsigned int* /* height_return */ +); + +extern int XQueryColor( + Display* /* display */, + Colormap /* colormap */, + XColor* /* def_in_out */ +); + +extern int XQueryColors( + Display* /* display */, + Colormap /* colormap */, + XColor* /* defs_in_out */, + int /* ncolors */ +); + +extern Bool XQueryExtension( + Display* /* display */, + _Xconst char* /* name */, + int* /* major_opcode_return */, + int* /* first_event_return */, + int* /* first_error_return */ +); + +extern int XQueryKeymap( + Display* /* display */, + char [32] /* keys_return */ +); + +extern Bool XQueryPointer( + Display* /* display */, + Window /* w */, + Window* /* root_return */, + Window* /* child_return */, + int* /* root_x_return */, + int* /* root_y_return */, + int* /* win_x_return */, + int* /* win_y_return */, + unsigned int* /* mask_return */ +); + +extern int XQueryTextExtents( + Display* /* display */, + XID /* font_ID */, + _Xconst char* /* string */, + int /* nchars */, + int* /* direction_return */, + int* /* font_ascent_return */, + int* /* font_descent_return */, + XCharStruct* /* overall_return */ +); + +extern int XQueryTextExtents16( + Display* /* display */, + XID /* font_ID */, + _Xconst XChar2b* /* string */, + int /* nchars */, + int* /* direction_return */, + int* /* font_ascent_return */, + int* /* font_descent_return */, + XCharStruct* /* overall_return */ +); + +extern Status XQueryTree( + Display* /* display */, + Window /* w */, + Window* /* root_return */, + Window* /* parent_return */, + Window** /* children_return */, + unsigned int* /* nchildren_return */ +); + +extern int XRaiseWindow( + Display* /* display */, + Window /* w */ +); + +extern int XReadBitmapFile( + Display* /* display */, + Drawable /* d */, + _Xconst char* /* filename */, + unsigned int* /* width_return */, + unsigned int* /* height_return */, + Pixmap* /* bitmap_return */, + int* /* x_hot_return */, + int* /* y_hot_return */ +); + +extern int XReadBitmapFileData( + _Xconst char* /* filename */, + unsigned int* /* width_return */, + unsigned int* /* height_return */, + unsigned char** /* data_return */, + int* /* x_hot_return */, + int* /* y_hot_return */ +); + +extern int XRebindKeysym( + Display* /* display */, + KeySym /* keysym */, + KeySym* /* list */, + int /* mod_count */, + _Xconst unsigned char* /* string */, + int /* bytes_string */ +); + +extern int XRecolorCursor( + Display* /* display */, + Cursor /* cursor */, + XColor* /* foreground_color */, + XColor* /* background_color */ +); + +extern int XRefreshKeyboardMapping( + XMappingEvent* /* event_map */ +); + +extern int XRemoveFromSaveSet( + Display* /* display */, + Window /* w */ +); + +extern int XRemoveHost( + Display* /* display */, + XHostAddress* /* host */ +); + +extern int XRemoveHosts( + Display* /* display */, + XHostAddress* /* hosts */, + int /* num_hosts */ +); + +extern int XReparentWindow( + Display* /* display */, + Window /* w */, + Window /* parent */, + int /* x */, + int /* y */ +); + +extern int XResetScreenSaver( + Display* /* display */ +); + +extern int XResizeWindow( + Display* /* display */, + Window /* w */, + unsigned int /* width */, + unsigned int /* height */ +); + +extern int XRestackWindows( + Display* /* display */, + Window* /* windows */, + int /* nwindows */ +); + +extern int XRotateBuffers( + Display* /* display */, + int /* rotate */ +); + +extern int XRotateWindowProperties( + Display* /* display */, + Window /* w */, + Atom* /* properties */, + int /* num_prop */, + int /* npositions */ +); + +extern int XScreenCount( + Display* /* display */ +); + +extern int XSelectInput( + Display* /* display */, + Window /* w */, + long /* event_mask */ +); + +extern Status XSendEvent( + Display* /* display */, + Window /* w */, + Bool /* propagate */, + long /* event_mask */, + XEvent* /* event_send */ +); + +extern int XSetAccessControl( + Display* /* display */, + int /* mode */ +); + +extern int XSetArcMode( + Display* /* display */, + GC /* gc */, + int /* arc_mode */ +); + +extern int XSetBackground( + Display* /* display */, + GC /* gc */, + unsigned long /* background */ +); + +extern int XSetClipMask( + Display* /* display */, + GC /* gc */, + Pixmap /* pixmap */ +); + +extern int XSetClipOrigin( + Display* /* display */, + GC /* gc */, + int /* clip_x_origin */, + int /* clip_y_origin */ +); + +extern int XSetClipRectangles( + Display* /* display */, + GC /* gc */, + int /* clip_x_origin */, + int /* clip_y_origin */, + XRectangle* /* rectangles */, + int /* n */, + int /* ordering */ +); + +extern int XSetCloseDownMode( + Display* /* display */, + int /* close_mode */ +); + +extern int XSetCommand( + Display* /* display */, + Window /* w */, + char** /* argv */, + int /* argc */ +); + +extern int XSetDashes( + Display* /* display */, + GC /* gc */, + int /* dash_offset */, + _Xconst char* /* dash_list */, + int /* n */ +); + +extern int XSetFillRule( + Display* /* display */, + GC /* gc */, + int /* fill_rule */ +); + +extern int XSetFillStyle( + Display* /* display */, + GC /* gc */, + int /* fill_style */ +); + +extern int XSetFont( + Display* /* display */, + GC /* gc */, + Font /* font */ +); + +extern int XSetFontPath( + Display* /* display */, + char** /* directories */, + int /* ndirs */ +); + +extern int XSetForeground( + Display* /* display */, + GC /* gc */, + unsigned long /* foreground */ +); + +extern int XSetFunction( + Display* /* display */, + GC /* gc */, + int /* function */ +); + +extern int XSetGraphicsExposures( + Display* /* display */, + GC /* gc */, + Bool /* graphics_exposures */ +); + +extern int XSetIconName( + Display* /* display */, + Window /* w */, + _Xconst char* /* icon_name */ +); + +extern int XSetInputFocus( + Display* /* display */, + Window /* focus */, + int /* revert_to */, + Time /* time */ +); + +extern int XSetLineAttributes( + Display* /* display */, + GC /* gc */, + unsigned int /* line_width */, + int /* line_style */, + int /* cap_style */, + int /* join_style */ +); + +extern int XSetModifierMapping( + Display* /* display */, + XModifierKeymap* /* modmap */ +); + +extern int XSetPlaneMask( + Display* /* display */, + GC /* gc */, + unsigned long /* plane_mask */ +); + +extern int XSetPointerMapping( + Display* /* display */, + _Xconst unsigned char* /* map */, + int /* nmap */ +); + +extern int XSetScreenSaver( + Display* /* display */, + int /* timeout */, + int /* interval */, + int /* prefer_blanking */, + int /* allow_exposures */ +); + +extern int XSetSelectionOwner( + Display* /* display */, + Atom /* selection */, + Window /* owner */, + Time /* time */ +); + +extern int XSetState( + Display* /* display */, + GC /* gc */, + unsigned long /* foreground */, + unsigned long /* background */, + int /* function */, + unsigned long /* plane_mask */ +); + +extern int XSetStipple( + Display* /* display */, + GC /* gc */, + Pixmap /* stipple */ +); + +extern int XSetSubwindowMode( + Display* /* display */, + GC /* gc */, + int /* subwindow_mode */ +); + +extern int XSetTSOrigin( + Display* /* display */, + GC /* gc */, + int /* ts_x_origin */, + int /* ts_y_origin */ +); + +extern int XSetTile( + Display* /* display */, + GC /* gc */, + Pixmap /* tile */ +); + +extern int XSetWindowBackground( + Display* /* display */, + Window /* w */, + unsigned long /* background_pixel */ +); + +extern int XSetWindowBackgroundPixmap( + Display* /* display */, + Window /* w */, + Pixmap /* background_pixmap */ +); + +extern int XSetWindowBorder( + Display* /* display */, + Window /* w */, + unsigned long /* border_pixel */ +); + +extern int XSetWindowBorderPixmap( + Display* /* display */, + Window /* w */, + Pixmap /* border_pixmap */ +); + +extern int XSetWindowBorderWidth( + Display* /* display */, + Window /* w */, + unsigned int /* width */ +); + +extern int XSetWindowColormap( + Display* /* display */, + Window /* w */, + Colormap /* colormap */ +); + +extern int XStoreBuffer( + Display* /* display */, + _Xconst char* /* bytes */, + int /* nbytes */, + int /* buffer */ +); + +extern int XStoreBytes( + Display* /* display */, + _Xconst char* /* bytes */, + int /* nbytes */ +); + +extern int XStoreColor( + Display* /* display */, + Colormap /* colormap */, + XColor* /* color */ +); + +extern int XStoreColors( + Display* /* display */, + Colormap /* colormap */, + XColor* /* color */, + int /* ncolors */ +); + +extern int XStoreName( + Display* /* display */, + Window /* w */, + _Xconst char* /* window_name */ +); + +extern int XStoreNamedColor( + Display* /* display */, + Colormap /* colormap */, + _Xconst char* /* color */, + unsigned long /* pixel */, + int /* flags */ +); + +extern int XSync( + Display* /* display */, + Bool /* discard */ +); + +extern int XTextExtents( + XFontStruct* /* font_struct */, + _Xconst char* /* string */, + int /* nchars */, + int* /* direction_return */, + int* /* font_ascent_return */, + int* /* font_descent_return */, + XCharStruct* /* overall_return */ +); + +extern int XTextExtents16( + XFontStruct* /* font_struct */, + _Xconst XChar2b* /* string */, + int /* nchars */, + int* /* direction_return */, + int* /* font_ascent_return */, + int* /* font_descent_return */, + XCharStruct* /* overall_return */ +); + +extern int XTextWidth( + XFontStruct* /* font_struct */, + _Xconst char* /* string */, + int /* count */ +); + +extern int XTextWidth16( + XFontStruct* /* font_struct */, + _Xconst XChar2b* /* string */, + int /* count */ +); + +extern Bool XTranslateCoordinates( + Display* /* display */, + Window /* src_w */, + Window /* dest_w */, + int /* src_x */, + int /* src_y */, + int* /* dest_x_return */, + int* /* dest_y_return */, + Window* /* child_return */ +); + +extern int XUndefineCursor( + Display* /* display */, + Window /* w */ +); + +extern int XUngrabButton( + Display* /* display */, + unsigned int /* button */, + unsigned int /* modifiers */, + Window /* grab_window */ +); + +extern int XUngrabKey( + Display* /* display */, + int /* keycode */, + unsigned int /* modifiers */, + Window /* grab_window */ +); + +extern int XUngrabKeyboard( + Display* /* display */, + Time /* time */ +); + +extern int XUngrabPointer( + Display* /* display */, + Time /* time */ +); + +extern int XUngrabServer( + Display* /* display */ +); + +extern int XUninstallColormap( + Display* /* display */, + Colormap /* colormap */ +); + +extern int XUnloadFont( + Display* /* display */, + Font /* font */ +); + +extern int XUnmapSubwindows( + Display* /* display */, + Window /* w */ +); + +extern int XUnmapWindow( + Display* /* display */, + Window /* w */ +); + +extern int XVendorRelease( + Display* /* display */ +); + +extern int XWarpPointer( + Display* /* display */, + Window /* src_w */, + Window /* dest_w */, + int /* src_x */, + int /* src_y */, + unsigned int /* src_width */, + unsigned int /* src_height */, + int /* dest_x */, + int /* dest_y */ +); + +extern int XWidthMMOfScreen( + Screen* /* screen */ +); + +extern int XWidthOfScreen( + Screen* /* screen */ +); + +extern int XWindowEvent( + Display* /* display */, + Window /* w */, + long /* event_mask */, + XEvent* /* event_return */ +); + +extern int XWriteBitmapFile( + Display* /* display */, + _Xconst char* /* filename */, + Pixmap /* bitmap */, + unsigned int /* width */, + unsigned int /* height */, + int /* x_hot */, + int /* y_hot */ +); + +extern Bool XSupportsLocale (void); + +extern char *XSetLocaleModifiers( + const char* /* modifier_list */ +); + +extern XOM XOpenOM( + Display* /* display */, + struct _XrmHashBucketRec* /* rdb */, + _Xconst char* /* res_name */, + _Xconst char* /* res_class */ +); + +extern Status XCloseOM( + XOM /* om */ +); + +extern char *XSetOMValues( + XOM /* om */, + ... +) _X_SENTINEL(0); + +extern char *XGetOMValues( + XOM /* om */, + ... +) _X_SENTINEL(0); + +extern Display *XDisplayOfOM( + XOM /* om */ +); + +extern char *XLocaleOfOM( + XOM /* om */ +); + +extern XOC XCreateOC( + XOM /* om */, + ... +) _X_SENTINEL(0); + +extern void XDestroyOC( + XOC /* oc */ +); + +extern XOM XOMOfOC( + XOC /* oc */ +); + +extern char *XSetOCValues( + XOC /* oc */, + ... +) _X_SENTINEL(0); + +extern char *XGetOCValues( + XOC /* oc */, + ... +) _X_SENTINEL(0); + +extern XFontSet XCreateFontSet( + Display* /* display */, + _Xconst char* /* base_font_name_list */, + char*** /* missing_charset_list */, + int* /* missing_charset_count */, + char** /* def_string */ +); + +extern void XFreeFontSet( + Display* /* display */, + XFontSet /* font_set */ +); + +extern int XFontsOfFontSet( + XFontSet /* font_set */, + XFontStruct*** /* font_struct_list */, + char*** /* font_name_list */ +); + +extern char *XBaseFontNameListOfFontSet( + XFontSet /* font_set */ +); + +extern char *XLocaleOfFontSet( + XFontSet /* font_set */ +); + +extern Bool XContextDependentDrawing( + XFontSet /* font_set */ +); + +extern Bool XDirectionalDependentDrawing( + XFontSet /* font_set */ +); + +extern Bool XContextualDrawing( + XFontSet /* font_set */ +); + +extern XFontSetExtents *XExtentsOfFontSet( + XFontSet /* font_set */ +); + +extern int XmbTextEscapement( + XFontSet /* font_set */, + _Xconst char* /* text */, + int /* bytes_text */ +); + +extern int XwcTextEscapement( + XFontSet /* font_set */, + _Xconst wchar_t* /* text */, + int /* num_wchars */ +); + +extern int Xutf8TextEscapement( + XFontSet /* font_set */, + _Xconst char* /* text */, + int /* bytes_text */ +); + +extern int XmbTextExtents( + XFontSet /* font_set */, + _Xconst char* /* text */, + int /* bytes_text */, + XRectangle* /* overall_ink_return */, + XRectangle* /* overall_logical_return */ +); + +extern int XwcTextExtents( + XFontSet /* font_set */, + _Xconst wchar_t* /* text */, + int /* num_wchars */, + XRectangle* /* overall_ink_return */, + XRectangle* /* overall_logical_return */ +); + +extern int Xutf8TextExtents( + XFontSet /* font_set */, + _Xconst char* /* text */, + int /* bytes_text */, + XRectangle* /* overall_ink_return */, + XRectangle* /* overall_logical_return */ +); + +extern Status XmbTextPerCharExtents( + XFontSet /* font_set */, + _Xconst char* /* text */, + int /* bytes_text */, + XRectangle* /* ink_extents_buffer */, + XRectangle* /* logical_extents_buffer */, + int /* buffer_size */, + int* /* num_chars */, + XRectangle* /* overall_ink_return */, + XRectangle* /* overall_logical_return */ +); + +extern Status XwcTextPerCharExtents( + XFontSet /* font_set */, + _Xconst wchar_t* /* text */, + int /* num_wchars */, + XRectangle* /* ink_extents_buffer */, + XRectangle* /* logical_extents_buffer */, + int /* buffer_size */, + int* /* num_chars */, + XRectangle* /* overall_ink_return */, + XRectangle* /* overall_logical_return */ +); + +extern Status Xutf8TextPerCharExtents( + XFontSet /* font_set */, + _Xconst char* /* text */, + int /* bytes_text */, + XRectangle* /* ink_extents_buffer */, + XRectangle* /* logical_extents_buffer */, + int /* buffer_size */, + int* /* num_chars */, + XRectangle* /* overall_ink_return */, + XRectangle* /* overall_logical_return */ +); + +extern void XmbDrawText( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + XmbTextItem* /* text_items */, + int /* nitems */ +); + +extern void XwcDrawText( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + XwcTextItem* /* text_items */, + int /* nitems */ +); + +extern void Xutf8DrawText( + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + XmbTextItem* /* text_items */, + int /* nitems */ +); + +extern void XmbDrawString( + Display* /* display */, + Drawable /* d */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst char* /* text */, + int /* bytes_text */ +); + +extern void XwcDrawString( + Display* /* display */, + Drawable /* d */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst wchar_t* /* text */, + int /* num_wchars */ +); + +extern void Xutf8DrawString( + Display* /* display */, + Drawable /* d */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst char* /* text */, + int /* bytes_text */ +); + +extern void XmbDrawImageString( + Display* /* display */, + Drawable /* d */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst char* /* text */, + int /* bytes_text */ +); + +extern void XwcDrawImageString( + Display* /* display */, + Drawable /* d */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst wchar_t* /* text */, + int /* num_wchars */ +); + +extern void Xutf8DrawImageString( + Display* /* display */, + Drawable /* d */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst char* /* text */, + int /* bytes_text */ +); + +extern XIM XOpenIM( + Display* /* dpy */, + struct _XrmHashBucketRec* /* rdb */, + char* /* res_name */, + char* /* res_class */ +); + +extern Status XCloseIM( + XIM /* im */ +); + +extern char *XGetIMValues( + XIM /* im */, ... +) _X_SENTINEL(0); + +extern char *XSetIMValues( + XIM /* im */, ... +) _X_SENTINEL(0); + +extern Display *XDisplayOfIM( + XIM /* im */ +); + +extern char *XLocaleOfIM( + XIM /* im*/ +); + +extern XIC XCreateIC( + XIM /* im */, ... +) _X_SENTINEL(0); + +extern void XDestroyIC( + XIC /* ic */ +); + +extern void XSetICFocus( + XIC /* ic */ +); + +extern void XUnsetICFocus( + XIC /* ic */ +); + +extern wchar_t *XwcResetIC( + XIC /* ic */ +); + +extern char *XmbResetIC( + XIC /* ic */ +); + +extern char *Xutf8ResetIC( + XIC /* ic */ +); + +extern char *XSetICValues( + XIC /* ic */, ... +) _X_SENTINEL(0); + +extern char *XGetICValues( + XIC /* ic */, ... +) _X_SENTINEL(0); + +extern XIM XIMOfIC( + XIC /* ic */ +); + +extern Bool XFilterEvent( + XEvent* /* event */, + Window /* window */ +); + +extern int XmbLookupString( + XIC /* ic */, + XKeyPressedEvent* /* event */, + char* /* buffer_return */, + int /* bytes_buffer */, + KeySym* /* keysym_return */, + Status* /* status_return */ +); + +extern int XwcLookupString( + XIC /* ic */, + XKeyPressedEvent* /* event */, + wchar_t* /* buffer_return */, + int /* wchars_buffer */, + KeySym* /* keysym_return */, + Status* /* status_return */ +); + +extern int Xutf8LookupString( + XIC /* ic */, + XKeyPressedEvent* /* event */, + char* /* buffer_return */, + int /* bytes_buffer */, + KeySym* /* keysym_return */, + Status* /* status_return */ +); + +extern XVaNestedList XVaCreateNestedList( + int /*unused*/, ... +) _X_SENTINEL(0); + +/* internal connections for IMs */ + +extern Bool XRegisterIMInstantiateCallback( + Display* /* dpy */, + struct _XrmHashBucketRec* /* rdb */, + char* /* res_name */, + char* /* res_class */, + XIDProc /* callback */, + XPointer /* client_data */ +); + +extern Bool XUnregisterIMInstantiateCallback( + Display* /* dpy */, + struct _XrmHashBucketRec* /* rdb */, + char* /* res_name */, + char* /* res_class */, + XIDProc /* callback */, + XPointer /* client_data */ +); + +typedef void (*XConnectionWatchProc)( + Display* /* dpy */, + XPointer /* client_data */, + int /* fd */, + Bool /* opening */, /* open or close flag */ + XPointer* /* watch_data */ /* open sets, close uses */ +); + + +extern Status XInternalConnectionNumbers( + Display* /* dpy */, + int** /* fd_return */, + int* /* count_return */ +); + +extern void XProcessInternalConnection( + Display* /* dpy */, + int /* fd */ +); + +extern Status XAddConnectionWatch( + Display* /* dpy */, + XConnectionWatchProc /* callback */, + XPointer /* client_data */ +); + +extern void XRemoveConnectionWatch( + Display* /* dpy */, + XConnectionWatchProc /* callback */, + XPointer /* client_data */ +); + +extern void XSetAuthorization( + char * /* name */, + int /* namelen */, + char * /* data */, + int /* datalen */ +); + +extern int _Xmbtowc( + wchar_t * /* wstr */, + char * /* str */, + int /* len */ +); + +extern int _Xwctomb( + char * /* str */, + wchar_t /* wc */ +); + +extern Bool XGetEventData( + Display* /* dpy */, + XGenericEventCookie* /* cookie*/ +); + +extern void XFreeEventData( + Display* /* dpy */, + XGenericEventCookie* /* cookie*/ +); + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +_XFUNCPROTOEND + +#endif /* _X11_XLIB_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/Xosdefs.h b/thirdparty/linuxbsd_headers/X11/Xosdefs.h new file mode 100644 index 0000000000..33eaee4360 --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/Xosdefs.h @@ -0,0 +1,116 @@ +/* + * O/S-dependent (mis)feature macro definitions + * +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + */ + +#ifndef _XOSDEFS_H_ +# define _XOSDEFS_H_ + +/* + * X_NOT_POSIX means does not have POSIX header files. Lack of this + * symbol does NOT mean that the POSIX environment is the default. + * You may still have to define _POSIX_SOURCE to get it. + */ + + +# ifdef _SCO_DS +# ifndef __SCO__ +# define __SCO__ +# endif +# endif + +# ifdef __i386__ +# ifdef SYSV +# if !defined(__SCO__) && \ + !defined(__UNIXWARE__) && !defined(__sun) +# if !defined(_POSIX_SOURCE) +# define X_NOT_POSIX +# endif +# endif +# endif +# endif + +# ifdef __sun +/* Imake configs define SVR4 on Solaris, but cc & gcc only define __SVR4 + * This check allows non-Imake configured programs to build correctly. + */ +# if defined(__SVR4) && !defined(SVR4) +# define SVR4 1 +# endif +# ifdef SVR4 +/* define this to whatever it needs to be */ +# define X_POSIX_C_SOURCE 199300L +# endif +# endif + +# ifdef WIN32 +# ifndef _POSIX_ +# define X_NOT_POSIX +# endif +# endif + + +# ifdef __APPLE__ +# define NULL_NOT_ZERO + +/* Defining any of these will sanitize the namespace to JUST want is defined by + * that particular standard. If that happens, we don't get some expected + * prototypes, typedefs, etc (like fd_mask). We can define _DARWIN_C_SOURCE to + * loosen our belts a tad. + */ +# if defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) +# ifndef _DARWIN_C_SOURCE +# define _DARWIN_C_SOURCE +# endif +# endif + +# endif + +# ifdef __GNU__ +# ifndef PATH_MAX +# define PATH_MAX 4096 +# endif +# ifndef MAXPATHLEN +# define MAXPATHLEN 4096 +# endif +# endif + +# if defined(__SCO__) || defined(__UNIXWARE__) +# ifndef PATH_MAX +# define PATH_MAX 1024 +# endif +# ifndef MAXPATHLEN +# define MAXPATHLEN 1024 +# endif +# endif + +# if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) \ + || defined(__APPLE__) || defined(__DragonFly__) +# ifndef CSRG_BASED +# define CSRG_BASED +# endif +# endif + +#endif /* _XOSDEFS_H_ */ + diff --git a/thirdparty/linuxbsd_headers/X11/Xutil.h b/thirdparty/linuxbsd_headers/X11/Xutil.h new file mode 100644 index 0000000000..62cdf55563 --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/Xutil.h @@ -0,0 +1,838 @@ + +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _X11_XUTIL_H_ +#define _X11_XUTIL_H_ + +/* You must include <X11/Xlib.h> before including this file */ +#include <X11/Xlib.h> +#include <X11/keysym.h> + +/* The Xlib structs are full of implicit padding to properly align members. + We can't clean that up without breaking ABI, so tell clang not to bother + complaining about it. */ +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +/* + * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding + * value (x, y, width, height) was found in the parsed string. + */ +#define NoValue 0x0000 +#define XValue 0x0001 +#define YValue 0x0002 +#define WidthValue 0x0004 +#define HeightValue 0x0008 +#define AllValues 0x000F +#define XNegative 0x0010 +#define YNegative 0x0020 + +/* + * new version containing base_width, base_height, and win_gravity fields; + * used with WM_NORMAL_HINTS. + */ +typedef struct { + long flags; /* marks which fields in this structure are defined */ + int x, y; /* obsolete for new window mgrs, but clients */ + int width, height; /* should set so old wm's don't mess up */ + int min_width, min_height; + int max_width, max_height; + int width_inc, height_inc; + struct { + int x; /* numerator */ + int y; /* denominator */ + } min_aspect, max_aspect; + int base_width, base_height; /* added by ICCCM version 1 */ + int win_gravity; /* added by ICCCM version 1 */ +} XSizeHints; + +/* + * The next block of definitions are for window manager properties that + * clients and applications use for communication. + */ + +/* flags argument in size hints */ +#define USPosition (1L << 0) /* user specified x, y */ +#define USSize (1L << 1) /* user specified width, height */ + +#define PPosition (1L << 2) /* program specified position */ +#define PSize (1L << 3) /* program specified size */ +#define PMinSize (1L << 4) /* program specified minimum size */ +#define PMaxSize (1L << 5) /* program specified maximum size */ +#define PResizeInc (1L << 6) /* program specified resize increments */ +#define PAspect (1L << 7) /* program specified min and max aspect ratios */ +#define PBaseSize (1L << 8) /* program specified base for incrementing */ +#define PWinGravity (1L << 9) /* program specified window gravity */ + +/* obsolete */ +#define PAllHints (PPosition|PSize|PMinSize|PMaxSize|PResizeInc|PAspect) + + + +typedef struct { + long flags; /* marks which fields in this structure are defined */ + Bool input; /* does this application rely on the window manager to + get keyboard input? */ + int initial_state; /* see below */ + Pixmap icon_pixmap; /* pixmap to be used as icon */ + Window icon_window; /* window to be used as icon */ + int icon_x, icon_y; /* initial position of icon */ + Pixmap icon_mask; /* icon mask bitmap */ + XID window_group; /* id of related window group */ + /* this structure may be extended in the future */ +} XWMHints; + +/* definition for flags of XWMHints */ + +#define InputHint (1L << 0) +#define StateHint (1L << 1) +#define IconPixmapHint (1L << 2) +#define IconWindowHint (1L << 3) +#define IconPositionHint (1L << 4) +#define IconMaskHint (1L << 5) +#define WindowGroupHint (1L << 6) +#define AllHints (InputHint|StateHint|IconPixmapHint|IconWindowHint| \ +IconPositionHint|IconMaskHint|WindowGroupHint) +#define XUrgencyHint (1L << 8) + +/* definitions for initial window state */ +#define WithdrawnState 0 /* for windows that are not mapped */ +#define NormalState 1 /* most applications want to start this way */ +#define IconicState 3 /* application wants to start as an icon */ + +/* + * Obsolete states no longer defined by ICCCM + */ +#define DontCareState 0 /* don't know or care */ +#define ZoomState 2 /* application wants to start zoomed */ +#define InactiveState 4 /* application believes it is seldom used; */ + /* some wm's may put it on inactive menu */ + + +/* + * new structure for manipulating TEXT properties; used with WM_NAME, + * WM_ICON_NAME, WM_CLIENT_MACHINE, and WM_COMMAND. + */ +typedef struct { + unsigned char *value; /* same as Property routines */ + Atom encoding; /* prop type */ + int format; /* prop data format: 8, 16, or 32 */ + unsigned long nitems; /* number of data items in value */ +} XTextProperty; + +#define XNoMemory -1 +#define XLocaleNotSupported -2 +#define XConverterNotFound -3 + +typedef enum { + XStringStyle, /* STRING */ + XCompoundTextStyle, /* COMPOUND_TEXT */ + XTextStyle, /* text in owner's encoding (current locale)*/ + XStdICCTextStyle, /* STRING, else COMPOUND_TEXT */ + /* The following is an XFree86 extension, introduced in November 2000 */ + XUTF8StringStyle /* UTF8_STRING */ +} XICCEncodingStyle; + +typedef struct { + int min_width, min_height; + int max_width, max_height; + int width_inc, height_inc; +} XIconSize; + +typedef struct { + char *res_name; + char *res_class; +} XClassHint; + +#ifdef XUTIL_DEFINE_FUNCTIONS +extern int XDestroyImage( + XImage *ximage); +extern unsigned long XGetPixel( + XImage *ximage, + int x, int y); +extern int XPutPixel( + XImage *ximage, + int x, int y, + unsigned long pixel); +extern XImage *XSubImage( + XImage *ximage, + int x, int y, + unsigned int width, unsigned int height); +extern int XAddPixel( + XImage *ximage, + long value); +#else +/* + * These macros are used to give some sugar to the image routines so that + * naive people are more comfortable with them. + */ +#define XDestroyImage(ximage) \ + ((*((ximage)->f.destroy_image))((ximage))) +#define XGetPixel(ximage, x, y) \ + ((*((ximage)->f.get_pixel))((ximage), (x), (y))) +#define XPutPixel(ximage, x, y, pixel) \ + ((*((ximage)->f.put_pixel))((ximage), (x), (y), (pixel))) +#define XSubImage(ximage, x, y, width, height) \ + ((*((ximage)->f.sub_image))((ximage), (x), (y), (width), (height))) +#define XAddPixel(ximage, value) \ + ((*((ximage)->f.add_pixel))((ximage), (value))) +#endif + +/* + * Compose sequence status structure, used in calling XLookupString. + */ +typedef struct _XComposeStatus { + XPointer compose_ptr; /* state table pointer */ + int chars_matched; /* match state */ +} XComposeStatus; + +/* + * Keysym macros, used on Keysyms to test for classes of symbols + */ +#define IsKeypadKey(keysym) \ + (((KeySym)(keysym) >= XK_KP_Space) && ((KeySym)(keysym) <= XK_KP_Equal)) + +#define IsPrivateKeypadKey(keysym) \ + (((KeySym)(keysym) >= 0x11000000) && ((KeySym)(keysym) <= 0x1100FFFF)) + +#define IsCursorKey(keysym) \ + (((KeySym)(keysym) >= XK_Home) && ((KeySym)(keysym) < XK_Select)) + +#define IsPFKey(keysym) \ + (((KeySym)(keysym) >= XK_KP_F1) && ((KeySym)(keysym) <= XK_KP_F4)) + +#define IsFunctionKey(keysym) \ + (((KeySym)(keysym) >= XK_F1) && ((KeySym)(keysym) <= XK_F35)) + +#define IsMiscFunctionKey(keysym) \ + (((KeySym)(keysym) >= XK_Select) && ((KeySym)(keysym) <= XK_Break)) + +#ifdef XK_XKB_KEYS +#define IsModifierKey(keysym) \ + ((((KeySym)(keysym) >= XK_Shift_L) && ((KeySym)(keysym) <= XK_Hyper_R)) \ + || (((KeySym)(keysym) >= XK_ISO_Lock) && \ + ((KeySym)(keysym) <= XK_ISO_Level5_Lock)) \ + || ((KeySym)(keysym) == XK_Mode_switch) \ + || ((KeySym)(keysym) == XK_Num_Lock)) +#else +#define IsModifierKey(keysym) \ + ((((KeySym)(keysym) >= XK_Shift_L) && ((KeySym)(keysym) <= XK_Hyper_R)) \ + || ((KeySym)(keysym) == XK_Mode_switch) \ + || ((KeySym)(keysym) == XK_Num_Lock)) +#endif +/* + * opaque reference to Region data type + */ +typedef struct _XRegion *Region; + +/* Return values from XRectInRegion() */ + +#define RectangleOut 0 +#define RectangleIn 1 +#define RectanglePart 2 + + +/* + * Information used by the visual utility routines to find desired visual + * type from the many visuals a display may support. + */ + +typedef struct { + Visual *visual; + VisualID visualid; + int screen; + int depth; +#if defined(__cplusplus) || defined(c_plusplus) + int c_class; /* C++ */ +#else + int class; +#endif + unsigned long red_mask; + unsigned long green_mask; + unsigned long blue_mask; + int colormap_size; + int bits_per_rgb; +} XVisualInfo; + +#define VisualNoMask 0x0 +#define VisualIDMask 0x1 +#define VisualScreenMask 0x2 +#define VisualDepthMask 0x4 +#define VisualClassMask 0x8 +#define VisualRedMaskMask 0x10 +#define VisualGreenMaskMask 0x20 +#define VisualBlueMaskMask 0x40 +#define VisualColormapSizeMask 0x80 +#define VisualBitsPerRGBMask 0x100 +#define VisualAllMask 0x1FF + +/* + * This defines a window manager property that clients may use to + * share standard color maps of type RGB_COLOR_MAP: + */ +typedef struct { + Colormap colormap; + unsigned long red_max; + unsigned long red_mult; + unsigned long green_max; + unsigned long green_mult; + unsigned long blue_max; + unsigned long blue_mult; + unsigned long base_pixel; + VisualID visualid; /* added by ICCCM version 1 */ + XID killid; /* added by ICCCM version 1 */ +} XStandardColormap; + +#define ReleaseByFreeingColormap ((XID) 1L) /* for killid field above */ + + +/* + * return codes for XReadBitmapFile and XWriteBitmapFile + */ +#define BitmapSuccess 0 +#define BitmapOpenFailed 1 +#define BitmapFileInvalid 2 +#define BitmapNoMemory 3 + +/**************************************************************** + * + * Context Management + * + ****************************************************************/ + + +/* Associative lookup table return codes */ + +#define XCSUCCESS 0 /* No error. */ +#define XCNOMEM 1 /* Out of memory */ +#define XCNOENT 2 /* No entry in table */ + +typedef int XContext; + +#define XUniqueContext() ((XContext) XrmUniqueQuark()) +#define XStringToContext(string) ((XContext) XrmStringToQuark(string)) + +_XFUNCPROTOBEGIN + +/* The following declarations are alphabetized. */ + +extern XClassHint *XAllocClassHint ( + void +); + +extern XIconSize *XAllocIconSize ( + void +); + +extern XSizeHints *XAllocSizeHints ( + void +); + +extern XStandardColormap *XAllocStandardColormap ( + void +); + +extern XWMHints *XAllocWMHints ( + void +); + +extern int XClipBox( + Region /* r */, + XRectangle* /* rect_return */ +); + +extern Region XCreateRegion( + void +); + +extern const char *XDefaultString (void); + +extern int XDeleteContext( + Display* /* display */, + XID /* rid */, + XContext /* context */ +); + +extern int XDestroyRegion( + Region /* r */ +); + +extern int XEmptyRegion( + Region /* r */ +); + +extern int XEqualRegion( + Region /* r1 */, + Region /* r2 */ +); + +extern int XFindContext( + Display* /* display */, + XID /* rid */, + XContext /* context */, + XPointer* /* data_return */ +); + +extern Status XGetClassHint( + Display* /* display */, + Window /* w */, + XClassHint* /* class_hints_return */ +); + +extern Status XGetIconSizes( + Display* /* display */, + Window /* w */, + XIconSize** /* size_list_return */, + int* /* count_return */ +); + +extern Status XGetNormalHints( + Display* /* display */, + Window /* w */, + XSizeHints* /* hints_return */ +); + +extern Status XGetRGBColormaps( + Display* /* display */, + Window /* w */, + XStandardColormap** /* stdcmap_return */, + int* /* count_return */, + Atom /* property */ +); + +extern Status XGetSizeHints( + Display* /* display */, + Window /* w */, + XSizeHints* /* hints_return */, + Atom /* property */ +); + +extern Status XGetStandardColormap( + Display* /* display */, + Window /* w */, + XStandardColormap* /* colormap_return */, + Atom /* property */ +); + +extern Status XGetTextProperty( + Display* /* display */, + Window /* window */, + XTextProperty* /* text_prop_return */, + Atom /* property */ +); + +extern XVisualInfo *XGetVisualInfo( + Display* /* display */, + long /* vinfo_mask */, + XVisualInfo* /* vinfo_template */, + int* /* nitems_return */ +); + +extern Status XGetWMClientMachine( + Display* /* display */, + Window /* w */, + XTextProperty* /* text_prop_return */ +); + +extern XWMHints *XGetWMHints( + Display* /* display */, + Window /* w */ +); + +extern Status XGetWMIconName( + Display* /* display */, + Window /* w */, + XTextProperty* /* text_prop_return */ +); + +extern Status XGetWMName( + Display* /* display */, + Window /* w */, + XTextProperty* /* text_prop_return */ +); + +extern Status XGetWMNormalHints( + Display* /* display */, + Window /* w */, + XSizeHints* /* hints_return */, + long* /* supplied_return */ +); + +extern Status XGetWMSizeHints( + Display* /* display */, + Window /* w */, + XSizeHints* /* hints_return */, + long* /* supplied_return */, + Atom /* property */ +); + +extern Status XGetZoomHints( + Display* /* display */, + Window /* w */, + XSizeHints* /* zhints_return */ +); + +extern int XIntersectRegion( + Region /* sra */, + Region /* srb */, + Region /* dr_return */ +); + +extern void XConvertCase( + KeySym /* sym */, + KeySym* /* lower */, + KeySym* /* upper */ +); + +extern int XLookupString( + XKeyEvent* /* event_struct */, + char* /* buffer_return */, + int /* bytes_buffer */, + KeySym* /* keysym_return */, + XComposeStatus* /* status_in_out */ +); + +extern Status XMatchVisualInfo( + Display* /* display */, + int /* screen */, + int /* depth */, + int /* class */, + XVisualInfo* /* vinfo_return */ +); + +extern int XOffsetRegion( + Region /* r */, + int /* dx */, + int /* dy */ +); + +extern Bool XPointInRegion( + Region /* r */, + int /* x */, + int /* y */ +); + +extern Region XPolygonRegion( + XPoint* /* points */, + int /* n */, + int /* fill_rule */ +); + +extern int XRectInRegion( + Region /* r */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */ +); + +extern int XSaveContext( + Display* /* display */, + XID /* rid */, + XContext /* context */, + _Xconst char* /* data */ +); + +extern int XSetClassHint( + Display* /* display */, + Window /* w */, + XClassHint* /* class_hints */ +); + +extern int XSetIconSizes( + Display* /* display */, + Window /* w */, + XIconSize* /* size_list */, + int /* count */ +); + +extern int XSetNormalHints( + Display* /* display */, + Window /* w */, + XSizeHints* /* hints */ +); + +extern void XSetRGBColormaps( + Display* /* display */, + Window /* w */, + XStandardColormap* /* stdcmaps */, + int /* count */, + Atom /* property */ +); + +extern int XSetSizeHints( + Display* /* display */, + Window /* w */, + XSizeHints* /* hints */, + Atom /* property */ +); + +extern int XSetStandardProperties( + Display* /* display */, + Window /* w */, + _Xconst char* /* window_name */, + _Xconst char* /* icon_name */, + Pixmap /* icon_pixmap */, + char** /* argv */, + int /* argc */, + XSizeHints* /* hints */ +); + +extern void XSetTextProperty( + Display* /* display */, + Window /* w */, + XTextProperty* /* text_prop */, + Atom /* property */ +); + +extern void XSetWMClientMachine( + Display* /* display */, + Window /* w */, + XTextProperty* /* text_prop */ +); + +extern int XSetWMHints( + Display* /* display */, + Window /* w */, + XWMHints* /* wm_hints */ +); + +extern void XSetWMIconName( + Display* /* display */, + Window /* w */, + XTextProperty* /* text_prop */ +); + +extern void XSetWMName( + Display* /* display */, + Window /* w */, + XTextProperty* /* text_prop */ +); + +extern void XSetWMNormalHints( + Display* /* display */, + Window /* w */, + XSizeHints* /* hints */ +); + +extern void XSetWMProperties( + Display* /* display */, + Window /* w */, + XTextProperty* /* window_name */, + XTextProperty* /* icon_name */, + char** /* argv */, + int /* argc */, + XSizeHints* /* normal_hints */, + XWMHints* /* wm_hints */, + XClassHint* /* class_hints */ +); + +extern void XmbSetWMProperties( + Display* /* display */, + Window /* w */, + _Xconst char* /* window_name */, + _Xconst char* /* icon_name */, + char** /* argv */, + int /* argc */, + XSizeHints* /* normal_hints */, + XWMHints* /* wm_hints */, + XClassHint* /* class_hints */ +); + +extern void Xutf8SetWMProperties( + Display* /* display */, + Window /* w */, + _Xconst char* /* window_name */, + _Xconst char* /* icon_name */, + char** /* argv */, + int /* argc */, + XSizeHints* /* normal_hints */, + XWMHints* /* wm_hints */, + XClassHint* /* class_hints */ +); + +extern void XSetWMSizeHints( + Display* /* display */, + Window /* w */, + XSizeHints* /* hints */, + Atom /* property */ +); + +extern int XSetRegion( + Display* /* display */, + GC /* gc */, + Region /* r */ +); + +extern void XSetStandardColormap( + Display* /* display */, + Window /* w */, + XStandardColormap* /* colormap */, + Atom /* property */ +); + +extern int XSetZoomHints( + Display* /* display */, + Window /* w */, + XSizeHints* /* zhints */ +); + +extern int XShrinkRegion( + Region /* r */, + int /* dx */, + int /* dy */ +); + +extern Status XStringListToTextProperty( + char** /* list */, + int /* count */, + XTextProperty* /* text_prop_return */ +); + +extern int XSubtractRegion( + Region /* sra */, + Region /* srb */, + Region /* dr_return */ +); + +extern int XmbTextListToTextProperty( + Display* display, + char** list, + int count, + XICCEncodingStyle style, + XTextProperty* text_prop_return +); + +extern int XwcTextListToTextProperty( + Display* display, + wchar_t** list, + int count, + XICCEncodingStyle style, + XTextProperty* text_prop_return +); + +extern int Xutf8TextListToTextProperty( + Display* display, + char** list, + int count, + XICCEncodingStyle style, + XTextProperty* text_prop_return +); + +extern void XwcFreeStringList( + wchar_t** list +); + +extern Status XTextPropertyToStringList( + XTextProperty* /* text_prop */, + char*** /* list_return */, + int* /* count_return */ +); + +extern int XmbTextPropertyToTextList( + Display* display, + const XTextProperty* text_prop, + char*** list_return, + int* count_return +); + +extern int XwcTextPropertyToTextList( + Display* display, + const XTextProperty* text_prop, + wchar_t*** list_return, + int* count_return +); + +extern int Xutf8TextPropertyToTextList( + Display* display, + const XTextProperty* text_prop, + char*** list_return, + int* count_return +); + +extern int XUnionRectWithRegion( + XRectangle* /* rectangle */, + Region /* src_region */, + Region /* dest_region_return */ +); + +extern int XUnionRegion( + Region /* sra */, + Region /* srb */, + Region /* dr_return */ +); + +extern int XWMGeometry( + Display* /* display */, + int /* screen_number */, + _Xconst char* /* user_geometry */, + _Xconst char* /* default_geometry */, + unsigned int /* border_width */, + XSizeHints* /* hints */, + int* /* x_return */, + int* /* y_return */, + int* /* width_return */, + int* /* height_return */, + int* /* gravity_return */ +); + +extern int XXorRegion( + Region /* sra */, + Region /* srb */, + Region /* dr_return */ +); + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +_XFUNCPROTOEND + +#endif /* _X11_XUTIL_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/extensions/XI2.h b/thirdparty/linuxbsd_headers/X11/extensions/XI2.h new file mode 100644 index 0000000000..cc47085df0 --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/extensions/XI2.h @@ -0,0 +1,259 @@ +/* + * Copyright © 2009 Red Hat, Inc. + * + * 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 (including the next + * paragraph) 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. + * + */ + +#ifndef _XI2_H_ +#define _XI2_H_ + +#define XInput_2_0 7 +/* DO NOT ADD TO THIS LIST. These are libXi-specific defines. + See commit libXi-1.4.2-21-ge8531dd */ + +#define XI_2_Major 2 +#define XI_2_Minor 4 + +/* Property event flags */ +#define XIPropertyDeleted 0 +#define XIPropertyCreated 1 +#define XIPropertyModified 2 + +/* Property modes */ +#define XIPropModeReplace 0 +#define XIPropModePrepend 1 +#define XIPropModeAppend 2 + +/* Special property type used for XIGetProperty */ +#define XIAnyPropertyType 0L + +/* Enter/Leave and Focus In/Out modes */ +#define XINotifyNormal 0 +#define XINotifyGrab 1 +#define XINotifyUngrab 2 +#define XINotifyWhileGrabbed 3 +#define XINotifyPassiveGrab 4 +#define XINotifyPassiveUngrab 5 + +/* Enter/Leave and focus In/out detail */ +#define XINotifyAncestor 0 +#define XINotifyVirtual 1 +#define XINotifyInferior 2 +#define XINotifyNonlinear 3 +#define XINotifyNonlinearVirtual 4 +#define XINotifyPointer 5 +#define XINotifyPointerRoot 6 +#define XINotifyDetailNone 7 + +/* Grab modes */ +#define XIGrabModeSync 0 +#define XIGrabModeAsync 1 +#define XIGrabModeTouch 2 + +/* Grab reply status codes */ +#define XIGrabSuccess 0 +#define XIAlreadyGrabbed 1 +#define XIGrabInvalidTime 2 +#define XIGrabNotViewable 3 +#define XIGrabFrozen 4 + +/* Grab owner events values */ +#define XIOwnerEvents True +#define XINoOwnerEvents False + +/* Passive grab types */ +#define XIGrabtypeButton 0 +#define XIGrabtypeKeycode 1 +#define XIGrabtypeEnter 2 +#define XIGrabtypeFocusIn 3 +#define XIGrabtypeTouchBegin 4 +#define XIGrabtypeGesturePinchBegin 5 +#define XIGrabtypeGestureSwipeBegin 6 + +/* Passive grab modifier */ +#define XIAnyModifier (1U << 31) +#define XIAnyButton 0 +#define XIAnyKeycode 0 + +/* XIAllowEvents event-modes */ +#define XIAsyncDevice 0 +#define XISyncDevice 1 +#define XIReplayDevice 2 +#define XIAsyncPairedDevice 3 +#define XIAsyncPair 4 +#define XISyncPair 5 +#define XIAcceptTouch 6 +#define XIRejectTouch 7 + +/* DeviceChangedEvent change reasons */ +#define XISlaveSwitch 1 +#define XIDeviceChange 2 + +/* Hierarchy flags */ +#define XIMasterAdded (1 << 0) +#define XIMasterRemoved (1 << 1) +#define XISlaveAdded (1 << 2) +#define XISlaveRemoved (1 << 3) +#define XISlaveAttached (1 << 4) +#define XISlaveDetached (1 << 5) +#define XIDeviceEnabled (1 << 6) +#define XIDeviceDisabled (1 << 7) + +/* ChangeHierarchy constants */ +#define XIAddMaster 1 +#define XIRemoveMaster 2 +#define XIAttachSlave 3 +#define XIDetachSlave 4 + +#define XIAttachToMaster 1 +#define XIFloating 2 + +/* Valuator modes */ +#define XIModeRelative 0 +#define XIModeAbsolute 1 + +/* Device types */ +#define XIMasterPointer 1 +#define XIMasterKeyboard 2 +#define XISlavePointer 3 +#define XISlaveKeyboard 4 +#define XIFloatingSlave 5 + +/* Device classes: classes that are not identical to Xi 1.x classes must be + * numbered starting from 8. */ +#define XIKeyClass 0 +#define XIButtonClass 1 +#define XIValuatorClass 2 +#define XIScrollClass 3 +#define XITouchClass 8 +#define XIGestureClass 9 + +/* Scroll class types */ +#define XIScrollTypeVertical 1 +#define XIScrollTypeHorizontal 2 + +/* Scroll class flags */ +#define XIScrollFlagNoEmulation (1 << 0) +#define XIScrollFlagPreferred (1 << 1) + +/* Device event flags (common) */ +/* Device event flags (key events only) */ +#define XIKeyRepeat (1 << 16) +/* Device event flags (pointer events only) */ +#define XIPointerEmulated (1 << 16) +/* Device event flags (touch events only) */ +#define XITouchPendingEnd (1 << 16) +#define XITouchEmulatingPointer (1 << 17) + +/* Barrier event flags */ +#define XIBarrierPointerReleased (1 << 0) +#define XIBarrierDeviceIsGrabbed (1 << 1) + +/* Gesture pinch event flags */ +#define XIGesturePinchEventCancelled (1 << 0) + +/* Gesture swipe event flags */ +#define XIGestureSwipeEventCancelled (1 << 0) + +/* Touch modes */ +#define XIDirectTouch 1 +#define XIDependentTouch 2 + +/* XI2 event mask macros */ +#define XISetMask(ptr, event) (((unsigned char*)(ptr))[(event)>>3] |= (1 << ((event) & 7))) +#define XIClearMask(ptr, event) (((unsigned char*)(ptr))[(event)>>3] &= ~(1 << ((event) & 7))) +#define XIMaskIsSet(ptr, event) (((unsigned char*)(ptr))[(event)>>3] & (1 << ((event) & 7))) +#define XIMaskLen(event) (((event) >> 3) + 1) + +/* Fake device ID's for event selection */ +#define XIAllDevices 0 +#define XIAllMasterDevices 1 + +/* Event types */ +#define XI_DeviceChanged 1 +#define XI_KeyPress 2 +#define XI_KeyRelease 3 +#define XI_ButtonPress 4 +#define XI_ButtonRelease 5 +#define XI_Motion 6 +#define XI_Enter 7 +#define XI_Leave 8 +#define XI_FocusIn 9 +#define XI_FocusOut 10 +#define XI_HierarchyChanged 11 +#define XI_PropertyEvent 12 +#define XI_RawKeyPress 13 +#define XI_RawKeyRelease 14 +#define XI_RawButtonPress 15 +#define XI_RawButtonRelease 16 +#define XI_RawMotion 17 +#define XI_TouchBegin 18 /* XI 2.2 */ +#define XI_TouchUpdate 19 +#define XI_TouchEnd 20 +#define XI_TouchOwnership 21 +#define XI_RawTouchBegin 22 +#define XI_RawTouchUpdate 23 +#define XI_RawTouchEnd 24 +#define XI_BarrierHit 25 /* XI 2.3 */ +#define XI_BarrierLeave 26 +#define XI_GesturePinchBegin 27 /* XI 2.4 */ +#define XI_GesturePinchUpdate 28 +#define XI_GesturePinchEnd 29 +#define XI_GestureSwipeBegin 30 +#define XI_GestureSwipeUpdate 31 +#define XI_GestureSwipeEnd 32 +#define XI_LASTEVENT XI_GestureSwipeEnd +/* NOTE: XI2LASTEVENT in xserver/include/inputstr.h must be the same value + * as XI_LASTEVENT if the server is supposed to handle masks etc. for this + * type of event. */ + +/* Event masks. + * Note: the protocol spec defines a mask to be of (1 << type). Clients are + * free to create masks by bitshifting instead of using these defines. + */ +#define XI_DeviceChangedMask (1 << XI_DeviceChanged) +#define XI_KeyPressMask (1 << XI_KeyPress) +#define XI_KeyReleaseMask (1 << XI_KeyRelease) +#define XI_ButtonPressMask (1 << XI_ButtonPress) +#define XI_ButtonReleaseMask (1 << XI_ButtonRelease) +#define XI_MotionMask (1 << XI_Motion) +#define XI_EnterMask (1 << XI_Enter) +#define XI_LeaveMask (1 << XI_Leave) +#define XI_FocusInMask (1 << XI_FocusIn) +#define XI_FocusOutMask (1 << XI_FocusOut) +#define XI_HierarchyChangedMask (1 << XI_HierarchyChanged) +#define XI_PropertyEventMask (1 << XI_PropertyEvent) +#define XI_RawKeyPressMask (1 << XI_RawKeyPress) +#define XI_RawKeyReleaseMask (1 << XI_RawKeyRelease) +#define XI_RawButtonPressMask (1 << XI_RawButtonPress) +#define XI_RawButtonReleaseMask (1 << XI_RawButtonRelease) +#define XI_RawMotionMask (1 << XI_RawMotion) +#define XI_TouchBeginMask (1 << XI_TouchBegin) +#define XI_TouchEndMask (1 << XI_TouchEnd) +#define XI_TouchOwnershipChangedMask (1 << XI_TouchOwnership) +#define XI_TouchUpdateMask (1 << XI_TouchUpdate) +#define XI_RawTouchBeginMask (1 << XI_RawTouchBegin) +#define XI_RawTouchEndMask (1 << XI_RawTouchEnd) +#define XI_RawTouchUpdateMask (1 << XI_RawTouchUpdate) +#define XI_BarrierHitMask (1 << XI_BarrierHit) +#define XI_BarrierLeaveMask (1 << XI_BarrierLeave) + +#endif /* _XI2_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/extensions/XInput2.h b/thirdparty/linuxbsd_headers/X11/extensions/XInput2.h new file mode 100644 index 0000000000..33670ebf20 --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/extensions/XInput2.h @@ -0,0 +1,657 @@ +/* + * Copyright © 2009 Red Hat, Inc. + * + * 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 (including the next + * paragraph) 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. + * + */ + +/* Definitions used by the library and client */ + +#ifndef _XINPUT2_H_ +#define _XINPUT2_H_ + +#include <X11/Xlib.h> +#include <X11/extensions/XI2.h> +#include <X11/extensions/Xge.h> +#include <X11/extensions/Xfixes.h> /* PointerBarrier */ + +/******************************************************************* + * + */ +typedef struct { + int type; + char* name; + Bool send_core; + Bool enable; +} XIAddMasterInfo; + +typedef struct { + int type; + int deviceid; + int return_mode; /* AttachToMaster, Floating */ + int return_pointer; + int return_keyboard; +} XIRemoveMasterInfo; + +typedef struct { + int type; + int deviceid; + int new_master; +} XIAttachSlaveInfo; + +typedef struct { + int type; + int deviceid; +} XIDetachSlaveInfo; + +typedef union { + int type; /* must be first element */ + XIAddMasterInfo add; + XIRemoveMasterInfo remove; + XIAttachSlaveInfo attach; + XIDetachSlaveInfo detach; +} XIAnyHierarchyChangeInfo; + +typedef struct +{ + int base; + int latched; + int locked; + int effective; +} XIModifierState; + +typedef XIModifierState XIGroupState; + +typedef struct { + int mask_len; + unsigned char *mask; +} XIButtonState; + +typedef struct { + int mask_len; + unsigned char *mask; + double *values; +} XIValuatorState; + + +typedef struct +{ + int deviceid; + int mask_len; + unsigned char* mask; +} XIEventMask; + +typedef struct +{ + int type; + int sourceid; +} XIAnyClassInfo; + +typedef struct +{ + int type; + int sourceid; + int num_buttons; + Atom *labels; + XIButtonState state; +} XIButtonClassInfo; + +typedef struct +{ + int type; + int sourceid; + int num_keycodes; + int *keycodes; +} XIKeyClassInfo; + +typedef struct +{ + int type; + int sourceid; + int number; + Atom label; + double min; + double max; + double value; + int resolution; + int mode; +} XIValuatorClassInfo; + +/* new in XI 2.1 */ +typedef struct +{ + int type; + int sourceid; + int number; + int scroll_type; + double increment; + int flags; +} XIScrollClassInfo; + +typedef struct +{ + int type; + int sourceid; + int mode; + int num_touches; +} XITouchClassInfo; + +typedef struct +{ + int deviceid; + char *name; + int use; + int attachment; + Bool enabled; + int num_classes; + XIAnyClassInfo **classes; +} XIDeviceInfo; + +typedef struct +{ + int modifiers; + int status; +} XIGrabModifiers; + +typedef unsigned int BarrierEventID; + +typedef struct +{ + int deviceid; + PointerBarrier barrier; + BarrierEventID eventid; +} XIBarrierReleasePointerInfo; + +/** + * Generic XI2 event. All XI2 events have the same header. + */ +typedef struct { + int type; /* GenericEvent */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + int extension; /* XI extension offset */ + int evtype; + Time time; +} XIEvent; + + +typedef struct { + int deviceid; + int attachment; + int use; + Bool enabled; + int flags; +} XIHierarchyInfo; + +/* + * Notifies the client that the device hierarchy has been changed. The client + * is expected to re-query the server for the device hierarchy. + */ +typedef struct { + int type; /* GenericEvent */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + int extension; /* XI extension offset */ + int evtype; /* XI_HierarchyChanged */ + Time time; + int flags; + int num_info; + XIHierarchyInfo *info; +} XIHierarchyEvent; + +/* + * Notifies the client that the classes have been changed. This happens when + * the slave device that sends through the master changes. + */ +typedef struct { + int type; /* GenericEvent */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + int extension; /* XI extension offset */ + int evtype; /* XI_DeviceChanged */ + Time time; + int deviceid; /* id of the device that changed */ + int sourceid; /* Source for the new classes. */ + int reason; /* Reason for the change */ + int num_classes; + XIAnyClassInfo **classes; /* same as in XIDeviceInfo */ +} XIDeviceChangedEvent; + +typedef struct { + int type; /* GenericEvent */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + int extension; /* XI extension offset */ + int evtype; + Time time; + int deviceid; + int sourceid; + int detail; + Window root; + Window event; + Window child; + double root_x; + double root_y; + double event_x; + double event_y; + int flags; + XIButtonState buttons; + XIValuatorState valuators; + XIModifierState mods; + XIGroupState group; +} XIDeviceEvent; + +typedef struct { + int type; /* GenericEvent */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + int extension; /* XI extension offset */ + int evtype; /* XI_RawKeyPress, XI_RawKeyRelease, etc. */ + Time time; + int deviceid; + int sourceid; /* Bug: Always 0. https://bugs.freedesktop.org//show_bug.cgi?id=34240 */ + int detail; + int flags; + XIValuatorState valuators; + double *raw_values; +} XIRawEvent; + +typedef struct { + int type; /* GenericEvent */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + int extension; /* XI extension offset */ + int evtype; + Time time; + int deviceid; + int sourceid; + int detail; + Window root; + Window event; + Window child; + double root_x; + double root_y; + double event_x; + double event_y; + int mode; + Bool focus; + Bool same_screen; + XIButtonState buttons; + XIModifierState mods; + XIGroupState group; +} XIEnterEvent; + +typedef XIEnterEvent XILeaveEvent; +typedef XIEnterEvent XIFocusInEvent; +typedef XIEnterEvent XIFocusOutEvent; + +typedef struct { + int type; /* GenericEvent */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + int extension; /* XI extension offset */ + int evtype; /* XI_PropertyEvent */ + Time time; + int deviceid; /* id of the device that changed */ + Atom property; + int what; +} XIPropertyEvent; + +typedef struct { + int type; /* GenericEvent */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + int extension; /* XI extension offset */ + int evtype; + Time time; + int deviceid; + int sourceid; + unsigned int touchid; + Window root; + Window event; + Window child; + int flags; +} XITouchOwnershipEvent; + +typedef struct { + int type; /* GenericEvent */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + int extension; /* XI extension offset */ + int evtype; + Time time; + int deviceid; + int sourceid; + Window event; + Window root; + double root_x; + double root_y; + double dx; + double dy; + int dtime; + int flags; + PointerBarrier barrier; + BarrierEventID eventid; +} XIBarrierEvent; + +_XFUNCPROTOBEGIN + +extern Bool XIQueryPointer( + Display* display, + int deviceid, + Window win, + Window* root, + Window* child, + double* root_x, + double* root_y, + double* win_x, + double* win_y, + XIButtonState *buttons, + XIModifierState *mods, + XIGroupState *group +); + +extern Bool XIWarpPointer( + Display* display, + int deviceid, + Window src_win, + Window dst_win, + double src_x, + double src_y, + unsigned int src_width, + unsigned int src_height, + double dst_x, + double dst_y +); + +extern Status XIDefineCursor( + Display* display, + int deviceid, + Window win, + Cursor cursor +); + +extern Status XIUndefineCursor( + Display* display, + int deviceid, + Window win +); + +extern Status XIChangeHierarchy( + Display* display, + XIAnyHierarchyChangeInfo* changes, + int num_changes +); + +extern Status XISetClientPointer( + Display* dpy, + Window win, + int deviceid +); + +extern Bool XIGetClientPointer( + Display* dpy, + Window win, + int* deviceid +); + +extern int XISelectEvents( + Display* dpy, + Window win, + XIEventMask *masks, + int num_masks +); + +extern XIEventMask *XIGetSelectedEvents( + Display* dpy, + Window win, + int *num_masks_return +); + +extern Status XIQueryVersion( + Display* dpy, + int* major_version_inout, + int* minor_version_inout +); + +extern XIDeviceInfo* XIQueryDevice( + Display* dpy, + int deviceid, + int* ndevices_return +); + +extern Status XISetFocus( + Display* dpy, + int deviceid, + Window focus, + Time time +); + +extern Status XIGetFocus( + Display* dpy, + int deviceid, + Window *focus_return); + +extern Status XIGrabDevice( + Display* dpy, + int deviceid, + Window grab_window, + Time time, + Cursor cursor, + int grab_mode, + int paired_device_mode, + Bool owner_events, + XIEventMask *mask +); + +extern Status XIUngrabDevice( + Display* dpy, + int deviceid, + Time time +); + +extern Status XIAllowEvents( + Display* display, + int deviceid, + int event_mode, + Time time +); + +extern Status XIAllowTouchEvents( + Display* display, + int deviceid, + unsigned int touchid, + Window grab_window, + int event_mode +); + +extern int XIGrabButton( + Display* display, + int deviceid, + int button, + Window grab_window, + Cursor cursor, + int grab_mode, + int paired_device_mode, + int owner_events, + XIEventMask *mask, + int num_modifiers, + XIGrabModifiers *modifiers_inout +); + +extern int XIGrabKeycode( + Display* display, + int deviceid, + int keycode, + Window grab_window, + int grab_mode, + int paired_device_mode, + int owner_events, + XIEventMask *mask, + int num_modifiers, + XIGrabModifiers *modifiers_inout +); + +extern int XIGrabEnter( + Display* display, + int deviceid, + Window grab_window, + Cursor cursor, + int grab_mode, + int paired_device_mode, + int owner_events, + XIEventMask *mask, + int num_modifiers, + XIGrabModifiers *modifiers_inout +); + +extern int XIGrabFocusIn( + Display* display, + int deviceid, + Window grab_window, + int grab_mode, + int paired_device_mode, + int owner_events, + XIEventMask *mask, + int num_modifiers, + XIGrabModifiers *modifiers_inout +); + +extern int XIGrabTouchBegin( + Display* display, + int deviceid, + Window grab_window, + int owner_events, + XIEventMask *mask, + int num_modifiers, + XIGrabModifiers *modifiers_inout +); + +extern Status XIUngrabButton( + Display* display, + int deviceid, + int button, + Window grab_window, + int num_modifiers, + XIGrabModifiers *modifiers +); + +extern Status XIUngrabKeycode( + Display* display, + int deviceid, + int keycode, + Window grab_window, + int num_modifiers, + XIGrabModifiers *modifiers +); + +extern Status XIUngrabEnter( + Display* display, + int deviceid, + Window grab_window, + int num_modifiers, + XIGrabModifiers *modifiers +); + +extern Status XIUngrabFocusIn( + Display* display, + int deviceid, + Window grab_window, + int num_modifiers, + XIGrabModifiers *modifiers +); + +extern Status XIUngrabTouchBegin( + Display* display, + int deviceid, + Window grab_window, + int num_modifiers, + XIGrabModifiers *modifiers +); + +extern Atom *XIListProperties( + Display* display, + int deviceid, + int *num_props_return +); + +extern void XIChangeProperty( + Display* display, + int deviceid, + Atom property, + Atom type, + int format, + int mode, + unsigned char *data, + int num_items +); + +extern void +XIDeleteProperty( + Display* display, + int deviceid, + Atom property +); + +extern Status +XIGetProperty( + Display* display, + int deviceid, + Atom property, + long offset, + long length, + Bool delete_property, + Atom type, + Atom *type_return, + int *format_return, + unsigned long *num_items_return, + unsigned long *bytes_after_return, + unsigned char **data +); + +extern void +XIBarrierReleasePointers( + Display* display, + XIBarrierReleasePointerInfo *barriers, + int num_barriers +); + +extern void +XIBarrierReleasePointer( + Display* display, + int deviceid, + PointerBarrier barrier, + BarrierEventID eventid +); + +extern void XIFreeDeviceInfo(XIDeviceInfo *info); + +_XFUNCPROTOEND + +#endif /* XINPUT2_H */ diff --git a/thirdparty/linuxbsd_headers/X11/extensions/XKB.h b/thirdparty/linuxbsd_headers/X11/extensions/XKB.h new file mode 100644 index 0000000000..5d3f87016f --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/extensions/XKB.h @@ -0,0 +1,786 @@ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +Permission to use, copy, modify, and distribute this +software and its documentation for any purpose and without +fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright +notice and this permission notice appear in supporting +documentation, and that the name of Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL +DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH +THE USE OR PERFORMANCE OF THIS SOFTWARE. + +********************************************************/ + +#ifndef _XKB_H_ +#define _XKB_H_ + + /* + * XKB request codes, used in: + * - xkbReqType field of all requests + * - requestMinor field of some events + */ +#define X_kbUseExtension 0 +#define X_kbSelectEvents 1 +#define X_kbBell 3 +#define X_kbGetState 4 +#define X_kbLatchLockState 5 +#define X_kbGetControls 6 +#define X_kbSetControls 7 +#define X_kbGetMap 8 +#define X_kbSetMap 9 +#define X_kbGetCompatMap 10 +#define X_kbSetCompatMap 11 +#define X_kbGetIndicatorState 12 +#define X_kbGetIndicatorMap 13 +#define X_kbSetIndicatorMap 14 +#define X_kbGetNamedIndicator 15 +#define X_kbSetNamedIndicator 16 +#define X_kbGetNames 17 +#define X_kbSetNames 18 +#define X_kbGetGeometry 19 +#define X_kbSetGeometry 20 +#define X_kbPerClientFlags 21 +#define X_kbListComponents 22 +#define X_kbGetKbdByName 23 +#define X_kbGetDeviceInfo 24 +#define X_kbSetDeviceInfo 25 +#define X_kbSetDebuggingFlags 101 + + /* + * In the X sense, XKB reports only one event. + * The type field of all XKB events is XkbEventCode + */ +#define XkbEventCode 0 +#define XkbNumberEvents (XkbEventCode+1) + + /* + * XKB has a minor event code so it can use one X event code for + * multiple purposes. + * - reported in the xkbType field of all XKB events. + * - XkbSelectEventDetails: Indicates the event for which event details + * are being changed + */ +#define XkbNewKeyboardNotify 0 +#define XkbMapNotify 1 +#define XkbStateNotify 2 +#define XkbControlsNotify 3 +#define XkbIndicatorStateNotify 4 +#define XkbIndicatorMapNotify 5 +#define XkbNamesNotify 6 +#define XkbCompatMapNotify 7 +#define XkbBellNotify 8 +#define XkbActionMessage 9 +#define XkbAccessXNotify 10 +#define XkbExtensionDeviceNotify 11 + + /* + * Event Mask: + * - XkbSelectEvents: Specifies event interest. + */ +#define XkbNewKeyboardNotifyMask (1L << 0) +#define XkbMapNotifyMask (1L << 1) +#define XkbStateNotifyMask (1L << 2) +#define XkbControlsNotifyMask (1L << 3) +#define XkbIndicatorStateNotifyMask (1L << 4) +#define XkbIndicatorMapNotifyMask (1L << 5) +#define XkbNamesNotifyMask (1L << 6) +#define XkbCompatMapNotifyMask (1L << 7) +#define XkbBellNotifyMask (1L << 8) +#define XkbActionMessageMask (1L << 9) +#define XkbAccessXNotifyMask (1L << 10) +#define XkbExtensionDeviceNotifyMask (1L << 11) +#define XkbAllEventsMask (0xFFF) + + /* + * NewKeyboardNotify event details: + */ +#define XkbNKN_KeycodesMask (1L << 0) +#define XkbNKN_GeometryMask (1L << 1) +#define XkbNKN_DeviceIDMask (1L << 2) +#define XkbAllNewKeyboardEventsMask (0x7) + + /* + * AccessXNotify event types: + * - The 'what' field of AccessXNotify events reports the + * reason that the event was generated. + */ +#define XkbAXN_SKPress 0 +#define XkbAXN_SKAccept 1 +#define XkbAXN_SKReject 2 +#define XkbAXN_SKRelease 3 +#define XkbAXN_BKAccept 4 +#define XkbAXN_BKReject 5 +#define XkbAXN_AXKWarning 6 + + /* + * AccessXNotify details: + * - Used as an event detail mask to limit the conditions under which + * AccessXNotify events are reported + */ +#define XkbAXN_SKPressMask (1L << 0) +#define XkbAXN_SKAcceptMask (1L << 1) +#define XkbAXN_SKRejectMask (1L << 2) +#define XkbAXN_SKReleaseMask (1L << 3) +#define XkbAXN_BKAcceptMask (1L << 4) +#define XkbAXN_BKRejectMask (1L << 5) +#define XkbAXN_AXKWarningMask (1L << 6) +#define XkbAllAccessXEventsMask (0x7f) + + /* + * Miscellaneous event details: + * - event detail masks for assorted events that don't really + * have any details. + */ +#define XkbAllStateEventsMask XkbAllStateComponentsMask +#define XkbAllMapEventsMask XkbAllMapComponentsMask +#define XkbAllControlEventsMask XkbAllControlsMask +#define XkbAllIndicatorEventsMask XkbAllIndicatorsMask +#define XkbAllNameEventsMask XkbAllNamesMask +#define XkbAllCompatMapEventsMask XkbAllCompatMask +#define XkbAllBellEventsMask (1L << 0) +#define XkbAllActionMessagesMask (1L << 0) + + /* + * XKB reports one error: BadKeyboard + * A further reason for the error is encoded into to most significant + * byte of the resourceID for the error: + * XkbErr_BadDevice - the device in question was not found + * XkbErr_BadClass - the device was found but it doesn't belong to + * the appropriate class. + * XkbErr_BadId - the device was found and belongs to the right + * class, but not feedback with a matching id was + * found. + * The low byte of the resourceID for this error contains the device + * id, class specifier or feedback id that failed. + */ +#define XkbKeyboard 0 +#define XkbNumberErrors 1 + +#define XkbErr_BadDevice 0xff +#define XkbErr_BadClass 0xfe +#define XkbErr_BadId 0xfd + + /* + * Keyboard Components Mask: + * - Specifies the components that follow a GetKeyboardByNameReply + */ +#define XkbClientMapMask (1L << 0) +#define XkbServerMapMask (1L << 1) +#define XkbCompatMapMask (1L << 2) +#define XkbIndicatorMapMask (1L << 3) +#define XkbNamesMask (1L << 4) +#define XkbGeometryMask (1L << 5) +#define XkbControlsMask (1L << 6) +#define XkbAllComponentsMask (0x7f) + + /* + * State detail mask: + * - The 'changed' field of StateNotify events reports which of + * the keyboard state components have changed. + * - Used as an event detail mask to limit the conditions under + * which StateNotify events are reported. + */ +#define XkbModifierStateMask (1L << 0) +#define XkbModifierBaseMask (1L << 1) +#define XkbModifierLatchMask (1L << 2) +#define XkbModifierLockMask (1L << 3) +#define XkbGroupStateMask (1L << 4) +#define XkbGroupBaseMask (1L << 5) +#define XkbGroupLatchMask (1L << 6) +#define XkbGroupLockMask (1L << 7) +#define XkbCompatStateMask (1L << 8) +#define XkbGrabModsMask (1L << 9) +#define XkbCompatGrabModsMask (1L << 10) +#define XkbLookupModsMask (1L << 11) +#define XkbCompatLookupModsMask (1L << 12) +#define XkbPointerButtonMask (1L << 13) +#define XkbAllStateComponentsMask (0x3fff) + + /* + * Controls detail masks: + * The controls specified in XkbAllControlsMask: + * - The 'changed' field of ControlsNotify events reports which of + * the keyboard controls have changed. + * - The 'changeControls' field of the SetControls request specifies + * the controls for which values are to be changed. + * - Used as an event detail mask to limit the conditions under + * which ControlsNotify events are reported. + * + * The controls specified in the XkbAllBooleanCtrlsMask: + * - The 'enabledControls' field of ControlsNotify events reports the + * current status of the boolean controls. + * - The 'enabledControlsChanges' field of ControlsNotify events reports + * any boolean controls that have been turned on or off. + * - The 'affectEnabledControls' and 'enabledControls' fields of the + * kbSetControls request change the set of enabled controls. + * - The 'accessXTimeoutMask' and 'accessXTimeoutValues' fields of + * an XkbControlsRec specify the controls to be changed if the keyboard + * times out and the values to which they should be changed. + * - The 'autoCtrls' and 'autoCtrlsValues' fields of the PerClientFlags + * request specifies the specify the controls to be reset when the + * client exits and the values to which they should be reset. + * - The 'ctrls' field of an indicator map specifies the controls + * that drive the indicator. + * - Specifies the boolean controls affected by the SetControls and + * LockControls key actions. + */ +#define XkbRepeatKeysMask (1L << 0) +#define XkbSlowKeysMask (1L << 1) +#define XkbBounceKeysMask (1L << 2) +#define XkbStickyKeysMask (1L << 3) +#define XkbMouseKeysMask (1L << 4) +#define XkbMouseKeysAccelMask (1L << 5) +#define XkbAccessXKeysMask (1L << 6) +#define XkbAccessXTimeoutMask (1L << 7) +#define XkbAccessXFeedbackMask (1L << 8) +#define XkbAudibleBellMask (1L << 9) +#define XkbOverlay1Mask (1L << 10) +#define XkbOverlay2Mask (1L << 11) +#define XkbIgnoreGroupLockMask (1L << 12) +#define XkbGroupsWrapMask (1L << 27) +#define XkbInternalModsMask (1L << 28) +#define XkbIgnoreLockModsMask (1L << 29) +#define XkbPerKeyRepeatMask (1L << 30) +#define XkbControlsEnabledMask (1L << 31) + +#define XkbAccessXOptionsMask (XkbStickyKeysMask|XkbAccessXFeedbackMask) + +#define XkbAllBooleanCtrlsMask (0x00001FFF) +#define XkbAllControlsMask (0xF8001FFF) +#define XkbAllControlEventsMask XkbAllControlsMask + + /* + * AccessX Options Mask + * - The 'accessXOptions' field of an XkbControlsRec specifies the + * AccessX options that are currently in effect. + * - The 'accessXTimeoutOptionsMask' and 'accessXTimeoutOptionsValues' + * fields of an XkbControlsRec specify the Access X options to be + * changed if the keyboard times out and the values to which they + * should be changed. + */ +#define XkbAX_SKPressFBMask (1L << 0) +#define XkbAX_SKAcceptFBMask (1L << 1) +#define XkbAX_FeatureFBMask (1L << 2) +#define XkbAX_SlowWarnFBMask (1L << 3) +#define XkbAX_IndicatorFBMask (1L << 4) +#define XkbAX_StickyKeysFBMask (1L << 5) +#define XkbAX_TwoKeysMask (1L << 6) +#define XkbAX_LatchToLockMask (1L << 7) +#define XkbAX_SKReleaseFBMask (1L << 8) +#define XkbAX_SKRejectFBMask (1L << 9) +#define XkbAX_BKRejectFBMask (1L << 10) +#define XkbAX_DumbBellFBMask (1L << 11) +#define XkbAX_FBOptionsMask (0xF3F) +#define XkbAX_SKOptionsMask (0x0C0) +#define XkbAX_AllOptionsMask (0xFFF) + + /* + * XkbUseCoreKbd is used to specify the core keyboard without having + * to look up its X input extension identifier. + * XkbUseCorePtr is used to specify the core pointer without having + * to look up its X input extension identifier. + * XkbDfltXIClass is used to specify "don't care" any place that the + * XKB protocol is looking for an X Input Extension + * device class. + * XkbDfltXIId is used to specify "don't care" any place that the + * XKB protocol is looking for an X Input Extension + * feedback identifier. + * XkbAllXIClasses is used to get information about all device indicators, + * whether they're part of the indicator feedback class + * or the keyboard feedback class. + * XkbAllXIIds is used to get information about all device indicator + * feedbacks without having to list them. + * XkbXINone is used to indicate that no class or id has been specified. + * XkbLegalXILedClass(c) True if 'c' specifies a legal class with LEDs + * XkbLegalXIBellClass(c) True if 'c' specifies a legal class with bells + * XkbExplicitXIDevice(d) True if 'd' explicitly specifies a device + * XkbExplicitXIClass(c) True if 'c' explicitly specifies a device class + * XkbExplicitXIId(c) True if 'i' explicitly specifies a device id + * XkbSingleXIClass(c) True if 'c' specifies exactly one device class, + * including the default. + * XkbSingleXIId(i) True if 'i' specifies exactly one device + * identifier, including the default. + */ +#define XkbUseCoreKbd 0x0100 +#define XkbUseCorePtr 0x0200 +#define XkbDfltXIClass 0x0300 +#define XkbDfltXIId 0x0400 +#define XkbAllXIClasses 0x0500 +#define XkbAllXIIds 0x0600 +#define XkbXINone 0xff00 + +#define XkbLegalXILedClass(c) (((c)==KbdFeedbackClass)||\ + ((c)==LedFeedbackClass)||\ + ((c)==XkbDfltXIClass)||\ + ((c)==XkbAllXIClasses)) +#define XkbLegalXIBellClass(c) (((c)==KbdFeedbackClass)||\ + ((c)==BellFeedbackClass)||\ + ((c)==XkbDfltXIClass)||\ + ((c)==XkbAllXIClasses)) +#define XkbExplicitXIDevice(c) (((c)&(~0xff))==0) +#define XkbExplicitXIClass(c) (((c)&(~0xff))==0) +#define XkbExplicitXIId(c) (((c)&(~0xff))==0) +#define XkbSingleXIClass(c) ((((c)&(~0xff))==0)||((c)==XkbDfltXIClass)) +#define XkbSingleXIId(c) ((((c)&(~0xff))==0)||((c)==XkbDfltXIId)) + +#define XkbNoModifier 0xff +#define XkbNoShiftLevel 0xff +#define XkbNoShape 0xff +#define XkbNoIndicator 0xff + +#define XkbNoModifierMask 0 +#define XkbAllModifiersMask 0xff +#define XkbAllVirtualModsMask 0xffff + +#define XkbNumKbdGroups 4 +#define XkbMaxKbdGroup (XkbNumKbdGroups-1) + +#define XkbMaxMouseKeysBtn 4 + + /* + * Group Index and Mask: + * - Indices into the kt_index array of a key type. + * - Mask specifies types to be changed for XkbChangeTypesOfKey + */ +#define XkbGroup1Index 0 +#define XkbGroup2Index 1 +#define XkbGroup3Index 2 +#define XkbGroup4Index 3 +#define XkbAnyGroup 254 +#define XkbAllGroups 255 + +#define XkbGroup1Mask (1<<0) +#define XkbGroup2Mask (1<<1) +#define XkbGroup3Mask (1<<2) +#define XkbGroup4Mask (1<<3) +#define XkbAnyGroupMask (1<<7) +#define XkbAllGroupsMask (0xf) + + /* + * BuildCoreState: Given a keyboard group and a modifier state, + * construct the value to be reported an event. + * GroupForCoreState: Given the state reported in an event, + * determine the keyboard group. + * IsLegalGroup: Returns TRUE if 'g' is a valid group index. + */ +#define XkbBuildCoreState(m,g) ((((g)&0x3)<<13)|((m)&0xff)) +#define XkbGroupForCoreState(s) (((s)>>13)&0x3) +#define XkbIsLegalGroup(g) (((g)>=0)&&((g)<XkbNumKbdGroups)) + + /* + * GroupsWrap values: + * - The 'groupsWrap' field of an XkbControlsRec specifies the + * treatment of out of range groups. + * - Bits 6 and 7 of the group info field of a key symbol map + * specify the interpretation of out of range groups for the + * corresponding key. + */ +#define XkbWrapIntoRange (0x00) +#define XkbClampIntoRange (0x40) +#define XkbRedirectIntoRange (0x80) + + /* + * Action flags: Reported in the 'flags' field of most key actions. + * Interpretation depends on the type of the action; not all actions + * accept all flags. + * + * Option Used for Actions + * ------ ---------------- + * ClearLocks SetMods, LatchMods, SetGroup, LatchGroup + * LatchToLock SetMods, LatchMods, SetGroup, LatchGroup + * LockNoLock LockMods, ISOLock, LockPtrBtn, LockDeviceBtn + * LockNoUnlock LockMods, ISOLock, LockPtrBtn, LockDeviceBtn + * UseModMapMods SetMods, LatchMods, LockMods, ISOLock + * GroupAbsolute SetGroup, LatchGroup, LockGroup, ISOLock + * UseDfltButton PtrBtn, LockPtrBtn + * NoAcceleration MovePtr + * MoveAbsoluteX MovePtr + * MoveAbsoluteY MovePtr + * ISODfltIsGroup ISOLock + * ISONoAffectMods ISOLock + * ISONoAffectGroup ISOLock + * ISONoAffectPtr ISOLock + * ISONoAffectCtrls ISOLock + * MessageOnPress ActionMessage + * MessageOnRelease ActionMessage + * MessageGenKeyEvent ActionMessage + * AffectDfltBtn SetPtrDflt + * DfltBtnAbsolute SetPtrDflt + * SwitchApplication SwitchScreen + * SwitchAbsolute SwitchScreen + */ + +#define XkbSA_ClearLocks (1L << 0) +#define XkbSA_LatchToLock (1L << 1) + +#define XkbSA_LockNoLock (1L << 0) +#define XkbSA_LockNoUnlock (1L << 1) + +#define XkbSA_UseModMapMods (1L << 2) + +#define XkbSA_GroupAbsolute (1L << 2) +#define XkbSA_UseDfltButton 0 + +#define XkbSA_NoAcceleration (1L << 0) +#define XkbSA_MoveAbsoluteX (1L << 1) +#define XkbSA_MoveAbsoluteY (1L << 2) + +#define XkbSA_ISODfltIsGroup (1L << 7) +#define XkbSA_ISONoAffectMods (1L << 6) +#define XkbSA_ISONoAffectGroup (1L << 5) +#define XkbSA_ISONoAffectPtr (1L << 4) +#define XkbSA_ISONoAffectCtrls (1L << 3) +#define XkbSA_ISOAffectMask (0x78) + +#define XkbSA_MessageOnPress (1L << 0) +#define XkbSA_MessageOnRelease (1L << 1) +#define XkbSA_MessageGenKeyEvent (1L << 2) + +#define XkbSA_AffectDfltBtn 1 +#define XkbSA_DfltBtnAbsolute (1L << 2) + +#define XkbSA_SwitchApplication (1L << 0) +#define XkbSA_SwitchAbsolute (1L << 2) + + /* + * The following values apply to the SA_DeviceValuator + * action only. Valuator operations specify the action + * to be taken. Values specified in the action are + * multiplied by 2^scale before they are applied. + */ +#define XkbSA_IgnoreVal (0x00) +#define XkbSA_SetValMin (0x10) +#define XkbSA_SetValCenter (0x20) +#define XkbSA_SetValMax (0x30) +#define XkbSA_SetValRelative (0x40) +#define XkbSA_SetValAbsolute (0x50) +#define XkbSA_ValOpMask (0x70) +#define XkbSA_ValScaleMask (0x07) +#define XkbSA_ValOp(a) ((a)&XkbSA_ValOpMask) +#define XkbSA_ValScale(a) ((a)&XkbSA_ValScaleMask) + + /* + * Action types: specifies the type of a key action. Reported in the + * type field of all key actions. + */ +#define XkbSA_NoAction 0x00 +#define XkbSA_SetMods 0x01 +#define XkbSA_LatchMods 0x02 +#define XkbSA_LockMods 0x03 +#define XkbSA_SetGroup 0x04 +#define XkbSA_LatchGroup 0x05 +#define XkbSA_LockGroup 0x06 +#define XkbSA_MovePtr 0x07 +#define XkbSA_PtrBtn 0x08 +#define XkbSA_LockPtrBtn 0x09 +#define XkbSA_SetPtrDflt 0x0a +#define XkbSA_ISOLock 0x0b +#define XkbSA_Terminate 0x0c +#define XkbSA_SwitchScreen 0x0d +#define XkbSA_SetControls 0x0e +#define XkbSA_LockControls 0x0f +#define XkbSA_ActionMessage 0x10 +#define XkbSA_RedirectKey 0x11 +#define XkbSA_DeviceBtn 0x12 +#define XkbSA_LockDeviceBtn 0x13 +#define XkbSA_DeviceValuator 0x14 +#define XkbSA_LastAction XkbSA_DeviceValuator +#define XkbSA_NumActions (XkbSA_LastAction+1) + +#define XkbSA_XFree86Private 0x86 + + /* + * Specifies the key actions that clear latched groups or modifiers. + */ +#define XkbSA_BreakLatch \ + ((1<<XkbSA_NoAction)|(1<<XkbSA_PtrBtn)|(1<<XkbSA_LockPtrBtn)|\ + (1<<XkbSA_Terminate)|(1<<XkbSA_SwitchScreen)|(1<<XkbSA_SetControls)|\ + (1<<XkbSA_LockControls)|(1<<XkbSA_ActionMessage)|\ + (1<<XkbSA_RedirectKey)|(1<<XkbSA_DeviceBtn)|(1<<XkbSA_LockDeviceBtn)) + + /* + * Macros to classify key actions + */ +#define XkbIsModAction(a) (((a)->type>=Xkb_SASetMods)&&((a)->type<=XkbSA_LockMods)) +#define XkbIsGroupAction(a) (((a)->type>=XkbSA_SetGroup)&&((a)->type<=XkbSA_LockGroup)) +#define XkbIsPtrAction(a) (((a)->type>=XkbSA_MovePtr)&&((a)->type<=XkbSA_SetPtrDflt)) + + + /* + * Key Behavior Qualifier: + * KB_Permanent indicates that the behavior describes an unalterable + * characteristic of the keyboard, not an XKB software-simulation of + * the listed behavior. + * Key Behavior Types: + * Specifies the behavior of the underlying key. + */ +#define XkbKB_Permanent 0x80 +#define XkbKB_OpMask 0x7f + +#define XkbKB_Default 0x00 +#define XkbKB_Lock 0x01 +#define XkbKB_RadioGroup 0x02 +#define XkbKB_Overlay1 0x03 +#define XkbKB_Overlay2 0x04 + +#define XkbKB_RGAllowNone 0x80 + + /* + * Various macros which describe the range of legal keycodes. + */ +#define XkbMinLegalKeyCode 8 +#define XkbMaxLegalKeyCode 255 +#define XkbMaxKeyCount (XkbMaxLegalKeyCode-XkbMinLegalKeyCode+1) +#define XkbPerKeyBitArraySize ((XkbMaxLegalKeyCode+1)/8) +/* Seems kinda silly to check that an unsigned char is <= 255... */ +#define XkbIsLegalKeycode(k) ((k)>=XkbMinLegalKeyCode) + + /* + * Assorted constants and limits. + */ +#define XkbNumModifiers 8 +#define XkbNumVirtualMods 16 +#define XkbNumIndicators 32 +#define XkbAllIndicatorsMask (0xffffffff) +#define XkbMaxRadioGroups 32 +#define XkbAllRadioGroupsMask (0xffffffff) +#define XkbMaxShiftLevel 63 +#define XkbMaxSymsPerKey (XkbMaxShiftLevel*XkbNumKbdGroups) +#define XkbRGMaxMembers 12 +#define XkbActionMessageLength 6 +#define XkbKeyNameLength 4 +#define XkbMaxRedirectCount 8 + +#define XkbGeomPtsPerMM 10 +#define XkbGeomMaxColors 32 +#define XkbGeomMaxLabelColors 3 +#define XkbGeomMaxPriority 255 + + /* + * Key Type index and mask for the four standard key types. + */ +#define XkbOneLevelIndex 0 +#define XkbTwoLevelIndex 1 +#define XkbAlphabeticIndex 2 +#define XkbKeypadIndex 3 +#define XkbLastRequiredType XkbKeypadIndex +#define XkbNumRequiredTypes (XkbLastRequiredType+1) +#define XkbMaxKeyTypes 255 + +#define XkbOneLevelMask (1<<0) +#define XkbTwoLevelMask (1<<1) +#define XkbAlphabeticMask (1<<2) +#define XkbKeypadMask (1<<3) +#define XkbAllRequiredTypes (0xf) + +#define XkbShiftLevel(n) ((n)-1) +#define XkbShiftLevelMask(n) (1<<((n)-1)) + + /* + * Extension name and version information + */ +#define XkbName "XKEYBOARD" +#define XkbMajorVersion 1 +#define XkbMinorVersion 0 + + /* + * Explicit map components: + * - Used in the 'explicit' field of an XkbServerMap. Specifies + * the keyboard components that should _not_ be updated automatically + * in response to core protocol keyboard mapping requests. + */ +#define XkbExplicitKeyTypesMask (0x0f) +#define XkbExplicitKeyType1Mask (1<<0) +#define XkbExplicitKeyType2Mask (1<<1) +#define XkbExplicitKeyType3Mask (1<<2) +#define XkbExplicitKeyType4Mask (1<<3) +#define XkbExplicitInterpretMask (1<<4) +#define XkbExplicitAutoRepeatMask (1<<5) +#define XkbExplicitBehaviorMask (1<<6) +#define XkbExplicitVModMapMask (1<<7) +#define XkbAllExplicitMask (0xff) + + /* + * Map components masks: + * Those in AllMapComponentsMask: + * - Specifies the individual fields to be loaded or changed for the + * GetMap and SetMap requests. + * Those in ClientInfoMask: + * - Specifies the components to be allocated by XkbAllocClientMap. + * Those in ServerInfoMask: + * - Specifies the components to be allocated by XkbAllocServerMap. + */ +#define XkbKeyTypesMask (1<<0) +#define XkbKeySymsMask (1<<1) +#define XkbModifierMapMask (1<<2) +#define XkbExplicitComponentsMask (1<<3) +#define XkbKeyActionsMask (1<<4) +#define XkbKeyBehaviorsMask (1<<5) +#define XkbVirtualModsMask (1<<6) +#define XkbVirtualModMapMask (1<<7) + +#define XkbAllClientInfoMask (XkbKeyTypesMask|XkbKeySymsMask|XkbModifierMapMask) +#define XkbAllServerInfoMask (XkbExplicitComponentsMask|XkbKeyActionsMask|XkbKeyBehaviorsMask|XkbVirtualModsMask|XkbVirtualModMapMask) +#define XkbAllMapComponentsMask (XkbAllClientInfoMask|XkbAllServerInfoMask) + + /* + * Symbol interpretations flags: + * - Used in the flags field of a symbol interpretation + */ +#define XkbSI_AutoRepeat (1<<0) +#define XkbSI_LockingKey (1<<1) + + /* + * Symbol interpretations match specification: + * - Used in the match field of a symbol interpretation to specify + * the conditions under which an interpretation is used. + */ +#define XkbSI_LevelOneOnly (0x80) +#define XkbSI_OpMask (0x7f) +#define XkbSI_NoneOf (0) +#define XkbSI_AnyOfOrNone (1) +#define XkbSI_AnyOf (2) +#define XkbSI_AllOf (3) +#define XkbSI_Exactly (4) + + /* + * Indicator map flags: + * - Used in the flags field of an indicator map to indicate the + * conditions under which and indicator can be changed and the + * effects of changing the indicator. + */ +#define XkbIM_NoExplicit (1L << 7) +#define XkbIM_NoAutomatic (1L << 6) +#define XkbIM_LEDDrivesKB (1L << 5) + + /* + * Indicator map component specifications: + * - Used by the 'which_groups' and 'which_mods' fields of an indicator + * map to specify which keyboard components should be used to drive + * the indicator. + */ +#define XkbIM_UseBase (1L << 0) +#define XkbIM_UseLatched (1L << 1) +#define XkbIM_UseLocked (1L << 2) +#define XkbIM_UseEffective (1L << 3) +#define XkbIM_UseCompat (1L << 4) + +#define XkbIM_UseNone 0 +#define XkbIM_UseAnyGroup (XkbIM_UseBase|XkbIM_UseLatched|XkbIM_UseLocked\ + |XkbIM_UseEffective) +#define XkbIM_UseAnyMods (XkbIM_UseAnyGroup|XkbIM_UseCompat) + + /* + * Compatibility Map Components: + * - Specifies the components to be allocated in XkbAllocCompatMap. + */ +#define XkbSymInterpMask (1<<0) +#define XkbGroupCompatMask (1<<1) +#define XkbAllCompatMask (0x3) + + /* + * Names component mask: + * - Specifies the names to be loaded or changed for the GetNames and + * SetNames requests. + * - Specifies the names that have changed in a NamesNotify event. + * - Specifies the names components to be allocated by XkbAllocNames. + */ +#define XkbKeycodesNameMask (1<<0) +#define XkbGeometryNameMask (1<<1) +#define XkbSymbolsNameMask (1<<2) +#define XkbPhysSymbolsNameMask (1<<3) +#define XkbTypesNameMask (1<<4) +#define XkbCompatNameMask (1<<5) +#define XkbKeyTypeNamesMask (1<<6) +#define XkbKTLevelNamesMask (1<<7) +#define XkbIndicatorNamesMask (1<<8) +#define XkbKeyNamesMask (1<<9) +#define XkbKeyAliasesMask (1<<10) +#define XkbVirtualModNamesMask (1<<11) +#define XkbGroupNamesMask (1<<12) +#define XkbRGNamesMask (1<<13) +#define XkbComponentNamesMask (0x3f) +#define XkbAllNamesMask (0x3fff) + + /* + * GetByName components: + * - Specifies desired or necessary components to GetKbdByName request. + * - Reports the components that were found in a GetKbdByNameReply + */ +#define XkbGBN_TypesMask (1L << 0) +#define XkbGBN_CompatMapMask (1L << 1) +#define XkbGBN_ClientSymbolsMask (1L << 2) +#define XkbGBN_ServerSymbolsMask (1L << 3) +#define XkbGBN_SymbolsMask (XkbGBN_ClientSymbolsMask|XkbGBN_ServerSymbolsMask) +#define XkbGBN_IndicatorMapMask (1L << 4) +#define XkbGBN_KeyNamesMask (1L << 5) +#define XkbGBN_GeometryMask (1L << 6) +#define XkbGBN_OtherNamesMask (1L << 7) +#define XkbGBN_AllComponentsMask (0xff) + + /* + * ListComponents flags + */ +#define XkbLC_Hidden (1L << 0) +#define XkbLC_Default (1L << 1) +#define XkbLC_Partial (1L << 2) + +#define XkbLC_AlphanumericKeys (1L << 8) +#define XkbLC_ModifierKeys (1L << 9) +#define XkbLC_KeypadKeys (1L << 10) +#define XkbLC_FunctionKeys (1L << 11) +#define XkbLC_AlternateGroup (1L << 12) + + /* + * X Input Extension Interactions + * - Specifies the possible interactions between XKB and the X input + * extension + * - Used to request (XkbGetDeviceInfo) or change (XKbSetDeviceInfo) + * XKB information about an extension device. + * - Reports the list of supported optional features in the reply to + * XkbGetDeviceInfo or in an XkbExtensionDeviceNotify event. + * XkbXI_UnsupportedFeature is reported in XkbExtensionDeviceNotify + * events to indicate an attempt to use an unsupported feature. + */ +#define XkbXI_KeyboardsMask (1L << 0) +#define XkbXI_ButtonActionsMask (1L << 1) +#define XkbXI_IndicatorNamesMask (1L << 2) +#define XkbXI_IndicatorMapsMask (1L << 3) +#define XkbXI_IndicatorStateMask (1L << 4) +#define XkbXI_UnsupportedFeatureMask (1L << 15) +#define XkbXI_AllFeaturesMask (0x001f) +#define XkbXI_AllDeviceFeaturesMask (0x001e) + +#define XkbXI_IndicatorsMask (0x001c) +#define XkbAllExtensionDeviceEventsMask (0x801f) + + /* + * Per-Client Flags: + * - Specifies flags to be changed by the PerClientFlags request. + */ +#define XkbPCF_DetectableAutoRepeatMask (1L << 0) +#define XkbPCF_GrabsUseXKBStateMask (1L << 1) +#define XkbPCF_AutoResetControlsMask (1L << 2) +#define XkbPCF_LookupStateWhenGrabbed (1L << 3) +#define XkbPCF_SendEventUsesXKBState (1L << 4) +#define XkbPCF_AllFlagsMask (0x1F) + + /* + * Debugging flags and controls + */ +#define XkbDF_DisableLocks (1<<0) + +#endif /* _XKB_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/extensions/XKBstr.h b/thirdparty/linuxbsd_headers/X11/extensions/XKBstr.h new file mode 100644 index 0000000000..eaefae8220 --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/extensions/XKBstr.h @@ -0,0 +1,643 @@ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +Permission to use, copy, modify, and distribute this +software and its documentation for any purpose and without +fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright +notice and this permission notice appear in supporting +documentation, and that the name of Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL +DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH +THE USE OR PERFORMANCE OF THIS SOFTWARE. + +********************************************************/ + +#ifndef _XKBSTR_H_ +#define _XKBSTR_H_ + +#include <X11/Xfuncproto.h> +#include <X11/extensions/XKB.h> + +#define XkbCharToInt(v) ((v)&0x80?(int)((v)|(~0xff)):(int)((v)&0x7f)) +#define XkbIntTo2Chars(i,h,l) (((h)=((i>>8)&0xff)),((l)=((i)&0xff))) +#define Xkb2CharsToInt(h,l) ((short)(((h)<<8)|(l))) + +/* + * The Xkb structs are full of implicit padding to properly align members. + * We can't clean that up without breaking ABI, so tell clang not to bother + * complaining about it. + */ +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + + /* + * Common data structures and access macros + */ + +typedef struct _XkbStateRec { + unsigned char group; + unsigned char locked_group; + unsigned short base_group; + unsigned short latched_group; + unsigned char mods; + unsigned char base_mods; + unsigned char latched_mods; + unsigned char locked_mods; + unsigned char compat_state; + unsigned char grab_mods; + unsigned char compat_grab_mods; + unsigned char lookup_mods; + unsigned char compat_lookup_mods; + unsigned short ptr_buttons; +} XkbStateRec,*XkbStatePtr; +#define XkbModLocks(s) ((s)->locked_mods) +#define XkbStateMods(s) ((s)->base_mods|(s)->latched_mods|XkbModLocks(s)) +#define XkbGroupLock(s) ((s)->locked_group) +#define XkbStateGroup(s) ((s)->base_group+(s)->latched_group+XkbGroupLock(s)) +#define XkbStateFieldFromRec(s) XkbBuildCoreState((s)->lookup_mods,(s)->group) +#define XkbGrabStateFromRec(s) XkbBuildCoreState((s)->grab_mods,(s)->group) + +typedef struct _XkbMods { + unsigned char mask; /* effective mods */ + unsigned char real_mods; + unsigned short vmods; +} XkbModsRec,*XkbModsPtr; + +typedef struct _XkbKTMapEntry { + Bool active; + unsigned char level; + XkbModsRec mods; +} XkbKTMapEntryRec,*XkbKTMapEntryPtr; + +typedef struct _XkbKeyType { + XkbModsRec mods; + unsigned char num_levels; + unsigned char map_count; + /* map is an array of map_count XkbKTMapEntryRec structs */ + XkbKTMapEntryPtr map; + /* preserve is an array of map_count XkbModsRec structs */ + XkbModsPtr preserve; + Atom name; + /* level_names is an array of num_levels Atoms */ + Atom * level_names; +} XkbKeyTypeRec, *XkbKeyTypePtr; + +#define XkbNumGroups(g) ((g)&0x0f) +#define XkbOutOfRangeGroupInfo(g) ((g)&0xf0) +#define XkbOutOfRangeGroupAction(g) ((g)&0xc0) +#define XkbOutOfRangeGroupNumber(g) (((g)&0x30)>>4) +#define XkbSetGroupInfo(g,w,n) (((w)&0xc0)|(((n)&3)<<4)|((g)&0x0f)) +#define XkbSetNumGroups(g,n) (((g)&0xf0)|((n)&0x0f)) + + /* + * Structures and access macros used primarily by the server + */ + +typedef struct _XkbBehavior { + unsigned char type; + unsigned char data; +} XkbBehavior; + +#define XkbAnyActionDataSize 7 +typedef struct _XkbAnyAction { + unsigned char type; + unsigned char data[XkbAnyActionDataSize]; +} XkbAnyAction; + +typedef struct _XkbModAction { + unsigned char type; + unsigned char flags; + unsigned char mask; + unsigned char real_mods; + unsigned char vmods1; + unsigned char vmods2; +} XkbModAction; +#define XkbModActionVMods(a) \ + ((short)(((a)->vmods1<<8)|((a)->vmods2))) +#define XkbSetModActionVMods(a,v) \ + (((a)->vmods1=(((v)>>8)&0xff)),(a)->vmods2=((v)&0xff)) + +typedef struct _XkbGroupAction { + unsigned char type; + unsigned char flags; + char group_XXX; +} XkbGroupAction; +#define XkbSAGroup(a) (XkbCharToInt((a)->group_XXX)) +#define XkbSASetGroup(a,g) ((a)->group_XXX=(g)) + +typedef struct _XkbISOAction { + unsigned char type; + unsigned char flags; + unsigned char mask; + unsigned char real_mods; + char group_XXX; + unsigned char affect; + unsigned char vmods1; + unsigned char vmods2; +} XkbISOAction; + +typedef struct _XkbPtrAction { + unsigned char type; + unsigned char flags; + unsigned char high_XXX; + unsigned char low_XXX; + unsigned char high_YYY; + unsigned char low_YYY; +} XkbPtrAction; +#define XkbPtrActionX(a) (Xkb2CharsToInt((a)->high_XXX,(a)->low_XXX)) +#define XkbPtrActionY(a) (Xkb2CharsToInt((a)->high_YYY,(a)->low_YYY)) +#define XkbSetPtrActionX(a,x) (XkbIntTo2Chars(x,(a)->high_XXX,(a)->low_XXX)) +#define XkbSetPtrActionY(a,y) (XkbIntTo2Chars(y,(a)->high_YYY,(a)->low_YYY)) + +typedef struct _XkbPtrBtnAction { + unsigned char type; + unsigned char flags; + unsigned char count; + unsigned char button; +} XkbPtrBtnAction; + +typedef struct _XkbPtrDfltAction { + unsigned char type; + unsigned char flags; + unsigned char affect; + char valueXXX; +} XkbPtrDfltAction; +#define XkbSAPtrDfltValue(a) (XkbCharToInt((a)->valueXXX)) +#define XkbSASetPtrDfltValue(a,c) ((a)->valueXXX= ((c)&0xff)) + +typedef struct _XkbSwitchScreenAction { + unsigned char type; + unsigned char flags; + char screenXXX; +} XkbSwitchScreenAction; +#define XkbSAScreen(a) (XkbCharToInt((a)->screenXXX)) +#define XkbSASetScreen(a,s) ((a)->screenXXX= ((s)&0xff)) + +typedef struct _XkbCtrlsAction { + unsigned char type; + unsigned char flags; + unsigned char ctrls3; + unsigned char ctrls2; + unsigned char ctrls1; + unsigned char ctrls0; +} XkbCtrlsAction; +#define XkbActionSetCtrls(a,c) (((a)->ctrls3=(((c)>>24)&0xff)),\ + ((a)->ctrls2=(((c)>>16)&0xff)),\ + ((a)->ctrls1=(((c)>>8)&0xff)),\ + ((a)->ctrls0=((c)&0xff))) +#define XkbActionCtrls(a) ((((unsigned int)(a)->ctrls3)<<24)|\ + (((unsigned int)(a)->ctrls2)<<16)|\ + (((unsigned int)(a)->ctrls1)<<8)|\ + ((unsigned int)((a)->ctrls0))) + +typedef struct _XkbMessageAction { + unsigned char type; + unsigned char flags; + unsigned char message[6]; +} XkbMessageAction; + +typedef struct _XkbRedirectKeyAction { + unsigned char type; + unsigned char new_key; + unsigned char mods_mask; + unsigned char mods; + unsigned char vmods_mask0; + unsigned char vmods_mask1; + unsigned char vmods0; + unsigned char vmods1; +} XkbRedirectKeyAction; + +#define XkbSARedirectVMods(a) ((((unsigned int)(a)->vmods1)<<8)|\ + ((unsigned int)(a)->vmods0)) +#define XkbSARedirectSetVMods(a,m) (((a)->vmods1=(((m)>>8)&0xff)),\ + ((a)->vmods0=((m)&0xff))) +#define XkbSARedirectVModsMask(a) ((((unsigned int)(a)->vmods_mask1)<<8)|\ + ((unsigned int)(a)->vmods_mask0)) +#define XkbSARedirectSetVModsMask(a,m) (((a)->vmods_mask1=(((m)>>8)&0xff)),\ + ((a)->vmods_mask0=((m)&0xff))) + +typedef struct _XkbDeviceBtnAction { + unsigned char type; + unsigned char flags; + unsigned char count; + unsigned char button; + unsigned char device; +} XkbDeviceBtnAction; + +typedef struct _XkbDeviceValuatorAction { + unsigned char type; + unsigned char device; + unsigned char v1_what; + unsigned char v1_ndx; + unsigned char v1_value; + unsigned char v2_what; + unsigned char v2_ndx; + unsigned char v2_value; +} XkbDeviceValuatorAction; + +typedef union _XkbAction { + XkbAnyAction any; + XkbModAction mods; + XkbGroupAction group; + XkbISOAction iso; + XkbPtrAction ptr; + XkbPtrBtnAction btn; + XkbPtrDfltAction dflt; + XkbSwitchScreenAction screen; + XkbCtrlsAction ctrls; + XkbMessageAction msg; + XkbRedirectKeyAction redirect; + XkbDeviceBtnAction devbtn; + XkbDeviceValuatorAction devval; + unsigned char type; +} XkbAction; + +typedef struct _XkbControls { + unsigned char mk_dflt_btn; + unsigned char num_groups; + unsigned char groups_wrap; + XkbModsRec internal; + XkbModsRec ignore_lock; + unsigned int enabled_ctrls; + unsigned short repeat_delay; + unsigned short repeat_interval; + unsigned short slow_keys_delay; + unsigned short debounce_delay; + unsigned short mk_delay; + unsigned short mk_interval; + unsigned short mk_time_to_max; + unsigned short mk_max_speed; + short mk_curve; + unsigned short ax_options; + unsigned short ax_timeout; + unsigned short axt_opts_mask; + unsigned short axt_opts_values; + unsigned int axt_ctrls_mask; + unsigned int axt_ctrls_values; + unsigned char per_key_repeat[XkbPerKeyBitArraySize]; +} XkbControlsRec, *XkbControlsPtr; + +#define XkbAX_AnyFeedback(c) ((c)->enabled_ctrls&XkbAccessXFeedbackMask) +#define XkbAX_NeedOption(c,w) ((c)->ax_options&(w)) +#define XkbAX_NeedFeedback(c,w) (XkbAX_AnyFeedback(c)&&XkbAX_NeedOption(c,w)) + +typedef struct _XkbServerMapRec { + /* acts is an array of XkbActions structs, with size_acts entries + allocated, and num_acts entries used. */ + unsigned short num_acts; + unsigned short size_acts; + XkbAction *acts; + + /* behaviors, key_acts, explicit, & vmodmap are all arrays with + (xkb->max_key_code + 1) entries allocated for each. */ + XkbBehavior *behaviors; + unsigned short *key_acts; +#if defined(__cplusplus) || defined(c_plusplus) + /* explicit is a C++ reserved word */ + unsigned char *c_explicit; +#else + unsigned char *explicit; +#endif + unsigned char vmods[XkbNumVirtualMods]; + unsigned short *vmodmap; +} XkbServerMapRec, *XkbServerMapPtr; + +#define XkbSMKeyActionsPtr(m,k) (&(m)->acts[(m)->key_acts[k]]) + + /* + * Structures and access macros used primarily by clients + */ + +typedef struct _XkbSymMapRec { + unsigned char kt_index[XkbNumKbdGroups]; + unsigned char group_info; + unsigned char width; + unsigned short offset; +} XkbSymMapRec, *XkbSymMapPtr; + +typedef struct _XkbClientMapRec { + /* types is an array of XkbKeyTypeRec structs, with size_types entries + allocated, and num_types entries used. */ + unsigned char size_types; + unsigned char num_types; + XkbKeyTypePtr types; + + /* syms is an array of size_syms KeySyms, in which num_syms are used */ + unsigned short size_syms; + unsigned short num_syms; + KeySym *syms; + /* key_sym_map is an array of (max_key_code + 1) XkbSymMapRec structs */ + XkbSymMapPtr key_sym_map; + + /* modmap is an array of (max_key_code + 1) unsigned chars */ + unsigned char *modmap; +} XkbClientMapRec, *XkbClientMapPtr; + +#define XkbCMKeyGroupInfo(m,k) ((m)->key_sym_map[k].group_info) +#define XkbCMKeyNumGroups(m,k) (XkbNumGroups((m)->key_sym_map[k].group_info)) +#define XkbCMKeyGroupWidth(m,k,g) (XkbCMKeyType(m,k,g)->num_levels) +#define XkbCMKeyGroupsWidth(m,k) ((m)->key_sym_map[k].width) +#define XkbCMKeyTypeIndex(m,k,g) ((m)->key_sym_map[k].kt_index[g&0x3]) +#define XkbCMKeyType(m,k,g) (&(m)->types[XkbCMKeyTypeIndex(m,k,g)]) +#define XkbCMKeyNumSyms(m,k) (XkbCMKeyGroupsWidth(m,k)*XkbCMKeyNumGroups(m,k)) +#define XkbCMKeySymsOffset(m,k) ((m)->key_sym_map[k].offset) +#define XkbCMKeySymsPtr(m,k) (&(m)->syms[XkbCMKeySymsOffset(m,k)]) + + /* + * Compatibility structures and access macros + */ + +typedef struct _XkbSymInterpretRec { + KeySym sym; + unsigned char flags; + unsigned char match; + unsigned char mods; + unsigned char virtual_mod; + XkbAnyAction act; +} XkbSymInterpretRec,*XkbSymInterpretPtr; + +typedef struct _XkbCompatMapRec { + /* sym_interpret is an array of XkbSymInterpretRec structs, + in which size_si are allocated & num_si are used. */ + XkbSymInterpretPtr sym_interpret; + XkbModsRec groups[XkbNumKbdGroups]; + unsigned short num_si; + unsigned short size_si; +} XkbCompatMapRec, *XkbCompatMapPtr; + +typedef struct _XkbIndicatorMapRec { + unsigned char flags; + unsigned char which_groups; + unsigned char groups; + unsigned char which_mods; + XkbModsRec mods; + unsigned int ctrls; +} XkbIndicatorMapRec, *XkbIndicatorMapPtr; + +#define XkbIM_IsAuto(i) ((((i)->flags&XkbIM_NoAutomatic)==0)&&\ + (((i)->which_groups&&(i)->groups)||\ + ((i)->which_mods&&(i)->mods.mask)||\ + ((i)->ctrls))) +#define XkbIM_InUse(i) (((i)->flags)||((i)->which_groups)||\ + ((i)->which_mods)||((i)->ctrls)) + + +typedef struct _XkbIndicatorRec { + unsigned long phys_indicators; + XkbIndicatorMapRec maps[XkbNumIndicators]; +} XkbIndicatorRec,*XkbIndicatorPtr; + +typedef struct _XkbKeyNameRec { + char name[XkbKeyNameLength] _X_NONSTRING; +} XkbKeyNameRec,*XkbKeyNamePtr; + +typedef struct _XkbKeyAliasRec { + char real[XkbKeyNameLength] _X_NONSTRING; + char alias[XkbKeyNameLength] _X_NONSTRING; +} XkbKeyAliasRec,*XkbKeyAliasPtr; + + /* + * Names for everything + */ +typedef struct _XkbNamesRec { + Atom keycodes; + Atom geometry; + Atom symbols; + Atom types; + Atom compat; + Atom vmods[XkbNumVirtualMods]; + Atom indicators[XkbNumIndicators]; + Atom groups[XkbNumKbdGroups]; + /* keys is an array of (xkb->max_key_code + 1) XkbKeyNameRec entries */ + XkbKeyNamePtr keys; + /* key_aliases is an array of num_key_aliases XkbKeyAliasRec entries */ + XkbKeyAliasPtr key_aliases; + /* radio_groups is an array of num_rg Atoms */ + Atom *radio_groups; + Atom phys_symbols; + + /* num_keys seems to be unused in libX11 */ + unsigned char num_keys; + unsigned char num_key_aliases; + unsigned short num_rg; +} XkbNamesRec,*XkbNamesPtr; + +typedef struct _XkbGeometry *XkbGeometryPtr; + /* + * Tie it all together into one big keyboard description + */ +typedef struct _XkbDesc { + struct _XDisplay * dpy; + unsigned short flags; + unsigned short device_spec; + KeyCode min_key_code; + KeyCode max_key_code; + + XkbControlsPtr ctrls; + XkbServerMapPtr server; + XkbClientMapPtr map; + XkbIndicatorPtr indicators; + XkbNamesPtr names; + XkbCompatMapPtr compat; + XkbGeometryPtr geom; +} XkbDescRec, *XkbDescPtr; +#define XkbKeyKeyTypeIndex(d,k,g) (XkbCMKeyTypeIndex((d)->map,k,g)) +#define XkbKeyKeyType(d,k,g) (XkbCMKeyType((d)->map,k,g)) +#define XkbKeyGroupWidth(d,k,g) (XkbCMKeyGroupWidth((d)->map,k,g)) +#define XkbKeyGroupsWidth(d,k) (XkbCMKeyGroupsWidth((d)->map,k)) +#define XkbKeyGroupInfo(d,k) (XkbCMKeyGroupInfo((d)->map,(k))) +#define XkbKeyNumGroups(d,k) (XkbCMKeyNumGroups((d)->map,(k))) +#define XkbKeyNumSyms(d,k) (XkbCMKeyNumSyms((d)->map,(k))) +#define XkbKeySymsPtr(d,k) (XkbCMKeySymsPtr((d)->map,(k))) +#define XkbKeySym(d,k,n) (XkbKeySymsPtr(d,k)[n]) +#define XkbKeySymEntry(d,k,sl,g) \ + (XkbKeySym(d,k,((XkbKeyGroupsWidth(d,k)*(g))+(sl)))) +#define XkbKeyAction(d,k,n) \ + (XkbKeyHasActions(d,k)?&XkbKeyActionsPtr(d,k)[n]:NULL) +#define XkbKeyActionEntry(d,k,sl,g) \ + (XkbKeyHasActions(d,k)?\ + XkbKeyAction(d,k,((XkbKeyGroupsWidth(d,k)*(g))+(sl))):NULL) + +#define XkbKeyHasActions(d,k) ((d)->server->key_acts[k]!=0) +#define XkbKeyNumActions(d,k) (XkbKeyHasActions(d,k)?XkbKeyNumSyms(d,k):1) +#define XkbKeyActionsPtr(d,k) (XkbSMKeyActionsPtr((d)->server,k)) +#define XkbKeycodeInRange(d,k) (((k)>=(d)->min_key_code)&&\ + ((k)<=(d)->max_key_code)) +#define XkbNumKeys(d) ((d)->max_key_code-(d)->min_key_code+1) + + + /* + * The following structures can be used to track changes + * to a keyboard device + */ +typedef struct _XkbMapChanges { + unsigned short changed; + KeyCode min_key_code; + KeyCode max_key_code; + unsigned char first_type; + unsigned char num_types; + KeyCode first_key_sym; + unsigned char num_key_syms; + KeyCode first_key_act; + unsigned char num_key_acts; + KeyCode first_key_behavior; + unsigned char num_key_behaviors; + KeyCode first_key_explicit; + unsigned char num_key_explicit; + KeyCode first_modmap_key; + unsigned char num_modmap_keys; + KeyCode first_vmodmap_key; + unsigned char num_vmodmap_keys; + unsigned char pad; + unsigned short vmods; +} XkbMapChangesRec,*XkbMapChangesPtr; + +typedef struct _XkbControlsChanges { + unsigned int changed_ctrls; + unsigned int enabled_ctrls_changes; + Bool num_groups_changed; +} XkbControlsChangesRec,*XkbControlsChangesPtr; + +typedef struct _XkbIndicatorChanges { + unsigned int state_changes; + unsigned int map_changes; +} XkbIndicatorChangesRec,*XkbIndicatorChangesPtr; + +typedef struct _XkbNameChanges { + unsigned int changed; + unsigned char first_type; + unsigned char num_types; + unsigned char first_lvl; + unsigned char num_lvls; + unsigned char num_aliases; + unsigned char num_rg; + unsigned char first_key; + unsigned char num_keys; + unsigned short changed_vmods; + unsigned long changed_indicators; + unsigned char changed_groups; +} XkbNameChangesRec,*XkbNameChangesPtr; + +typedef struct _XkbCompatChanges { + unsigned char changed_groups; + unsigned short first_si; + unsigned short num_si; +} XkbCompatChangesRec,*XkbCompatChangesPtr; + +typedef struct _XkbChanges { + unsigned short device_spec; + unsigned short state_changes; + XkbMapChangesRec map; + XkbControlsChangesRec ctrls; + XkbIndicatorChangesRec indicators; + XkbNameChangesRec names; + XkbCompatChangesRec compat; +} XkbChangesRec, *XkbChangesPtr; + + /* + * These data structures are used to construct a keymap from + * a set of components or to list components in the server + * database. + */ +typedef struct _XkbComponentNames { + char * keymap; + char * keycodes; + char * types; + char * compat; + char * symbols; + char * geometry; +} XkbComponentNamesRec, *XkbComponentNamesPtr; + +typedef struct _XkbComponentName { + unsigned short flags; + char * name; +} XkbComponentNameRec,*XkbComponentNamePtr; + +typedef struct _XkbComponentList { + int num_keymaps; + int num_keycodes; + int num_types; + int num_compat; + int num_symbols; + int num_geometry; + XkbComponentNamePtr keymaps; + XkbComponentNamePtr keycodes; + XkbComponentNamePtr types; + XkbComponentNamePtr compat; + XkbComponentNamePtr symbols; + XkbComponentNamePtr geometry; +} XkbComponentListRec, *XkbComponentListPtr; + + /* + * The following data structures describe and track changes to a + * non-keyboard extension device + */ +typedef struct _XkbDeviceLedInfo { + unsigned short led_class; + unsigned short led_id; + unsigned int phys_indicators; + unsigned int maps_present; + unsigned int names_present; + unsigned int state; + Atom names[XkbNumIndicators]; + XkbIndicatorMapRec maps[XkbNumIndicators]; +} XkbDeviceLedInfoRec,*XkbDeviceLedInfoPtr; + +typedef struct _XkbDeviceInfo { + char * name; + Atom type; + unsigned short device_spec; + Bool has_own_state; + unsigned short supported; + unsigned short unsupported; + + /* btn_acts is an array of num_btn XkbAction entries */ + unsigned short num_btns; + XkbAction * btn_acts; + + unsigned short sz_leds; + unsigned short num_leds; + unsigned short dflt_kbd_fb; + unsigned short dflt_led_fb; + /* leds is an array of XkbDeviceLedInfoRec in which + sz_leds entries are allocated and num_leds entries are used */ + XkbDeviceLedInfoPtr leds; +} XkbDeviceInfoRec,*XkbDeviceInfoPtr; + +#define XkbXI_DevHasBtnActs(d) (((d)->num_btns>0)&&((d)->btn_acts!=NULL)) +#define XkbXI_LegalDevBtn(d,b) (XkbXI_DevHasBtnActs(d)&&((b)<(d)->num_btns)) +#define XkbXI_DevHasLeds(d) (((d)->num_leds>0)&&((d)->leds!=NULL)) + +typedef struct _XkbDeviceLedChanges { + unsigned short led_class; + unsigned short led_id; + unsigned int defined; /* names or maps changed */ + struct _XkbDeviceLedChanges *next; +} XkbDeviceLedChangesRec,*XkbDeviceLedChangesPtr; + +typedef struct _XkbDeviceChanges { + unsigned int changed; + unsigned short first_btn; + unsigned short num_btns; + XkbDeviceLedChangesRec leds; +} XkbDeviceChangesRec,*XkbDeviceChangesPtr; + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#endif /* _XKBSTR_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/extensions/Xext.h b/thirdparty/linuxbsd_headers/X11/extensions/Xext.h new file mode 100644 index 0000000000..858592b78b --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/extensions/Xext.h @@ -0,0 +1,53 @@ +/* + * +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + */ + +#ifndef _XEXT_H_ +#define _XEXT_H_ + +#include <X11/Xfuncproto.h> + +_XFUNCPROTOBEGIN + +typedef int (*XextErrorHandler) ( + Display * /* dpy */, + _Xconst char* /* ext_name */, + _Xconst char* /* reason */ +); + +extern XextErrorHandler XSetExtensionErrorHandler( + XextErrorHandler /* handler */ +); + +extern int XMissingExtension( + Display* /* dpy */, + _Xconst char* /* ext_name */ +); + +_XFUNCPROTOEND + +#define X_EXTENSION_UNKNOWN "unknown" +#define X_EXTENSION_MISSING "missing" + +#endif /* _XEXT_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/extensions/Xfixes.h b/thirdparty/linuxbsd_headers/X11/extensions/Xfixes.h new file mode 100644 index 0000000000..b62b95bac6 --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/extensions/Xfixes.h @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011, 2021 Red Hat, Inc. + * + * 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 (including the next + * paragraph) 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. + */ +/* + * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _XFIXES_H_ +#define _XFIXES_H_ + +#include <X11/extensions/xfixeswire.h> + +#include <X11/Xfuncproto.h> +#include <X11/Xlib.h> + +/* + * This revision number also appears in configure.ac, they have + * to be manually synchronized + */ +#define XFIXES_REVISION 1 +#define XFIXES_VERSION ((XFIXES_MAJOR * 10000) + (XFIXES_MINOR * 100) + (XFIXES_REVISION)) + +typedef struct { + int type; /* event base */ + unsigned long serial; + Bool send_event; + Display *display; + Window window; + int subtype; + Window owner; + Atom selection; + Time timestamp; + Time selection_timestamp; +} XFixesSelectionNotifyEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; + Bool send_event; + Display *display; + Window window; + int subtype; + unsigned long cursor_serial; + Time timestamp; + Atom cursor_name; +} XFixesCursorNotifyEvent; + +typedef struct { + short x, y; + unsigned short width, height; + unsigned short xhot, yhot; + unsigned long cursor_serial; + unsigned long *pixels; +#if XFIXES_MAJOR >= 2 + Atom atom; /* Version >= 2 only */ + const char *name; /* Version >= 2 only */ +#endif +} XFixesCursorImage; + +#if XFIXES_MAJOR >= 2 +/* Version 2 types */ + +typedef XID XserverRegion; + +typedef struct { + short x, y; + unsigned short width, height; + unsigned short xhot, yhot; + unsigned long cursor_serial; + unsigned long *pixels; + Atom atom; + const char *name; +} XFixesCursorImageAndName; + +#endif + +_XFUNCPROTOBEGIN + +Bool XFixesQueryExtension (Display *dpy, + int *event_base_return, + int *error_base_return); +Status XFixesQueryVersion (Display *dpy, + int *major_version_return, + int *minor_version_return); + +int XFixesVersion (void); + +void +XFixesChangeSaveSet (Display *dpy, + Window win, + int mode, + int target, + int map); + +void +XFixesSelectSelectionInput (Display *dpy, + Window win, + Atom selection, + unsigned long eventMask); + +void +XFixesSelectCursorInput (Display *dpy, + Window win, + unsigned long eventMask); + +XFixesCursorImage * +XFixesGetCursorImage (Display *dpy); + +#if XFIXES_MAJOR >= 2 +/* Version 2 functions */ + +XserverRegion +XFixesCreateRegion (Display *dpy, XRectangle *rectangles, int nrectangles); + +XserverRegion +XFixesCreateRegionFromBitmap (Display *dpy, Pixmap bitmap); + +XserverRegion +XFixesCreateRegionFromWindow (Display *dpy, Window window, int kind); + +XserverRegion +XFixesCreateRegionFromGC (Display *dpy, GC gc); + +XserverRegion +XFixesCreateRegionFromPicture (Display *dpy, XID picture); + +void +XFixesDestroyRegion (Display *dpy, XserverRegion region); + +void +XFixesSetRegion (Display *dpy, XserverRegion region, + XRectangle *rectangles, int nrectangles); + +void +XFixesCopyRegion (Display *dpy, XserverRegion dst, XserverRegion src); + +void +XFixesUnionRegion (Display *dpy, XserverRegion dst, + XserverRegion src1, XserverRegion src2); + +void +XFixesIntersectRegion (Display *dpy, XserverRegion dst, + XserverRegion src1, XserverRegion src2); + +void +XFixesSubtractRegion (Display *dpy, XserverRegion dst, + XserverRegion src1, XserverRegion src2); + +void +XFixesInvertRegion (Display *dpy, XserverRegion dst, + XRectangle *rect, XserverRegion src); + +void +XFixesTranslateRegion (Display *dpy, XserverRegion region, int dx, int dy); + +void +XFixesRegionExtents (Display *dpy, XserverRegion dst, XserverRegion src); + +XRectangle * +XFixesFetchRegion (Display *dpy, XserverRegion region, int *nrectanglesRet); + +XRectangle * +XFixesFetchRegionAndBounds (Display *dpy, XserverRegion region, + int *nrectanglesRet, + XRectangle *bounds); + +void +XFixesSetGCClipRegion (Display *dpy, GC gc, + int clip_x_origin, int clip_y_origin, + XserverRegion region); + +void +XFixesSetWindowShapeRegion (Display *dpy, Window win, int shape_kind, + int x_off, int y_off, XserverRegion region); + +void +XFixesSetPictureClipRegion (Display *dpy, XID picture, + int clip_x_origin, int clip_y_origin, + XserverRegion region); + +void +XFixesSetCursorName (Display *dpy, Cursor cursor, const char *name); + +const char * +XFixesGetCursorName (Display *dpy, Cursor cursor, Atom *atom); + +void +XFixesChangeCursor (Display *dpy, Cursor source, Cursor destination); + +void +XFixesChangeCursorByName (Display *dpy, Cursor source, const char *name); + +#endif /* XFIXES_MAJOR >= 2 */ + +#if XFIXES_MAJOR >= 3 + +void +XFixesExpandRegion (Display *dpy, XserverRegion dst, XserverRegion src, + unsigned left, unsigned right, + unsigned top, unsigned bottom); + +#endif /* XFIXES_MAJOR >= 3 */ + +#if XFIXES_MAJOR >= 4 +/* Version 4.0 externs */ + +void +XFixesHideCursor (Display *dpy, Window win); + +void +XFixesShowCursor (Display *dpy, Window win); + +#endif /* XFIXES_MAJOR >= 4 */ + +#if XFIXES_MAJOR >= 5 + +typedef XID PointerBarrier; + +PointerBarrier +XFixesCreatePointerBarrier(Display *dpy, Window w, int x1, int y1, + int x2, int y2, int directions, + int num_devices, int *devices); + +void +XFixesDestroyPointerBarrier(Display *dpy, PointerBarrier b); + +#endif /* XFIXES_MAJOR >= 5 */ + +#if XFIXES_MAJOR >= 6 + +void +XFixesSetClientDisconnectMode(Display *dpy, int disconnect_mode); + +int +XFixesGetClientDisconnectMode(Display *dpy); + +#endif /* XFIXES_MAJOR >= 6 */ + +_XFUNCPROTOEND + +#endif /* _XFIXES_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/extensions/Xge.h b/thirdparty/linuxbsd_headers/X11/extensions/Xge.h new file mode 100644 index 0000000000..76b5a6a019 --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/extensions/Xge.h @@ -0,0 +1,57 @@ +/* + * Copyright © 2007-2008 Peter Hutterer + * + * 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 (including the next + * paragraph) 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. + * + * Authors: Peter Hutterer, University of South Australia, NICTA + * + */ + + +/* XGE Client interfaces */ + +#ifndef _XGE_H_ +#define _XGE_H_ + +#include <X11/Xlib.h> +#include <X11/Xfuncproto.h> + +_XFUNCPROTOBEGIN + +/** + * Generic Event mask. + * To be used whenever a list of masks per extension has to be provided. + * + * But, don't actually use the CARD{8,16,32} types. We can't get them them + * defined here without polluting the namespace. + */ +typedef struct { + unsigned char extension; + unsigned char pad0; + unsigned short pad1; + unsigned int evmask; +} XGenericEventMask; + +Bool XGEQueryExtension(Display* dpy, int *event_basep, int *err_basep); +Bool XGEQueryVersion(Display* dpy, int *major, int* minor); + +_XFUNCPROTOEND + +#endif /* _XGE_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h b/thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h new file mode 100644 index 0000000000..8c0f8296ac --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h @@ -0,0 +1,74 @@ +/* + +Copyright 2003 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +#ifndef _Xinerama_h +#define _Xinerama_h + +#include <X11/Xlib.h> + +typedef struct { + int screen_number; + short x_org; + short y_org; + short width; + short height; +} XineramaScreenInfo; + +_XFUNCPROTOBEGIN + +Bool XineramaQueryExtension ( + Display *dpy, + int *event_base, + int *error_base +); + +Status XineramaQueryVersion( + Display *dpy, + int *major_versionp, + int *minor_versionp +); + +Bool XineramaIsActive(Display *dpy); + + +/* + Returns the number of heads and a pointer to an array of + structures describing the position and size of the individual + heads. Returns NULL and number = 0 if Xinerama is not active. + + Returned array should be freed with XFree(). +*/ + +XineramaScreenInfo * +XineramaQueryScreens( + Display *dpy, + int *number +); + +_XFUNCPROTOEND + +#endif /* _Xinerama_h */ + diff --git a/thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h b/thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h new file mode 100644 index 0000000000..65940bbdb1 --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h @@ -0,0 +1,587 @@ +/* + * Copyright © 2000 Compaq Computer Corporation, Inc. + * Copyright © 2002 Hewlett-Packard Company, Inc. + * Copyright © 2006 Intel Corporation + * Copyright © 2008 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + * + * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc. + * Keith Packard, Intel Corporation + */ + +#ifndef _XRANDR_H_ +#define _XRANDR_H_ + +#include <X11/extensions/randr.h> +#include <X11/extensions/Xrender.h> + +#include <X11/Xfuncproto.h> + +_XFUNCPROTOBEGIN + +typedef XID RROutput; +typedef XID RRCrtc; +typedef XID RRMode; +typedef XID RRProvider; + +typedef struct { + int width, height; + int mwidth, mheight; +} XRRScreenSize; + +/* + * Events. + */ + +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + Window root; /* Root window for changed screen */ + Time timestamp; /* when the screen change occurred */ + Time config_timestamp; /* when the last configuration change */ + SizeID size_index; + SubpixelOrder subpixel_order; + Rotation rotation; + int width; + int height; + int mwidth; + int mheight; +} XRRScreenChangeNotifyEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + int subtype; /* RRNotify_ subtype */ +} XRRNotifyEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + int subtype; /* RRNotify_OutputChange */ + RROutput output; /* affected output */ + RRCrtc crtc; /* current crtc (or None) */ + RRMode mode; /* current mode (or None) */ + Rotation rotation; /* current rotation of associated crtc */ + Connection connection; /* current connection status */ + SubpixelOrder subpixel_order; +} XRROutputChangeNotifyEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + int subtype; /* RRNotify_CrtcChange */ + RRCrtc crtc; /* current crtc (or None) */ + RRMode mode; /* current mode (or None) */ + Rotation rotation; /* current rotation of associated crtc */ + int x, y; /* position */ + unsigned int width, height; /* size */ +} XRRCrtcChangeNotifyEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + int subtype; /* RRNotify_OutputProperty */ + RROutput output; /* related output */ + Atom property; /* changed property */ + Time timestamp; /* time of change */ + int state; /* NewValue, Deleted */ +} XRROutputPropertyNotifyEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + int subtype; /* RRNotify_ProviderChange */ + RRProvider provider; /* current provider (or None) */ + Time timestamp; /* time of change */ + unsigned int current_role; +} XRRProviderChangeNotifyEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + int subtype; /* RRNotify_ProviderProperty */ + RRProvider provider; /* related provider */ + Atom property; /* changed property */ + Time timestamp; /* time of change */ + int state; /* NewValue, Deleted */ +} XRRProviderPropertyNotifyEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + int subtype; /* RRNotify_ResourceChange */ + Time timestamp; /* time of change */ +} XRRResourceChangeNotifyEvent; + +/* internal representation is private to the library */ +typedef struct _XRRScreenConfiguration XRRScreenConfiguration; + +Bool XRRQueryExtension (Display *dpy, + int *event_base_return, + int *error_base_return); +Status XRRQueryVersion (Display *dpy, + int *major_version_return, + int *minor_version_return); + +XRRScreenConfiguration *XRRGetScreenInfo (Display *dpy, + Window window); + +void XRRFreeScreenConfigInfo (XRRScreenConfiguration *config); + +/* + * Note that screen configuration changes are only permitted if the client can + * prove it has up to date configuration information. We are trying to + * insist that it become possible for screens to change dynamically, so + * we want to ensure the client knows what it is talking about when requesting + * changes. + */ +Status XRRSetScreenConfig (Display *dpy, + XRRScreenConfiguration *config, + Drawable draw, + int size_index, + Rotation rotation, + Time timestamp); + +/* added in v1.1, sorry for the lame name */ +Status XRRSetScreenConfigAndRate (Display *dpy, + XRRScreenConfiguration *config, + Drawable draw, + int size_index, + Rotation rotation, + short rate, + Time timestamp); + + +Rotation XRRConfigRotations(XRRScreenConfiguration *config, Rotation *current_rotation); + +Time XRRConfigTimes (XRRScreenConfiguration *config, Time *config_timestamp); + +XRRScreenSize *XRRConfigSizes(XRRScreenConfiguration *config, int *nsizes); + +short *XRRConfigRates (XRRScreenConfiguration *config, int sizeID, int *nrates); + +SizeID XRRConfigCurrentConfiguration (XRRScreenConfiguration *config, + Rotation *rotation); + +short XRRConfigCurrentRate (XRRScreenConfiguration *config); + +int XRRRootToScreen(Display *dpy, Window root); + +/* + * returns the screen configuration for the specified screen; does a lazy + * evalution to delay getting the information, and caches the result. + * These routines should be used in preference to XRRGetScreenInfo + * to avoid unneeded round trips to the X server. These are new + * in protocol version 0.1. + */ + + +void XRRSelectInput(Display *dpy, Window window, int mask); + +/* + * the following are always safe to call, even if RandR is not implemented + * on a screen + */ + + +Rotation XRRRotations(Display *dpy, int screen, Rotation *current_rotation); +XRRScreenSize *XRRSizes(Display *dpy, int screen, int *nsizes); +short *XRRRates (Display *dpy, int screen, int sizeID, int *nrates); +Time XRRTimes (Display *dpy, int screen, Time *config_timestamp); + + +/* Version 1.2 additions */ + +/* despite returning a Status, this returns 1 for success */ +Status +XRRGetScreenSizeRange (Display *dpy, Window window, + int *minWidth, int *minHeight, + int *maxWidth, int *maxHeight); + +void +XRRSetScreenSize (Display *dpy, Window window, + int width, int height, + int mmWidth, int mmHeight); + +typedef unsigned long XRRModeFlags; + +typedef struct _XRRModeInfo { + RRMode id; + unsigned int width; + unsigned int height; + unsigned long dotClock; + unsigned int hSyncStart; + unsigned int hSyncEnd; + unsigned int hTotal; + unsigned int hSkew; + unsigned int vSyncStart; + unsigned int vSyncEnd; + unsigned int vTotal; + char *name; + unsigned int nameLength; + XRRModeFlags modeFlags; +} XRRModeInfo; + +typedef struct _XRRScreenResources { + Time timestamp; + Time configTimestamp; + int ncrtc; + RRCrtc *crtcs; + int noutput; + RROutput *outputs; + int nmode; + XRRModeInfo *modes; +} XRRScreenResources; + +XRRScreenResources * +XRRGetScreenResources (Display *dpy, Window window); + +void +XRRFreeScreenResources (XRRScreenResources *resources); + +typedef struct _XRROutputInfo { + Time timestamp; + RRCrtc crtc; + char *name; + int nameLen; + unsigned long mm_width; + unsigned long mm_height; + Connection connection; + SubpixelOrder subpixel_order; + int ncrtc; + RRCrtc *crtcs; + int nclone; + RROutput *clones; + int nmode; + int npreferred; + RRMode *modes; +} XRROutputInfo; + +XRROutputInfo * +XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output); + +void +XRRFreeOutputInfo (XRROutputInfo *outputInfo); + +Atom * +XRRListOutputProperties (Display *dpy, RROutput output, int *nprop); + +typedef struct { + Bool pending; + Bool range; + Bool immutable; + int num_values; + long *values; +} XRRPropertyInfo; + +XRRPropertyInfo * +XRRQueryOutputProperty (Display *dpy, RROutput output, Atom property); + +void +XRRConfigureOutputProperty (Display *dpy, RROutput output, Atom property, + Bool pending, Bool range, int num_values, + long *values); + +void +XRRChangeOutputProperty (Display *dpy, RROutput output, + Atom property, Atom type, + int format, int mode, + _Xconst unsigned char *data, int nelements); + +void +XRRDeleteOutputProperty (Display *dpy, RROutput output, Atom property); + +int +XRRGetOutputProperty (Display *dpy, RROutput output, + Atom property, long offset, long length, + Bool _delete, Bool pending, Atom req_type, + Atom *actual_type, int *actual_format, + unsigned long *nitems, unsigned long *bytes_after, + unsigned char **prop); + +XRRModeInfo * +XRRAllocModeInfo (_Xconst char *name, int nameLength); + +RRMode +XRRCreateMode (Display *dpy, Window window, XRRModeInfo *modeInfo); + +void +XRRDestroyMode (Display *dpy, RRMode mode); + +void +XRRAddOutputMode (Display *dpy, RROutput output, RRMode mode); + +void +XRRDeleteOutputMode (Display *dpy, RROutput output, RRMode mode); + +void +XRRFreeModeInfo (XRRModeInfo *modeInfo); + +typedef struct _XRRCrtcInfo { + Time timestamp; + int x, y; + unsigned int width, height; + RRMode mode; + Rotation rotation; + int noutput; + RROutput *outputs; + Rotation rotations; + int npossible; + RROutput *possible; +} XRRCrtcInfo; + +XRRCrtcInfo * +XRRGetCrtcInfo (Display *dpy, XRRScreenResources *resources, RRCrtc crtc); + +void +XRRFreeCrtcInfo (XRRCrtcInfo *crtcInfo); + +Status +XRRSetCrtcConfig (Display *dpy, + XRRScreenResources *resources, + RRCrtc crtc, + Time timestamp, + int x, int y, + RRMode mode, + Rotation rotation, + RROutput *outputs, + int noutputs); + +int +XRRGetCrtcGammaSize (Display *dpy, RRCrtc crtc); + +typedef struct _XRRCrtcGamma { + int size; + unsigned short *red; + unsigned short *green; + unsigned short *blue; +} XRRCrtcGamma; + +XRRCrtcGamma * +XRRGetCrtcGamma (Display *dpy, RRCrtc crtc); + +XRRCrtcGamma * +XRRAllocGamma (int size); + +void +XRRSetCrtcGamma (Display *dpy, RRCrtc crtc, XRRCrtcGamma *gamma); + +void +XRRFreeGamma (XRRCrtcGamma *gamma); + +/* Version 1.3 additions */ + +XRRScreenResources * +XRRGetScreenResourcesCurrent (Display *dpy, Window window); + +void +XRRSetCrtcTransform (Display *dpy, + RRCrtc crtc, + XTransform *transform, + _Xconst char *filter, + XFixed *params, + int nparams); + +typedef struct _XRRCrtcTransformAttributes { + XTransform pendingTransform; + char *pendingFilter; + int pendingNparams; + XFixed *pendingParams; + XTransform currentTransform; + char *currentFilter; + int currentNparams; + XFixed *currentParams; +} XRRCrtcTransformAttributes; + +/* + * Get current crtc transforms and filters. + * Pass *attributes to XFree to free + */ +Status +XRRGetCrtcTransform (Display *dpy, + RRCrtc crtc, + XRRCrtcTransformAttributes **attributes); + +/* + * intended to take RRScreenChangeNotify, or + * ConfigureNotify (on the root window) + * returns 1 if it is an event type it understands, 0 if not + */ +int XRRUpdateConfiguration(XEvent *event); + +typedef struct _XRRPanning { + Time timestamp; + unsigned int left; + unsigned int top; + unsigned int width; + unsigned int height; + unsigned int track_left; + unsigned int track_top; + unsigned int track_width; + unsigned int track_height; + int border_left; + int border_top; + int border_right; + int border_bottom; +} XRRPanning; + +XRRPanning * +XRRGetPanning (Display *dpy, XRRScreenResources *resources, RRCrtc crtc); + +void +XRRFreePanning (XRRPanning *panning); + +Status +XRRSetPanning (Display *dpy, + XRRScreenResources *resources, + RRCrtc crtc, + XRRPanning *panning); + +void +XRRSetOutputPrimary(Display *dpy, + Window window, + RROutput output); + +RROutput +XRRGetOutputPrimary(Display *dpy, + Window window); + +typedef struct _XRRProviderResources { + Time timestamp; + int nproviders; + RRProvider *providers; +} XRRProviderResources; + +XRRProviderResources * +XRRGetProviderResources(Display *dpy, Window window); + +void +XRRFreeProviderResources(XRRProviderResources *resources); + +typedef struct _XRRProviderInfo { + unsigned int capabilities; + int ncrtcs; + RRCrtc *crtcs; + int noutputs; + RROutput *outputs; + char *name; + int nassociatedproviders; + RRProvider *associated_providers; + unsigned int *associated_capability; + int nameLen; +} XRRProviderInfo; + +XRRProviderInfo * +XRRGetProviderInfo(Display *dpy, XRRScreenResources *resources, RRProvider provider); + +void +XRRFreeProviderInfo(XRRProviderInfo *provider); + +int +XRRSetProviderOutputSource(Display *dpy, XID provider, XID source_provider); + +int +XRRSetProviderOffloadSink(Display *dpy, XID provider, XID sink_provider); + +Atom * +XRRListProviderProperties (Display *dpy, RRProvider provider, int *nprop); + +XRRPropertyInfo * +XRRQueryProviderProperty (Display *dpy, RRProvider provider, Atom property); + +void +XRRConfigureProviderProperty (Display *dpy, RRProvider provider, Atom property, + Bool pending, Bool range, int num_values, + long *values); + +void +XRRChangeProviderProperty (Display *dpy, RRProvider provider, + Atom property, Atom type, + int format, int mode, + _Xconst unsigned char *data, int nelements); + +void +XRRDeleteProviderProperty (Display *dpy, RRProvider provider, Atom property); + +int +XRRGetProviderProperty (Display *dpy, RRProvider provider, + Atom property, long offset, long length, + Bool _delete, Bool pending, Atom req_type, + Atom *actual_type, int *actual_format, + unsigned long *nitems, unsigned long *bytes_after, + unsigned char **prop); + + +typedef struct _XRRMonitorInfo { + Atom name; + Bool primary; + Bool automatic; + int noutput; + int x; + int y; + int width; + int height; + int mwidth; + int mheight; + RROutput *outputs; +} XRRMonitorInfo; + +XRRMonitorInfo * +XRRAllocateMonitor(Display *dpy, int noutput); + +XRRMonitorInfo * +XRRGetMonitors(Display *dpy, Window window, Bool get_active, int *nmonitors); + +void +XRRSetMonitor(Display *dpy, Window window, XRRMonitorInfo *monitor); + +void +XRRDeleteMonitor(Display *dpy, Window window, Atom name); + +void +XRRFreeMonitors(XRRMonitorInfo *monitors); + +_XFUNCPROTOEND + +#endif /* _XRANDR_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/extensions/Xrender.h b/thirdparty/linuxbsd_headers/X11/extensions/Xrender.h new file mode 100644 index 0000000000..1d1cd086ec --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/extensions/Xrender.h @@ -0,0 +1,528 @@ +/* + * + * Copyright © 2000 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#ifndef _XRENDER_H_ +#define _XRENDER_H_ + +#include <X11/Xlib.h> +#include <X11/Xfuncproto.h> +#include <X11/Xosdefs.h> +#include <X11/Xutil.h> + +#include <X11/extensions/render.h> + +typedef struct { + short red; + short redMask; + short green; + short greenMask; + short blue; + short blueMask; + short alpha; + short alphaMask; +} XRenderDirectFormat; + +typedef struct { + PictFormat id; + int type; + int depth; + XRenderDirectFormat direct; + Colormap colormap; +} XRenderPictFormat; + +#define PictFormatID (1 << 0) +#define PictFormatType (1 << 1) +#define PictFormatDepth (1 << 2) +#define PictFormatRed (1 << 3) +#define PictFormatRedMask (1 << 4) +#define PictFormatGreen (1 << 5) +#define PictFormatGreenMask (1 << 6) +#define PictFormatBlue (1 << 7) +#define PictFormatBlueMask (1 << 8) +#define PictFormatAlpha (1 << 9) +#define PictFormatAlphaMask (1 << 10) +#define PictFormatColormap (1 << 11) + +typedef struct _XRenderPictureAttributes { + int repeat; + Picture alpha_map; + int alpha_x_origin; + int alpha_y_origin; + int clip_x_origin; + int clip_y_origin; + Pixmap clip_mask; + Bool graphics_exposures; + int subwindow_mode; + int poly_edge; + int poly_mode; + Atom dither; + Bool component_alpha; +} XRenderPictureAttributes; + +typedef struct { + unsigned short red; + unsigned short green; + unsigned short blue; + unsigned short alpha; +} XRenderColor; + +typedef struct _XGlyphInfo { + unsigned short width; + unsigned short height; + short x; + short y; + short xOff; + short yOff; +} XGlyphInfo; + +typedef struct _XGlyphElt8 { + GlyphSet glyphset; + _Xconst char *chars; + int nchars; + int xOff; + int yOff; +} XGlyphElt8; + +typedef struct _XGlyphElt16 { + GlyphSet glyphset; + _Xconst unsigned short *chars; + int nchars; + int xOff; + int yOff; +} XGlyphElt16; + +typedef struct _XGlyphElt32 { + GlyphSet glyphset; + _Xconst unsigned int *chars; + int nchars; + int xOff; + int yOff; +} XGlyphElt32; + +typedef double XDouble; + +typedef struct _XPointDouble { + XDouble x, y; +} XPointDouble; + +#define XDoubleToFixed(f) ((XFixed) ((f) * 65536)) +#define XFixedToDouble(f) (((XDouble) (f)) / 65536) + +typedef int XFixed; + +typedef struct _XPointFixed { + XFixed x, y; +} XPointFixed; + +typedef struct _XLineFixed { + XPointFixed p1, p2; +} XLineFixed; + +typedef struct _XTriangle { + XPointFixed p1, p2, p3; +} XTriangle; + +typedef struct _XCircle { + XFixed x; + XFixed y; + XFixed radius; +} XCircle; + +typedef struct _XTrapezoid { + XFixed top, bottom; + XLineFixed left, right; +} XTrapezoid; + +typedef struct _XTransform { + XFixed matrix[3][3]; +} XTransform; + +typedef struct _XFilters { + int nfilter; + char **filter; + int nalias; + short *alias; +} XFilters; + +typedef struct _XIndexValue { + unsigned long pixel; + unsigned short red, green, blue, alpha; +} XIndexValue; + +typedef struct _XAnimCursor { + Cursor cursor; + unsigned long delay; +} XAnimCursor; + +typedef struct _XSpanFix { + XFixed left, right, y; +} XSpanFix; + +typedef struct _XTrap { + XSpanFix top, bottom; +} XTrap; + +typedef struct _XLinearGradient { + XPointFixed p1; + XPointFixed p2; +} XLinearGradient; + +typedef struct _XRadialGradient { + XCircle inner; + XCircle outer; +} XRadialGradient; + +typedef struct _XConicalGradient { + XPointFixed center; + XFixed angle; /* in degrees */ +} XConicalGradient; + +_XFUNCPROTOBEGIN + +Bool XRenderQueryExtension (Display *dpy, int *event_basep, int *error_basep); + +Status XRenderQueryVersion (Display *dpy, + int *major_versionp, + int *minor_versionp); + +Status XRenderQueryFormats (Display *dpy); + +int XRenderQuerySubpixelOrder (Display *dpy, int screen); + +Bool XRenderSetSubpixelOrder (Display *dpy, int screen, int subpixel); + +XRenderPictFormat * +XRenderFindVisualFormat (Display *dpy, _Xconst Visual *visual); + +XRenderPictFormat * +XRenderFindFormat (Display *dpy, + unsigned long mask, + _Xconst XRenderPictFormat *templ, + int count); + +#define PictStandardARGB32 0 +#define PictStandardRGB24 1 +#define PictStandardA8 2 +#define PictStandardA4 3 +#define PictStandardA1 4 +#define PictStandardNUM 5 + +XRenderPictFormat * +XRenderFindStandardFormat (Display *dpy, + int format); + +XIndexValue * +XRenderQueryPictIndexValues(Display *dpy, + _Xconst XRenderPictFormat *format, + int *num); + +Picture +XRenderCreatePicture (Display *dpy, + Drawable drawable, + _Xconst XRenderPictFormat *format, + unsigned long valuemask, + _Xconst XRenderPictureAttributes *attributes); + +void +XRenderChangePicture (Display *dpy, + Picture picture, + unsigned long valuemask, + _Xconst XRenderPictureAttributes *attributes); + +void +XRenderSetPictureClipRectangles (Display *dpy, + Picture picture, + int xOrigin, + int yOrigin, + _Xconst XRectangle *rects, + int n); + +void +XRenderSetPictureClipRegion (Display *dpy, + Picture picture, + Region r); + +void +XRenderSetPictureTransform (Display *dpy, + Picture picture, + XTransform *transform); + +void +XRenderFreePicture (Display *dpy, + Picture picture); + +void +XRenderComposite (Display *dpy, + int op, + Picture src, + Picture mask, + Picture dst, + int src_x, + int src_y, + int mask_x, + int mask_y, + int dst_x, + int dst_y, + unsigned int width, + unsigned int height); + +GlyphSet +XRenderCreateGlyphSet (Display *dpy, _Xconst XRenderPictFormat *format); + +GlyphSet +XRenderReferenceGlyphSet (Display *dpy, GlyphSet existing); + +void +XRenderFreeGlyphSet (Display *dpy, GlyphSet glyphset); + +void +XRenderAddGlyphs (Display *dpy, + GlyphSet glyphset, + _Xconst Glyph *gids, + _Xconst XGlyphInfo *glyphs, + int nglyphs, + _Xconst char *images, + int nbyte_images); + +void +XRenderFreeGlyphs (Display *dpy, + GlyphSet glyphset, + _Xconst Glyph *gids, + int nglyphs); + +void +XRenderCompositeString8 (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + GlyphSet glyphset, + int xSrc, + int ySrc, + int xDst, + int yDst, + _Xconst char *string, + int nchar); + +void +XRenderCompositeString16 (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + GlyphSet glyphset, + int xSrc, + int ySrc, + int xDst, + int yDst, + _Xconst unsigned short *string, + int nchar); + +void +XRenderCompositeString32 (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + GlyphSet glyphset, + int xSrc, + int ySrc, + int xDst, + int yDst, + _Xconst unsigned int *string, + int nchar); + +void +XRenderCompositeText8 (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + int xSrc, + int ySrc, + int xDst, + int yDst, + _Xconst XGlyphElt8 *elts, + int nelt); + +void +XRenderCompositeText16 (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + int xSrc, + int ySrc, + int xDst, + int yDst, + _Xconst XGlyphElt16 *elts, + int nelt); + +void +XRenderCompositeText32 (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + int xSrc, + int ySrc, + int xDst, + int yDst, + _Xconst XGlyphElt32 *elts, + int nelt); + +void +XRenderFillRectangle (Display *dpy, + int op, + Picture dst, + _Xconst XRenderColor *color, + int x, + int y, + unsigned int width, + unsigned int height); + +void +XRenderFillRectangles (Display *dpy, + int op, + Picture dst, + _Xconst XRenderColor *color, + _Xconst XRectangle *rectangles, + int n_rects); + +void +XRenderCompositeTrapezoids (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + int xSrc, + int ySrc, + _Xconst XTrapezoid *traps, + int ntrap); + +void +XRenderCompositeTriangles (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + int xSrc, + int ySrc, + _Xconst XTriangle *triangles, + int ntriangle); + +void +XRenderCompositeTriStrip (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + int xSrc, + int ySrc, + _Xconst XPointFixed *points, + int npoint); + +void +XRenderCompositeTriFan (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + int xSrc, + int ySrc, + _Xconst XPointFixed *points, + int npoint); + +void +XRenderCompositeDoublePoly (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + int xSrc, + int ySrc, + int xDst, + int yDst, + _Xconst XPointDouble *fpoints, + int npoints, + int winding); +Status +XRenderParseColor(Display *dpy, + char *spec, + XRenderColor *def); + +Cursor +XRenderCreateCursor (Display *dpy, + Picture source, + unsigned int x, + unsigned int y); + +XFilters * +XRenderQueryFilters (Display *dpy, Drawable drawable); + +void +XRenderSetPictureFilter (Display *dpy, + Picture picture, + const char *filter, + XFixed *params, + int nparams); + +Cursor +XRenderCreateAnimCursor (Display *dpy, + int ncursor, + XAnimCursor *cursors); + + +void +XRenderAddTraps (Display *dpy, + Picture picture, + int xOff, + int yOff, + _Xconst XTrap *traps, + int ntrap); + +Picture XRenderCreateSolidFill (Display *dpy, + const XRenderColor *color); + +Picture XRenderCreateLinearGradient (Display *dpy, + const XLinearGradient *gradient, + const XFixed *stops, + const XRenderColor *colors, + int nstops); + +Picture XRenderCreateRadialGradient (Display *dpy, + const XRadialGradient *gradient, + const XFixed *stops, + const XRenderColor *colors, + int nstops); + +Picture XRenderCreateConicalGradient (Display *dpy, + const XConicalGradient *gradient, + const XFixed *stops, + const XRenderColor *colors, + int nstops); + +_XFUNCPROTOEND + +#endif /* _XRENDER_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/extensions/randr.h b/thirdparty/linuxbsd_headers/X11/extensions/randr.h new file mode 100644 index 0000000000..e7caab1725 --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/extensions/randr.h @@ -0,0 +1,208 @@ +/* + * Copyright © 2000 Compaq Computer Corporation + * Copyright © 2002 Hewlett Packard Company + * Copyright © 2006 Intel Corporation + * Copyright © 2008 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + * + * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc. + * Keith Packard, Intel Corporation + */ + +#ifndef _RANDR_H_ +#define _RANDR_H_ + +typedef unsigned short Rotation; +typedef unsigned short SizeID; +typedef unsigned short SubpixelOrder; +typedef unsigned short Connection; +typedef unsigned short XRandrRotation; +typedef unsigned short XRandrSizeID; +typedef unsigned short XRandrSubpixelOrder; +typedef unsigned long XRandrModeFlags; + +#define RANDR_NAME "RANDR" +#define RANDR_MAJOR 1 +#define RANDR_MINOR 6 + +#define RRNumberErrors 5 +#define RRNumberEvents 2 +#define RRNumberRequests 47 + +#define X_RRQueryVersion 0 +/* we skip 1 to make old clients fail pretty immediately */ +#define X_RROldGetScreenInfo 1 +#define X_RR1_0SetScreenConfig 2 +/* V1.0 apps share the same set screen config request id */ +#define X_RRSetScreenConfig 2 +#define X_RROldScreenChangeSelectInput 3 +/* 3 used to be ScreenChangeSelectInput; deprecated */ +#define X_RRSelectInput 4 +#define X_RRGetScreenInfo 5 + +/* V1.2 additions */ +#define X_RRGetScreenSizeRange 6 +#define X_RRSetScreenSize 7 +#define X_RRGetScreenResources 8 +#define X_RRGetOutputInfo 9 +#define X_RRListOutputProperties 10 +#define X_RRQueryOutputProperty 11 +#define X_RRConfigureOutputProperty 12 +#define X_RRChangeOutputProperty 13 +#define X_RRDeleteOutputProperty 14 +#define X_RRGetOutputProperty 15 +#define X_RRCreateMode 16 +#define X_RRDestroyMode 17 +#define X_RRAddOutputMode 18 +#define X_RRDeleteOutputMode 19 +#define X_RRGetCrtcInfo 20 +#define X_RRSetCrtcConfig 21 +#define X_RRGetCrtcGammaSize 22 +#define X_RRGetCrtcGamma 23 +#define X_RRSetCrtcGamma 24 + +/* V1.3 additions */ +#define X_RRGetScreenResourcesCurrent 25 +#define X_RRSetCrtcTransform 26 +#define X_RRGetCrtcTransform 27 +#define X_RRGetPanning 28 +#define X_RRSetPanning 29 +#define X_RRSetOutputPrimary 30 +#define X_RRGetOutputPrimary 31 + +#define RRTransformUnit (1L << 0) +#define RRTransformScaleUp (1L << 1) +#define RRTransformScaleDown (1L << 2) +#define RRTransformProjective (1L << 3) + +/* v1.4 */ +#define X_RRGetProviders 32 +#define X_RRGetProviderInfo 33 +#define X_RRSetProviderOffloadSink 34 +#define X_RRSetProviderOutputSource 35 +#define X_RRListProviderProperties 36 +#define X_RRQueryProviderProperty 37 +#define X_RRConfigureProviderProperty 38 +#define X_RRChangeProviderProperty 39 +#define X_RRDeleteProviderProperty 40 +#define X_RRGetProviderProperty 41 + +/* v1.5 */ +#define X_RRGetMonitors 42 +#define X_RRSetMonitor 43 +#define X_RRDeleteMonitor 44 + +/* v1.6 */ +#define X_RRCreateLease 45 +#define X_RRFreeLease 46 + +/* Event selection bits */ +#define RRScreenChangeNotifyMask (1L << 0) +/* V1.2 additions */ +#define RRCrtcChangeNotifyMask (1L << 1) +#define RROutputChangeNotifyMask (1L << 2) +#define RROutputPropertyNotifyMask (1L << 3) +/* V1.4 additions */ +#define RRProviderChangeNotifyMask (1L << 4) +#define RRProviderPropertyNotifyMask (1L << 5) +#define RRResourceChangeNotifyMask (1L << 6) +/* V1.6 additions */ +#define RRLeaseNotifyMask (1L << 7) + +/* Event codes */ +#define RRScreenChangeNotify 0 +/* V1.2 additions */ +#define RRNotify 1 +/* RRNotify Subcodes */ +#define RRNotify_CrtcChange 0 +#define RRNotify_OutputChange 1 +#define RRNotify_OutputProperty 2 +#define RRNotify_ProviderChange 3 +#define RRNotify_ProviderProperty 4 +#define RRNotify_ResourceChange 5 +/* V1.6 additions */ +#define RRNotify_Lease 6 +/* used in the rotation field; rotation and reflection in 0.1 proto. */ +#define RR_Rotate_0 1 +#define RR_Rotate_90 2 +#define RR_Rotate_180 4 +#define RR_Rotate_270 8 + +/* new in 1.0 protocol, to allow reflection of screen */ + +#define RR_Reflect_X 16 +#define RR_Reflect_Y 32 + +#define RRSetConfigSuccess 0 +#define RRSetConfigInvalidConfigTime 1 +#define RRSetConfigInvalidTime 2 +#define RRSetConfigFailed 3 + +/* new in 1.2 protocol */ + +#define RR_HSyncPositive 0x00000001 +#define RR_HSyncNegative 0x00000002 +#define RR_VSyncPositive 0x00000004 +#define RR_VSyncNegative 0x00000008 +#define RR_Interlace 0x00000010 +#define RR_DoubleScan 0x00000020 +#define RR_CSync 0x00000040 +#define RR_CSyncPositive 0x00000080 +#define RR_CSyncNegative 0x00000100 +#define RR_HSkewPresent 0x00000200 +#define RR_BCast 0x00000400 +#define RR_PixelMultiplex 0x00000800 +#define RR_DoubleClock 0x00001000 +#define RR_ClockDivideBy2 0x00002000 + +#define RR_Connected 0 +#define RR_Disconnected 1 +#define RR_UnknownConnection 2 + +#define BadRROutput 0 +#define BadRRCrtc 1 +#define BadRRMode 2 +#define BadRRProvider 3 +#define BadRRLease 4 + +/* Conventional RandR output properties */ + +#define RR_PROPERTY_BACKLIGHT "Backlight" +#define RR_PROPERTY_RANDR_EDID "EDID" +#define RR_PROPERTY_SIGNAL_FORMAT "SignalFormat" +#define RR_PROPERTY_SIGNAL_PROPERTIES "SignalProperties" +#define RR_PROPERTY_CONNECTOR_TYPE "ConnectorType" +#define RR_PROPERTY_CONNECTOR_NUMBER "ConnectorNumber" +#define RR_PROPERTY_COMPATIBILITY_LIST "CompatibilityList" +#define RR_PROPERTY_CLONE_LIST "CloneList" +#define RR_PROPERTY_BORDER "Border" +#define RR_PROPERTY_BORDER_DIMENSIONS "BorderDimensions" +#define RR_PROPERTY_GUID "GUID" +#define RR_PROPERTY_RANDR_TILE "TILE" +#define RR_PROPERTY_NON_DESKTOP "non-desktop" + +/* roles this device can carry out */ +#define RR_Capability_None 0 +#define RR_Capability_SourceOutput 1 +#define RR_Capability_SinkOutput 2 +#define RR_Capability_SourceOffload 4 +#define RR_Capability_SinkOffload 8 + +#endif /* _RANDR_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/extensions/randrproto.h b/thirdparty/linuxbsd_headers/X11/extensions/randrproto.h new file mode 100644 index 0000000000..624c2544c9 --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/extensions/randrproto.h @@ -0,0 +1,1152 @@ +/* + * Copyright © 2000 Compaq Computer Corporation + * Copyright © 2002 Hewlett-Packard Company + * Copyright © 2006 Intel Corporation + * Copyright © 2008 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + * + * Author: Jim Gettys, Hewlett-Packard Company, Inc. + * Keith Packard, Intel Corporation + */ + +/* note that RANDR 1.0 is incompatible with version 0.0, or 0.1 */ +/* V1.0 removes depth switching from the protocol */ +#ifndef _XRANDRP_H_ +#define _XRANDRP_H_ + +#include <X11/extensions/randr.h> +#include <X11/extensions/renderproto.h> + +#define Window CARD32 +#define Drawable CARD32 +#define Font CARD32 +#define Pixmap CARD32 +#define Cursor CARD32 +#define Colormap CARD32 +#define GContext CARD32 +#define Atom CARD32 +#define Time CARD32 +#define KeyCode CARD8 +#define KeySym CARD32 +#define RROutput CARD32 +#define RRMode CARD32 +#define RRCrtc CARD32 +#define RRProvider CARD32 +#define RRModeFlags CARD32 +#define RRLease CARD32 + +#define Rotation CARD16 +#define SizeID CARD16 +#define SubpixelOrder CARD16 + +/* + * data structures + */ + +typedef struct { + CARD16 widthInPixels; + CARD16 heightInPixels; + CARD16 widthInMillimeters; + CARD16 heightInMillimeters; +} xScreenSizes; +#define sz_xScreenSizes 8 + +/* + * requests and replies + */ + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + CARD32 majorVersion; + CARD32 minorVersion; +} xRRQueryVersionReq; +#define sz_xRRQueryVersionReq 12 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber; + CARD32 length; + CARD32 majorVersion; + CARD32 minorVersion; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; +} xRRQueryVersionReply; +#define sz_xRRQueryVersionReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + Window window; +} xRRGetScreenInfoReq; +#define sz_xRRGetScreenInfoReq 8 + +/* + * the xRRScreenInfoReply structure is followed by: + * + * the size information + */ + + +typedef struct { + BYTE type; /* X_Reply */ + BYTE setOfRotations; + CARD16 sequenceNumber; + CARD32 length; + Window root; + Time timestamp; + Time configTimestamp; + CARD16 nSizes; + SizeID sizeID; + Rotation rotation; + CARD16 rate; + CARD16 nrateEnts; + CARD16 pad; +} xRRGetScreenInfoReply; +#define sz_xRRGetScreenInfoReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + Drawable drawable; + Time timestamp; + Time configTimestamp; + SizeID sizeID; + Rotation rotation; +} xRR1_0SetScreenConfigReq; +#define sz_xRR1_0SetScreenConfigReq 20 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + Drawable drawable; + Time timestamp; + Time configTimestamp; + SizeID sizeID; + Rotation rotation; + CARD16 rate; + CARD16 pad; +} xRRSetScreenConfigReq; +#define sz_xRRSetScreenConfigReq 24 + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 status; + CARD16 sequenceNumber; + CARD32 length; + Time newTimestamp; + Time newConfigTimestamp; + Window root; + CARD16 subpixelOrder; + CARD16 pad4; + CARD32 pad5; + CARD32 pad6; +} xRRSetScreenConfigReply; +#define sz_xRRSetScreenConfigReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + Window window; + CARD16 enable; + CARD16 pad2; +} xRRSelectInputReq; +#define sz_xRRSelectInputReq 12 + +/* + * Additions for version 1.2 + */ + +typedef struct _xRRModeInfo { + RRMode id; + CARD16 width; + CARD16 height; + CARD32 dotClock; + CARD16 hSyncStart; + CARD16 hSyncEnd; + CARD16 hTotal; + CARD16 hSkew; + CARD16 vSyncStart; + CARD16 vSyncEnd; + CARD16 vTotal; + CARD16 nameLength; + RRModeFlags modeFlags; +} xRRModeInfo; +#define sz_xRRModeInfo 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + Window window; +} xRRGetScreenSizeRangeReq; +#define sz_xRRGetScreenSizeRangeReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 pad; + CARD16 sequenceNumber; + CARD32 length; + CARD16 minWidth; + CARD16 minHeight; + CARD16 maxWidth; + CARD16 maxHeight; + CARD32 pad0; + CARD32 pad1; + CARD32 pad2; + CARD32 pad3; +} xRRGetScreenSizeRangeReply; +#define sz_xRRGetScreenSizeRangeReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + Window window; + CARD16 width; + CARD16 height; + CARD32 widthInMillimeters; + CARD32 heightInMillimeters; +} xRRSetScreenSizeReq; +#define sz_xRRSetScreenSizeReq 20 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + Window window; +} xRRGetScreenResourcesReq; +#define sz_xRRGetScreenResourcesReq 8 + +typedef struct { + BYTE type; + CARD8 pad; + CARD16 sequenceNumber; + CARD32 length; + Time timestamp; + Time configTimestamp; + CARD16 nCrtcs; + CARD16 nOutputs; + CARD16 nModes; + CARD16 nbytesNames; + CARD32 pad1; + CARD32 pad2; +} xRRGetScreenResourcesReply; +#define sz_xRRGetScreenResourcesReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RROutput output; + Time configTimestamp; +} xRRGetOutputInfoReq; +#define sz_xRRGetOutputInfoReq 12 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber; + CARD32 length; + Time timestamp; + RRCrtc crtc; + CARD32 mmWidth; + CARD32 mmHeight; + CARD8 connection; + CARD8 subpixelOrder; + CARD16 nCrtcs; + CARD16 nModes; + CARD16 nPreferred; + CARD16 nClones; + CARD16 nameLength; +} xRRGetOutputInfoReply; +#define sz_xRRGetOutputInfoReply 36 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RROutput output; +} xRRListOutputPropertiesReq; +#define sz_xRRListOutputPropertiesReq 8 + +typedef struct { + BYTE type; + CARD8 pad0; + CARD16 sequenceNumber; + CARD32 length; + CARD16 nAtoms; + CARD16 pad1; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; + CARD32 pad6; +} xRRListOutputPropertiesReply; +#define sz_xRRListOutputPropertiesReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RROutput output; + Atom property; +} xRRQueryOutputPropertyReq; +#define sz_xRRQueryOutputPropertyReq 12 + +typedef struct { + BYTE type; + BYTE pad0; + CARD16 sequenceNumber; + CARD32 length; + BOOL pending; + BOOL range; + BOOL immutable; + BYTE pad1; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; + CARD32 pad6; +} xRRQueryOutputPropertyReply; +#define sz_xRRQueryOutputPropertyReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RROutput output; + Atom property; + BOOL pending; + BOOL range; + CARD16 pad; +} xRRConfigureOutputPropertyReq; +#define sz_xRRConfigureOutputPropertyReq 16 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RROutput output; + Atom property; + Atom type; + CARD8 format; + CARD8 mode; + CARD16 pad; + CARD32 nUnits; +} xRRChangeOutputPropertyReq; +#define sz_xRRChangeOutputPropertyReq 24 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RROutput output; + Atom property; +} xRRDeleteOutputPropertyReq; +#define sz_xRRDeleteOutputPropertyReq 12 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RROutput output; + Atom property; + Atom type; + CARD32 longOffset; + CARD32 longLength; +#ifdef __cplusplus + BOOL _delete; +#else + BOOL delete; +#endif + BOOL pending; + CARD16 pad1; +} xRRGetOutputPropertyReq; +#define sz_xRRGetOutputPropertyReq 28 + +typedef struct { + BYTE type; + CARD8 format; + CARD16 sequenceNumber; + CARD32 length; + Atom propertyType; + CARD32 bytesAfter; + CARD32 nItems; + CARD32 pad1; + CARD32 pad2; + CARD32 pad3; +} xRRGetOutputPropertyReply; +#define sz_xRRGetOutputPropertyReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + Window window; + xRRModeInfo modeInfo; +} xRRCreateModeReq; +#define sz_xRRCreateModeReq 40 + +typedef struct { + BYTE type; + CARD8 pad0; + CARD16 sequenceNumber; + CARD32 length; + RRMode mode; + CARD32 pad1; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; +} xRRCreateModeReply; +#define sz_xRRCreateModeReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRMode mode; +} xRRDestroyModeReq; +#define sz_xRRDestroyModeReq 8 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RROutput output; + RRMode mode; +} xRRAddOutputModeReq; +#define sz_xRRAddOutputModeReq 12 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RROutput output; + RRMode mode; +} xRRDeleteOutputModeReq; +#define sz_xRRDeleteOutputModeReq 12 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRCrtc crtc; + Time configTimestamp; +} xRRGetCrtcInfoReq; +#define sz_xRRGetCrtcInfoReq 12 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber; + CARD32 length; + Time timestamp; + INT16 x; + INT16 y; + CARD16 width; + CARD16 height; + RRMode mode; + Rotation rotation; + Rotation rotations; + CARD16 nOutput; + CARD16 nPossibleOutput; +} xRRGetCrtcInfoReply; +#define sz_xRRGetCrtcInfoReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRCrtc crtc; + Time timestamp; + Time configTimestamp; + INT16 x; + INT16 y; + RRMode mode; + Rotation rotation; + CARD16 pad; +} xRRSetCrtcConfigReq; +#define sz_xRRSetCrtcConfigReq 28 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber; + CARD32 length; + Time newTimestamp; + CARD32 pad1; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; +} xRRSetCrtcConfigReply; +#define sz_xRRSetCrtcConfigReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRCrtc crtc; +} xRRGetCrtcGammaSizeReq; +#define sz_xRRGetCrtcGammaSizeReq 8 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber; + CARD32 length; + CARD16 size; + CARD16 pad1; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; + CARD32 pad6; +} xRRGetCrtcGammaSizeReply; +#define sz_xRRGetCrtcGammaSizeReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRCrtc crtc; +} xRRGetCrtcGammaReq; +#define sz_xRRGetCrtcGammaReq 8 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber; + CARD32 length; + CARD16 size; + CARD16 pad1; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; + CARD32 pad6; +} xRRGetCrtcGammaReply; +#define sz_xRRGetCrtcGammaReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRCrtc crtc; + CARD16 size; + CARD16 pad1; +} xRRSetCrtcGammaReq; +#define sz_xRRSetCrtcGammaReq 12 + +/* + * Additions for V1.3 + */ + +typedef xRRGetScreenResourcesReq xRRGetScreenResourcesCurrentReq; + +#define sz_xRRGetScreenResourcesCurrentReq sz_xRRGetScreenResourcesReq + +typedef xRRGetScreenResourcesReply xRRGetScreenResourcesCurrentReply; +#define sz_xRRGetScreenResourcesCurrentReply sz_xRRGetScreenResourcesReply + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRCrtc crtc; + xRenderTransform transform; + CARD16 nbytesFilter; /* number of bytes in filter name */ + CARD16 pad; +} xRRSetCrtcTransformReq; + +#define sz_xRRSetCrtcTransformReq 48 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRCrtc crtc; +} xRRGetCrtcTransformReq; + +#define sz_xRRGetCrtcTransformReq 8 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber; + CARD32 length; + xRenderTransform pendingTransform; + BYTE hasTransforms; + CARD8 pad0; + CARD16 pad1; + xRenderTransform currentTransform; + CARD32 pad2; + CARD16 pendingNbytesFilter; /* number of bytes in filter name */ + CARD16 pendingNparamsFilter; /* number of filter params */ + CARD16 currentNbytesFilter; /* number of bytes in filter name */ + CARD16 currentNparamsFilter; /* number of filter params */ +} xRRGetCrtcTransformReply; + +#define sz_xRRGetCrtcTransformReply 96 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + Window window; + RROutput output; +} xRRSetOutputPrimaryReq; +#define sz_xRRSetOutputPrimaryReq 12 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + Window window; +} xRRGetOutputPrimaryReq; +#define sz_xRRGetOutputPrimaryReq 8 + +typedef struct { + BYTE type; + CARD8 pad; + CARD16 sequenceNumber; + CARD32 length; + RROutput output; + CARD32 pad1; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; +} xRRGetOutputPrimaryReply; +#define sz_xRRGetOutputPrimaryReply 32 + +/* + * Additions for V1.4 + */ + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + Window window; +} xRRGetProvidersReq; +#define sz_xRRGetProvidersReq 8 + +typedef struct { + BYTE type; + CARD8 pad; + CARD16 sequenceNumber; + CARD32 length; + Time timestamp; + CARD16 nProviders; + CARD16 pad1; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; +} xRRGetProvidersReply; +#define sz_xRRGetProvidersReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRProvider provider; + Time configTimestamp; +} xRRGetProviderInfoReq; +#define sz_xRRGetProviderInfoReq 12 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber; + CARD32 length; + Time timestamp; + CARD32 capabilities; + CARD16 nCrtcs; + CARD16 nOutputs; + CARD16 nAssociatedProviders; + CARD16 nameLength; + CARD32 pad1; + CARD32 pad2; +} xRRGetProviderInfoReply; +#define sz_xRRGetProviderInfoReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRProvider provider; + RRProvider source_provider; + Time configTimestamp; +} xRRSetProviderOutputSourceReq; +#define sz_xRRSetProviderOutputSourceReq 16 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRProvider provider; + RRProvider sink_provider; + Time configTimestamp; +} xRRSetProviderOffloadSinkReq; +#define sz_xRRSetProviderOffloadSinkReq 16 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRProvider provider; +} xRRListProviderPropertiesReq; +#define sz_xRRListProviderPropertiesReq 8 + +typedef struct { + BYTE type; + CARD8 pad0; + CARD16 sequenceNumber; + CARD32 length; + CARD16 nAtoms; + CARD16 pad1; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; + CARD32 pad6; +} xRRListProviderPropertiesReply; +#define sz_xRRListProviderPropertiesReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRProvider provider; + Atom property; +} xRRQueryProviderPropertyReq; +#define sz_xRRQueryProviderPropertyReq 12 + +typedef struct { + BYTE type; + BYTE pad0; + CARD16 sequenceNumber; + CARD32 length; + BOOL pending; + BOOL range; + BOOL immutable; + BYTE pad1; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; + CARD32 pad6; +} xRRQueryProviderPropertyReply; +#define sz_xRRQueryProviderPropertyReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRProvider provider; + Atom property; + BOOL pending; + BOOL range; + CARD16 pad; +} xRRConfigureProviderPropertyReq; +#define sz_xRRConfigureProviderPropertyReq 16 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRProvider provider; + Atom property; + Atom type; + CARD8 format; + CARD8 mode; + CARD16 pad; + CARD32 nUnits; +} xRRChangeProviderPropertyReq; +#define sz_xRRChangeProviderPropertyReq 24 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRProvider provider; + Atom property; +} xRRDeleteProviderPropertyReq; +#define sz_xRRDeleteProviderPropertyReq 12 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRProvider provider; + Atom property; + Atom type; + CARD32 longOffset; + CARD32 longLength; +#ifdef __cplusplus + BOOL _delete; +#else + BOOL delete; +#endif + BOOL pending; + CARD16 pad1; +} xRRGetProviderPropertyReq; +#define sz_xRRGetProviderPropertyReq 28 + +typedef struct { + BYTE type; + CARD8 format; + CARD16 sequenceNumber; + CARD32 length; + Atom propertyType; + CARD32 bytesAfter; + CARD32 nItems; + CARD32 pad1; + CARD32 pad2; + CARD32 pad3; +} xRRGetProviderPropertyReply; +#define sz_xRRGetProviderPropertyReply 32 + +/* + * Additions for V1.6 + */ + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + Window window; + RRLease lid; + CARD16 nCrtcs; + CARD16 nOutputs; +} xRRCreateLeaseReq; +#define sz_xRRCreateLeaseReq 16 + +typedef struct { + BYTE type; + CARD8 nfd; + CARD16 sequenceNumber; + CARD32 length; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; + CARD32 pad6; + CARD32 pad7; +} xRRCreateLeaseReply; +#define sz_xRRCreateLeaseReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRLease lid; + BYTE terminate; + CARD8 pad1; + CARD16 pad2; +} xRRFreeLeaseReq; +#define sz_xRRFreeLeaseReq 12 + +/* + * event + */ +typedef struct { + CARD8 type; /* always evBase + ScreenChangeNotify */ + CARD8 rotation; /* new rotation */ + CARD16 sequenceNumber; + Time timestamp; /* time screen was changed */ + Time configTimestamp; /* time config data was changed */ + Window root; /* root window */ + Window window; /* window requesting notification */ + SizeID sizeID; /* new size ID */ + CARD16 subpixelOrder; /* subpixel order */ + CARD16 widthInPixels; /* new size */ + CARD16 heightInPixels; + CARD16 widthInMillimeters; + CARD16 heightInMillimeters; +} xRRScreenChangeNotifyEvent; +#define sz_xRRScreenChangeNotifyEvent 32 + +typedef struct { + CARD8 type; /* always evBase + RRNotify */ + CARD8 subCode; /* RRNotify_CrtcChange */ + CARD16 sequenceNumber; + Time timestamp; /* time crtc was changed */ + Window window; /* window requesting notification */ + RRCrtc crtc; /* affected CRTC */ + RRMode mode; /* current mode */ + CARD16 rotation; /* rotation and reflection */ + CARD16 pad1; /* unused */ + INT16 x; /* new location */ + INT16 y; + CARD16 width; /* new size */ + CARD16 height; +} xRRCrtcChangeNotifyEvent; +#define sz_xRRCrtcChangeNotifyEvent 32 + +typedef struct { + CARD8 type; /* always evBase + RRNotify */ + CARD8 subCode; /* RRNotify_OutputChange */ + CARD16 sequenceNumber; + Time timestamp; /* time output was changed */ + Time configTimestamp; /* time config was changed */ + Window window; /* window requesting notification */ + RROutput output; /* affected output */ + RRCrtc crtc; /* current crtc */ + RRMode mode; /* current mode */ + CARD16 rotation; /* rotation and reflection */ + CARD8 connection; /* connection status */ + CARD8 subpixelOrder; /* subpixel order */ +} xRROutputChangeNotifyEvent; +#define sz_xRROutputChangeNotifyEvent 32 + +typedef struct { + CARD8 type; /* always evBase + RRNotify */ + CARD8 subCode; /* RRNotify_OutputProperty */ + CARD16 sequenceNumber; + Window window; /* window requesting notification */ + RROutput output; /* affected output */ + Atom atom; /* property name */ + Time timestamp; /* time crtc was changed */ + CARD8 state; /* NewValue or Deleted */ + CARD8 pad1; + CARD16 pad2; + CARD32 pad3; + CARD32 pad4; +} xRROutputPropertyNotifyEvent; +#define sz_xRROutputPropertyNotifyEvent 32 + +typedef struct { + CARD8 type; /* always evBase + RRNotify */ + CARD8 subCode; /* RRNotify_ProviderChange */ + CARD16 sequenceNumber; + Time timestamp; /* time provider was changed */ + Window window; /* window requesting notification */ + RRProvider provider; /* affected provider */ + CARD32 pad1; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; +} xRRProviderChangeNotifyEvent; +#define sz_xRRProviderChangeNotifyEvent 32 + +typedef struct { + CARD8 type; /* always evBase + RRNotify */ + CARD8 subCode; /* RRNotify_ProviderProperty */ + CARD16 sequenceNumber; + Window window; /* window requesting notification */ + RRProvider provider; /* affected provider */ + Atom atom; /* property name */ + Time timestamp; /* time provider was changed */ + CARD8 state; /* NewValue or Deleted */ + CARD8 pad1; + CARD16 pad2; + CARD32 pad3; + CARD32 pad4; +} xRRProviderPropertyNotifyEvent; +#define sz_xRRProviderPropertyNotifyEvent 32 + +typedef struct { + CARD8 type; /* always evBase + RRNotify */ + CARD8 subCode; /* RRNotify_ResourceChange */ + CARD16 sequenceNumber; + Time timestamp; /* time resource was changed */ + Window window; /* window requesting notification */ + CARD32 pad1; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; +} xRRResourceChangeNotifyEvent; +#define sz_xRRResourceChangeNotifyEvent 32 + +typedef struct { + CARD8 type; /* always evBase + RRNotify */ + CARD8 subCode; /* RRNotify_Lease */ + CARD16 sequenceNumber; + Time timestamp; /* time resource was changed */ + Window window; /* window requesting notification */ + RRLease lease; + CARD8 created; /* created/deleted */ + CARD8 pad0; + CARD16 pad1; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; +} xRRLeaseNotifyEvent; +#define sz_xRRLeaseNotifyEvent 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRCrtc crtc; +} xRRGetPanningReq; +#define sz_xRRGetPanningReq 8 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber; + CARD32 length; + Time timestamp; + CARD16 left; + CARD16 top; + CARD16 width; + CARD16 height; + CARD16 track_left; + CARD16 track_top; + CARD16 track_width; + CARD16 track_height; + INT16 border_left; + INT16 border_top; + INT16 border_right; + INT16 border_bottom; +} xRRGetPanningReply; +#define sz_xRRGetPanningReply 36 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + RRCrtc crtc; + Time timestamp; + CARD16 left; + CARD16 top; + CARD16 width; + CARD16 height; + CARD16 track_left; + CARD16 track_top; + CARD16 track_width; + CARD16 track_height; + INT16 border_left; + INT16 border_top; + INT16 border_right; + INT16 border_bottom; +} xRRSetPanningReq; +#define sz_xRRSetPanningReq 36 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber; + CARD32 length; + Time newTimestamp; + CARD32 pad1; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; +} xRRSetPanningReply; +#define sz_xRRSetPanningReply 32 + +typedef struct { + Atom name; + BOOL primary; + BOOL automatic; + CARD16 noutput; + INT16 x; + INT16 y; + CARD16 width; + CARD16 height; + CARD32 widthInMillimeters; + CARD32 heightInMillimeters; +} xRRMonitorInfo; +#define sz_xRRMonitorInfo 24 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + Window window; + BOOL get_active; + CARD8 pad; + CARD16 pad2; +} xRRGetMonitorsReq; +#define sz_xRRGetMonitorsReq 12 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber; + CARD32 length; + Time timestamp; + CARD32 nmonitors; + CARD32 noutputs; + CARD32 pad1; + CARD32 pad2; + CARD32 pad3; +} xRRGetMonitorsReply; +#define sz_xRRGetMonitorsReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + Window window; + xRRMonitorInfo monitor; +} xRRSetMonitorReq; +#define sz_xRRSetMonitorReq 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length; + Window window; + Atom name; +} xRRDeleteMonitorReq; +#define sz_xRRDeleteMonitorReq 12 + +#undef RRLease +#undef RRModeFlags +#undef RRCrtc +#undef RRMode +#undef RROutput +#undef RRMode +#undef RRCrtc +#undef RRProvider +#undef Drawable +#undef Window +#undef Font +#undef Pixmap +#undef Cursor +#undef Colormap +#undef GContext +#undef Atom +#undef Time +#undef KeyCode +#undef KeySym +#undef Rotation +#undef SizeID +#undef SubpixelOrder + +#endif /* _XRANDRP_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/extensions/render.h b/thirdparty/linuxbsd_headers/X11/extensions/render.h new file mode 100644 index 0000000000..7ecde3f59e --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/extensions/render.h @@ -0,0 +1,210 @@ +/* + * Copyright © 2000 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#ifndef _RENDER_H_ +#define _RENDER_H_ + +#include <X11/Xdefs.h> + +typedef XID Glyph; +typedef XID GlyphSet; +typedef XID Picture; +typedef XID PictFormat; + +#define RENDER_NAME "RENDER" +#define RENDER_MAJOR 0 +#define RENDER_MINOR 11 + +#define X_RenderQueryVersion 0 +#define X_RenderQueryPictFormats 1 +#define X_RenderQueryPictIndexValues 2 /* 0.7 */ +#define X_RenderQueryDithers 3 +#define X_RenderCreatePicture 4 +#define X_RenderChangePicture 5 +#define X_RenderSetPictureClipRectangles 6 +#define X_RenderFreePicture 7 +#define X_RenderComposite 8 +#define X_RenderScale 9 +#define X_RenderTrapezoids 10 +#define X_RenderTriangles 11 +#define X_RenderTriStrip 12 +#define X_RenderTriFan 13 +#define X_RenderColorTrapezoids 14 +#define X_RenderColorTriangles 15 +/* #define X_RenderTransform 16 */ +#define X_RenderCreateGlyphSet 17 +#define X_RenderReferenceGlyphSet 18 +#define X_RenderFreeGlyphSet 19 +#define X_RenderAddGlyphs 20 +#define X_RenderAddGlyphsFromPicture 21 +#define X_RenderFreeGlyphs 22 +#define X_RenderCompositeGlyphs8 23 +#define X_RenderCompositeGlyphs16 24 +#define X_RenderCompositeGlyphs32 25 +#define X_RenderFillRectangles 26 +/* 0.5 */ +#define X_RenderCreateCursor 27 +/* 0.6 */ +#define X_RenderSetPictureTransform 28 +#define X_RenderQueryFilters 29 +#define X_RenderSetPictureFilter 30 +/* 0.8 */ +#define X_RenderCreateAnimCursor 31 +/* 0.9 */ +#define X_RenderAddTraps 32 +/* 0.10 */ +#define X_RenderCreateSolidFill 33 +#define X_RenderCreateLinearGradient 34 +#define X_RenderCreateRadialGradient 35 +#define X_RenderCreateConicalGradient 36 +#define RenderNumberRequests (X_RenderCreateConicalGradient+1) + +#define BadPictFormat 0 +#define BadPicture 1 +#define BadPictOp 2 +#define BadGlyphSet 3 +#define BadGlyph 4 +#define RenderNumberErrors (BadGlyph+1) + +#define PictTypeIndexed 0 +#define PictTypeDirect 1 + +#define PictOpMinimum 0 +#define PictOpClear 0 +#define PictOpSrc 1 +#define PictOpDst 2 +#define PictOpOver 3 +#define PictOpOverReverse 4 +#define PictOpIn 5 +#define PictOpInReverse 6 +#define PictOpOut 7 +#define PictOpOutReverse 8 +#define PictOpAtop 9 +#define PictOpAtopReverse 10 +#define PictOpXor 11 +#define PictOpAdd 12 +#define PictOpSaturate 13 +#define PictOpMaximum 13 + +/* + * Operators only available in version 0.2 + */ +#define PictOpDisjointMinimum 0x10 +#define PictOpDisjointClear 0x10 +#define PictOpDisjointSrc 0x11 +#define PictOpDisjointDst 0x12 +#define PictOpDisjointOver 0x13 +#define PictOpDisjointOverReverse 0x14 +#define PictOpDisjointIn 0x15 +#define PictOpDisjointInReverse 0x16 +#define PictOpDisjointOut 0x17 +#define PictOpDisjointOutReverse 0x18 +#define PictOpDisjointAtop 0x19 +#define PictOpDisjointAtopReverse 0x1a +#define PictOpDisjointXor 0x1b +#define PictOpDisjointMaximum 0x1b + +#define PictOpConjointMinimum 0x20 +#define PictOpConjointClear 0x20 +#define PictOpConjointSrc 0x21 +#define PictOpConjointDst 0x22 +#define PictOpConjointOver 0x23 +#define PictOpConjointOverReverse 0x24 +#define PictOpConjointIn 0x25 +#define PictOpConjointInReverse 0x26 +#define PictOpConjointOut 0x27 +#define PictOpConjointOutReverse 0x28 +#define PictOpConjointAtop 0x29 +#define PictOpConjointAtopReverse 0x2a +#define PictOpConjointXor 0x2b +#define PictOpConjointMaximum 0x2b + +/* + * Operators only available in version 0.11 + */ +#define PictOpBlendMinimum 0x30 +#define PictOpMultiply 0x30 +#define PictOpScreen 0x31 +#define PictOpOverlay 0x32 +#define PictOpDarken 0x33 +#define PictOpLighten 0x34 +#define PictOpColorDodge 0x35 +#define PictOpColorBurn 0x36 +#define PictOpHardLight 0x37 +#define PictOpSoftLight 0x38 +#define PictOpDifference 0x39 +#define PictOpExclusion 0x3a +#define PictOpHSLHue 0x3b +#define PictOpHSLSaturation 0x3c +#define PictOpHSLColor 0x3d +#define PictOpHSLLuminosity 0x3e +#define PictOpBlendMaximum 0x3e + +#define PolyEdgeSharp 0 +#define PolyEdgeSmooth 1 + +#define PolyModePrecise 0 +#define PolyModeImprecise 1 + +#define CPRepeat (1 << 0) +#define CPAlphaMap (1 << 1) +#define CPAlphaXOrigin (1 << 2) +#define CPAlphaYOrigin (1 << 3) +#define CPClipXOrigin (1 << 4) +#define CPClipYOrigin (1 << 5) +#define CPClipMask (1 << 6) +#define CPGraphicsExposure (1 << 7) +#define CPSubwindowMode (1 << 8) +#define CPPolyEdge (1 << 9) +#define CPPolyMode (1 << 10) +#define CPDither (1 << 11) +#define CPComponentAlpha (1 << 12) +#define CPLastBit 12 + +/* Filters included in 0.6 */ +#define FilterNearest "nearest" +#define FilterBilinear "bilinear" +/* Filters included in 0.10 */ +#define FilterConvolution "convolution" + +#define FilterFast "fast" +#define FilterGood "good" +#define FilterBest "best" + +#define FilterAliasNone -1 + +/* Subpixel orders included in 0.6 */ +#define SubPixelUnknown 0 +#define SubPixelHorizontalRGB 1 +#define SubPixelHorizontalBGR 2 +#define SubPixelVerticalRGB 3 +#define SubPixelVerticalBGR 4 +#define SubPixelNone 5 + +/* Extended repeat attributes included in 0.10 */ +#define RepeatNone 0 +#define RepeatNormal 1 +#define RepeatPad 2 +#define RepeatReflect 3 + +#endif /* _RENDER_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/extensions/renderproto.h b/thirdparty/linuxbsd_headers/X11/extensions/renderproto.h new file mode 100644 index 0000000000..2cd06af5d2 --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/extensions/renderproto.h @@ -0,0 +1,661 @@ +/* + * Copyright © 2000 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#ifndef _XRENDERP_H_ +#define _XRENDERP_H_ + +#include <X11/Xmd.h> +#include <X11/extensions/render.h> + +#define Window CARD32 +#define Drawable CARD32 +#define Font CARD32 +#define Pixmap CARD32 +#define Cursor CARD32 +#define Colormap CARD32 +#define GContext CARD32 +#define Atom CARD32 +#define VisualID CARD32 +#define Time CARD32 +#define KeyCode CARD8 +#define KeySym CARD32 + +#define Picture CARD32 +#define PictFormat CARD32 +#define Fixed INT32 +#define Glyphset CARD32 + +/* + * data structures + */ + +typedef struct { + CARD16 red; + CARD16 redMask; + CARD16 green; + CARD16 greenMask; + CARD16 blue; + CARD16 blueMask; + CARD16 alpha; + CARD16 alphaMask; +} xDirectFormat; + +#define sz_xDirectFormat 16 + +typedef struct { + PictFormat id; + CARD8 type; + CARD8 depth; + CARD16 pad1; + xDirectFormat direct; + Colormap colormap; +} xPictFormInfo; + +#define sz_xPictFormInfo 28 + +typedef struct { + VisualID visual; + PictFormat format; +} xPictVisual; + +#define sz_xPictVisual 8 + +typedef struct { + CARD8 depth; + CARD8 pad1; + CARD16 nPictVisuals; + CARD32 pad2; +} xPictDepth; + +#define sz_xPictDepth 8 + +typedef struct { + CARD32 nDepth; + PictFormat fallback; +} xPictScreen; + +#define sz_xPictScreen 8 + +typedef struct { + CARD32 pixel; + CARD16 red; + CARD16 green; + CARD16 blue; + CARD16 alpha; +} xIndexValue; + +#define sz_xIndexValue 12 + +typedef struct { + CARD16 red; + CARD16 green; + CARD16 blue; + CARD16 alpha; +} xRenderColor; + +#define sz_xRenderColor 8 + +typedef struct { + Fixed x; + Fixed y; +} xPointFixed; + +#define sz_xPointFixed 8 + +typedef struct { + xPointFixed p1; + xPointFixed p2; +} xLineFixed; + +#define sz_xLineFixed 16 + +typedef struct { + xPointFixed p1, p2, p3; +} xTriangle; + +#define sz_xTriangle 24 + +typedef struct { + Fixed top; + Fixed bottom; + xLineFixed left; + xLineFixed right; +} xTrapezoid; + +#define sz_xTrapezoid 40 + +typedef struct { + CARD16 width; + CARD16 height; + INT16 x; + INT16 y; + INT16 xOff; + INT16 yOff; +} xGlyphInfo; + +#define sz_xGlyphInfo 12 + +typedef struct { + CARD8 len; + CARD8 pad1; + CARD16 pad2; + INT16 deltax; + INT16 deltay; +} xGlyphElt; + +#define sz_xGlyphElt 8 + +typedef struct { + Fixed l, r, y; +} xSpanFix; + +#define sz_xSpanFix 12 + +typedef struct { + xSpanFix top, bot; +} xTrap; + +#define sz_xTrap 24 + +/* + * requests and replies + */ +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + CARD32 majorVersion; + CARD32 minorVersion; +} xRenderQueryVersionReq; + +#define sz_xRenderQueryVersionReq 12 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber; + CARD32 length; + CARD32 majorVersion; + CARD32 minorVersion; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; +} xRenderQueryVersionReply; + +#define sz_xRenderQueryVersionReply 32 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; +} xRenderQueryPictFormatsReq; + +#define sz_xRenderQueryPictFormatsReq 4 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber; + CARD32 length; + CARD32 numFormats; + CARD32 numScreens; + CARD32 numDepths; + CARD32 numVisuals; + CARD32 numSubpixel; /* Version 0.6 */ + CARD32 pad5; +} xRenderQueryPictFormatsReply; + +#define sz_xRenderQueryPictFormatsReply 32 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + PictFormat format; +} xRenderQueryPictIndexValuesReq; + +#define sz_xRenderQueryPictIndexValuesReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber; + CARD32 length; + CARD32 numIndexValues; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; + CARD32 pad6; +} xRenderQueryPictIndexValuesReply; + +#define sz_xRenderQueryPictIndexValuesReply 32 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Picture pid; + Drawable drawable; + PictFormat format; + CARD32 mask; +} xRenderCreatePictureReq; + +#define sz_xRenderCreatePictureReq 20 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Picture picture; + CARD32 mask; +} xRenderChangePictureReq; + +#define sz_xRenderChangePictureReq 12 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Picture picture; + INT16 xOrigin; + INT16 yOrigin; +} xRenderSetPictureClipRectanglesReq; + +#define sz_xRenderSetPictureClipRectanglesReq 12 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Picture picture; +} xRenderFreePictureReq; + +#define sz_xRenderFreePictureReq 8 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + CARD8 op; + CARD8 pad1; + CARD16 pad2; + Picture src; + Picture mask; + Picture dst; + INT16 xSrc; + INT16 ySrc; + INT16 xMask; + INT16 yMask; + INT16 xDst; + INT16 yDst; + CARD16 width; + CARD16 height; +} xRenderCompositeReq; + +#define sz_xRenderCompositeReq 36 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Picture src; + Picture dst; + CARD32 colorScale; + CARD32 alphaScale; + INT16 xSrc; + INT16 ySrc; + INT16 xDst; + INT16 yDst; + CARD16 width; + CARD16 height; +} xRenderScaleReq; + +#define sz_xRenderScaleReq 32 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + CARD8 op; + CARD8 pad1; + CARD16 pad2; + Picture src; + Picture dst; + PictFormat maskFormat; + INT16 xSrc; + INT16 ySrc; +} xRenderTrapezoidsReq; + +#define sz_xRenderTrapezoidsReq 24 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + CARD8 op; + CARD8 pad1; + CARD16 pad2; + Picture src; + Picture dst; + PictFormat maskFormat; + INT16 xSrc; + INT16 ySrc; +} xRenderTrianglesReq; + +#define sz_xRenderTrianglesReq 24 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + CARD8 op; + CARD8 pad1; + CARD16 pad2; + Picture src; + Picture dst; + PictFormat maskFormat; + INT16 xSrc; + INT16 ySrc; +} xRenderTriStripReq; + +#define sz_xRenderTriStripReq 24 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + CARD8 op; + CARD8 pad1; + CARD16 pad2; + Picture src; + Picture dst; + PictFormat maskFormat; + INT16 xSrc; + INT16 ySrc; +} xRenderTriFanReq; + +#define sz_xRenderTriFanReq 24 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Glyphset gsid; + PictFormat format; +} xRenderCreateGlyphSetReq; + +#define sz_xRenderCreateGlyphSetReq 12 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Glyphset gsid; + Glyphset existing; +} xRenderReferenceGlyphSetReq; + +#define sz_xRenderReferenceGlyphSetReq 24 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Glyphset glyphset; +} xRenderFreeGlyphSetReq; + +#define sz_xRenderFreeGlyphSetReq 8 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Glyphset glyphset; + CARD32 nglyphs; +} xRenderAddGlyphsReq; + +#define sz_xRenderAddGlyphsReq 12 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Glyphset glyphset; +} xRenderFreeGlyphsReq; + +#define sz_xRenderFreeGlyphsReq 8 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + CARD8 op; + CARD8 pad1; + CARD16 pad2; + Picture src; + Picture dst; + PictFormat maskFormat; + Glyphset glyphset; + INT16 xSrc; + INT16 ySrc; +} xRenderCompositeGlyphsReq, xRenderCompositeGlyphs8Req, +xRenderCompositeGlyphs16Req, xRenderCompositeGlyphs32Req; + +#define sz_xRenderCompositeGlyphs8Req 28 +#define sz_xRenderCompositeGlyphs16Req 28 +#define sz_xRenderCompositeGlyphs32Req 28 + +/* 0.1 and higher */ + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + CARD8 op; + CARD8 pad1; + CARD16 pad2; + Picture dst; + xRenderColor color; +} xRenderFillRectanglesReq; + +#define sz_xRenderFillRectanglesReq 20 + +/* 0.5 and higher */ + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Cursor cid; + Picture src; + CARD16 x; + CARD16 y; +} xRenderCreateCursorReq; + +#define sz_xRenderCreateCursorReq 16 + +/* 0.6 and higher */ + +/* + * This can't use an array because 32-bit values may be in bitfields + */ +typedef struct { + Fixed matrix11; + Fixed matrix12; + Fixed matrix13; + Fixed matrix21; + Fixed matrix22; + Fixed matrix23; + Fixed matrix31; + Fixed matrix32; + Fixed matrix33; +} xRenderTransform; + +#define sz_xRenderTransform 36 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Picture picture; + xRenderTransform transform; +} xRenderSetPictureTransformReq; + +#define sz_xRenderSetPictureTransformReq 44 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Drawable drawable; +} xRenderQueryFiltersReq; + +#define sz_xRenderQueryFiltersReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber; + CARD32 length; + CARD32 numAliases; /* LISTofCARD16 */ + CARD32 numFilters; /* LISTofSTRING8 */ + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; +} xRenderQueryFiltersReply; + +#define sz_xRenderQueryFiltersReply 32 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Picture picture; + CARD16 nbytes; /* number of bytes in name */ + CARD16 pad; +} xRenderSetPictureFilterReq; + +#define sz_xRenderSetPictureFilterReq 12 + +/* 0.8 and higher */ + +typedef struct { + Cursor cursor; + CARD32 delay; +} xAnimCursorElt; + +#define sz_xAnimCursorElt 8 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Cursor cid; +} xRenderCreateAnimCursorReq; + +#define sz_xRenderCreateAnimCursorReq 8 + +/* 0.9 and higher */ + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Picture picture; + INT16 xOff; + INT16 yOff; +} xRenderAddTrapsReq; + +#define sz_xRenderAddTrapsReq 12 + +/* 0.10 and higher */ + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Picture pid; + xRenderColor color; +} xRenderCreateSolidFillReq; + +#define sz_xRenderCreateSolidFillReq 16 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Picture pid; + xPointFixed p1; + xPointFixed p2; + CARD32 nStops; +} xRenderCreateLinearGradientReq; + +#define sz_xRenderCreateLinearGradientReq 28 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Picture pid; + xPointFixed inner; + xPointFixed outer; + Fixed inner_radius; + Fixed outer_radius; + CARD32 nStops; +} xRenderCreateRadialGradientReq; + +#define sz_xRenderCreateRadialGradientReq 36 + +typedef struct { + CARD8 reqType; + CARD8 renderReqType; + CARD16 length; + Picture pid; + xPointFixed center; + Fixed angle; /* in degrees */ + CARD32 nStops; +} xRenderCreateConicalGradientReq; + +#define sz_xRenderCreateConicalGradientReq 24 + +#undef Window +#undef Drawable +#undef Font +#undef Pixmap +#undef Cursor +#undef Colormap +#undef GContext +#undef Atom +#undef VisualID +#undef Time +#undef KeyCode +#undef KeySym + +#undef Picture +#undef PictFormat +#undef Fixed +#undef Glyphset + +#endif /* _XRENDERP_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/extensions/shape.h b/thirdparty/linuxbsd_headers/X11/extensions/shape.h new file mode 100644 index 0000000000..66af5b1b44 --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/extensions/shape.h @@ -0,0 +1,152 @@ +/************************************************************ + +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +********************************************************/ + +#ifndef _SHAPE_H_ +#define _SHAPE_H_ + +#include <X11/Xfuncproto.h> +#include <X11/extensions/shapeconst.h> + +#ifndef _SHAPE_SERVER_ +#include <X11/Xutil.h> + +typedef struct { + int type; /* of event */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came frome a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window of event */ + int kind; /* ShapeBounding or ShapeClip */ + int x, y; /* extents of new region */ + unsigned width, height; + Time time; /* server timestamp when region changed */ + Bool shaped; /* true if the region exists */ +} XShapeEvent; + +_XFUNCPROTOBEGIN + +extern Bool XShapeQueryExtension ( + Display* /* display */, + int* /* event_base */, + int* /* error_base */ +); + +extern Status XShapeQueryVersion ( + Display* /* display */, + int* /* major_version */, + int* /* minor_version */ +); + +extern void XShapeCombineRegion ( + Display* /* display */, + Window /* dest */, + int /* dest_kind */, + int /* x_off */, + int /* y_off */, + Region /* region */, + int /* op */ +); + +extern void XShapeCombineRectangles ( + Display* /* display */, + Window /* dest */, + int /* dest_kind */, + int /* x_off */, + int /* y_off */, + XRectangle* /* rectangles */, + int /* n_rects */, + int /* op */, + int /* ordering */ +); + +extern void XShapeCombineMask ( + Display* /* display */, + Window /* dest */, + int /* dest_kind */, + int /* x_off */, + int /* y_off */, + Pixmap /* src */, + int /* op */ +); + +extern void XShapeCombineShape ( + Display* /* display */, + Window /* dest */, + int /* dest_kind */, + int /* x_off */, + int /* y_off */, + Window /* src */, + int /* src_kind */, + int /* op */ +); + +extern void XShapeOffsetShape ( + Display* /* display */, + Window /* dest */, + int /* dest_kind */, + int /* x_off */, + int /* y_off */ +); + +extern Status XShapeQueryExtents ( + Display* /* display */, + Window /* window */, + Bool* /* bounding_shaped */, + int* /* x_bounding */, + int* /* y_bounding */, + unsigned int* /* w_bounding */, + unsigned int* /* h_bounding */, + Bool* /* clip_shaped */, + int* /* x_clip */, + int* /* y_clip */, + unsigned int* /* w_clip */, + unsigned int* /* h_clip */ +); + +extern void XShapeSelectInput ( + Display* /* display */, + Window /* window */, + unsigned long /* mask */ +); + +extern unsigned long XShapeInputSelected ( + Display* /* display */, + Window /* window */ +); + +extern XRectangle *XShapeGetRectangles ( + Display* /* display */, + Window /* window */, + int /* kind */, + int* /* count */, + int* /* ordering */ +); + +_XFUNCPROTOEND + +#endif /* !_SHAPE_SERVER_ */ + +#endif /* _SHAPE_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/extensions/shapeconst.h b/thirdparty/linuxbsd_headers/X11/extensions/shapeconst.h new file mode 100644 index 0000000000..9088956f1b --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/extensions/shapeconst.h @@ -0,0 +1,55 @@ +/************************************************************ + +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +********************************************************/ + +#ifndef _SHAPECONST_H_ +#define _SHAPECONST_H_ + +/* + * Protocol requests constants and alignment values + * These would really be in SHAPE's X.h and Xproto.h equivalents + */ + +#define SHAPENAME "SHAPE" + +#define SHAPE_MAJOR_VERSION 1 /* current version numbers */ +#define SHAPE_MINOR_VERSION 1 + +#define ShapeSet 0 +#define ShapeUnion 1 +#define ShapeIntersect 2 +#define ShapeSubtract 3 +#define ShapeInvert 4 + +#define ShapeBounding 0 +#define ShapeClip 1 +#define ShapeInput 2 + +#define ShapeNotifyMask (1L << 0) +#define ShapeNotify 0 + +#define ShapeNumberEvents (ShapeNotify + 1) + +#endif /* _SHAPECONST_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/extensions/xfixeswire.h b/thirdparty/linuxbsd_headers/X11/extensions/xfixeswire.h new file mode 100644 index 0000000000..f6953e5c6d --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/extensions/xfixeswire.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright 2010 Red Hat, Inc. + * + * 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 (including the next + * paragraph) 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. + */ +/* + * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + + +#ifndef _XFIXESWIRE_H_ +#define _XFIXESWIRE_H_ + +#define XFIXES_NAME "XFIXES" +#define XFIXES_MAJOR 6 +#define XFIXES_MINOR 0 + +/*************** Version 1 ******************/ +#define X_XFixesQueryVersion 0 +#define X_XFixesChangeSaveSet 1 +#define X_XFixesSelectSelectionInput 2 +#define X_XFixesSelectCursorInput 3 +#define X_XFixesGetCursorImage 4 +/*************** Version 2 ******************/ +#define X_XFixesCreateRegion 5 +#define X_XFixesCreateRegionFromBitmap 6 +#define X_XFixesCreateRegionFromWindow 7 +#define X_XFixesCreateRegionFromGC 8 +#define X_XFixesCreateRegionFromPicture 9 +#define X_XFixesDestroyRegion 10 +#define X_XFixesSetRegion 11 +#define X_XFixesCopyRegion 12 +#define X_XFixesUnionRegion 13 +#define X_XFixesIntersectRegion 14 +#define X_XFixesSubtractRegion 15 +#define X_XFixesInvertRegion 16 +#define X_XFixesTranslateRegion 17 +#define X_XFixesRegionExtents 18 +#define X_XFixesFetchRegion 19 +#define X_XFixesSetGCClipRegion 20 +#define X_XFixesSetWindowShapeRegion 21 +#define X_XFixesSetPictureClipRegion 22 +#define X_XFixesSetCursorName 23 +#define X_XFixesGetCursorName 24 +#define X_XFixesGetCursorImageAndName 25 +#define X_XFixesChangeCursor 26 +#define X_XFixesChangeCursorByName 27 +/*************** Version 3 ******************/ +#define X_XFixesExpandRegion 28 +/*************** Version 4 ******************/ +#define X_XFixesHideCursor 29 +#define X_XFixesShowCursor 30 +/*************** Version 5 ******************/ +#define X_XFixesCreatePointerBarrier 31 +#define X_XFixesDestroyPointerBarrier 32 +/*************** Version 6 ******************/ +#define X_XFixesSetClientDisconnectMode 33 +#define X_XFixesGetClientDisconnectMode 34 + +#define XFixesNumberRequests (X_XFixesGetClientDisconnectMode+1) + +/* Selection events share one event number */ +#define XFixesSelectionNotify 0 + +/* Within the selection, the 'subtype' field distinguishes */ +#define XFixesSetSelectionOwnerNotify 0 +#define XFixesSelectionWindowDestroyNotify 1 +#define XFixesSelectionClientCloseNotify 2 + +#define XFixesSetSelectionOwnerNotifyMask (1L << 0) +#define XFixesSelectionWindowDestroyNotifyMask (1L << 1) +#define XFixesSelectionClientCloseNotifyMask (1L << 2) + +/* There's only one cursor event so far */ +#define XFixesCursorNotify 1 + +#define XFixesDisplayCursorNotify 0 + +#define XFixesDisplayCursorNotifyMask (1L << 0) + +#define XFixesNumberEvents (2) + +/* errors */ +#define BadRegion 0 +#define BadBarrier 1 +#define XFixesNumberErrors (BadBarrier+1) + +#define SaveSetNearest 0 +#define SaveSetRoot 1 + +#define SaveSetMap 0 +#define SaveSetUnmap 1 + +/*************** Version 2 ******************/ + +#define WindowRegionBounding 0 +#define WindowRegionClip 1 + +/*************** Version 5 ******************/ + +#define BarrierPositiveX (1L << 0) +#define BarrierPositiveY (1L << 1) +#define BarrierNegativeX (1L << 2) +#define BarrierNegativeY (1L << 3) + +/*************** Version 6 ******************/ + +/* The default server behaviour */ +#define XFixesClientDisconnectFlagDefault 0 +/* The server may disconnect this client to shut down */ +#define XFixesClientDisconnectFlagTerminate (1L << 0) + +#endif /* _XFIXESWIRE_H_ */ diff --git a/thirdparty/linuxbsd_headers/X11/keysym.h b/thirdparty/linuxbsd_headers/X11/keysym.h new file mode 100644 index 0000000000..0ffdde4a5a --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/keysym.h @@ -0,0 +1,74 @@ +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* default keysyms */ +#define XK_MISCELLANY +#define XK_XKB_KEYS +#define XK_LATIN1 +#define XK_LATIN2 +#define XK_LATIN3 +#define XK_LATIN4 +#define XK_LATIN8 +#define XK_LATIN9 +#define XK_CAUCASUS +#define XK_GREEK +#define XK_KATAKANA +#define XK_ARABIC +#define XK_CYRILLIC +#define XK_HEBREW +#define XK_THAI +#define XK_KOREAN +#define XK_ARMENIAN +#define XK_GEORGIAN +#define XK_VIETNAMESE +#define XK_CURRENCY +#define XK_MATHEMATICAL +#define XK_BRAILLE +#define XK_SINHALA + +#include <X11/keysymdef.h> + diff --git a/thirdparty/linuxbsd_headers/X11/keysymdef.h b/thirdparty/linuxbsd_headers/X11/keysymdef.h new file mode 100644 index 0000000000..35cf5439e3 --- /dev/null +++ b/thirdparty/linuxbsd_headers/X11/keysymdef.h @@ -0,0 +1,2502 @@ +/*********************************************************** +Copyright 1987, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * The "X11 Window System Protocol" standard defines in Appendix A the + * keysym codes. These 29-bit integer values identify characters or + * functions associated with each key (e.g., via the visible + * engraving) of a keyboard layout. This file assigns mnemonic macro + * names for these keysyms. + * + * This file is also compiled (by src/util/makekeys.c in libX11) into + * hash tables that can be accessed with X11 library functions such as + * XStringToKeysym() and XKeysymToString(). + * + * Where a keysym corresponds one-to-one to an ISO 10646 / Unicode + * character, this is noted in a comment that provides both the U+xxxx + * Unicode position, as well as the official Unicode name of the + * character. + * + * Where the correspondence is either not one-to-one or semantically + * unclear, the Unicode position and name are enclosed in + * parentheses. Such legacy keysyms should be considered deprecated + * and are not recommended for use in future keyboard mappings. + * + * For any future extension of the keysyms with characters already + * found in ISO 10646 / Unicode, the following algorithm shall be + * used. The new keysym code position will simply be the character's + * Unicode number plus 0x01000000. The keysym values in the range + * 0x01000100 to 0x0110ffff are reserved to represent Unicode + * characters in the range U+0100 to U+10FFFF. + * + * While most newer Unicode-based X11 clients do already accept + * Unicode-mapped keysyms in the range 0x01000100 to 0x0110ffff, it + * will remain necessary for clients -- in the interest of + * compatibility with existing servers -- to also understand the + * existing legacy keysym values in the range 0x0100 to 0x20ff. + * + * Where several mnemonic names are defined for the same keysym in this + * file, all but the first one listed should be considered deprecated. + * + * Mnemonic names for keysyms are defined in this file with lines + * that match one of these Perl regular expressions: + * + * /^\#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*\/\* U\+([0-9A-F]{4,6}) (.*) \*\/\s*$/ + * /^\#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*\/\*\(U\+([0-9A-F]{4,6}) (.*)\)\*\/\s*$/ + * /^\#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*(\/\*\s*(.*)\s*\*\/)?\s*$/ + * + * Before adding new keysyms, please do consider the following: In + * addition to the keysym names defined in this file, the + * XStringToKeysym() and XKeysymToString() functions will also handle + * any keysym string of the form "U0020" to "U007E" and "U00A0" to + * "U10FFFF" for all possible Unicode characters. In other words, + * every possible Unicode character has already a keysym string + * defined algorithmically, even if it is not listed here. Therefore, + * defining an additional keysym macro is only necessary where a + * non-hexadecimal mnemonic name is needed, or where the new keysym + * does not represent any existing Unicode character. + * + * When adding new keysyms to this file, do not forget to also update the + * following as needed: + * + * - the mappings in src/KeyBind.c in the libX11 repo + * https://gitlab.freedesktop.org/xorg/lib/libx11 + * + * - the protocol specification in specs/keysyms.xml in this repo + * https://gitlab.freedesktop.org/xorg/proto/xorgproto + * + */ + +#define XK_VoidSymbol 0xffffff /* Void symbol */ + +#ifdef XK_MISCELLANY +/* + * TTY function keys, cleverly chosen to map to ASCII, for convenience of + * programming, but could have been arbitrary (at the cost of lookup + * tables in client code). + */ + +#define XK_BackSpace 0xff08 /* Back space, back char */ +#define XK_Tab 0xff09 +#define XK_Linefeed 0xff0a /* Linefeed, LF */ +#define XK_Clear 0xff0b +#define XK_Return 0xff0d /* Return, enter */ +#define XK_Pause 0xff13 /* Pause, hold */ +#define XK_Scroll_Lock 0xff14 +#define XK_Sys_Req 0xff15 +#define XK_Escape 0xff1b +#define XK_Delete 0xffff /* Delete, rubout */ + + + +/* International & multi-key character composition */ + +#define XK_Multi_key 0xff20 /* Multi-key character compose */ +#define XK_Codeinput 0xff37 +#define XK_SingleCandidate 0xff3c +#define XK_MultipleCandidate 0xff3d +#define XK_PreviousCandidate 0xff3e + +/* Japanese keyboard support */ + +#define XK_Kanji 0xff21 /* Kanji, Kanji convert */ +#define XK_Muhenkan 0xff22 /* Cancel Conversion */ +#define XK_Henkan_Mode 0xff23 /* Start/Stop Conversion */ +#define XK_Henkan 0xff23 /* Alias for Henkan_Mode */ +#define XK_Romaji 0xff24 /* to Romaji */ +#define XK_Hiragana 0xff25 /* to Hiragana */ +#define XK_Katakana 0xff26 /* to Katakana */ +#define XK_Hiragana_Katakana 0xff27 /* Hiragana/Katakana toggle */ +#define XK_Zenkaku 0xff28 /* to Zenkaku */ +#define XK_Hankaku 0xff29 /* to Hankaku */ +#define XK_Zenkaku_Hankaku 0xff2a /* Zenkaku/Hankaku toggle */ +#define XK_Touroku 0xff2b /* Add to Dictionary */ +#define XK_Massyo 0xff2c /* Delete from Dictionary */ +#define XK_Kana_Lock 0xff2d /* Kana Lock */ +#define XK_Kana_Shift 0xff2e /* Kana Shift */ +#define XK_Eisu_Shift 0xff2f /* Alphanumeric Shift */ +#define XK_Eisu_toggle 0xff30 /* Alphanumeric toggle */ +#define XK_Kanji_Bangou 0xff37 /* Codeinput */ +#define XK_Zen_Koho 0xff3d /* Multiple/All Candidate(s) */ +#define XK_Mae_Koho 0xff3e /* Previous Candidate */ + +/* 0xff31 thru 0xff3f are under XK_KOREAN */ + +/* Cursor control & motion */ + +#define XK_Home 0xff50 +#define XK_Left 0xff51 /* Move left, left arrow */ +#define XK_Up 0xff52 /* Move up, up arrow */ +#define XK_Right 0xff53 /* Move right, right arrow */ +#define XK_Down 0xff54 /* Move down, down arrow */ +#define XK_Prior 0xff55 /* Prior, previous */ +#define XK_Page_Up 0xff55 +#define XK_Next 0xff56 /* Next */ +#define XK_Page_Down 0xff56 +#define XK_End 0xff57 /* EOL */ +#define XK_Begin 0xff58 /* BOL */ + + +/* Misc functions */ + +#define XK_Select 0xff60 /* Select, mark */ +#define XK_Print 0xff61 +#define XK_Execute 0xff62 /* Execute, run, do */ +#define XK_Insert 0xff63 /* Insert, insert here */ +#define XK_Undo 0xff65 +#define XK_Redo 0xff66 /* Redo, again */ +#define XK_Menu 0xff67 +#define XK_Find 0xff68 /* Find, search */ +#define XK_Cancel 0xff69 /* Cancel, stop, abort, exit */ +#define XK_Help 0xff6a /* Help */ +#define XK_Break 0xff6b +#define XK_Mode_switch 0xff7e /* Character set switch */ +#define XK_script_switch 0xff7e /* Alias for mode_switch */ +#define XK_Num_Lock 0xff7f + +/* Keypad functions, keypad numbers cleverly chosen to map to ASCII */ + +#define XK_KP_Space 0xff80 /* Space */ +#define XK_KP_Tab 0xff89 +#define XK_KP_Enter 0xff8d /* Enter */ +#define XK_KP_F1 0xff91 /* PF1, KP_A, ... */ +#define XK_KP_F2 0xff92 +#define XK_KP_F3 0xff93 +#define XK_KP_F4 0xff94 +#define XK_KP_Home 0xff95 +#define XK_KP_Left 0xff96 +#define XK_KP_Up 0xff97 +#define XK_KP_Right 0xff98 +#define XK_KP_Down 0xff99 +#define XK_KP_Prior 0xff9a +#define XK_KP_Page_Up 0xff9a +#define XK_KP_Next 0xff9b +#define XK_KP_Page_Down 0xff9b +#define XK_KP_End 0xff9c +#define XK_KP_Begin 0xff9d +#define XK_KP_Insert 0xff9e +#define XK_KP_Delete 0xff9f +#define XK_KP_Equal 0xffbd /* Equals */ +#define XK_KP_Multiply 0xffaa +#define XK_KP_Add 0xffab +#define XK_KP_Separator 0xffac /* Separator, often comma */ +#define XK_KP_Subtract 0xffad +#define XK_KP_Decimal 0xffae +#define XK_KP_Divide 0xffaf + +#define XK_KP_0 0xffb0 +#define XK_KP_1 0xffb1 +#define XK_KP_2 0xffb2 +#define XK_KP_3 0xffb3 +#define XK_KP_4 0xffb4 +#define XK_KP_5 0xffb5 +#define XK_KP_6 0xffb6 +#define XK_KP_7 0xffb7 +#define XK_KP_8 0xffb8 +#define XK_KP_9 0xffb9 + + + +/* + * Auxiliary functions; note the duplicate definitions for left and right + * function keys; Sun keyboards and a few other manufacturers have such + * function key groups on the left and/or right sides of the keyboard. + * We've not found a keyboard with more than 35 function keys total. + */ + +#define XK_F1 0xffbe +#define XK_F2 0xffbf +#define XK_F3 0xffc0 +#define XK_F4 0xffc1 +#define XK_F5 0xffc2 +#define XK_F6 0xffc3 +#define XK_F7 0xffc4 +#define XK_F8 0xffc5 +#define XK_F9 0xffc6 +#define XK_F10 0xffc7 +#define XK_F11 0xffc8 +#define XK_L1 0xffc8 +#define XK_F12 0xffc9 +#define XK_L2 0xffc9 +#define XK_F13 0xffca +#define XK_L3 0xffca +#define XK_F14 0xffcb +#define XK_L4 0xffcb +#define XK_F15 0xffcc +#define XK_L5 0xffcc +#define XK_F16 0xffcd +#define XK_L6 0xffcd +#define XK_F17 0xffce +#define XK_L7 0xffce +#define XK_F18 0xffcf +#define XK_L8 0xffcf +#define XK_F19 0xffd0 +#define XK_L9 0xffd0 +#define XK_F20 0xffd1 +#define XK_L10 0xffd1 +#define XK_F21 0xffd2 +#define XK_R1 0xffd2 +#define XK_F22 0xffd3 +#define XK_R2 0xffd3 +#define XK_F23 0xffd4 +#define XK_R3 0xffd4 +#define XK_F24 0xffd5 +#define XK_R4 0xffd5 +#define XK_F25 0xffd6 +#define XK_R5 0xffd6 +#define XK_F26 0xffd7 +#define XK_R6 0xffd7 +#define XK_F27 0xffd8 +#define XK_R7 0xffd8 +#define XK_F28 0xffd9 +#define XK_R8 0xffd9 +#define XK_F29 0xffda +#define XK_R9 0xffda +#define XK_F30 0xffdb +#define XK_R10 0xffdb +#define XK_F31 0xffdc +#define XK_R11 0xffdc +#define XK_F32 0xffdd +#define XK_R12 0xffdd +#define XK_F33 0xffde +#define XK_R13 0xffde +#define XK_F34 0xffdf +#define XK_R14 0xffdf +#define XK_F35 0xffe0 +#define XK_R15 0xffe0 + +/* Modifiers */ + +#define XK_Shift_L 0xffe1 /* Left shift */ +#define XK_Shift_R 0xffe2 /* Right shift */ +#define XK_Control_L 0xffe3 /* Left control */ +#define XK_Control_R 0xffe4 /* Right control */ +#define XK_Caps_Lock 0xffe5 /* Caps lock */ +#define XK_Shift_Lock 0xffe6 /* Shift lock */ + +#define XK_Meta_L 0xffe7 /* Left meta */ +#define XK_Meta_R 0xffe8 /* Right meta */ +#define XK_Alt_L 0xffe9 /* Left alt */ +#define XK_Alt_R 0xffea /* Right alt */ +#define XK_Super_L 0xffeb /* Left super */ +#define XK_Super_R 0xffec /* Right super */ +#define XK_Hyper_L 0xffed /* Left hyper */ +#define XK_Hyper_R 0xffee /* Right hyper */ +#endif /* XK_MISCELLANY */ + +/* + * Keyboard (XKB) Extension function and modifier keys + * (from Appendix C of "The X Keyboard Extension: Protocol Specification") + * Byte 3 = 0xfe + */ + +#ifdef XK_XKB_KEYS +#define XK_ISO_Lock 0xfe01 +#define XK_ISO_Level2_Latch 0xfe02 +#define XK_ISO_Level3_Shift 0xfe03 +#define XK_ISO_Level3_Latch 0xfe04 +#define XK_ISO_Level3_Lock 0xfe05 +#define XK_ISO_Level5_Shift 0xfe11 +#define XK_ISO_Level5_Latch 0xfe12 +#define XK_ISO_Level5_Lock 0xfe13 +#define XK_ISO_Group_Shift 0xff7e /* Alias for mode_switch */ +#define XK_ISO_Group_Latch 0xfe06 +#define XK_ISO_Group_Lock 0xfe07 +#define XK_ISO_Next_Group 0xfe08 +#define XK_ISO_Next_Group_Lock 0xfe09 +#define XK_ISO_Prev_Group 0xfe0a +#define XK_ISO_Prev_Group_Lock 0xfe0b +#define XK_ISO_First_Group 0xfe0c +#define XK_ISO_First_Group_Lock 0xfe0d +#define XK_ISO_Last_Group 0xfe0e +#define XK_ISO_Last_Group_Lock 0xfe0f + +#define XK_ISO_Left_Tab 0xfe20 +#define XK_ISO_Move_Line_Up 0xfe21 +#define XK_ISO_Move_Line_Down 0xfe22 +#define XK_ISO_Partial_Line_Up 0xfe23 +#define XK_ISO_Partial_Line_Down 0xfe24 +#define XK_ISO_Partial_Space_Left 0xfe25 +#define XK_ISO_Partial_Space_Right 0xfe26 +#define XK_ISO_Set_Margin_Left 0xfe27 +#define XK_ISO_Set_Margin_Right 0xfe28 +#define XK_ISO_Release_Margin_Left 0xfe29 +#define XK_ISO_Release_Margin_Right 0xfe2a +#define XK_ISO_Release_Both_Margins 0xfe2b +#define XK_ISO_Fast_Cursor_Left 0xfe2c +#define XK_ISO_Fast_Cursor_Right 0xfe2d +#define XK_ISO_Fast_Cursor_Up 0xfe2e +#define XK_ISO_Fast_Cursor_Down 0xfe2f +#define XK_ISO_Continuous_Underline 0xfe30 +#define XK_ISO_Discontinuous_Underline 0xfe31 +#define XK_ISO_Emphasize 0xfe32 +#define XK_ISO_Center_Object 0xfe33 +#define XK_ISO_Enter 0xfe34 + +#define XK_dead_grave 0xfe50 +#define XK_dead_acute 0xfe51 +#define XK_dead_circumflex 0xfe52 +#define XK_dead_tilde 0xfe53 +#define XK_dead_perispomeni 0xfe53 /* alias for dead_tilde */ +#define XK_dead_macron 0xfe54 +#define XK_dead_breve 0xfe55 +#define XK_dead_abovedot 0xfe56 +#define XK_dead_diaeresis 0xfe57 +#define XK_dead_abovering 0xfe58 +#define XK_dead_doubleacute 0xfe59 +#define XK_dead_caron 0xfe5a +#define XK_dead_cedilla 0xfe5b +#define XK_dead_ogonek 0xfe5c +#define XK_dead_iota 0xfe5d +#define XK_dead_voiced_sound 0xfe5e +#define XK_dead_semivoiced_sound 0xfe5f +#define XK_dead_belowdot 0xfe60 +#define XK_dead_hook 0xfe61 +#define XK_dead_horn 0xfe62 +#define XK_dead_stroke 0xfe63 +#define XK_dead_abovecomma 0xfe64 +#define XK_dead_psili 0xfe64 /* alias for dead_abovecomma */ +#define XK_dead_abovereversedcomma 0xfe65 +#define XK_dead_dasia 0xfe65 /* alias for dead_abovereversedcomma */ +#define XK_dead_doublegrave 0xfe66 +#define XK_dead_belowring 0xfe67 +#define XK_dead_belowmacron 0xfe68 +#define XK_dead_belowcircumflex 0xfe69 +#define XK_dead_belowtilde 0xfe6a +#define XK_dead_belowbreve 0xfe6b +#define XK_dead_belowdiaeresis 0xfe6c +#define XK_dead_invertedbreve 0xfe6d +#define XK_dead_belowcomma 0xfe6e +#define XK_dead_currency 0xfe6f + +/* extra dead elements for German T3 layout */ +#define XK_dead_lowline 0xfe90 +#define XK_dead_aboveverticalline 0xfe91 +#define XK_dead_belowverticalline 0xfe92 +#define XK_dead_longsolidusoverlay 0xfe93 + +/* dead vowels for universal syllable entry */ +#define XK_dead_a 0xfe80 +#define XK_dead_A 0xfe81 +#define XK_dead_e 0xfe82 +#define XK_dead_E 0xfe83 +#define XK_dead_i 0xfe84 +#define XK_dead_I 0xfe85 +#define XK_dead_o 0xfe86 +#define XK_dead_O 0xfe87 +#define XK_dead_u 0xfe88 +#define XK_dead_U 0xfe89 +#define XK_dead_small_schwa 0xfe8a +#define XK_dead_capital_schwa 0xfe8b + +#define XK_dead_greek 0xfe8c + +#define XK_First_Virtual_Screen 0xfed0 +#define XK_Prev_Virtual_Screen 0xfed1 +#define XK_Next_Virtual_Screen 0xfed2 +#define XK_Last_Virtual_Screen 0xfed4 +#define XK_Terminate_Server 0xfed5 + +#define XK_AccessX_Enable 0xfe70 +#define XK_AccessX_Feedback_Enable 0xfe71 +#define XK_RepeatKeys_Enable 0xfe72 +#define XK_SlowKeys_Enable 0xfe73 +#define XK_BounceKeys_Enable 0xfe74 +#define XK_StickyKeys_Enable 0xfe75 +#define XK_MouseKeys_Enable 0xfe76 +#define XK_MouseKeys_Accel_Enable 0xfe77 +#define XK_Overlay1_Enable 0xfe78 +#define XK_Overlay2_Enable 0xfe79 +#define XK_AudibleBell_Enable 0xfe7a + +#define XK_Pointer_Left 0xfee0 +#define XK_Pointer_Right 0xfee1 +#define XK_Pointer_Up 0xfee2 +#define XK_Pointer_Down 0xfee3 +#define XK_Pointer_UpLeft 0xfee4 +#define XK_Pointer_UpRight 0xfee5 +#define XK_Pointer_DownLeft 0xfee6 +#define XK_Pointer_DownRight 0xfee7 +#define XK_Pointer_Button_Dflt 0xfee8 +#define XK_Pointer_Button1 0xfee9 +#define XK_Pointer_Button2 0xfeea +#define XK_Pointer_Button3 0xfeeb +#define XK_Pointer_Button4 0xfeec +#define XK_Pointer_Button5 0xfeed +#define XK_Pointer_DblClick_Dflt 0xfeee +#define XK_Pointer_DblClick1 0xfeef +#define XK_Pointer_DblClick2 0xfef0 +#define XK_Pointer_DblClick3 0xfef1 +#define XK_Pointer_DblClick4 0xfef2 +#define XK_Pointer_DblClick5 0xfef3 +#define XK_Pointer_Drag_Dflt 0xfef4 +#define XK_Pointer_Drag1 0xfef5 +#define XK_Pointer_Drag2 0xfef6 +#define XK_Pointer_Drag3 0xfef7 +#define XK_Pointer_Drag4 0xfef8 +#define XK_Pointer_Drag5 0xfefd + +#define XK_Pointer_EnableKeys 0xfef9 +#define XK_Pointer_Accelerate 0xfefa +#define XK_Pointer_DfltBtnNext 0xfefb +#define XK_Pointer_DfltBtnPrev 0xfefc + +/* Single-Stroke Multiple-Character N-Graph Keysyms For The X Input Method */ + +#define XK_ch 0xfea0 +#define XK_Ch 0xfea1 +#define XK_CH 0xfea2 +#define XK_c_h 0xfea3 +#define XK_C_h 0xfea4 +#define XK_C_H 0xfea5 + +#endif /* XK_XKB_KEYS */ + +/* + * 3270 Terminal Keys + * Byte 3 = 0xfd + */ + +#ifdef XK_3270 +#define XK_3270_Duplicate 0xfd01 +#define XK_3270_FieldMark 0xfd02 +#define XK_3270_Right2 0xfd03 +#define XK_3270_Left2 0xfd04 +#define XK_3270_BackTab 0xfd05 +#define XK_3270_EraseEOF 0xfd06 +#define XK_3270_EraseInput 0xfd07 +#define XK_3270_Reset 0xfd08 +#define XK_3270_Quit 0xfd09 +#define XK_3270_PA1 0xfd0a +#define XK_3270_PA2 0xfd0b +#define XK_3270_PA3 0xfd0c +#define XK_3270_Test 0xfd0d +#define XK_3270_Attn 0xfd0e +#define XK_3270_CursorBlink 0xfd0f +#define XK_3270_AltCursor 0xfd10 +#define XK_3270_KeyClick 0xfd11 +#define XK_3270_Jump 0xfd12 +#define XK_3270_Ident 0xfd13 +#define XK_3270_Rule 0xfd14 +#define XK_3270_Copy 0xfd15 +#define XK_3270_Play 0xfd16 +#define XK_3270_Setup 0xfd17 +#define XK_3270_Record 0xfd18 +#define XK_3270_ChangeScreen 0xfd19 +#define XK_3270_DeleteWord 0xfd1a +#define XK_3270_ExSelect 0xfd1b +#define XK_3270_CursorSelect 0xfd1c +#define XK_3270_PrintScreen 0xfd1d +#define XK_3270_Enter 0xfd1e +#endif /* XK_3270 */ + +/* + * Latin 1 + * (ISO/IEC 8859-1 = Unicode U+0020..U+00FF) + * Byte 3 = 0 + */ +#ifdef XK_LATIN1 +#define XK_space 0x0020 /* U+0020 SPACE */ +#define XK_exclam 0x0021 /* U+0021 EXCLAMATION MARK */ +#define XK_quotedbl 0x0022 /* U+0022 QUOTATION MARK */ +#define XK_numbersign 0x0023 /* U+0023 NUMBER SIGN */ +#define XK_dollar 0x0024 /* U+0024 DOLLAR SIGN */ +#define XK_percent 0x0025 /* U+0025 PERCENT SIGN */ +#define XK_ampersand 0x0026 /* U+0026 AMPERSAND */ +#define XK_apostrophe 0x0027 /* U+0027 APOSTROPHE */ +#define XK_quoteright 0x0027 /* deprecated */ +#define XK_parenleft 0x0028 /* U+0028 LEFT PARENTHESIS */ +#define XK_parenright 0x0029 /* U+0029 RIGHT PARENTHESIS */ +#define XK_asterisk 0x002a /* U+002A ASTERISK */ +#define XK_plus 0x002b /* U+002B PLUS SIGN */ +#define XK_comma 0x002c /* U+002C COMMA */ +#define XK_minus 0x002d /* U+002D HYPHEN-MINUS */ +#define XK_period 0x002e /* U+002E FULL STOP */ +#define XK_slash 0x002f /* U+002F SOLIDUS */ +#define XK_0 0x0030 /* U+0030 DIGIT ZERO */ +#define XK_1 0x0031 /* U+0031 DIGIT ONE */ +#define XK_2 0x0032 /* U+0032 DIGIT TWO */ +#define XK_3 0x0033 /* U+0033 DIGIT THREE */ +#define XK_4 0x0034 /* U+0034 DIGIT FOUR */ +#define XK_5 0x0035 /* U+0035 DIGIT FIVE */ +#define XK_6 0x0036 /* U+0036 DIGIT SIX */ +#define XK_7 0x0037 /* U+0037 DIGIT SEVEN */ +#define XK_8 0x0038 /* U+0038 DIGIT EIGHT */ +#define XK_9 0x0039 /* U+0039 DIGIT NINE */ +#define XK_colon 0x003a /* U+003A COLON */ +#define XK_semicolon 0x003b /* U+003B SEMICOLON */ +#define XK_less 0x003c /* U+003C LESS-THAN SIGN */ +#define XK_equal 0x003d /* U+003D EQUALS SIGN */ +#define XK_greater 0x003e /* U+003E GREATER-THAN SIGN */ +#define XK_question 0x003f /* U+003F QUESTION MARK */ +#define XK_at 0x0040 /* U+0040 COMMERCIAL AT */ +#define XK_A 0x0041 /* U+0041 LATIN CAPITAL LETTER A */ +#define XK_B 0x0042 /* U+0042 LATIN CAPITAL LETTER B */ +#define XK_C 0x0043 /* U+0043 LATIN CAPITAL LETTER C */ +#define XK_D 0x0044 /* U+0044 LATIN CAPITAL LETTER D */ +#define XK_E 0x0045 /* U+0045 LATIN CAPITAL LETTER E */ +#define XK_F 0x0046 /* U+0046 LATIN CAPITAL LETTER F */ +#define XK_G 0x0047 /* U+0047 LATIN CAPITAL LETTER G */ +#define XK_H 0x0048 /* U+0048 LATIN CAPITAL LETTER H */ +#define XK_I 0x0049 /* U+0049 LATIN CAPITAL LETTER I */ +#define XK_J 0x004a /* U+004A LATIN CAPITAL LETTER J */ +#define XK_K 0x004b /* U+004B LATIN CAPITAL LETTER K */ +#define XK_L 0x004c /* U+004C LATIN CAPITAL LETTER L */ +#define XK_M 0x004d /* U+004D LATIN CAPITAL LETTER M */ +#define XK_N 0x004e /* U+004E LATIN CAPITAL LETTER N */ +#define XK_O 0x004f /* U+004F LATIN CAPITAL LETTER O */ +#define XK_P 0x0050 /* U+0050 LATIN CAPITAL LETTER P */ +#define XK_Q 0x0051 /* U+0051 LATIN CAPITAL LETTER Q */ +#define XK_R 0x0052 /* U+0052 LATIN CAPITAL LETTER R */ +#define XK_S 0x0053 /* U+0053 LATIN CAPITAL LETTER S */ +#define XK_T 0x0054 /* U+0054 LATIN CAPITAL LETTER T */ +#define XK_U 0x0055 /* U+0055 LATIN CAPITAL LETTER U */ +#define XK_V 0x0056 /* U+0056 LATIN CAPITAL LETTER V */ +#define XK_W 0x0057 /* U+0057 LATIN CAPITAL LETTER W */ +#define XK_X 0x0058 /* U+0058 LATIN CAPITAL LETTER X */ +#define XK_Y 0x0059 /* U+0059 LATIN CAPITAL LETTER Y */ +#define XK_Z 0x005a /* U+005A LATIN CAPITAL LETTER Z */ +#define XK_bracketleft 0x005b /* U+005B LEFT SQUARE BRACKET */ +#define XK_backslash 0x005c /* U+005C REVERSE SOLIDUS */ +#define XK_bracketright 0x005d /* U+005D RIGHT SQUARE BRACKET */ +#define XK_asciicircum 0x005e /* U+005E CIRCUMFLEX ACCENT */ +#define XK_underscore 0x005f /* U+005F LOW LINE */ +#define XK_grave 0x0060 /* U+0060 GRAVE ACCENT */ +#define XK_quoteleft 0x0060 /* deprecated */ +#define XK_a 0x0061 /* U+0061 LATIN SMALL LETTER A */ +#define XK_b 0x0062 /* U+0062 LATIN SMALL LETTER B */ +#define XK_c 0x0063 /* U+0063 LATIN SMALL LETTER C */ +#define XK_d 0x0064 /* U+0064 LATIN SMALL LETTER D */ +#define XK_e 0x0065 /* U+0065 LATIN SMALL LETTER E */ +#define XK_f 0x0066 /* U+0066 LATIN SMALL LETTER F */ +#define XK_g 0x0067 /* U+0067 LATIN SMALL LETTER G */ +#define XK_h 0x0068 /* U+0068 LATIN SMALL LETTER H */ +#define XK_i 0x0069 /* U+0069 LATIN SMALL LETTER I */ +#define XK_j 0x006a /* U+006A LATIN SMALL LETTER J */ +#define XK_k 0x006b /* U+006B LATIN SMALL LETTER K */ +#define XK_l 0x006c /* U+006C LATIN SMALL LETTER L */ +#define XK_m 0x006d /* U+006D LATIN SMALL LETTER M */ +#define XK_n 0x006e /* U+006E LATIN SMALL LETTER N */ +#define XK_o 0x006f /* U+006F LATIN SMALL LETTER O */ +#define XK_p 0x0070 /* U+0070 LATIN SMALL LETTER P */ +#define XK_q 0x0071 /* U+0071 LATIN SMALL LETTER Q */ +#define XK_r 0x0072 /* U+0072 LATIN SMALL LETTER R */ +#define XK_s 0x0073 /* U+0073 LATIN SMALL LETTER S */ +#define XK_t 0x0074 /* U+0074 LATIN SMALL LETTER T */ +#define XK_u 0x0075 /* U+0075 LATIN SMALL LETTER U */ +#define XK_v 0x0076 /* U+0076 LATIN SMALL LETTER V */ +#define XK_w 0x0077 /* U+0077 LATIN SMALL LETTER W */ +#define XK_x 0x0078 /* U+0078 LATIN SMALL LETTER X */ +#define XK_y 0x0079 /* U+0079 LATIN SMALL LETTER Y */ +#define XK_z 0x007a /* U+007A LATIN SMALL LETTER Z */ +#define XK_braceleft 0x007b /* U+007B LEFT CURLY BRACKET */ +#define XK_bar 0x007c /* U+007C VERTICAL LINE */ +#define XK_braceright 0x007d /* U+007D RIGHT CURLY BRACKET */ +#define XK_asciitilde 0x007e /* U+007E TILDE */ + +#define XK_nobreakspace 0x00a0 /* U+00A0 NO-BREAK SPACE */ +#define XK_exclamdown 0x00a1 /* U+00A1 INVERTED EXCLAMATION MARK */ +#define XK_cent 0x00a2 /* U+00A2 CENT SIGN */ +#define XK_sterling 0x00a3 /* U+00A3 POUND SIGN */ +#define XK_currency 0x00a4 /* U+00A4 CURRENCY SIGN */ +#define XK_yen 0x00a5 /* U+00A5 YEN SIGN */ +#define XK_brokenbar 0x00a6 /* U+00A6 BROKEN BAR */ +#define XK_section 0x00a7 /* U+00A7 SECTION SIGN */ +#define XK_diaeresis 0x00a8 /* U+00A8 DIAERESIS */ +#define XK_copyright 0x00a9 /* U+00A9 COPYRIGHT SIGN */ +#define XK_ordfeminine 0x00aa /* U+00AA FEMININE ORDINAL INDICATOR */ +#define XK_guillemotleft 0x00ab /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ +#define XK_notsign 0x00ac /* U+00AC NOT SIGN */ +#define XK_hyphen 0x00ad /* U+00AD SOFT HYPHEN */ +#define XK_registered 0x00ae /* U+00AE REGISTERED SIGN */ +#define XK_macron 0x00af /* U+00AF MACRON */ +#define XK_degree 0x00b0 /* U+00B0 DEGREE SIGN */ +#define XK_plusminus 0x00b1 /* U+00B1 PLUS-MINUS SIGN */ +#define XK_twosuperior 0x00b2 /* U+00B2 SUPERSCRIPT TWO */ +#define XK_threesuperior 0x00b3 /* U+00B3 SUPERSCRIPT THREE */ +#define XK_acute 0x00b4 /* U+00B4 ACUTE ACCENT */ +#define XK_mu 0x00b5 /* U+00B5 MICRO SIGN */ +#define XK_paragraph 0x00b6 /* U+00B6 PILCROW SIGN */ +#define XK_periodcentered 0x00b7 /* U+00B7 MIDDLE DOT */ +#define XK_cedilla 0x00b8 /* U+00B8 CEDILLA */ +#define XK_onesuperior 0x00b9 /* U+00B9 SUPERSCRIPT ONE */ +#define XK_masculine 0x00ba /* U+00BA MASCULINE ORDINAL INDICATOR */ +#define XK_guillemotright 0x00bb /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ +#define XK_onequarter 0x00bc /* U+00BC VULGAR FRACTION ONE QUARTER */ +#define XK_onehalf 0x00bd /* U+00BD VULGAR FRACTION ONE HALF */ +#define XK_threequarters 0x00be /* U+00BE VULGAR FRACTION THREE QUARTERS */ +#define XK_questiondown 0x00bf /* U+00BF INVERTED QUESTION MARK */ +#define XK_Agrave 0x00c0 /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */ +#define XK_Aacute 0x00c1 /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */ +#define XK_Acircumflex 0x00c2 /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ +#define XK_Atilde 0x00c3 /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */ +#define XK_Adiaeresis 0x00c4 /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */ +#define XK_Aring 0x00c5 /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */ +#define XK_AE 0x00c6 /* U+00C6 LATIN CAPITAL LETTER AE */ +#define XK_Ccedilla 0x00c7 /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */ +#define XK_Egrave 0x00c8 /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */ +#define XK_Eacute 0x00c9 /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */ +#define XK_Ecircumflex 0x00ca /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ +#define XK_Ediaeresis 0x00cb /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */ +#define XK_Igrave 0x00cc /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */ +#define XK_Iacute 0x00cd /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */ +#define XK_Icircumflex 0x00ce /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ +#define XK_Idiaeresis 0x00cf /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */ +#define XK_ETH 0x00d0 /* U+00D0 LATIN CAPITAL LETTER ETH */ +#define XK_Eth 0x00d0 /* deprecated */ +#define XK_Ntilde 0x00d1 /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */ +#define XK_Ograve 0x00d2 /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */ +#define XK_Oacute 0x00d3 /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */ +#define XK_Ocircumflex 0x00d4 /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ +#define XK_Otilde 0x00d5 /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */ +#define XK_Odiaeresis 0x00d6 /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */ +#define XK_multiply 0x00d7 /* U+00D7 MULTIPLICATION SIGN */ +#define XK_Oslash 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ +#define XK_Ooblique 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ +#define XK_Ugrave 0x00d9 /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */ +#define XK_Uacute 0x00da /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */ +#define XK_Ucircumflex 0x00db /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ +#define XK_Udiaeresis 0x00dc /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */ +#define XK_Yacute 0x00dd /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */ +#define XK_THORN 0x00de /* U+00DE LATIN CAPITAL LETTER THORN */ +#define XK_Thorn 0x00de /* deprecated */ +#define XK_ssharp 0x00df /* U+00DF LATIN SMALL LETTER SHARP S */ +#define XK_agrave 0x00e0 /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */ +#define XK_aacute 0x00e1 /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */ +#define XK_acircumflex 0x00e2 /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */ +#define XK_atilde 0x00e3 /* U+00E3 LATIN SMALL LETTER A WITH TILDE */ +#define XK_adiaeresis 0x00e4 /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */ +#define XK_aring 0x00e5 /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */ +#define XK_ae 0x00e6 /* U+00E6 LATIN SMALL LETTER AE */ +#define XK_ccedilla 0x00e7 /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ +#define XK_egrave 0x00e8 /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */ +#define XK_eacute 0x00e9 /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ +#define XK_ecircumflex 0x00ea /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */ +#define XK_ediaeresis 0x00eb /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */ +#define XK_igrave 0x00ec /* U+00EC LATIN SMALL LETTER I WITH GRAVE */ +#define XK_iacute 0x00ed /* U+00ED LATIN SMALL LETTER I WITH ACUTE */ +#define XK_icircumflex 0x00ee /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */ +#define XK_idiaeresis 0x00ef /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */ +#define XK_eth 0x00f0 /* U+00F0 LATIN SMALL LETTER ETH */ +#define XK_ntilde 0x00f1 /* U+00F1 LATIN SMALL LETTER N WITH TILDE */ +#define XK_ograve 0x00f2 /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */ +#define XK_oacute 0x00f3 /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */ +#define XK_ocircumflex 0x00f4 /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */ +#define XK_otilde 0x00f5 /* U+00F5 LATIN SMALL LETTER O WITH TILDE */ +#define XK_odiaeresis 0x00f6 /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */ +#define XK_division 0x00f7 /* U+00F7 DIVISION SIGN */ +#define XK_oslash 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ +#define XK_ooblique 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ +#define XK_ugrave 0x00f9 /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */ +#define XK_uacute 0x00fa /* U+00FA LATIN SMALL LETTER U WITH ACUTE */ +#define XK_ucircumflex 0x00fb /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */ +#define XK_udiaeresis 0x00fc /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */ +#define XK_yacute 0x00fd /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */ +#define XK_thorn 0x00fe /* U+00FE LATIN SMALL LETTER THORN */ +#define XK_ydiaeresis 0x00ff /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */ +#endif /* XK_LATIN1 */ + +/* + * Latin 2 + * Byte 3 = 1 + */ + +#ifdef XK_LATIN2 +#define XK_Aogonek 0x01a1 /* U+0104 LATIN CAPITAL LETTER A WITH OGONEK */ +#define XK_breve 0x01a2 /* U+02D8 BREVE */ +#define XK_Lstroke 0x01a3 /* U+0141 LATIN CAPITAL LETTER L WITH STROKE */ +#define XK_Lcaron 0x01a5 /* U+013D LATIN CAPITAL LETTER L WITH CARON */ +#define XK_Sacute 0x01a6 /* U+015A LATIN CAPITAL LETTER S WITH ACUTE */ +#define XK_Scaron 0x01a9 /* U+0160 LATIN CAPITAL LETTER S WITH CARON */ +#define XK_Scedilla 0x01aa /* U+015E LATIN CAPITAL LETTER S WITH CEDILLA */ +#define XK_Tcaron 0x01ab /* U+0164 LATIN CAPITAL LETTER T WITH CARON */ +#define XK_Zacute 0x01ac /* U+0179 LATIN CAPITAL LETTER Z WITH ACUTE */ +#define XK_Zcaron 0x01ae /* U+017D LATIN CAPITAL LETTER Z WITH CARON */ +#define XK_Zabovedot 0x01af /* U+017B LATIN CAPITAL LETTER Z WITH DOT ABOVE */ +#define XK_aogonek 0x01b1 /* U+0105 LATIN SMALL LETTER A WITH OGONEK */ +#define XK_ogonek 0x01b2 /* U+02DB OGONEK */ +#define XK_lstroke 0x01b3 /* U+0142 LATIN SMALL LETTER L WITH STROKE */ +#define XK_lcaron 0x01b5 /* U+013E LATIN SMALL LETTER L WITH CARON */ +#define XK_sacute 0x01b6 /* U+015B LATIN SMALL LETTER S WITH ACUTE */ +#define XK_caron 0x01b7 /* U+02C7 CARON */ +#define XK_scaron 0x01b9 /* U+0161 LATIN SMALL LETTER S WITH CARON */ +#define XK_scedilla 0x01ba /* U+015F LATIN SMALL LETTER S WITH CEDILLA */ +#define XK_tcaron 0x01bb /* U+0165 LATIN SMALL LETTER T WITH CARON */ +#define XK_zacute 0x01bc /* U+017A LATIN SMALL LETTER Z WITH ACUTE */ +#define XK_doubleacute 0x01bd /* U+02DD DOUBLE ACUTE ACCENT */ +#define XK_zcaron 0x01be /* U+017E LATIN SMALL LETTER Z WITH CARON */ +#define XK_zabovedot 0x01bf /* U+017C LATIN SMALL LETTER Z WITH DOT ABOVE */ +#define XK_Racute 0x01c0 /* U+0154 LATIN CAPITAL LETTER R WITH ACUTE */ +#define XK_Abreve 0x01c3 /* U+0102 LATIN CAPITAL LETTER A WITH BREVE */ +#define XK_Lacute 0x01c5 /* U+0139 LATIN CAPITAL LETTER L WITH ACUTE */ +#define XK_Cacute 0x01c6 /* U+0106 LATIN CAPITAL LETTER C WITH ACUTE */ +#define XK_Ccaron 0x01c8 /* U+010C LATIN CAPITAL LETTER C WITH CARON */ +#define XK_Eogonek 0x01ca /* U+0118 LATIN CAPITAL LETTER E WITH OGONEK */ +#define XK_Ecaron 0x01cc /* U+011A LATIN CAPITAL LETTER E WITH CARON */ +#define XK_Dcaron 0x01cf /* U+010E LATIN CAPITAL LETTER D WITH CARON */ +#define XK_Dstroke 0x01d0 /* U+0110 LATIN CAPITAL LETTER D WITH STROKE */ +#define XK_Nacute 0x01d1 /* U+0143 LATIN CAPITAL LETTER N WITH ACUTE */ +#define XK_Ncaron 0x01d2 /* U+0147 LATIN CAPITAL LETTER N WITH CARON */ +#define XK_Odoubleacute 0x01d5 /* U+0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ +#define XK_Rcaron 0x01d8 /* U+0158 LATIN CAPITAL LETTER R WITH CARON */ +#define XK_Uring 0x01d9 /* U+016E LATIN CAPITAL LETTER U WITH RING ABOVE */ +#define XK_Udoubleacute 0x01db /* U+0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ +#define XK_Tcedilla 0x01de /* U+0162 LATIN CAPITAL LETTER T WITH CEDILLA */ +#define XK_racute 0x01e0 /* U+0155 LATIN SMALL LETTER R WITH ACUTE */ +#define XK_abreve 0x01e3 /* U+0103 LATIN SMALL LETTER A WITH BREVE */ +#define XK_lacute 0x01e5 /* U+013A LATIN SMALL LETTER L WITH ACUTE */ +#define XK_cacute 0x01e6 /* U+0107 LATIN SMALL LETTER C WITH ACUTE */ +#define XK_ccaron 0x01e8 /* U+010D LATIN SMALL LETTER C WITH CARON */ +#define XK_eogonek 0x01ea /* U+0119 LATIN SMALL LETTER E WITH OGONEK */ +#define XK_ecaron 0x01ec /* U+011B LATIN SMALL LETTER E WITH CARON */ +#define XK_dcaron 0x01ef /* U+010F LATIN SMALL LETTER D WITH CARON */ +#define XK_dstroke 0x01f0 /* U+0111 LATIN SMALL LETTER D WITH STROKE */ +#define XK_nacute 0x01f1 /* U+0144 LATIN SMALL LETTER N WITH ACUTE */ +#define XK_ncaron 0x01f2 /* U+0148 LATIN SMALL LETTER N WITH CARON */ +#define XK_odoubleacute 0x01f5 /* U+0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE */ +#define XK_rcaron 0x01f8 /* U+0159 LATIN SMALL LETTER R WITH CARON */ +#define XK_uring 0x01f9 /* U+016F LATIN SMALL LETTER U WITH RING ABOVE */ +#define XK_udoubleacute 0x01fb /* U+0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE */ +#define XK_tcedilla 0x01fe /* U+0163 LATIN SMALL LETTER T WITH CEDILLA */ +#define XK_abovedot 0x01ff /* U+02D9 DOT ABOVE */ +#endif /* XK_LATIN2 */ + +/* + * Latin 3 + * Byte 3 = 2 + */ + +#ifdef XK_LATIN3 +#define XK_Hstroke 0x02a1 /* U+0126 LATIN CAPITAL LETTER H WITH STROKE */ +#define XK_Hcircumflex 0x02a6 /* U+0124 LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ +#define XK_Iabovedot 0x02a9 /* U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE */ +#define XK_Gbreve 0x02ab /* U+011E LATIN CAPITAL LETTER G WITH BREVE */ +#define XK_Jcircumflex 0x02ac /* U+0134 LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ +#define XK_hstroke 0x02b1 /* U+0127 LATIN SMALL LETTER H WITH STROKE */ +#define XK_hcircumflex 0x02b6 /* U+0125 LATIN SMALL LETTER H WITH CIRCUMFLEX */ +#define XK_idotless 0x02b9 /* U+0131 LATIN SMALL LETTER DOTLESS I */ +#define XK_gbreve 0x02bb /* U+011F LATIN SMALL LETTER G WITH BREVE */ +#define XK_jcircumflex 0x02bc /* U+0135 LATIN SMALL LETTER J WITH CIRCUMFLEX */ +#define XK_Cabovedot 0x02c5 /* U+010A LATIN CAPITAL LETTER C WITH DOT ABOVE */ +#define XK_Ccircumflex 0x02c6 /* U+0108 LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ +#define XK_Gabovedot 0x02d5 /* U+0120 LATIN CAPITAL LETTER G WITH DOT ABOVE */ +#define XK_Gcircumflex 0x02d8 /* U+011C LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ +#define XK_Ubreve 0x02dd /* U+016C LATIN CAPITAL LETTER U WITH BREVE */ +#define XK_Scircumflex 0x02de /* U+015C LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ +#define XK_cabovedot 0x02e5 /* U+010B LATIN SMALL LETTER C WITH DOT ABOVE */ +#define XK_ccircumflex 0x02e6 /* U+0109 LATIN SMALL LETTER C WITH CIRCUMFLEX */ +#define XK_gabovedot 0x02f5 /* U+0121 LATIN SMALL LETTER G WITH DOT ABOVE */ +#define XK_gcircumflex 0x02f8 /* U+011D LATIN SMALL LETTER G WITH CIRCUMFLEX */ +#define XK_ubreve 0x02fd /* U+016D LATIN SMALL LETTER U WITH BREVE */ +#define XK_scircumflex 0x02fe /* U+015D LATIN SMALL LETTER S WITH CIRCUMFLEX */ +#endif /* XK_LATIN3 */ + + +/* + * Latin 4 + * Byte 3 = 3 + */ + +#ifdef XK_LATIN4 +#define XK_kra 0x03a2 /* U+0138 LATIN SMALL LETTER KRA */ +#define XK_kappa 0x03a2 /* deprecated */ +#define XK_Rcedilla 0x03a3 /* U+0156 LATIN CAPITAL LETTER R WITH CEDILLA */ +#define XK_Itilde 0x03a5 /* U+0128 LATIN CAPITAL LETTER I WITH TILDE */ +#define XK_Lcedilla 0x03a6 /* U+013B LATIN CAPITAL LETTER L WITH CEDILLA */ +#define XK_Emacron 0x03aa /* U+0112 LATIN CAPITAL LETTER E WITH MACRON */ +#define XK_Gcedilla 0x03ab /* U+0122 LATIN CAPITAL LETTER G WITH CEDILLA */ +#define XK_Tslash 0x03ac /* U+0166 LATIN CAPITAL LETTER T WITH STROKE */ +#define XK_rcedilla 0x03b3 /* U+0157 LATIN SMALL LETTER R WITH CEDILLA */ +#define XK_itilde 0x03b5 /* U+0129 LATIN SMALL LETTER I WITH TILDE */ +#define XK_lcedilla 0x03b6 /* U+013C LATIN SMALL LETTER L WITH CEDILLA */ +#define XK_emacron 0x03ba /* U+0113 LATIN SMALL LETTER E WITH MACRON */ +#define XK_gcedilla 0x03bb /* U+0123 LATIN SMALL LETTER G WITH CEDILLA */ +#define XK_tslash 0x03bc /* U+0167 LATIN SMALL LETTER T WITH STROKE */ +#define XK_ENG 0x03bd /* U+014A LATIN CAPITAL LETTER ENG */ +#define XK_eng 0x03bf /* U+014B LATIN SMALL LETTER ENG */ +#define XK_Amacron 0x03c0 /* U+0100 LATIN CAPITAL LETTER A WITH MACRON */ +#define XK_Iogonek 0x03c7 /* U+012E LATIN CAPITAL LETTER I WITH OGONEK */ +#define XK_Eabovedot 0x03cc /* U+0116 LATIN CAPITAL LETTER E WITH DOT ABOVE */ +#define XK_Imacron 0x03cf /* U+012A LATIN CAPITAL LETTER I WITH MACRON */ +#define XK_Ncedilla 0x03d1 /* U+0145 LATIN CAPITAL LETTER N WITH CEDILLA */ +#define XK_Omacron 0x03d2 /* U+014C LATIN CAPITAL LETTER O WITH MACRON */ +#define XK_Kcedilla 0x03d3 /* U+0136 LATIN CAPITAL LETTER K WITH CEDILLA */ +#define XK_Uogonek 0x03d9 /* U+0172 LATIN CAPITAL LETTER U WITH OGONEK */ +#define XK_Utilde 0x03dd /* U+0168 LATIN CAPITAL LETTER U WITH TILDE */ +#define XK_Umacron 0x03de /* U+016A LATIN CAPITAL LETTER U WITH MACRON */ +#define XK_amacron 0x03e0 /* U+0101 LATIN SMALL LETTER A WITH MACRON */ +#define XK_iogonek 0x03e7 /* U+012F LATIN SMALL LETTER I WITH OGONEK */ +#define XK_eabovedot 0x03ec /* U+0117 LATIN SMALL LETTER E WITH DOT ABOVE */ +#define XK_imacron 0x03ef /* U+012B LATIN SMALL LETTER I WITH MACRON */ +#define XK_ncedilla 0x03f1 /* U+0146 LATIN SMALL LETTER N WITH CEDILLA */ +#define XK_omacron 0x03f2 /* U+014D LATIN SMALL LETTER O WITH MACRON */ +#define XK_kcedilla 0x03f3 /* U+0137 LATIN SMALL LETTER K WITH CEDILLA */ +#define XK_uogonek 0x03f9 /* U+0173 LATIN SMALL LETTER U WITH OGONEK */ +#define XK_utilde 0x03fd /* U+0169 LATIN SMALL LETTER U WITH TILDE */ +#define XK_umacron 0x03fe /* U+016B LATIN SMALL LETTER U WITH MACRON */ +#endif /* XK_LATIN4 */ + +/* + * Latin 8 + */ +#ifdef XK_LATIN8 +#define XK_Wcircumflex 0x1000174 /* U+0174 LATIN CAPITAL LETTER W WITH CIRCUMFLEX */ +#define XK_wcircumflex 0x1000175 /* U+0175 LATIN SMALL LETTER W WITH CIRCUMFLEX */ +#define XK_Ycircumflex 0x1000176 /* U+0176 LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */ +#define XK_ycircumflex 0x1000177 /* U+0177 LATIN SMALL LETTER Y WITH CIRCUMFLEX */ +#define XK_Babovedot 0x1001e02 /* U+1E02 LATIN CAPITAL LETTER B WITH DOT ABOVE */ +#define XK_babovedot 0x1001e03 /* U+1E03 LATIN SMALL LETTER B WITH DOT ABOVE */ +#define XK_Dabovedot 0x1001e0a /* U+1E0A LATIN CAPITAL LETTER D WITH DOT ABOVE */ +#define XK_dabovedot 0x1001e0b /* U+1E0B LATIN SMALL LETTER D WITH DOT ABOVE */ +#define XK_Fabovedot 0x1001e1e /* U+1E1E LATIN CAPITAL LETTER F WITH DOT ABOVE */ +#define XK_fabovedot 0x1001e1f /* U+1E1F LATIN SMALL LETTER F WITH DOT ABOVE */ +#define XK_Mabovedot 0x1001e40 /* U+1E40 LATIN CAPITAL LETTER M WITH DOT ABOVE */ +#define XK_mabovedot 0x1001e41 /* U+1E41 LATIN SMALL LETTER M WITH DOT ABOVE */ +#define XK_Pabovedot 0x1001e56 /* U+1E56 LATIN CAPITAL LETTER P WITH DOT ABOVE */ +#define XK_pabovedot 0x1001e57 /* U+1E57 LATIN SMALL LETTER P WITH DOT ABOVE */ +#define XK_Sabovedot 0x1001e60 /* U+1E60 LATIN CAPITAL LETTER S WITH DOT ABOVE */ +#define XK_sabovedot 0x1001e61 /* U+1E61 LATIN SMALL LETTER S WITH DOT ABOVE */ +#define XK_Tabovedot 0x1001e6a /* U+1E6A LATIN CAPITAL LETTER T WITH DOT ABOVE */ +#define XK_tabovedot 0x1001e6b /* U+1E6B LATIN SMALL LETTER T WITH DOT ABOVE */ +#define XK_Wgrave 0x1001e80 /* U+1E80 LATIN CAPITAL LETTER W WITH GRAVE */ +#define XK_wgrave 0x1001e81 /* U+1E81 LATIN SMALL LETTER W WITH GRAVE */ +#define XK_Wacute 0x1001e82 /* U+1E82 LATIN CAPITAL LETTER W WITH ACUTE */ +#define XK_wacute 0x1001e83 /* U+1E83 LATIN SMALL LETTER W WITH ACUTE */ +#define XK_Wdiaeresis 0x1001e84 /* U+1E84 LATIN CAPITAL LETTER W WITH DIAERESIS */ +#define XK_wdiaeresis 0x1001e85 /* U+1E85 LATIN SMALL LETTER W WITH DIAERESIS */ +#define XK_Ygrave 0x1001ef2 /* U+1EF2 LATIN CAPITAL LETTER Y WITH GRAVE */ +#define XK_ygrave 0x1001ef3 /* U+1EF3 LATIN SMALL LETTER Y WITH GRAVE */ +#endif /* XK_LATIN8 */ + +/* + * Latin 9 + * Byte 3 = 0x13 + */ + +#ifdef XK_LATIN9 +#define XK_OE 0x13bc /* U+0152 LATIN CAPITAL LIGATURE OE */ +#define XK_oe 0x13bd /* U+0153 LATIN SMALL LIGATURE OE */ +#define XK_Ydiaeresis 0x13be /* U+0178 LATIN CAPITAL LETTER Y WITH DIAERESIS */ +#endif /* XK_LATIN9 */ + +/* + * Katakana + * Byte 3 = 4 + */ + +#ifdef XK_KATAKANA +#define XK_overline 0x047e /* U+203E OVERLINE */ +#define XK_kana_fullstop 0x04a1 /* U+3002 IDEOGRAPHIC FULL STOP */ +#define XK_kana_openingbracket 0x04a2 /* U+300C LEFT CORNER BRACKET */ +#define XK_kana_closingbracket 0x04a3 /* U+300D RIGHT CORNER BRACKET */ +#define XK_kana_comma 0x04a4 /* U+3001 IDEOGRAPHIC COMMA */ +#define XK_kana_conjunctive 0x04a5 /* U+30FB KATAKANA MIDDLE DOT */ +#define XK_kana_middledot 0x04a5 /* deprecated */ +#define XK_kana_WO 0x04a6 /* U+30F2 KATAKANA LETTER WO */ +#define XK_kana_a 0x04a7 /* U+30A1 KATAKANA LETTER SMALL A */ +#define XK_kana_i 0x04a8 /* U+30A3 KATAKANA LETTER SMALL I */ +#define XK_kana_u 0x04a9 /* U+30A5 KATAKANA LETTER SMALL U */ +#define XK_kana_e 0x04aa /* U+30A7 KATAKANA LETTER SMALL E */ +#define XK_kana_o 0x04ab /* U+30A9 KATAKANA LETTER SMALL O */ +#define XK_kana_ya 0x04ac /* U+30E3 KATAKANA LETTER SMALL YA */ +#define XK_kana_yu 0x04ad /* U+30E5 KATAKANA LETTER SMALL YU */ +#define XK_kana_yo 0x04ae /* U+30E7 KATAKANA LETTER SMALL YO */ +#define XK_kana_tsu 0x04af /* U+30C3 KATAKANA LETTER SMALL TU */ +#define XK_kana_tu 0x04af /* deprecated */ +#define XK_prolongedsound 0x04b0 /* U+30FC KATAKANA-HIRAGANA PROLONGED SOUND MARK */ +#define XK_kana_A 0x04b1 /* U+30A2 KATAKANA LETTER A */ +#define XK_kana_I 0x04b2 /* U+30A4 KATAKANA LETTER I */ +#define XK_kana_U 0x04b3 /* U+30A6 KATAKANA LETTER U */ +#define XK_kana_E 0x04b4 /* U+30A8 KATAKANA LETTER E */ +#define XK_kana_O 0x04b5 /* U+30AA KATAKANA LETTER O */ +#define XK_kana_KA 0x04b6 /* U+30AB KATAKANA LETTER KA */ +#define XK_kana_KI 0x04b7 /* U+30AD KATAKANA LETTER KI */ +#define XK_kana_KU 0x04b8 /* U+30AF KATAKANA LETTER KU */ +#define XK_kana_KE 0x04b9 /* U+30B1 KATAKANA LETTER KE */ +#define XK_kana_KO 0x04ba /* U+30B3 KATAKANA LETTER KO */ +#define XK_kana_SA 0x04bb /* U+30B5 KATAKANA LETTER SA */ +#define XK_kana_SHI 0x04bc /* U+30B7 KATAKANA LETTER SI */ +#define XK_kana_SU 0x04bd /* U+30B9 KATAKANA LETTER SU */ +#define XK_kana_SE 0x04be /* U+30BB KATAKANA LETTER SE */ +#define XK_kana_SO 0x04bf /* U+30BD KATAKANA LETTER SO */ +#define XK_kana_TA 0x04c0 /* U+30BF KATAKANA LETTER TA */ +#define XK_kana_CHI 0x04c1 /* U+30C1 KATAKANA LETTER TI */ +#define XK_kana_TI 0x04c1 /* deprecated */ +#define XK_kana_TSU 0x04c2 /* U+30C4 KATAKANA LETTER TU */ +#define XK_kana_TU 0x04c2 /* deprecated */ +#define XK_kana_TE 0x04c3 /* U+30C6 KATAKANA LETTER TE */ +#define XK_kana_TO 0x04c4 /* U+30C8 KATAKANA LETTER TO */ +#define XK_kana_NA 0x04c5 /* U+30CA KATAKANA LETTER NA */ +#define XK_kana_NI 0x04c6 /* U+30CB KATAKANA LETTER NI */ +#define XK_kana_NU 0x04c7 /* U+30CC KATAKANA LETTER NU */ +#define XK_kana_NE 0x04c8 /* U+30CD KATAKANA LETTER NE */ +#define XK_kana_NO 0x04c9 /* U+30CE KATAKANA LETTER NO */ +#define XK_kana_HA 0x04ca /* U+30CF KATAKANA LETTER HA */ +#define XK_kana_HI 0x04cb /* U+30D2 KATAKANA LETTER HI */ +#define XK_kana_FU 0x04cc /* U+30D5 KATAKANA LETTER HU */ +#define XK_kana_HU 0x04cc /* deprecated */ +#define XK_kana_HE 0x04cd /* U+30D8 KATAKANA LETTER HE */ +#define XK_kana_HO 0x04ce /* U+30DB KATAKANA LETTER HO */ +#define XK_kana_MA 0x04cf /* U+30DE KATAKANA LETTER MA */ +#define XK_kana_MI 0x04d0 /* U+30DF KATAKANA LETTER MI */ +#define XK_kana_MU 0x04d1 /* U+30E0 KATAKANA LETTER MU */ +#define XK_kana_ME 0x04d2 /* U+30E1 KATAKANA LETTER ME */ +#define XK_kana_MO 0x04d3 /* U+30E2 KATAKANA LETTER MO */ +#define XK_kana_YA 0x04d4 /* U+30E4 KATAKANA LETTER YA */ +#define XK_kana_YU 0x04d5 /* U+30E6 KATAKANA LETTER YU */ +#define XK_kana_YO 0x04d6 /* U+30E8 KATAKANA LETTER YO */ +#define XK_kana_RA 0x04d7 /* U+30E9 KATAKANA LETTER RA */ +#define XK_kana_RI 0x04d8 /* U+30EA KATAKANA LETTER RI */ +#define XK_kana_RU 0x04d9 /* U+30EB KATAKANA LETTER RU */ +#define XK_kana_RE 0x04da /* U+30EC KATAKANA LETTER RE */ +#define XK_kana_RO 0x04db /* U+30ED KATAKANA LETTER RO */ +#define XK_kana_WA 0x04dc /* U+30EF KATAKANA LETTER WA */ +#define XK_kana_N 0x04dd /* U+30F3 KATAKANA LETTER N */ +#define XK_voicedsound 0x04de /* U+309B KATAKANA-HIRAGANA VOICED SOUND MARK */ +#define XK_semivoicedsound 0x04df /* U+309C KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ +#define XK_kana_switch 0xff7e /* Alias for mode_switch */ +#endif /* XK_KATAKANA */ + +/* + * Arabic + * Byte 3 = 5 + */ + +#ifdef XK_ARABIC +#define XK_Farsi_0 0x10006f0 /* U+06F0 EXTENDED ARABIC-INDIC DIGIT ZERO */ +#define XK_Farsi_1 0x10006f1 /* U+06F1 EXTENDED ARABIC-INDIC DIGIT ONE */ +#define XK_Farsi_2 0x10006f2 /* U+06F2 EXTENDED ARABIC-INDIC DIGIT TWO */ +#define XK_Farsi_3 0x10006f3 /* U+06F3 EXTENDED ARABIC-INDIC DIGIT THREE */ +#define XK_Farsi_4 0x10006f4 /* U+06F4 EXTENDED ARABIC-INDIC DIGIT FOUR */ +#define XK_Farsi_5 0x10006f5 /* U+06F5 EXTENDED ARABIC-INDIC DIGIT FIVE */ +#define XK_Farsi_6 0x10006f6 /* U+06F6 EXTENDED ARABIC-INDIC DIGIT SIX */ +#define XK_Farsi_7 0x10006f7 /* U+06F7 EXTENDED ARABIC-INDIC DIGIT SEVEN */ +#define XK_Farsi_8 0x10006f8 /* U+06F8 EXTENDED ARABIC-INDIC DIGIT EIGHT */ +#define XK_Farsi_9 0x10006f9 /* U+06F9 EXTENDED ARABIC-INDIC DIGIT NINE */ +#define XK_Arabic_percent 0x100066a /* U+066A ARABIC PERCENT SIGN */ +#define XK_Arabic_superscript_alef 0x1000670 /* U+0670 ARABIC LETTER SUPERSCRIPT ALEF */ +#define XK_Arabic_tteh 0x1000679 /* U+0679 ARABIC LETTER TTEH */ +#define XK_Arabic_peh 0x100067e /* U+067E ARABIC LETTER PEH */ +#define XK_Arabic_tcheh 0x1000686 /* U+0686 ARABIC LETTER TCHEH */ +#define XK_Arabic_ddal 0x1000688 /* U+0688 ARABIC LETTER DDAL */ +#define XK_Arabic_rreh 0x1000691 /* U+0691 ARABIC LETTER RREH */ +#define XK_Arabic_comma 0x05ac /* U+060C ARABIC COMMA */ +#define XK_Arabic_fullstop 0x10006d4 /* U+06D4 ARABIC FULL STOP */ +#define XK_Arabic_0 0x1000660 /* U+0660 ARABIC-INDIC DIGIT ZERO */ +#define XK_Arabic_1 0x1000661 /* U+0661 ARABIC-INDIC DIGIT ONE */ +#define XK_Arabic_2 0x1000662 /* U+0662 ARABIC-INDIC DIGIT TWO */ +#define XK_Arabic_3 0x1000663 /* U+0663 ARABIC-INDIC DIGIT THREE */ +#define XK_Arabic_4 0x1000664 /* U+0664 ARABIC-INDIC DIGIT FOUR */ +#define XK_Arabic_5 0x1000665 /* U+0665 ARABIC-INDIC DIGIT FIVE */ +#define XK_Arabic_6 0x1000666 /* U+0666 ARABIC-INDIC DIGIT SIX */ +#define XK_Arabic_7 0x1000667 /* U+0667 ARABIC-INDIC DIGIT SEVEN */ +#define XK_Arabic_8 0x1000668 /* U+0668 ARABIC-INDIC DIGIT EIGHT */ +#define XK_Arabic_9 0x1000669 /* U+0669 ARABIC-INDIC DIGIT NINE */ +#define XK_Arabic_semicolon 0x05bb /* U+061B ARABIC SEMICOLON */ +#define XK_Arabic_question_mark 0x05bf /* U+061F ARABIC QUESTION MARK */ +#define XK_Arabic_hamza 0x05c1 /* U+0621 ARABIC LETTER HAMZA */ +#define XK_Arabic_maddaonalef 0x05c2 /* U+0622 ARABIC LETTER ALEF WITH MADDA ABOVE */ +#define XK_Arabic_hamzaonalef 0x05c3 /* U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE */ +#define XK_Arabic_hamzaonwaw 0x05c4 /* U+0624 ARABIC LETTER WAW WITH HAMZA ABOVE */ +#define XK_Arabic_hamzaunderalef 0x05c5 /* U+0625 ARABIC LETTER ALEF WITH HAMZA BELOW */ +#define XK_Arabic_hamzaonyeh 0x05c6 /* U+0626 ARABIC LETTER YEH WITH HAMZA ABOVE */ +#define XK_Arabic_alef 0x05c7 /* U+0627 ARABIC LETTER ALEF */ +#define XK_Arabic_beh 0x05c8 /* U+0628 ARABIC LETTER BEH */ +#define XK_Arabic_tehmarbuta 0x05c9 /* U+0629 ARABIC LETTER TEH MARBUTA */ +#define XK_Arabic_teh 0x05ca /* U+062A ARABIC LETTER TEH */ +#define XK_Arabic_theh 0x05cb /* U+062B ARABIC LETTER THEH */ +#define XK_Arabic_jeem 0x05cc /* U+062C ARABIC LETTER JEEM */ +#define XK_Arabic_hah 0x05cd /* U+062D ARABIC LETTER HAH */ +#define XK_Arabic_khah 0x05ce /* U+062E ARABIC LETTER KHAH */ +#define XK_Arabic_dal 0x05cf /* U+062F ARABIC LETTER DAL */ +#define XK_Arabic_thal 0x05d0 /* U+0630 ARABIC LETTER THAL */ +#define XK_Arabic_ra 0x05d1 /* U+0631 ARABIC LETTER REH */ +#define XK_Arabic_zain 0x05d2 /* U+0632 ARABIC LETTER ZAIN */ +#define XK_Arabic_seen 0x05d3 /* U+0633 ARABIC LETTER SEEN */ +#define XK_Arabic_sheen 0x05d4 /* U+0634 ARABIC LETTER SHEEN */ +#define XK_Arabic_sad 0x05d5 /* U+0635 ARABIC LETTER SAD */ +#define XK_Arabic_dad 0x05d6 /* U+0636 ARABIC LETTER DAD */ +#define XK_Arabic_tah 0x05d7 /* U+0637 ARABIC LETTER TAH */ +#define XK_Arabic_zah 0x05d8 /* U+0638 ARABIC LETTER ZAH */ +#define XK_Arabic_ain 0x05d9 /* U+0639 ARABIC LETTER AIN */ +#define XK_Arabic_ghain 0x05da /* U+063A ARABIC LETTER GHAIN */ +#define XK_Arabic_tatweel 0x05e0 /* U+0640 ARABIC TATWEEL */ +#define XK_Arabic_feh 0x05e1 /* U+0641 ARABIC LETTER FEH */ +#define XK_Arabic_qaf 0x05e2 /* U+0642 ARABIC LETTER QAF */ +#define XK_Arabic_kaf 0x05e3 /* U+0643 ARABIC LETTER KAF */ +#define XK_Arabic_lam 0x05e4 /* U+0644 ARABIC LETTER LAM */ +#define XK_Arabic_meem 0x05e5 /* U+0645 ARABIC LETTER MEEM */ +#define XK_Arabic_noon 0x05e6 /* U+0646 ARABIC LETTER NOON */ +#define XK_Arabic_ha 0x05e7 /* U+0647 ARABIC LETTER HEH */ +#define XK_Arabic_heh 0x05e7 /* deprecated */ +#define XK_Arabic_waw 0x05e8 /* U+0648 ARABIC LETTER WAW */ +#define XK_Arabic_alefmaksura 0x05e9 /* U+0649 ARABIC LETTER ALEF MAKSURA */ +#define XK_Arabic_yeh 0x05ea /* U+064A ARABIC LETTER YEH */ +#define XK_Arabic_fathatan 0x05eb /* U+064B ARABIC FATHATAN */ +#define XK_Arabic_dammatan 0x05ec /* U+064C ARABIC DAMMATAN */ +#define XK_Arabic_kasratan 0x05ed /* U+064D ARABIC KASRATAN */ +#define XK_Arabic_fatha 0x05ee /* U+064E ARABIC FATHA */ +#define XK_Arabic_damma 0x05ef /* U+064F ARABIC DAMMA */ +#define XK_Arabic_kasra 0x05f0 /* U+0650 ARABIC KASRA */ +#define XK_Arabic_shadda 0x05f1 /* U+0651 ARABIC SHADDA */ +#define XK_Arabic_sukun 0x05f2 /* U+0652 ARABIC SUKUN */ +#define XK_Arabic_madda_above 0x1000653 /* U+0653 ARABIC MADDAH ABOVE */ +#define XK_Arabic_hamza_above 0x1000654 /* U+0654 ARABIC HAMZA ABOVE */ +#define XK_Arabic_hamza_below 0x1000655 /* U+0655 ARABIC HAMZA BELOW */ +#define XK_Arabic_jeh 0x1000698 /* U+0698 ARABIC LETTER JEH */ +#define XK_Arabic_veh 0x10006a4 /* U+06A4 ARABIC LETTER VEH */ +#define XK_Arabic_keheh 0x10006a9 /* U+06A9 ARABIC LETTER KEHEH */ +#define XK_Arabic_gaf 0x10006af /* U+06AF ARABIC LETTER GAF */ +#define XK_Arabic_noon_ghunna 0x10006ba /* U+06BA ARABIC LETTER NOON GHUNNA */ +#define XK_Arabic_heh_doachashmee 0x10006be /* U+06BE ARABIC LETTER HEH DOACHASHMEE */ +#define XK_Farsi_yeh 0x10006cc /* U+06CC ARABIC LETTER FARSI YEH */ +#define XK_Arabic_farsi_yeh 0x10006cc /* U+06CC ARABIC LETTER FARSI YEH */ +#define XK_Arabic_yeh_baree 0x10006d2 /* U+06D2 ARABIC LETTER YEH BARREE */ +#define XK_Arabic_heh_goal 0x10006c1 /* U+06C1 ARABIC LETTER HEH GOAL */ +#define XK_Arabic_switch 0xff7e /* Alias for mode_switch */ +#endif /* XK_ARABIC */ + +/* + * Cyrillic + * Byte 3 = 6 + */ +#ifdef XK_CYRILLIC +#define XK_Cyrillic_GHE_bar 0x1000492 /* U+0492 CYRILLIC CAPITAL LETTER GHE WITH STROKE */ +#define XK_Cyrillic_ghe_bar 0x1000493 /* U+0493 CYRILLIC SMALL LETTER GHE WITH STROKE */ +#define XK_Cyrillic_ZHE_descender 0x1000496 /* U+0496 CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER */ +#define XK_Cyrillic_zhe_descender 0x1000497 /* U+0497 CYRILLIC SMALL LETTER ZHE WITH DESCENDER */ +#define XK_Cyrillic_KA_descender 0x100049a /* U+049A CYRILLIC CAPITAL LETTER KA WITH DESCENDER */ +#define XK_Cyrillic_ka_descender 0x100049b /* U+049B CYRILLIC SMALL LETTER KA WITH DESCENDER */ +#define XK_Cyrillic_KA_vertstroke 0x100049c /* U+049C CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE */ +#define XK_Cyrillic_ka_vertstroke 0x100049d /* U+049D CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE */ +#define XK_Cyrillic_EN_descender 0x10004a2 /* U+04A2 CYRILLIC CAPITAL LETTER EN WITH DESCENDER */ +#define XK_Cyrillic_en_descender 0x10004a3 /* U+04A3 CYRILLIC SMALL LETTER EN WITH DESCENDER */ +#define XK_Cyrillic_U_straight 0x10004ae /* U+04AE CYRILLIC CAPITAL LETTER STRAIGHT U */ +#define XK_Cyrillic_u_straight 0x10004af /* U+04AF CYRILLIC SMALL LETTER STRAIGHT U */ +#define XK_Cyrillic_U_straight_bar 0x10004b0 /* U+04B0 CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE */ +#define XK_Cyrillic_u_straight_bar 0x10004b1 /* U+04B1 CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE */ +#define XK_Cyrillic_HA_descender 0x10004b2 /* U+04B2 CYRILLIC CAPITAL LETTER HA WITH DESCENDER */ +#define XK_Cyrillic_ha_descender 0x10004b3 /* U+04B3 CYRILLIC SMALL LETTER HA WITH DESCENDER */ +#define XK_Cyrillic_CHE_descender 0x10004b6 /* U+04B6 CYRILLIC CAPITAL LETTER CHE WITH DESCENDER */ +#define XK_Cyrillic_che_descender 0x10004b7 /* U+04B7 CYRILLIC SMALL LETTER CHE WITH DESCENDER */ +#define XK_Cyrillic_CHE_vertstroke 0x10004b8 /* U+04B8 CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE */ +#define XK_Cyrillic_che_vertstroke 0x10004b9 /* U+04B9 CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE */ +#define XK_Cyrillic_SHHA 0x10004ba /* U+04BA CYRILLIC CAPITAL LETTER SHHA */ +#define XK_Cyrillic_shha 0x10004bb /* U+04BB CYRILLIC SMALL LETTER SHHA */ + +#define XK_Cyrillic_SCHWA 0x10004d8 /* U+04D8 CYRILLIC CAPITAL LETTER SCHWA */ +#define XK_Cyrillic_schwa 0x10004d9 /* U+04D9 CYRILLIC SMALL LETTER SCHWA */ +#define XK_Cyrillic_I_macron 0x10004e2 /* U+04E2 CYRILLIC CAPITAL LETTER I WITH MACRON */ +#define XK_Cyrillic_i_macron 0x10004e3 /* U+04E3 CYRILLIC SMALL LETTER I WITH MACRON */ +#define XK_Cyrillic_O_bar 0x10004e8 /* U+04E8 CYRILLIC CAPITAL LETTER BARRED O */ +#define XK_Cyrillic_o_bar 0x10004e9 /* U+04E9 CYRILLIC SMALL LETTER BARRED O */ +#define XK_Cyrillic_U_macron 0x10004ee /* U+04EE CYRILLIC CAPITAL LETTER U WITH MACRON */ +#define XK_Cyrillic_u_macron 0x10004ef /* U+04EF CYRILLIC SMALL LETTER U WITH MACRON */ + +#define XK_Serbian_dje 0x06a1 /* U+0452 CYRILLIC SMALL LETTER DJE */ +#define XK_Macedonia_gje 0x06a2 /* U+0453 CYRILLIC SMALL LETTER GJE */ +#define XK_Cyrillic_io 0x06a3 /* U+0451 CYRILLIC SMALL LETTER IO */ +#define XK_Ukrainian_ie 0x06a4 /* U+0454 CYRILLIC SMALL LETTER UKRAINIAN IE */ +#define XK_Ukranian_je 0x06a4 /* deprecated */ +#define XK_Macedonia_dse 0x06a5 /* U+0455 CYRILLIC SMALL LETTER DZE */ +#define XK_Ukrainian_i 0x06a6 /* U+0456 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ +#define XK_Ukranian_i 0x06a6 /* deprecated */ +#define XK_Ukrainian_yi 0x06a7 /* U+0457 CYRILLIC SMALL LETTER YI */ +#define XK_Ukranian_yi 0x06a7 /* deprecated */ +#define XK_Cyrillic_je 0x06a8 /* U+0458 CYRILLIC SMALL LETTER JE */ +#define XK_Serbian_je 0x06a8 /* deprecated */ +#define XK_Cyrillic_lje 0x06a9 /* U+0459 CYRILLIC SMALL LETTER LJE */ +#define XK_Serbian_lje 0x06a9 /* deprecated */ +#define XK_Cyrillic_nje 0x06aa /* U+045A CYRILLIC SMALL LETTER NJE */ +#define XK_Serbian_nje 0x06aa /* deprecated */ +#define XK_Serbian_tshe 0x06ab /* U+045B CYRILLIC SMALL LETTER TSHE */ +#define XK_Macedonia_kje 0x06ac /* U+045C CYRILLIC SMALL LETTER KJE */ +#define XK_Ukrainian_ghe_with_upturn 0x06ad /* U+0491 CYRILLIC SMALL LETTER GHE WITH UPTURN */ +#define XK_Byelorussian_shortu 0x06ae /* U+045E CYRILLIC SMALL LETTER SHORT U */ +#define XK_Cyrillic_dzhe 0x06af /* U+045F CYRILLIC SMALL LETTER DZHE */ +#define XK_Serbian_dze 0x06af /* deprecated */ +#define XK_numerosign 0x06b0 /* U+2116 NUMERO SIGN */ +#define XK_Serbian_DJE 0x06b1 /* U+0402 CYRILLIC CAPITAL LETTER DJE */ +#define XK_Macedonia_GJE 0x06b2 /* U+0403 CYRILLIC CAPITAL LETTER GJE */ +#define XK_Cyrillic_IO 0x06b3 /* U+0401 CYRILLIC CAPITAL LETTER IO */ +#define XK_Ukrainian_IE 0x06b4 /* U+0404 CYRILLIC CAPITAL LETTER UKRAINIAN IE */ +#define XK_Ukranian_JE 0x06b4 /* deprecated */ +#define XK_Macedonia_DSE 0x06b5 /* U+0405 CYRILLIC CAPITAL LETTER DZE */ +#define XK_Ukrainian_I 0x06b6 /* U+0406 CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ +#define XK_Ukranian_I 0x06b6 /* deprecated */ +#define XK_Ukrainian_YI 0x06b7 /* U+0407 CYRILLIC CAPITAL LETTER YI */ +#define XK_Ukranian_YI 0x06b7 /* deprecated */ +#define XK_Cyrillic_JE 0x06b8 /* U+0408 CYRILLIC CAPITAL LETTER JE */ +#define XK_Serbian_JE 0x06b8 /* deprecated */ +#define XK_Cyrillic_LJE 0x06b9 /* U+0409 CYRILLIC CAPITAL LETTER LJE */ +#define XK_Serbian_LJE 0x06b9 /* deprecated */ +#define XK_Cyrillic_NJE 0x06ba /* U+040A CYRILLIC CAPITAL LETTER NJE */ +#define XK_Serbian_NJE 0x06ba /* deprecated */ +#define XK_Serbian_TSHE 0x06bb /* U+040B CYRILLIC CAPITAL LETTER TSHE */ +#define XK_Macedonia_KJE 0x06bc /* U+040C CYRILLIC CAPITAL LETTER KJE */ +#define XK_Ukrainian_GHE_WITH_UPTURN 0x06bd /* U+0490 CYRILLIC CAPITAL LETTER GHE WITH UPTURN */ +#define XK_Byelorussian_SHORTU 0x06be /* U+040E CYRILLIC CAPITAL LETTER SHORT U */ +#define XK_Cyrillic_DZHE 0x06bf /* U+040F CYRILLIC CAPITAL LETTER DZHE */ +#define XK_Serbian_DZE 0x06bf /* deprecated */ +#define XK_Cyrillic_yu 0x06c0 /* U+044E CYRILLIC SMALL LETTER YU */ +#define XK_Cyrillic_a 0x06c1 /* U+0430 CYRILLIC SMALL LETTER A */ +#define XK_Cyrillic_be 0x06c2 /* U+0431 CYRILLIC SMALL LETTER BE */ +#define XK_Cyrillic_tse 0x06c3 /* U+0446 CYRILLIC SMALL LETTER TSE */ +#define XK_Cyrillic_de 0x06c4 /* U+0434 CYRILLIC SMALL LETTER DE */ +#define XK_Cyrillic_ie 0x06c5 /* U+0435 CYRILLIC SMALL LETTER IE */ +#define XK_Cyrillic_ef 0x06c6 /* U+0444 CYRILLIC SMALL LETTER EF */ +#define XK_Cyrillic_ghe 0x06c7 /* U+0433 CYRILLIC SMALL LETTER GHE */ +#define XK_Cyrillic_ha 0x06c8 /* U+0445 CYRILLIC SMALL LETTER HA */ +#define XK_Cyrillic_i 0x06c9 /* U+0438 CYRILLIC SMALL LETTER I */ +#define XK_Cyrillic_shorti 0x06ca /* U+0439 CYRILLIC SMALL LETTER SHORT I */ +#define XK_Cyrillic_ka 0x06cb /* U+043A CYRILLIC SMALL LETTER KA */ +#define XK_Cyrillic_el 0x06cc /* U+043B CYRILLIC SMALL LETTER EL */ +#define XK_Cyrillic_em 0x06cd /* U+043C CYRILLIC SMALL LETTER EM */ +#define XK_Cyrillic_en 0x06ce /* U+043D CYRILLIC SMALL LETTER EN */ +#define XK_Cyrillic_o 0x06cf /* U+043E CYRILLIC SMALL LETTER O */ +#define XK_Cyrillic_pe 0x06d0 /* U+043F CYRILLIC SMALL LETTER PE */ +#define XK_Cyrillic_ya 0x06d1 /* U+044F CYRILLIC SMALL LETTER YA */ +#define XK_Cyrillic_er 0x06d2 /* U+0440 CYRILLIC SMALL LETTER ER */ +#define XK_Cyrillic_es 0x06d3 /* U+0441 CYRILLIC SMALL LETTER ES */ +#define XK_Cyrillic_te 0x06d4 /* U+0442 CYRILLIC SMALL LETTER TE */ +#define XK_Cyrillic_u 0x06d5 /* U+0443 CYRILLIC SMALL LETTER U */ +#define XK_Cyrillic_zhe 0x06d6 /* U+0436 CYRILLIC SMALL LETTER ZHE */ +#define XK_Cyrillic_ve 0x06d7 /* U+0432 CYRILLIC SMALL LETTER VE */ +#define XK_Cyrillic_softsign 0x06d8 /* U+044C CYRILLIC SMALL LETTER SOFT SIGN */ +#define XK_Cyrillic_yeru 0x06d9 /* U+044B CYRILLIC SMALL LETTER YERU */ +#define XK_Cyrillic_ze 0x06da /* U+0437 CYRILLIC SMALL LETTER ZE */ +#define XK_Cyrillic_sha 0x06db /* U+0448 CYRILLIC SMALL LETTER SHA */ +#define XK_Cyrillic_e 0x06dc /* U+044D CYRILLIC SMALL LETTER E */ +#define XK_Cyrillic_shcha 0x06dd /* U+0449 CYRILLIC SMALL LETTER SHCHA */ +#define XK_Cyrillic_che 0x06de /* U+0447 CYRILLIC SMALL LETTER CHE */ +#define XK_Cyrillic_hardsign 0x06df /* U+044A CYRILLIC SMALL LETTER HARD SIGN */ +#define XK_Cyrillic_YU 0x06e0 /* U+042E CYRILLIC CAPITAL LETTER YU */ +#define XK_Cyrillic_A 0x06e1 /* U+0410 CYRILLIC CAPITAL LETTER A */ +#define XK_Cyrillic_BE 0x06e2 /* U+0411 CYRILLIC CAPITAL LETTER BE */ +#define XK_Cyrillic_TSE 0x06e3 /* U+0426 CYRILLIC CAPITAL LETTER TSE */ +#define XK_Cyrillic_DE 0x06e4 /* U+0414 CYRILLIC CAPITAL LETTER DE */ +#define XK_Cyrillic_IE 0x06e5 /* U+0415 CYRILLIC CAPITAL LETTER IE */ +#define XK_Cyrillic_EF 0x06e6 /* U+0424 CYRILLIC CAPITAL LETTER EF */ +#define XK_Cyrillic_GHE 0x06e7 /* U+0413 CYRILLIC CAPITAL LETTER GHE */ +#define XK_Cyrillic_HA 0x06e8 /* U+0425 CYRILLIC CAPITAL LETTER HA */ +#define XK_Cyrillic_I 0x06e9 /* U+0418 CYRILLIC CAPITAL LETTER I */ +#define XK_Cyrillic_SHORTI 0x06ea /* U+0419 CYRILLIC CAPITAL LETTER SHORT I */ +#define XK_Cyrillic_KA 0x06eb /* U+041A CYRILLIC CAPITAL LETTER KA */ +#define XK_Cyrillic_EL 0x06ec /* U+041B CYRILLIC CAPITAL LETTER EL */ +#define XK_Cyrillic_EM 0x06ed /* U+041C CYRILLIC CAPITAL LETTER EM */ +#define XK_Cyrillic_EN 0x06ee /* U+041D CYRILLIC CAPITAL LETTER EN */ +#define XK_Cyrillic_O 0x06ef /* U+041E CYRILLIC CAPITAL LETTER O */ +#define XK_Cyrillic_PE 0x06f0 /* U+041F CYRILLIC CAPITAL LETTER PE */ +#define XK_Cyrillic_YA 0x06f1 /* U+042F CYRILLIC CAPITAL LETTER YA */ +#define XK_Cyrillic_ER 0x06f2 /* U+0420 CYRILLIC CAPITAL LETTER ER */ +#define XK_Cyrillic_ES 0x06f3 /* U+0421 CYRILLIC CAPITAL LETTER ES */ +#define XK_Cyrillic_TE 0x06f4 /* U+0422 CYRILLIC CAPITAL LETTER TE */ +#define XK_Cyrillic_U 0x06f5 /* U+0423 CYRILLIC CAPITAL LETTER U */ +#define XK_Cyrillic_ZHE 0x06f6 /* U+0416 CYRILLIC CAPITAL LETTER ZHE */ +#define XK_Cyrillic_VE 0x06f7 /* U+0412 CYRILLIC CAPITAL LETTER VE */ +#define XK_Cyrillic_SOFTSIGN 0x06f8 /* U+042C CYRILLIC CAPITAL LETTER SOFT SIGN */ +#define XK_Cyrillic_YERU 0x06f9 /* U+042B CYRILLIC CAPITAL LETTER YERU */ +#define XK_Cyrillic_ZE 0x06fa /* U+0417 CYRILLIC CAPITAL LETTER ZE */ +#define XK_Cyrillic_SHA 0x06fb /* U+0428 CYRILLIC CAPITAL LETTER SHA */ +#define XK_Cyrillic_E 0x06fc /* U+042D CYRILLIC CAPITAL LETTER E */ +#define XK_Cyrillic_SHCHA 0x06fd /* U+0429 CYRILLIC CAPITAL LETTER SHCHA */ +#define XK_Cyrillic_CHE 0x06fe /* U+0427 CYRILLIC CAPITAL LETTER CHE */ +#define XK_Cyrillic_HARDSIGN 0x06ff /* U+042A CYRILLIC CAPITAL LETTER HARD SIGN */ +#endif /* XK_CYRILLIC */ + +/* + * Greek + * (based on an early draft of, and not quite identical to, ISO/IEC 8859-7) + * Byte 3 = 7 + */ + +#ifdef XK_GREEK +#define XK_Greek_ALPHAaccent 0x07a1 /* U+0386 GREEK CAPITAL LETTER ALPHA WITH TONOS */ +#define XK_Greek_EPSILONaccent 0x07a2 /* U+0388 GREEK CAPITAL LETTER EPSILON WITH TONOS */ +#define XK_Greek_ETAaccent 0x07a3 /* U+0389 GREEK CAPITAL LETTER ETA WITH TONOS */ +#define XK_Greek_IOTAaccent 0x07a4 /* U+038A GREEK CAPITAL LETTER IOTA WITH TONOS */ +#define XK_Greek_IOTAdieresis 0x07a5 /* U+03AA GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ +#define XK_Greek_IOTAdiaeresis 0x07a5 /* old typo */ +#define XK_Greek_OMICRONaccent 0x07a7 /* U+038C GREEK CAPITAL LETTER OMICRON WITH TONOS */ +#define XK_Greek_UPSILONaccent 0x07a8 /* U+038E GREEK CAPITAL LETTER UPSILON WITH TONOS */ +#define XK_Greek_UPSILONdieresis 0x07a9 /* U+03AB GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ +#define XK_Greek_OMEGAaccent 0x07ab /* U+038F GREEK CAPITAL LETTER OMEGA WITH TONOS */ +#define XK_Greek_accentdieresis 0x07ae /* U+0385 GREEK DIALYTIKA TONOS */ +#define XK_Greek_horizbar 0x07af /* U+2015 HORIZONTAL BAR */ +#define XK_Greek_alphaaccent 0x07b1 /* U+03AC GREEK SMALL LETTER ALPHA WITH TONOS */ +#define XK_Greek_epsilonaccent 0x07b2 /* U+03AD GREEK SMALL LETTER EPSILON WITH TONOS */ +#define XK_Greek_etaaccent 0x07b3 /* U+03AE GREEK SMALL LETTER ETA WITH TONOS */ +#define XK_Greek_iotaaccent 0x07b4 /* U+03AF GREEK SMALL LETTER IOTA WITH TONOS */ +#define XK_Greek_iotadieresis 0x07b5 /* U+03CA GREEK SMALL LETTER IOTA WITH DIALYTIKA */ +#define XK_Greek_iotaaccentdieresis 0x07b6 /* U+0390 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ +#define XK_Greek_omicronaccent 0x07b7 /* U+03CC GREEK SMALL LETTER OMICRON WITH TONOS */ +#define XK_Greek_upsilonaccent 0x07b8 /* U+03CD GREEK SMALL LETTER UPSILON WITH TONOS */ +#define XK_Greek_upsilondieresis 0x07b9 /* U+03CB GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ +#define XK_Greek_upsilonaccentdieresis 0x07ba /* U+03B0 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ +#define XK_Greek_omegaaccent 0x07bb /* U+03CE GREEK SMALL LETTER OMEGA WITH TONOS */ +#define XK_Greek_ALPHA 0x07c1 /* U+0391 GREEK CAPITAL LETTER ALPHA */ +#define XK_Greek_BETA 0x07c2 /* U+0392 GREEK CAPITAL LETTER BETA */ +#define XK_Greek_GAMMA 0x07c3 /* U+0393 GREEK CAPITAL LETTER GAMMA */ +#define XK_Greek_DELTA 0x07c4 /* U+0394 GREEK CAPITAL LETTER DELTA */ +#define XK_Greek_EPSILON 0x07c5 /* U+0395 GREEK CAPITAL LETTER EPSILON */ +#define XK_Greek_ZETA 0x07c6 /* U+0396 GREEK CAPITAL LETTER ZETA */ +#define XK_Greek_ETA 0x07c7 /* U+0397 GREEK CAPITAL LETTER ETA */ +#define XK_Greek_THETA 0x07c8 /* U+0398 GREEK CAPITAL LETTER THETA */ +#define XK_Greek_IOTA 0x07c9 /* U+0399 GREEK CAPITAL LETTER IOTA */ +#define XK_Greek_KAPPA 0x07ca /* U+039A GREEK CAPITAL LETTER KAPPA */ +#define XK_Greek_LAMDA 0x07cb /* U+039B GREEK CAPITAL LETTER LAMDA */ +#define XK_Greek_LAMBDA 0x07cb /* U+039B GREEK CAPITAL LETTER LAMDA */ +#define XK_Greek_MU 0x07cc /* U+039C GREEK CAPITAL LETTER MU */ +#define XK_Greek_NU 0x07cd /* U+039D GREEK CAPITAL LETTER NU */ +#define XK_Greek_XI 0x07ce /* U+039E GREEK CAPITAL LETTER XI */ +#define XK_Greek_OMICRON 0x07cf /* U+039F GREEK CAPITAL LETTER OMICRON */ +#define XK_Greek_PI 0x07d0 /* U+03A0 GREEK CAPITAL LETTER PI */ +#define XK_Greek_RHO 0x07d1 /* U+03A1 GREEK CAPITAL LETTER RHO */ +#define XK_Greek_SIGMA 0x07d2 /* U+03A3 GREEK CAPITAL LETTER SIGMA */ +#define XK_Greek_TAU 0x07d4 /* U+03A4 GREEK CAPITAL LETTER TAU */ +#define XK_Greek_UPSILON 0x07d5 /* U+03A5 GREEK CAPITAL LETTER UPSILON */ +#define XK_Greek_PHI 0x07d6 /* U+03A6 GREEK CAPITAL LETTER PHI */ +#define XK_Greek_CHI 0x07d7 /* U+03A7 GREEK CAPITAL LETTER CHI */ +#define XK_Greek_PSI 0x07d8 /* U+03A8 GREEK CAPITAL LETTER PSI */ +#define XK_Greek_OMEGA 0x07d9 /* U+03A9 GREEK CAPITAL LETTER OMEGA */ +#define XK_Greek_alpha 0x07e1 /* U+03B1 GREEK SMALL LETTER ALPHA */ +#define XK_Greek_beta 0x07e2 /* U+03B2 GREEK SMALL LETTER BETA */ +#define XK_Greek_gamma 0x07e3 /* U+03B3 GREEK SMALL LETTER GAMMA */ +#define XK_Greek_delta 0x07e4 /* U+03B4 GREEK SMALL LETTER DELTA */ +#define XK_Greek_epsilon 0x07e5 /* U+03B5 GREEK SMALL LETTER EPSILON */ +#define XK_Greek_zeta 0x07e6 /* U+03B6 GREEK SMALL LETTER ZETA */ +#define XK_Greek_eta 0x07e7 /* U+03B7 GREEK SMALL LETTER ETA */ +#define XK_Greek_theta 0x07e8 /* U+03B8 GREEK SMALL LETTER THETA */ +#define XK_Greek_iota 0x07e9 /* U+03B9 GREEK SMALL LETTER IOTA */ +#define XK_Greek_kappa 0x07ea /* U+03BA GREEK SMALL LETTER KAPPA */ +#define XK_Greek_lamda 0x07eb /* U+03BB GREEK SMALL LETTER LAMDA */ +#define XK_Greek_lambda 0x07eb /* U+03BB GREEK SMALL LETTER LAMDA */ +#define XK_Greek_mu 0x07ec /* U+03BC GREEK SMALL LETTER MU */ +#define XK_Greek_nu 0x07ed /* U+03BD GREEK SMALL LETTER NU */ +#define XK_Greek_xi 0x07ee /* U+03BE GREEK SMALL LETTER XI */ +#define XK_Greek_omicron 0x07ef /* U+03BF GREEK SMALL LETTER OMICRON */ +#define XK_Greek_pi 0x07f0 /* U+03C0 GREEK SMALL LETTER PI */ +#define XK_Greek_rho 0x07f1 /* U+03C1 GREEK SMALL LETTER RHO */ +#define XK_Greek_sigma 0x07f2 /* U+03C3 GREEK SMALL LETTER SIGMA */ +#define XK_Greek_finalsmallsigma 0x07f3 /* U+03C2 GREEK SMALL LETTER FINAL SIGMA */ +#define XK_Greek_tau 0x07f4 /* U+03C4 GREEK SMALL LETTER TAU */ +#define XK_Greek_upsilon 0x07f5 /* U+03C5 GREEK SMALL LETTER UPSILON */ +#define XK_Greek_phi 0x07f6 /* U+03C6 GREEK SMALL LETTER PHI */ +#define XK_Greek_chi 0x07f7 /* U+03C7 GREEK SMALL LETTER CHI */ +#define XK_Greek_psi 0x07f8 /* U+03C8 GREEK SMALL LETTER PSI */ +#define XK_Greek_omega 0x07f9 /* U+03C9 GREEK SMALL LETTER OMEGA */ +#define XK_Greek_switch 0xff7e /* Alias for mode_switch */ +#endif /* XK_GREEK */ + +/* + * Technical + * (from the DEC VT330/VT420 Technical Character Set, http://vt100.net/charsets/technical.html) + * Byte 3 = 8 + */ + +#ifdef XK_TECHNICAL +#define XK_leftradical 0x08a1 /* U+23B7 RADICAL SYMBOL BOTTOM */ +#define XK_topleftradical 0x08a2 /*(U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT)*/ +#define XK_horizconnector 0x08a3 /*(U+2500 BOX DRAWINGS LIGHT HORIZONTAL)*/ +#define XK_topintegral 0x08a4 /* U+2320 TOP HALF INTEGRAL */ +#define XK_botintegral 0x08a5 /* U+2321 BOTTOM HALF INTEGRAL */ +#define XK_vertconnector 0x08a6 /*(U+2502 BOX DRAWINGS LIGHT VERTICAL)*/ +#define XK_topleftsqbracket 0x08a7 /* U+23A1 LEFT SQUARE BRACKET UPPER CORNER */ +#define XK_botleftsqbracket 0x08a8 /* U+23A3 LEFT SQUARE BRACKET LOWER CORNER */ +#define XK_toprightsqbracket 0x08a9 /* U+23A4 RIGHT SQUARE BRACKET UPPER CORNER */ +#define XK_botrightsqbracket 0x08aa /* U+23A6 RIGHT SQUARE BRACKET LOWER CORNER */ +#define XK_topleftparens 0x08ab /* U+239B LEFT PARENTHESIS UPPER HOOK */ +#define XK_botleftparens 0x08ac /* U+239D LEFT PARENTHESIS LOWER HOOK */ +#define XK_toprightparens 0x08ad /* U+239E RIGHT PARENTHESIS UPPER HOOK */ +#define XK_botrightparens 0x08ae /* U+23A0 RIGHT PARENTHESIS LOWER HOOK */ +#define XK_leftmiddlecurlybrace 0x08af /* U+23A8 LEFT CURLY BRACKET MIDDLE PIECE */ +#define XK_rightmiddlecurlybrace 0x08b0 /* U+23AC RIGHT CURLY BRACKET MIDDLE PIECE */ +#define XK_topleftsummation 0x08b1 +#define XK_botleftsummation 0x08b2 +#define XK_topvertsummationconnector 0x08b3 +#define XK_botvertsummationconnector 0x08b4 +#define XK_toprightsummation 0x08b5 +#define XK_botrightsummation 0x08b6 +#define XK_rightmiddlesummation 0x08b7 +#define XK_lessthanequal 0x08bc /* U+2264 LESS-THAN OR EQUAL TO */ +#define XK_notequal 0x08bd /* U+2260 NOT EQUAL TO */ +#define XK_greaterthanequal 0x08be /* U+2265 GREATER-THAN OR EQUAL TO */ +#define XK_integral 0x08bf /* U+222B INTEGRAL */ +#define XK_therefore 0x08c0 /* U+2234 THEREFORE */ +#define XK_variation 0x08c1 /* U+221D PROPORTIONAL TO */ +#define XK_infinity 0x08c2 /* U+221E INFINITY */ +#define XK_nabla 0x08c5 /* U+2207 NABLA */ +#define XK_approximate 0x08c8 /* U+223C TILDE OPERATOR */ +#define XK_similarequal 0x08c9 /* U+2243 ASYMPTOTICALLY EQUAL TO */ +#define XK_ifonlyif 0x08cd /* U+21D4 LEFT RIGHT DOUBLE ARROW */ +#define XK_implies 0x08ce /* U+21D2 RIGHTWARDS DOUBLE ARROW */ +#define XK_identical 0x08cf /* U+2261 IDENTICAL TO */ +#define XK_radical 0x08d6 /* U+221A SQUARE ROOT */ +#define XK_includedin 0x08da /* U+2282 SUBSET OF */ +#define XK_includes 0x08db /* U+2283 SUPERSET OF */ +#define XK_intersection 0x08dc /* U+2229 INTERSECTION */ +#define XK_union 0x08dd /* U+222A UNION */ +#define XK_logicaland 0x08de /* U+2227 LOGICAL AND */ +#define XK_logicalor 0x08df /* U+2228 LOGICAL OR */ +#define XK_partialderivative 0x08ef /* U+2202 PARTIAL DIFFERENTIAL */ +#define XK_function 0x08f6 /* U+0192 LATIN SMALL LETTER F WITH HOOK */ +#define XK_leftarrow 0x08fb /* U+2190 LEFTWARDS ARROW */ +#define XK_uparrow 0x08fc /* U+2191 UPWARDS ARROW */ +#define XK_rightarrow 0x08fd /* U+2192 RIGHTWARDS ARROW */ +#define XK_downarrow 0x08fe /* U+2193 DOWNWARDS ARROW */ +#endif /* XK_TECHNICAL */ + +/* + * Special + * (from the DEC VT100 Special Graphics Character Set) + * Byte 3 = 9 + */ + +#ifdef XK_SPECIAL +#define XK_blank 0x09df +#define XK_soliddiamond 0x09e0 /* U+25C6 BLACK DIAMOND */ +#define XK_checkerboard 0x09e1 /* U+2592 MEDIUM SHADE */ +#define XK_ht 0x09e2 /* U+2409 SYMBOL FOR HORIZONTAL TABULATION */ +#define XK_ff 0x09e3 /* U+240C SYMBOL FOR FORM FEED */ +#define XK_cr 0x09e4 /* U+240D SYMBOL FOR CARRIAGE RETURN */ +#define XK_lf 0x09e5 /* U+240A SYMBOL FOR LINE FEED */ +#define XK_nl 0x09e8 /* U+2424 SYMBOL FOR NEWLINE */ +#define XK_vt 0x09e9 /* U+240B SYMBOL FOR VERTICAL TABULATION */ +#define XK_lowrightcorner 0x09ea /* U+2518 BOX DRAWINGS LIGHT UP AND LEFT */ +#define XK_uprightcorner 0x09eb /* U+2510 BOX DRAWINGS LIGHT DOWN AND LEFT */ +#define XK_upleftcorner 0x09ec /* U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT */ +#define XK_lowleftcorner 0x09ed /* U+2514 BOX DRAWINGS LIGHT UP AND RIGHT */ +#define XK_crossinglines 0x09ee /* U+253C BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ +#define XK_horizlinescan1 0x09ef /* U+23BA HORIZONTAL SCAN LINE-1 */ +#define XK_horizlinescan3 0x09f0 /* U+23BB HORIZONTAL SCAN LINE-3 */ +#define XK_horizlinescan5 0x09f1 /* U+2500 BOX DRAWINGS LIGHT HORIZONTAL */ +#define XK_horizlinescan7 0x09f2 /* U+23BC HORIZONTAL SCAN LINE-7 */ +#define XK_horizlinescan9 0x09f3 /* U+23BD HORIZONTAL SCAN LINE-9 */ +#define XK_leftt 0x09f4 /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ +#define XK_rightt 0x09f5 /* U+2524 BOX DRAWINGS LIGHT VERTICAL AND LEFT */ +#define XK_bott 0x09f6 /* U+2534 BOX DRAWINGS LIGHT UP AND HORIZONTAL */ +#define XK_topt 0x09f7 /* U+252C BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ +#define XK_vertbar 0x09f8 /* U+2502 BOX DRAWINGS LIGHT VERTICAL */ +#endif /* XK_SPECIAL */ + +/* + * Publishing + * (these are probably from a long forgotten DEC Publishing + * font that once shipped with DECwrite) + * Byte 3 = 0x0a + */ + +#ifdef XK_PUBLISHING +#define XK_emspace 0x0aa1 /* U+2003 EM SPACE */ +#define XK_enspace 0x0aa2 /* U+2002 EN SPACE */ +#define XK_em3space 0x0aa3 /* U+2004 THREE-PER-EM SPACE */ +#define XK_em4space 0x0aa4 /* U+2005 FOUR-PER-EM SPACE */ +#define XK_digitspace 0x0aa5 /* U+2007 FIGURE SPACE */ +#define XK_punctspace 0x0aa6 /* U+2008 PUNCTUATION SPACE */ +#define XK_thinspace 0x0aa7 /* U+2009 THIN SPACE */ +#define XK_hairspace 0x0aa8 /* U+200A HAIR SPACE */ +#define XK_emdash 0x0aa9 /* U+2014 EM DASH */ +#define XK_endash 0x0aaa /* U+2013 EN DASH */ +#define XK_signifblank 0x0aac /*(U+2423 OPEN BOX)*/ +#define XK_ellipsis 0x0aae /* U+2026 HORIZONTAL ELLIPSIS */ +#define XK_doubbaselinedot 0x0aaf /* U+2025 TWO DOT LEADER */ +#define XK_onethird 0x0ab0 /* U+2153 VULGAR FRACTION ONE THIRD */ +#define XK_twothirds 0x0ab1 /* U+2154 VULGAR FRACTION TWO THIRDS */ +#define XK_onefifth 0x0ab2 /* U+2155 VULGAR FRACTION ONE FIFTH */ +#define XK_twofifths 0x0ab3 /* U+2156 VULGAR FRACTION TWO FIFTHS */ +#define XK_threefifths 0x0ab4 /* U+2157 VULGAR FRACTION THREE FIFTHS */ +#define XK_fourfifths 0x0ab5 /* U+2158 VULGAR FRACTION FOUR FIFTHS */ +#define XK_onesixth 0x0ab6 /* U+2159 VULGAR FRACTION ONE SIXTH */ +#define XK_fivesixths 0x0ab7 /* U+215A VULGAR FRACTION FIVE SIXTHS */ +#define XK_careof 0x0ab8 /* U+2105 CARE OF */ +#define XK_figdash 0x0abb /* U+2012 FIGURE DASH */ +#define XK_leftanglebracket 0x0abc /*(U+2329 LEFT-POINTING ANGLE BRACKET)*/ +#define XK_decimalpoint 0x0abd /*(U+002E FULL STOP)*/ +#define XK_rightanglebracket 0x0abe /*(U+232A RIGHT-POINTING ANGLE BRACKET)*/ +#define XK_marker 0x0abf +#define XK_oneeighth 0x0ac3 /* U+215B VULGAR FRACTION ONE EIGHTH */ +#define XK_threeeighths 0x0ac4 /* U+215C VULGAR FRACTION THREE EIGHTHS */ +#define XK_fiveeighths 0x0ac5 /* U+215D VULGAR FRACTION FIVE EIGHTHS */ +#define XK_seveneighths 0x0ac6 /* U+215E VULGAR FRACTION SEVEN EIGHTHS */ +#define XK_trademark 0x0ac9 /* U+2122 TRADE MARK SIGN */ +#define XK_signaturemark 0x0aca /*(U+2613 SALTIRE)*/ +#define XK_trademarkincircle 0x0acb +#define XK_leftopentriangle 0x0acc /*(U+25C1 WHITE LEFT-POINTING TRIANGLE)*/ +#define XK_rightopentriangle 0x0acd /*(U+25B7 WHITE RIGHT-POINTING TRIANGLE)*/ +#define XK_emopencircle 0x0ace /*(U+25CB WHITE CIRCLE)*/ +#define XK_emopenrectangle 0x0acf /*(U+25AF WHITE VERTICAL RECTANGLE)*/ +#define XK_leftsinglequotemark 0x0ad0 /* U+2018 LEFT SINGLE QUOTATION MARK */ +#define XK_rightsinglequotemark 0x0ad1 /* U+2019 RIGHT SINGLE QUOTATION MARK */ +#define XK_leftdoublequotemark 0x0ad2 /* U+201C LEFT DOUBLE QUOTATION MARK */ +#define XK_rightdoublequotemark 0x0ad3 /* U+201D RIGHT DOUBLE QUOTATION MARK */ +#define XK_prescription 0x0ad4 /* U+211E PRESCRIPTION TAKE */ +#define XK_permille 0x0ad5 /* U+2030 PER MILLE SIGN */ +#define XK_minutes 0x0ad6 /* U+2032 PRIME */ +#define XK_seconds 0x0ad7 /* U+2033 DOUBLE PRIME */ +#define XK_latincross 0x0ad9 /* U+271D LATIN CROSS */ +#define XK_hexagram 0x0ada +#define XK_filledrectbullet 0x0adb /*(U+25AC BLACK RECTANGLE)*/ +#define XK_filledlefttribullet 0x0adc /*(U+25C0 BLACK LEFT-POINTING TRIANGLE)*/ +#define XK_filledrighttribullet 0x0add /*(U+25B6 BLACK RIGHT-POINTING TRIANGLE)*/ +#define XK_emfilledcircle 0x0ade /*(U+25CF BLACK CIRCLE)*/ +#define XK_emfilledrect 0x0adf /*(U+25AE BLACK VERTICAL RECTANGLE)*/ +#define XK_enopencircbullet 0x0ae0 /*(U+25E6 WHITE BULLET)*/ +#define XK_enopensquarebullet 0x0ae1 /*(U+25AB WHITE SMALL SQUARE)*/ +#define XK_openrectbullet 0x0ae2 /*(U+25AD WHITE RECTANGLE)*/ +#define XK_opentribulletup 0x0ae3 /*(U+25B3 WHITE UP-POINTING TRIANGLE)*/ +#define XK_opentribulletdown 0x0ae4 /*(U+25BD WHITE DOWN-POINTING TRIANGLE)*/ +#define XK_openstar 0x0ae5 /*(U+2606 WHITE STAR)*/ +#define XK_enfilledcircbullet 0x0ae6 /*(U+2022 BULLET)*/ +#define XK_enfilledsqbullet 0x0ae7 /*(U+25AA BLACK SMALL SQUARE)*/ +#define XK_filledtribulletup 0x0ae8 /*(U+25B2 BLACK UP-POINTING TRIANGLE)*/ +#define XK_filledtribulletdown 0x0ae9 /*(U+25BC BLACK DOWN-POINTING TRIANGLE)*/ +#define XK_leftpointer 0x0aea /*(U+261C WHITE LEFT POINTING INDEX)*/ +#define XK_rightpointer 0x0aeb /*(U+261E WHITE RIGHT POINTING INDEX)*/ +#define XK_club 0x0aec /* U+2663 BLACK CLUB SUIT */ +#define XK_diamond 0x0aed /* U+2666 BLACK DIAMOND SUIT */ +#define XK_heart 0x0aee /* U+2665 BLACK HEART SUIT */ +#define XK_maltesecross 0x0af0 /* U+2720 MALTESE CROSS */ +#define XK_dagger 0x0af1 /* U+2020 DAGGER */ +#define XK_doubledagger 0x0af2 /* U+2021 DOUBLE DAGGER */ +#define XK_checkmark 0x0af3 /* U+2713 CHECK MARK */ +#define XK_ballotcross 0x0af4 /* U+2717 BALLOT X */ +#define XK_musicalsharp 0x0af5 /* U+266F MUSIC SHARP SIGN */ +#define XK_musicalflat 0x0af6 /* U+266D MUSIC FLAT SIGN */ +#define XK_malesymbol 0x0af7 /* U+2642 MALE SIGN */ +#define XK_femalesymbol 0x0af8 /* U+2640 FEMALE SIGN */ +#define XK_telephone 0x0af9 /* U+260E BLACK TELEPHONE */ +#define XK_telephonerecorder 0x0afa /* U+2315 TELEPHONE RECORDER */ +#define XK_phonographcopyright 0x0afb /* U+2117 SOUND RECORDING COPYRIGHT */ +#define XK_caret 0x0afc /* U+2038 CARET */ +#define XK_singlelowquotemark 0x0afd /* U+201A SINGLE LOW-9 QUOTATION MARK */ +#define XK_doublelowquotemark 0x0afe /* U+201E DOUBLE LOW-9 QUOTATION MARK */ +#define XK_cursor 0x0aff +#endif /* XK_PUBLISHING */ + +/* + * APL + * Byte 3 = 0x0b + */ + +#ifdef XK_APL +#define XK_leftcaret 0x0ba3 /*(U+003C LESS-THAN SIGN)*/ +#define XK_rightcaret 0x0ba6 /*(U+003E GREATER-THAN SIGN)*/ +#define XK_downcaret 0x0ba8 /*(U+2228 LOGICAL OR)*/ +#define XK_upcaret 0x0ba9 /*(U+2227 LOGICAL AND)*/ +#define XK_overbar 0x0bc0 /*(U+00AF MACRON)*/ +#define XK_downtack 0x0bc2 /* U+22A4 DOWN TACK */ +#define XK_upshoe 0x0bc3 /*(U+2229 INTERSECTION)*/ +#define XK_downstile 0x0bc4 /* U+230A LEFT FLOOR */ +#define XK_underbar 0x0bc6 /*(U+005F LOW LINE)*/ +#define XK_jot 0x0bca /* U+2218 RING OPERATOR */ +#define XK_quad 0x0bcc /* U+2395 APL FUNCTIONAL SYMBOL QUAD */ +#define XK_uptack 0x0bce /* U+22A5 UP TACK */ +#define XK_circle 0x0bcf /* U+25CB WHITE CIRCLE */ +#define XK_upstile 0x0bd3 /* U+2308 LEFT CEILING */ +#define XK_downshoe 0x0bd6 /*(U+222A UNION)*/ +#define XK_rightshoe 0x0bd8 /*(U+2283 SUPERSET OF)*/ +#define XK_leftshoe 0x0bda /*(U+2282 SUBSET OF)*/ +#define XK_lefttack 0x0bdc /* U+22A3 LEFT TACK */ +#define XK_righttack 0x0bfc /* U+22A2 RIGHT TACK */ +#endif /* XK_APL */ + +/* + * Hebrew + * Byte 3 = 0x0c + */ + +#ifdef XK_HEBREW +#define XK_hebrew_doublelowline 0x0cdf /* U+2017 DOUBLE LOW LINE */ +#define XK_hebrew_aleph 0x0ce0 /* U+05D0 HEBREW LETTER ALEF */ +#define XK_hebrew_bet 0x0ce1 /* U+05D1 HEBREW LETTER BET */ +#define XK_hebrew_beth 0x0ce1 /* deprecated */ +#define XK_hebrew_gimel 0x0ce2 /* U+05D2 HEBREW LETTER GIMEL */ +#define XK_hebrew_gimmel 0x0ce2 /* deprecated */ +#define XK_hebrew_dalet 0x0ce3 /* U+05D3 HEBREW LETTER DALET */ +#define XK_hebrew_daleth 0x0ce3 /* deprecated */ +#define XK_hebrew_he 0x0ce4 /* U+05D4 HEBREW LETTER HE */ +#define XK_hebrew_waw 0x0ce5 /* U+05D5 HEBREW LETTER VAV */ +#define XK_hebrew_zain 0x0ce6 /* U+05D6 HEBREW LETTER ZAYIN */ +#define XK_hebrew_zayin 0x0ce6 /* deprecated */ +#define XK_hebrew_chet 0x0ce7 /* U+05D7 HEBREW LETTER HET */ +#define XK_hebrew_het 0x0ce7 /* deprecated */ +#define XK_hebrew_tet 0x0ce8 /* U+05D8 HEBREW LETTER TET */ +#define XK_hebrew_teth 0x0ce8 /* deprecated */ +#define XK_hebrew_yod 0x0ce9 /* U+05D9 HEBREW LETTER YOD */ +#define XK_hebrew_finalkaph 0x0cea /* U+05DA HEBREW LETTER FINAL KAF */ +#define XK_hebrew_kaph 0x0ceb /* U+05DB HEBREW LETTER KAF */ +#define XK_hebrew_lamed 0x0cec /* U+05DC HEBREW LETTER LAMED */ +#define XK_hebrew_finalmem 0x0ced /* U+05DD HEBREW LETTER FINAL MEM */ +#define XK_hebrew_mem 0x0cee /* U+05DE HEBREW LETTER MEM */ +#define XK_hebrew_finalnun 0x0cef /* U+05DF HEBREW LETTER FINAL NUN */ +#define XK_hebrew_nun 0x0cf0 /* U+05E0 HEBREW LETTER NUN */ +#define XK_hebrew_samech 0x0cf1 /* U+05E1 HEBREW LETTER SAMEKH */ +#define XK_hebrew_samekh 0x0cf1 /* deprecated */ +#define XK_hebrew_ayin 0x0cf2 /* U+05E2 HEBREW LETTER AYIN */ +#define XK_hebrew_finalpe 0x0cf3 /* U+05E3 HEBREW LETTER FINAL PE */ +#define XK_hebrew_pe 0x0cf4 /* U+05E4 HEBREW LETTER PE */ +#define XK_hebrew_finalzade 0x0cf5 /* U+05E5 HEBREW LETTER FINAL TSADI */ +#define XK_hebrew_finalzadi 0x0cf5 /* deprecated */ +#define XK_hebrew_zade 0x0cf6 /* U+05E6 HEBREW LETTER TSADI */ +#define XK_hebrew_zadi 0x0cf6 /* deprecated */ +#define XK_hebrew_qoph 0x0cf7 /* U+05E7 HEBREW LETTER QOF */ +#define XK_hebrew_kuf 0x0cf7 /* deprecated */ +#define XK_hebrew_resh 0x0cf8 /* U+05E8 HEBREW LETTER RESH */ +#define XK_hebrew_shin 0x0cf9 /* U+05E9 HEBREW LETTER SHIN */ +#define XK_hebrew_taw 0x0cfa /* U+05EA HEBREW LETTER TAV */ +#define XK_hebrew_taf 0x0cfa /* deprecated */ +#define XK_Hebrew_switch 0xff7e /* Alias for mode_switch */ +#endif /* XK_HEBREW */ + +/* + * Thai + * Byte 3 = 0x0d + */ + +#ifdef XK_THAI +#define XK_Thai_kokai 0x0da1 /* U+0E01 THAI CHARACTER KO KAI */ +#define XK_Thai_khokhai 0x0da2 /* U+0E02 THAI CHARACTER KHO KHAI */ +#define XK_Thai_khokhuat 0x0da3 /* U+0E03 THAI CHARACTER KHO KHUAT */ +#define XK_Thai_khokhwai 0x0da4 /* U+0E04 THAI CHARACTER KHO KHWAI */ +#define XK_Thai_khokhon 0x0da5 /* U+0E05 THAI CHARACTER KHO KHON */ +#define XK_Thai_khorakhang 0x0da6 /* U+0E06 THAI CHARACTER KHO RAKHANG */ +#define XK_Thai_ngongu 0x0da7 /* U+0E07 THAI CHARACTER NGO NGU */ +#define XK_Thai_chochan 0x0da8 /* U+0E08 THAI CHARACTER CHO CHAN */ +#define XK_Thai_choching 0x0da9 /* U+0E09 THAI CHARACTER CHO CHING */ +#define XK_Thai_chochang 0x0daa /* U+0E0A THAI CHARACTER CHO CHANG */ +#define XK_Thai_soso 0x0dab /* U+0E0B THAI CHARACTER SO SO */ +#define XK_Thai_chochoe 0x0dac /* U+0E0C THAI CHARACTER CHO CHOE */ +#define XK_Thai_yoying 0x0dad /* U+0E0D THAI CHARACTER YO YING */ +#define XK_Thai_dochada 0x0dae /* U+0E0E THAI CHARACTER DO CHADA */ +#define XK_Thai_topatak 0x0daf /* U+0E0F THAI CHARACTER TO PATAK */ +#define XK_Thai_thothan 0x0db0 /* U+0E10 THAI CHARACTER THO THAN */ +#define XK_Thai_thonangmontho 0x0db1 /* U+0E11 THAI CHARACTER THO NANGMONTHO */ +#define XK_Thai_thophuthao 0x0db2 /* U+0E12 THAI CHARACTER THO PHUTHAO */ +#define XK_Thai_nonen 0x0db3 /* U+0E13 THAI CHARACTER NO NEN */ +#define XK_Thai_dodek 0x0db4 /* U+0E14 THAI CHARACTER DO DEK */ +#define XK_Thai_totao 0x0db5 /* U+0E15 THAI CHARACTER TO TAO */ +#define XK_Thai_thothung 0x0db6 /* U+0E16 THAI CHARACTER THO THUNG */ +#define XK_Thai_thothahan 0x0db7 /* U+0E17 THAI CHARACTER THO THAHAN */ +#define XK_Thai_thothong 0x0db8 /* U+0E18 THAI CHARACTER THO THONG */ +#define XK_Thai_nonu 0x0db9 /* U+0E19 THAI CHARACTER NO NU */ +#define XK_Thai_bobaimai 0x0dba /* U+0E1A THAI CHARACTER BO BAIMAI */ +#define XK_Thai_popla 0x0dbb /* U+0E1B THAI CHARACTER PO PLA */ +#define XK_Thai_phophung 0x0dbc /* U+0E1C THAI CHARACTER PHO PHUNG */ +#define XK_Thai_fofa 0x0dbd /* U+0E1D THAI CHARACTER FO FA */ +#define XK_Thai_phophan 0x0dbe /* U+0E1E THAI CHARACTER PHO PHAN */ +#define XK_Thai_fofan 0x0dbf /* U+0E1F THAI CHARACTER FO FAN */ +#define XK_Thai_phosamphao 0x0dc0 /* U+0E20 THAI CHARACTER PHO SAMPHAO */ +#define XK_Thai_moma 0x0dc1 /* U+0E21 THAI CHARACTER MO MA */ +#define XK_Thai_yoyak 0x0dc2 /* U+0E22 THAI CHARACTER YO YAK */ +#define XK_Thai_rorua 0x0dc3 /* U+0E23 THAI CHARACTER RO RUA */ +#define XK_Thai_ru 0x0dc4 /* U+0E24 THAI CHARACTER RU */ +#define XK_Thai_loling 0x0dc5 /* U+0E25 THAI CHARACTER LO LING */ +#define XK_Thai_lu 0x0dc6 /* U+0E26 THAI CHARACTER LU */ +#define XK_Thai_wowaen 0x0dc7 /* U+0E27 THAI CHARACTER WO WAEN */ +#define XK_Thai_sosala 0x0dc8 /* U+0E28 THAI CHARACTER SO SALA */ +#define XK_Thai_sorusi 0x0dc9 /* U+0E29 THAI CHARACTER SO RUSI */ +#define XK_Thai_sosua 0x0dca /* U+0E2A THAI CHARACTER SO SUA */ +#define XK_Thai_hohip 0x0dcb /* U+0E2B THAI CHARACTER HO HIP */ +#define XK_Thai_lochula 0x0dcc /* U+0E2C THAI CHARACTER LO CHULA */ +#define XK_Thai_oang 0x0dcd /* U+0E2D THAI CHARACTER O ANG */ +#define XK_Thai_honokhuk 0x0dce /* U+0E2E THAI CHARACTER HO NOKHUK */ +#define XK_Thai_paiyannoi 0x0dcf /* U+0E2F THAI CHARACTER PAIYANNOI */ +#define XK_Thai_saraa 0x0dd0 /* U+0E30 THAI CHARACTER SARA A */ +#define XK_Thai_maihanakat 0x0dd1 /* U+0E31 THAI CHARACTER MAI HAN-AKAT */ +#define XK_Thai_saraaa 0x0dd2 /* U+0E32 THAI CHARACTER SARA AA */ +#define XK_Thai_saraam 0x0dd3 /* U+0E33 THAI CHARACTER SARA AM */ +#define XK_Thai_sarai 0x0dd4 /* U+0E34 THAI CHARACTER SARA I */ +#define XK_Thai_saraii 0x0dd5 /* U+0E35 THAI CHARACTER SARA II */ +#define XK_Thai_saraue 0x0dd6 /* U+0E36 THAI CHARACTER SARA UE */ +#define XK_Thai_sarauee 0x0dd7 /* U+0E37 THAI CHARACTER SARA UEE */ +#define XK_Thai_sarau 0x0dd8 /* U+0E38 THAI CHARACTER SARA U */ +#define XK_Thai_sarauu 0x0dd9 /* U+0E39 THAI CHARACTER SARA UU */ +#define XK_Thai_phinthu 0x0dda /* U+0E3A THAI CHARACTER PHINTHU */ +#define XK_Thai_maihanakat_maitho 0x0dde +#define XK_Thai_baht 0x0ddf /* U+0E3F THAI CURRENCY SYMBOL BAHT */ +#define XK_Thai_sarae 0x0de0 /* U+0E40 THAI CHARACTER SARA E */ +#define XK_Thai_saraae 0x0de1 /* U+0E41 THAI CHARACTER SARA AE */ +#define XK_Thai_sarao 0x0de2 /* U+0E42 THAI CHARACTER SARA O */ +#define XK_Thai_saraaimaimuan 0x0de3 /* U+0E43 THAI CHARACTER SARA AI MAIMUAN */ +#define XK_Thai_saraaimaimalai 0x0de4 /* U+0E44 THAI CHARACTER SARA AI MAIMALAI */ +#define XK_Thai_lakkhangyao 0x0de5 /* U+0E45 THAI CHARACTER LAKKHANGYAO */ +#define XK_Thai_maiyamok 0x0de6 /* U+0E46 THAI CHARACTER MAIYAMOK */ +#define XK_Thai_maitaikhu 0x0de7 /* U+0E47 THAI CHARACTER MAITAIKHU */ +#define XK_Thai_maiek 0x0de8 /* U+0E48 THAI CHARACTER MAI EK */ +#define XK_Thai_maitho 0x0de9 /* U+0E49 THAI CHARACTER MAI THO */ +#define XK_Thai_maitri 0x0dea /* U+0E4A THAI CHARACTER MAI TRI */ +#define XK_Thai_maichattawa 0x0deb /* U+0E4B THAI CHARACTER MAI CHATTAWA */ +#define XK_Thai_thanthakhat 0x0dec /* U+0E4C THAI CHARACTER THANTHAKHAT */ +#define XK_Thai_nikhahit 0x0ded /* U+0E4D THAI CHARACTER NIKHAHIT */ +#define XK_Thai_leksun 0x0df0 /* U+0E50 THAI DIGIT ZERO */ +#define XK_Thai_leknung 0x0df1 /* U+0E51 THAI DIGIT ONE */ +#define XK_Thai_leksong 0x0df2 /* U+0E52 THAI DIGIT TWO */ +#define XK_Thai_leksam 0x0df3 /* U+0E53 THAI DIGIT THREE */ +#define XK_Thai_leksi 0x0df4 /* U+0E54 THAI DIGIT FOUR */ +#define XK_Thai_lekha 0x0df5 /* U+0E55 THAI DIGIT FIVE */ +#define XK_Thai_lekhok 0x0df6 /* U+0E56 THAI DIGIT SIX */ +#define XK_Thai_lekchet 0x0df7 /* U+0E57 THAI DIGIT SEVEN */ +#define XK_Thai_lekpaet 0x0df8 /* U+0E58 THAI DIGIT EIGHT */ +#define XK_Thai_lekkao 0x0df9 /* U+0E59 THAI DIGIT NINE */ +#endif /* XK_THAI */ + +/* + * Korean + * Byte 3 = 0x0e + */ + +#ifdef XK_KOREAN + +#define XK_Hangul 0xff31 /* Hangul start/stop(toggle) */ +#define XK_Hangul_Start 0xff32 /* Hangul start */ +#define XK_Hangul_End 0xff33 /* Hangul end, English start */ +#define XK_Hangul_Hanja 0xff34 /* Start Hangul->Hanja Conversion */ +#define XK_Hangul_Jamo 0xff35 /* Hangul Jamo mode */ +#define XK_Hangul_Romaja 0xff36 /* Hangul Romaja mode */ +#define XK_Hangul_Codeinput 0xff37 /* Hangul code input mode */ +#define XK_Hangul_Jeonja 0xff38 /* Jeonja mode */ +#define XK_Hangul_Banja 0xff39 /* Banja mode */ +#define XK_Hangul_PreHanja 0xff3a /* Pre Hanja conversion */ +#define XK_Hangul_PostHanja 0xff3b /* Post Hanja conversion */ +#define XK_Hangul_SingleCandidate 0xff3c /* Single candidate */ +#define XK_Hangul_MultipleCandidate 0xff3d /* Multiple candidate */ +#define XK_Hangul_PreviousCandidate 0xff3e /* Previous candidate */ +#define XK_Hangul_Special 0xff3f /* Special symbols */ +#define XK_Hangul_switch 0xff7e /* Alias for mode_switch */ + +/* Hangul Consonant Characters */ +#define XK_Hangul_Kiyeog 0x0ea1 /* U+3131 HANGUL LETTER KIYEOK */ +#define XK_Hangul_SsangKiyeog 0x0ea2 /* U+3132 HANGUL LETTER SSANGKIYEOK */ +#define XK_Hangul_KiyeogSios 0x0ea3 /* U+3133 HANGUL LETTER KIYEOK-SIOS */ +#define XK_Hangul_Nieun 0x0ea4 /* U+3134 HANGUL LETTER NIEUN */ +#define XK_Hangul_NieunJieuj 0x0ea5 /* U+3135 HANGUL LETTER NIEUN-CIEUC */ +#define XK_Hangul_NieunHieuh 0x0ea6 /* U+3136 HANGUL LETTER NIEUN-HIEUH */ +#define XK_Hangul_Dikeud 0x0ea7 /* U+3137 HANGUL LETTER TIKEUT */ +#define XK_Hangul_SsangDikeud 0x0ea8 /* U+3138 HANGUL LETTER SSANGTIKEUT */ +#define XK_Hangul_Rieul 0x0ea9 /* U+3139 HANGUL LETTER RIEUL */ +#define XK_Hangul_RieulKiyeog 0x0eaa /* U+313A HANGUL LETTER RIEUL-KIYEOK */ +#define XK_Hangul_RieulMieum 0x0eab /* U+313B HANGUL LETTER RIEUL-MIEUM */ +#define XK_Hangul_RieulPieub 0x0eac /* U+313C HANGUL LETTER RIEUL-PIEUP */ +#define XK_Hangul_RieulSios 0x0ead /* U+313D HANGUL LETTER RIEUL-SIOS */ +#define XK_Hangul_RieulTieut 0x0eae /* U+313E HANGUL LETTER RIEUL-THIEUTH */ +#define XK_Hangul_RieulPhieuf 0x0eaf /* U+313F HANGUL LETTER RIEUL-PHIEUPH */ +#define XK_Hangul_RieulHieuh 0x0eb0 /* U+3140 HANGUL LETTER RIEUL-HIEUH */ +#define XK_Hangul_Mieum 0x0eb1 /* U+3141 HANGUL LETTER MIEUM */ +#define XK_Hangul_Pieub 0x0eb2 /* U+3142 HANGUL LETTER PIEUP */ +#define XK_Hangul_SsangPieub 0x0eb3 /* U+3143 HANGUL LETTER SSANGPIEUP */ +#define XK_Hangul_PieubSios 0x0eb4 /* U+3144 HANGUL LETTER PIEUP-SIOS */ +#define XK_Hangul_Sios 0x0eb5 /* U+3145 HANGUL LETTER SIOS */ +#define XK_Hangul_SsangSios 0x0eb6 /* U+3146 HANGUL LETTER SSANGSIOS */ +#define XK_Hangul_Ieung 0x0eb7 /* U+3147 HANGUL LETTER IEUNG */ +#define XK_Hangul_Jieuj 0x0eb8 /* U+3148 HANGUL LETTER CIEUC */ +#define XK_Hangul_SsangJieuj 0x0eb9 /* U+3149 HANGUL LETTER SSANGCIEUC */ +#define XK_Hangul_Cieuc 0x0eba /* U+314A HANGUL LETTER CHIEUCH */ +#define XK_Hangul_Khieuq 0x0ebb /* U+314B HANGUL LETTER KHIEUKH */ +#define XK_Hangul_Tieut 0x0ebc /* U+314C HANGUL LETTER THIEUTH */ +#define XK_Hangul_Phieuf 0x0ebd /* U+314D HANGUL LETTER PHIEUPH */ +#define XK_Hangul_Hieuh 0x0ebe /* U+314E HANGUL LETTER HIEUH */ + +/* Hangul Vowel Characters */ +#define XK_Hangul_A 0x0ebf /* U+314F HANGUL LETTER A */ +#define XK_Hangul_AE 0x0ec0 /* U+3150 HANGUL LETTER AE */ +#define XK_Hangul_YA 0x0ec1 /* U+3151 HANGUL LETTER YA */ +#define XK_Hangul_YAE 0x0ec2 /* U+3152 HANGUL LETTER YAE */ +#define XK_Hangul_EO 0x0ec3 /* U+3153 HANGUL LETTER EO */ +#define XK_Hangul_E 0x0ec4 /* U+3154 HANGUL LETTER E */ +#define XK_Hangul_YEO 0x0ec5 /* U+3155 HANGUL LETTER YEO */ +#define XK_Hangul_YE 0x0ec6 /* U+3156 HANGUL LETTER YE */ +#define XK_Hangul_O 0x0ec7 /* U+3157 HANGUL LETTER O */ +#define XK_Hangul_WA 0x0ec8 /* U+3158 HANGUL LETTER WA */ +#define XK_Hangul_WAE 0x0ec9 /* U+3159 HANGUL LETTER WAE */ +#define XK_Hangul_OE 0x0eca /* U+315A HANGUL LETTER OE */ +#define XK_Hangul_YO 0x0ecb /* U+315B HANGUL LETTER YO */ +#define XK_Hangul_U 0x0ecc /* U+315C HANGUL LETTER U */ +#define XK_Hangul_WEO 0x0ecd /* U+315D HANGUL LETTER WEO */ +#define XK_Hangul_WE 0x0ece /* U+315E HANGUL LETTER WE */ +#define XK_Hangul_WI 0x0ecf /* U+315F HANGUL LETTER WI */ +#define XK_Hangul_YU 0x0ed0 /* U+3160 HANGUL LETTER YU */ +#define XK_Hangul_EU 0x0ed1 /* U+3161 HANGUL LETTER EU */ +#define XK_Hangul_YI 0x0ed2 /* U+3162 HANGUL LETTER YI */ +#define XK_Hangul_I 0x0ed3 /* U+3163 HANGUL LETTER I */ + +/* Hangul syllable-final (JongSeong) Characters */ +#define XK_Hangul_J_Kiyeog 0x0ed4 /* U+11A8 HANGUL JONGSEONG KIYEOK */ +#define XK_Hangul_J_SsangKiyeog 0x0ed5 /* U+11A9 HANGUL JONGSEONG SSANGKIYEOK */ +#define XK_Hangul_J_KiyeogSios 0x0ed6 /* U+11AA HANGUL JONGSEONG KIYEOK-SIOS */ +#define XK_Hangul_J_Nieun 0x0ed7 /* U+11AB HANGUL JONGSEONG NIEUN */ +#define XK_Hangul_J_NieunJieuj 0x0ed8 /* U+11AC HANGUL JONGSEONG NIEUN-CIEUC */ +#define XK_Hangul_J_NieunHieuh 0x0ed9 /* U+11AD HANGUL JONGSEONG NIEUN-HIEUH */ +#define XK_Hangul_J_Dikeud 0x0eda /* U+11AE HANGUL JONGSEONG TIKEUT */ +#define XK_Hangul_J_Rieul 0x0edb /* U+11AF HANGUL JONGSEONG RIEUL */ +#define XK_Hangul_J_RieulKiyeog 0x0edc /* U+11B0 HANGUL JONGSEONG RIEUL-KIYEOK */ +#define XK_Hangul_J_RieulMieum 0x0edd /* U+11B1 HANGUL JONGSEONG RIEUL-MIEUM */ +#define XK_Hangul_J_RieulPieub 0x0ede /* U+11B2 HANGUL JONGSEONG RIEUL-PIEUP */ +#define XK_Hangul_J_RieulSios 0x0edf /* U+11B3 HANGUL JONGSEONG RIEUL-SIOS */ +#define XK_Hangul_J_RieulTieut 0x0ee0 /* U+11B4 HANGUL JONGSEONG RIEUL-THIEUTH */ +#define XK_Hangul_J_RieulPhieuf 0x0ee1 /* U+11B5 HANGUL JONGSEONG RIEUL-PHIEUPH */ +#define XK_Hangul_J_RieulHieuh 0x0ee2 /* U+11B6 HANGUL JONGSEONG RIEUL-HIEUH */ +#define XK_Hangul_J_Mieum 0x0ee3 /* U+11B7 HANGUL JONGSEONG MIEUM */ +#define XK_Hangul_J_Pieub 0x0ee4 /* U+11B8 HANGUL JONGSEONG PIEUP */ +#define XK_Hangul_J_PieubSios 0x0ee5 /* U+11B9 HANGUL JONGSEONG PIEUP-SIOS */ +#define XK_Hangul_J_Sios 0x0ee6 /* U+11BA HANGUL JONGSEONG SIOS */ +#define XK_Hangul_J_SsangSios 0x0ee7 /* U+11BB HANGUL JONGSEONG SSANGSIOS */ +#define XK_Hangul_J_Ieung 0x0ee8 /* U+11BC HANGUL JONGSEONG IEUNG */ +#define XK_Hangul_J_Jieuj 0x0ee9 /* U+11BD HANGUL JONGSEONG CIEUC */ +#define XK_Hangul_J_Cieuc 0x0eea /* U+11BE HANGUL JONGSEONG CHIEUCH */ +#define XK_Hangul_J_Khieuq 0x0eeb /* U+11BF HANGUL JONGSEONG KHIEUKH */ +#define XK_Hangul_J_Tieut 0x0eec /* U+11C0 HANGUL JONGSEONG THIEUTH */ +#define XK_Hangul_J_Phieuf 0x0eed /* U+11C1 HANGUL JONGSEONG PHIEUPH */ +#define XK_Hangul_J_Hieuh 0x0eee /* U+11C2 HANGUL JONGSEONG HIEUH */ + +/* Ancient Hangul Consonant Characters */ +#define XK_Hangul_RieulYeorinHieuh 0x0eef /* U+316D HANGUL LETTER RIEUL-YEORINHIEUH */ +#define XK_Hangul_SunkyeongeumMieum 0x0ef0 /* U+3171 HANGUL LETTER KAPYEOUNMIEUM */ +#define XK_Hangul_SunkyeongeumPieub 0x0ef1 /* U+3178 HANGUL LETTER KAPYEOUNPIEUP */ +#define XK_Hangul_PanSios 0x0ef2 /* U+317F HANGUL LETTER PANSIOS */ +#define XK_Hangul_KkogjiDalrinIeung 0x0ef3 /* U+3181 HANGUL LETTER YESIEUNG */ +#define XK_Hangul_SunkyeongeumPhieuf 0x0ef4 /* U+3184 HANGUL LETTER KAPYEOUNPHIEUPH */ +#define XK_Hangul_YeorinHieuh 0x0ef5 /* U+3186 HANGUL LETTER YEORINHIEUH */ + +/* Ancient Hangul Vowel Characters */ +#define XK_Hangul_AraeA 0x0ef6 /* U+318D HANGUL LETTER ARAEA */ +#define XK_Hangul_AraeAE 0x0ef7 /* U+318E HANGUL LETTER ARAEAE */ + +/* Ancient Hangul syllable-final (JongSeong) Characters */ +#define XK_Hangul_J_PanSios 0x0ef8 /* U+11EB HANGUL JONGSEONG PANSIOS */ +#define XK_Hangul_J_KkogjiDalrinIeung 0x0ef9 /* U+11F0 HANGUL JONGSEONG YESIEUNG */ +#define XK_Hangul_J_YeorinHieuh 0x0efa /* U+11F9 HANGUL JONGSEONG YEORINHIEUH */ + +/* Korean currency symbol */ +#define XK_Korean_Won 0x0eff /*(U+20A9 WON SIGN)*/ + +#endif /* XK_KOREAN */ + +/* + * Armenian + */ + +#ifdef XK_ARMENIAN +#define XK_Armenian_ligature_ew 0x1000587 /* U+0587 ARMENIAN SMALL LIGATURE ECH YIWN */ +#define XK_Armenian_full_stop 0x1000589 /* U+0589 ARMENIAN FULL STOP */ +#define XK_Armenian_verjaket 0x1000589 /* U+0589 ARMENIAN FULL STOP */ +#define XK_Armenian_separation_mark 0x100055d /* U+055D ARMENIAN COMMA */ +#define XK_Armenian_but 0x100055d /* U+055D ARMENIAN COMMA */ +#define XK_Armenian_hyphen 0x100058a /* U+058A ARMENIAN HYPHEN */ +#define XK_Armenian_yentamna 0x100058a /* U+058A ARMENIAN HYPHEN */ +#define XK_Armenian_exclam 0x100055c /* U+055C ARMENIAN EXCLAMATION MARK */ +#define XK_Armenian_amanak 0x100055c /* U+055C ARMENIAN EXCLAMATION MARK */ +#define XK_Armenian_accent 0x100055b /* U+055B ARMENIAN EMPHASIS MARK */ +#define XK_Armenian_shesht 0x100055b /* U+055B ARMENIAN EMPHASIS MARK */ +#define XK_Armenian_question 0x100055e /* U+055E ARMENIAN QUESTION MARK */ +#define XK_Armenian_paruyk 0x100055e /* U+055E ARMENIAN QUESTION MARK */ +#define XK_Armenian_AYB 0x1000531 /* U+0531 ARMENIAN CAPITAL LETTER AYB */ +#define XK_Armenian_ayb 0x1000561 /* U+0561 ARMENIAN SMALL LETTER AYB */ +#define XK_Armenian_BEN 0x1000532 /* U+0532 ARMENIAN CAPITAL LETTER BEN */ +#define XK_Armenian_ben 0x1000562 /* U+0562 ARMENIAN SMALL LETTER BEN */ +#define XK_Armenian_GIM 0x1000533 /* U+0533 ARMENIAN CAPITAL LETTER GIM */ +#define XK_Armenian_gim 0x1000563 /* U+0563 ARMENIAN SMALL LETTER GIM */ +#define XK_Armenian_DA 0x1000534 /* U+0534 ARMENIAN CAPITAL LETTER DA */ +#define XK_Armenian_da 0x1000564 /* U+0564 ARMENIAN SMALL LETTER DA */ +#define XK_Armenian_YECH 0x1000535 /* U+0535 ARMENIAN CAPITAL LETTER ECH */ +#define XK_Armenian_yech 0x1000565 /* U+0565 ARMENIAN SMALL LETTER ECH */ +#define XK_Armenian_ZA 0x1000536 /* U+0536 ARMENIAN CAPITAL LETTER ZA */ +#define XK_Armenian_za 0x1000566 /* U+0566 ARMENIAN SMALL LETTER ZA */ +#define XK_Armenian_E 0x1000537 /* U+0537 ARMENIAN CAPITAL LETTER EH */ +#define XK_Armenian_e 0x1000567 /* U+0567 ARMENIAN SMALL LETTER EH */ +#define XK_Armenian_AT 0x1000538 /* U+0538 ARMENIAN CAPITAL LETTER ET */ +#define XK_Armenian_at 0x1000568 /* U+0568 ARMENIAN SMALL LETTER ET */ +#define XK_Armenian_TO 0x1000539 /* U+0539 ARMENIAN CAPITAL LETTER TO */ +#define XK_Armenian_to 0x1000569 /* U+0569 ARMENIAN SMALL LETTER TO */ +#define XK_Armenian_ZHE 0x100053a /* U+053A ARMENIAN CAPITAL LETTER ZHE */ +#define XK_Armenian_zhe 0x100056a /* U+056A ARMENIAN SMALL LETTER ZHE */ +#define XK_Armenian_INI 0x100053b /* U+053B ARMENIAN CAPITAL LETTER INI */ +#define XK_Armenian_ini 0x100056b /* U+056B ARMENIAN SMALL LETTER INI */ +#define XK_Armenian_LYUN 0x100053c /* U+053C ARMENIAN CAPITAL LETTER LIWN */ +#define XK_Armenian_lyun 0x100056c /* U+056C ARMENIAN SMALL LETTER LIWN */ +#define XK_Armenian_KHE 0x100053d /* U+053D ARMENIAN CAPITAL LETTER XEH */ +#define XK_Armenian_khe 0x100056d /* U+056D ARMENIAN SMALL LETTER XEH */ +#define XK_Armenian_TSA 0x100053e /* U+053E ARMENIAN CAPITAL LETTER CA */ +#define XK_Armenian_tsa 0x100056e /* U+056E ARMENIAN SMALL LETTER CA */ +#define XK_Armenian_KEN 0x100053f /* U+053F ARMENIAN CAPITAL LETTER KEN */ +#define XK_Armenian_ken 0x100056f /* U+056F ARMENIAN SMALL LETTER KEN */ +#define XK_Armenian_HO 0x1000540 /* U+0540 ARMENIAN CAPITAL LETTER HO */ +#define XK_Armenian_ho 0x1000570 /* U+0570 ARMENIAN SMALL LETTER HO */ +#define XK_Armenian_DZA 0x1000541 /* U+0541 ARMENIAN CAPITAL LETTER JA */ +#define XK_Armenian_dza 0x1000571 /* U+0571 ARMENIAN SMALL LETTER JA */ +#define XK_Armenian_GHAT 0x1000542 /* U+0542 ARMENIAN CAPITAL LETTER GHAD */ +#define XK_Armenian_ghat 0x1000572 /* U+0572 ARMENIAN SMALL LETTER GHAD */ +#define XK_Armenian_TCHE 0x1000543 /* U+0543 ARMENIAN CAPITAL LETTER CHEH */ +#define XK_Armenian_tche 0x1000573 /* U+0573 ARMENIAN SMALL LETTER CHEH */ +#define XK_Armenian_MEN 0x1000544 /* U+0544 ARMENIAN CAPITAL LETTER MEN */ +#define XK_Armenian_men 0x1000574 /* U+0574 ARMENIAN SMALL LETTER MEN */ +#define XK_Armenian_HI 0x1000545 /* U+0545 ARMENIAN CAPITAL LETTER YI */ +#define XK_Armenian_hi 0x1000575 /* U+0575 ARMENIAN SMALL LETTER YI */ +#define XK_Armenian_NU 0x1000546 /* U+0546 ARMENIAN CAPITAL LETTER NOW */ +#define XK_Armenian_nu 0x1000576 /* U+0576 ARMENIAN SMALL LETTER NOW */ +#define XK_Armenian_SHA 0x1000547 /* U+0547 ARMENIAN CAPITAL LETTER SHA */ +#define XK_Armenian_sha 0x1000577 /* U+0577 ARMENIAN SMALL LETTER SHA */ +#define XK_Armenian_VO 0x1000548 /* U+0548 ARMENIAN CAPITAL LETTER VO */ +#define XK_Armenian_vo 0x1000578 /* U+0578 ARMENIAN SMALL LETTER VO */ +#define XK_Armenian_CHA 0x1000549 /* U+0549 ARMENIAN CAPITAL LETTER CHA */ +#define XK_Armenian_cha 0x1000579 /* U+0579 ARMENIAN SMALL LETTER CHA */ +#define XK_Armenian_PE 0x100054a /* U+054A ARMENIAN CAPITAL LETTER PEH */ +#define XK_Armenian_pe 0x100057a /* U+057A ARMENIAN SMALL LETTER PEH */ +#define XK_Armenian_JE 0x100054b /* U+054B ARMENIAN CAPITAL LETTER JHEH */ +#define XK_Armenian_je 0x100057b /* U+057B ARMENIAN SMALL LETTER JHEH */ +#define XK_Armenian_RA 0x100054c /* U+054C ARMENIAN CAPITAL LETTER RA */ +#define XK_Armenian_ra 0x100057c /* U+057C ARMENIAN SMALL LETTER RA */ +#define XK_Armenian_SE 0x100054d /* U+054D ARMENIAN CAPITAL LETTER SEH */ +#define XK_Armenian_se 0x100057d /* U+057D ARMENIAN SMALL LETTER SEH */ +#define XK_Armenian_VEV 0x100054e /* U+054E ARMENIAN CAPITAL LETTER VEW */ +#define XK_Armenian_vev 0x100057e /* U+057E ARMENIAN SMALL LETTER VEW */ +#define XK_Armenian_TYUN 0x100054f /* U+054F ARMENIAN CAPITAL LETTER TIWN */ +#define XK_Armenian_tyun 0x100057f /* U+057F ARMENIAN SMALL LETTER TIWN */ +#define XK_Armenian_RE 0x1000550 /* U+0550 ARMENIAN CAPITAL LETTER REH */ +#define XK_Armenian_re 0x1000580 /* U+0580 ARMENIAN SMALL LETTER REH */ +#define XK_Armenian_TSO 0x1000551 /* U+0551 ARMENIAN CAPITAL LETTER CO */ +#define XK_Armenian_tso 0x1000581 /* U+0581 ARMENIAN SMALL LETTER CO */ +#define XK_Armenian_VYUN 0x1000552 /* U+0552 ARMENIAN CAPITAL LETTER YIWN */ +#define XK_Armenian_vyun 0x1000582 /* U+0582 ARMENIAN SMALL LETTER YIWN */ +#define XK_Armenian_PYUR 0x1000553 /* U+0553 ARMENIAN CAPITAL LETTER PIWR */ +#define XK_Armenian_pyur 0x1000583 /* U+0583 ARMENIAN SMALL LETTER PIWR */ +#define XK_Armenian_KE 0x1000554 /* U+0554 ARMENIAN CAPITAL LETTER KEH */ +#define XK_Armenian_ke 0x1000584 /* U+0584 ARMENIAN SMALL LETTER KEH */ +#define XK_Armenian_O 0x1000555 /* U+0555 ARMENIAN CAPITAL LETTER OH */ +#define XK_Armenian_o 0x1000585 /* U+0585 ARMENIAN SMALL LETTER OH */ +#define XK_Armenian_FE 0x1000556 /* U+0556 ARMENIAN CAPITAL LETTER FEH */ +#define XK_Armenian_fe 0x1000586 /* U+0586 ARMENIAN SMALL LETTER FEH */ +#define XK_Armenian_apostrophe 0x100055a /* U+055A ARMENIAN APOSTROPHE */ +#endif /* XK_ARMENIAN */ + +/* + * Georgian + */ + +#ifdef XK_GEORGIAN +#define XK_Georgian_an 0x10010d0 /* U+10D0 GEORGIAN LETTER AN */ +#define XK_Georgian_ban 0x10010d1 /* U+10D1 GEORGIAN LETTER BAN */ +#define XK_Georgian_gan 0x10010d2 /* U+10D2 GEORGIAN LETTER GAN */ +#define XK_Georgian_don 0x10010d3 /* U+10D3 GEORGIAN LETTER DON */ +#define XK_Georgian_en 0x10010d4 /* U+10D4 GEORGIAN LETTER EN */ +#define XK_Georgian_vin 0x10010d5 /* U+10D5 GEORGIAN LETTER VIN */ +#define XK_Georgian_zen 0x10010d6 /* U+10D6 GEORGIAN LETTER ZEN */ +#define XK_Georgian_tan 0x10010d7 /* U+10D7 GEORGIAN LETTER TAN */ +#define XK_Georgian_in 0x10010d8 /* U+10D8 GEORGIAN LETTER IN */ +#define XK_Georgian_kan 0x10010d9 /* U+10D9 GEORGIAN LETTER KAN */ +#define XK_Georgian_las 0x10010da /* U+10DA GEORGIAN LETTER LAS */ +#define XK_Georgian_man 0x10010db /* U+10DB GEORGIAN LETTER MAN */ +#define XK_Georgian_nar 0x10010dc /* U+10DC GEORGIAN LETTER NAR */ +#define XK_Georgian_on 0x10010dd /* U+10DD GEORGIAN LETTER ON */ +#define XK_Georgian_par 0x10010de /* U+10DE GEORGIAN LETTER PAR */ +#define XK_Georgian_zhar 0x10010df /* U+10DF GEORGIAN LETTER ZHAR */ +#define XK_Georgian_rae 0x10010e0 /* U+10E0 GEORGIAN LETTER RAE */ +#define XK_Georgian_san 0x10010e1 /* U+10E1 GEORGIAN LETTER SAN */ +#define XK_Georgian_tar 0x10010e2 /* U+10E2 GEORGIAN LETTER TAR */ +#define XK_Georgian_un 0x10010e3 /* U+10E3 GEORGIAN LETTER UN */ +#define XK_Georgian_phar 0x10010e4 /* U+10E4 GEORGIAN LETTER PHAR */ +#define XK_Georgian_khar 0x10010e5 /* U+10E5 GEORGIAN LETTER KHAR */ +#define XK_Georgian_ghan 0x10010e6 /* U+10E6 GEORGIAN LETTER GHAN */ +#define XK_Georgian_qar 0x10010e7 /* U+10E7 GEORGIAN LETTER QAR */ +#define XK_Georgian_shin 0x10010e8 /* U+10E8 GEORGIAN LETTER SHIN */ +#define XK_Georgian_chin 0x10010e9 /* U+10E9 GEORGIAN LETTER CHIN */ +#define XK_Georgian_can 0x10010ea /* U+10EA GEORGIAN LETTER CAN */ +#define XK_Georgian_jil 0x10010eb /* U+10EB GEORGIAN LETTER JIL */ +#define XK_Georgian_cil 0x10010ec /* U+10EC GEORGIAN LETTER CIL */ +#define XK_Georgian_char 0x10010ed /* U+10ED GEORGIAN LETTER CHAR */ +#define XK_Georgian_xan 0x10010ee /* U+10EE GEORGIAN LETTER XAN */ +#define XK_Georgian_jhan 0x10010ef /* U+10EF GEORGIAN LETTER JHAN */ +#define XK_Georgian_hae 0x10010f0 /* U+10F0 GEORGIAN LETTER HAE */ +#define XK_Georgian_he 0x10010f1 /* U+10F1 GEORGIAN LETTER HE */ +#define XK_Georgian_hie 0x10010f2 /* U+10F2 GEORGIAN LETTER HIE */ +#define XK_Georgian_we 0x10010f3 /* U+10F3 GEORGIAN LETTER WE */ +#define XK_Georgian_har 0x10010f4 /* U+10F4 GEORGIAN LETTER HAR */ +#define XK_Georgian_hoe 0x10010f5 /* U+10F5 GEORGIAN LETTER HOE */ +#define XK_Georgian_fi 0x10010f6 /* U+10F6 GEORGIAN LETTER FI */ +#endif /* XK_GEORGIAN */ + +/* + * Azeri (and other Turkic or Caucasian languages) + */ + +#ifdef XK_CAUCASUS +/* latin */ +#define XK_Xabovedot 0x1001e8a /* U+1E8A LATIN CAPITAL LETTER X WITH DOT ABOVE */ +#define XK_Ibreve 0x100012c /* U+012C LATIN CAPITAL LETTER I WITH BREVE */ +#define XK_Zstroke 0x10001b5 /* U+01B5 LATIN CAPITAL LETTER Z WITH STROKE */ +#define XK_Gcaron 0x10001e6 /* U+01E6 LATIN CAPITAL LETTER G WITH CARON */ +#define XK_Ocaron 0x10001d1 /* U+01D1 LATIN CAPITAL LETTER O WITH CARON */ +#define XK_Obarred 0x100019f /* U+019F LATIN CAPITAL LETTER O WITH MIDDLE TILDE */ +#define XK_xabovedot 0x1001e8b /* U+1E8B LATIN SMALL LETTER X WITH DOT ABOVE */ +#define XK_ibreve 0x100012d /* U+012D LATIN SMALL LETTER I WITH BREVE */ +#define XK_zstroke 0x10001b6 /* U+01B6 LATIN SMALL LETTER Z WITH STROKE */ +#define XK_gcaron 0x10001e7 /* U+01E7 LATIN SMALL LETTER G WITH CARON */ +#define XK_ocaron 0x10001d2 /* U+01D2 LATIN SMALL LETTER O WITH CARON */ +#define XK_obarred 0x1000275 /* U+0275 LATIN SMALL LETTER BARRED O */ +#define XK_SCHWA 0x100018f /* U+018F LATIN CAPITAL LETTER SCHWA */ +#define XK_schwa 0x1000259 /* U+0259 LATIN SMALL LETTER SCHWA */ +#define XK_EZH 0x10001b7 /* U+01B7 LATIN CAPITAL LETTER EZH */ +#define XK_ezh 0x1000292 /* U+0292 LATIN SMALL LETTER EZH */ +/* those are not really Caucasus */ +/* For Inupiak */ +#define XK_Lbelowdot 0x1001e36 /* U+1E36 LATIN CAPITAL LETTER L WITH DOT BELOW */ +#define XK_lbelowdot 0x1001e37 /* U+1E37 LATIN SMALL LETTER L WITH DOT BELOW */ +#endif /* XK_CAUCASUS */ + +/* + * Vietnamese + */ + +#ifdef XK_VIETNAMESE +#define XK_Abelowdot 0x1001ea0 /* U+1EA0 LATIN CAPITAL LETTER A WITH DOT BELOW */ +#define XK_abelowdot 0x1001ea1 /* U+1EA1 LATIN SMALL LETTER A WITH DOT BELOW */ +#define XK_Ahook 0x1001ea2 /* U+1EA2 LATIN CAPITAL LETTER A WITH HOOK ABOVE */ +#define XK_ahook 0x1001ea3 /* U+1EA3 LATIN SMALL LETTER A WITH HOOK ABOVE */ +#define XK_Acircumflexacute 0x1001ea4 /* U+1EA4 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE */ +#define XK_acircumflexacute 0x1001ea5 /* U+1EA5 LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE */ +#define XK_Acircumflexgrave 0x1001ea6 /* U+1EA6 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE */ +#define XK_acircumflexgrave 0x1001ea7 /* U+1EA7 LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE */ +#define XK_Acircumflexhook 0x1001ea8 /* U+1EA8 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */ +#define XK_acircumflexhook 0x1001ea9 /* U+1EA9 LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */ +#define XK_Acircumflextilde 0x1001eaa /* U+1EAA LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE */ +#define XK_acircumflextilde 0x1001eab /* U+1EAB LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE */ +#define XK_Acircumflexbelowdot 0x1001eac /* U+1EAC LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW */ +#define XK_acircumflexbelowdot 0x1001ead /* U+1EAD LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW */ +#define XK_Abreveacute 0x1001eae /* U+1EAE LATIN CAPITAL LETTER A WITH BREVE AND ACUTE */ +#define XK_abreveacute 0x1001eaf /* U+1EAF LATIN SMALL LETTER A WITH BREVE AND ACUTE */ +#define XK_Abrevegrave 0x1001eb0 /* U+1EB0 LATIN CAPITAL LETTER A WITH BREVE AND GRAVE */ +#define XK_abrevegrave 0x1001eb1 /* U+1EB1 LATIN SMALL LETTER A WITH BREVE AND GRAVE */ +#define XK_Abrevehook 0x1001eb2 /* U+1EB2 LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE */ +#define XK_abrevehook 0x1001eb3 /* U+1EB3 LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE */ +#define XK_Abrevetilde 0x1001eb4 /* U+1EB4 LATIN CAPITAL LETTER A WITH BREVE AND TILDE */ +#define XK_abrevetilde 0x1001eb5 /* U+1EB5 LATIN SMALL LETTER A WITH BREVE AND TILDE */ +#define XK_Abrevebelowdot 0x1001eb6 /* U+1EB6 LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW */ +#define XK_abrevebelowdot 0x1001eb7 /* U+1EB7 LATIN SMALL LETTER A WITH BREVE AND DOT BELOW */ +#define XK_Ebelowdot 0x1001eb8 /* U+1EB8 LATIN CAPITAL LETTER E WITH DOT BELOW */ +#define XK_ebelowdot 0x1001eb9 /* U+1EB9 LATIN SMALL LETTER E WITH DOT BELOW */ +#define XK_Ehook 0x1001eba /* U+1EBA LATIN CAPITAL LETTER E WITH HOOK ABOVE */ +#define XK_ehook 0x1001ebb /* U+1EBB LATIN SMALL LETTER E WITH HOOK ABOVE */ +#define XK_Etilde 0x1001ebc /* U+1EBC LATIN CAPITAL LETTER E WITH TILDE */ +#define XK_etilde 0x1001ebd /* U+1EBD LATIN SMALL LETTER E WITH TILDE */ +#define XK_Ecircumflexacute 0x1001ebe /* U+1EBE LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE */ +#define XK_ecircumflexacute 0x1001ebf /* U+1EBF LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE */ +#define XK_Ecircumflexgrave 0x1001ec0 /* U+1EC0 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE */ +#define XK_ecircumflexgrave 0x1001ec1 /* U+1EC1 LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE */ +#define XK_Ecircumflexhook 0x1001ec2 /* U+1EC2 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */ +#define XK_ecircumflexhook 0x1001ec3 /* U+1EC3 LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */ +#define XK_Ecircumflextilde 0x1001ec4 /* U+1EC4 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE */ +#define XK_ecircumflextilde 0x1001ec5 /* U+1EC5 LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE */ +#define XK_Ecircumflexbelowdot 0x1001ec6 /* U+1EC6 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW */ +#define XK_ecircumflexbelowdot 0x1001ec7 /* U+1EC7 LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW */ +#define XK_Ihook 0x1001ec8 /* U+1EC8 LATIN CAPITAL LETTER I WITH HOOK ABOVE */ +#define XK_ihook 0x1001ec9 /* U+1EC9 LATIN SMALL LETTER I WITH HOOK ABOVE */ +#define XK_Ibelowdot 0x1001eca /* U+1ECA LATIN CAPITAL LETTER I WITH DOT BELOW */ +#define XK_ibelowdot 0x1001ecb /* U+1ECB LATIN SMALL LETTER I WITH DOT BELOW */ +#define XK_Obelowdot 0x1001ecc /* U+1ECC LATIN CAPITAL LETTER O WITH DOT BELOW */ +#define XK_obelowdot 0x1001ecd /* U+1ECD LATIN SMALL LETTER O WITH DOT BELOW */ +#define XK_Ohook 0x1001ece /* U+1ECE LATIN CAPITAL LETTER O WITH HOOK ABOVE */ +#define XK_ohook 0x1001ecf /* U+1ECF LATIN SMALL LETTER O WITH HOOK ABOVE */ +#define XK_Ocircumflexacute 0x1001ed0 /* U+1ED0 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE */ +#define XK_ocircumflexacute 0x1001ed1 /* U+1ED1 LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE */ +#define XK_Ocircumflexgrave 0x1001ed2 /* U+1ED2 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE */ +#define XK_ocircumflexgrave 0x1001ed3 /* U+1ED3 LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE */ +#define XK_Ocircumflexhook 0x1001ed4 /* U+1ED4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */ +#define XK_ocircumflexhook 0x1001ed5 /* U+1ED5 LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */ +#define XK_Ocircumflextilde 0x1001ed6 /* U+1ED6 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE */ +#define XK_ocircumflextilde 0x1001ed7 /* U+1ED7 LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE */ +#define XK_Ocircumflexbelowdot 0x1001ed8 /* U+1ED8 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW */ +#define XK_ocircumflexbelowdot 0x1001ed9 /* U+1ED9 LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW */ +#define XK_Ohornacute 0x1001eda /* U+1EDA LATIN CAPITAL LETTER O WITH HORN AND ACUTE */ +#define XK_ohornacute 0x1001edb /* U+1EDB LATIN SMALL LETTER O WITH HORN AND ACUTE */ +#define XK_Ohorngrave 0x1001edc /* U+1EDC LATIN CAPITAL LETTER O WITH HORN AND GRAVE */ +#define XK_ohorngrave 0x1001edd /* U+1EDD LATIN SMALL LETTER O WITH HORN AND GRAVE */ +#define XK_Ohornhook 0x1001ede /* U+1EDE LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE */ +#define XK_ohornhook 0x1001edf /* U+1EDF LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE */ +#define XK_Ohorntilde 0x1001ee0 /* U+1EE0 LATIN CAPITAL LETTER O WITH HORN AND TILDE */ +#define XK_ohorntilde 0x1001ee1 /* U+1EE1 LATIN SMALL LETTER O WITH HORN AND TILDE */ +#define XK_Ohornbelowdot 0x1001ee2 /* U+1EE2 LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW */ +#define XK_ohornbelowdot 0x1001ee3 /* U+1EE3 LATIN SMALL LETTER O WITH HORN AND DOT BELOW */ +#define XK_Ubelowdot 0x1001ee4 /* U+1EE4 LATIN CAPITAL LETTER U WITH DOT BELOW */ +#define XK_ubelowdot 0x1001ee5 /* U+1EE5 LATIN SMALL LETTER U WITH DOT BELOW */ +#define XK_Uhook 0x1001ee6 /* U+1EE6 LATIN CAPITAL LETTER U WITH HOOK ABOVE */ +#define XK_uhook 0x1001ee7 /* U+1EE7 LATIN SMALL LETTER U WITH HOOK ABOVE */ +#define XK_Uhornacute 0x1001ee8 /* U+1EE8 LATIN CAPITAL LETTER U WITH HORN AND ACUTE */ +#define XK_uhornacute 0x1001ee9 /* U+1EE9 LATIN SMALL LETTER U WITH HORN AND ACUTE */ +#define XK_Uhorngrave 0x1001eea /* U+1EEA LATIN CAPITAL LETTER U WITH HORN AND GRAVE */ +#define XK_uhorngrave 0x1001eeb /* U+1EEB LATIN SMALL LETTER U WITH HORN AND GRAVE */ +#define XK_Uhornhook 0x1001eec /* U+1EEC LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE */ +#define XK_uhornhook 0x1001eed /* U+1EED LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE */ +#define XK_Uhorntilde 0x1001eee /* U+1EEE LATIN CAPITAL LETTER U WITH HORN AND TILDE */ +#define XK_uhorntilde 0x1001eef /* U+1EEF LATIN SMALL LETTER U WITH HORN AND TILDE */ +#define XK_Uhornbelowdot 0x1001ef0 /* U+1EF0 LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW */ +#define XK_uhornbelowdot 0x1001ef1 /* U+1EF1 LATIN SMALL LETTER U WITH HORN AND DOT BELOW */ +#define XK_Ybelowdot 0x1001ef4 /* U+1EF4 LATIN CAPITAL LETTER Y WITH DOT BELOW */ +#define XK_ybelowdot 0x1001ef5 /* U+1EF5 LATIN SMALL LETTER Y WITH DOT BELOW */ +#define XK_Yhook 0x1001ef6 /* U+1EF6 LATIN CAPITAL LETTER Y WITH HOOK ABOVE */ +#define XK_yhook 0x1001ef7 /* U+1EF7 LATIN SMALL LETTER Y WITH HOOK ABOVE */ +#define XK_Ytilde 0x1001ef8 /* U+1EF8 LATIN CAPITAL LETTER Y WITH TILDE */ +#define XK_ytilde 0x1001ef9 /* U+1EF9 LATIN SMALL LETTER Y WITH TILDE */ +#define XK_Ohorn 0x10001a0 /* U+01A0 LATIN CAPITAL LETTER O WITH HORN */ +#define XK_ohorn 0x10001a1 /* U+01A1 LATIN SMALL LETTER O WITH HORN */ +#define XK_Uhorn 0x10001af /* U+01AF LATIN CAPITAL LETTER U WITH HORN */ +#define XK_uhorn 0x10001b0 /* U+01B0 LATIN SMALL LETTER U WITH HORN */ +#define XK_combining_tilde 0x1000303 /* U+0303 COMBINING TILDE */ +#define XK_combining_grave 0x1000300 /* U+0300 COMBINING GRAVE ACCENT */ +#define XK_combining_acute 0x1000301 /* U+0301 COMBINING ACUTE ACCENT */ +#define XK_combining_hook 0x1000309 /* U+0309 COMBINING HOOK ABOVE */ +#define XK_combining_belowdot 0x1000323 /* U+0323 COMBINING DOT BELOW */ + +#endif /* XK_VIETNAMESE */ + +#ifdef XK_CURRENCY +#define XK_EcuSign 0x10020a0 /* U+20A0 EURO-CURRENCY SIGN */ +#define XK_ColonSign 0x10020a1 /* U+20A1 COLON SIGN */ +#define XK_CruzeiroSign 0x10020a2 /* U+20A2 CRUZEIRO SIGN */ +#define XK_FFrancSign 0x10020a3 /* U+20A3 FRENCH FRANC SIGN */ +#define XK_LiraSign 0x10020a4 /* U+20A4 LIRA SIGN */ +#define XK_MillSign 0x10020a5 /* U+20A5 MILL SIGN */ +#define XK_NairaSign 0x10020a6 /* U+20A6 NAIRA SIGN */ +#define XK_PesetaSign 0x10020a7 /* U+20A7 PESETA SIGN */ +#define XK_RupeeSign 0x10020a8 /* U+20A8 RUPEE SIGN */ +#define XK_WonSign 0x10020a9 /* U+20A9 WON SIGN */ +#define XK_NewSheqelSign 0x10020aa /* U+20AA NEW SHEQEL SIGN */ +#define XK_DongSign 0x10020ab /* U+20AB DONG SIGN */ +#define XK_EuroSign 0x20ac /* U+20AC EURO SIGN */ +#endif /* XK_CURRENCY */ + +#ifdef XK_MATHEMATICAL +/* one, two and three are defined above. */ +#define XK_zerosuperior 0x1002070 /* U+2070 SUPERSCRIPT ZERO */ +#define XK_foursuperior 0x1002074 /* U+2074 SUPERSCRIPT FOUR */ +#define XK_fivesuperior 0x1002075 /* U+2075 SUPERSCRIPT FIVE */ +#define XK_sixsuperior 0x1002076 /* U+2076 SUPERSCRIPT SIX */ +#define XK_sevensuperior 0x1002077 /* U+2077 SUPERSCRIPT SEVEN */ +#define XK_eightsuperior 0x1002078 /* U+2078 SUPERSCRIPT EIGHT */ +#define XK_ninesuperior 0x1002079 /* U+2079 SUPERSCRIPT NINE */ +#define XK_zerosubscript 0x1002080 /* U+2080 SUBSCRIPT ZERO */ +#define XK_onesubscript 0x1002081 /* U+2081 SUBSCRIPT ONE */ +#define XK_twosubscript 0x1002082 /* U+2082 SUBSCRIPT TWO */ +#define XK_threesubscript 0x1002083 /* U+2083 SUBSCRIPT THREE */ +#define XK_foursubscript 0x1002084 /* U+2084 SUBSCRIPT FOUR */ +#define XK_fivesubscript 0x1002085 /* U+2085 SUBSCRIPT FIVE */ +#define XK_sixsubscript 0x1002086 /* U+2086 SUBSCRIPT SIX */ +#define XK_sevensubscript 0x1002087 /* U+2087 SUBSCRIPT SEVEN */ +#define XK_eightsubscript 0x1002088 /* U+2088 SUBSCRIPT EIGHT */ +#define XK_ninesubscript 0x1002089 /* U+2089 SUBSCRIPT NINE */ +#define XK_partdifferential 0x1002202 /* U+2202 PARTIAL DIFFERENTIAL */ +#define XK_emptyset 0x1002205 /* U+2205 NULL SET */ +#define XK_elementof 0x1002208 /* U+2208 ELEMENT OF */ +#define XK_notelementof 0x1002209 /* U+2209 NOT AN ELEMENT OF */ +#define XK_containsas 0x100220B /* U+220B CONTAINS AS MEMBER */ +#define XK_squareroot 0x100221A /* U+221A SQUARE ROOT */ +#define XK_cuberoot 0x100221B /* U+221B CUBE ROOT */ +#define XK_fourthroot 0x100221C /* U+221C FOURTH ROOT */ +#define XK_dintegral 0x100222C /* U+222C DOUBLE INTEGRAL */ +#define XK_tintegral 0x100222D /* U+222D TRIPLE INTEGRAL */ +#define XK_because 0x1002235 /* U+2235 BECAUSE */ +#define XK_approxeq 0x1002248 /*(U+2248 ALMOST EQUAL TO)*/ +#define XK_notapproxeq 0x1002247 /*(U+2247 NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO)*/ +#define XK_notidentical 0x1002262 /* U+2262 NOT IDENTICAL TO */ +#define XK_stricteq 0x1002263 /* U+2263 STRICTLY EQUIVALENT TO */ +#endif /* XK_MATHEMATICAL */ + +#ifdef XK_BRAILLE +#define XK_braille_dot_1 0xfff1 +#define XK_braille_dot_2 0xfff2 +#define XK_braille_dot_3 0xfff3 +#define XK_braille_dot_4 0xfff4 +#define XK_braille_dot_5 0xfff5 +#define XK_braille_dot_6 0xfff6 +#define XK_braille_dot_7 0xfff7 +#define XK_braille_dot_8 0xfff8 +#define XK_braille_dot_9 0xfff9 +#define XK_braille_dot_10 0xfffa +#define XK_braille_blank 0x1002800 /* U+2800 BRAILLE PATTERN BLANK */ +#define XK_braille_dots_1 0x1002801 /* U+2801 BRAILLE PATTERN DOTS-1 */ +#define XK_braille_dots_2 0x1002802 /* U+2802 BRAILLE PATTERN DOTS-2 */ +#define XK_braille_dots_12 0x1002803 /* U+2803 BRAILLE PATTERN DOTS-12 */ +#define XK_braille_dots_3 0x1002804 /* U+2804 BRAILLE PATTERN DOTS-3 */ +#define XK_braille_dots_13 0x1002805 /* U+2805 BRAILLE PATTERN DOTS-13 */ +#define XK_braille_dots_23 0x1002806 /* U+2806 BRAILLE PATTERN DOTS-23 */ +#define XK_braille_dots_123 0x1002807 /* U+2807 BRAILLE PATTERN DOTS-123 */ +#define XK_braille_dots_4 0x1002808 /* U+2808 BRAILLE PATTERN DOTS-4 */ +#define XK_braille_dots_14 0x1002809 /* U+2809 BRAILLE PATTERN DOTS-14 */ +#define XK_braille_dots_24 0x100280a /* U+280a BRAILLE PATTERN DOTS-24 */ +#define XK_braille_dots_124 0x100280b /* U+280b BRAILLE PATTERN DOTS-124 */ +#define XK_braille_dots_34 0x100280c /* U+280c BRAILLE PATTERN DOTS-34 */ +#define XK_braille_dots_134 0x100280d /* U+280d BRAILLE PATTERN DOTS-134 */ +#define XK_braille_dots_234 0x100280e /* U+280e BRAILLE PATTERN DOTS-234 */ +#define XK_braille_dots_1234 0x100280f /* U+280f BRAILLE PATTERN DOTS-1234 */ +#define XK_braille_dots_5 0x1002810 /* U+2810 BRAILLE PATTERN DOTS-5 */ +#define XK_braille_dots_15 0x1002811 /* U+2811 BRAILLE PATTERN DOTS-15 */ +#define XK_braille_dots_25 0x1002812 /* U+2812 BRAILLE PATTERN DOTS-25 */ +#define XK_braille_dots_125 0x1002813 /* U+2813 BRAILLE PATTERN DOTS-125 */ +#define XK_braille_dots_35 0x1002814 /* U+2814 BRAILLE PATTERN DOTS-35 */ +#define XK_braille_dots_135 0x1002815 /* U+2815 BRAILLE PATTERN DOTS-135 */ +#define XK_braille_dots_235 0x1002816 /* U+2816 BRAILLE PATTERN DOTS-235 */ +#define XK_braille_dots_1235 0x1002817 /* U+2817 BRAILLE PATTERN DOTS-1235 */ +#define XK_braille_dots_45 0x1002818 /* U+2818 BRAILLE PATTERN DOTS-45 */ +#define XK_braille_dots_145 0x1002819 /* U+2819 BRAILLE PATTERN DOTS-145 */ +#define XK_braille_dots_245 0x100281a /* U+281a BRAILLE PATTERN DOTS-245 */ +#define XK_braille_dots_1245 0x100281b /* U+281b BRAILLE PATTERN DOTS-1245 */ +#define XK_braille_dots_345 0x100281c /* U+281c BRAILLE PATTERN DOTS-345 */ +#define XK_braille_dots_1345 0x100281d /* U+281d BRAILLE PATTERN DOTS-1345 */ +#define XK_braille_dots_2345 0x100281e /* U+281e BRAILLE PATTERN DOTS-2345 */ +#define XK_braille_dots_12345 0x100281f /* U+281f BRAILLE PATTERN DOTS-12345 */ +#define XK_braille_dots_6 0x1002820 /* U+2820 BRAILLE PATTERN DOTS-6 */ +#define XK_braille_dots_16 0x1002821 /* U+2821 BRAILLE PATTERN DOTS-16 */ +#define XK_braille_dots_26 0x1002822 /* U+2822 BRAILLE PATTERN DOTS-26 */ +#define XK_braille_dots_126 0x1002823 /* U+2823 BRAILLE PATTERN DOTS-126 */ +#define XK_braille_dots_36 0x1002824 /* U+2824 BRAILLE PATTERN DOTS-36 */ +#define XK_braille_dots_136 0x1002825 /* U+2825 BRAILLE PATTERN DOTS-136 */ +#define XK_braille_dots_236 0x1002826 /* U+2826 BRAILLE PATTERN DOTS-236 */ +#define XK_braille_dots_1236 0x1002827 /* U+2827 BRAILLE PATTERN DOTS-1236 */ +#define XK_braille_dots_46 0x1002828 /* U+2828 BRAILLE PATTERN DOTS-46 */ +#define XK_braille_dots_146 0x1002829 /* U+2829 BRAILLE PATTERN DOTS-146 */ +#define XK_braille_dots_246 0x100282a /* U+282a BRAILLE PATTERN DOTS-246 */ +#define XK_braille_dots_1246 0x100282b /* U+282b BRAILLE PATTERN DOTS-1246 */ +#define XK_braille_dots_346 0x100282c /* U+282c BRAILLE PATTERN DOTS-346 */ +#define XK_braille_dots_1346 0x100282d /* U+282d BRAILLE PATTERN DOTS-1346 */ +#define XK_braille_dots_2346 0x100282e /* U+282e BRAILLE PATTERN DOTS-2346 */ +#define XK_braille_dots_12346 0x100282f /* U+282f BRAILLE PATTERN DOTS-12346 */ +#define XK_braille_dots_56 0x1002830 /* U+2830 BRAILLE PATTERN DOTS-56 */ +#define XK_braille_dots_156 0x1002831 /* U+2831 BRAILLE PATTERN DOTS-156 */ +#define XK_braille_dots_256 0x1002832 /* U+2832 BRAILLE PATTERN DOTS-256 */ +#define XK_braille_dots_1256 0x1002833 /* U+2833 BRAILLE PATTERN DOTS-1256 */ +#define XK_braille_dots_356 0x1002834 /* U+2834 BRAILLE PATTERN DOTS-356 */ +#define XK_braille_dots_1356 0x1002835 /* U+2835 BRAILLE PATTERN DOTS-1356 */ +#define XK_braille_dots_2356 0x1002836 /* U+2836 BRAILLE PATTERN DOTS-2356 */ +#define XK_braille_dots_12356 0x1002837 /* U+2837 BRAILLE PATTERN DOTS-12356 */ +#define XK_braille_dots_456 0x1002838 /* U+2838 BRAILLE PATTERN DOTS-456 */ +#define XK_braille_dots_1456 0x1002839 /* U+2839 BRAILLE PATTERN DOTS-1456 */ +#define XK_braille_dots_2456 0x100283a /* U+283a BRAILLE PATTERN DOTS-2456 */ +#define XK_braille_dots_12456 0x100283b /* U+283b BRAILLE PATTERN DOTS-12456 */ +#define XK_braille_dots_3456 0x100283c /* U+283c BRAILLE PATTERN DOTS-3456 */ +#define XK_braille_dots_13456 0x100283d /* U+283d BRAILLE PATTERN DOTS-13456 */ +#define XK_braille_dots_23456 0x100283e /* U+283e BRAILLE PATTERN DOTS-23456 */ +#define XK_braille_dots_123456 0x100283f /* U+283f BRAILLE PATTERN DOTS-123456 */ +#define XK_braille_dots_7 0x1002840 /* U+2840 BRAILLE PATTERN DOTS-7 */ +#define XK_braille_dots_17 0x1002841 /* U+2841 BRAILLE PATTERN DOTS-17 */ +#define XK_braille_dots_27 0x1002842 /* U+2842 BRAILLE PATTERN DOTS-27 */ +#define XK_braille_dots_127 0x1002843 /* U+2843 BRAILLE PATTERN DOTS-127 */ +#define XK_braille_dots_37 0x1002844 /* U+2844 BRAILLE PATTERN DOTS-37 */ +#define XK_braille_dots_137 0x1002845 /* U+2845 BRAILLE PATTERN DOTS-137 */ +#define XK_braille_dots_237 0x1002846 /* U+2846 BRAILLE PATTERN DOTS-237 */ +#define XK_braille_dots_1237 0x1002847 /* U+2847 BRAILLE PATTERN DOTS-1237 */ +#define XK_braille_dots_47 0x1002848 /* U+2848 BRAILLE PATTERN DOTS-47 */ +#define XK_braille_dots_147 0x1002849 /* U+2849 BRAILLE PATTERN DOTS-147 */ +#define XK_braille_dots_247 0x100284a /* U+284a BRAILLE PATTERN DOTS-247 */ +#define XK_braille_dots_1247 0x100284b /* U+284b BRAILLE PATTERN DOTS-1247 */ +#define XK_braille_dots_347 0x100284c /* U+284c BRAILLE PATTERN DOTS-347 */ +#define XK_braille_dots_1347 0x100284d /* U+284d BRAILLE PATTERN DOTS-1347 */ +#define XK_braille_dots_2347 0x100284e /* U+284e BRAILLE PATTERN DOTS-2347 */ +#define XK_braille_dots_12347 0x100284f /* U+284f BRAILLE PATTERN DOTS-12347 */ +#define XK_braille_dots_57 0x1002850 /* U+2850 BRAILLE PATTERN DOTS-57 */ +#define XK_braille_dots_157 0x1002851 /* U+2851 BRAILLE PATTERN DOTS-157 */ +#define XK_braille_dots_257 0x1002852 /* U+2852 BRAILLE PATTERN DOTS-257 */ +#define XK_braille_dots_1257 0x1002853 /* U+2853 BRAILLE PATTERN DOTS-1257 */ +#define XK_braille_dots_357 0x1002854 /* U+2854 BRAILLE PATTERN DOTS-357 */ +#define XK_braille_dots_1357 0x1002855 /* U+2855 BRAILLE PATTERN DOTS-1357 */ +#define XK_braille_dots_2357 0x1002856 /* U+2856 BRAILLE PATTERN DOTS-2357 */ +#define XK_braille_dots_12357 0x1002857 /* U+2857 BRAILLE PATTERN DOTS-12357 */ +#define XK_braille_dots_457 0x1002858 /* U+2858 BRAILLE PATTERN DOTS-457 */ +#define XK_braille_dots_1457 0x1002859 /* U+2859 BRAILLE PATTERN DOTS-1457 */ +#define XK_braille_dots_2457 0x100285a /* U+285a BRAILLE PATTERN DOTS-2457 */ +#define XK_braille_dots_12457 0x100285b /* U+285b BRAILLE PATTERN DOTS-12457 */ +#define XK_braille_dots_3457 0x100285c /* U+285c BRAILLE PATTERN DOTS-3457 */ +#define XK_braille_dots_13457 0x100285d /* U+285d BRAILLE PATTERN DOTS-13457 */ +#define XK_braille_dots_23457 0x100285e /* U+285e BRAILLE PATTERN DOTS-23457 */ +#define XK_braille_dots_123457 0x100285f /* U+285f BRAILLE PATTERN DOTS-123457 */ +#define XK_braille_dots_67 0x1002860 /* U+2860 BRAILLE PATTERN DOTS-67 */ +#define XK_braille_dots_167 0x1002861 /* U+2861 BRAILLE PATTERN DOTS-167 */ +#define XK_braille_dots_267 0x1002862 /* U+2862 BRAILLE PATTERN DOTS-267 */ +#define XK_braille_dots_1267 0x1002863 /* U+2863 BRAILLE PATTERN DOTS-1267 */ +#define XK_braille_dots_367 0x1002864 /* U+2864 BRAILLE PATTERN DOTS-367 */ +#define XK_braille_dots_1367 0x1002865 /* U+2865 BRAILLE PATTERN DOTS-1367 */ +#define XK_braille_dots_2367 0x1002866 /* U+2866 BRAILLE PATTERN DOTS-2367 */ +#define XK_braille_dots_12367 0x1002867 /* U+2867 BRAILLE PATTERN DOTS-12367 */ +#define XK_braille_dots_467 0x1002868 /* U+2868 BRAILLE PATTERN DOTS-467 */ +#define XK_braille_dots_1467 0x1002869 /* U+2869 BRAILLE PATTERN DOTS-1467 */ +#define XK_braille_dots_2467 0x100286a /* U+286a BRAILLE PATTERN DOTS-2467 */ +#define XK_braille_dots_12467 0x100286b /* U+286b BRAILLE PATTERN DOTS-12467 */ +#define XK_braille_dots_3467 0x100286c /* U+286c BRAILLE PATTERN DOTS-3467 */ +#define XK_braille_dots_13467 0x100286d /* U+286d BRAILLE PATTERN DOTS-13467 */ +#define XK_braille_dots_23467 0x100286e /* U+286e BRAILLE PATTERN DOTS-23467 */ +#define XK_braille_dots_123467 0x100286f /* U+286f BRAILLE PATTERN DOTS-123467 */ +#define XK_braille_dots_567 0x1002870 /* U+2870 BRAILLE PATTERN DOTS-567 */ +#define XK_braille_dots_1567 0x1002871 /* U+2871 BRAILLE PATTERN DOTS-1567 */ +#define XK_braille_dots_2567 0x1002872 /* U+2872 BRAILLE PATTERN DOTS-2567 */ +#define XK_braille_dots_12567 0x1002873 /* U+2873 BRAILLE PATTERN DOTS-12567 */ +#define XK_braille_dots_3567 0x1002874 /* U+2874 BRAILLE PATTERN DOTS-3567 */ +#define XK_braille_dots_13567 0x1002875 /* U+2875 BRAILLE PATTERN DOTS-13567 */ +#define XK_braille_dots_23567 0x1002876 /* U+2876 BRAILLE PATTERN DOTS-23567 */ +#define XK_braille_dots_123567 0x1002877 /* U+2877 BRAILLE PATTERN DOTS-123567 */ +#define XK_braille_dots_4567 0x1002878 /* U+2878 BRAILLE PATTERN DOTS-4567 */ +#define XK_braille_dots_14567 0x1002879 /* U+2879 BRAILLE PATTERN DOTS-14567 */ +#define XK_braille_dots_24567 0x100287a /* U+287a BRAILLE PATTERN DOTS-24567 */ +#define XK_braille_dots_124567 0x100287b /* U+287b BRAILLE PATTERN DOTS-124567 */ +#define XK_braille_dots_34567 0x100287c /* U+287c BRAILLE PATTERN DOTS-34567 */ +#define XK_braille_dots_134567 0x100287d /* U+287d BRAILLE PATTERN DOTS-134567 */ +#define XK_braille_dots_234567 0x100287e /* U+287e BRAILLE PATTERN DOTS-234567 */ +#define XK_braille_dots_1234567 0x100287f /* U+287f BRAILLE PATTERN DOTS-1234567 */ +#define XK_braille_dots_8 0x1002880 /* U+2880 BRAILLE PATTERN DOTS-8 */ +#define XK_braille_dots_18 0x1002881 /* U+2881 BRAILLE PATTERN DOTS-18 */ +#define XK_braille_dots_28 0x1002882 /* U+2882 BRAILLE PATTERN DOTS-28 */ +#define XK_braille_dots_128 0x1002883 /* U+2883 BRAILLE PATTERN DOTS-128 */ +#define XK_braille_dots_38 0x1002884 /* U+2884 BRAILLE PATTERN DOTS-38 */ +#define XK_braille_dots_138 0x1002885 /* U+2885 BRAILLE PATTERN DOTS-138 */ +#define XK_braille_dots_238 0x1002886 /* U+2886 BRAILLE PATTERN DOTS-238 */ +#define XK_braille_dots_1238 0x1002887 /* U+2887 BRAILLE PATTERN DOTS-1238 */ +#define XK_braille_dots_48 0x1002888 /* U+2888 BRAILLE PATTERN DOTS-48 */ +#define XK_braille_dots_148 0x1002889 /* U+2889 BRAILLE PATTERN DOTS-148 */ +#define XK_braille_dots_248 0x100288a /* U+288a BRAILLE PATTERN DOTS-248 */ +#define XK_braille_dots_1248 0x100288b /* U+288b BRAILLE PATTERN DOTS-1248 */ +#define XK_braille_dots_348 0x100288c /* U+288c BRAILLE PATTERN DOTS-348 */ +#define XK_braille_dots_1348 0x100288d /* U+288d BRAILLE PATTERN DOTS-1348 */ +#define XK_braille_dots_2348 0x100288e /* U+288e BRAILLE PATTERN DOTS-2348 */ +#define XK_braille_dots_12348 0x100288f /* U+288f BRAILLE PATTERN DOTS-12348 */ +#define XK_braille_dots_58 0x1002890 /* U+2890 BRAILLE PATTERN DOTS-58 */ +#define XK_braille_dots_158 0x1002891 /* U+2891 BRAILLE PATTERN DOTS-158 */ +#define XK_braille_dots_258 0x1002892 /* U+2892 BRAILLE PATTERN DOTS-258 */ +#define XK_braille_dots_1258 0x1002893 /* U+2893 BRAILLE PATTERN DOTS-1258 */ +#define XK_braille_dots_358 0x1002894 /* U+2894 BRAILLE PATTERN DOTS-358 */ +#define XK_braille_dots_1358 0x1002895 /* U+2895 BRAILLE PATTERN DOTS-1358 */ +#define XK_braille_dots_2358 0x1002896 /* U+2896 BRAILLE PATTERN DOTS-2358 */ +#define XK_braille_dots_12358 0x1002897 /* U+2897 BRAILLE PATTERN DOTS-12358 */ +#define XK_braille_dots_458 0x1002898 /* U+2898 BRAILLE PATTERN DOTS-458 */ +#define XK_braille_dots_1458 0x1002899 /* U+2899 BRAILLE PATTERN DOTS-1458 */ +#define XK_braille_dots_2458 0x100289a /* U+289a BRAILLE PATTERN DOTS-2458 */ +#define XK_braille_dots_12458 0x100289b /* U+289b BRAILLE PATTERN DOTS-12458 */ +#define XK_braille_dots_3458 0x100289c /* U+289c BRAILLE PATTERN DOTS-3458 */ +#define XK_braille_dots_13458 0x100289d /* U+289d BRAILLE PATTERN DOTS-13458 */ +#define XK_braille_dots_23458 0x100289e /* U+289e BRAILLE PATTERN DOTS-23458 */ +#define XK_braille_dots_123458 0x100289f /* U+289f BRAILLE PATTERN DOTS-123458 */ +#define XK_braille_dots_68 0x10028a0 /* U+28a0 BRAILLE PATTERN DOTS-68 */ +#define XK_braille_dots_168 0x10028a1 /* U+28a1 BRAILLE PATTERN DOTS-168 */ +#define XK_braille_dots_268 0x10028a2 /* U+28a2 BRAILLE PATTERN DOTS-268 */ +#define XK_braille_dots_1268 0x10028a3 /* U+28a3 BRAILLE PATTERN DOTS-1268 */ +#define XK_braille_dots_368 0x10028a4 /* U+28a4 BRAILLE PATTERN DOTS-368 */ +#define XK_braille_dots_1368 0x10028a5 /* U+28a5 BRAILLE PATTERN DOTS-1368 */ +#define XK_braille_dots_2368 0x10028a6 /* U+28a6 BRAILLE PATTERN DOTS-2368 */ +#define XK_braille_dots_12368 0x10028a7 /* U+28a7 BRAILLE PATTERN DOTS-12368 */ +#define XK_braille_dots_468 0x10028a8 /* U+28a8 BRAILLE PATTERN DOTS-468 */ +#define XK_braille_dots_1468 0x10028a9 /* U+28a9 BRAILLE PATTERN DOTS-1468 */ +#define XK_braille_dots_2468 0x10028aa /* U+28aa BRAILLE PATTERN DOTS-2468 */ +#define XK_braille_dots_12468 0x10028ab /* U+28ab BRAILLE PATTERN DOTS-12468 */ +#define XK_braille_dots_3468 0x10028ac /* U+28ac BRAILLE PATTERN DOTS-3468 */ +#define XK_braille_dots_13468 0x10028ad /* U+28ad BRAILLE PATTERN DOTS-13468 */ +#define XK_braille_dots_23468 0x10028ae /* U+28ae BRAILLE PATTERN DOTS-23468 */ +#define XK_braille_dots_123468 0x10028af /* U+28af BRAILLE PATTERN DOTS-123468 */ +#define XK_braille_dots_568 0x10028b0 /* U+28b0 BRAILLE PATTERN DOTS-568 */ +#define XK_braille_dots_1568 0x10028b1 /* U+28b1 BRAILLE PATTERN DOTS-1568 */ +#define XK_braille_dots_2568 0x10028b2 /* U+28b2 BRAILLE PATTERN DOTS-2568 */ +#define XK_braille_dots_12568 0x10028b3 /* U+28b3 BRAILLE PATTERN DOTS-12568 */ +#define XK_braille_dots_3568 0x10028b4 /* U+28b4 BRAILLE PATTERN DOTS-3568 */ +#define XK_braille_dots_13568 0x10028b5 /* U+28b5 BRAILLE PATTERN DOTS-13568 */ +#define XK_braille_dots_23568 0x10028b6 /* U+28b6 BRAILLE PATTERN DOTS-23568 */ +#define XK_braille_dots_123568 0x10028b7 /* U+28b7 BRAILLE PATTERN DOTS-123568 */ +#define XK_braille_dots_4568 0x10028b8 /* U+28b8 BRAILLE PATTERN DOTS-4568 */ +#define XK_braille_dots_14568 0x10028b9 /* U+28b9 BRAILLE PATTERN DOTS-14568 */ +#define XK_braille_dots_24568 0x10028ba /* U+28ba BRAILLE PATTERN DOTS-24568 */ +#define XK_braille_dots_124568 0x10028bb /* U+28bb BRAILLE PATTERN DOTS-124568 */ +#define XK_braille_dots_34568 0x10028bc /* U+28bc BRAILLE PATTERN DOTS-34568 */ +#define XK_braille_dots_134568 0x10028bd /* U+28bd BRAILLE PATTERN DOTS-134568 */ +#define XK_braille_dots_234568 0x10028be /* U+28be BRAILLE PATTERN DOTS-234568 */ +#define XK_braille_dots_1234568 0x10028bf /* U+28bf BRAILLE PATTERN DOTS-1234568 */ +#define XK_braille_dots_78 0x10028c0 /* U+28c0 BRAILLE PATTERN DOTS-78 */ +#define XK_braille_dots_178 0x10028c1 /* U+28c1 BRAILLE PATTERN DOTS-178 */ +#define XK_braille_dots_278 0x10028c2 /* U+28c2 BRAILLE PATTERN DOTS-278 */ +#define XK_braille_dots_1278 0x10028c3 /* U+28c3 BRAILLE PATTERN DOTS-1278 */ +#define XK_braille_dots_378 0x10028c4 /* U+28c4 BRAILLE PATTERN DOTS-378 */ +#define XK_braille_dots_1378 0x10028c5 /* U+28c5 BRAILLE PATTERN DOTS-1378 */ +#define XK_braille_dots_2378 0x10028c6 /* U+28c6 BRAILLE PATTERN DOTS-2378 */ +#define XK_braille_dots_12378 0x10028c7 /* U+28c7 BRAILLE PATTERN DOTS-12378 */ +#define XK_braille_dots_478 0x10028c8 /* U+28c8 BRAILLE PATTERN DOTS-478 */ +#define XK_braille_dots_1478 0x10028c9 /* U+28c9 BRAILLE PATTERN DOTS-1478 */ +#define XK_braille_dots_2478 0x10028ca /* U+28ca BRAILLE PATTERN DOTS-2478 */ +#define XK_braille_dots_12478 0x10028cb /* U+28cb BRAILLE PATTERN DOTS-12478 */ +#define XK_braille_dots_3478 0x10028cc /* U+28cc BRAILLE PATTERN DOTS-3478 */ +#define XK_braille_dots_13478 0x10028cd /* U+28cd BRAILLE PATTERN DOTS-13478 */ +#define XK_braille_dots_23478 0x10028ce /* U+28ce BRAILLE PATTERN DOTS-23478 */ +#define XK_braille_dots_123478 0x10028cf /* U+28cf BRAILLE PATTERN DOTS-123478 */ +#define XK_braille_dots_578 0x10028d0 /* U+28d0 BRAILLE PATTERN DOTS-578 */ +#define XK_braille_dots_1578 0x10028d1 /* U+28d1 BRAILLE PATTERN DOTS-1578 */ +#define XK_braille_dots_2578 0x10028d2 /* U+28d2 BRAILLE PATTERN DOTS-2578 */ +#define XK_braille_dots_12578 0x10028d3 /* U+28d3 BRAILLE PATTERN DOTS-12578 */ +#define XK_braille_dots_3578 0x10028d4 /* U+28d4 BRAILLE PATTERN DOTS-3578 */ +#define XK_braille_dots_13578 0x10028d5 /* U+28d5 BRAILLE PATTERN DOTS-13578 */ +#define XK_braille_dots_23578 0x10028d6 /* U+28d6 BRAILLE PATTERN DOTS-23578 */ +#define XK_braille_dots_123578 0x10028d7 /* U+28d7 BRAILLE PATTERN DOTS-123578 */ +#define XK_braille_dots_4578 0x10028d8 /* U+28d8 BRAILLE PATTERN DOTS-4578 */ +#define XK_braille_dots_14578 0x10028d9 /* U+28d9 BRAILLE PATTERN DOTS-14578 */ +#define XK_braille_dots_24578 0x10028da /* U+28da BRAILLE PATTERN DOTS-24578 */ +#define XK_braille_dots_124578 0x10028db /* U+28db BRAILLE PATTERN DOTS-124578 */ +#define XK_braille_dots_34578 0x10028dc /* U+28dc BRAILLE PATTERN DOTS-34578 */ +#define XK_braille_dots_134578 0x10028dd /* U+28dd BRAILLE PATTERN DOTS-134578 */ +#define XK_braille_dots_234578 0x10028de /* U+28de BRAILLE PATTERN DOTS-234578 */ +#define XK_braille_dots_1234578 0x10028df /* U+28df BRAILLE PATTERN DOTS-1234578 */ +#define XK_braille_dots_678 0x10028e0 /* U+28e0 BRAILLE PATTERN DOTS-678 */ +#define XK_braille_dots_1678 0x10028e1 /* U+28e1 BRAILLE PATTERN DOTS-1678 */ +#define XK_braille_dots_2678 0x10028e2 /* U+28e2 BRAILLE PATTERN DOTS-2678 */ +#define XK_braille_dots_12678 0x10028e3 /* U+28e3 BRAILLE PATTERN DOTS-12678 */ +#define XK_braille_dots_3678 0x10028e4 /* U+28e4 BRAILLE PATTERN DOTS-3678 */ +#define XK_braille_dots_13678 0x10028e5 /* U+28e5 BRAILLE PATTERN DOTS-13678 */ +#define XK_braille_dots_23678 0x10028e6 /* U+28e6 BRAILLE PATTERN DOTS-23678 */ +#define XK_braille_dots_123678 0x10028e7 /* U+28e7 BRAILLE PATTERN DOTS-123678 */ +#define XK_braille_dots_4678 0x10028e8 /* U+28e8 BRAILLE PATTERN DOTS-4678 */ +#define XK_braille_dots_14678 0x10028e9 /* U+28e9 BRAILLE PATTERN DOTS-14678 */ +#define XK_braille_dots_24678 0x10028ea /* U+28ea BRAILLE PATTERN DOTS-24678 */ +#define XK_braille_dots_124678 0x10028eb /* U+28eb BRAILLE PATTERN DOTS-124678 */ +#define XK_braille_dots_34678 0x10028ec /* U+28ec BRAILLE PATTERN DOTS-34678 */ +#define XK_braille_dots_134678 0x10028ed /* U+28ed BRAILLE PATTERN DOTS-134678 */ +#define XK_braille_dots_234678 0x10028ee /* U+28ee BRAILLE PATTERN DOTS-234678 */ +#define XK_braille_dots_1234678 0x10028ef /* U+28ef BRAILLE PATTERN DOTS-1234678 */ +#define XK_braille_dots_5678 0x10028f0 /* U+28f0 BRAILLE PATTERN DOTS-5678 */ +#define XK_braille_dots_15678 0x10028f1 /* U+28f1 BRAILLE PATTERN DOTS-15678 */ +#define XK_braille_dots_25678 0x10028f2 /* U+28f2 BRAILLE PATTERN DOTS-25678 */ +#define XK_braille_dots_125678 0x10028f3 /* U+28f3 BRAILLE PATTERN DOTS-125678 */ +#define XK_braille_dots_35678 0x10028f4 /* U+28f4 BRAILLE PATTERN DOTS-35678 */ +#define XK_braille_dots_135678 0x10028f5 /* U+28f5 BRAILLE PATTERN DOTS-135678 */ +#define XK_braille_dots_235678 0x10028f6 /* U+28f6 BRAILLE PATTERN DOTS-235678 */ +#define XK_braille_dots_1235678 0x10028f7 /* U+28f7 BRAILLE PATTERN DOTS-1235678 */ +#define XK_braille_dots_45678 0x10028f8 /* U+28f8 BRAILLE PATTERN DOTS-45678 */ +#define XK_braille_dots_145678 0x10028f9 /* U+28f9 BRAILLE PATTERN DOTS-145678 */ +#define XK_braille_dots_245678 0x10028fa /* U+28fa BRAILLE PATTERN DOTS-245678 */ +#define XK_braille_dots_1245678 0x10028fb /* U+28fb BRAILLE PATTERN DOTS-1245678 */ +#define XK_braille_dots_345678 0x10028fc /* U+28fc BRAILLE PATTERN DOTS-345678 */ +#define XK_braille_dots_1345678 0x10028fd /* U+28fd BRAILLE PATTERN DOTS-1345678 */ +#define XK_braille_dots_2345678 0x10028fe /* U+28fe BRAILLE PATTERN DOTS-2345678 */ +#define XK_braille_dots_12345678 0x10028ff /* U+28ff BRAILLE PATTERN DOTS-12345678 */ +#endif /* XK_BRAILLE */ + +/* + * Sinhala (http://unicode.org/charts/PDF/U0D80.pdf) + * http://www.nongnu.org/sinhala/doc/transliteration/sinhala-transliteration_6.html + */ + +#ifdef XK_SINHALA +#define XK_Sinh_ng 0x1000d82 /* U+0D82 SINHALA ANUSVARAYA */ +#define XK_Sinh_h2 0x1000d83 /* U+0D83 SINHALA VISARGAYA */ +#define XK_Sinh_a 0x1000d85 /* U+0D85 SINHALA AYANNA */ +#define XK_Sinh_aa 0x1000d86 /* U+0D86 SINHALA AAYANNA */ +#define XK_Sinh_ae 0x1000d87 /* U+0D87 SINHALA AEYANNA */ +#define XK_Sinh_aee 0x1000d88 /* U+0D88 SINHALA AEEYANNA */ +#define XK_Sinh_i 0x1000d89 /* U+0D89 SINHALA IYANNA */ +#define XK_Sinh_ii 0x1000d8a /* U+0D8A SINHALA IIYANNA */ +#define XK_Sinh_u 0x1000d8b /* U+0D8B SINHALA UYANNA */ +#define XK_Sinh_uu 0x1000d8c /* U+0D8C SINHALA UUYANNA */ +#define XK_Sinh_ri 0x1000d8d /* U+0D8D SINHALA IRUYANNA */ +#define XK_Sinh_rii 0x1000d8e /* U+0D8E SINHALA IRUUYANNA */ +#define XK_Sinh_lu 0x1000d8f /* U+0D8F SINHALA ILUYANNA */ +#define XK_Sinh_luu 0x1000d90 /* U+0D90 SINHALA ILUUYANNA */ +#define XK_Sinh_e 0x1000d91 /* U+0D91 SINHALA EYANNA */ +#define XK_Sinh_ee 0x1000d92 /* U+0D92 SINHALA EEYANNA */ +#define XK_Sinh_ai 0x1000d93 /* U+0D93 SINHALA AIYANNA */ +#define XK_Sinh_o 0x1000d94 /* U+0D94 SINHALA OYANNA */ +#define XK_Sinh_oo 0x1000d95 /* U+0D95 SINHALA OOYANNA */ +#define XK_Sinh_au 0x1000d96 /* U+0D96 SINHALA AUYANNA */ +#define XK_Sinh_ka 0x1000d9a /* U+0D9A SINHALA KAYANNA */ +#define XK_Sinh_kha 0x1000d9b /* U+0D9B SINHALA MAHA. KAYANNA */ +#define XK_Sinh_ga 0x1000d9c /* U+0D9C SINHALA GAYANNA */ +#define XK_Sinh_gha 0x1000d9d /* U+0D9D SINHALA MAHA. GAYANNA */ +#define XK_Sinh_ng2 0x1000d9e /* U+0D9E SINHALA KANTAJA NAASIKYAYA */ +#define XK_Sinh_nga 0x1000d9f /* U+0D9F SINHALA SANYAKA GAYANNA */ +#define XK_Sinh_ca 0x1000da0 /* U+0DA0 SINHALA CAYANNA */ +#define XK_Sinh_cha 0x1000da1 /* U+0DA1 SINHALA MAHA. CAYANNA */ +#define XK_Sinh_ja 0x1000da2 /* U+0DA2 SINHALA JAYANNA */ +#define XK_Sinh_jha 0x1000da3 /* U+0DA3 SINHALA MAHA. JAYANNA */ +#define XK_Sinh_nya 0x1000da4 /* U+0DA4 SINHALA TAALUJA NAASIKYAYA */ +#define XK_Sinh_jnya 0x1000da5 /* U+0DA5 SINHALA TAALUJA SANYOOGA NAASIKYAYA */ +#define XK_Sinh_nja 0x1000da6 /* U+0DA6 SINHALA SANYAKA JAYANNA */ +#define XK_Sinh_tta 0x1000da7 /* U+0DA7 SINHALA TTAYANNA */ +#define XK_Sinh_ttha 0x1000da8 /* U+0DA8 SINHALA MAHA. TTAYANNA */ +#define XK_Sinh_dda 0x1000da9 /* U+0DA9 SINHALA DDAYANNA */ +#define XK_Sinh_ddha 0x1000daa /* U+0DAA SINHALA MAHA. DDAYANNA */ +#define XK_Sinh_nna 0x1000dab /* U+0DAB SINHALA MUURDHAJA NAYANNA */ +#define XK_Sinh_ndda 0x1000dac /* U+0DAC SINHALA SANYAKA DDAYANNA */ +#define XK_Sinh_tha 0x1000dad /* U+0DAD SINHALA TAYANNA */ +#define XK_Sinh_thha 0x1000dae /* U+0DAE SINHALA MAHA. TAYANNA */ +#define XK_Sinh_dha 0x1000daf /* U+0DAF SINHALA DAYANNA */ +#define XK_Sinh_dhha 0x1000db0 /* U+0DB0 SINHALA MAHA. DAYANNA */ +#define XK_Sinh_na 0x1000db1 /* U+0DB1 SINHALA DANTAJA NAYANNA */ +#define XK_Sinh_ndha 0x1000db3 /* U+0DB3 SINHALA SANYAKA DAYANNA */ +#define XK_Sinh_pa 0x1000db4 /* U+0DB4 SINHALA PAYANNA */ +#define XK_Sinh_pha 0x1000db5 /* U+0DB5 SINHALA MAHA. PAYANNA */ +#define XK_Sinh_ba 0x1000db6 /* U+0DB6 SINHALA BAYANNA */ +#define XK_Sinh_bha 0x1000db7 /* U+0DB7 SINHALA MAHA. BAYANNA */ +#define XK_Sinh_ma 0x1000db8 /* U+0DB8 SINHALA MAYANNA */ +#define XK_Sinh_mba 0x1000db9 /* U+0DB9 SINHALA AMBA BAYANNA */ +#define XK_Sinh_ya 0x1000dba /* U+0DBA SINHALA YAYANNA */ +#define XK_Sinh_ra 0x1000dbb /* U+0DBB SINHALA RAYANNA */ +#define XK_Sinh_la 0x1000dbd /* U+0DBD SINHALA DANTAJA LAYANNA */ +#define XK_Sinh_va 0x1000dc0 /* U+0DC0 SINHALA VAYANNA */ +#define XK_Sinh_sha 0x1000dc1 /* U+0DC1 SINHALA TAALUJA SAYANNA */ +#define XK_Sinh_ssha 0x1000dc2 /* U+0DC2 SINHALA MUURDHAJA SAYANNA */ +#define XK_Sinh_sa 0x1000dc3 /* U+0DC3 SINHALA DANTAJA SAYANNA */ +#define XK_Sinh_ha 0x1000dc4 /* U+0DC4 SINHALA HAYANNA */ +#define XK_Sinh_lla 0x1000dc5 /* U+0DC5 SINHALA MUURDHAJA LAYANNA */ +#define XK_Sinh_fa 0x1000dc6 /* U+0DC6 SINHALA FAYANNA */ +#define XK_Sinh_al 0x1000dca /* U+0DCA SINHALA AL-LAKUNA */ +#define XK_Sinh_aa2 0x1000dcf /* U+0DCF SINHALA AELA-PILLA */ +#define XK_Sinh_ae2 0x1000dd0 /* U+0DD0 SINHALA AEDA-PILLA */ +#define XK_Sinh_aee2 0x1000dd1 /* U+0DD1 SINHALA DIGA AEDA-PILLA */ +#define XK_Sinh_i2 0x1000dd2 /* U+0DD2 SINHALA IS-PILLA */ +#define XK_Sinh_ii2 0x1000dd3 /* U+0DD3 SINHALA DIGA IS-PILLA */ +#define XK_Sinh_u2 0x1000dd4 /* U+0DD4 SINHALA PAA-PILLA */ +#define XK_Sinh_uu2 0x1000dd6 /* U+0DD6 SINHALA DIGA PAA-PILLA */ +#define XK_Sinh_ru2 0x1000dd8 /* U+0DD8 SINHALA GAETTA-PILLA */ +#define XK_Sinh_e2 0x1000dd9 /* U+0DD9 SINHALA KOMBUVA */ +#define XK_Sinh_ee2 0x1000dda /* U+0DDA SINHALA DIGA KOMBUVA */ +#define XK_Sinh_ai2 0x1000ddb /* U+0DDB SINHALA KOMBU DEKA */ +#define XK_Sinh_o2 0x1000ddc /* U+0DDC SINHALA KOMBUVA HAA AELA-PILLA*/ +#define XK_Sinh_oo2 0x1000ddd /* U+0DDD SINHALA KOMBUVA HAA DIGA AELA-PILLA*/ +#define XK_Sinh_au2 0x1000dde /* U+0DDE SINHALA KOMBUVA HAA GAYANUKITTA */ +#define XK_Sinh_lu2 0x1000ddf /* U+0DDF SINHALA GAYANUKITTA */ +#define XK_Sinh_ruu2 0x1000df2 /* U+0DF2 SINHALA DIGA GAETTA-PILLA */ +#define XK_Sinh_luu2 0x1000df3 /* U+0DF3 SINHALA DIGA GAYANUKITTA */ +#define XK_Sinh_kunddaliya 0x1000df4 /* U+0DF4 SINHALA KUNDDALIYA */ +#endif /* XK_SINHALA */ diff --git a/thirdparty/linuxbsd_headers/alsa/alisp.h b/thirdparty/linuxbsd_headers/alsa/alisp.h new file mode 100644 index 0000000000..407ed646e8 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/alisp.h @@ -0,0 +1,55 @@ +/* + * ALSA lisp implementation + * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz> + * + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +struct alisp_cfg { + int verbose: 1, + warning: 1, + debug: 1; + snd_input_t *in; /* program code */ + snd_output_t *out; /* program output */ + snd_output_t *eout; /* error output */ + snd_output_t *vout; /* verbose output */ + snd_output_t *wout; /* warning output */ + snd_output_t *dout; /* debug output */ +}; + +struct alisp_instance; +struct alisp_object; +struct alisp_seq_iterator; + +struct alisp_cfg *alsa_lisp_default_cfg(snd_input_t *input); +void alsa_lisp_default_cfg_free(struct alisp_cfg *cfg); +int alsa_lisp(struct alisp_cfg *cfg, struct alisp_instance **instance); +void alsa_lisp_free(struct alisp_instance *instance); +int alsa_lisp_function(struct alisp_instance *instance, struct alisp_seq_iterator **result, + const char *id, const char *args, ...) +#ifndef DOC_HIDDEN + __attribute__ ((format (printf, 4, 5))) +#endif + ; +void alsa_lisp_result_free(struct alisp_instance *instance, + struct alisp_seq_iterator *result); +int alsa_lisp_seq_first(struct alisp_instance *instance, const char *id, + struct alisp_seq_iterator **seq); +int alsa_lisp_seq_next(struct alisp_seq_iterator **seq); +int alsa_lisp_seq_count(struct alisp_seq_iterator *seq); +int alsa_lisp_seq_integer(struct alisp_seq_iterator *seq, long *val); +int alsa_lisp_seq_pointer(struct alisp_seq_iterator *seq, const char *ptr_id, void **ptr); diff --git a/thirdparty/linuxbsd_headers/alsa/asoundef.h b/thirdparty/linuxbsd_headers/alsa/asoundef.h new file mode 100644 index 0000000000..c6c4eec951 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/asoundef.h @@ -0,0 +1,310 @@ +/** + * \file include/asoundef.h + * \brief Application interface library for the ALSA driver + * \author Jaroslav Kysela <perex@perex.cz> + * \author Abramo Bagnara <abramo@alsa-project.org> + * \author Takashi Iwai <tiwai@suse.de> + * \date 1998-2001 + * + * Definitions of constants for the ALSA driver + */ +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_ASOUNDEF_H +#define __ALSA_ASOUNDEF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup Digital_Audio_Interface Constants for Digital Audio Interfaces + * AES/IEC958 channel status bits. + * \{ + */ + +#define IEC958_AES0_PROFESSIONAL (1<<0) /**< 0 = consumer, 1 = professional */ +#define IEC958_AES0_NONAUDIO (1<<1) /**< 0 = audio, 1 = non-audio */ +#define IEC958_AES0_PRO_EMPHASIS (7<<2) /**< mask - emphasis */ +#define IEC958_AES0_PRO_EMPHASIS_NOTID (0<<2) /**< emphasis not indicated */ +#define IEC958_AES0_PRO_EMPHASIS_NONE (1<<2) /**< no emphasis */ +#define IEC958_AES0_PRO_EMPHASIS_5015 (3<<2) /**< 50/15us emphasis */ +#define IEC958_AES0_PRO_EMPHASIS_CCITT (7<<2) /**< CCITT J.17 emphasis */ +#define IEC958_AES0_PRO_FREQ_UNLOCKED (1<<5) /**< source sample frequency: 0 = locked, 1 = unlocked */ +#define IEC958_AES0_PRO_FS (3<<6) /**< mask - sample frequency */ +#define IEC958_AES0_PRO_FS_NOTID (0<<6) /**< fs not indicated */ +#define IEC958_AES0_PRO_FS_44100 (1<<6) /**< 44.1kHz */ +#define IEC958_AES0_PRO_FS_48000 (2<<6) /**< 48kHz */ +#define IEC958_AES0_PRO_FS_32000 (3<<6) /**< 32kHz */ +#define IEC958_AES0_CON_NOT_COPYRIGHT (1<<2) /**< 0 = copyright, 1 = not copyright */ +#define IEC958_AES0_CON_EMPHASIS (7<<3) /**< mask - emphasis */ +#define IEC958_AES0_CON_EMPHASIS_NONE (0<<3) /**< no emphasis */ +#define IEC958_AES0_CON_EMPHASIS_5015 (1<<3) /**< 50/15us emphasis */ +#define IEC958_AES0_CON_MODE (3<<6) /**< mask - mode */ +#define IEC958_AES1_PRO_MODE (15<<0) /**< mask - channel mode */ +#define IEC958_AES1_PRO_MODE_NOTID (0<<0) /**< mode not indicated */ +#define IEC958_AES1_PRO_MODE_STEREOPHONIC (2<<0) /**< stereophonic - ch A is left */ +#define IEC958_AES1_PRO_MODE_SINGLE (4<<0) /**< single channel */ +#define IEC958_AES1_PRO_MODE_TWO (8<<0) /**< two channels */ +#define IEC958_AES1_PRO_MODE_PRIMARY (12<<0) /**< primary/secondary */ +#define IEC958_AES1_PRO_MODE_BYTE3 (15<<0) /**< vector to byte 3 */ +#define IEC958_AES1_PRO_USERBITS (15<<4) /**< mask - user bits */ +#define IEC958_AES1_PRO_USERBITS_NOTID (0<<4) /**< user bits not indicated */ +#define IEC958_AES1_PRO_USERBITS_192 (8<<4) /**< 192-bit structure */ +#define IEC958_AES1_PRO_USERBITS_UDEF (12<<4) /**< user defined application */ +#define IEC958_AES1_CON_CATEGORY 0x7f /**< consumer category */ +#define IEC958_AES1_CON_GENERAL 0x00 /**< general category */ +#define IEC958_AES1_CON_LASEROPT_MASK 0x07 /**< Laser-optical mask */ +#define IEC958_AES1_CON_LASEROPT_ID 0x01 /**< Laser-optical ID */ +#define IEC958_AES1_CON_IEC908_CD (IEC958_AES1_CON_LASEROPT_ID|0x00) /**< IEC958 CD compatible device */ +#define IEC958_AES1_CON_NON_IEC908_CD (IEC958_AES1_CON_LASEROPT_ID|0x08) /**< non-IEC958 CD compatible device */ +#define IEC958_AES1_CON_MINI_DISC (IEC958_AES1_CON_LASEROPT_ID|0x48) /**< Mini-Disc device */ +#define IEC958_AES1_CON_DVD (IEC958_AES1_CON_LASEROPT_ID|0x18) /**< DVD device */ +#define IEC958_AES1_CON_LASTEROPT_OTHER (IEC958_AES1_CON_LASEROPT_ID|0x78) /**< Other laser-optical product */ +#define IEC958_AES1_CON_DIGDIGCONV_MASK 0x07 /**< digital<->digital converter mask */ +#define IEC958_AES1_CON_DIGDIGCONV_ID 0x02 /**< digital<->digital converter id */ +#define IEC958_AES1_CON_PCM_CODER (IEC958_AES1_CON_DIGDIGCONV_ID|0x00) /**< PCM coder */ +#define IEC958_AES1_CON_MIXER (IEC958_AES1_CON_DIGDIGCONV_ID|0x10) /**< Digital signal mixer */ +#define IEC958_AES1_CON_RATE_CONVERTER (IEC958_AES1_CON_DIGDIGCONV_ID|0x18) /**< Rate converter */ +#define IEC958_AES1_CON_SAMPLER (IEC958_AES1_CON_DIGDIGCONV_ID|0x20) /**< PCM sampler */ +#define IEC958_AES1_CON_DSP (IEC958_AES1_CON_DIGDIGCONV_ID|0x28) /**< Digital sound processor */ +#define IEC958_AES1_CON_DIGDIGCONV_OTHER (IEC958_AES1_CON_DIGDIGCONV_ID|0x78) /**< Other digital<->digital product */ +#define IEC958_AES1_CON_MAGNETIC_MASK 0x07 /**< Magnetic device mask */ +#define IEC958_AES1_CON_MAGNETIC_ID 0x03 /**< Magnetic device ID */ +#define IEC958_AES1_CON_DAT (IEC958_AES1_CON_MAGNETIC_ID|0x00) /**< Digital Audio Tape */ +#define IEC958_AES1_CON_VCR (IEC958_AES1_CON_MAGNETIC_ID|0x08) /**< Video recorder */ +#define IEC958_AES1_CON_DCC (IEC958_AES1_CON_MAGNETIC_ID|0x40) /**< Digital compact cassette */ +#define IEC958_AES1_CON_MAGNETIC_DISC (IEC958_AES1_CON_MAGNETIC_ID|0x18) /**< Magnetic disc digital audio device */ +#define IEC958_AES1_CON_MAGNETIC_OTHER (IEC958_AES1_CON_MAGNETIC_ID|0x78) /**< Other magnetic device */ +#define IEC958_AES1_CON_BROADCAST1_MASK 0x07 /**< Broadcast mask */ +#define IEC958_AES1_CON_BROADCAST1_ID 0x04 /**< Broadcast ID */ +#define IEC958_AES1_CON_DAB_JAPAN (IEC958_AES1_CON_BROADCAST1_ID|0x00) /**< Digital audio broadcast (Japan) */ +#define IEC958_AES1_CON_DAB_EUROPE (IEC958_AES1_CON_BROADCAST1_ID|0x08) /**< Digital audio broadcast (Europe) */ +#define IEC958_AES1_CON_DAB_USA (IEC958_AES1_CON_BROADCAST1_ID|0x60) /**< Digital audio broadcast (USA) */ +#define IEC958_AES1_CON_SOFTWARE (IEC958_AES1_CON_BROADCAST1_ID|0x40) /**< Electronic software delivery */ +#define IEC958_AES1_CON_IEC62105 (IEC958_AES1_CON_BROADCAST1_ID|0x20) /**< Used by another standard (IEC 62105) */ +#define IEC958_AES1_CON_BROADCAST1_OTHER (IEC958_AES1_CON_BROADCAST1_ID|0x78) /**< Other broadcast product */ +#define IEC958_AES1_CON_BROADCAST2_MASK 0x0f /**< Broadcast alternative mask */ +#define IEC958_AES1_CON_BROADCAST2_ID 0x0e /**< Broadcast alternative ID */ +#define IEC958_AES1_CON_MUSICAL_MASK 0x07 /**< Musical device mask */ +#define IEC958_AES1_CON_MUSICAL_ID 0x05 /**< Musical device ID */ +#define IEC958_AES1_CON_SYNTHESIZER (IEC958_AES1_CON_MUSICAL_ID|0x00) /**< Synthesizer */ +#define IEC958_AES1_CON_MICROPHONE (IEC958_AES1_CON_MUSICAL_ID|0x08) /**< Microphone */ +#define IEC958_AES1_CON_MUSICAL_OTHER (IEC958_AES1_CON_MUSICAL_ID|0x78) /**< Other musical device */ +#define IEC958_AES1_CON_ADC_MASK 0x1f /**< ADC Mask */ +#define IEC958_AES1_CON_ADC_ID 0x06 /**< ADC ID */ +#define IEC958_AES1_CON_ADC (IEC958_AES1_CON_ADC_ID|0x00) /**< ADC without copyright information */ +#define IEC958_AES1_CON_ADC_OTHER (IEC958_AES1_CON_ADC_ID|0x60) /**< Other ADC product (with no copyright information) */ +#define IEC958_AES1_CON_ADC_COPYRIGHT_MASK 0x1f /**< ADC Copyright mask */ +#define IEC958_AES1_CON_ADC_COPYRIGHT_ID 0x16 /**< ADC Copyright ID */ +#define IEC958_AES1_CON_ADC_COPYRIGHT (IEC958_AES1_CON_ADC_COPYRIGHT_ID|0x00) /**< ADC with copyright information */ +#define IEC958_AES1_CON_ADC_COPYRIGHT_OTHER (IEC958_AES1_CON_ADC_COPYRIGHT_ID|0x60) /**< Other ADC with copyright information product */ +#define IEC958_AES1_CON_SOLIDMEM_MASK 0x0f /**< Solid memory based products mask */ +#define IEC958_AES1_CON_SOLIDMEM_ID 0x08 /**< Solid memory based products ID */ +#define IEC958_AES1_CON_SOLIDMEM_DIGITAL_RECORDER_PLAYER (IEC958_AES1_CON_SOLIDMEM_ID|0x00) /**< Digital audio recorder and player using solid state memory */ +#define IEC958_AES1_CON_SOLIDMEM_OTHER (IEC958_AES1_CON_SOLIDMEM_ID|0x70) /**< Other solid state memory based product */ +#define IEC958_AES1_CON_EXPERIMENTAL 0x40 /**< experimental category */ +#define IEC958_AES1_CON_ORIGINAL (1<<7) /**< this bits depends on the category code */ +#define IEC958_AES2_PRO_SBITS (7<<0) /**< mask - sample bits */ +#define IEC958_AES2_PRO_SBITS_20 (2<<0) /**< 20-bit - coordination */ +#define IEC958_AES2_PRO_SBITS_24 (4<<0) /**< 24-bit - main audio */ +#define IEC958_AES2_PRO_SBITS_UDEF (6<<0) /**< user defined application */ +#define IEC958_AES2_PRO_WORDLEN (7<<3) /**< mask - source word length */ +#define IEC958_AES2_PRO_WORDLEN_NOTID (0<<3) /**< source word length not indicated */ +#define IEC958_AES2_PRO_WORDLEN_22_18 (2<<3) /**< 22-bit or 18-bit */ +#define IEC958_AES2_PRO_WORDLEN_23_19 (4<<3) /**< 23-bit or 19-bit */ +#define IEC958_AES2_PRO_WORDLEN_24_20 (5<<3) /**< 24-bit or 20-bit */ +#define IEC958_AES2_PRO_WORDLEN_20_16 (6<<3) /**< 20-bit or 16-bit */ +#define IEC958_AES2_CON_SOURCE (15<<0) /**< mask - source number */ +#define IEC958_AES2_CON_SOURCE_UNSPEC (0<<0) /**< source number unspecified */ +#define IEC958_AES2_CON_CHANNEL (15<<4) /**< mask - channel number */ +#define IEC958_AES2_CON_CHANNEL_UNSPEC (0<<4) /**< channel number unspecified */ +#define IEC958_AES3_CON_FS (15<<0) /**< mask - sample frequency */ +#define IEC958_AES3_CON_FS_44100 (0<<0) /**< 44.1kHz */ +#define IEC958_AES3_CON_FS_NOTID (1<<0) /**< sample frequency non indicated */ +#define IEC958_AES3_CON_FS_48000 (2<<0) /**< 48kHz */ +#define IEC958_AES3_CON_FS_32000 (3<<0) /**< 32kHz */ +#define IEC958_AES3_CON_FS_22050 (4<<0) /**< 22.05kHz */ +#define IEC958_AES3_CON_FS_24000 (6<<0) /**< 24kHz */ +#define IEC958_AES3_CON_FS_88200 (8<<0) /**< 88.2kHz */ +#define IEC958_AES3_CON_FS_768000 (9<<0) /**< 768kHz */ +#define IEC958_AES3_CON_FS_96000 (10<<0) /**< 96kHz */ +#define IEC958_AES3_CON_FS_176400 (12<<0) /**< 176.4kHz */ +#define IEC958_AES3_CON_FS_192000 (14<<0) /**< 192kHz */ +#define IEC958_AES3_CON_CLOCK (3<<4) /**< mask - clock accuracy */ +#define IEC958_AES3_CON_CLOCK_1000PPM (0<<4) /**< 1000 ppm */ +#define IEC958_AES3_CON_CLOCK_50PPM (1<<4) /**< 50 ppm */ +#define IEC958_AES3_CON_CLOCK_VARIABLE (2<<4) /**< variable pitch */ +#define IEC958_AES4_CON_MAX_WORDLEN_24 (1<<0) /**< 0 = 20-bit, 1 = 24-bit */ +#define IEC958_AES4_CON_WORDLEN (7<<1) /**< mask - sample word length */ +#define IEC958_AES4_CON_WORDLEN_NOTID (0<<1) /**< not indicated */ +#define IEC958_AES4_CON_WORDLEN_20_16 (1<<1) /**< 20-bit or 16-bit */ +#define IEC958_AES4_CON_WORDLEN_22_18 (2<<1) /**< 22-bit or 18-bit */ +#define IEC958_AES4_CON_WORDLEN_23_19 (4<<1) /**< 23-bit or 19-bit */ +#define IEC958_AES4_CON_WORDLEN_24_20 (5<<1) /**< 24-bit or 20-bit */ +#define IEC958_AES4_CON_WORDLEN_21_17 (6<<1) /**< 21-bit or 17-bit */ +#define IEC958_AES4_CON_ORIGFS (15<<4) /**< mask - original sample frequency */ +#define IEC958_AES4_CON_ORIGFS_NOTID (0<<4) /**< original sample frequency not indicated */ +#define IEC958_AES4_CON_ORIGFS_192000 (1<<4) /**< 192kHz */ +#define IEC958_AES4_CON_ORIGFS_12000 (2<<4) /**< 12kHz */ +#define IEC958_AES4_CON_ORIGFS_176400 (3<<4) /**< 176.4kHz */ +#define IEC958_AES4_CON_ORIGFS_96000 (5<<4) /**< 96kHz */ +#define IEC958_AES4_CON_ORIGFS_8000 (6<<4) /**< 8kHz */ +#define IEC958_AES4_CON_ORIGFS_88200 (7<<4) /**< 88.2kHz */ +#define IEC958_AES4_CON_ORIGFS_16000 (8<<4) /**< 16kHz */ +#define IEC958_AES4_CON_ORIGFS_24000 (9<<4) /**< 24kHz */ +#define IEC958_AES4_CON_ORIGFS_11025 (10<<4) /**< 11.025kHz */ +#define IEC958_AES4_CON_ORIGFS_22050 (11<<4) /**< 22.05kHz */ +#define IEC958_AES4_CON_ORIGFS_32000 (12<<4) /**< 32kHz */ +#define IEC958_AES4_CON_ORIGFS_48000 (13<<4) /**< 48kHz */ +#define IEC958_AES4_CON_ORIGFS_44100 (15<<4) /**< 44.1kHz */ +#define IEC958_AES5_CON_CGMSA (3<<0) /**< mask - CGMS-A */ +#define IEC958_AES5_CON_CGMSA_COPYFREELY (0<<0) /**< copying is permitted without restriction */ +#define IEC958_AES5_CON_CGMSA_COPYONCE (1<<0) /**< one generation of copies may be made */ +#define IEC958_AES5_CON_CGMSA_COPYNOMORE (2<<0) /**< condition not be used */ +#define IEC958_AES5_CON_CGMSA_COPYNEVER (3<<0) /**< no copying is permitted */ + +/** \} */ + +/** + * \defgroup MIDI_Interface Constants for MIDI v1.0 + * Constants for MIDI v1.0. + * \{ + */ + +#define MIDI_CHANNELS 16 /**< Number of channels per port/cable. */ +#define MIDI_GM_DRUM_CHANNEL (10-1) /**< Channel number for GM drums. */ + +/** + * \defgroup MIDI_Commands MIDI Commands + * MIDI command codes. + * \{ + */ + +#define MIDI_CMD_NOTE_OFF 0x80 /**< note off */ +#define MIDI_CMD_NOTE_ON 0x90 /**< note on */ +#define MIDI_CMD_NOTE_PRESSURE 0xa0 /**< key pressure */ +#define MIDI_CMD_CONTROL 0xb0 /**< control change */ +#define MIDI_CMD_PGM_CHANGE 0xc0 /**< program change */ +#define MIDI_CMD_CHANNEL_PRESSURE 0xd0 /**< channel pressure */ +#define MIDI_CMD_BENDER 0xe0 /**< pitch bender */ + +#define MIDI_CMD_COMMON_SYSEX 0xf0 /**< sysex (system exclusive) begin */ +#define MIDI_CMD_COMMON_MTC_QUARTER 0xf1 /**< MTC quarter frame */ +#define MIDI_CMD_COMMON_SONG_POS 0xf2 /**< song position */ +#define MIDI_CMD_COMMON_SONG_SELECT 0xf3 /**< song select */ +#define MIDI_CMD_COMMON_TUNE_REQUEST 0xf6 /**< tune request */ +#define MIDI_CMD_COMMON_SYSEX_END 0xf7 /**< end of sysex */ +#define MIDI_CMD_COMMON_CLOCK 0xf8 /**< clock */ +#define MIDI_CMD_COMMON_START 0xfa /**< start */ +#define MIDI_CMD_COMMON_CONTINUE 0xfb /**< continue */ +#define MIDI_CMD_COMMON_STOP 0xfc /**< stop */ +#define MIDI_CMD_COMMON_SENSING 0xfe /**< active sensing */ +#define MIDI_CMD_COMMON_RESET 0xff /**< reset */ + +/** \} */ + +/** + * \defgroup MIDI_Controllers MIDI Controllers + * MIDI controller numbers. + * \{ + */ + +#define MIDI_CTL_MSB_BANK 0x00 /**< Bank selection */ +#define MIDI_CTL_MSB_MODWHEEL 0x01 /**< Modulation */ +#define MIDI_CTL_MSB_BREATH 0x02 /**< Breath */ +#define MIDI_CTL_MSB_FOOT 0x04 /**< Foot */ +#define MIDI_CTL_MSB_PORTAMENTO_TIME 0x05 /**< Portamento time */ +#define MIDI_CTL_MSB_DATA_ENTRY 0x06 /**< Data entry */ +#define MIDI_CTL_MSB_MAIN_VOLUME 0x07 /**< Main volume */ +#define MIDI_CTL_MSB_BALANCE 0x08 /**< Balance */ +#define MIDI_CTL_MSB_PAN 0x0a /**< Panpot */ +#define MIDI_CTL_MSB_EXPRESSION 0x0b /**< Expression */ +#define MIDI_CTL_MSB_EFFECT1 0x0c /**< Effect1 */ +#define MIDI_CTL_MSB_EFFECT2 0x0d /**< Effect2 */ +#define MIDI_CTL_MSB_GENERAL_PURPOSE1 0x10 /**< General purpose 1 */ +#define MIDI_CTL_MSB_GENERAL_PURPOSE2 0x11 /**< General purpose 2 */ +#define MIDI_CTL_MSB_GENERAL_PURPOSE3 0x12 /**< General purpose 3 */ +#define MIDI_CTL_MSB_GENERAL_PURPOSE4 0x13 /**< General purpose 4 */ +#define MIDI_CTL_LSB_BANK 0x20 /**< Bank selection */ +#define MIDI_CTL_LSB_MODWHEEL 0x21 /**< Modulation */ +#define MIDI_CTL_LSB_BREATH 0x22 /**< Breath */ +#define MIDI_CTL_LSB_FOOT 0x24 /**< Foot */ +#define MIDI_CTL_LSB_PORTAMENTO_TIME 0x25 /**< Portamento time */ +#define MIDI_CTL_LSB_DATA_ENTRY 0x26 /**< Data entry */ +#define MIDI_CTL_LSB_MAIN_VOLUME 0x27 /**< Main volume */ +#define MIDI_CTL_LSB_BALANCE 0x28 /**< Balance */ +#define MIDI_CTL_LSB_PAN 0x2a /**< Panpot */ +#define MIDI_CTL_LSB_EXPRESSION 0x2b /**< Expression */ +#define MIDI_CTL_LSB_EFFECT1 0x2c /**< Effect1 */ +#define MIDI_CTL_LSB_EFFECT2 0x2d /**< Effect2 */ +#define MIDI_CTL_LSB_GENERAL_PURPOSE1 0x30 /**< General purpose 1 */ +#define MIDI_CTL_LSB_GENERAL_PURPOSE2 0x31 /**< General purpose 2 */ +#define MIDI_CTL_LSB_GENERAL_PURPOSE3 0x32 /**< General purpose 3 */ +#define MIDI_CTL_LSB_GENERAL_PURPOSE4 0x33 /**< General purpose 4 */ +#define MIDI_CTL_SUSTAIN 0x40 /**< Sustain pedal */ +#define MIDI_CTL_PORTAMENTO 0x41 /**< Portamento */ +#define MIDI_CTL_SOSTENUTO 0x42 /**< Sostenuto */ +#define MIDI_CTL_SUSTENUTO 0x42 /**< Sostenuto (a typo in the older version) */ +#define MIDI_CTL_SOFT_PEDAL 0x43 /**< Soft pedal */ +#define MIDI_CTL_LEGATO_FOOTSWITCH 0x44 /**< Legato foot switch */ +#define MIDI_CTL_HOLD2 0x45 /**< Hold2 */ +#define MIDI_CTL_SC1_SOUND_VARIATION 0x46 /**< SC1 Sound Variation */ +#define MIDI_CTL_SC2_TIMBRE 0x47 /**< SC2 Timbre */ +#define MIDI_CTL_SC3_RELEASE_TIME 0x48 /**< SC3 Release Time */ +#define MIDI_CTL_SC4_ATTACK_TIME 0x49 /**< SC4 Attack Time */ +#define MIDI_CTL_SC5_BRIGHTNESS 0x4a /**< SC5 Brightness */ +#define MIDI_CTL_SC6 0x4b /**< SC6 */ +#define MIDI_CTL_SC7 0x4c /**< SC7 */ +#define MIDI_CTL_SC8 0x4d /**< SC8 */ +#define MIDI_CTL_SC9 0x4e /**< SC9 */ +#define MIDI_CTL_SC10 0x4f /**< SC10 */ +#define MIDI_CTL_GENERAL_PURPOSE5 0x50 /**< General purpose 5 */ +#define MIDI_CTL_GENERAL_PURPOSE6 0x51 /**< General purpose 6 */ +#define MIDI_CTL_GENERAL_PURPOSE7 0x52 /**< General purpose 7 */ +#define MIDI_CTL_GENERAL_PURPOSE8 0x53 /**< General purpose 8 */ +#define MIDI_CTL_PORTAMENTO_CONTROL 0x54 /**< Portamento control */ +#define MIDI_CTL_E1_REVERB_DEPTH 0x5b /**< E1 Reverb Depth */ +#define MIDI_CTL_E2_TREMOLO_DEPTH 0x5c /**< E2 Tremolo Depth */ +#define MIDI_CTL_E3_CHORUS_DEPTH 0x5d /**< E3 Chorus Depth */ +#define MIDI_CTL_E4_DETUNE_DEPTH 0x5e /**< E4 Detune Depth */ +#define MIDI_CTL_E5_PHASER_DEPTH 0x5f /**< E5 Phaser Depth */ +#define MIDI_CTL_DATA_INCREMENT 0x60 /**< Data Increment */ +#define MIDI_CTL_DATA_DECREMENT 0x61 /**< Data Decrement */ +#define MIDI_CTL_NONREG_PARM_NUM_LSB 0x62 /**< Non-registered parameter number */ +#define MIDI_CTL_NONREG_PARM_NUM_MSB 0x63 /**< Non-registered parameter number */ +#define MIDI_CTL_REGIST_PARM_NUM_LSB 0x64 /**< Registered parameter number */ +#define MIDI_CTL_REGIST_PARM_NUM_MSB 0x65 /**< Registered parameter number */ +#define MIDI_CTL_ALL_SOUNDS_OFF 0x78 /**< All sounds off */ +#define MIDI_CTL_RESET_CONTROLLERS 0x79 /**< Reset Controllers */ +#define MIDI_CTL_LOCAL_CONTROL_SWITCH 0x7a /**< Local control switch */ +#define MIDI_CTL_ALL_NOTES_OFF 0x7b /**< All notes off */ +#define MIDI_CTL_OMNI_OFF 0x7c /**< Omni off */ +#define MIDI_CTL_OMNI_ON 0x7d /**< Omni on */ +#define MIDI_CTL_MONO1 0x7e /**< Mono1 */ +#define MIDI_CTL_MONO2 0x7f /**< Mono2 */ + +/** \} */ + +/** \} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALSA_ASOUNDEF_H */ diff --git a/thirdparty/linuxbsd_headers/alsa/asoundlib.h b/thirdparty/linuxbsd_headers/alsa/asoundlib.h new file mode 100644 index 0000000000..a546194382 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/asoundlib.h @@ -0,0 +1,65 @@ +/** + * \file include/asoundlib.h + * \brief Application interface library for the ALSA driver + * \author Jaroslav Kysela <perex@perex.cz> + * \author Abramo Bagnara <abramo@alsa-project.org> + * \author Takashi Iwai <tiwai@suse.de> + * \date 1998-2001 + * + * Application interface library for the ALSA driver + */ +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ASOUNDLIB_H +#define __ASOUNDLIB_H + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <fcntl.h> +#include <assert.h> +#include <poll.h> +#include <errno.h> +#include <stdarg.h> +#include <endian.h> + +#ifndef __GNUC__ +#define __inline__ inline +#endif + +#include <alsa/asoundef.h> +#include <alsa/version.h> +#include <alsa/global.h> +#include <alsa/input.h> +#include <alsa/output.h> +#include <alsa/error.h> +#include <alsa/conf.h> +#include <alsa/pcm.h> +#include <alsa/rawmidi.h> +#include <alsa/timer.h> +#include <alsa/hwdep.h> +#include <alsa/control.h> +#include <alsa/mixer.h> +#include <alsa/seq_event.h> +#include <alsa/seq.h> +#include <alsa/seqmid.h> +#include <alsa/seq_midi_event.h> + +#endif /* __ASOUNDLIB_H */ diff --git a/thirdparty/linuxbsd_headers/alsa/conf.h b/thirdparty/linuxbsd_headers/alsa/conf.h new file mode 100644 index 0000000000..5d293d583f --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/conf.h @@ -0,0 +1,212 @@ +/** + * \file include/conf.h + * \brief Application interface library for the ALSA driver + * \author Jaroslav Kysela <perex@perex.cz> + * \author Abramo Bagnara <abramo@alsa-project.org> + * \author Takashi Iwai <tiwai@suse.de> + * \date 1998-2001 + * + * Application interface library for the ALSA driver + */ +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_CONF_H +#define __ALSA_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup Config Configuration Interface + * The configuration functions and types allow you to read, enumerate, + * modify and write the contents of ALSA configuration files. + * \{ + */ + +/** \brief \c dlsym version for the config evaluate callback. */ +#define SND_CONFIG_DLSYM_VERSION_EVALUATE _dlsym_config_evaluate_001 +/** \brief \c dlsym version for the config hook callback. */ +#define SND_CONFIG_DLSYM_VERSION_HOOK _dlsym_config_hook_001 + +/** \brief Configuration node type. */ +typedef enum _snd_config_type { + /** Integer number. */ + SND_CONFIG_TYPE_INTEGER, + /** 64-bit integer number. */ + SND_CONFIG_TYPE_INTEGER64, + /** Real number. */ + SND_CONFIG_TYPE_REAL, + /** Character string. */ + SND_CONFIG_TYPE_STRING, + /** Pointer (runtime only, cannot be saved). */ + SND_CONFIG_TYPE_POINTER, + /** Compound node. */ + SND_CONFIG_TYPE_COMPOUND = 1024 +} snd_config_type_t; + +/** + * \brief Internal structure for a configuration node object. + * + * The ALSA library uses a pointer to this structure as a handle to a + * configuration node. Applications don't access its contents directly. + */ +typedef struct _snd_config snd_config_t; +/** + * \brief Type for a configuration compound iterator. + * + * The ALSA library uses this pointer type as a handle to a configuration + * compound iterator. Applications don't directly access the contents of + * the structure pointed to by this type. + */ +typedef struct _snd_config_iterator *snd_config_iterator_t; +/** + * \brief Internal structure for a configuration private update object. + * + * The ALSA library uses this structure to save private update information. + */ +typedef struct _snd_config_update snd_config_update_t; + +extern snd_config_t *snd_config; + +int snd_config_top(snd_config_t **config); + +int snd_config_load(snd_config_t *config, snd_input_t *in); +int snd_config_load_override(snd_config_t *config, snd_input_t *in); +int snd_config_save(snd_config_t *config, snd_output_t *out); +int snd_config_update(void); +int snd_config_update_r(snd_config_t **top, snd_config_update_t **update, const char *path); +int snd_config_update_free(snd_config_update_t *update); +int snd_config_update_free_global(void); + +int snd_config_update_ref(snd_config_t **top); +void snd_config_ref(snd_config_t *top); +void snd_config_unref(snd_config_t *top); + +int snd_config_search(snd_config_t *config, const char *key, + snd_config_t **result); +int snd_config_searchv(snd_config_t *config, + snd_config_t **result, ...); +int snd_config_search_definition(snd_config_t *config, + const char *base, const char *key, + snd_config_t **result); + +int snd_config_expand(snd_config_t *config, snd_config_t *root, + const char *args, snd_config_t *private_data, + snd_config_t **result); +int snd_config_evaluate(snd_config_t *config, snd_config_t *root, + snd_config_t *private_data, snd_config_t **result); + +int snd_config_add(snd_config_t *config, snd_config_t *leaf); +int snd_config_delete(snd_config_t *config); +int snd_config_delete_compound_members(const snd_config_t *config); +int snd_config_copy(snd_config_t **dst, snd_config_t *src); + +int snd_config_make(snd_config_t **config, const char *key, + snd_config_type_t type); +int snd_config_make_integer(snd_config_t **config, const char *key); +int snd_config_make_integer64(snd_config_t **config, const char *key); +int snd_config_make_real(snd_config_t **config, const char *key); +int snd_config_make_string(snd_config_t **config, const char *key); +int snd_config_make_pointer(snd_config_t **config, const char *key); +int snd_config_make_compound(snd_config_t **config, const char *key, int join); + +int snd_config_imake_integer(snd_config_t **config, const char *key, const long value); +int snd_config_imake_integer64(snd_config_t **config, const char *key, const long long value); +int snd_config_imake_real(snd_config_t **config, const char *key, const double value); +int snd_config_imake_string(snd_config_t **config, const char *key, const char *ascii); +int snd_config_imake_safe_string(snd_config_t **config, const char *key, const char *ascii); +int snd_config_imake_pointer(snd_config_t **config, const char *key, const void *ptr); + +snd_config_type_t snd_config_get_type(const snd_config_t *config); + +int snd_config_set_id(snd_config_t *config, const char *id); +int snd_config_set_integer(snd_config_t *config, long value); +int snd_config_set_integer64(snd_config_t *config, long long value); +int snd_config_set_real(snd_config_t *config, double value); +int snd_config_set_string(snd_config_t *config, const char *value); +int snd_config_set_ascii(snd_config_t *config, const char *ascii); +int snd_config_set_pointer(snd_config_t *config, const void *ptr); +int snd_config_get_id(const snd_config_t *config, const char **value); +int snd_config_get_integer(const snd_config_t *config, long *value); +int snd_config_get_integer64(const snd_config_t *config, long long *value); +int snd_config_get_real(const snd_config_t *config, double *value); +int snd_config_get_ireal(const snd_config_t *config, double *value); +int snd_config_get_string(const snd_config_t *config, const char **value); +int snd_config_get_ascii(const snd_config_t *config, char **value); +int snd_config_get_pointer(const snd_config_t *config, const void **value); +int snd_config_test_id(const snd_config_t *config, const char *id); + +snd_config_iterator_t snd_config_iterator_first(const snd_config_t *node); +snd_config_iterator_t snd_config_iterator_next(const snd_config_iterator_t iterator); +snd_config_iterator_t snd_config_iterator_end(const snd_config_t *node); +snd_config_t *snd_config_iterator_entry(const snd_config_iterator_t iterator); + +/** + * \brief Helper macro to iterate over the children of a compound node. + * \param[in,out] pos Iterator variable for the current node. + * \param[in,out] next Temporary iterator variable for the next node. + * \param[in] node Handle to the compound configuration node to iterate over. + * + * Use this macro like a \c for statement, e.g.: + * \code + * snd_config_iterator_t pos, next; + * snd_config_for_each(pos, next, node) { + * snd_config_t *entry = snd_config_iterator_entry(pos); + * ... + * } + * \endcode + * + * This macro allows deleting or removing the current node. + */ +#define snd_config_for_each(pos, next, node) \ + for (pos = snd_config_iterator_first(node), next = snd_config_iterator_next(pos); pos != snd_config_iterator_end(node); pos = next, next = snd_config_iterator_next(pos)) + +/* Misc functions */ + +int snd_config_get_bool_ascii(const char *ascii); +int snd_config_get_bool(const snd_config_t *conf); +int snd_config_get_ctl_iface_ascii(const char *ascii); +int snd_config_get_ctl_iface(const snd_config_t *conf); + +/* Names functions */ + +/** + * Device-name list element + */ +typedef struct snd_devname snd_devname_t; + +/** + * Device-name list element (definition) + */ +struct snd_devname { + char *name; /**< Device name string */ + char *comment; /**< Comments */ + snd_devname_t *next; /**< Next pointer */ +}; + +int snd_names_list(const char *iface, snd_devname_t **list); +void snd_names_list_free(snd_devname_t *list); + +/** \} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALSA_CONF_H */ diff --git a/thirdparty/linuxbsd_headers/alsa/control.h b/thirdparty/linuxbsd_headers/alsa/control.h new file mode 100644 index 0000000000..1d4bfcbb08 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/control.h @@ -0,0 +1,622 @@ +/** + * \file include/control.h + * \brief Application interface library for the ALSA driver + * \author Jaroslav Kysela <perex@perex.cz> + * \author Abramo Bagnara <abramo@alsa-project.org> + * \author Takashi Iwai <tiwai@suse.de> + * \date 1998-2001 + * + * Application interface library for the ALSA driver + */ +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_CONTROL_H +#define __ALSA_CONTROL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup Control Control Interface + * The control interface. + * See \ref control page for more details. + * \{ + */ + +/** dlsym version for interface entry callback */ +#define SND_CONTROL_DLSYM_VERSION _dlsym_control_001 + +/** IEC958 structure */ +typedef struct snd_aes_iec958 { + unsigned char status[24]; /**< AES/IEC958 channel status bits */ + unsigned char subcode[147]; /**< AES/IEC958 subcode bits */ + unsigned char pad; /**< nothing */ + unsigned char dig_subframe[4]; /**< AES/IEC958 subframe bits */ +} snd_aes_iec958_t; + +/** CTL card info container */ +typedef struct _snd_ctl_card_info snd_ctl_card_info_t; + +/** CTL element identifier container */ +typedef struct _snd_ctl_elem_id snd_ctl_elem_id_t; + +/** CTL element identifier list container */ +typedef struct _snd_ctl_elem_list snd_ctl_elem_list_t; + +/** CTL element info container */ +typedef struct _snd_ctl_elem_info snd_ctl_elem_info_t; + +/** CTL element value container */ +typedef struct _snd_ctl_elem_value snd_ctl_elem_value_t; + +/** CTL event container */ +typedef struct _snd_ctl_event snd_ctl_event_t; + +/** CTL element type */ +typedef enum _snd_ctl_elem_type { + /** Invalid type */ + SND_CTL_ELEM_TYPE_NONE = 0, + /** Boolean contents */ + SND_CTL_ELEM_TYPE_BOOLEAN, + /** Integer contents */ + SND_CTL_ELEM_TYPE_INTEGER, + /** Enumerated contents */ + SND_CTL_ELEM_TYPE_ENUMERATED, + /** Bytes contents */ + SND_CTL_ELEM_TYPE_BYTES, + /** IEC958 (S/PDIF) setting content */ + SND_CTL_ELEM_TYPE_IEC958, + /** 64-bit integer contents */ + SND_CTL_ELEM_TYPE_INTEGER64, + SND_CTL_ELEM_TYPE_LAST = SND_CTL_ELEM_TYPE_INTEGER64 +} snd_ctl_elem_type_t; + +/** CTL related interface */ +typedef enum _snd_ctl_elem_iface { + /** Card level */ + SND_CTL_ELEM_IFACE_CARD = 0, + /** Hardware dependent device */ + SND_CTL_ELEM_IFACE_HWDEP, + /** Mixer */ + SND_CTL_ELEM_IFACE_MIXER, + /** PCM */ + SND_CTL_ELEM_IFACE_PCM, + /** RawMidi */ + SND_CTL_ELEM_IFACE_RAWMIDI, + /** Timer */ + SND_CTL_ELEM_IFACE_TIMER, + /** Sequencer */ + SND_CTL_ELEM_IFACE_SEQUENCER, + SND_CTL_ELEM_IFACE_LAST = SND_CTL_ELEM_IFACE_SEQUENCER +} snd_ctl_elem_iface_t; + +/** Event class */ +typedef enum _snd_ctl_event_type { + /** Elements related event */ + SND_CTL_EVENT_ELEM = 0, + SND_CTL_EVENT_LAST = SND_CTL_EVENT_ELEM +}snd_ctl_event_type_t; + +/** Element has been removed (Warning: test this first and if set don't + * test the other masks) \hideinitializer */ +#define SND_CTL_EVENT_MASK_REMOVE (~0U) +/** Element value has been changed \hideinitializer */ +#define SND_CTL_EVENT_MASK_VALUE (1<<0) +/** Element info has been changed \hideinitializer */ +#define SND_CTL_EVENT_MASK_INFO (1<<1) +/** Element has been added \hideinitializer */ +#define SND_CTL_EVENT_MASK_ADD (1<<2) +/** Element's TLV value has been changed \hideinitializer */ +#define SND_CTL_EVENT_MASK_TLV (1<<3) + +/** CTL name helper */ +#define SND_CTL_NAME_NONE "" +/** CTL name helper */ +#define SND_CTL_NAME_PLAYBACK "Playback " +/** CTL name helper */ +#define SND_CTL_NAME_CAPTURE "Capture " + +/** CTL name helper */ +#define SND_CTL_NAME_IEC958_NONE "" +/** CTL name helper */ +#define SND_CTL_NAME_IEC958_SWITCH "Switch" +/** CTL name helper */ +#define SND_CTL_NAME_IEC958_VOLUME "Volume" +/** CTL name helper */ +#define SND_CTL_NAME_IEC958_DEFAULT "Default" +/** CTL name helper */ +#define SND_CTL_NAME_IEC958_MASK "Mask" +/** CTL name helper */ +#define SND_CTL_NAME_IEC958_CON_MASK "Con Mask" +/** CTL name helper */ +#define SND_CTL_NAME_IEC958_PRO_MASK "Pro Mask" +/** CTL name helper */ +#define SND_CTL_NAME_IEC958_PCM_STREAM "PCM Stream" +/** Element name for IEC958 (S/PDIF) */ +#define SND_CTL_NAME_IEC958(expl,direction,what) "IEC958 " expl SND_CTL_NAME_##direction SND_CTL_NAME_IEC958_##what + +/** Mask for the major Power State identifier */ +#define SND_CTL_POWER_MASK 0xff00 +/** ACPI/PCI Power State D0 */ +#define SND_CTL_POWER_D0 0x0000 +/** ACPI/PCI Power State D1 */ +#define SND_CTL_POWER_D1 0x0100 +/** ACPI/PCI Power State D2 */ +#define SND_CTL_POWER_D2 0x0200 +/** ACPI/PCI Power State D3 */ +#define SND_CTL_POWER_D3 0x0300 +/** ACPI/PCI Power State D3hot */ +#define SND_CTL_POWER_D3hot (SND_CTL_POWER_D3|0x0000) +/** ACPI/PCI Power State D3cold */ +#define SND_CTL_POWER_D3cold (SND_CTL_POWER_D3|0x0001) + +/** TLV type - Container */ +#define SND_CTL_TLVT_CONTAINER 0x0000 +/** TLV type - basic dB scale */ +#define SND_CTL_TLVT_DB_SCALE 0x0001 +/** TLV type - linear volume */ +#define SND_CTL_TLVT_DB_LINEAR 0x0002 +/** TLV type - dB range container */ +#define SND_CTL_TLVT_DB_RANGE 0x0003 +/** TLV type - dB scale specified by min/max values */ +#define SND_CTL_TLVT_DB_MINMAX 0x0004 +/** TLV type - dB scale specified by min/max values (with mute) */ +#define SND_CTL_TLVT_DB_MINMAX_MUTE 0x0005 + +/** Mute state */ +#define SND_CTL_TLV_DB_GAIN_MUTE -9999999 + +/** TLV type - fixed channel map positions */ +#define SND_CTL_TLVT_CHMAP_FIXED 0x00101 +/** TLV type - freely swappable channel map positions */ +#define SND_CTL_TLVT_CHMAP_VAR 0x00102 +/** TLV type - pair-wise swappable channel map positions */ +#define SND_CTL_TLVT_CHMAP_PAIRED 0x00103 + +/** CTL type */ +typedef enum _snd_ctl_type { + /** Kernel level CTL */ + SND_CTL_TYPE_HW, + /** Shared memory client CTL */ + SND_CTL_TYPE_SHM, + /** INET client CTL (not yet implemented) */ + SND_CTL_TYPE_INET, + /** External control plugin */ + SND_CTL_TYPE_EXT +} snd_ctl_type_t; + +/** Non blocking mode (flag for open mode) \hideinitializer */ +#define SND_CTL_NONBLOCK 0x0001 + +/** Async notification (flag for open mode) \hideinitializer */ +#define SND_CTL_ASYNC 0x0002 + +/** Read only (flag for open mode) \hideinitializer */ +#define SND_CTL_READONLY 0x0004 + +/** CTL handle */ +typedef struct _snd_ctl snd_ctl_t; + +/** Don't destroy the ctl handle when close */ +#define SND_SCTL_NOFREE 0x0001 + +/** SCTL type */ +typedef struct _snd_sctl snd_sctl_t; + +int snd_card_load(int card); +int snd_card_next(int *card); +int snd_card_get_index(const char *name); +int snd_card_get_name(int card, char **name); +int snd_card_get_longname(int card, char **name); + +int snd_device_name_hint(int card, const char *iface, void ***hints); +int snd_device_name_free_hint(void **hints); +char *snd_device_name_get_hint(const void *hint, const char *id); + +int snd_ctl_open(snd_ctl_t **ctl, const char *name, int mode); +int snd_ctl_open_lconf(snd_ctl_t **ctl, const char *name, int mode, snd_config_t *lconf); +int snd_ctl_open_fallback(snd_ctl_t **ctl, snd_config_t *root, const char *name, const char *orig_name, int mode); +int snd_ctl_close(snd_ctl_t *ctl); +int snd_ctl_nonblock(snd_ctl_t *ctl, int nonblock); +static __inline__ int snd_ctl_abort(snd_ctl_t *ctl) { return snd_ctl_nonblock(ctl, 2); } +int snd_async_add_ctl_handler(snd_async_handler_t **handler, snd_ctl_t *ctl, + snd_async_callback_t callback, void *private_data); +snd_ctl_t *snd_async_handler_get_ctl(snd_async_handler_t *handler); +int snd_ctl_poll_descriptors_count(snd_ctl_t *ctl); +int snd_ctl_poll_descriptors(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int space); +int snd_ctl_poll_descriptors_revents(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); +int snd_ctl_subscribe_events(snd_ctl_t *ctl, int subscribe); +int snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info); +int snd_ctl_elem_list(snd_ctl_t *ctl, snd_ctl_elem_list_t *list); +int snd_ctl_elem_info(snd_ctl_t *ctl, snd_ctl_elem_info_t *info); +int snd_ctl_elem_read(snd_ctl_t *ctl, snd_ctl_elem_value_t *data); +int snd_ctl_elem_write(snd_ctl_t *ctl, snd_ctl_elem_value_t *data); +int snd_ctl_elem_lock(snd_ctl_t *ctl, snd_ctl_elem_id_t *id); +int snd_ctl_elem_unlock(snd_ctl_t *ctl, snd_ctl_elem_id_t *id); +int snd_ctl_elem_tlv_read(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, + unsigned int *tlv, unsigned int tlv_size); +int snd_ctl_elem_tlv_write(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, + const unsigned int *tlv); +int snd_ctl_elem_tlv_command(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, + const unsigned int *tlv); +#ifdef __ALSA_HWDEP_H +int snd_ctl_hwdep_next_device(snd_ctl_t *ctl, int * device); +int snd_ctl_hwdep_info(snd_ctl_t *ctl, snd_hwdep_info_t * info); +#endif +#ifdef __ALSA_PCM_H +int snd_ctl_pcm_next_device(snd_ctl_t *ctl, int *device); +int snd_ctl_pcm_info(snd_ctl_t *ctl, snd_pcm_info_t * info); +int snd_ctl_pcm_prefer_subdevice(snd_ctl_t *ctl, int subdev); +#endif +#ifdef __ALSA_RAWMIDI_H +int snd_ctl_rawmidi_next_device(snd_ctl_t *ctl, int * device); +int snd_ctl_rawmidi_info(snd_ctl_t *ctl, snd_rawmidi_info_t * info); +int snd_ctl_rawmidi_prefer_subdevice(snd_ctl_t *ctl, int subdev); +#endif +int snd_ctl_set_power_state(snd_ctl_t *ctl, unsigned int state); +int snd_ctl_get_power_state(snd_ctl_t *ctl, unsigned int *state); + +int snd_ctl_read(snd_ctl_t *ctl, snd_ctl_event_t *event); +int snd_ctl_wait(snd_ctl_t *ctl, int timeout); +const char *snd_ctl_name(snd_ctl_t *ctl); +snd_ctl_type_t snd_ctl_type(snd_ctl_t *ctl); + +const char *snd_ctl_elem_type_name(snd_ctl_elem_type_t type); +const char *snd_ctl_elem_iface_name(snd_ctl_elem_iface_t iface); +const char *snd_ctl_event_type_name(snd_ctl_event_type_t type); + +unsigned int snd_ctl_event_elem_get_mask(const snd_ctl_event_t *obj); +unsigned int snd_ctl_event_elem_get_numid(const snd_ctl_event_t *obj); +void snd_ctl_event_elem_get_id(const snd_ctl_event_t *obj, snd_ctl_elem_id_t *ptr); +snd_ctl_elem_iface_t snd_ctl_event_elem_get_interface(const snd_ctl_event_t *obj); +unsigned int snd_ctl_event_elem_get_device(const snd_ctl_event_t *obj); +unsigned int snd_ctl_event_elem_get_subdevice(const snd_ctl_event_t *obj); +const char *snd_ctl_event_elem_get_name(const snd_ctl_event_t *obj); +unsigned int snd_ctl_event_elem_get_index(const snd_ctl_event_t *obj); + +int snd_ctl_elem_list_alloc_space(snd_ctl_elem_list_t *obj, unsigned int entries); +void snd_ctl_elem_list_free_space(snd_ctl_elem_list_t *obj); + +char *snd_ctl_ascii_elem_id_get(snd_ctl_elem_id_t *id); +int snd_ctl_ascii_elem_id_parse(snd_ctl_elem_id_t *dst, const char *str); +int snd_ctl_ascii_value_parse(snd_ctl_t *handle, + snd_ctl_elem_value_t *dst, + snd_ctl_elem_info_t *info, + const char *value); + +size_t snd_ctl_elem_id_sizeof(void); +/** \hideinitializer + * \brief allocate an invalid #snd_ctl_elem_id_t using standard alloca + * \param ptr returned pointer + */ +#define snd_ctl_elem_id_alloca(ptr) __snd_alloca(ptr, snd_ctl_elem_id) +int snd_ctl_elem_id_malloc(snd_ctl_elem_id_t **ptr); +void snd_ctl_elem_id_free(snd_ctl_elem_id_t *obj); +void snd_ctl_elem_id_clear(snd_ctl_elem_id_t *obj); +void snd_ctl_elem_id_copy(snd_ctl_elem_id_t *dst, const snd_ctl_elem_id_t *src); +unsigned int snd_ctl_elem_id_get_numid(const snd_ctl_elem_id_t *obj); +snd_ctl_elem_iface_t snd_ctl_elem_id_get_interface(const snd_ctl_elem_id_t *obj); +unsigned int snd_ctl_elem_id_get_device(const snd_ctl_elem_id_t *obj); +unsigned int snd_ctl_elem_id_get_subdevice(const snd_ctl_elem_id_t *obj); +const char *snd_ctl_elem_id_get_name(const snd_ctl_elem_id_t *obj); +unsigned int snd_ctl_elem_id_get_index(const snd_ctl_elem_id_t *obj); +void snd_ctl_elem_id_set_numid(snd_ctl_elem_id_t *obj, unsigned int val); +void snd_ctl_elem_id_set_interface(snd_ctl_elem_id_t *obj, snd_ctl_elem_iface_t val); +void snd_ctl_elem_id_set_device(snd_ctl_elem_id_t *obj, unsigned int val); +void snd_ctl_elem_id_set_subdevice(snd_ctl_elem_id_t *obj, unsigned int val); +void snd_ctl_elem_id_set_name(snd_ctl_elem_id_t *obj, const char *val); +void snd_ctl_elem_id_set_index(snd_ctl_elem_id_t *obj, unsigned int val); + +size_t snd_ctl_card_info_sizeof(void); +/** \hideinitializer + * \brief allocate an invalid #snd_ctl_card_info_t using standard alloca + * \param ptr returned pointer + */ +#define snd_ctl_card_info_alloca(ptr) __snd_alloca(ptr, snd_ctl_card_info) +int snd_ctl_card_info_malloc(snd_ctl_card_info_t **ptr); +void snd_ctl_card_info_free(snd_ctl_card_info_t *obj); +void snd_ctl_card_info_clear(snd_ctl_card_info_t *obj); +void snd_ctl_card_info_copy(snd_ctl_card_info_t *dst, const snd_ctl_card_info_t *src); +int snd_ctl_card_info_get_card(const snd_ctl_card_info_t *obj); +const char *snd_ctl_card_info_get_id(const snd_ctl_card_info_t *obj); +const char *snd_ctl_card_info_get_driver(const snd_ctl_card_info_t *obj); +const char *snd_ctl_card_info_get_name(const snd_ctl_card_info_t *obj); +const char *snd_ctl_card_info_get_longname(const snd_ctl_card_info_t *obj); +const char *snd_ctl_card_info_get_mixername(const snd_ctl_card_info_t *obj); +const char *snd_ctl_card_info_get_components(const snd_ctl_card_info_t *obj); + +size_t snd_ctl_event_sizeof(void); +/** \hideinitializer + * \brief allocate an invalid #snd_ctl_event_t using standard alloca + * \param ptr returned pointer + */ +#define snd_ctl_event_alloca(ptr) __snd_alloca(ptr, snd_ctl_event) +int snd_ctl_event_malloc(snd_ctl_event_t **ptr); +void snd_ctl_event_free(snd_ctl_event_t *obj); +void snd_ctl_event_clear(snd_ctl_event_t *obj); +void snd_ctl_event_copy(snd_ctl_event_t *dst, const snd_ctl_event_t *src); +snd_ctl_event_type_t snd_ctl_event_get_type(const snd_ctl_event_t *obj); + +size_t snd_ctl_elem_list_sizeof(void); +/** \hideinitializer + * \brief allocate an invalid #snd_ctl_elem_list_t using standard alloca + * \param ptr returned pointer + */ +#define snd_ctl_elem_list_alloca(ptr) __snd_alloca(ptr, snd_ctl_elem_list) +int snd_ctl_elem_list_malloc(snd_ctl_elem_list_t **ptr); +void snd_ctl_elem_list_free(snd_ctl_elem_list_t *obj); +void snd_ctl_elem_list_clear(snd_ctl_elem_list_t *obj); +void snd_ctl_elem_list_copy(snd_ctl_elem_list_t *dst, const snd_ctl_elem_list_t *src); +void snd_ctl_elem_list_set_offset(snd_ctl_elem_list_t *obj, unsigned int val); +unsigned int snd_ctl_elem_list_get_used(const snd_ctl_elem_list_t *obj); +unsigned int snd_ctl_elem_list_get_count(const snd_ctl_elem_list_t *obj); +void snd_ctl_elem_list_get_id(const snd_ctl_elem_list_t *obj, unsigned int idx, snd_ctl_elem_id_t *ptr); +unsigned int snd_ctl_elem_list_get_numid(const snd_ctl_elem_list_t *obj, unsigned int idx); +snd_ctl_elem_iface_t snd_ctl_elem_list_get_interface(const snd_ctl_elem_list_t *obj, unsigned int idx); +unsigned int snd_ctl_elem_list_get_device(const snd_ctl_elem_list_t *obj, unsigned int idx); +unsigned int snd_ctl_elem_list_get_subdevice(const snd_ctl_elem_list_t *obj, unsigned int idx); +const char *snd_ctl_elem_list_get_name(const snd_ctl_elem_list_t *obj, unsigned int idx); +unsigned int snd_ctl_elem_list_get_index(const snd_ctl_elem_list_t *obj, unsigned int idx); + +size_t snd_ctl_elem_info_sizeof(void); +/** \hideinitializer + * \brief allocate an invalid #snd_ctl_elem_info_t using standard alloca + * \param ptr returned pointer + */ +#define snd_ctl_elem_info_alloca(ptr) __snd_alloca(ptr, snd_ctl_elem_info) +int snd_ctl_elem_info_malloc(snd_ctl_elem_info_t **ptr); +void snd_ctl_elem_info_free(snd_ctl_elem_info_t *obj); +void snd_ctl_elem_info_clear(snd_ctl_elem_info_t *obj); +void snd_ctl_elem_info_copy(snd_ctl_elem_info_t *dst, const snd_ctl_elem_info_t *src); +snd_ctl_elem_type_t snd_ctl_elem_info_get_type(const snd_ctl_elem_info_t *obj); +int snd_ctl_elem_info_is_readable(const snd_ctl_elem_info_t *obj); +int snd_ctl_elem_info_is_writable(const snd_ctl_elem_info_t *obj); +int snd_ctl_elem_info_is_volatile(const snd_ctl_elem_info_t *obj); +int snd_ctl_elem_info_is_inactive(const snd_ctl_elem_info_t *obj); +int snd_ctl_elem_info_is_locked(const snd_ctl_elem_info_t *obj); +int snd_ctl_elem_info_is_tlv_readable(const snd_ctl_elem_info_t *obj); +int snd_ctl_elem_info_is_tlv_writable(const snd_ctl_elem_info_t *obj); +int snd_ctl_elem_info_is_tlv_commandable(const snd_ctl_elem_info_t *obj); +int snd_ctl_elem_info_is_owner(const snd_ctl_elem_info_t *obj); +int snd_ctl_elem_info_is_user(const snd_ctl_elem_info_t *obj); +pid_t snd_ctl_elem_info_get_owner(const snd_ctl_elem_info_t *obj); +unsigned int snd_ctl_elem_info_get_count(const snd_ctl_elem_info_t *obj); +long snd_ctl_elem_info_get_min(const snd_ctl_elem_info_t *obj); +long snd_ctl_elem_info_get_max(const snd_ctl_elem_info_t *obj); +long snd_ctl_elem_info_get_step(const snd_ctl_elem_info_t *obj); +long long snd_ctl_elem_info_get_min64(const snd_ctl_elem_info_t *obj); +long long snd_ctl_elem_info_get_max64(const snd_ctl_elem_info_t *obj); +long long snd_ctl_elem_info_get_step64(const snd_ctl_elem_info_t *obj); +unsigned int snd_ctl_elem_info_get_items(const snd_ctl_elem_info_t *obj); +void snd_ctl_elem_info_set_item(snd_ctl_elem_info_t *obj, unsigned int val); +const char *snd_ctl_elem_info_get_item_name(const snd_ctl_elem_info_t *obj); +int snd_ctl_elem_info_get_dimensions(const snd_ctl_elem_info_t *obj); +int snd_ctl_elem_info_get_dimension(const snd_ctl_elem_info_t *obj, unsigned int idx); +int snd_ctl_elem_info_set_dimension(snd_ctl_elem_info_t *info, + const int dimension[4]); +void snd_ctl_elem_info_get_id(const snd_ctl_elem_info_t *obj, snd_ctl_elem_id_t *ptr); +unsigned int snd_ctl_elem_info_get_numid(const snd_ctl_elem_info_t *obj); +snd_ctl_elem_iface_t snd_ctl_elem_info_get_interface(const snd_ctl_elem_info_t *obj); +unsigned int snd_ctl_elem_info_get_device(const snd_ctl_elem_info_t *obj); +unsigned int snd_ctl_elem_info_get_subdevice(const snd_ctl_elem_info_t *obj); +const char *snd_ctl_elem_info_get_name(const snd_ctl_elem_info_t *obj); +unsigned int snd_ctl_elem_info_get_index(const snd_ctl_elem_info_t *obj); +void snd_ctl_elem_info_set_id(snd_ctl_elem_info_t *obj, const snd_ctl_elem_id_t *ptr); +void snd_ctl_elem_info_set_numid(snd_ctl_elem_info_t *obj, unsigned int val); +void snd_ctl_elem_info_set_interface(snd_ctl_elem_info_t *obj, snd_ctl_elem_iface_t val); +void snd_ctl_elem_info_set_device(snd_ctl_elem_info_t *obj, unsigned int val); +void snd_ctl_elem_info_set_subdevice(snd_ctl_elem_info_t *obj, unsigned int val); +void snd_ctl_elem_info_set_name(snd_ctl_elem_info_t *obj, const char *val); +void snd_ctl_elem_info_set_index(snd_ctl_elem_info_t *obj, unsigned int val); + +int snd_ctl_add_integer_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info, + unsigned int element_count, + unsigned int member_count, + long min, long max, long step); +int snd_ctl_add_integer64_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info, + unsigned int element_count, + unsigned int member_count, + long long min, long long max, + long long step); +int snd_ctl_add_boolean_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info, + unsigned int element_count, + unsigned int member_count); +int snd_ctl_add_enumerated_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info, + unsigned int element_count, + unsigned int member_count, + unsigned int items, + const char *const labels[]); +int snd_ctl_add_bytes_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info, + unsigned int element_count, + unsigned int member_count); + +int snd_ctl_elem_add_integer(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, unsigned int count, long imin, long imax, long istep); +int snd_ctl_elem_add_integer64(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, unsigned int count, long long imin, long long imax, long long istep); +int snd_ctl_elem_add_boolean(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, unsigned int count); +int snd_ctl_elem_add_enumerated(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, unsigned int count, unsigned int items, const char *const names[]); +int snd_ctl_elem_add_iec958(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id); +int snd_ctl_elem_remove(snd_ctl_t *ctl, snd_ctl_elem_id_t *id); + +size_t snd_ctl_elem_value_sizeof(void); +/** \hideinitializer + * \brief allocate an invalid #snd_ctl_elem_value_t using standard alloca + * \param ptr returned pointer + */ +#define snd_ctl_elem_value_alloca(ptr) __snd_alloca(ptr, snd_ctl_elem_value) +int snd_ctl_elem_value_malloc(snd_ctl_elem_value_t **ptr); +void snd_ctl_elem_value_free(snd_ctl_elem_value_t *obj); +void snd_ctl_elem_value_clear(snd_ctl_elem_value_t *obj); +void snd_ctl_elem_value_copy(snd_ctl_elem_value_t *dst, const snd_ctl_elem_value_t *src); +int snd_ctl_elem_value_compare(snd_ctl_elem_value_t *left, const snd_ctl_elem_value_t *right); +void snd_ctl_elem_value_get_id(const snd_ctl_elem_value_t *obj, snd_ctl_elem_id_t *ptr); +unsigned int snd_ctl_elem_value_get_numid(const snd_ctl_elem_value_t *obj); +snd_ctl_elem_iface_t snd_ctl_elem_value_get_interface(const snd_ctl_elem_value_t *obj); +unsigned int snd_ctl_elem_value_get_device(const snd_ctl_elem_value_t *obj); +unsigned int snd_ctl_elem_value_get_subdevice(const snd_ctl_elem_value_t *obj); +const char *snd_ctl_elem_value_get_name(const snd_ctl_elem_value_t *obj); +unsigned int snd_ctl_elem_value_get_index(const snd_ctl_elem_value_t *obj); +void snd_ctl_elem_value_set_id(snd_ctl_elem_value_t *obj, const snd_ctl_elem_id_t *ptr); +void snd_ctl_elem_value_set_numid(snd_ctl_elem_value_t *obj, unsigned int val); +void snd_ctl_elem_value_set_interface(snd_ctl_elem_value_t *obj, snd_ctl_elem_iface_t val); +void snd_ctl_elem_value_set_device(snd_ctl_elem_value_t *obj, unsigned int val); +void snd_ctl_elem_value_set_subdevice(snd_ctl_elem_value_t *obj, unsigned int val); +void snd_ctl_elem_value_set_name(snd_ctl_elem_value_t *obj, const char *val); +void snd_ctl_elem_value_set_index(snd_ctl_elem_value_t *obj, unsigned int val); +int snd_ctl_elem_value_get_boolean(const snd_ctl_elem_value_t *obj, unsigned int idx); +long snd_ctl_elem_value_get_integer(const snd_ctl_elem_value_t *obj, unsigned int idx); +long long snd_ctl_elem_value_get_integer64(const snd_ctl_elem_value_t *obj, unsigned int idx); +unsigned int snd_ctl_elem_value_get_enumerated(const snd_ctl_elem_value_t *obj, unsigned int idx); +unsigned char snd_ctl_elem_value_get_byte(const snd_ctl_elem_value_t *obj, unsigned int idx); +void snd_ctl_elem_value_set_boolean(snd_ctl_elem_value_t *obj, unsigned int idx, long val); +void snd_ctl_elem_value_set_integer(snd_ctl_elem_value_t *obj, unsigned int idx, long val); +void snd_ctl_elem_value_set_integer64(snd_ctl_elem_value_t *obj, unsigned int idx, long long val); +void snd_ctl_elem_value_set_enumerated(snd_ctl_elem_value_t *obj, unsigned int idx, unsigned int val); +void snd_ctl_elem_value_set_byte(snd_ctl_elem_value_t *obj, unsigned int idx, unsigned char val); +void snd_ctl_elem_set_bytes(snd_ctl_elem_value_t *obj, void *data, size_t size); +const void * snd_ctl_elem_value_get_bytes(const snd_ctl_elem_value_t *obj); +void snd_ctl_elem_value_get_iec958(const snd_ctl_elem_value_t *obj, snd_aes_iec958_t *ptr); +void snd_ctl_elem_value_set_iec958(snd_ctl_elem_value_t *obj, const snd_aes_iec958_t *ptr); + +int snd_tlv_parse_dB_info(unsigned int *tlv, unsigned int tlv_size, + unsigned int **db_tlvp); +int snd_tlv_get_dB_range(unsigned int *tlv, long rangemin, long rangemax, + long *min, long *max); +int snd_tlv_convert_to_dB(unsigned int *tlv, long rangemin, long rangemax, + long volume, long *db_gain); +int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax, + long db_gain, long *value, int xdir); +int snd_ctl_get_dB_range(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, + long *min, long *max); +int snd_ctl_convert_to_dB(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, + long volume, long *db_gain); +int snd_ctl_convert_from_dB(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, + long db_gain, long *value, int xdir); + +/** + * \defgroup HControl High level Control Interface + * \ingroup Control + * The high level control interface. + * See \ref hcontrol page for more details. + * \{ + */ + +/** HCTL element handle */ +typedef struct _snd_hctl_elem snd_hctl_elem_t; + +/** HCTL handle */ +typedef struct _snd_hctl snd_hctl_t; + +/** + * \brief Compare function for sorting HCTL elements + * \param e1 First element + * \param e2 Second element + * \return -1 if e1 < e2, 0 if e1 == e2, 1 if e1 > e2 + */ +typedef int (*snd_hctl_compare_t)(const snd_hctl_elem_t *e1, + const snd_hctl_elem_t *e2); +int snd_hctl_compare_fast(const snd_hctl_elem_t *c1, + const snd_hctl_elem_t *c2); +/** + * \brief HCTL callback function + * \param hctl HCTL handle + * \param mask event mask + * \param elem related HCTL element (if any) + * \return 0 on success otherwise a negative error code + */ +typedef int (*snd_hctl_callback_t)(snd_hctl_t *hctl, + unsigned int mask, + snd_hctl_elem_t *elem); +/** + * \brief HCTL element callback function + * \param elem HCTL element + * \param mask event mask + * \return 0 on success otherwise a negative error code + */ +typedef int (*snd_hctl_elem_callback_t)(snd_hctl_elem_t *elem, + unsigned int mask); + +int snd_hctl_open(snd_hctl_t **hctl, const char *name, int mode); +int snd_hctl_open_ctl(snd_hctl_t **hctlp, snd_ctl_t *ctl); +int snd_hctl_close(snd_hctl_t *hctl); +int snd_hctl_nonblock(snd_hctl_t *hctl, int nonblock); +static __inline__ int snd_hctl_abort(snd_hctl_t *hctl) { return snd_hctl_nonblock(hctl, 2); } +int snd_hctl_poll_descriptors_count(snd_hctl_t *hctl); +int snd_hctl_poll_descriptors(snd_hctl_t *hctl, struct pollfd *pfds, unsigned int space); +int snd_hctl_poll_descriptors_revents(snd_hctl_t *ctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); +unsigned int snd_hctl_get_count(snd_hctl_t *hctl); +int snd_hctl_set_compare(snd_hctl_t *hctl, snd_hctl_compare_t hsort); +snd_hctl_elem_t *snd_hctl_first_elem(snd_hctl_t *hctl); +snd_hctl_elem_t *snd_hctl_last_elem(snd_hctl_t *hctl); +snd_hctl_elem_t *snd_hctl_find_elem(snd_hctl_t *hctl, const snd_ctl_elem_id_t *id); +void snd_hctl_set_callback(snd_hctl_t *hctl, snd_hctl_callback_t callback); +void snd_hctl_set_callback_private(snd_hctl_t *hctl, void *data); +void *snd_hctl_get_callback_private(snd_hctl_t *hctl); +int snd_hctl_load(snd_hctl_t *hctl); +int snd_hctl_free(snd_hctl_t *hctl); +int snd_hctl_handle_events(snd_hctl_t *hctl); +const char *snd_hctl_name(snd_hctl_t *hctl); +int snd_hctl_wait(snd_hctl_t *hctl, int timeout); +snd_ctl_t *snd_hctl_ctl(snd_hctl_t *hctl); + +snd_hctl_elem_t *snd_hctl_elem_next(snd_hctl_elem_t *elem); +snd_hctl_elem_t *snd_hctl_elem_prev(snd_hctl_elem_t *elem); +int snd_hctl_elem_info(snd_hctl_elem_t *elem, snd_ctl_elem_info_t * info); +int snd_hctl_elem_read(snd_hctl_elem_t *elem, snd_ctl_elem_value_t * value); +int snd_hctl_elem_write(snd_hctl_elem_t *elem, snd_ctl_elem_value_t * value); +int snd_hctl_elem_tlv_read(snd_hctl_elem_t *elem, unsigned int *tlv, unsigned int tlv_size); +int snd_hctl_elem_tlv_write(snd_hctl_elem_t *elem, const unsigned int *tlv); +int snd_hctl_elem_tlv_command(snd_hctl_elem_t *elem, const unsigned int *tlv); + +snd_hctl_t *snd_hctl_elem_get_hctl(snd_hctl_elem_t *elem); + +void snd_hctl_elem_get_id(const snd_hctl_elem_t *obj, snd_ctl_elem_id_t *ptr); +unsigned int snd_hctl_elem_get_numid(const snd_hctl_elem_t *obj); +snd_ctl_elem_iface_t snd_hctl_elem_get_interface(const snd_hctl_elem_t *obj); +unsigned int snd_hctl_elem_get_device(const snd_hctl_elem_t *obj); +unsigned int snd_hctl_elem_get_subdevice(const snd_hctl_elem_t *obj); +const char *snd_hctl_elem_get_name(const snd_hctl_elem_t *obj); +unsigned int snd_hctl_elem_get_index(const snd_hctl_elem_t *obj); +void snd_hctl_elem_set_callback(snd_hctl_elem_t *obj, snd_hctl_elem_callback_t val); +void * snd_hctl_elem_get_callback_private(const snd_hctl_elem_t *obj); +void snd_hctl_elem_set_callback_private(snd_hctl_elem_t *obj, void * val); + +/** \} */ + +/** \} */ + +/** + * \defgroup SControl Setup Control Interface + * \ingroup Control + * The setup control interface - set or modify control elements from a configuration file. + * \{ + */ + +int snd_sctl_build(snd_sctl_t **ctl, snd_ctl_t *handle, snd_config_t *config, + snd_config_t *private_data, int mode); +int snd_sctl_free(snd_sctl_t *handle); +int snd_sctl_install(snd_sctl_t *handle); +int snd_sctl_remove(snd_sctl_t *handle); + +/** \} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALSA_CONTROL_H */ diff --git a/thirdparty/linuxbsd_headers/alsa/control_external.h b/thirdparty/linuxbsd_headers/alsa/control_external.h new file mode 100644 index 0000000000..12958e70a5 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/control_external.h @@ -0,0 +1,286 @@ +/** + * \file include/control_external.h + * \brief External control plugin SDK + * \author Takashi Iwai <tiwai@suse.de> + * \date 2005 + * + * External control plugin SDK. + */ + +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef __ALSA_CONTROL_EXTERNAL_H +#define __ALSA_CONTROL_EXTERNAL_H + +#include "control.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup CtlPlugin_SDK External Control Plugin SDK + * \{ + */ + +/** + * Define the object entry for external control plugins + */ +#define SND_CTL_PLUGIN_ENTRY(name) _snd_ctl_##name##_open + +/** + * Define the symbols of the given control plugin with versions + */ +#define SND_CTL_PLUGIN_SYMBOL(name) SND_DLSYM_BUILD_VERSION(SND_CTL_PLUGIN_ENTRY(name), SND_CONTROL_DLSYM_VERSION); + +/** + * Define the control plugin + */ +#define SND_CTL_PLUGIN_DEFINE_FUNC(plugin) \ +int SND_CTL_PLUGIN_ENTRY(plugin) (snd_ctl_t **handlep, const char *name,\ + snd_config_t *root, snd_config_t *conf, int mode) + +/** External control plugin handle */ +typedef struct snd_ctl_ext snd_ctl_ext_t; +/** Callback table of control ext */ +typedef struct snd_ctl_ext_callback snd_ctl_ext_callback_t; +/** Key to access a control pointer */ +typedef unsigned long snd_ctl_ext_key_t; +#ifdef DOC_HIDDEN +/* redefine typedef's for stupid doxygen */ +typedef snd_ctl_ext snd_ctl_ext_t; +typedef snd_ctl_ext_callback snd_ctl_ext_callback_t; +#endif +/** Callback to handle TLV commands. */ +typedef int (snd_ctl_ext_tlv_rw_t)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, int op_flag, unsigned int numid, + unsigned int *tlv, unsigned int tlv_size); + +/* + * Protocol version + */ +#define SND_CTL_EXT_VERSION_MAJOR 1 /**< Protocol major version */ +#define SND_CTL_EXT_VERSION_MINOR 0 /**< Protocol minor version */ +#define SND_CTL_EXT_VERSION_TINY 1 /**< Protocol tiny version */ +/** + * external plugin protocol version + */ +#define SND_CTL_EXT_VERSION ((SND_CTL_EXT_VERSION_MAJOR<<16) |\ + (SND_CTL_EXT_VERSION_MINOR<<8) |\ + (SND_CTL_EXT_VERSION_TINY)) + +/** Handle of control ext */ +struct snd_ctl_ext { + /** + * protocol version; #SND_CTL_EXT_VERSION must be filled here + * before calling #snd_ctl_ext_create() + */ + unsigned int version; + /** + * Index of this card; must be filled before calling #snd_ctl_ext_create() + */ + int card_idx; + /** + * ID string of this card; must be filled before calling #snd_ctl_ext_create() + */ + char id[16]; + /** + * Driver name of this card; must be filled before calling #snd_ctl_ext_create() + */ + char driver[16]; + /** + * short name of this card; must be filled before calling #snd_ctl_ext_create() + */ + char name[32]; + /** + * Long name of this card; must be filled before calling #snd_ctl_ext_create() + */ + char longname[80]; + /** + * Mixer name of this card; must be filled before calling #snd_ctl_ext_create() + */ + char mixername[80]; + /** + * poll descriptor + */ + int poll_fd; + + /** + * callbacks of this plugin; must be filled before calling #snd_pcm_ioplug_create() + */ + const snd_ctl_ext_callback_t *callback; + /** + * private data, which can be used freely in the driver callbacks + */ + void *private_data; + /** + * control handle filled by #snd_ctl_ext_create() + */ + snd_ctl_t *handle; + + int nonblock; /**< non-block mode; read-only */ + int subscribed; /**< events subscribed; read-only */ + + /** + * optional TLV data for the control (since protocol 1.0.1) + */ + union { + snd_ctl_ext_tlv_rw_t *c; + const unsigned int *p; + } tlv; +}; + +/** Callback table of ext. */ +struct snd_ctl_ext_callback { + /** + * close the control handle; optional + */ + void (*close)(snd_ctl_ext_t *ext); + /** + * return the total number of elements; required + */ + int (*elem_count)(snd_ctl_ext_t *ext); + /** + * return the element id of the given offset (array index); required + */ + int (*elem_list)(snd_ctl_ext_t *ext, unsigned int offset, snd_ctl_elem_id_t *id); + /** + * convert the element id to a search key; required + */ + snd_ctl_ext_key_t (*find_elem)(snd_ctl_ext_t *ext, const snd_ctl_elem_id_t *id); + /** + * the destructor of the key; optional + */ + void (*free_key)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key); + /** + * get the attribute of the element; required + */ + int (*get_attribute)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, + int *type, unsigned int *acc, unsigned int *count); + /** + * get the element information of integer type + */ + int (*get_integer_info)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, + long *imin, long *imax, long *istep); + /** + * get the element information of integer64 type + */ + int (*get_integer64_info)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, + int64_t *imin, int64_t *imax, int64_t *istep); + /** + * get the element information of enumerated type + */ + int (*get_enumerated_info)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned int *items); + /** + * get the name of the enumerated item + */ + int (*get_enumerated_name)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned int item, + char *name, size_t name_max_len); + /** + * read the current values of integer type + */ + int (*read_integer)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, long *value); + /** + * read the current values of integer64 type + */ + int (*read_integer64)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, int64_t *value); + /** + * read the current values of enumerated type + */ + int (*read_enumerated)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned int *items); + /** + * read the current values of bytes type + */ + int (*read_bytes)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned char *data, + size_t max_bytes); + /** + * read the current values of iec958 type + */ + int (*read_iec958)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, snd_aes_iec958_t *iec958); + /** + * update the current values of integer type with the given values + */ + int (*write_integer)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, long *value); + /** + * update the current values of integer64 type with the given values + */ + int (*write_integer64)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, int64_t *value); + /** + * update the current values of enumerated type with the given values + */ + int (*write_enumerated)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned int *items); + /** + * update the current values of bytes type with the given values + */ + int (*write_bytes)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned char *data, + size_t max_bytes); + /** + * update the current values of iec958 type with the given values + */ + int (*write_iec958)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, snd_aes_iec958_t *iec958); + /** + * subscribe/unsubscribe the event notification; optional + */ + void (*subscribe_events)(snd_ctl_ext_t *ext, int subscribe); + /** + * read a pending notification event; optional + */ + int (*read_event)(snd_ctl_ext_t *ext, snd_ctl_elem_id_t *id, unsigned int *event_mask); + /** + * return the number of poll descriptors; optional + */ + int (*poll_descriptors_count)(snd_ctl_ext_t *ext); + /** + * fill the poll descriptors; optional + */ + int (*poll_descriptors)(snd_ctl_ext_t *ext, struct pollfd *pfds, unsigned int space); + /** + * mangle the revents of poll descriptors + */ + int (*poll_revents)(snd_ctl_ext_t *ext, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); +}; + +/** + * The access type bits stored in get_attribute callback + */ +typedef enum snd_ctl_ext_access { + SND_CTL_EXT_ACCESS_READ = (1<<0), + SND_CTL_EXT_ACCESS_WRITE = (1<<1), + SND_CTL_EXT_ACCESS_READWRITE = (3<<0), + SND_CTL_EXT_ACCESS_VOLATILE = (1<<2), + SND_CTL_EXT_ACCESS_TLV_READ = (1<<4), + SND_CTL_EXT_ACCESS_TLV_WRITE = (1<<5), + SND_CTL_EXT_ACCESS_TLV_READWRITE = (3<<4), + SND_CTL_EXT_ACCESS_TLV_COMMAND = (1<<6), + SND_CTL_EXT_ACCESS_INACTIVE = (1<<8), + SND_CTL_EXT_ACCESS_TLV_CALLBACK = (1<<28), +} snd_ctl_ext_access_t; + +/** + * find_elem callback returns this if no matching control element is found + */ +#define SND_CTL_EXT_KEY_NOT_FOUND (snd_ctl_ext_key_t)(-1) + +int snd_ctl_ext_create(snd_ctl_ext_t *ext, const char *name, int mode); +int snd_ctl_ext_delete(snd_ctl_ext_t *ext); + +/** \} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALSA_CONTROL_EXTERNAL_H */ diff --git a/thirdparty/linuxbsd_headers/alsa/error.h b/thirdparty/linuxbsd_headers/alsa/error.h new file mode 100644 index 0000000000..38ee0704d2 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/error.h @@ -0,0 +1,85 @@ +/** + * \file include/error.h + * \brief Application interface library for the ALSA driver + * \author Jaroslav Kysela <perex@perex.cz> + * \author Abramo Bagnara <abramo@alsa-project.org> + * \author Takashi Iwai <tiwai@suse.de> + * \date 1998-2001 + * + * Application interface library for the ALSA driver + */ +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_ERROR_H +#define __ALSA_ERROR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup Error Error handling + * Error handling macros and functions. + * \{ + */ + +#define SND_ERROR_BEGIN 500000 /**< Lower boundary of sound error codes. */ +#define SND_ERROR_INCOMPATIBLE_VERSION (SND_ERROR_BEGIN+0) /**< Kernel/library protocols are not compatible. */ +#define SND_ERROR_ALISP_NIL (SND_ERROR_BEGIN+1) /**< Lisp encountered an error during acall. */ + +const char *snd_strerror(int errnum); + +/** + * \brief Error handler callback. + * \param file Source file name. + * \param line Line number. + * \param function Function name. + * \param err Value of \c errno, or 0 if not relevant. + * \param fmt \c printf(3) format. + * \param ... \c printf(3) arguments. + * + * A function of this type is called by the ALSA library when an error occurs. + * This function usually shows the message on the screen, and/or logs it. + */ +typedef void (*snd_lib_error_handler_t)(const char *file, int line, const char *function, int err, const char *fmt, ...) /* __attribute__ ((format (printf, 5, 6))) */; +extern snd_lib_error_handler_t snd_lib_error; +extern int snd_lib_error_set_handler(snd_lib_error_handler_t handler); + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 95) +#define SNDERR(...) snd_lib_error(__FILE__, __LINE__, __FUNCTION__, 0, __VA_ARGS__) /**< Shows a sound error message. */ +#define SYSERR(...) snd_lib_error(__FILE__, __LINE__, __FUNCTION__, errno, __VA_ARGS__) /**< Shows a system error message (related to \c errno). */ +#else +#define SNDERR(args...) snd_lib_error(__FILE__, __LINE__, __FUNCTION__, 0, ##args) /**< Shows a sound error message. */ +#define SYSERR(args...) snd_lib_error(__FILE__, __LINE__, __FUNCTION__, errno, ##args) /**< Shows a system error message (related to \c errno). */ +#endif + +/** \} */ + +#ifdef __cplusplus +} +#endif + +/** Local error handler function type */ +typedef void (*snd_local_error_handler_t)(const char *file, int line, + const char *func, int err, + const char *fmt, va_list arg); + +snd_local_error_handler_t snd_lib_error_set_local(snd_local_error_handler_t func); + +#endif /* __ALSA_ERROR_H */ + diff --git a/thirdparty/linuxbsd_headers/alsa/global.h b/thirdparty/linuxbsd_headers/alsa/global.h new file mode 100644 index 0000000000..16a26dc835 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/global.h @@ -0,0 +1,161 @@ +/** + * \file include/global.h + * \brief Application interface library for the ALSA driver + * \author Jaroslav Kysela <perex@perex.cz> + * \author Abramo Bagnara <abramo@alsa-project.org> + * \author Takashi Iwai <tiwai@suse.de> + * \date 1998-2001 + * + * Application interface library for the ALSA driver + */ +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_GLOBAL_H_ +#define __ALSA_GLOBAL_H_ + +/* for timeval and timespec */ +#include <time.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup Global Global defines and functions + * Global defines and functions. + * \par + * The ALSA library implementation uses these macros and functions. + * Most applications probably do not need them. + * \{ + */ + +const char *snd_asoundlib_version(void); + +#ifndef ATTRIBUTE_UNUSED +/** do not print warning (gcc) when function parameter is not used */ +#define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +#endif + +#ifdef PIC /* dynamic build */ + +/** \hideinitializer \brief Helper macro for #SND_DLSYM_BUILD_VERSION. */ +#define __SND_DLSYM_VERSION(name, version) _ ## name ## version +/** + * \hideinitializer + * \brief Appends the build version to the name of a versioned dynamic symbol. + */ +#define SND_DLSYM_BUILD_VERSION(name, version) char __SND_DLSYM_VERSION(name, version); + +#else /* static build */ + +struct snd_dlsym_link { + struct snd_dlsym_link *next; + const char *dlsym_name; + const void *dlsym_ptr; +}; + +extern struct snd_dlsym_link *snd_dlsym_start; + +/** \hideinitializer \brief Helper macro for #SND_DLSYM_BUILD_VERSION. */ +#define __SND_DLSYM_VERSION(prefix, name, version) _ ## prefix ## name ## version +/** + * \hideinitializer + * \brief Appends the build version to the name of a versioned dynamic symbol. + */ +#define SND_DLSYM_BUILD_VERSION(name, version) \ + static struct snd_dlsym_link __SND_DLSYM_VERSION(snd_dlsym_, name, version); \ + void __SND_DLSYM_VERSION(snd_dlsym_constructor_, name, version) (void) __attribute__ ((constructor)); \ + void __SND_DLSYM_VERSION(snd_dlsym_constructor_, name, version) (void) { \ + __SND_DLSYM_VERSION(snd_dlsym_, name, version).next = snd_dlsym_start; \ + __SND_DLSYM_VERSION(snd_dlsym_, name, version).dlsym_name = # name; \ + __SND_DLSYM_VERSION(snd_dlsym_, name, version).dlsym_ptr = (void *)&name; \ + snd_dlsym_start = &__SND_DLSYM_VERSION(snd_dlsym_, name, version); \ + } + +#endif + +#ifndef __STRING +/** \brief Return 'x' argument as string */ +#define __STRING(x) #x +#endif + +/** \brief Returns the version of a dynamic symbol as a string. */ +#define SND_DLSYM_VERSION(version) __STRING(version) + +void *snd_dlopen(const char *file, int mode); +void *snd_dlsym(void *handle, const char *name, const char *version); +int snd_dlclose(void *handle); + + +/** \brief alloca helper macro. */ +#define __snd_alloca(ptr,type) do { *ptr = (type##_t *) alloca(type##_sizeof()); memset(*ptr, 0, type##_sizeof()); } while (0) + +/** + * \brief Internal structure for an async notification client handler. + * + * The ALSA library uses a pointer to this structure as a handle to an async + * notification object. Applications don't access its contents directly. + */ +typedef struct _snd_async_handler snd_async_handler_t; + +/** + * \brief Async notification callback. + * + * See the #snd_async_add_handler function for details. + */ +typedef void (*snd_async_callback_t)(snd_async_handler_t *handler); + +int snd_async_add_handler(snd_async_handler_t **handler, int fd, + snd_async_callback_t callback, void *private_data); +int snd_async_del_handler(snd_async_handler_t *handler); +int snd_async_handler_get_fd(snd_async_handler_t *handler); +int snd_async_handler_get_signo(snd_async_handler_t *handler); +void *snd_async_handler_get_callback_private(snd_async_handler_t *handler); + +struct snd_shm_area *snd_shm_area_create(int shmid, void *ptr); +struct snd_shm_area *snd_shm_area_share(struct snd_shm_area *area); +int snd_shm_area_destroy(struct snd_shm_area *area); + +int snd_user_file(const char *file, char **result); + +#ifdef __GLIBC__ +#if !defined(_POSIX_C_SOURCE) && !defined(_POSIX_SOURCE) +struct timeval { + time_t tv_sec; /* seconds */ + long tv_usec; /* microseconds */ +}; + +struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* nanoseconds */ +}; +#endif +#endif + +/** Timestamp */ +typedef struct timeval snd_timestamp_t; +/** Hi-res timestamp */ +typedef struct timespec snd_htimestamp_t; + +/** \} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALSA_GLOBAL_H */ diff --git a/thirdparty/linuxbsd_headers/alsa/hwdep.h b/thirdparty/linuxbsd_headers/alsa/hwdep.h new file mode 100644 index 0000000000..2fe78cd84d --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/hwdep.h @@ -0,0 +1,169 @@ +/** + * \file include/hwdep.h + * \brief Application interface library for the ALSA driver + * \author Jaroslav Kysela <perex@perex.cz> + * \author Abramo Bagnara <abramo@alsa-project.org> + * \author Takashi Iwai <tiwai@suse.de> + * \date 1998-2001 + * + * Application interface library for the ALSA driver + */ +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_HWDEP_H +#define __ALSA_HWDEP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup HwDep Hardware Dependant Interface + * The Hardware Dependant Interface. + * \{ + */ + +/** dlsym version for interface entry callback */ +#define SND_HWDEP_DLSYM_VERSION _dlsym_hwdep_001 + +/** HwDep information container */ +typedef struct _snd_hwdep_info snd_hwdep_info_t; + +/** HwDep DSP status container */ +typedef struct _snd_hwdep_dsp_status snd_hwdep_dsp_status_t; + +/** HwDep DSP image container */ +typedef struct _snd_hwdep_dsp_image snd_hwdep_dsp_image_t; + +/** HwDep interface */ +typedef enum _snd_hwdep_iface { + SND_HWDEP_IFACE_OPL2 = 0, /**< OPL2 raw driver */ + SND_HWDEP_IFACE_OPL3, /**< OPL3 raw driver */ + SND_HWDEP_IFACE_OPL4, /**< OPL4 raw driver */ + SND_HWDEP_IFACE_SB16CSP, /**< SB16CSP driver */ + SND_HWDEP_IFACE_EMU10K1, /**< EMU10K1 driver */ + SND_HWDEP_IFACE_YSS225, /**< YSS225 driver */ + SND_HWDEP_IFACE_ICS2115, /**< ICS2115 driver */ + SND_HWDEP_IFACE_SSCAPE, /**< Ensoniq SoundScape ISA card (MC68EC000) */ + SND_HWDEP_IFACE_VX, /**< Digigram VX cards */ + SND_HWDEP_IFACE_MIXART, /**< Digigram miXart cards */ + SND_HWDEP_IFACE_USX2Y, /**< Tascam US122, US224 & US428 usb */ + SND_HWDEP_IFACE_EMUX_WAVETABLE, /**< EmuX wavetable */ + SND_HWDEP_IFACE_BLUETOOTH, /**< Bluetooth audio */ + SND_HWDEP_IFACE_USX2Y_PCM, /**< Tascam US122, US224 & US428 raw USB PCM */ + SND_HWDEP_IFACE_PCXHR, /**< Digigram PCXHR */ + SND_HWDEP_IFACE_SB_RC, /**< SB Extigy/Audigy2NX remote control */ + SND_HWDEP_IFACE_HDA, /**< HD-audio */ + SND_HWDEP_IFACE_USB_STREAM, /**< direct access to usb stream */ + SND_HWDEP_IFACE_FW_DICE, /**< TC DICE FireWire device */ + SND_HWDEP_IFACE_FW_FIREWORKS, /**< Echo Audio Fireworks based device */ + SND_HWDEP_IFACE_FW_BEBOB, /**< BridgeCo BeBoB based device */ + SND_HWDEP_IFACE_FW_OXFW, /**< Oxford OXFW970/971 based device */ + SND_HWDEP_IFACE_FW_DIGI00X, /* Digidesign Digi 002/003 family */ + SND_HWDEP_IFACE_FW_TASCAM, /* TASCAM FireWire series */ + + SND_HWDEP_IFACE_LAST = SND_HWDEP_IFACE_FW_TASCAM /**< last known hwdep interface */ +} snd_hwdep_iface_t; + +/** open for reading */ +#define SND_HWDEP_OPEN_READ (O_RDONLY) +/** open for writing */ +#define SND_HWDEP_OPEN_WRITE (O_WRONLY) +/** open for reading and writing */ +#define SND_HWDEP_OPEN_DUPLEX (O_RDWR) +/** open mode flag: open in nonblock mode */ +#define SND_HWDEP_OPEN_NONBLOCK (O_NONBLOCK) + +/** HwDep handle type */ +typedef enum _snd_hwdep_type { + /** Kernel level HwDep */ + SND_HWDEP_TYPE_HW, + /** Shared memory client HwDep (not yet implemented) */ + SND_HWDEP_TYPE_SHM, + /** INET client HwDep (not yet implemented) */ + SND_HWDEP_TYPE_INET +} snd_hwdep_type_t; + +/** HwDep handle */ +typedef struct _snd_hwdep snd_hwdep_t; + +int snd_hwdep_open(snd_hwdep_t **hwdep, const char *name, int mode); +int snd_hwdep_close(snd_hwdep_t *hwdep); +int snd_hwdep_poll_descriptors(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned int space); +int snd_hwdep_poll_descriptors_count(snd_hwdep_t *hwdep); +int snd_hwdep_poll_descriptors_revents(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); +int snd_hwdep_nonblock(snd_hwdep_t *hwdep, int nonblock); +int snd_hwdep_info(snd_hwdep_t *hwdep, snd_hwdep_info_t * info); +int snd_hwdep_dsp_status(snd_hwdep_t *hwdep, snd_hwdep_dsp_status_t *status); +int snd_hwdep_dsp_load(snd_hwdep_t *hwdep, snd_hwdep_dsp_image_t *block); +int snd_hwdep_ioctl(snd_hwdep_t *hwdep, unsigned int request, void * arg); +ssize_t snd_hwdep_write(snd_hwdep_t *hwdep, const void *buffer, size_t size); +ssize_t snd_hwdep_read(snd_hwdep_t *hwdep, void *buffer, size_t size); + +size_t snd_hwdep_info_sizeof(void); +/** allocate #snd_hwdep_info_t container on stack */ +#define snd_hwdep_info_alloca(ptr) __snd_alloca(ptr, snd_hwdep_info) +int snd_hwdep_info_malloc(snd_hwdep_info_t **ptr); +void snd_hwdep_info_free(snd_hwdep_info_t *obj); +void snd_hwdep_info_copy(snd_hwdep_info_t *dst, const snd_hwdep_info_t *src); + +unsigned int snd_hwdep_info_get_device(const snd_hwdep_info_t *obj); +int snd_hwdep_info_get_card(const snd_hwdep_info_t *obj); +const char *snd_hwdep_info_get_id(const snd_hwdep_info_t *obj); +const char *snd_hwdep_info_get_name(const snd_hwdep_info_t *obj); +snd_hwdep_iface_t snd_hwdep_info_get_iface(const snd_hwdep_info_t *obj); +void snd_hwdep_info_set_device(snd_hwdep_info_t *obj, unsigned int val); + +size_t snd_hwdep_dsp_status_sizeof(void); +/** allocate #snd_hwdep_dsp_status_t container on stack */ +#define snd_hwdep_dsp_status_alloca(ptr) __snd_alloca(ptr, snd_hwdep_dsp_status) +int snd_hwdep_dsp_status_malloc(snd_hwdep_dsp_status_t **ptr); +void snd_hwdep_dsp_status_free(snd_hwdep_dsp_status_t *obj); +void snd_hwdep_dsp_status_copy(snd_hwdep_dsp_status_t *dst, const snd_hwdep_dsp_status_t *src); + +unsigned int snd_hwdep_dsp_status_get_version(const snd_hwdep_dsp_status_t *obj); +const char *snd_hwdep_dsp_status_get_id(const snd_hwdep_dsp_status_t *obj); +unsigned int snd_hwdep_dsp_status_get_num_dsps(const snd_hwdep_dsp_status_t *obj); +unsigned int snd_hwdep_dsp_status_get_dsp_loaded(const snd_hwdep_dsp_status_t *obj); +unsigned int snd_hwdep_dsp_status_get_chip_ready(const snd_hwdep_dsp_status_t *obj); + +size_t snd_hwdep_dsp_image_sizeof(void); +/** allocate #snd_hwdep_dsp_image_t container on stack */ +#define snd_hwdep_dsp_image_alloca(ptr) __snd_alloca(ptr, snd_hwdep_dsp_image) +int snd_hwdep_dsp_image_malloc(snd_hwdep_dsp_image_t **ptr); +void snd_hwdep_dsp_image_free(snd_hwdep_dsp_image_t *obj); +void snd_hwdep_dsp_image_copy(snd_hwdep_dsp_image_t *dst, const snd_hwdep_dsp_image_t *src); + +unsigned int snd_hwdep_dsp_image_get_index(const snd_hwdep_dsp_image_t *obj); +const char *snd_hwdep_dsp_image_get_name(const snd_hwdep_dsp_image_t *obj); +const void *snd_hwdep_dsp_image_get_image(const snd_hwdep_dsp_image_t *obj); +size_t snd_hwdep_dsp_image_get_length(const snd_hwdep_dsp_image_t *obj); + +void snd_hwdep_dsp_image_set_index(snd_hwdep_dsp_image_t *obj, unsigned int _index); +void snd_hwdep_dsp_image_set_name(snd_hwdep_dsp_image_t *obj, const char *name); +void snd_hwdep_dsp_image_set_image(snd_hwdep_dsp_image_t *obj, void *buffer); +void snd_hwdep_dsp_image_set_length(snd_hwdep_dsp_image_t *obj, size_t length); + +/** \} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALSA_HWDEP_H */ + diff --git a/thirdparty/linuxbsd_headers/alsa/input.h b/thirdparty/linuxbsd_headers/alsa/input.h new file mode 100644 index 0000000000..fc5d0e6774 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/input.h @@ -0,0 +1,83 @@ +/** + * \file include/input.h + * \brief Application interface library for the ALSA driver + * \author Jaroslav Kysela <perex@perex.cz> + * \author Abramo Bagnara <abramo@alsa-project.org> + * \author Takashi Iwai <tiwai@suse.de> + * \date 1998-2001 + * + * Application interface library for the ALSA driver + */ +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_INPUT_H +#define __ALSA_INPUT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup Input Input Interface + * + * The input functions present an interface similar to the stdio functions + * on top of different underlying input sources. + * + * The #snd_config_load function uses such an input handle to be able to + * load configurations not only from standard files but also from other + * sources, e.g. from memory buffers. + * + * \{ + */ + +/** + * \brief Internal structure for an input object. + * + * The ALSA library uses a pointer to this structure as a handle to an + * input object. Applications don't access its contents directly. + */ +typedef struct _snd_input snd_input_t; + +/** Input type. */ +typedef enum _snd_input_type { + /** Input from a stdio stream. */ + SND_INPUT_STDIO, + /** Input from a memory buffer. */ + SND_INPUT_BUFFER +} snd_input_type_t; + +int snd_input_stdio_open(snd_input_t **inputp, const char *file, const char *mode); +int snd_input_stdio_attach(snd_input_t **inputp, FILE *fp, int _close); +int snd_input_buffer_open(snd_input_t **inputp, const char *buffer, ssize_t size); +int snd_input_close(snd_input_t *input); +int snd_input_scanf(snd_input_t *input, const char *format, ...) +#ifndef DOC_HIDDEN + __attribute__ ((format (scanf, 2, 3))) +#endif + ; +char *snd_input_gets(snd_input_t *input, char *str, size_t size); +int snd_input_getc(snd_input_t *input); +int snd_input_ungetc(snd_input_t *input, int c); + +/** \} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALSA_INPUT_H */ diff --git a/thirdparty/linuxbsd_headers/alsa/mixer.h b/thirdparty/linuxbsd_headers/alsa/mixer.h new file mode 100644 index 0000000000..066d978435 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/mixer.h @@ -0,0 +1,317 @@ +/** + * \file include/mixer.h + * \brief Application interface library for the ALSA driver + * \author Jaroslav Kysela <perex@perex.cz> + * \author Abramo Bagnara <abramo@alsa-project.org> + * \author Takashi Iwai <tiwai@suse.de> + * \date 1998-2001 + * + * Application interface library for the ALSA driver + */ +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_MIXER_H +#define __ALSA_MIXER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup Mixer Mixer Interface + * The mixer interface. + * \{ + */ + +/** Mixer handle */ +typedef struct _snd_mixer snd_mixer_t; +/** Mixer elements class handle */ +typedef struct _snd_mixer_class snd_mixer_class_t; +/** Mixer element handle */ +typedef struct _snd_mixer_elem snd_mixer_elem_t; + +/** + * \brief Mixer callback function + * \param mixer Mixer handle + * \param mask event mask + * \param elem related mixer element (if any) + * \return 0 on success otherwise a negative error code + */ +typedef int (*snd_mixer_callback_t)(snd_mixer_t *ctl, + unsigned int mask, + snd_mixer_elem_t *elem); + +/** + * \brief Mixer element callback function + * \param elem Mixer element + * \param mask event mask + * \return 0 on success otherwise a negative error code + */ +typedef int (*snd_mixer_elem_callback_t)(snd_mixer_elem_t *elem, + unsigned int mask); + +/** + * \brief Compare function for sorting mixer elements + * \param e1 First element + * \param e2 Second element + * \return -1 if e1 < e2, 0 if e1 == e2, 1 if e1 > e2 + */ +typedef int (*snd_mixer_compare_t)(const snd_mixer_elem_t *e1, + const snd_mixer_elem_t *e2); + +/** + * \brief Event callback for the mixer class + * \param class_ Mixer class + * \param mask Event mask (SND_CTL_EVENT_*) + * \param helem HCTL element which invoked the event + * \param melem Mixer element associated to HCTL element + * \return zero if success, otherwise a negative error value + */ +typedef int (*snd_mixer_event_t)(snd_mixer_class_t *class_, unsigned int mask, + snd_hctl_elem_t *helem, snd_mixer_elem_t *melem); + + +/** Mixer element type */ +typedef enum _snd_mixer_elem_type { + /* Simple mixer elements */ + SND_MIXER_ELEM_SIMPLE, + SND_MIXER_ELEM_LAST = SND_MIXER_ELEM_SIMPLE +} snd_mixer_elem_type_t; + +int snd_mixer_open(snd_mixer_t **mixer, int mode); +int snd_mixer_close(snd_mixer_t *mixer); +snd_mixer_elem_t *snd_mixer_first_elem(snd_mixer_t *mixer); +snd_mixer_elem_t *snd_mixer_last_elem(snd_mixer_t *mixer); +int snd_mixer_handle_events(snd_mixer_t *mixer); +int snd_mixer_attach(snd_mixer_t *mixer, const char *name); +int snd_mixer_attach_hctl(snd_mixer_t *mixer, snd_hctl_t *hctl); +int snd_mixer_detach(snd_mixer_t *mixer, const char *name); +int snd_mixer_detach_hctl(snd_mixer_t *mixer, snd_hctl_t *hctl); +int snd_mixer_get_hctl(snd_mixer_t *mixer, const char *name, snd_hctl_t **hctl); +int snd_mixer_poll_descriptors_count(snd_mixer_t *mixer); +int snd_mixer_poll_descriptors(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int space); +int snd_mixer_poll_descriptors_revents(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); +int snd_mixer_load(snd_mixer_t *mixer); +void snd_mixer_free(snd_mixer_t *mixer); +int snd_mixer_wait(snd_mixer_t *mixer, int timeout); +int snd_mixer_set_compare(snd_mixer_t *mixer, snd_mixer_compare_t msort); +void snd_mixer_set_callback(snd_mixer_t *obj, snd_mixer_callback_t val); +void * snd_mixer_get_callback_private(const snd_mixer_t *obj); +void snd_mixer_set_callback_private(snd_mixer_t *obj, void * val); +unsigned int snd_mixer_get_count(const snd_mixer_t *obj); +int snd_mixer_class_unregister(snd_mixer_class_t *clss); + +snd_mixer_elem_t *snd_mixer_elem_next(snd_mixer_elem_t *elem); +snd_mixer_elem_t *snd_mixer_elem_prev(snd_mixer_elem_t *elem); +void snd_mixer_elem_set_callback(snd_mixer_elem_t *obj, snd_mixer_elem_callback_t val); +void * snd_mixer_elem_get_callback_private(const snd_mixer_elem_t *obj); +void snd_mixer_elem_set_callback_private(snd_mixer_elem_t *obj, void * val); +snd_mixer_elem_type_t snd_mixer_elem_get_type(const snd_mixer_elem_t *obj); + +int snd_mixer_class_register(snd_mixer_class_t *class_, snd_mixer_t *mixer); +int snd_mixer_elem_new(snd_mixer_elem_t **elem, + snd_mixer_elem_type_t type, + int compare_weight, + void *private_data, + void (*private_free)(snd_mixer_elem_t *elem)); +int snd_mixer_elem_add(snd_mixer_elem_t *elem, snd_mixer_class_t *class_); +int snd_mixer_elem_remove(snd_mixer_elem_t *elem); +void snd_mixer_elem_free(snd_mixer_elem_t *elem); +int snd_mixer_elem_info(snd_mixer_elem_t *elem); +int snd_mixer_elem_value(snd_mixer_elem_t *elem); +int snd_mixer_elem_attach(snd_mixer_elem_t *melem, snd_hctl_elem_t *helem); +int snd_mixer_elem_detach(snd_mixer_elem_t *melem, snd_hctl_elem_t *helem); +int snd_mixer_elem_empty(snd_mixer_elem_t *melem); +void *snd_mixer_elem_get_private(const snd_mixer_elem_t *melem); + +size_t snd_mixer_class_sizeof(void); +/** \hideinitializer + * \brief allocate an invalid #snd_mixer_class_t using standard alloca + * \param ptr returned pointer + */ +#define snd_mixer_class_alloca(ptr) __snd_alloca(ptr, snd_mixer_class) +int snd_mixer_class_malloc(snd_mixer_class_t **ptr); +void snd_mixer_class_free(snd_mixer_class_t *obj); +void snd_mixer_class_copy(snd_mixer_class_t *dst, const snd_mixer_class_t *src); +snd_mixer_t *snd_mixer_class_get_mixer(const snd_mixer_class_t *class_); +snd_mixer_event_t snd_mixer_class_get_event(const snd_mixer_class_t *class_); +void *snd_mixer_class_get_private(const snd_mixer_class_t *class_); +snd_mixer_compare_t snd_mixer_class_get_compare(const snd_mixer_class_t *class_); +int snd_mixer_class_set_event(snd_mixer_class_t *class_, snd_mixer_event_t event); +int snd_mixer_class_set_private(snd_mixer_class_t *class_, void *private_data); +int snd_mixer_class_set_private_free(snd_mixer_class_t *class_, void (*private_free)(snd_mixer_class_t *)); +int snd_mixer_class_set_compare(snd_mixer_class_t *class_, snd_mixer_compare_t compare); + +/** + * \defgroup SimpleMixer Simple Mixer Interface + * \ingroup Mixer + * The simple mixer interface. + * \{ + */ + +/* Simple mixer elements API */ + +/** Mixer simple element channel identifier */ +typedef enum _snd_mixer_selem_channel_id { + /** Unknown */ + SND_MIXER_SCHN_UNKNOWN = -1, + /** Front left */ + SND_MIXER_SCHN_FRONT_LEFT = 0, + /** Front right */ + SND_MIXER_SCHN_FRONT_RIGHT, + /** Rear left */ + SND_MIXER_SCHN_REAR_LEFT, + /** Rear right */ + SND_MIXER_SCHN_REAR_RIGHT, + /** Front center */ + SND_MIXER_SCHN_FRONT_CENTER, + /** Woofer */ + SND_MIXER_SCHN_WOOFER, + /** Side Left */ + SND_MIXER_SCHN_SIDE_LEFT, + /** Side Right */ + SND_MIXER_SCHN_SIDE_RIGHT, + /** Rear Center */ + SND_MIXER_SCHN_REAR_CENTER, + SND_MIXER_SCHN_LAST = 31, + /** Mono (Front left alias) */ + SND_MIXER_SCHN_MONO = SND_MIXER_SCHN_FRONT_LEFT +} snd_mixer_selem_channel_id_t; + +/** Mixer simple element - register options - abstraction level */ +enum snd_mixer_selem_regopt_abstract { + /** no abstraction - try use all universal controls from driver */ + SND_MIXER_SABSTRACT_NONE = 0, + /** basic abstraction - Master,PCM,CD,Aux,Record-Gain etc. */ + SND_MIXER_SABSTRACT_BASIC, +}; + +/** Mixer simple element - register options */ +struct snd_mixer_selem_regopt { + /** structure version */ + int ver; + /** v1: abstract layer selection */ + enum snd_mixer_selem_regopt_abstract abstract; + /** v1: device name (must be NULL when playback_pcm or capture_pcm != NULL) */ + const char *device; + /** v1: playback PCM connected to mixer device (NULL == none) */ + snd_pcm_t *playback_pcm; + /** v1: capture PCM connected to mixer device (NULL == none) */ + snd_pcm_t *capture_pcm; +}; + +/** Mixer simple element identifier */ +typedef struct _snd_mixer_selem_id snd_mixer_selem_id_t; + +const char *snd_mixer_selem_channel_name(snd_mixer_selem_channel_id_t channel); + +int snd_mixer_selem_register(snd_mixer_t *mixer, + struct snd_mixer_selem_regopt *options, + snd_mixer_class_t **classp); +void snd_mixer_selem_get_id(snd_mixer_elem_t *element, + snd_mixer_selem_id_t *id); +const char *snd_mixer_selem_get_name(snd_mixer_elem_t *elem); +unsigned int snd_mixer_selem_get_index(snd_mixer_elem_t *elem); +snd_mixer_elem_t *snd_mixer_find_selem(snd_mixer_t *mixer, + const snd_mixer_selem_id_t *id); + +int snd_mixer_selem_is_active(snd_mixer_elem_t *elem); +int snd_mixer_selem_is_playback_mono(snd_mixer_elem_t *elem); +int snd_mixer_selem_has_playback_channel(snd_mixer_elem_t *obj, snd_mixer_selem_channel_id_t channel); +int snd_mixer_selem_is_capture_mono(snd_mixer_elem_t *elem); +int snd_mixer_selem_has_capture_channel(snd_mixer_elem_t *obj, snd_mixer_selem_channel_id_t channel); +int snd_mixer_selem_get_capture_group(snd_mixer_elem_t *elem); +int snd_mixer_selem_has_common_volume(snd_mixer_elem_t *elem); +int snd_mixer_selem_has_playback_volume(snd_mixer_elem_t *elem); +int snd_mixer_selem_has_playback_volume_joined(snd_mixer_elem_t *elem); +int snd_mixer_selem_has_capture_volume(snd_mixer_elem_t *elem); +int snd_mixer_selem_has_capture_volume_joined(snd_mixer_elem_t *elem); +int snd_mixer_selem_has_common_switch(snd_mixer_elem_t *elem); +int snd_mixer_selem_has_playback_switch(snd_mixer_elem_t *elem); +int snd_mixer_selem_has_playback_switch_joined(snd_mixer_elem_t *elem); +int snd_mixer_selem_has_capture_switch(snd_mixer_elem_t *elem); +int snd_mixer_selem_has_capture_switch_joined(snd_mixer_elem_t *elem); +int snd_mixer_selem_has_capture_switch_exclusive(snd_mixer_elem_t *elem); + +int snd_mixer_selem_ask_playback_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue); +int snd_mixer_selem_ask_capture_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue); +int snd_mixer_selem_ask_playback_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value); +int snd_mixer_selem_ask_capture_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value); +int snd_mixer_selem_get_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value); +int snd_mixer_selem_get_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value); +int snd_mixer_selem_get_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value); +int snd_mixer_selem_get_capture_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value); +int snd_mixer_selem_get_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value); +int snd_mixer_selem_get_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value); +int snd_mixer_selem_set_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value); +int snd_mixer_selem_set_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value); +int snd_mixer_selem_set_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value, int dir); +int snd_mixer_selem_set_capture_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value, int dir); +int snd_mixer_selem_set_playback_volume_all(snd_mixer_elem_t *elem, long value); +int snd_mixer_selem_set_capture_volume_all(snd_mixer_elem_t *elem, long value); +int snd_mixer_selem_set_playback_dB_all(snd_mixer_elem_t *elem, long value, int dir); +int snd_mixer_selem_set_capture_dB_all(snd_mixer_elem_t *elem, long value, int dir); +int snd_mixer_selem_set_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value); +int snd_mixer_selem_set_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value); +int snd_mixer_selem_set_playback_switch_all(snd_mixer_elem_t *elem, int value); +int snd_mixer_selem_set_capture_switch_all(snd_mixer_elem_t *elem, int value); +int snd_mixer_selem_get_playback_volume_range(snd_mixer_elem_t *elem, + long *min, long *max); +int snd_mixer_selem_get_playback_dB_range(snd_mixer_elem_t *elem, + long *min, long *max); +int snd_mixer_selem_set_playback_volume_range(snd_mixer_elem_t *elem, + long min, long max); +int snd_mixer_selem_get_capture_volume_range(snd_mixer_elem_t *elem, + long *min, long *max); +int snd_mixer_selem_get_capture_dB_range(snd_mixer_elem_t *elem, + long *min, long *max); +int snd_mixer_selem_set_capture_volume_range(snd_mixer_elem_t *elem, + long min, long max); + +int snd_mixer_selem_is_enumerated(snd_mixer_elem_t *elem); +int snd_mixer_selem_is_enum_playback(snd_mixer_elem_t *elem); +int snd_mixer_selem_is_enum_capture(snd_mixer_elem_t *elem); +int snd_mixer_selem_get_enum_items(snd_mixer_elem_t *elem); +int snd_mixer_selem_get_enum_item_name(snd_mixer_elem_t *elem, unsigned int idx, size_t maxlen, char *str); +int snd_mixer_selem_get_enum_item(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, unsigned int *idxp); +int snd_mixer_selem_set_enum_item(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, unsigned int idx); + +size_t snd_mixer_selem_id_sizeof(void); +/** \hideinitializer + * \brief allocate an invalid #snd_mixer_selem_id_t using standard alloca + * \param ptr returned pointer + */ +#define snd_mixer_selem_id_alloca(ptr) __snd_alloca(ptr, snd_mixer_selem_id) +int snd_mixer_selem_id_malloc(snd_mixer_selem_id_t **ptr); +void snd_mixer_selem_id_free(snd_mixer_selem_id_t *obj); +void snd_mixer_selem_id_copy(snd_mixer_selem_id_t *dst, const snd_mixer_selem_id_t *src); +const char *snd_mixer_selem_id_get_name(const snd_mixer_selem_id_t *obj); +unsigned int snd_mixer_selem_id_get_index(const snd_mixer_selem_id_t *obj); +void snd_mixer_selem_id_set_name(snd_mixer_selem_id_t *obj, const char *val); +void snd_mixer_selem_id_set_index(snd_mixer_selem_id_t *obj, unsigned int val); + +/** \} */ + +/** \} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALSA_MIXER_H */ + diff --git a/thirdparty/linuxbsd_headers/alsa/mixer_abst.h b/thirdparty/linuxbsd_headers/alsa/mixer_abst.h new file mode 100644 index 0000000000..7844b19101 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/mixer_abst.h @@ -0,0 +1,112 @@ +/** + * \file include/mixer_abst.h + * \brief Mixer abstract implementation interface library for the ALSA library + * \author Jaroslav Kysela <perex@perex.cz> + * \date 2005 + * + * Mixer abstact implementation interface library for the ALSA library + */ +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_MIXER_ABST_H +#define __ALSA_MIXER_ABST_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup Mixer_Abstract Mixer Abstact Module Interface + * The mixer abstact module interface. + * \{ + */ + +#define SM_PLAY 0 +#define SM_CAPT 1 + +#define SM_CAP_GVOLUME (1<<1) +#define SM_CAP_GSWITCH (1<<2) +#define SM_CAP_PVOLUME (1<<3) +#define SM_CAP_PVOLUME_JOIN (1<<4) +#define SM_CAP_PSWITCH (1<<5) +#define SM_CAP_PSWITCH_JOIN (1<<6) +#define SM_CAP_CVOLUME (1<<7) +#define SM_CAP_CVOLUME_JOIN (1<<8) +#define SM_CAP_CSWITCH (1<<9) +#define SM_CAP_CSWITCH_JOIN (1<<10) +#define SM_CAP_CSWITCH_EXCL (1<<11) +#define SM_CAP_PENUM (1<<12) +#define SM_CAP_CENUM (1<<13) +/* SM_CAP_* 24-31 => private for module use */ + +#define SM_OPS_IS_ACTIVE 0 +#define SM_OPS_IS_MONO 1 +#define SM_OPS_IS_CHANNEL 2 +#define SM_OPS_IS_ENUMERATED 3 +#define SM_OPS_IS_ENUMCNT 4 + +#define sm_selem(x) ((sm_selem_t *)((x)->private_data)) +#define sm_selem_ops(x) ((sm_selem_t *)((x)->private_data))->ops + +typedef struct _sm_selem { + snd_mixer_selem_id_t *id; + struct sm_elem_ops *ops; + unsigned int caps; + unsigned int capture_group; +} sm_selem_t; + +typedef struct _sm_class_basic { + char *device; + snd_ctl_t *ctl; + snd_hctl_t *hctl; + snd_ctl_card_info_t *info; +} sm_class_basic_t; + +struct sm_elem_ops { + int (*is)(snd_mixer_elem_t *elem, int dir, int cmd, int val); + int (*get_range)(snd_mixer_elem_t *elem, int dir, long *min, long *max); + int (*set_range)(snd_mixer_elem_t *elem, int dir, long min, long max); + int (*get_dB_range)(snd_mixer_elem_t *elem, int dir, long *min, long *max); + int (*ask_vol_dB)(snd_mixer_elem_t *elem, int dir, long value, long *dbValue); + int (*ask_dB_vol)(snd_mixer_elem_t *elem, int dir, long dbValue, long *value, int xdir); + int (*get_volume)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long *value); + int (*get_dB)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long *value); + int (*set_volume)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long value); + int (*set_dB)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long value, int xdir); + int (*get_switch)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, int *value); + int (*set_switch)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, int value); + int (*enum_item_name)(snd_mixer_elem_t *elem, unsigned int item, size_t maxlen, char *buf); + int (*get_enum_item)(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, unsigned int *itemp); + int (*set_enum_item)(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, unsigned int item); +}; + +int snd_mixer_selem_compare(const snd_mixer_elem_t *c1, const snd_mixer_elem_t *c2); + +int snd_mixer_sbasic_info(const snd_mixer_class_t *class, sm_class_basic_t *info); +void *snd_mixer_sbasic_get_private(const snd_mixer_class_t *class); +void snd_mixer_sbasic_set_private(const snd_mixer_class_t *class, void *private_data); +void snd_mixer_sbasic_set_private_free(const snd_mixer_class_t *class, void (*private_free)(snd_mixer_class_t *class)); + +/** \} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALSA_MIXER_ABST_H */ + diff --git a/thirdparty/linuxbsd_headers/alsa/output.h b/thirdparty/linuxbsd_headers/alsa/output.h new file mode 100644 index 0000000000..5279aa2ed0 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/output.h @@ -0,0 +1,86 @@ +/** + * \file include/output.h + * \brief Application interface library for the ALSA driver + * \author Jaroslav Kysela <perex@perex.cz> + * \author Abramo Bagnara <abramo@alsa-project.org> + * \author Takashi Iwai <tiwai@suse.de> + * \date 1998-2001 + * + * Application interface library for the ALSA driver + */ +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_OUTPUT_H +#define __ALSA_OUTPUT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup Output Output Interface + * + * The output functions present an interface similar to the stdio functions + * on top of different underlying output destinations. + * + * Many PCM debugging functions (\c snd_pcm_xxx_dump_xxx) use such an output + * handle to be able to write not only to the screen but also to other + * destinations, e.g. to files or to memory buffers. + * + * \{ + */ + +/** + * \brief Internal structure for an output object. + * + * The ALSA library uses a pointer to this structure as a handle to an + * output object. Applications don't access its contents directly. + */ +typedef struct _snd_output snd_output_t; + +/** Output type. */ +typedef enum _snd_output_type { + /** Output to a stdio stream. */ + SND_OUTPUT_STDIO, + /** Output to a memory buffer. */ + SND_OUTPUT_BUFFER +} snd_output_type_t; + +int snd_output_stdio_open(snd_output_t **outputp, const char *file, const char *mode); +int snd_output_stdio_attach(snd_output_t **outputp, FILE *fp, int _close); +int snd_output_buffer_open(snd_output_t **outputp); +size_t snd_output_buffer_string(snd_output_t *output, char **buf); +int snd_output_close(snd_output_t *output); +int snd_output_printf(snd_output_t *output, const char *format, ...) +#ifndef DOC_HIDDEN + __attribute__ ((format (printf, 2, 3))) +#endif + ; +int snd_output_vprintf(snd_output_t *output, const char *format, va_list args); +int snd_output_puts(snd_output_t *output, const char *str); +int snd_output_putc(snd_output_t *output, int c); +int snd_output_flush(snd_output_t *output); + +/** \} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALSA_OUTPUT_H */ + diff --git a/thirdparty/linuxbsd_headers/alsa/patches/use-standard-poll-h.diff b/thirdparty/linuxbsd_headers/alsa/patches/use-standard-poll-h.diff new file mode 100644 index 0000000000..8d536df579 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/patches/use-standard-poll-h.diff @@ -0,0 +1,11 @@ +--- a/asoundlib.h ++++ b/asoundlib.h +@@ -35,7 +35,7 @@ + #include <string.h> + #include <fcntl.h> + #include <assert.h> +-#include <sys/poll.h> ++#include <poll.h> + #include <errno.h> + #include <stdarg.h> + #include <endian.h> diff --git a/thirdparty/linuxbsd_headers/alsa/pcm.h b/thirdparty/linuxbsd_headers/alsa/pcm.h new file mode 100644 index 0000000000..0be1a321ad --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/pcm.h @@ -0,0 +1,1327 @@ +/** + * \file include/pcm.h + * \brief Application interface library for the ALSA driver + * \author Jaroslav Kysela <perex@perex.cz> + * \author Abramo Bagnara <abramo@alsa-project.org> + * \author Takashi Iwai <tiwai@suse.de> + * \date 1998-2001 + * + * Application interface library for the ALSA driver. + * See the \ref pcm page for more details. + */ +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_PCM_H +#define __ALSA_PCM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup PCM PCM Interface + * See the \ref pcm page for more details. + * \{ + */ + +/** dlsym version for interface entry callback */ +#define SND_PCM_DLSYM_VERSION _dlsym_pcm_001 + +/** PCM generic info container */ +typedef struct _snd_pcm_info snd_pcm_info_t; + +/** PCM hardware configuration space container + * + * snd_pcm_hw_params_t is an opaque structure which contains a set of possible + * PCM hardware configurations. For example, a given instance might include a + * range of buffer sizes, a range of period sizes, and a set of several sample + * formats. Some subset of all possible combinations these sets may be valid, + * but not necessarily any combination will be valid. + * + * When a parameter is set or restricted using a snd_pcm_hw_params_set* + * function, all of the other ranges will be updated to exclude as many + * impossible configurations as possible. Attempting to set a parameter + * outside of its acceptable range will result in the function failing + * and an error code being returned. + */ +typedef struct _snd_pcm_hw_params snd_pcm_hw_params_t; + +/** PCM software configuration container */ +typedef struct _snd_pcm_sw_params snd_pcm_sw_params_t; +/** PCM status container */ + typedef struct _snd_pcm_status snd_pcm_status_t; +/** PCM access types mask */ +typedef struct _snd_pcm_access_mask snd_pcm_access_mask_t; +/** PCM formats mask */ +typedef struct _snd_pcm_format_mask snd_pcm_format_mask_t; +/** PCM subformats mask */ +typedef struct _snd_pcm_subformat_mask snd_pcm_subformat_mask_t; + +/** PCM class */ +typedef enum _snd_pcm_class { + /** standard device */ + + SND_PCM_CLASS_GENERIC = 0, + /** multichannel device */ + SND_PCM_CLASS_MULTI, + /** software modem device */ + SND_PCM_CLASS_MODEM, + /** digitizer device */ + SND_PCM_CLASS_DIGITIZER, + SND_PCM_CLASS_LAST = SND_PCM_CLASS_DIGITIZER +} snd_pcm_class_t; + +/** PCM subclass */ +typedef enum _snd_pcm_subclass { + /** subdevices are mixed together */ + SND_PCM_SUBCLASS_GENERIC_MIX = 0, + /** multichannel subdevices are mixed together */ + SND_PCM_SUBCLASS_MULTI_MIX, + SND_PCM_SUBCLASS_LAST = SND_PCM_SUBCLASS_MULTI_MIX +} snd_pcm_subclass_t; + +/** PCM stream (direction) */ +typedef enum _snd_pcm_stream { + /** Playback stream */ + SND_PCM_STREAM_PLAYBACK = 0, + /** Capture stream */ + SND_PCM_STREAM_CAPTURE, + SND_PCM_STREAM_LAST = SND_PCM_STREAM_CAPTURE +} snd_pcm_stream_t; + +/** PCM access type */ +typedef enum _snd_pcm_access { + /** mmap access with simple interleaved channels */ + SND_PCM_ACCESS_MMAP_INTERLEAVED = 0, + /** mmap access with simple non interleaved channels */ + SND_PCM_ACCESS_MMAP_NONINTERLEAVED, + /** mmap access with complex placement */ + SND_PCM_ACCESS_MMAP_COMPLEX, + /** snd_pcm_readi/snd_pcm_writei access */ + SND_PCM_ACCESS_RW_INTERLEAVED, + /** snd_pcm_readn/snd_pcm_writen access */ + SND_PCM_ACCESS_RW_NONINTERLEAVED, + SND_PCM_ACCESS_LAST = SND_PCM_ACCESS_RW_NONINTERLEAVED +} snd_pcm_access_t; + +/** PCM sample format */ +typedef enum _snd_pcm_format { + /** Unknown */ + SND_PCM_FORMAT_UNKNOWN = -1, + /** Signed 8 bit */ + SND_PCM_FORMAT_S8 = 0, + /** Unsigned 8 bit */ + SND_PCM_FORMAT_U8, + /** Signed 16 bit Little Endian */ + SND_PCM_FORMAT_S16_LE, + /** Signed 16 bit Big Endian */ + SND_PCM_FORMAT_S16_BE, + /** Unsigned 16 bit Little Endian */ + SND_PCM_FORMAT_U16_LE, + /** Unsigned 16 bit Big Endian */ + SND_PCM_FORMAT_U16_BE, + /** Signed 24 bit Little Endian using low three bytes in 32-bit word */ + SND_PCM_FORMAT_S24_LE, + /** Signed 24 bit Big Endian using low three bytes in 32-bit word */ + SND_PCM_FORMAT_S24_BE, + /** Unsigned 24 bit Little Endian using low three bytes in 32-bit word */ + SND_PCM_FORMAT_U24_LE, + /** Unsigned 24 bit Big Endian using low three bytes in 32-bit word */ + SND_PCM_FORMAT_U24_BE, + /** Signed 32 bit Little Endian */ + SND_PCM_FORMAT_S32_LE, + /** Signed 32 bit Big Endian */ + SND_PCM_FORMAT_S32_BE, + /** Unsigned 32 bit Little Endian */ + SND_PCM_FORMAT_U32_LE, + /** Unsigned 32 bit Big Endian */ + SND_PCM_FORMAT_U32_BE, + /** Float 32 bit Little Endian, Range -1.0 to 1.0 */ + SND_PCM_FORMAT_FLOAT_LE, + /** Float 32 bit Big Endian, Range -1.0 to 1.0 */ + SND_PCM_FORMAT_FLOAT_BE, + /** Float 64 bit Little Endian, Range -1.0 to 1.0 */ + SND_PCM_FORMAT_FLOAT64_LE, + /** Float 64 bit Big Endian, Range -1.0 to 1.0 */ + SND_PCM_FORMAT_FLOAT64_BE, + /** IEC-958 Little Endian */ + SND_PCM_FORMAT_IEC958_SUBFRAME_LE, + /** IEC-958 Big Endian */ + SND_PCM_FORMAT_IEC958_SUBFRAME_BE, + /** Mu-Law */ + SND_PCM_FORMAT_MU_LAW, + /** A-Law */ + SND_PCM_FORMAT_A_LAW, + /** Ima-ADPCM */ + SND_PCM_FORMAT_IMA_ADPCM, + /** MPEG */ + SND_PCM_FORMAT_MPEG, + /** GSM */ + SND_PCM_FORMAT_GSM, + /** Special */ + SND_PCM_FORMAT_SPECIAL = 31, + /** Signed 24bit Little Endian in 3bytes format */ + SND_PCM_FORMAT_S24_3LE = 32, + /** Signed 24bit Big Endian in 3bytes format */ + SND_PCM_FORMAT_S24_3BE, + /** Unsigned 24bit Little Endian in 3bytes format */ + SND_PCM_FORMAT_U24_3LE, + /** Unsigned 24bit Big Endian in 3bytes format */ + SND_PCM_FORMAT_U24_3BE, + /** Signed 20bit Little Endian in 3bytes format */ + SND_PCM_FORMAT_S20_3LE, + /** Signed 20bit Big Endian in 3bytes format */ + SND_PCM_FORMAT_S20_3BE, + /** Unsigned 20bit Little Endian in 3bytes format */ + SND_PCM_FORMAT_U20_3LE, + /** Unsigned 20bit Big Endian in 3bytes format */ + SND_PCM_FORMAT_U20_3BE, + /** Signed 18bit Little Endian in 3bytes format */ + SND_PCM_FORMAT_S18_3LE, + /** Signed 18bit Big Endian in 3bytes format */ + SND_PCM_FORMAT_S18_3BE, + /** Unsigned 18bit Little Endian in 3bytes format */ + SND_PCM_FORMAT_U18_3LE, + /** Unsigned 18bit Big Endian in 3bytes format */ + SND_PCM_FORMAT_U18_3BE, + /* G.723 (ADPCM) 24 kbit/s, 8 samples in 3 bytes */ + SND_PCM_FORMAT_G723_24, + /* G.723 (ADPCM) 24 kbit/s, 1 sample in 1 byte */ + SND_PCM_FORMAT_G723_24_1B, + /* G.723 (ADPCM) 40 kbit/s, 8 samples in 3 bytes */ + SND_PCM_FORMAT_G723_40, + /* G.723 (ADPCM) 40 kbit/s, 1 sample in 1 byte */ + SND_PCM_FORMAT_G723_40_1B, + /* Direct Stream Digital (DSD) in 1-byte samples (x8) */ + SND_PCM_FORMAT_DSD_U8, + /* Direct Stream Digital (DSD) in 2-byte samples (x16) */ + SND_PCM_FORMAT_DSD_U16_LE, + /* Direct Stream Digital (DSD) in 4-byte samples (x32) */ + SND_PCM_FORMAT_DSD_U32_LE, + /* Direct Stream Digital (DSD) in 2-byte samples (x16) */ + SND_PCM_FORMAT_DSD_U16_BE, + /* Direct Stream Digital (DSD) in 4-byte samples (x32) */ + SND_PCM_FORMAT_DSD_U32_BE, + SND_PCM_FORMAT_LAST = SND_PCM_FORMAT_DSD_U32_BE, + +#if __BYTE_ORDER == __LITTLE_ENDIAN + /** Signed 16 bit CPU endian */ + SND_PCM_FORMAT_S16 = SND_PCM_FORMAT_S16_LE, + /** Unsigned 16 bit CPU endian */ + SND_PCM_FORMAT_U16 = SND_PCM_FORMAT_U16_LE, + /** Signed 24 bit CPU endian */ + SND_PCM_FORMAT_S24 = SND_PCM_FORMAT_S24_LE, + /** Unsigned 24 bit CPU endian */ + SND_PCM_FORMAT_U24 = SND_PCM_FORMAT_U24_LE, + /** Signed 32 bit CPU endian */ + SND_PCM_FORMAT_S32 = SND_PCM_FORMAT_S32_LE, + /** Unsigned 32 bit CPU endian */ + SND_PCM_FORMAT_U32 = SND_PCM_FORMAT_U32_LE, + /** Float 32 bit CPU endian */ + SND_PCM_FORMAT_FLOAT = SND_PCM_FORMAT_FLOAT_LE, + /** Float 64 bit CPU endian */ + SND_PCM_FORMAT_FLOAT64 = SND_PCM_FORMAT_FLOAT64_LE, + /** IEC-958 CPU Endian */ + SND_PCM_FORMAT_IEC958_SUBFRAME = SND_PCM_FORMAT_IEC958_SUBFRAME_LE +#elif __BYTE_ORDER == __BIG_ENDIAN + /** Signed 16 bit CPU endian */ + SND_PCM_FORMAT_S16 = SND_PCM_FORMAT_S16_BE, + /** Unsigned 16 bit CPU endian */ + SND_PCM_FORMAT_U16 = SND_PCM_FORMAT_U16_BE, + /** Signed 24 bit CPU endian */ + SND_PCM_FORMAT_S24 = SND_PCM_FORMAT_S24_BE, + /** Unsigned 24 bit CPU endian */ + SND_PCM_FORMAT_U24 = SND_PCM_FORMAT_U24_BE, + /** Signed 32 bit CPU endian */ + SND_PCM_FORMAT_S32 = SND_PCM_FORMAT_S32_BE, + /** Unsigned 32 bit CPU endian */ + SND_PCM_FORMAT_U32 = SND_PCM_FORMAT_U32_BE, + /** Float 32 bit CPU endian */ + SND_PCM_FORMAT_FLOAT = SND_PCM_FORMAT_FLOAT_BE, + /** Float 64 bit CPU endian */ + SND_PCM_FORMAT_FLOAT64 = SND_PCM_FORMAT_FLOAT64_BE, + /** IEC-958 CPU Endian */ + SND_PCM_FORMAT_IEC958_SUBFRAME = SND_PCM_FORMAT_IEC958_SUBFRAME_BE +#else +#error "Unknown endian" +#endif +} snd_pcm_format_t; + +/** PCM sample subformat */ +typedef enum _snd_pcm_subformat { + /** Standard */ + SND_PCM_SUBFORMAT_STD = 0, + SND_PCM_SUBFORMAT_LAST = SND_PCM_SUBFORMAT_STD +} snd_pcm_subformat_t; + +/** PCM state */ +typedef enum _snd_pcm_state { + /** Open */ + SND_PCM_STATE_OPEN = 0, + /** Setup installed */ + SND_PCM_STATE_SETUP, + /** Ready to start */ + SND_PCM_STATE_PREPARED, + /** Running */ + SND_PCM_STATE_RUNNING, + /** Stopped: underrun (playback) or overrun (capture) detected */ + SND_PCM_STATE_XRUN, + /** Draining: running (playback) or stopped (capture) */ + SND_PCM_STATE_DRAINING, + /** Paused */ + SND_PCM_STATE_PAUSED, + /** Hardware is suspended */ + SND_PCM_STATE_SUSPENDED, + /** Hardware is disconnected */ + SND_PCM_STATE_DISCONNECTED, + SND_PCM_STATE_LAST = SND_PCM_STATE_DISCONNECTED +} snd_pcm_state_t; + +/** PCM start mode */ +typedef enum _snd_pcm_start { + /** Automatic start on data read/write */ + SND_PCM_START_DATA = 0, + /** Explicit start */ + SND_PCM_START_EXPLICIT, + SND_PCM_START_LAST = SND_PCM_START_EXPLICIT +} snd_pcm_start_t; + +/** PCM xrun mode */ +typedef enum _snd_pcm_xrun { + /** Xrun detection disabled */ + SND_PCM_XRUN_NONE = 0, + /** Stop on xrun detection */ + SND_PCM_XRUN_STOP, + SND_PCM_XRUN_LAST = SND_PCM_XRUN_STOP +} snd_pcm_xrun_t; + +/** PCM timestamp mode */ +typedef enum _snd_pcm_tstamp { + /** No timestamp */ + SND_PCM_TSTAMP_NONE = 0, + /** Update timestamp at every hardware position update */ + SND_PCM_TSTAMP_ENABLE, + /** Equivalent with #SND_PCM_TSTAMP_ENABLE, + * just for compatibility with older versions + */ + SND_PCM_TSTAMP_MMAP = SND_PCM_TSTAMP_ENABLE, + SND_PCM_TSTAMP_LAST = SND_PCM_TSTAMP_ENABLE +} snd_pcm_tstamp_t; + +typedef enum _snd_pcm_tstamp_type { + SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY = 0, /**< gettimeofday equivalent */ + SND_PCM_TSTAMP_TYPE_MONOTONIC, /**< posix_clock_monotonic equivalent */ + SND_PCM_TSTAMP_TYPE_MONOTONIC_RAW, /**< monotonic_raw (no NTP) */ + SND_PCM_TSTAMP_TYPE_LAST = SND_PCM_TSTAMP_TYPE_MONOTONIC_RAW, +} snd_pcm_tstamp_type_t; + +typedef struct _snd_pcm_audio_tstamp_config { + /* 5 of max 16 bits used */ + unsigned int type_requested:4; + unsigned int report_delay:1; /* add total delay to A/D or D/A */ +} snd_pcm_audio_tstamp_config_t; + +typedef struct _snd_pcm_audio_tstamp_report { + /* 6 of max 16 bits used for bit-fields */ + + /* for backwards compatibility */ + unsigned int valid:1; + + /* actual type if hardware could not support requested timestamp */ + unsigned int actual_type:4; + + /* accuracy represented in ns units */ + unsigned int accuracy_report:1; /* 0 if accuracy unknown, 1 if accuracy field is valid */ + unsigned int accuracy; /* up to 4.29s, will be packed in separate field */ +} snd_pcm_audio_tstamp_report_t; + +/** Unsigned frames quantity */ +typedef unsigned long snd_pcm_uframes_t; +/** Signed frames quantity */ +typedef long snd_pcm_sframes_t; + +/** Non blocking mode (flag for open mode) \hideinitializer */ +#define SND_PCM_NONBLOCK 0x00000001 +/** Async notification (flag for open mode) \hideinitializer */ +#define SND_PCM_ASYNC 0x00000002 +/** In an abort state (internal, not allowed for open) */ +#define SND_PCM_ABORT 0x00008000 +/** Disable automatic (but not forced!) rate resamplinig */ +#define SND_PCM_NO_AUTO_RESAMPLE 0x00010000 +/** Disable automatic (but not forced!) channel conversion */ +#define SND_PCM_NO_AUTO_CHANNELS 0x00020000 +/** Disable automatic (but not forced!) format conversion */ +#define SND_PCM_NO_AUTO_FORMAT 0x00040000 +/** Disable soft volume control */ +#define SND_PCM_NO_SOFTVOL 0x00080000 + +/** PCM handle */ +typedef struct _snd_pcm snd_pcm_t; + +/** PCM type */ +enum _snd_pcm_type { + /** Kernel level PCM */ + SND_PCM_TYPE_HW = 0, + /** Hooked PCM */ + SND_PCM_TYPE_HOOKS, + /** One or more linked PCM with exclusive access to selected + channels */ + SND_PCM_TYPE_MULTI, + /** File writing plugin */ + SND_PCM_TYPE_FILE, + /** Null endpoint PCM */ + SND_PCM_TYPE_NULL, + /** Shared memory client PCM */ + SND_PCM_TYPE_SHM, + /** INET client PCM (not yet implemented) */ + SND_PCM_TYPE_INET, + /** Copying plugin */ + SND_PCM_TYPE_COPY, + /** Linear format conversion PCM */ + SND_PCM_TYPE_LINEAR, + /** A-Law format conversion PCM */ + SND_PCM_TYPE_ALAW, + /** Mu-Law format conversion PCM */ + SND_PCM_TYPE_MULAW, + /** IMA-ADPCM format conversion PCM */ + SND_PCM_TYPE_ADPCM, + /** Rate conversion PCM */ + SND_PCM_TYPE_RATE, + /** Attenuated static route PCM */ + SND_PCM_TYPE_ROUTE, + /** Format adjusted PCM */ + SND_PCM_TYPE_PLUG, + /** Sharing PCM */ + SND_PCM_TYPE_SHARE, + /** Meter plugin */ + SND_PCM_TYPE_METER, + /** Mixing PCM */ + SND_PCM_TYPE_MIX, + /** Attenuated dynamic route PCM (not yet implemented) */ + SND_PCM_TYPE_DROUTE, + /** Loopback server plugin (not yet implemented) */ + SND_PCM_TYPE_LBSERVER, + /** Linear Integer <-> Linear Float format conversion PCM */ + SND_PCM_TYPE_LINEAR_FLOAT, + /** LADSPA integration plugin */ + SND_PCM_TYPE_LADSPA, + /** Direct Mixing plugin */ + SND_PCM_TYPE_DMIX, + /** Jack Audio Connection Kit plugin */ + SND_PCM_TYPE_JACK, + /** Direct Snooping plugin */ + SND_PCM_TYPE_DSNOOP, + /** Direct Sharing plugin */ + SND_PCM_TYPE_DSHARE, + /** IEC958 subframe plugin */ + SND_PCM_TYPE_IEC958, + /** Soft volume plugin */ + SND_PCM_TYPE_SOFTVOL, + /** External I/O plugin */ + SND_PCM_TYPE_IOPLUG, + /** External filter plugin */ + SND_PCM_TYPE_EXTPLUG, + /** Mmap-emulation plugin */ + SND_PCM_TYPE_MMAP_EMUL, + SND_PCM_TYPE_LAST = SND_PCM_TYPE_MMAP_EMUL +}; + +/** PCM type */ +typedef enum _snd_pcm_type snd_pcm_type_t; + +/** PCM area specification */ +typedef struct _snd_pcm_channel_area { + /** base address of channel samples */ + void *addr; + /** offset to first sample in bits */ + unsigned int first; + /** samples distance in bits */ + unsigned int step; +} snd_pcm_channel_area_t; + +/** PCM synchronization ID */ +typedef union _snd_pcm_sync_id { + /** 8-bit ID */ + unsigned char id[16]; + /** 16-bit ID */ + unsigned short id16[8]; + /** 32-bit ID */ + unsigned int id32[4]; +} snd_pcm_sync_id_t; + +/** #SND_PCM_TYPE_METER scope handle */ +typedef struct _snd_pcm_scope snd_pcm_scope_t; + +int snd_pcm_open(snd_pcm_t **pcm, const char *name, + snd_pcm_stream_t stream, int mode); +int snd_pcm_open_lconf(snd_pcm_t **pcm, const char *name, + snd_pcm_stream_t stream, int mode, + snd_config_t *lconf); +int snd_pcm_open_fallback(snd_pcm_t **pcm, snd_config_t *root, + const char *name, const char *orig_name, + snd_pcm_stream_t stream, int mode); + +int snd_pcm_close(snd_pcm_t *pcm); +const char *snd_pcm_name(snd_pcm_t *pcm); +snd_pcm_type_t snd_pcm_type(snd_pcm_t *pcm); +snd_pcm_stream_t snd_pcm_stream(snd_pcm_t *pcm); +int snd_pcm_poll_descriptors_count(snd_pcm_t *pcm); +int snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space); +int snd_pcm_poll_descriptors_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); +int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock); +static __inline__ int snd_pcm_abort(snd_pcm_t *pcm) { return snd_pcm_nonblock(pcm, 2); } +int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm, + snd_async_callback_t callback, void *private_data); +snd_pcm_t *snd_async_handler_get_pcm(snd_async_handler_t *handler); +int snd_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t *info); +int snd_pcm_hw_params_current(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); +int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); +int snd_pcm_hw_free(snd_pcm_t *pcm); +int snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params); +int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params); +int snd_pcm_prepare(snd_pcm_t *pcm); +int snd_pcm_reset(snd_pcm_t *pcm); +int snd_pcm_status(snd_pcm_t *pcm, snd_pcm_status_t *status); +int snd_pcm_start(snd_pcm_t *pcm); +int snd_pcm_drop(snd_pcm_t *pcm); +int snd_pcm_drain(snd_pcm_t *pcm); +int snd_pcm_pause(snd_pcm_t *pcm, int enable); +snd_pcm_state_t snd_pcm_state(snd_pcm_t *pcm); +int snd_pcm_hwsync(snd_pcm_t *pcm); +int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp); +int snd_pcm_resume(snd_pcm_t *pcm); +int snd_pcm_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail, snd_htimestamp_t *tstamp); +snd_pcm_sframes_t snd_pcm_avail(snd_pcm_t *pcm); +snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm); +int snd_pcm_avail_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *availp, snd_pcm_sframes_t *delayp); +snd_pcm_sframes_t snd_pcm_rewindable(snd_pcm_t *pcm); +snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames); +snd_pcm_sframes_t snd_pcm_forwardable(snd_pcm_t *pcm); +snd_pcm_sframes_t snd_pcm_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames); +snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size); +snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size); +snd_pcm_sframes_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size); +snd_pcm_sframes_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size); +int snd_pcm_wait(snd_pcm_t *pcm, int timeout); + +int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2); +int snd_pcm_unlink(snd_pcm_t *pcm); + +/** channel mapping API version number */ +#define SND_CHMAP_API_VERSION ((1 << 16) | (0 << 8) | 1) + +/** channel map list type */ +enum snd_pcm_chmap_type { + SND_CHMAP_TYPE_NONE = 0,/**< unspecified channel position */ + SND_CHMAP_TYPE_FIXED, /**< fixed channel position */ + SND_CHMAP_TYPE_VAR, /**< freely swappable channel position */ + SND_CHMAP_TYPE_PAIRED, /**< pair-wise swappable channel position */ + SND_CHMAP_TYPE_LAST = SND_CHMAP_TYPE_PAIRED, /**< last entry */ +}; + +/** channel positions */ +enum snd_pcm_chmap_position { + SND_CHMAP_UNKNOWN = 0, /**< unspecified */ + SND_CHMAP_NA, /**< N/A, silent */ + SND_CHMAP_MONO, /**< mono stream */ + SND_CHMAP_FL, /**< front left */ + SND_CHMAP_FR, /**< front right */ + SND_CHMAP_RL, /**< rear left */ + SND_CHMAP_RR, /**< rear right */ + SND_CHMAP_FC, /**< front center */ + SND_CHMAP_LFE, /**< LFE */ + SND_CHMAP_SL, /**< side left */ + SND_CHMAP_SR, /**< side right */ + SND_CHMAP_RC, /**< rear center */ + SND_CHMAP_FLC, /**< front left center */ + SND_CHMAP_FRC, /**< front right center */ + SND_CHMAP_RLC, /**< rear left center */ + SND_CHMAP_RRC, /**< rear right center */ + SND_CHMAP_FLW, /**< front left wide */ + SND_CHMAP_FRW, /**< front right wide */ + SND_CHMAP_FLH, /**< front left high */ + SND_CHMAP_FCH, /**< front center high */ + SND_CHMAP_FRH, /**< front right high */ + SND_CHMAP_TC, /**< top center */ + SND_CHMAP_TFL, /**< top front left */ + SND_CHMAP_TFR, /**< top front right */ + SND_CHMAP_TFC, /**< top front center */ + SND_CHMAP_TRL, /**< top rear left */ + SND_CHMAP_TRR, /**< top rear right */ + SND_CHMAP_TRC, /**< top rear center */ + SND_CHMAP_TFLC, /**< top front left center */ + SND_CHMAP_TFRC, /**< top front right center */ + SND_CHMAP_TSL, /**< top side left */ + SND_CHMAP_TSR, /**< top side right */ + SND_CHMAP_LLFE, /**< left LFE */ + SND_CHMAP_RLFE, /**< right LFE */ + SND_CHMAP_BC, /**< bottom center */ + SND_CHMAP_BLC, /**< bottom left center */ + SND_CHMAP_BRC, /**< bottom right center */ + SND_CHMAP_LAST = SND_CHMAP_BRC, +}; + +/** bitmask for channel position */ +#define SND_CHMAP_POSITION_MASK 0xffff + +/** bit flag indicating the channel is phase inverted */ +#define SND_CHMAP_PHASE_INVERSE (0x01 << 16) +/** bit flag indicating the non-standard channel value */ +#define SND_CHMAP_DRIVER_SPEC (0x02 << 16) + +/** the channel map header */ +typedef struct snd_pcm_chmap { + unsigned int channels; /**< number of channels */ + unsigned int pos[0]; /**< channel position array */ +} snd_pcm_chmap_t; + +/** the header of array items returned from snd_pcm_query_chmaps() */ +typedef struct snd_pcm_chmap_query { + enum snd_pcm_chmap_type type; /**< channel map type */ + snd_pcm_chmap_t map; /**< available channel map */ +} snd_pcm_chmap_query_t; + + +snd_pcm_chmap_query_t **snd_pcm_query_chmaps(snd_pcm_t *pcm); +snd_pcm_chmap_query_t **snd_pcm_query_chmaps_from_hw(int card, int dev, + int subdev, + snd_pcm_stream_t stream); +void snd_pcm_free_chmaps(snd_pcm_chmap_query_t **maps); +snd_pcm_chmap_t *snd_pcm_get_chmap(snd_pcm_t *pcm); +int snd_pcm_set_chmap(snd_pcm_t *pcm, const snd_pcm_chmap_t *map); + +const char *snd_pcm_chmap_type_name(enum snd_pcm_chmap_type val); +const char *snd_pcm_chmap_name(enum snd_pcm_chmap_position val); +const char *snd_pcm_chmap_long_name(enum snd_pcm_chmap_position val); +int snd_pcm_chmap_print(const snd_pcm_chmap_t *map, size_t maxlen, char *buf); +unsigned int snd_pcm_chmap_from_string(const char *str); +snd_pcm_chmap_t *snd_pcm_chmap_parse_string(const char *str); + +//int snd_pcm_mixer_element(snd_pcm_t *pcm, snd_mixer_t *mixer, snd_mixer_elem_t **elem); + +/* + * application helpers - these functions are implemented on top + * of the basic API + */ + +int snd_pcm_recover(snd_pcm_t *pcm, int err, int silent); +int snd_pcm_set_params(snd_pcm_t *pcm, + snd_pcm_format_t format, + snd_pcm_access_t access, + unsigned int channels, + unsigned int rate, + int soft_resample, + unsigned int latency); +int snd_pcm_get_params(snd_pcm_t *pcm, + snd_pcm_uframes_t *buffer_size, + snd_pcm_uframes_t *period_size); + +/** \} */ + +/** + * \defgroup PCM_Info Stream Information + * \ingroup PCM + * See the \ref pcm page for more details. + * \{ + */ + +size_t snd_pcm_info_sizeof(void); +/** \hideinitializer + * \brief allocate an invalid #snd_pcm_info_t using standard alloca + * \param ptr returned pointer + */ +#define snd_pcm_info_alloca(ptr) __snd_alloca(ptr, snd_pcm_info) +int snd_pcm_info_malloc(snd_pcm_info_t **ptr); +void snd_pcm_info_free(snd_pcm_info_t *obj); +void snd_pcm_info_copy(snd_pcm_info_t *dst, const snd_pcm_info_t *src); +unsigned int snd_pcm_info_get_device(const snd_pcm_info_t *obj); +unsigned int snd_pcm_info_get_subdevice(const snd_pcm_info_t *obj); +snd_pcm_stream_t snd_pcm_info_get_stream(const snd_pcm_info_t *obj); +int snd_pcm_info_get_card(const snd_pcm_info_t *obj); +const char *snd_pcm_info_get_id(const snd_pcm_info_t *obj); +const char *snd_pcm_info_get_name(const snd_pcm_info_t *obj); +const char *snd_pcm_info_get_subdevice_name(const snd_pcm_info_t *obj); +snd_pcm_class_t snd_pcm_info_get_class(const snd_pcm_info_t *obj); +snd_pcm_subclass_t snd_pcm_info_get_subclass(const snd_pcm_info_t *obj); +unsigned int snd_pcm_info_get_subdevices_count(const snd_pcm_info_t *obj); +unsigned int snd_pcm_info_get_subdevices_avail(const snd_pcm_info_t *obj); +snd_pcm_sync_id_t snd_pcm_info_get_sync(const snd_pcm_info_t *obj); +void snd_pcm_info_set_device(snd_pcm_info_t *obj, unsigned int val); +void snd_pcm_info_set_subdevice(snd_pcm_info_t *obj, unsigned int val); +void snd_pcm_info_set_stream(snd_pcm_info_t *obj, snd_pcm_stream_t val); + +/** \} */ + +/** + * \defgroup PCM_HW_Params Hardware Parameters + * \ingroup PCM + * See the \ref pcm page for more details. + * \{ + */ + +int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); + +int snd_pcm_hw_params_can_mmap_sample_resolution(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_is_double(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_is_batch(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_is_block_transfer(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_is_monotonic(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_can_overrange(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_can_pause(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_can_resume(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_is_half_duplex(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_is_joint_duplex(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_can_sync_start(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_can_disable_period_wakeup(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_supports_audio_wallclock_ts(const snd_pcm_hw_params_t *params); /* deprecated, use audio_ts_type */ +int snd_pcm_hw_params_supports_audio_ts_type(const snd_pcm_hw_params_t *params, int type); +int snd_pcm_hw_params_get_rate_numden(const snd_pcm_hw_params_t *params, + unsigned int *rate_num, + unsigned int *rate_den); +int snd_pcm_hw_params_get_sbits(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_get_fifo_size(const snd_pcm_hw_params_t *params); + +#if 0 +typedef struct _snd_pcm_hw_strategy snd_pcm_hw_strategy_t; + +/* choices need to be sorted on ascending badness */ +typedef struct _snd_pcm_hw_strategy_simple_choices_list { + unsigned int value; + unsigned int badness; +} snd_pcm_hw_strategy_simple_choices_list_t; + +int snd_pcm_hw_params_strategy(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, + const snd_pcm_hw_strategy_t *strategy, + unsigned int badness_min, + unsigned int badness_max); + +void snd_pcm_hw_strategy_free(snd_pcm_hw_strategy_t *strategy); +int snd_pcm_hw_strategy_simple(snd_pcm_hw_strategy_t **strategyp, + unsigned int badness_min, + unsigned int badness_max); +int snd_pcm_hw_params_try_explain_failure(snd_pcm_t *pcm, + snd_pcm_hw_params_t *fail, + snd_pcm_hw_params_t *success, + unsigned int depth, + snd_output_t *out); + +#endif + +size_t snd_pcm_hw_params_sizeof(void); +/** \hideinitializer + * \brief allocate an invalid #snd_pcm_hw_params_t using standard alloca + * \param ptr returned pointer + */ +#define snd_pcm_hw_params_alloca(ptr) __snd_alloca(ptr, snd_pcm_hw_params) +int snd_pcm_hw_params_malloc(snd_pcm_hw_params_t **ptr); +void snd_pcm_hw_params_free(snd_pcm_hw_params_t *obj); +void snd_pcm_hw_params_copy(snd_pcm_hw_params_t *dst, const snd_pcm_hw_params_t *src); + +#if !defined(ALSA_LIBRARY_BUILD) && !defined(ALSA_PCM_OLD_HW_PARAMS_API) + +int snd_pcm_hw_params_get_access(const snd_pcm_hw_params_t *params, snd_pcm_access_t *_access); +int snd_pcm_hw_params_test_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t _access); +int snd_pcm_hw_params_set_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t _access); +int snd_pcm_hw_params_set_access_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *_access); +int snd_pcm_hw_params_set_access_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *_access); +int snd_pcm_hw_params_set_access_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask); +int snd_pcm_hw_params_get_access_mask(snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask); + +int snd_pcm_hw_params_get_format(const snd_pcm_hw_params_t *params, snd_pcm_format_t *val); +int snd_pcm_hw_params_test_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val); +int snd_pcm_hw_params_set_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val); +int snd_pcm_hw_params_set_format_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format); +int snd_pcm_hw_params_set_format_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format); +int snd_pcm_hw_params_set_format_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask); +void snd_pcm_hw_params_get_format_mask(snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask); + +int snd_pcm_hw_params_get_subformat(const snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat); +int snd_pcm_hw_params_test_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat); +int snd_pcm_hw_params_set_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat); +int snd_pcm_hw_params_set_subformat_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat); +int snd_pcm_hw_params_set_subformat_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat); +int snd_pcm_hw_params_set_subformat_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask); +void snd_pcm_hw_params_get_subformat_mask(snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask); + +int snd_pcm_hw_params_get_channels(const snd_pcm_hw_params_t *params, unsigned int *val); +int snd_pcm_hw_params_get_channels_min(const snd_pcm_hw_params_t *params, unsigned int *val); +int snd_pcm_hw_params_get_channels_max(const snd_pcm_hw_params_t *params, unsigned int *val); +int snd_pcm_hw_params_test_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); +int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); +int snd_pcm_hw_params_set_channels_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); +int snd_pcm_hw_params_set_channels_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); +int snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, unsigned int *max); +int snd_pcm_hw_params_set_channels_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); +int snd_pcm_hw_params_set_channels_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); +int snd_pcm_hw_params_set_channels_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); + +int snd_pcm_hw_params_get_rate(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_get_rate_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_get_rate_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_test_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); +int snd_pcm_hw_params_set_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); +int snd_pcm_hw_params_set_rate_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_rate_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_rate_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir); +int snd_pcm_hw_params_set_rate_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_rate_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_rate_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); +int snd_pcm_hw_params_get_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); +int snd_pcm_hw_params_set_export_buffer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); +int snd_pcm_hw_params_get_export_buffer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); +int snd_pcm_hw_params_set_period_wakeup(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); +int snd_pcm_hw_params_get_period_wakeup(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); + +int snd_pcm_hw_params_get_period_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_get_period_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_get_period_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_test_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); +int snd_pcm_hw_params_set_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); +int snd_pcm_hw_params_set_period_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_period_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_period_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir); +int snd_pcm_hw_params_set_period_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_period_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_period_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); + +int snd_pcm_hw_params_get_period_size(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir); +int snd_pcm_hw_params_get_period_size_min(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir); +int snd_pcm_hw_params_get_period_size_max(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir); +int snd_pcm_hw_params_test_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir); +int snd_pcm_hw_params_set_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir); +int snd_pcm_hw_params_set_period_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir); +int snd_pcm_hw_params_set_period_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir); +int snd_pcm_hw_params_set_period_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, int *mindir, snd_pcm_uframes_t *max, int *maxdir); +int snd_pcm_hw_params_set_period_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir); +int snd_pcm_hw_params_set_period_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir); +int snd_pcm_hw_params_set_period_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir); +int snd_pcm_hw_params_set_period_size_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); + +int snd_pcm_hw_params_get_periods(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_get_periods_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_get_periods_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_test_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); +int snd_pcm_hw_params_set_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); +int snd_pcm_hw_params_set_periods_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_periods_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_periods_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir); +int snd_pcm_hw_params_set_periods_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_periods_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_periods_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_periods_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); + +int snd_pcm_hw_params_get_buffer_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_get_buffer_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_get_buffer_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_test_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); +int snd_pcm_hw_params_set_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); +int snd_pcm_hw_params_set_buffer_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_buffer_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_buffer_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir); +int snd_pcm_hw_params_set_buffer_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_buffer_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_buffer_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); + +int snd_pcm_hw_params_get_buffer_size(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); +int snd_pcm_hw_params_get_buffer_size_min(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); +int snd_pcm_hw_params_get_buffer_size_max(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); +int snd_pcm_hw_params_test_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val); +int snd_pcm_hw_params_set_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val); +int snd_pcm_hw_params_set_buffer_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); +int snd_pcm_hw_params_set_buffer_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); +int snd_pcm_hw_params_set_buffer_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, snd_pcm_uframes_t *max); +int snd_pcm_hw_params_set_buffer_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); +int snd_pcm_hw_params_set_buffer_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); +int snd_pcm_hw_params_set_buffer_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); + +#endif /* !ALSA_LIBRARY_BUILD && !ALSA_PCM_OLD_HW_PARAMS_API */ + +int snd_pcm_hw_params_get_min_align(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); + +/** \} */ + +/** + * \defgroup PCM_SW_Params Software Parameters + * \ingroup PCM + * See the \ref pcm page for more details. + * \{ + */ + +size_t snd_pcm_sw_params_sizeof(void); +/** \hideinitializer + * \brief allocate an invalid #snd_pcm_sw_params_t using standard alloca + * \param ptr returned pointer + */ +#define snd_pcm_sw_params_alloca(ptr) __snd_alloca(ptr, snd_pcm_sw_params) +int snd_pcm_sw_params_malloc(snd_pcm_sw_params_t **ptr); +void snd_pcm_sw_params_free(snd_pcm_sw_params_t *obj); +void snd_pcm_sw_params_copy(snd_pcm_sw_params_t *dst, const snd_pcm_sw_params_t *src); +int snd_pcm_sw_params_get_boundary(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val); + +#if !defined(ALSA_LIBRARY_BUILD) && !defined(ALSA_PCM_OLD_SW_PARAMS_API) + +int snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_t val); +int snd_pcm_sw_params_get_tstamp_mode(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_t *val); +int snd_pcm_sw_params_set_tstamp_type(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_type_t val); +int snd_pcm_sw_params_get_tstamp_type(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_type_t *val); +int snd_pcm_sw_params_set_avail_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); +int snd_pcm_sw_params_get_avail_min(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val); +int snd_pcm_sw_params_set_period_event(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, int val); +int snd_pcm_sw_params_get_period_event(const snd_pcm_sw_params_t *params, int *val); +int snd_pcm_sw_params_set_start_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); +int snd_pcm_sw_params_get_start_threshold(const snd_pcm_sw_params_t *paramsm, snd_pcm_uframes_t *val); +int snd_pcm_sw_params_set_stop_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); +int snd_pcm_sw_params_get_stop_threshold(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val); +int snd_pcm_sw_params_set_silence_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); +int snd_pcm_sw_params_get_silence_threshold(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val); +int snd_pcm_sw_params_set_silence_size(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); +int snd_pcm_sw_params_get_silence_size(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val); + +#endif /* !ALSA_LIBRARY_BUILD && !ALSA_PCM_OLD_SW_PARAMS_API */ + +/** \} */ + +/* include old API */ +#ifndef ALSA_LIBRARY_BUILD +#if defined(ALSA_PCM_OLD_HW_PARAMS_API) || defined(ALSA_PCM_OLD_SW_PARAMS_API) +#include "pcm_old.h" +#endif +#endif + +/** + * \defgroup PCM_Access Access Mask Functions + * \ingroup PCM + * See the \ref pcm page for more details. + * \{ + */ + +size_t snd_pcm_access_mask_sizeof(void); +/** \hideinitializer + * \brief allocate an empty #snd_pcm_access_mask_t using standard alloca + * \param ptr returned pointer + */ +#define snd_pcm_access_mask_alloca(ptr) __snd_alloca(ptr, snd_pcm_access_mask) +int snd_pcm_access_mask_malloc(snd_pcm_access_mask_t **ptr); +void snd_pcm_access_mask_free(snd_pcm_access_mask_t *obj); +void snd_pcm_access_mask_copy(snd_pcm_access_mask_t *dst, const snd_pcm_access_mask_t *src); +void snd_pcm_access_mask_none(snd_pcm_access_mask_t *mask); +void snd_pcm_access_mask_any(snd_pcm_access_mask_t *mask); +int snd_pcm_access_mask_test(const snd_pcm_access_mask_t *mask, snd_pcm_access_t val); +int snd_pcm_access_mask_empty(const snd_pcm_access_mask_t *mask); +void snd_pcm_access_mask_set(snd_pcm_access_mask_t *mask, snd_pcm_access_t val); +void snd_pcm_access_mask_reset(snd_pcm_access_mask_t *mask, snd_pcm_access_t val); + +/** \} */ + +/** + * \defgroup PCM_Format Format Mask Functions + * \ingroup PCM + * See the \ref pcm page for more details. + * \{ + */ + +size_t snd_pcm_format_mask_sizeof(void); +/** \hideinitializer + * \brief allocate an empty #snd_pcm_format_mask_t using standard alloca + * \param ptr returned pointer + */ +#define snd_pcm_format_mask_alloca(ptr) __snd_alloca(ptr, snd_pcm_format_mask) +int snd_pcm_format_mask_malloc(snd_pcm_format_mask_t **ptr); +void snd_pcm_format_mask_free(snd_pcm_format_mask_t *obj); +void snd_pcm_format_mask_copy(snd_pcm_format_mask_t *dst, const snd_pcm_format_mask_t *src); +void snd_pcm_format_mask_none(snd_pcm_format_mask_t *mask); +void snd_pcm_format_mask_any(snd_pcm_format_mask_t *mask); +int snd_pcm_format_mask_test(const snd_pcm_format_mask_t *mask, snd_pcm_format_t val); +int snd_pcm_format_mask_empty(const snd_pcm_format_mask_t *mask); +void snd_pcm_format_mask_set(snd_pcm_format_mask_t *mask, snd_pcm_format_t val); +void snd_pcm_format_mask_reset(snd_pcm_format_mask_t *mask, snd_pcm_format_t val); + +/** \} */ + +/** + * \defgroup PCM_SubFormat Subformat Mask Functions + * \ingroup PCM + * See the \ref pcm page for more details. + * \{ + */ + +size_t snd_pcm_subformat_mask_sizeof(void); +/** \hideinitializer + * \brief allocate an empty #snd_pcm_subformat_mask_t using standard alloca + * \param ptr returned pointer + */ +#define snd_pcm_subformat_mask_alloca(ptr) __snd_alloca(ptr, snd_pcm_subformat_mask) +int snd_pcm_subformat_mask_malloc(snd_pcm_subformat_mask_t **ptr); +void snd_pcm_subformat_mask_free(snd_pcm_subformat_mask_t *obj); +void snd_pcm_subformat_mask_copy(snd_pcm_subformat_mask_t *dst, const snd_pcm_subformat_mask_t *src); +void snd_pcm_subformat_mask_none(snd_pcm_subformat_mask_t *mask); +void snd_pcm_subformat_mask_any(snd_pcm_subformat_mask_t *mask); +int snd_pcm_subformat_mask_test(const snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val); +int snd_pcm_subformat_mask_empty(const snd_pcm_subformat_mask_t *mask); +void snd_pcm_subformat_mask_set(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val); +void snd_pcm_subformat_mask_reset(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val); + +/** \} */ + +/** + * \defgroup PCM_Status Status Functions + * \ingroup PCM + * See the \ref pcm page for more details. + * \{ + */ + +size_t snd_pcm_status_sizeof(void); +/** \hideinitializer + * \brief allocate an invalid #snd_pcm_status_t using standard alloca + * \param ptr returned pointer + */ +#define snd_pcm_status_alloca(ptr) __snd_alloca(ptr, snd_pcm_status) +int snd_pcm_status_malloc(snd_pcm_status_t **ptr); +void snd_pcm_status_free(snd_pcm_status_t *obj); +void snd_pcm_status_copy(snd_pcm_status_t *dst, const snd_pcm_status_t *src); +snd_pcm_state_t snd_pcm_status_get_state(const snd_pcm_status_t *obj); +void snd_pcm_status_get_trigger_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr); +void snd_pcm_status_get_trigger_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr); +void snd_pcm_status_get_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr); +void snd_pcm_status_get_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr); +void snd_pcm_status_get_audio_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr); +void snd_pcm_status_get_driver_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr); +void snd_pcm_status_get_audio_htstamp_report(const snd_pcm_status_t *obj, + snd_pcm_audio_tstamp_report_t *audio_tstamp_report); +void snd_pcm_status_set_audio_htstamp_config(snd_pcm_status_t *obj, + snd_pcm_audio_tstamp_config_t *audio_tstamp_config); + +static inline void snd_pcm_pack_audio_tstamp_config(unsigned int *data, + snd_pcm_audio_tstamp_config_t *config) +{ + *data = config->report_delay; + *data <<= 4; + *data |= config->type_requested; +} + +static inline void snd_pcm_unpack_audio_tstamp_report(unsigned int data, unsigned int accuracy, + snd_pcm_audio_tstamp_report_t *report) +{ + data >>= 16; + report->valid = data & 1; + report->actual_type = (data >> 1) & 0xF; + report->accuracy_report = (data >> 5) & 1; + report->accuracy = accuracy; +} + +snd_pcm_sframes_t snd_pcm_status_get_delay(const snd_pcm_status_t *obj); +snd_pcm_uframes_t snd_pcm_status_get_avail(const snd_pcm_status_t *obj); +snd_pcm_uframes_t snd_pcm_status_get_avail_max(const snd_pcm_status_t *obj); +snd_pcm_uframes_t snd_pcm_status_get_overrange(const snd_pcm_status_t *obj); + +/** \} */ + +/** + * \defgroup PCM_Description Description Functions + * \ingroup PCM + * See the \ref pcm page for more details. + * \{ + */ + +const char *snd_pcm_type_name(snd_pcm_type_t type); +const char *snd_pcm_stream_name(const snd_pcm_stream_t stream); +const char *snd_pcm_access_name(const snd_pcm_access_t _access); +const char *snd_pcm_format_name(const snd_pcm_format_t format); +const char *snd_pcm_format_description(const snd_pcm_format_t format); +const char *snd_pcm_subformat_name(const snd_pcm_subformat_t subformat); +const char *snd_pcm_subformat_description(const snd_pcm_subformat_t subformat); +snd_pcm_format_t snd_pcm_format_value(const char* name); +const char *snd_pcm_tstamp_mode_name(const snd_pcm_tstamp_t mode); +const char *snd_pcm_state_name(const snd_pcm_state_t state); + +/** \} */ + +/** + * \defgroup PCM_Dump Debug Functions + * \ingroup PCM + * See the \ref pcm page for more details. + * \{ + */ + +int snd_pcm_dump(snd_pcm_t *pcm, snd_output_t *out); +int snd_pcm_dump_hw_setup(snd_pcm_t *pcm, snd_output_t *out); +int snd_pcm_dump_sw_setup(snd_pcm_t *pcm, snd_output_t *out); +int snd_pcm_dump_setup(snd_pcm_t *pcm, snd_output_t *out); +int snd_pcm_hw_params_dump(snd_pcm_hw_params_t *params, snd_output_t *out); +int snd_pcm_sw_params_dump(snd_pcm_sw_params_t *params, snd_output_t *out); +int snd_pcm_status_dump(snd_pcm_status_t *status, snd_output_t *out); + +/** \} */ + +/** + * \defgroup PCM_Direct Direct Access (MMAP) Functions + * \ingroup PCM + * See the \ref pcm page for more details. + * \{ + */ + +int snd_pcm_mmap_begin(snd_pcm_t *pcm, + const snd_pcm_channel_area_t **areas, + snd_pcm_uframes_t *offset, + snd_pcm_uframes_t *frames); +snd_pcm_sframes_t snd_pcm_mmap_commit(snd_pcm_t *pcm, + snd_pcm_uframes_t offset, + snd_pcm_uframes_t frames); +snd_pcm_sframes_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size); +snd_pcm_sframes_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size); +snd_pcm_sframes_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size); +snd_pcm_sframes_t snd_pcm_mmap_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size); + +/** \} */ + +/** + * \defgroup PCM_Helpers Helper Functions + * \ingroup PCM + * See the \ref pcm page for more details. + * \{ + */ + +int snd_pcm_format_signed(snd_pcm_format_t format); +int snd_pcm_format_unsigned(snd_pcm_format_t format); +int snd_pcm_format_linear(snd_pcm_format_t format); +int snd_pcm_format_float(snd_pcm_format_t format); +int snd_pcm_format_little_endian(snd_pcm_format_t format); +int snd_pcm_format_big_endian(snd_pcm_format_t format); +int snd_pcm_format_cpu_endian(snd_pcm_format_t format); +int snd_pcm_format_width(snd_pcm_format_t format); /* in bits */ +int snd_pcm_format_physical_width(snd_pcm_format_t format); /* in bits */ +snd_pcm_format_t snd_pcm_build_linear_format(int width, int pwidth, int unsignd, int big_endian); +ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples); +u_int8_t snd_pcm_format_silence(snd_pcm_format_t format); +u_int16_t snd_pcm_format_silence_16(snd_pcm_format_t format); +u_int32_t snd_pcm_format_silence_32(snd_pcm_format_t format); +u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format); +int snd_pcm_format_set_silence(snd_pcm_format_t format, void *buf, unsigned int samples); + +snd_pcm_sframes_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes); +ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames); +long snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes); +ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, long samples); + +int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_channel, snd_pcm_uframes_t dst_offset, + unsigned int samples, snd_pcm_format_t format); +int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_channels, snd_pcm_uframes_t dst_offset, + unsigned int channels, snd_pcm_uframes_t frames, snd_pcm_format_t format); +int snd_pcm_area_copy(const snd_pcm_channel_area_t *dst_channel, snd_pcm_uframes_t dst_offset, + const snd_pcm_channel_area_t *src_channel, snd_pcm_uframes_t src_offset, + unsigned int samples, snd_pcm_format_t format); +int snd_pcm_areas_copy(const snd_pcm_channel_area_t *dst_channels, snd_pcm_uframes_t dst_offset, + const snd_pcm_channel_area_t *src_channels, snd_pcm_uframes_t src_offset, + unsigned int channels, snd_pcm_uframes_t frames, snd_pcm_format_t format); + +/** \} */ + +/** + * \defgroup PCM_Hook Hook Extension + * \ingroup PCM + * See the \ref pcm page for more details. + * \{ + */ + +/** type of pcm hook */ +typedef enum _snd_pcm_hook_type { + SND_PCM_HOOK_TYPE_HW_PARAMS = 0, + SND_PCM_HOOK_TYPE_HW_FREE, + SND_PCM_HOOK_TYPE_CLOSE, + SND_PCM_HOOK_TYPE_LAST = SND_PCM_HOOK_TYPE_CLOSE +} snd_pcm_hook_type_t; + +/** PCM hook container */ +typedef struct _snd_pcm_hook snd_pcm_hook_t; +/** PCM hook callback function */ +typedef int (*snd_pcm_hook_func_t)(snd_pcm_hook_t *hook); +snd_pcm_t *snd_pcm_hook_get_pcm(snd_pcm_hook_t *hook); +void *snd_pcm_hook_get_private(snd_pcm_hook_t *hook); +void snd_pcm_hook_set_private(snd_pcm_hook_t *hook, void *private_data); +int snd_pcm_hook_add(snd_pcm_hook_t **hookp, snd_pcm_t *pcm, + snd_pcm_hook_type_t type, + snd_pcm_hook_func_t func, void *private_data); +int snd_pcm_hook_remove(snd_pcm_hook_t *hook); + +/** \} */ + +/** + * \defgroup PCM_Scope Scope Plugin Extension + * \ingroup PCM + * See the \ref pcm page for more details. + * \{ + */ + +/** #SND_PCM_TYPE_METER scope functions */ +typedef struct _snd_pcm_scope_ops { + /** \brief Enable and prepare it using current params + * \param scope scope handle + */ + int (*enable)(snd_pcm_scope_t *scope); + /** \brief Disable + * \param scope scope handle + */ + void (*disable)(snd_pcm_scope_t *scope); + /** \brief PCM has been started + * \param scope scope handle + */ + void (*start)(snd_pcm_scope_t *scope); + /** \brief PCM has been stopped + * \param scope scope handle + */ + void (*stop)(snd_pcm_scope_t *scope); + /** \brief New frames are present + * \param scope scope handle + */ + void (*update)(snd_pcm_scope_t *scope); + /** \brief Reset status + * \param scope scope handle + */ + void (*reset)(snd_pcm_scope_t *scope); + /** \brief PCM is closing + * \param scope scope handle + */ + void (*close)(snd_pcm_scope_t *scope); +} snd_pcm_scope_ops_t; + +snd_pcm_uframes_t snd_pcm_meter_get_bufsize(snd_pcm_t *pcm); +unsigned int snd_pcm_meter_get_channels(snd_pcm_t *pcm); +unsigned int snd_pcm_meter_get_rate(snd_pcm_t *pcm); +snd_pcm_uframes_t snd_pcm_meter_get_now(snd_pcm_t *pcm); +snd_pcm_uframes_t snd_pcm_meter_get_boundary(snd_pcm_t *pcm); +int snd_pcm_meter_add_scope(snd_pcm_t *pcm, snd_pcm_scope_t *scope); +snd_pcm_scope_t *snd_pcm_meter_search_scope(snd_pcm_t *pcm, const char *name); +int snd_pcm_scope_malloc(snd_pcm_scope_t **ptr); +void snd_pcm_scope_set_ops(snd_pcm_scope_t *scope, + const snd_pcm_scope_ops_t *val); +void snd_pcm_scope_set_name(snd_pcm_scope_t *scope, const char *val); +const char *snd_pcm_scope_get_name(snd_pcm_scope_t *scope); +void *snd_pcm_scope_get_callback_private(snd_pcm_scope_t *scope); +void snd_pcm_scope_set_callback_private(snd_pcm_scope_t *scope, void *val); +int snd_pcm_scope_s16_open(snd_pcm_t *pcm, const char *name, + snd_pcm_scope_t **scopep); +int16_t *snd_pcm_scope_s16_get_channel_buffer(snd_pcm_scope_t *scope, + unsigned int channel); + +/** \} */ + +/** + * \defgroup PCM_Simple Simple setup functions + * \ingroup PCM + * See the \ref pcm page for more details. + * \{ + */ + +/** Simple PCM latency type */ +typedef enum _snd_spcm_latency { + /** standard latency - for standard playback or capture + (estimated latency in one direction 350ms) */ + SND_SPCM_LATENCY_STANDARD = 0, + /** medium latency - software phones etc. + (estimated latency in one direction maximally 25ms */ + SND_SPCM_LATENCY_MEDIUM, + /** realtime latency - realtime applications (effect processors etc.) + (estimated latency in one direction 5ms and better) */ + SND_SPCM_LATENCY_REALTIME +} snd_spcm_latency_t; + +/** Simple PCM xrun type */ +typedef enum _snd_spcm_xrun_type { + /** driver / library will ignore all xruns, the stream runs forever */ + SND_SPCM_XRUN_IGNORE = 0, + /** driver / library stops the stream when an xrun occurs */ + SND_SPCM_XRUN_STOP +} snd_spcm_xrun_type_t; + +/** Simple PCM duplex type */ +typedef enum _snd_spcm_duplex_type { + /** liberal duplex - the buffer and period sizes might not match */ + SND_SPCM_DUPLEX_LIBERAL = 0, + /** pedantic duplex - the buffer and period sizes MUST match */ + SND_SPCM_DUPLEX_PEDANTIC +} snd_spcm_duplex_type_t; + +int snd_spcm_init(snd_pcm_t *pcm, + unsigned int rate, + unsigned int channels, + snd_pcm_format_t format, + snd_pcm_subformat_t subformat, + snd_spcm_latency_t latency, + snd_pcm_access_t _access, + snd_spcm_xrun_type_t xrun_type); + +int snd_spcm_init_duplex(snd_pcm_t *playback_pcm, + snd_pcm_t *capture_pcm, + unsigned int rate, + unsigned int channels, + snd_pcm_format_t format, + snd_pcm_subformat_t subformat, + snd_spcm_latency_t latency, + snd_pcm_access_t _access, + snd_spcm_xrun_type_t xrun_type, + snd_spcm_duplex_type_t duplex_type); + +int snd_spcm_init_get_params(snd_pcm_t *pcm, + unsigned int *rate, + snd_pcm_uframes_t *buffer_size, + snd_pcm_uframes_t *period_size); + +/** \} */ + +/** + * \defgroup PCM_Deprecated Deprecated Functions + * \ingroup PCM + * See the \ref pcm page for more details. + * \{ + */ + +/* Deprecated functions, for compatibility */ +const char *snd_pcm_start_mode_name(snd_pcm_start_t mode) __attribute__((deprecated)); +const char *snd_pcm_xrun_mode_name(snd_pcm_xrun_t mode) __attribute__((deprecated)); +int snd_pcm_sw_params_set_start_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_start_t val) __attribute__((deprecated)); +snd_pcm_start_t snd_pcm_sw_params_get_start_mode(const snd_pcm_sw_params_t *params) __attribute__((deprecated)); +int snd_pcm_sw_params_set_xrun_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_xrun_t val) __attribute__((deprecated)); +snd_pcm_xrun_t snd_pcm_sw_params_get_xrun_mode(const snd_pcm_sw_params_t *params) __attribute__((deprecated)); +#if !defined(ALSA_LIBRARY_BUILD) && !defined(ALSA_PCM_OLD_SW_PARAMS_API) +int snd_pcm_sw_params_set_xfer_align(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val) __attribute__((deprecated)); +int snd_pcm_sw_params_get_xfer_align(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val) __attribute__((deprecated)); +int snd_pcm_sw_params_set_sleep_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, unsigned int val) __attribute__((deprecated)); +int snd_pcm_sw_params_get_sleep_min(const snd_pcm_sw_params_t *params, unsigned int *val) __attribute__((deprecated)); +#endif /* !ALSA_LIBRARY_BUILD && !ALSA_PCM_OLD_SW_PARAMS_API */ +#if !defined(ALSA_LIBRARY_BUILD) && !defined(ALSA_PCM_OLD_HW_PARAMS_API) +int snd_pcm_hw_params_get_tick_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated)); +int snd_pcm_hw_params_get_tick_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated)); +int snd_pcm_hw_params_get_tick_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated)); +int snd_pcm_hw_params_test_tick_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir) __attribute__((deprecated)); +int snd_pcm_hw_params_set_tick_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir) __attribute__((deprecated)); +int snd_pcm_hw_params_set_tick_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated)); +int snd_pcm_hw_params_set_tick_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated)); +int snd_pcm_hw_params_set_tick_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir) __attribute__((deprecated)); +int snd_pcm_hw_params_set_tick_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated)); +int snd_pcm_hw_params_set_tick_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated)); +int snd_pcm_hw_params_set_tick_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated)); +#endif /* !ALSA_LIBRARY_BUILD && !ALSA_PCM_OLD_HW_PARAMS_API */ + +/** \} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALSA_PCM_H */ diff --git a/thirdparty/linuxbsd_headers/alsa/pcm_external.h b/thirdparty/linuxbsd_headers/alsa/pcm_external.h new file mode 100644 index 0000000000..5750418882 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/pcm_external.h @@ -0,0 +1,70 @@ +/** + * \file include/pcm_external.h + * \brief External PCM plugin SDK + * \author Takashi Iwai <tiwai@suse.de> + * \date 2005 + * + * Extern PCM plugin SDK. + */ + +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef __ALSA_PCM_EXTERNAL_H +#define __ALSA_PCM_EXTERNAL_H + +#include "pcm.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup Plugin_SDK External PCM plugin SDK + * \{ + */ + +/** + * Define the object entry for external PCM plugins + */ +#define SND_PCM_PLUGIN_ENTRY(name) _snd_pcm_##name##_open + +/** + * Define the symbols of the given plugin with versions + */ +#define SND_PCM_PLUGIN_SYMBOL(name) SND_DLSYM_BUILD_VERSION(SND_PCM_PLUGIN_ENTRY(name), SND_PCM_DLSYM_VERSION); + +/** + * Define the plugin + */ +#define SND_PCM_PLUGIN_DEFINE_FUNC(plugin) \ +int SND_PCM_PLUGIN_ENTRY(plugin) (snd_pcm_t **pcmp, const char *name,\ + snd_config_t *root, snd_config_t *conf, \ + snd_pcm_stream_t stream, int mode) + +#include "pcm_ioplug.h" +#include "pcm_extplug.h" + +int snd_pcm_parse_control_id(snd_config_t *conf, snd_ctl_elem_id_t *ctl_id, int *cardp, + int *cchannelsp, int *hwctlp); + +/** \} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALSA_PCM_EXTERNAL_H */ diff --git a/thirdparty/linuxbsd_headers/alsa/pcm_extplug.h b/thirdparty/linuxbsd_headers/alsa/pcm_extplug.h new file mode 100644 index 0000000000..e3b71bc07e --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/pcm_extplug.h @@ -0,0 +1,206 @@ +/** + * \file include/pcm_extplug.h + * \brief External Filter-Plugin SDK + * \author Takashi Iwai <tiwai@suse.de> + * \date 2005 + * + * External Filter-Plugin SDK + */ + +/* + * ALSA external PCM plugin SDK (draft version) + * + * Copyright (c) 2005 Takashi Iwai <tiwai@suse.de> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_PCM_EXTPLUG_H +#define __ALSA_PCM_EXTPLUG_H + +/** + * \defgroup PCM_ExtPlug External Filter plugin SDK + * \ingroup Plugin_SDK + * See the \ref pcm page for more details. + * \{ + */ + +/** hw constraints for extplug */ +enum { + SND_PCM_EXTPLUG_HW_FORMAT, /**< format */ + SND_PCM_EXTPLUG_HW_CHANNELS, /**< channels */ + SND_PCM_EXTPLUG_HW_PARAMS /**< max number of hw constraints */ +}; + +/** Handle of external filter plugin */ +typedef struct snd_pcm_extplug snd_pcm_extplug_t; +/** Callback table of extplug */ +typedef struct snd_pcm_extplug_callback snd_pcm_extplug_callback_t; +#ifdef DOC_HIDDEN +/* redefine typedefs for stupid doxygen */ +typedef snd_pcm_extplug snd_pcm_extplug_t; +typedef snd_pcm_extplug_callback snd_pcm_extplug_callback_t; +#endif + +/* + * Protocol version + */ +#define SND_PCM_EXTPLUG_VERSION_MAJOR 1 /**< Protocol major version */ +#define SND_PCM_EXTPLUG_VERSION_MINOR 0 /**< Protocol minor version */ +#define SND_PCM_EXTPLUG_VERSION_TINY 2 /**< Protocol tiny version */ +/** + * Filter-plugin protocol version + */ +#define SND_PCM_EXTPLUG_VERSION ((SND_PCM_EXTPLUG_VERSION_MAJOR<<16) |\ + (SND_PCM_EXTPLUG_VERSION_MINOR<<8) |\ + (SND_PCM_EXTPLUG_VERSION_TINY)) + +/** Handle of extplug */ +struct snd_pcm_extplug { + /** + * protocol version; #SND_PCM_EXTPLUG_VERSION must be filled here + * before calling #snd_pcm_extplug_create() + */ + unsigned int version; + /** + * name of this plugin; must be filled before calling #snd_pcm_extplug_create() + */ + const char *name; + /** + * callbacks of this plugin; must be filled before calling #snd_pcm_extplug_create() + */ + const snd_pcm_extplug_callback_t *callback; + /** + * private data, which can be used freely in the driver callbacks + */ + void *private_data; + /** + * PCM handle filled by #snd_pcm_extplug_create() + */ + snd_pcm_t *pcm; + /** + * stream direction; read-only status + */ + snd_pcm_stream_t stream; + /** + * format hw parameter; filled after hw_params is caled + */ + snd_pcm_format_t format; + /** + * subformat hw parameter; filled after hw_params is caled + */ + snd_pcm_subformat_t subformat; + /** + * channels hw parameter; filled after hw_params is caled + */ + unsigned int channels; + /** + * rate hw parameter; filled after hw_params is caled + */ + unsigned int rate; + /** + * slave_format hw parameter; filled after hw_params is caled + */ + snd_pcm_format_t slave_format; + /** + * slave_subformat hw parameter; filled after hw_params is caled + */ + snd_pcm_subformat_t slave_subformat; + /** + * slave_channels hw parameter; filled after hw_params is caled + */ + unsigned int slave_channels; +}; + +/** Callback table of extplug */ +struct snd_pcm_extplug_callback { + /** + * transfer between source and destination; this is a required callback + */ + snd_pcm_sframes_t (*transfer)(snd_pcm_extplug_t *ext, + const snd_pcm_channel_area_t *dst_areas, + snd_pcm_uframes_t dst_offset, + const snd_pcm_channel_area_t *src_areas, + snd_pcm_uframes_t src_offset, + snd_pcm_uframes_t size); + /** + * close the PCM; optional + */ + int (*close)(snd_pcm_extplug_t *ext); + /** + * hw_params; optional + */ + int (*hw_params)(snd_pcm_extplug_t *ext, snd_pcm_hw_params_t *params); + /** + * hw_free; optional + */ + int (*hw_free)(snd_pcm_extplug_t *ext); + /** + * dump; optional + */ + void (*dump)(snd_pcm_extplug_t *ext, snd_output_t *out); + /** + * init; optional initialization called at prepare or reset + */ + int (*init)(snd_pcm_extplug_t *ext); + /** + * query the channel maps; optional; since v1.0.2 + */ + snd_pcm_chmap_query_t **(*query_chmaps)(snd_pcm_extplug_t *ext); + /** + * get the channel map; optional; since v1.0.2 + */ + snd_pcm_chmap_t *(*get_chmap)(snd_pcm_extplug_t *ext); + /** + * set the channel map; optional; since v1.0.2 + */ + int (*set_chmap)(snd_pcm_extplug_t *ext, const snd_pcm_chmap_t *map); +}; + + +int snd_pcm_extplug_create(snd_pcm_extplug_t *ext, const char *name, + snd_config_t *root, snd_config_t *slave_conf, + snd_pcm_stream_t stream, int mode); +int snd_pcm_extplug_delete(snd_pcm_extplug_t *ext); + +/* clear hw_parameter setting */ +void snd_pcm_extplug_params_reset(snd_pcm_extplug_t *ext); + +/* hw_parameter setting */ +int snd_pcm_extplug_set_param_list(snd_pcm_extplug_t *extplug, int type, unsigned int num_list, const unsigned int *list); +int snd_pcm_extplug_set_param_minmax(snd_pcm_extplug_t *extplug, int type, unsigned int min, unsigned int max); +int snd_pcm_extplug_set_slave_param_list(snd_pcm_extplug_t *extplug, int type, unsigned int num_list, const unsigned int *list); +int snd_pcm_extplug_set_slave_param_minmax(snd_pcm_extplug_t *extplug, int type, unsigned int min, unsigned int max); + +/** + * set the parameter constraint with a single value + */ +static __inline__ int snd_pcm_extplug_set_param(snd_pcm_extplug_t *extplug, int type, unsigned int val) +{ + return snd_pcm_extplug_set_param_list(extplug, type, 1, &val); +} + +/** + * set the parameter constraint for slave PCM with a single value + */ +static __inline__ int snd_pcm_extplug_set_slave_param(snd_pcm_extplug_t *extplug, int type, unsigned int val) +{ + return snd_pcm_extplug_set_slave_param_list(extplug, type, 1, &val); +} + +/** \} */ + +#endif /* __ALSA_PCM_EXTPLUG_H */ diff --git a/thirdparty/linuxbsd_headers/alsa/pcm_ioplug.h b/thirdparty/linuxbsd_headers/alsa/pcm_ioplug.h new file mode 100644 index 0000000000..8c25e5e198 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/pcm_ioplug.h @@ -0,0 +1,234 @@ +/** + * \file include/pcm_ioplug.h + * \brief External I/O-Plugin SDK + * \author Takashi Iwai <tiwai@suse.de> + * \date 2005 + * + * External I/O-Plugin SDK + */ + +/* + * ALSA external PCM plugin SDK + * + * Copyright (c) 2005 Takashi Iwai <tiwai@suse.de> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_PCM_IOPLUG_H +#define __ALSA_PCM_IOPLUG_H + +/** + * \defgroup PCM_IOPlug External I/O plugin SDK + * \ingroup Plugin_SDK + * See the \ref pcm page for more details. + * \{ + */ + +/** hw constraints for ioplug */ +enum { + SND_PCM_IOPLUG_HW_ACCESS = 0, /**< access type */ + SND_PCM_IOPLUG_HW_FORMAT, /**< format */ + SND_PCM_IOPLUG_HW_CHANNELS, /**< channels */ + SND_PCM_IOPLUG_HW_RATE, /**< rate */ + SND_PCM_IOPLUG_HW_PERIOD_BYTES, /**< period bytes */ + SND_PCM_IOPLUG_HW_BUFFER_BYTES, /**< buffer bytes */ + SND_PCM_IOPLUG_HW_PERIODS, /**< number of periods */ + SND_PCM_IOPLUG_HW_PARAMS /**< max number of hw constraints */ +}; + +/** I/O plugin handle */ +typedef struct snd_pcm_ioplug snd_pcm_ioplug_t; +/** Callback table of ioplug */ +typedef struct snd_pcm_ioplug_callback snd_pcm_ioplug_callback_t; +#ifdef DOC_HIDDEN +/* redefine typedefs for stupid doxygen */ +typedef snd_pcm_ioplug snd_pcm_ioplug_t; +typedef snd_pcm_ioplug_callback snd_pcm_ioplug_callback_t; +#endif + +/* + * bit flags for additional conditions + */ +#define SND_PCM_IOPLUG_FLAG_LISTED (1<<0) /**< list up this PCM */ +#define SND_PCM_IOPLUG_FLAG_MONOTONIC (1<<1) /**< monotonic timestamps */ + +/* + * Protocol version + */ +#define SND_PCM_IOPLUG_VERSION_MAJOR 1 /**< Protocol major version */ +#define SND_PCM_IOPLUG_VERSION_MINOR 0 /**< Protocol minor version */ +#define SND_PCM_IOPLUG_VERSION_TINY 2 /**< Protocol tiny version */ +/** + * IO-plugin protocol version + */ +#define SND_PCM_IOPLUG_VERSION ((SND_PCM_IOPLUG_VERSION_MAJOR<<16) |\ + (SND_PCM_IOPLUG_VERSION_MINOR<<8) |\ + (SND_PCM_IOPLUG_VERSION_TINY)) + +/** Handle of ioplug */ +struct snd_pcm_ioplug { + /** + * protocol version; #SND_PCM_IOPLUG_VERSION must be filled here + * before calling #snd_pcm_ioplug_create() + */ + unsigned int version; + /** + * name of this plugin; must be filled before calling #snd_pcm_ioplug_create() + */ + const char *name; + unsigned int flags; /**< SND_PCM_IOPLUG_FLAG_XXX */ + int poll_fd; /**< poll file descriptor */ + unsigned int poll_events; /**< poll events */ + unsigned int mmap_rw; /**< pseudo mmap mode */ + /** + * callbacks of this plugin; must be filled before calling #snd_pcm_ioplug_create() + */ + const snd_pcm_ioplug_callback_t *callback; + /** + * private data, which can be used freely in the driver callbacks + */ + void *private_data; + /** + * PCM handle filled by #snd_pcm_extplug_create() + */ + snd_pcm_t *pcm; + + snd_pcm_stream_t stream; /**< stream direcion; read-only */ + snd_pcm_state_t state; /**< current PCM state; read-only */ + volatile snd_pcm_uframes_t appl_ptr; /**< application pointer; read-only */ + volatile snd_pcm_uframes_t hw_ptr; /**< hw pointer; read-only */ + int nonblock; /**< non-block mode; read-only */ + + snd_pcm_access_t access; /**< access type; filled after hw_params is called */ + snd_pcm_format_t format; /**< PCM format; filled after hw_params is called */ + unsigned int channels; /**< number of channels; filled after hw_params is called */ + unsigned int rate; /**< rate; filled after hw_params is called */ + snd_pcm_uframes_t period_size; /**< period size; filled after hw_params is called */ + snd_pcm_uframes_t buffer_size; /**< buffer size; filled after hw_params is called */ +}; + +/** Callback table of ioplug */ +struct snd_pcm_ioplug_callback { + /** + * start the PCM; required, called inside mutex lock + */ + int (*start)(snd_pcm_ioplug_t *io); + /** + * stop the PCM; required, called inside mutex lock + */ + int (*stop)(snd_pcm_ioplug_t *io); + /** + * get the current DMA position; required, called inside mutex lock + */ + snd_pcm_sframes_t (*pointer)(snd_pcm_ioplug_t *io); + /** + * transfer the data; optional, called inside mutex lock + */ + snd_pcm_sframes_t (*transfer)(snd_pcm_ioplug_t *io, + const snd_pcm_channel_area_t *areas, + snd_pcm_uframes_t offset, + snd_pcm_uframes_t size); + /** + * close the PCM; optional + */ + int (*close)(snd_pcm_ioplug_t *io); + /** + * hw_params; optional + */ + int (*hw_params)(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params); + /** + * hw_free; optional + */ + int (*hw_free)(snd_pcm_ioplug_t *io); + /** + * sw_params; optional + */ + int (*sw_params)(snd_pcm_ioplug_t *io, snd_pcm_sw_params_t *params); + /** + * prepare; optional + */ + int (*prepare)(snd_pcm_ioplug_t *io); + /** + * drain; optional + */ + int (*drain)(snd_pcm_ioplug_t *io); + /** + * toggle pause; optional, called inside mutex lock + */ + int (*pause)(snd_pcm_ioplug_t *io, int enable); + /** + * resume; optional + */ + int (*resume)(snd_pcm_ioplug_t *io); + /** + * poll descriptors count; optional + */ + int (*poll_descriptors_count)(snd_pcm_ioplug_t *io); + /** + * poll descriptors; optional + */ + int (*poll_descriptors)(snd_pcm_ioplug_t *io, struct pollfd *pfd, unsigned int space); + /** + * mangle poll events; optional + */ + int (*poll_revents)(snd_pcm_ioplug_t *io, struct pollfd *pfd, unsigned int nfds, unsigned short *revents); + /** + * dump; optional + */ + void (*dump)(snd_pcm_ioplug_t *io, snd_output_t *out); + /** + * get the delay for the running PCM; optional; since v1.0.1 + */ + int (*delay)(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delayp); + /** + * query the channel maps; optional; since v1.0.2 + */ + snd_pcm_chmap_query_t **(*query_chmaps)(snd_pcm_ioplug_t *io); + /** + * get the channel map; optional; since v1.0.2 + */ + snd_pcm_chmap_t *(*get_chmap)(snd_pcm_ioplug_t *io); + /** + * set the channel map; optional; since v1.0.2 + */ + int (*set_chmap)(snd_pcm_ioplug_t *io, const snd_pcm_chmap_t *map); +}; + + +int snd_pcm_ioplug_create(snd_pcm_ioplug_t *io, const char *name, + snd_pcm_stream_t stream, int mode); +int snd_pcm_ioplug_delete(snd_pcm_ioplug_t *io); + +/* update poll_fd and mmap_rw */ +int snd_pcm_ioplug_reinit_status(snd_pcm_ioplug_t *ioplug); + +/* get a mmap area (for mmap_rw only) */ +const snd_pcm_channel_area_t *snd_pcm_ioplug_mmap_areas(snd_pcm_ioplug_t *ioplug); + +/* clear hw_parameter setting */ +void snd_pcm_ioplug_params_reset(snd_pcm_ioplug_t *io); + +/* hw_parameter setting */ +int snd_pcm_ioplug_set_param_minmax(snd_pcm_ioplug_t *io, int type, unsigned int min, unsigned int max); +int snd_pcm_ioplug_set_param_list(snd_pcm_ioplug_t *io, int type, unsigned int num_list, const unsigned int *list); + +/* change PCM status */ +int snd_pcm_ioplug_set_state(snd_pcm_ioplug_t *ioplug, snd_pcm_state_t state); + +/** \} */ + +#endif /* __ALSA_PCM_IOPLUG_H */ diff --git a/thirdparty/linuxbsd_headers/alsa/pcm_old.h b/thirdparty/linuxbsd_headers/alsa/pcm_old.h new file mode 100644 index 0000000000..e6e050fc32 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/pcm_old.h @@ -0,0 +1,230 @@ +/* + * Old ALSA 0.9.x API + */ + +#ifdef ALSA_PCM_OLD_HW_PARAMS_API + +asm(".symver snd_pcm_hw_params_get_access,snd_pcm_hw_params_get_access@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_access_first,snd_pcm_hw_params_set_access_first@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_access_last,snd_pcm_hw_params_set_access_last@ALSA_0.9"); + +int snd_pcm_hw_params_get_access(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_test_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t val); +int snd_pcm_hw_params_set_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t val); +snd_pcm_access_t snd_pcm_hw_params_set_access_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); +snd_pcm_access_t snd_pcm_hw_params_set_access_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_set_access_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask); +void snd_pcm_hw_params_get_access_mask(snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask); + +asm(".symver snd_pcm_hw_params_get_format,snd_pcm_hw_params_get_format@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_format_first,snd_pcm_hw_params_set_format_first@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_format_last,snd_pcm_hw_params_set_format_last@ALSA_0.9"); + +int snd_pcm_hw_params_get_format(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_test_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val); +int snd_pcm_hw_params_set_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val); +snd_pcm_format_t snd_pcm_hw_params_set_format_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); +snd_pcm_format_t snd_pcm_hw_params_set_format_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_set_format_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask); +void snd_pcm_hw_params_get_format_mask(snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask); + +asm(".symver snd_pcm_hw_params_get_subformat,snd_pcm_hw_params_get_subformat@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_subformat_first,snd_pcm_hw_params_set_subformat_first@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_subformat_last,snd_pcm_hw_params_set_subformat_last@ALSA_0.9"); + +int snd_pcm_hw_params_test_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t val); +int snd_pcm_hw_params_get_subformat(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_set_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t val); +snd_pcm_subformat_t snd_pcm_hw_params_set_subformat_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); +snd_pcm_subformat_t snd_pcm_hw_params_set_subformat_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_set_subformat_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask); +void snd_pcm_hw_params_get_subformat_mask(snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask); + +asm(".symver snd_pcm_hw_params_get_channels,snd_pcm_hw_params_get_channels@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_get_channels_min,snd_pcm_hw_params_get_channels_min@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_get_channels_max,snd_pcm_hw_params_get_channels_max@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_channels_near,snd_pcm_hw_params_set_channels_near@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_channels_first,snd_pcm_hw_params_set_channels_first@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_channels_last,snd_pcm_hw_params_set_channels_last@ALSA_0.9"); + +int snd_pcm_hw_params_get_channels(const snd_pcm_hw_params_t *params); +unsigned int snd_pcm_hw_params_get_channels_min(const snd_pcm_hw_params_t *params); +unsigned int snd_pcm_hw_params_get_channels_max(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_test_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); +int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); +int snd_pcm_hw_params_set_channels_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); +int snd_pcm_hw_params_set_channels_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); +int snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, unsigned int *max); +unsigned int snd_pcm_hw_params_set_channels_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); +unsigned int snd_pcm_hw_params_set_channels_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); +unsigned int snd_pcm_hw_params_set_channels_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); + +asm(".symver snd_pcm_hw_params_get_rate,snd_pcm_hw_params_get_rate@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_get_rate_min,snd_pcm_hw_params_get_rate_min@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_get_rate_max,snd_pcm_hw_params_get_rate_max@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_rate_near,snd_pcm_hw_params_set_rate_near@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_rate_first,snd_pcm_hw_params_set_rate_first@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_rate_last,snd_pcm_hw_params_set_rate_last@ALSA_0.9"); + +int snd_pcm_hw_params_get_rate(const snd_pcm_hw_params_t *params, int *dir); +unsigned int snd_pcm_hw_params_get_rate_min(const snd_pcm_hw_params_t *params, int *dir); +unsigned int snd_pcm_hw_params_get_rate_max(const snd_pcm_hw_params_t *params, int *dir); +int snd_pcm_hw_params_test_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); +int snd_pcm_hw_params_set_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); +int snd_pcm_hw_params_set_rate_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_rate_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_rate_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir); +unsigned int snd_pcm_hw_params_set_rate_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir); +unsigned int snd_pcm_hw_params_set_rate_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); +unsigned int snd_pcm_hw_params_set_rate_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); +int snd_pcm_hw_params_set_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); +int snd_pcm_hw_params_get_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); + +asm(".symver snd_pcm_hw_params_get_period_time,snd_pcm_hw_params_get_period_time@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_get_period_time_min,snd_pcm_hw_params_get_period_time_min@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_get_period_time_max,snd_pcm_hw_params_get_period_time_max@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_period_time_near,snd_pcm_hw_params_set_period_time_near@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_period_time_first,snd_pcm_hw_params_set_period_time_first@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_period_time_last,snd_pcm_hw_params_set_period_time_last@ALSA_0.9"); + +int snd_pcm_hw_params_get_period_time(const snd_pcm_hw_params_t *params, int *dir); +unsigned int snd_pcm_hw_params_get_period_time_min(const snd_pcm_hw_params_t *params, int *dir); +unsigned int snd_pcm_hw_params_get_period_time_max(const snd_pcm_hw_params_t *params, int *dir); +int snd_pcm_hw_params_test_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); +int snd_pcm_hw_params_set_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); +int snd_pcm_hw_params_set_period_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_period_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_period_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir); +unsigned int snd_pcm_hw_params_set_period_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir); +unsigned int snd_pcm_hw_params_set_period_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); +unsigned int snd_pcm_hw_params_set_period_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); + +asm(".symver snd_pcm_hw_params_get_period_size,snd_pcm_hw_params_get_period_size@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_get_period_size_min,snd_pcm_hw_params_get_period_size_min@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_get_period_size_max,snd_pcm_hw_params_get_period_size_max@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_period_size_near,snd_pcm_hw_params_set_period_size_near@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_period_size_first,snd_pcm_hw_params_set_period_size_first@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_period_size_last,snd_pcm_hw_params_set_period_size_last@ALSA_0.9"); + +snd_pcm_sframes_t snd_pcm_hw_params_get_period_size(const snd_pcm_hw_params_t *params, int *dir); +snd_pcm_uframes_t snd_pcm_hw_params_get_period_size_min(const snd_pcm_hw_params_t *params, int *dir); +snd_pcm_uframes_t snd_pcm_hw_params_get_period_size_max(const snd_pcm_hw_params_t *params, int *dir); +int snd_pcm_hw_params_test_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir); +int snd_pcm_hw_params_set_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir); +int snd_pcm_hw_params_set_period_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir); +int snd_pcm_hw_params_set_period_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir); +int snd_pcm_hw_params_set_period_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, int *mindir, snd_pcm_uframes_t *max, int *maxdir); +snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int *dir); +snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); +snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); +int snd_pcm_hw_params_set_period_size_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); + +asm(".symver snd_pcm_hw_params_get_periods,snd_pcm_hw_params_get_periods@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_get_periods_min,snd_pcm_hw_params_get_periods_min@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_get_periods_max,snd_pcm_hw_params_get_periods_max@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_periods_near,snd_pcm_hw_params_set_periods_near@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_periods_first,snd_pcm_hw_params_set_periods_first@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_periods_last,snd_pcm_hw_params_set_periods_last@ALSA_0.9"); + +int snd_pcm_hw_params_get_periods(const snd_pcm_hw_params_t *params, int *dir); +unsigned int snd_pcm_hw_params_get_periods_min(const snd_pcm_hw_params_t *params, int *dir); +unsigned int snd_pcm_hw_params_get_periods_max(const snd_pcm_hw_params_t *params, int *dir); +int snd_pcm_hw_params_test_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); +int snd_pcm_hw_params_set_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); +int snd_pcm_hw_params_set_periods_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_periods_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_periods_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir); +unsigned int snd_pcm_hw_params_set_periods_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir); +unsigned int snd_pcm_hw_params_set_periods_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); +unsigned int snd_pcm_hw_params_set_periods_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); +int snd_pcm_hw_params_set_periods_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); + +asm(".symver snd_pcm_hw_params_get_buffer_time,snd_pcm_hw_params_get_buffer_time@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_get_buffer_time_min,snd_pcm_hw_params_get_buffer_time_min@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_get_buffer_time_max,snd_pcm_hw_params_get_buffer_time_max@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_buffer_time_near,snd_pcm_hw_params_set_buffer_time_near@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_buffer_time_first,snd_pcm_hw_params_set_buffer_time_first@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_buffer_time_last,snd_pcm_hw_params_set_buffer_time_last@ALSA_0.9"); + +int snd_pcm_hw_params_get_buffer_time(const snd_pcm_hw_params_t *params, int *dir); +unsigned int snd_pcm_hw_params_get_buffer_time_min(const snd_pcm_hw_params_t *params, int *dir); +unsigned int snd_pcm_hw_params_get_buffer_time_max(const snd_pcm_hw_params_t *params, int *dir); +int snd_pcm_hw_params_test_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); +int snd_pcm_hw_params_set_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); +int snd_pcm_hw_params_set_buffer_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_buffer_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_buffer_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir); +unsigned int snd_pcm_hw_params_set_buffer_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir); +unsigned int snd_pcm_hw_params_set_buffer_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); +unsigned int snd_pcm_hw_params_set_buffer_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); + +asm(".symver snd_pcm_hw_params_get_buffer_size,snd_pcm_hw_params_get_buffer_size@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_get_buffer_size_min,snd_pcm_hw_params_get_buffer_size_min@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_get_buffer_size_max,snd_pcm_hw_params_get_buffer_size_max@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_buffer_size_near,snd_pcm_hw_params_set_buffer_size_near@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_buffer_size_first,snd_pcm_hw_params_set_buffer_size_first@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_buffer_size_last,snd_pcm_hw_params_set_buffer_size_last@ALSA_0.9"); + +snd_pcm_sframes_t snd_pcm_hw_params_get_buffer_size(const snd_pcm_hw_params_t *params); +snd_pcm_uframes_t snd_pcm_hw_params_get_buffer_size_min(const snd_pcm_hw_params_t *params); +snd_pcm_uframes_t snd_pcm_hw_params_get_buffer_size_max(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_test_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val); +int snd_pcm_hw_params_set_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val); +int snd_pcm_hw_params_set_buffer_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); +int snd_pcm_hw_params_set_buffer_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); +int snd_pcm_hw_params_set_buffer_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, snd_pcm_uframes_t *max); +snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val); +snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); +snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); + +asm(".symver snd_pcm_hw_params_get_tick_time,snd_pcm_hw_params_get_tick_time@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_get_tick_time_min,snd_pcm_hw_params_get_tick_time_min@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_get_tick_time_max,snd_pcm_hw_params_get_tick_time_max@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_tick_time_near,snd_pcm_hw_params_set_tick_time_near@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_tick_time_first,snd_pcm_hw_params_set_tick_time_first@ALSA_0.9"); +asm(".symver snd_pcm_hw_params_set_tick_time_last,snd_pcm_hw_params_set_tick_time_last@ALSA_0.9"); + +int snd_pcm_hw_params_get_tick_time(const snd_pcm_hw_params_t *params, int *dir); +unsigned int snd_pcm_hw_params_get_tick_time_min(const snd_pcm_hw_params_t *params, int *dir); +unsigned int snd_pcm_hw_params_get_tick_time_max(const snd_pcm_hw_params_t *params, int *dir); +int snd_pcm_hw_params_test_tick_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); +int snd_pcm_hw_params_set_tick_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); +int snd_pcm_hw_params_set_tick_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_tick_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +int snd_pcm_hw_params_set_tick_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir); +unsigned int snd_pcm_hw_params_set_tick_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir); +unsigned int snd_pcm_hw_params_set_tick_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); +unsigned int snd_pcm_hw_params_set_tick_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); + +#endif /* ALSA_PCM_OLD_HW_PARAMS_API */ + + +#ifdef ALSA_PCM_OLD_SW_PARAMS_API + +asm(".symver snd_pcm_sw_params_get_tstamp_mode,snd_pcm_sw_params_get_tstamp_mode@ALSA_0.9"); +asm(".symver snd_pcm_sw_params_get_sleep_min,snd_pcm_sw_params_get_sleep_min@ALSA_0.9"); +asm(".symver snd_pcm_sw_params_get_avail_min,snd_pcm_sw_params_get_avail_min@ALSA_0.9"); +asm(".symver snd_pcm_sw_params_get_xfer_align,snd_pcm_sw_params_get_xfer_align@ALSA_0.9"); +asm(".symver snd_pcm_sw_params_get_start_threshold,snd_pcm_sw_params_get_start_threshold@ALSA_0.9"); +asm(".symver snd_pcm_sw_params_get_stop_threshold,snd_pcm_sw_params_get_stop_threshold@ALSA_0.9"); +asm(".symver snd_pcm_sw_params_get_silence_threshold,snd_pcm_sw_params_get_silence_threshold@ALSA_0.9"); +asm(".symver snd_pcm_sw_params_get_silence_size,snd_pcm_sw_params_get_silence_size@ALSA_0.9"); + +int snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_t val); +snd_pcm_tstamp_t snd_pcm_sw_params_get_tstamp_mode(const snd_pcm_sw_params_t *params); +int snd_pcm_sw_params_set_sleep_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, unsigned int val); +unsigned int snd_pcm_sw_params_get_sleep_min(const snd_pcm_sw_params_t *params); +int snd_pcm_sw_params_set_avail_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); +snd_pcm_uframes_t snd_pcm_sw_params_get_avail_min(const snd_pcm_sw_params_t *params); +int snd_pcm_sw_params_set_xfer_align(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); +snd_pcm_uframes_t snd_pcm_sw_params_get_xfer_align(const snd_pcm_sw_params_t *params); +int snd_pcm_sw_params_set_start_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); +snd_pcm_uframes_t snd_pcm_sw_params_get_start_threshold(const snd_pcm_sw_params_t *params); +int snd_pcm_sw_params_set_stop_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); +snd_pcm_uframes_t snd_pcm_sw_params_get_stop_threshold(const snd_pcm_sw_params_t *params); +int snd_pcm_sw_params_set_silence_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); +snd_pcm_uframes_t snd_pcm_sw_params_get_silence_threshold(const snd_pcm_sw_params_t *params); +int snd_pcm_sw_params_set_silence_size(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); +snd_pcm_uframes_t snd_pcm_sw_params_get_silence_size(const snd_pcm_sw_params_t *params); + +#endif /* ALSA_PCM_OLD_SW_PARAMS_API */ diff --git a/thirdparty/linuxbsd_headers/alsa/pcm_plugin.h b/thirdparty/linuxbsd_headers/alsa/pcm_plugin.h new file mode 100644 index 0000000000..eea1d82d87 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/pcm_plugin.h @@ -0,0 +1,202 @@ +/** + * \file include/pcm_plugin.h + * \brief Common PCM plugin code + * \author Abramo Bagnara <abramo@alsa-project.org> + * \author Jaroslav Kysela <perex@perex.cz> + * \date 2000-2001 + * + * Application interface library for the ALSA driver. + * See the \ref pcm_plugins page for more details. + * + * \warning Using of contents of this header file might be dangerous + * in the sense of compatibility reasons. The contents might be + * freely changed in future. + */ +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_PCM_PLUGIN_H + +/** + * \defgroup PCM_Plugins PCM Plugins + * \ingroup PCM + * See the \ref pcm_plugins page for more details. + * \{ + */ + +#define SND_PCM_PLUGIN_RATE_MIN 4000 /**< minimal rate for the rate plugin */ +#define SND_PCM_PLUGIN_RATE_MAX 192000 /**< maximal rate for the rate plugin */ + +/* ROUTE_FLOAT should be set to 0 for machines without FP unit - like iPAQ */ +#ifdef HAVE_SOFT_FLOAT +#define SND_PCM_PLUGIN_ROUTE_FLOAT 0 /**< use integers for route plugin */ +#else +#define SND_PCM_PLUGIN_ROUTE_FLOAT 1 /**< use floats for route plugin */ +#endif + +#define SND_PCM_PLUGIN_ROUTE_RESOLUTION 16 /**< integer resolution for route plugin */ + +#if SND_PCM_PLUGIN_ROUTE_FLOAT +/** route ttable entry type */ +typedef float snd_pcm_route_ttable_entry_t; +#define SND_PCM_PLUGIN_ROUTE_HALF 0.5 /**< half value */ +#define SND_PCM_PLUGIN_ROUTE_FULL 1.0 /**< full value */ +#else +/** route ttable entry type */ +typedef int snd_pcm_route_ttable_entry_t; +#define SND_PCM_PLUGIN_ROUTE_HALF (SND_PCM_PLUGIN_ROUTE_RESOLUTION / 2) /**< half value */ +#define SND_PCM_PLUGIN_ROUTE_FULL SND_PCM_PLUGIN_ROUTE_RESOLUTION /**< full value */ +#endif + +/* + * Hardware plugin + */ +int snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name, + int card, int device, int subdevice, + snd_pcm_stream_t stream, int mode, + int mmap_emulation, int sync_ptr_ioctl); +int _snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name, + snd_config_t *root ATTRIBUTE_UNUSED, snd_config_t *conf, + snd_pcm_stream_t stream, int mode); + +/* + * Copy plugin + */ +int snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name, + snd_pcm_t *slave, int close_slave); +int _snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name, + snd_config_t *root, snd_config_t *conf, + snd_pcm_stream_t stream, int mode); + +/* + * Linear conversion plugin + */ +int snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name, + snd_pcm_format_t sformat, snd_pcm_t *slave, + int close_slave); +int _snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name, + snd_config_t *root, snd_config_t *conf, + snd_pcm_stream_t stream, int mode); + +/* + * Linear<->Float conversion plugin + */ +int snd_pcm_lfloat_open(snd_pcm_t **pcmp, const char *name, + snd_pcm_format_t sformat, snd_pcm_t *slave, + int close_slave); +int _snd_pcm_lfloat_open(snd_pcm_t **pcmp, const char *name, + snd_config_t *root, snd_config_t *conf, + snd_pcm_stream_t stream, int mode); + +/* + * Linear<->mu-Law conversion plugin + */ +int snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name, + snd_pcm_format_t sformat, snd_pcm_t *slave, + int close_slave); +int _snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name, + snd_config_t *root, snd_config_t *conf, + snd_pcm_stream_t stream, int mode); + +/* + * Linear<->a-Law conversion plugin + */ +int snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name, + snd_pcm_format_t sformat, snd_pcm_t *slave, + int close_slave); +int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name, + snd_config_t *root, snd_config_t *conf, + snd_pcm_stream_t stream, int mode); + +/* + * Linear<->Ima-ADPCM conversion plugin + */ +int snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name, + snd_pcm_format_t sformat, snd_pcm_t *slave, + int close_slave); +int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name, + snd_config_t *root, snd_config_t *conf, + snd_pcm_stream_t stream, int mode); + +/* + * Route plugin for linear formats + */ +int snd_pcm_route_load_ttable(snd_config_t *tt, snd_pcm_route_ttable_entry_t *ttable, + unsigned int tt_csize, unsigned int tt_ssize, + unsigned int *tt_cused, unsigned int *tt_sused, + int schannels); +int snd_pcm_route_determine_ttable(snd_config_t *tt, + unsigned int *tt_csize, + unsigned int *tt_ssize); +int snd_pcm_route_open(snd_pcm_t **pcmp, const char *name, + snd_pcm_format_t sformat, int schannels, + snd_pcm_route_ttable_entry_t *ttable, + unsigned int tt_ssize, + unsigned int tt_cused, unsigned int tt_sused, + snd_pcm_t *slave, int close_slave); +int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name, + snd_config_t *root, snd_config_t *conf, + snd_pcm_stream_t stream, int mode); + +/* + * Rate plugin for linear formats + */ +int snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name, + snd_pcm_format_t sformat, unsigned int srate, + const snd_config_t *converter, + snd_pcm_t *slave, int close_slave); +int _snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name, + snd_config_t *root, snd_config_t *conf, + snd_pcm_stream_t stream, int mode); + +/* + * Hooks plugin + */ +int snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name, + snd_pcm_t *slave, int close_slave); +int _snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name, + snd_config_t *root, snd_config_t *conf, + snd_pcm_stream_t stream, int mode); + +/* + * LADSPA plugin + */ +int snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name, + const char *ladspa_path, + unsigned int channels, + snd_config_t *ladspa_pplugins, + snd_config_t *ladspa_cplugins, + snd_pcm_t *slave, int close_slave); +int _snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name, + snd_config_t *root, snd_config_t *conf, + snd_pcm_stream_t stream, int mode); + +/* + * Jack plugin + */ +int snd_pcm_jack_open(snd_pcm_t **pcmp, const char *name, + snd_config_t *playback_conf, + snd_config_t *capture_conf, + snd_pcm_stream_t stream, int mode); +int _snd_pcm_jack_open(snd_pcm_t **pcmp, const char *name, + snd_config_t *root, snd_config_t *conf, + snd_pcm_stream_t stream, int mode); + + +/** \} */ + +#endif /* __ALSA_PCM_PLUGIN_H */ diff --git a/thirdparty/linuxbsd_headers/alsa/pcm_rate.h b/thirdparty/linuxbsd_headers/alsa/pcm_rate.h new file mode 100644 index 0000000000..4d70df2693 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/pcm_rate.h @@ -0,0 +1,153 @@ +/** + * \file include/pcm_rate.h + * \brief External Rate-Converter-Plugin SDK + * \author Takashi Iwai <tiwai@suse.de> + * \date 2006 + * + * External Rate-Converter-Plugin SDK + */ + +/* + * ALSA external PCM rate-converter plugin SDK (draft version) + * + * Copyright (c) 2006 Takashi Iwai <tiwai@suse.de> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_PCM_RATE_H +#define __ALSA_PCM_RATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Protocol version + */ +#define SND_PCM_RATE_PLUGIN_VERSION 0x010002 + +/** hw_params information for a single side */ +typedef struct snd_pcm_rate_side_info { + snd_pcm_format_t format; + unsigned int rate; + snd_pcm_uframes_t buffer_size; + snd_pcm_uframes_t period_size; +} snd_pcm_rate_side_info_t; + +/** hw_params information */ +typedef struct snd_pcm_rate_info { + struct snd_pcm_rate_side_info in; + struct snd_pcm_rate_side_info out; + unsigned int channels; +} snd_pcm_rate_info_t; + +/** Callback table of rate-converter */ +typedef struct snd_pcm_rate_ops { + /** + * close the converter; optional + */ + void (*close)(void *obj); + /** + * initialize the converter, called at hw_params + */ + int (*init)(void *obj, snd_pcm_rate_info_t *info); + /** + * free the converter; optional + */ + void (*free)(void *obj); + /** + * reset the converter, called at prepare; optional + */ + void (*reset)(void *obj); + /** + * adjust the pitch, called at sw_params; optional + */ + int (*adjust_pitch)(void *obj, snd_pcm_rate_info_t *info); + /** + * convert the data + */ + void (*convert)(void *obj, + const snd_pcm_channel_area_t *dst_areas, + snd_pcm_uframes_t dst_offset, unsigned int dst_frames, + const snd_pcm_channel_area_t *src_areas, + snd_pcm_uframes_t src_offset, unsigned int src_frames); + /** + * convert an s16 interleaved-data array; exclusive with convert + */ + void (*convert_s16)(void *obj, int16_t *dst, unsigned int dst_frames, + const int16_t *src, unsigned int src_frames); + /** + * compute the frame size for input + */ + snd_pcm_uframes_t (*input_frames)(void *obj, snd_pcm_uframes_t frames); + /** + * compute the frame size for output + */ + snd_pcm_uframes_t (*output_frames)(void *obj, snd_pcm_uframes_t frames); + /** + * the protocol version the plugin supports; + * new field since version 0x010002 + */ + unsigned int version; + /** + * return the supported min / max sample rates; + * new ops since version 0x010002 + */ + int (*get_supported_rates)(void *obj, unsigned int *rate_min, + unsigned int *rate_max); + /** + * show some status messages for verbose mode; + * new ops since version 0x010002 + */ + void (*dump)(void *obj, snd_output_t *out); +} snd_pcm_rate_ops_t; + +/** open function type */ +typedef int (*snd_pcm_rate_open_func_t)(unsigned int version, void **objp, + snd_pcm_rate_ops_t *opsp); + +/** + * Define the object entry for external PCM rate-converter plugins + */ +#define SND_PCM_RATE_PLUGIN_ENTRY(name) _snd_pcm_rate_##name##_open + + +#ifndef DOC_HIDDEN +/* old rate_ops for protocol version 0x010001 */ +typedef struct snd_pcm_rate_old_ops { + void (*close)(void *obj); + int (*init)(void *obj, snd_pcm_rate_info_t *info); + void (*free)(void *obj); + void (*reset)(void *obj); + int (*adjust_pitch)(void *obj, snd_pcm_rate_info_t *info); + void (*convert)(void *obj, + const snd_pcm_channel_area_t *dst_areas, + snd_pcm_uframes_t dst_offset, unsigned int dst_frames, + const snd_pcm_channel_area_t *src_areas, + snd_pcm_uframes_t src_offset, unsigned int src_frames); + void (*convert_s16)(void *obj, int16_t *dst, unsigned int dst_frames, + const int16_t *src, unsigned int src_frames); + snd_pcm_uframes_t (*input_frames)(void *obj, snd_pcm_uframes_t frames); + snd_pcm_uframes_t (*output_frames)(void *obj, snd_pcm_uframes_t frames); +} snd_pcm_rate_old_ops_t; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __ALSA_PCM_RATE_H */ diff --git a/thirdparty/linuxbsd_headers/alsa/rawmidi.h b/thirdparty/linuxbsd_headers/alsa/rawmidi.h new file mode 100644 index 0000000000..1d8fd56276 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/rawmidi.h @@ -0,0 +1,159 @@ +/** + * \file include/rawmidi.h + * \brief Application interface library for the ALSA driver + * \author Jaroslav Kysela <perex@perex.cz> + * \author Abramo Bagnara <abramo@alsa-project.org> + * \author Takashi Iwai <tiwai@suse.de> + * \date 1998-2001 + * + * Application interface library for the ALSA driver + */ +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_RAWMIDI_H +#define __ALSA_RAWMIDI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup RawMidi RawMidi Interface + * The RawMidi Interface. See \ref rawmidi page for more details. + * \{ + */ + +/** dlsym version for interface entry callback */ +#define SND_RAWMIDI_DLSYM_VERSION _dlsym_rawmidi_001 + +/** RawMidi information container */ +typedef struct _snd_rawmidi_info snd_rawmidi_info_t; +/** RawMidi settings container */ +typedef struct _snd_rawmidi_params snd_rawmidi_params_t; +/** RawMidi status container */ +typedef struct _snd_rawmidi_status snd_rawmidi_status_t; + +/** RawMidi stream (direction) */ +typedef enum _snd_rawmidi_stream { + /** Output stream */ + SND_RAWMIDI_STREAM_OUTPUT = 0, + /** Input stream */ + SND_RAWMIDI_STREAM_INPUT, + SND_RAWMIDI_STREAM_LAST = SND_RAWMIDI_STREAM_INPUT +} snd_rawmidi_stream_t; + +/** Append (flag to open mode) \hideinitializer */ +#define SND_RAWMIDI_APPEND 0x0001 +/** Non blocking mode (flag to open mode) \hideinitializer */ +#define SND_RAWMIDI_NONBLOCK 0x0002 +/** Write sync mode (Flag to open mode) \hideinitializer */ +#define SND_RAWMIDI_SYNC 0x0004 + +/** RawMidi handle */ +typedef struct _snd_rawmidi snd_rawmidi_t; + +/** RawMidi type */ +typedef enum _snd_rawmidi_type { + /** Kernel level RawMidi */ + SND_RAWMIDI_TYPE_HW, + /** Shared memory client RawMidi (not yet implemented) */ + SND_RAWMIDI_TYPE_SHM, + /** INET client RawMidi (not yet implemented) */ + SND_RAWMIDI_TYPE_INET, + /** Virtual (sequencer) RawMidi */ + SND_RAWMIDI_TYPE_VIRTUAL +} snd_rawmidi_type_t; + +int snd_rawmidi_open(snd_rawmidi_t **in_rmidi, snd_rawmidi_t **out_rmidi, + const char *name, int mode); +int snd_rawmidi_open_lconf(snd_rawmidi_t **in_rmidi, snd_rawmidi_t **out_rmidi, + const char *name, int mode, snd_config_t *lconf); +int snd_rawmidi_close(snd_rawmidi_t *rmidi); +int snd_rawmidi_poll_descriptors_count(snd_rawmidi_t *rmidi); +int snd_rawmidi_poll_descriptors(snd_rawmidi_t *rmidi, struct pollfd *pfds, unsigned int space); +int snd_rawmidi_poll_descriptors_revents(snd_rawmidi_t *rawmidi, struct pollfd *pfds, unsigned int nfds, unsigned short *revent); +int snd_rawmidi_nonblock(snd_rawmidi_t *rmidi, int nonblock); +size_t snd_rawmidi_info_sizeof(void); +/** \hideinitializer + * \brief allocate an invalid #snd_rawmidi_info_t using standard alloca + * \param ptr returned pointer + */ +#define snd_rawmidi_info_alloca(ptr) __snd_alloca(ptr, snd_rawmidi_info) +int snd_rawmidi_info_malloc(snd_rawmidi_info_t **ptr); +void snd_rawmidi_info_free(snd_rawmidi_info_t *obj); +void snd_rawmidi_info_copy(snd_rawmidi_info_t *dst, const snd_rawmidi_info_t *src); +unsigned int snd_rawmidi_info_get_device(const snd_rawmidi_info_t *obj); +unsigned int snd_rawmidi_info_get_subdevice(const snd_rawmidi_info_t *obj); +snd_rawmidi_stream_t snd_rawmidi_info_get_stream(const snd_rawmidi_info_t *obj); +int snd_rawmidi_info_get_card(const snd_rawmidi_info_t *obj); +unsigned int snd_rawmidi_info_get_flags(const snd_rawmidi_info_t *obj); +const char *snd_rawmidi_info_get_id(const snd_rawmidi_info_t *obj); +const char *snd_rawmidi_info_get_name(const snd_rawmidi_info_t *obj); +const char *snd_rawmidi_info_get_subdevice_name(const snd_rawmidi_info_t *obj); +unsigned int snd_rawmidi_info_get_subdevices_count(const snd_rawmidi_info_t *obj); +unsigned int snd_rawmidi_info_get_subdevices_avail(const snd_rawmidi_info_t *obj); +void snd_rawmidi_info_set_device(snd_rawmidi_info_t *obj, unsigned int val); +void snd_rawmidi_info_set_subdevice(snd_rawmidi_info_t *obj, unsigned int val); +void snd_rawmidi_info_set_stream(snd_rawmidi_info_t *obj, snd_rawmidi_stream_t val); +int snd_rawmidi_info(snd_rawmidi_t *rmidi, snd_rawmidi_info_t * info); +size_t snd_rawmidi_params_sizeof(void); +/** \hideinitializer + * \brief allocate an invalid #snd_rawmidi_params_t using standard alloca + * \param ptr returned pointer + */ +#define snd_rawmidi_params_alloca(ptr) __snd_alloca(ptr, snd_rawmidi_params) +int snd_rawmidi_params_malloc(snd_rawmidi_params_t **ptr); +void snd_rawmidi_params_free(snd_rawmidi_params_t *obj); +void snd_rawmidi_params_copy(snd_rawmidi_params_t *dst, const snd_rawmidi_params_t *src); +int snd_rawmidi_params_set_buffer_size(snd_rawmidi_t *rmidi, snd_rawmidi_params_t *params, size_t val); +size_t snd_rawmidi_params_get_buffer_size(const snd_rawmidi_params_t *params); +int snd_rawmidi_params_set_avail_min(snd_rawmidi_t *rmidi, snd_rawmidi_params_t *params, size_t val); +size_t snd_rawmidi_params_get_avail_min(const snd_rawmidi_params_t *params); +int snd_rawmidi_params_set_no_active_sensing(snd_rawmidi_t *rmidi, snd_rawmidi_params_t *params, int val); +int snd_rawmidi_params_get_no_active_sensing(const snd_rawmidi_params_t *params); +int snd_rawmidi_params(snd_rawmidi_t *rmidi, snd_rawmidi_params_t * params); +int snd_rawmidi_params_current(snd_rawmidi_t *rmidi, snd_rawmidi_params_t *params); +size_t snd_rawmidi_status_sizeof(void); +/** \hideinitializer + * \brief allocate an invalid #snd_rawmidi_status_t using standard alloca + * \param ptr returned pointer + */ +#define snd_rawmidi_status_alloca(ptr) __snd_alloca(ptr, snd_rawmidi_status) +int snd_rawmidi_status_malloc(snd_rawmidi_status_t **ptr); +void snd_rawmidi_status_free(snd_rawmidi_status_t *obj); +void snd_rawmidi_status_copy(snd_rawmidi_status_t *dst, const snd_rawmidi_status_t *src); +void snd_rawmidi_status_get_tstamp(const snd_rawmidi_status_t *obj, snd_htimestamp_t *ptr); +size_t snd_rawmidi_status_get_avail(const snd_rawmidi_status_t *obj); +size_t snd_rawmidi_status_get_xruns(const snd_rawmidi_status_t *obj); +int snd_rawmidi_status(snd_rawmidi_t *rmidi, snd_rawmidi_status_t * status); +int snd_rawmidi_drain(snd_rawmidi_t *rmidi); +int snd_rawmidi_drop(snd_rawmidi_t *rmidi); +ssize_t snd_rawmidi_write(snd_rawmidi_t *rmidi, const void *buffer, size_t size); +ssize_t snd_rawmidi_read(snd_rawmidi_t *rmidi, void *buffer, size_t size); +const char *snd_rawmidi_name(snd_rawmidi_t *rmidi); +snd_rawmidi_type_t snd_rawmidi_type(snd_rawmidi_t *rmidi); +snd_rawmidi_stream_t snd_rawmidi_stream(snd_rawmidi_t *rawmidi); + +/** \} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __RAWMIDI_H */ + diff --git a/thirdparty/linuxbsd_headers/alsa/seq.h b/thirdparty/linuxbsd_headers/alsa/seq.h new file mode 100644 index 0000000000..d05940e859 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/seq.h @@ -0,0 +1,739 @@ +/** + * \file include/seq.h + * \brief Application interface library for the ALSA driver + * \author Jaroslav Kysela <perex@perex.cz> + * \author Abramo Bagnara <abramo@alsa-project.org> + * \author Takashi Iwai <tiwai@suse.de> + * \date 1998-2001 + */ +/* + * Application interface library for the ALSA driver + * + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_SEQ_H +#define __ALSA_SEQ_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup Sequencer MIDI Sequencer + * MIDI Sequencer Interface. + * See \ref seq page for more details. + * \{ + */ + +/** dlsym version for interface entry callback */ +#define SND_SEQ_DLSYM_VERSION _dlsym_seq_001 + +/** Sequencer handle */ +typedef struct _snd_seq snd_seq_t; + +/** + * sequencer opening stream types + */ +#define SND_SEQ_OPEN_OUTPUT 1 /**< open for output (write) */ +#define SND_SEQ_OPEN_INPUT 2 /**< open for input (read) */ +#define SND_SEQ_OPEN_DUPLEX (SND_SEQ_OPEN_OUTPUT|SND_SEQ_OPEN_INPUT) /**< open for both input and output (read/write) */ + +/** + * sequencer opening mode + */ +#define SND_SEQ_NONBLOCK 0x0001 /**< non-blocking mode (flag to open mode) */ + +/** sequencer handle type */ +typedef enum _snd_seq_type { + SND_SEQ_TYPE_HW, /**< hardware */ + SND_SEQ_TYPE_SHM, /**< shared memory (NYI) */ + SND_SEQ_TYPE_INET /**< network (NYI) */ +} snd_seq_type_t; + +/** special client (port) ids */ +#define SND_SEQ_ADDRESS_UNKNOWN 253 /**< unknown source */ +#define SND_SEQ_ADDRESS_SUBSCRIBERS 254 /**< send event to all subscribed ports */ +#define SND_SEQ_ADDRESS_BROADCAST 255 /**< send event to all queues/clients/ports/channels */ + +/** known client numbers */ +#define SND_SEQ_CLIENT_SYSTEM 0 /**< system client */ + +/* + */ +int snd_seq_open(snd_seq_t **handle, const char *name, int streams, int mode); +int snd_seq_open_lconf(snd_seq_t **handle, const char *name, int streams, int mode, snd_config_t *lconf); +const char *snd_seq_name(snd_seq_t *seq); +snd_seq_type_t snd_seq_type(snd_seq_t *seq); +int snd_seq_close(snd_seq_t *handle); +int snd_seq_poll_descriptors_count(snd_seq_t *handle, short events); +int snd_seq_poll_descriptors(snd_seq_t *handle, struct pollfd *pfds, unsigned int space, short events); +int snd_seq_poll_descriptors_revents(snd_seq_t *seq, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); +int snd_seq_nonblock(snd_seq_t *handle, int nonblock); +int snd_seq_client_id(snd_seq_t *handle); + +size_t snd_seq_get_output_buffer_size(snd_seq_t *handle); +size_t snd_seq_get_input_buffer_size(snd_seq_t *handle); +int snd_seq_set_output_buffer_size(snd_seq_t *handle, size_t size); +int snd_seq_set_input_buffer_size(snd_seq_t *handle, size_t size); + +/** system information container */ +typedef struct _snd_seq_system_info snd_seq_system_info_t; + +size_t snd_seq_system_info_sizeof(void); +/** allocate a #snd_seq_system_info_t container on stack */ +#define snd_seq_system_info_alloca(ptr) \ + __snd_alloca(ptr, snd_seq_system_info) +int snd_seq_system_info_malloc(snd_seq_system_info_t **ptr); +void snd_seq_system_info_free(snd_seq_system_info_t *ptr); +void snd_seq_system_info_copy(snd_seq_system_info_t *dst, const snd_seq_system_info_t *src); + +int snd_seq_system_info_get_queues(const snd_seq_system_info_t *info); +int snd_seq_system_info_get_clients(const snd_seq_system_info_t *info); +int snd_seq_system_info_get_ports(const snd_seq_system_info_t *info); +int snd_seq_system_info_get_channels(const snd_seq_system_info_t *info); +int snd_seq_system_info_get_cur_clients(const snd_seq_system_info_t *info); +int snd_seq_system_info_get_cur_queues(const snd_seq_system_info_t *info); + +int snd_seq_system_info(snd_seq_t *handle, snd_seq_system_info_t *info); + +/** \} */ + + +/** + * \defgroup SeqClient Sequencer Client Interface + * Sequencer Client Interface + * \ingroup Sequencer + * \{ + */ + +/** client information container */ +typedef struct _snd_seq_client_info snd_seq_client_info_t; + +/** client types */ +typedef enum snd_seq_client_type { + SND_SEQ_USER_CLIENT = 1, /**< user client */ + SND_SEQ_KERNEL_CLIENT = 2 /**< kernel client */ +} snd_seq_client_type_t; + +size_t snd_seq_client_info_sizeof(void); +/** allocate a #snd_seq_client_info_t container on stack */ +#define snd_seq_client_info_alloca(ptr) \ + __snd_alloca(ptr, snd_seq_client_info) +int snd_seq_client_info_malloc(snd_seq_client_info_t **ptr); +void snd_seq_client_info_free(snd_seq_client_info_t *ptr); +void snd_seq_client_info_copy(snd_seq_client_info_t *dst, const snd_seq_client_info_t *src); + +int snd_seq_client_info_get_client(const snd_seq_client_info_t *info); +snd_seq_client_type_t snd_seq_client_info_get_type(const snd_seq_client_info_t *info); +const char *snd_seq_client_info_get_name(snd_seq_client_info_t *info); +int snd_seq_client_info_get_broadcast_filter(const snd_seq_client_info_t *info); +int snd_seq_client_info_get_error_bounce(const snd_seq_client_info_t *info); +int snd_seq_client_info_get_card(const snd_seq_client_info_t *info); +int snd_seq_client_info_get_pid(const snd_seq_client_info_t *info); +const unsigned char *snd_seq_client_info_get_event_filter(const snd_seq_client_info_t *info); +int snd_seq_client_info_get_num_ports(const snd_seq_client_info_t *info); +int snd_seq_client_info_get_event_lost(const snd_seq_client_info_t *info); + +void snd_seq_client_info_set_client(snd_seq_client_info_t *info, int client); +void snd_seq_client_info_set_name(snd_seq_client_info_t *info, const char *name); +void snd_seq_client_info_set_broadcast_filter(snd_seq_client_info_t *info, int val); +void snd_seq_client_info_set_error_bounce(snd_seq_client_info_t *info, int val); +void snd_seq_client_info_set_event_filter(snd_seq_client_info_t *info, unsigned char *filter); + +void snd_seq_client_info_event_filter_clear(snd_seq_client_info_t *info); +void snd_seq_client_info_event_filter_add(snd_seq_client_info_t *info, int event_type); +void snd_seq_client_info_event_filter_del(snd_seq_client_info_t *info, int event_type); +int snd_seq_client_info_event_filter_check(snd_seq_client_info_t *info, int event_type); + +int snd_seq_get_client_info(snd_seq_t *handle, snd_seq_client_info_t *info); +int snd_seq_get_any_client_info(snd_seq_t *handle, int client, snd_seq_client_info_t *info); +int snd_seq_set_client_info(snd_seq_t *handle, snd_seq_client_info_t *info); +int snd_seq_query_next_client(snd_seq_t *handle, snd_seq_client_info_t *info); + +/* + */ + +/** client pool information container */ +typedef struct _snd_seq_client_pool snd_seq_client_pool_t; + +size_t snd_seq_client_pool_sizeof(void); +/** allocate a #snd_seq_client_pool_t container on stack */ +#define snd_seq_client_pool_alloca(ptr) \ + __snd_alloca(ptr, snd_seq_client_pool) +int snd_seq_client_pool_malloc(snd_seq_client_pool_t **ptr); +void snd_seq_client_pool_free(snd_seq_client_pool_t *ptr); +void snd_seq_client_pool_copy(snd_seq_client_pool_t *dst, const snd_seq_client_pool_t *src); + +int snd_seq_client_pool_get_client(const snd_seq_client_pool_t *info); +size_t snd_seq_client_pool_get_output_pool(const snd_seq_client_pool_t *info); +size_t snd_seq_client_pool_get_input_pool(const snd_seq_client_pool_t *info); +size_t snd_seq_client_pool_get_output_room(const snd_seq_client_pool_t *info); +size_t snd_seq_client_pool_get_output_free(const snd_seq_client_pool_t *info); +size_t snd_seq_client_pool_get_input_free(const snd_seq_client_pool_t *info); +void snd_seq_client_pool_set_output_pool(snd_seq_client_pool_t *info, size_t size); +void snd_seq_client_pool_set_input_pool(snd_seq_client_pool_t *info, size_t size); +void snd_seq_client_pool_set_output_room(snd_seq_client_pool_t *info, size_t size); + +int snd_seq_get_client_pool(snd_seq_t *handle, snd_seq_client_pool_t *info); +int snd_seq_set_client_pool(snd_seq_t *handle, snd_seq_client_pool_t *info); + + +/** \} */ + + +/** + * \defgroup SeqPort Sequencer Port Interface + * Sequencer Port Interface + * \ingroup Sequencer + * \{ + */ + +/** port information container */ +typedef struct _snd_seq_port_info snd_seq_port_info_t; + +/** known port numbers */ +#define SND_SEQ_PORT_SYSTEM_TIMER 0 /**< system timer port */ +#define SND_SEQ_PORT_SYSTEM_ANNOUNCE 1 /**< system announce port */ + +/** port capabilities (32 bits) */ +#define SND_SEQ_PORT_CAP_READ (1<<0) /**< readable from this port */ +#define SND_SEQ_PORT_CAP_WRITE (1<<1) /**< writable to this port */ + +#define SND_SEQ_PORT_CAP_SYNC_READ (1<<2) /**< allow read subscriptions */ +#define SND_SEQ_PORT_CAP_SYNC_WRITE (1<<3) /**< allow write subscriptions */ + +#define SND_SEQ_PORT_CAP_DUPLEX (1<<4) /**< allow read/write duplex */ + +#define SND_SEQ_PORT_CAP_SUBS_READ (1<<5) /**< allow read subscription */ +#define SND_SEQ_PORT_CAP_SUBS_WRITE (1<<6) /**< allow write subscription */ +#define SND_SEQ_PORT_CAP_NO_EXPORT (1<<7) /**< routing not allowed */ + +/* port type */ +/** Messages sent from/to this port have device-specific semantics. */ +#define SND_SEQ_PORT_TYPE_SPECIFIC (1<<0) +/** This port understands MIDI messages. */ +#define SND_SEQ_PORT_TYPE_MIDI_GENERIC (1<<1) +/** This port is compatible with the General MIDI specification. */ +#define SND_SEQ_PORT_TYPE_MIDI_GM (1<<2) +/** This port is compatible with the Roland GS standard. */ +#define SND_SEQ_PORT_TYPE_MIDI_GS (1<<3) +/** This port is compatible with the Yamaha XG specification. */ +#define SND_SEQ_PORT_TYPE_MIDI_XG (1<<4) +/** This port is compatible with the Roland MT-32. */ +#define SND_SEQ_PORT_TYPE_MIDI_MT32 (1<<5) +/** This port is compatible with the General MIDI 2 specification. */ +#define SND_SEQ_PORT_TYPE_MIDI_GM2 (1<<6) +/** This port understands SND_SEQ_EVENT_SAMPLE_xxx messages + (these are not MIDI messages). */ +#define SND_SEQ_PORT_TYPE_SYNTH (1<<10) +/** Instruments can be downloaded to this port + (with SND_SEQ_EVENT_INSTR_xxx messages sent directly). */ +#define SND_SEQ_PORT_TYPE_DIRECT_SAMPLE (1<<11) +/** Instruments can be downloaded to this port + (with SND_SEQ_EVENT_INSTR_xxx messages sent directly or through a queue). */ +#define SND_SEQ_PORT_TYPE_SAMPLE (1<<12) +/** This port is implemented in hardware. */ +#define SND_SEQ_PORT_TYPE_HARDWARE (1<<16) +/** This port is implemented in software. */ +#define SND_SEQ_PORT_TYPE_SOFTWARE (1<<17) +/** Messages sent to this port will generate sounds. */ +#define SND_SEQ_PORT_TYPE_SYNTHESIZER (1<<18) +/** This port may connect to other devices + (whose characteristics are not known). */ +#define SND_SEQ_PORT_TYPE_PORT (1<<19) +/** This port belongs to an application, such as a sequencer or editor. */ +#define SND_SEQ_PORT_TYPE_APPLICATION (1<<20) + + +size_t snd_seq_port_info_sizeof(void); +/** allocate a #snd_seq_port_info_t container on stack */ +#define snd_seq_port_info_alloca(ptr) \ + __snd_alloca(ptr, snd_seq_port_info) +int snd_seq_port_info_malloc(snd_seq_port_info_t **ptr); +void snd_seq_port_info_free(snd_seq_port_info_t *ptr); +void snd_seq_port_info_copy(snd_seq_port_info_t *dst, const snd_seq_port_info_t *src); + +int snd_seq_port_info_get_client(const snd_seq_port_info_t *info); +int snd_seq_port_info_get_port(const snd_seq_port_info_t *info); +const snd_seq_addr_t *snd_seq_port_info_get_addr(const snd_seq_port_info_t *info); +const char *snd_seq_port_info_get_name(const snd_seq_port_info_t *info); +unsigned int snd_seq_port_info_get_capability(const snd_seq_port_info_t *info); +unsigned int snd_seq_port_info_get_type(const snd_seq_port_info_t *info); +int snd_seq_port_info_get_midi_channels(const snd_seq_port_info_t *info); +int snd_seq_port_info_get_midi_voices(const snd_seq_port_info_t *info); +int snd_seq_port_info_get_synth_voices(const snd_seq_port_info_t *info); +int snd_seq_port_info_get_read_use(const snd_seq_port_info_t *info); +int snd_seq_port_info_get_write_use(const snd_seq_port_info_t *info); +int snd_seq_port_info_get_port_specified(const snd_seq_port_info_t *info); +int snd_seq_port_info_get_timestamping(const snd_seq_port_info_t *info); +int snd_seq_port_info_get_timestamp_real(const snd_seq_port_info_t *info); +int snd_seq_port_info_get_timestamp_queue(const snd_seq_port_info_t *info); + +void snd_seq_port_info_set_client(snd_seq_port_info_t *info, int client); +void snd_seq_port_info_set_port(snd_seq_port_info_t *info, int port); +void snd_seq_port_info_set_addr(snd_seq_port_info_t *info, const snd_seq_addr_t *addr); +void snd_seq_port_info_set_name(snd_seq_port_info_t *info, const char *name); +void snd_seq_port_info_set_capability(snd_seq_port_info_t *info, unsigned int capability); +void snd_seq_port_info_set_type(snd_seq_port_info_t *info, unsigned int type); +void snd_seq_port_info_set_midi_channels(snd_seq_port_info_t *info, int channels); +void snd_seq_port_info_set_midi_voices(snd_seq_port_info_t *info, int voices); +void snd_seq_port_info_set_synth_voices(snd_seq_port_info_t *info, int voices); +void snd_seq_port_info_set_port_specified(snd_seq_port_info_t *info, int val); +void snd_seq_port_info_set_timestamping(snd_seq_port_info_t *info, int enable); +void snd_seq_port_info_set_timestamp_real(snd_seq_port_info_t *info, int realtime); +void snd_seq_port_info_set_timestamp_queue(snd_seq_port_info_t *info, int queue); + +int snd_seq_create_port(snd_seq_t *handle, snd_seq_port_info_t *info); +int snd_seq_delete_port(snd_seq_t *handle, int port); +int snd_seq_get_port_info(snd_seq_t *handle, int port, snd_seq_port_info_t *info); +int snd_seq_get_any_port_info(snd_seq_t *handle, int client, int port, snd_seq_port_info_t *info); +int snd_seq_set_port_info(snd_seq_t *handle, int port, snd_seq_port_info_t *info); +int snd_seq_query_next_port(snd_seq_t *handle, snd_seq_port_info_t *info); + +/** \} */ + + +/** + * \defgroup SeqSubscribe Sequencer Port Subscription + * Sequencer Port Subscription + * \ingroup Sequencer + * \{ + */ + +/** port subscription container */ +typedef struct _snd_seq_port_subscribe snd_seq_port_subscribe_t; + +size_t snd_seq_port_subscribe_sizeof(void); +/** allocate a #snd_seq_port_subscribe_t container on stack */ +#define snd_seq_port_subscribe_alloca(ptr) \ + __snd_alloca(ptr, snd_seq_port_subscribe) +int snd_seq_port_subscribe_malloc(snd_seq_port_subscribe_t **ptr); +void snd_seq_port_subscribe_free(snd_seq_port_subscribe_t *ptr); +void snd_seq_port_subscribe_copy(snd_seq_port_subscribe_t *dst, const snd_seq_port_subscribe_t *src); + +const snd_seq_addr_t *snd_seq_port_subscribe_get_sender(const snd_seq_port_subscribe_t *info); +const snd_seq_addr_t *snd_seq_port_subscribe_get_dest(const snd_seq_port_subscribe_t *info); +int snd_seq_port_subscribe_get_queue(const snd_seq_port_subscribe_t *info); +int snd_seq_port_subscribe_get_exclusive(const snd_seq_port_subscribe_t *info); +int snd_seq_port_subscribe_get_time_update(const snd_seq_port_subscribe_t *info); +int snd_seq_port_subscribe_get_time_real(const snd_seq_port_subscribe_t *info); + +void snd_seq_port_subscribe_set_sender(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr); +void snd_seq_port_subscribe_set_dest(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr); +void snd_seq_port_subscribe_set_queue(snd_seq_port_subscribe_t *info, int q); +void snd_seq_port_subscribe_set_exclusive(snd_seq_port_subscribe_t *info, int val); +void snd_seq_port_subscribe_set_time_update(snd_seq_port_subscribe_t *info, int val); +void snd_seq_port_subscribe_set_time_real(snd_seq_port_subscribe_t *info, int val); + +int snd_seq_get_port_subscription(snd_seq_t *handle, snd_seq_port_subscribe_t *sub); +int snd_seq_subscribe_port(snd_seq_t *handle, snd_seq_port_subscribe_t *sub); +int snd_seq_unsubscribe_port(snd_seq_t *handle, snd_seq_port_subscribe_t *sub); + +/* + */ + +/** subscription query container */ +typedef struct _snd_seq_query_subscribe snd_seq_query_subscribe_t; + +/** type of query subscription */ +typedef enum { + SND_SEQ_QUERY_SUBS_READ, /**< query read subscriptions */ + SND_SEQ_QUERY_SUBS_WRITE /**< query write subscriptions */ +} snd_seq_query_subs_type_t; + +size_t snd_seq_query_subscribe_sizeof(void); +/** allocate a #snd_seq_query_subscribe_t container on stack */ +#define snd_seq_query_subscribe_alloca(ptr) \ + __snd_alloca(ptr, snd_seq_query_subscribe) +int snd_seq_query_subscribe_malloc(snd_seq_query_subscribe_t **ptr); +void snd_seq_query_subscribe_free(snd_seq_query_subscribe_t *ptr); +void snd_seq_query_subscribe_copy(snd_seq_query_subscribe_t *dst, const snd_seq_query_subscribe_t *src); + +int snd_seq_query_subscribe_get_client(const snd_seq_query_subscribe_t *info); +int snd_seq_query_subscribe_get_port(const snd_seq_query_subscribe_t *info); +const snd_seq_addr_t *snd_seq_query_subscribe_get_root(const snd_seq_query_subscribe_t *info); +snd_seq_query_subs_type_t snd_seq_query_subscribe_get_type(const snd_seq_query_subscribe_t *info); +int snd_seq_query_subscribe_get_index(const snd_seq_query_subscribe_t *info); +int snd_seq_query_subscribe_get_num_subs(const snd_seq_query_subscribe_t *info); +const snd_seq_addr_t *snd_seq_query_subscribe_get_addr(const snd_seq_query_subscribe_t *info); +int snd_seq_query_subscribe_get_queue(const snd_seq_query_subscribe_t *info); +int snd_seq_query_subscribe_get_exclusive(const snd_seq_query_subscribe_t *info); +int snd_seq_query_subscribe_get_time_update(const snd_seq_query_subscribe_t *info); +int snd_seq_query_subscribe_get_time_real(const snd_seq_query_subscribe_t *info); + +void snd_seq_query_subscribe_set_client(snd_seq_query_subscribe_t *info, int client); +void snd_seq_query_subscribe_set_port(snd_seq_query_subscribe_t *info, int port); +void snd_seq_query_subscribe_set_root(snd_seq_query_subscribe_t *info, const snd_seq_addr_t *addr); +void snd_seq_query_subscribe_set_type(snd_seq_query_subscribe_t *info, snd_seq_query_subs_type_t type); +void snd_seq_query_subscribe_set_index(snd_seq_query_subscribe_t *info, int _index); + +int snd_seq_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subscribe_t * subs); + +/** \} */ + + +/** + * \defgroup SeqQueue Sequencer Queue Interface + * Sequencer Queue Interface + * \ingroup Sequencer + * \{ + */ + +/** queue information container */ +typedef struct _snd_seq_queue_info snd_seq_queue_info_t; +/** queue status container */ +typedef struct _snd_seq_queue_status snd_seq_queue_status_t; +/** queue tempo container */ +typedef struct _snd_seq_queue_tempo snd_seq_queue_tempo_t; +/** queue timer information container */ +typedef struct _snd_seq_queue_timer snd_seq_queue_timer_t; + +/** special queue ids */ +#define SND_SEQ_QUEUE_DIRECT 253 /**< direct dispatch */ + +size_t snd_seq_queue_info_sizeof(void); +/** allocate a #snd_seq_queue_info_t container on stack */ +#define snd_seq_queue_info_alloca(ptr) \ + __snd_alloca(ptr, snd_seq_queue_info) +int snd_seq_queue_info_malloc(snd_seq_queue_info_t **ptr); +void snd_seq_queue_info_free(snd_seq_queue_info_t *ptr); +void snd_seq_queue_info_copy(snd_seq_queue_info_t *dst, const snd_seq_queue_info_t *src); + +int snd_seq_queue_info_get_queue(const snd_seq_queue_info_t *info); +const char *snd_seq_queue_info_get_name(const snd_seq_queue_info_t *info); +int snd_seq_queue_info_get_owner(const snd_seq_queue_info_t *info); +int snd_seq_queue_info_get_locked(const snd_seq_queue_info_t *info); +unsigned int snd_seq_queue_info_get_flags(const snd_seq_queue_info_t *info); + +void snd_seq_queue_info_set_name(snd_seq_queue_info_t *info, const char *name); +void snd_seq_queue_info_set_owner(snd_seq_queue_info_t *info, int owner); +void snd_seq_queue_info_set_locked(snd_seq_queue_info_t *info, int locked); +void snd_seq_queue_info_set_flags(snd_seq_queue_info_t *info, unsigned int flags); + +int snd_seq_create_queue(snd_seq_t *seq, snd_seq_queue_info_t *info); +int snd_seq_alloc_named_queue(snd_seq_t *seq, const char *name); +int snd_seq_alloc_queue(snd_seq_t *handle); +int snd_seq_free_queue(snd_seq_t *handle, int q); +int snd_seq_get_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info); +int snd_seq_set_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info); +int snd_seq_query_named_queue(snd_seq_t *seq, const char *name); + +int snd_seq_get_queue_usage(snd_seq_t *handle, int q); +int snd_seq_set_queue_usage(snd_seq_t *handle, int q, int used); + +/* + */ +size_t snd_seq_queue_status_sizeof(void); +/** allocate a #snd_seq_queue_status_t container on stack */ +#define snd_seq_queue_status_alloca(ptr) \ + __snd_alloca(ptr, snd_seq_queue_status) +int snd_seq_queue_status_malloc(snd_seq_queue_status_t **ptr); +void snd_seq_queue_status_free(snd_seq_queue_status_t *ptr); +void snd_seq_queue_status_copy(snd_seq_queue_status_t *dst, const snd_seq_queue_status_t *src); + +int snd_seq_queue_status_get_queue(const snd_seq_queue_status_t *info); +int snd_seq_queue_status_get_events(const snd_seq_queue_status_t *info); +snd_seq_tick_time_t snd_seq_queue_status_get_tick_time(const snd_seq_queue_status_t *info); +const snd_seq_real_time_t *snd_seq_queue_status_get_real_time(const snd_seq_queue_status_t *info); +unsigned int snd_seq_queue_status_get_status(const snd_seq_queue_status_t *info); + +int snd_seq_get_queue_status(snd_seq_t *handle, int q, snd_seq_queue_status_t *status); + +/* + */ +size_t snd_seq_queue_tempo_sizeof(void); +/** allocate a #snd_seq_queue_tempo_t container on stack */ +#define snd_seq_queue_tempo_alloca(ptr) \ + __snd_alloca(ptr, snd_seq_queue_tempo) +int snd_seq_queue_tempo_malloc(snd_seq_queue_tempo_t **ptr); +void snd_seq_queue_tempo_free(snd_seq_queue_tempo_t *ptr); +void snd_seq_queue_tempo_copy(snd_seq_queue_tempo_t *dst, const snd_seq_queue_tempo_t *src); + +int snd_seq_queue_tempo_get_queue(const snd_seq_queue_tempo_t *info); +unsigned int snd_seq_queue_tempo_get_tempo(const snd_seq_queue_tempo_t *info); +int snd_seq_queue_tempo_get_ppq(const snd_seq_queue_tempo_t *info); +unsigned int snd_seq_queue_tempo_get_skew(const snd_seq_queue_tempo_t *info); +unsigned int snd_seq_queue_tempo_get_skew_base(const snd_seq_queue_tempo_t *info); +void snd_seq_queue_tempo_set_tempo(snd_seq_queue_tempo_t *info, unsigned int tempo); +void snd_seq_queue_tempo_set_ppq(snd_seq_queue_tempo_t *info, int ppq); +void snd_seq_queue_tempo_set_skew(snd_seq_queue_tempo_t *info, unsigned int skew); +void snd_seq_queue_tempo_set_skew_base(snd_seq_queue_tempo_t *info, unsigned int base); + +int snd_seq_get_queue_tempo(snd_seq_t *handle, int q, snd_seq_queue_tempo_t *tempo); +int snd_seq_set_queue_tempo(snd_seq_t *handle, int q, snd_seq_queue_tempo_t *tempo); + +/* + */ + +/** sequencer timer sources */ +typedef enum { + SND_SEQ_TIMER_ALSA = 0, /* ALSA timer */ + SND_SEQ_TIMER_MIDI_CLOCK = 1, /* Midi Clock (CLOCK event) */ + SND_SEQ_TIMER_MIDI_TICK = 2 /* Midi Timer Tick (TICK event */ +} snd_seq_queue_timer_type_t; + +size_t snd_seq_queue_timer_sizeof(void); +/** allocate a #snd_seq_queue_timer_t container on stack */ +#define snd_seq_queue_timer_alloca(ptr) \ + __snd_alloca(ptr, snd_seq_queue_timer) +int snd_seq_queue_timer_malloc(snd_seq_queue_timer_t **ptr); +void snd_seq_queue_timer_free(snd_seq_queue_timer_t *ptr); +void snd_seq_queue_timer_copy(snd_seq_queue_timer_t *dst, const snd_seq_queue_timer_t *src); + +int snd_seq_queue_timer_get_queue(const snd_seq_queue_timer_t *info); +snd_seq_queue_timer_type_t snd_seq_queue_timer_get_type(const snd_seq_queue_timer_t *info); +const snd_timer_id_t *snd_seq_queue_timer_get_id(const snd_seq_queue_timer_t *info); +unsigned int snd_seq_queue_timer_get_resolution(const snd_seq_queue_timer_t *info); + +void snd_seq_queue_timer_set_type(snd_seq_queue_timer_t *info, snd_seq_queue_timer_type_t type); +void snd_seq_queue_timer_set_id(snd_seq_queue_timer_t *info, const snd_timer_id_t *id); +void snd_seq_queue_timer_set_resolution(snd_seq_queue_timer_t *info, unsigned int resolution); + +int snd_seq_get_queue_timer(snd_seq_t *handle, int q, snd_seq_queue_timer_t *timer); +int snd_seq_set_queue_timer(snd_seq_t *handle, int q, snd_seq_queue_timer_t *timer); + +/** \} */ + +/** + * \defgroup SeqEvent Sequencer Event API + * Sequencer Event API + * \ingroup Sequencer + * \{ + */ + +int snd_seq_free_event(snd_seq_event_t *ev); +ssize_t snd_seq_event_length(snd_seq_event_t *ev); +int snd_seq_event_output(snd_seq_t *handle, snd_seq_event_t *ev); +int snd_seq_event_output_buffer(snd_seq_t *handle, snd_seq_event_t *ev); +int snd_seq_event_output_direct(snd_seq_t *handle, snd_seq_event_t *ev); +int snd_seq_event_input(snd_seq_t *handle, snd_seq_event_t **ev); +int snd_seq_event_input_pending(snd_seq_t *seq, int fetch_sequencer); +int snd_seq_drain_output(snd_seq_t *handle); +int snd_seq_event_output_pending(snd_seq_t *seq); +int snd_seq_extract_output(snd_seq_t *handle, snd_seq_event_t **ev); +int snd_seq_drop_output(snd_seq_t *handle); +int snd_seq_drop_output_buffer(snd_seq_t *handle); +int snd_seq_drop_input(snd_seq_t *handle); +int snd_seq_drop_input_buffer(snd_seq_t *handle); + +/** event removal conditionals */ +typedef struct _snd_seq_remove_events snd_seq_remove_events_t; + +/** Remove conditional flags */ +#define SND_SEQ_REMOVE_INPUT (1<<0) /**< Flush input queues */ +#define SND_SEQ_REMOVE_OUTPUT (1<<1) /**< Flush output queues */ +#define SND_SEQ_REMOVE_DEST (1<<2) /**< Restrict by destination q:client:port */ +#define SND_SEQ_REMOVE_DEST_CHANNEL (1<<3) /**< Restrict by channel */ +#define SND_SEQ_REMOVE_TIME_BEFORE (1<<4) /**< Restrict to before time */ +#define SND_SEQ_REMOVE_TIME_AFTER (1<<5) /**< Restrict to time or after */ +#define SND_SEQ_REMOVE_TIME_TICK (1<<6) /**< Time is in ticks */ +#define SND_SEQ_REMOVE_EVENT_TYPE (1<<7) /**< Restrict to event type */ +#define SND_SEQ_REMOVE_IGNORE_OFF (1<<8) /**< Do not flush off events */ +#define SND_SEQ_REMOVE_TAG_MATCH (1<<9) /**< Restrict to events with given tag */ + +size_t snd_seq_remove_events_sizeof(void); +/** allocate a #snd_seq_remove_events_t container on stack */ +#define snd_seq_remove_events_alloca(ptr) \ + __snd_alloca(ptr, snd_seq_remove_events) +int snd_seq_remove_events_malloc(snd_seq_remove_events_t **ptr); +void snd_seq_remove_events_free(snd_seq_remove_events_t *ptr); +void snd_seq_remove_events_copy(snd_seq_remove_events_t *dst, const snd_seq_remove_events_t *src); + +unsigned int snd_seq_remove_events_get_condition(const snd_seq_remove_events_t *info); +int snd_seq_remove_events_get_queue(const snd_seq_remove_events_t *info); +const snd_seq_timestamp_t *snd_seq_remove_events_get_time(const snd_seq_remove_events_t *info); +const snd_seq_addr_t *snd_seq_remove_events_get_dest(const snd_seq_remove_events_t *info); +int snd_seq_remove_events_get_channel(const snd_seq_remove_events_t *info); +int snd_seq_remove_events_get_event_type(const snd_seq_remove_events_t *info); +int snd_seq_remove_events_get_tag(const snd_seq_remove_events_t *info); + +void snd_seq_remove_events_set_condition(snd_seq_remove_events_t *info, unsigned int flags); +void snd_seq_remove_events_set_queue(snd_seq_remove_events_t *info, int queue); +void snd_seq_remove_events_set_time(snd_seq_remove_events_t *info, const snd_seq_timestamp_t *time); +void snd_seq_remove_events_set_dest(snd_seq_remove_events_t *info, const snd_seq_addr_t *addr); +void snd_seq_remove_events_set_channel(snd_seq_remove_events_t *info, int channel); +void snd_seq_remove_events_set_event_type(snd_seq_remove_events_t *info, int type); +void snd_seq_remove_events_set_tag(snd_seq_remove_events_t *info, int tag); + +int snd_seq_remove_events(snd_seq_t *handle, snd_seq_remove_events_t *info); + +/** \} */ + +/** + * \defgroup SeqMisc Sequencer Miscellaneous + * Sequencer Miscellaneous + * \ingroup Sequencer + * \{ + */ + +void snd_seq_set_bit(int nr, void *array); +void snd_seq_unset_bit(int nr, void *array); +int snd_seq_change_bit(int nr, void *array); +int snd_seq_get_bit(int nr, void *array); + +/** \} */ + + +/** + * \defgroup SeqEvType Sequencer Event Type Checks + * Sequencer Event Type Checks + * \ingroup Sequencer + * \{ + */ + +/* event type macros */ +enum { + SND_SEQ_EVFLG_RESULT, + SND_SEQ_EVFLG_NOTE, + SND_SEQ_EVFLG_CONTROL, + SND_SEQ_EVFLG_QUEUE, + SND_SEQ_EVFLG_SYSTEM, + SND_SEQ_EVFLG_MESSAGE, + SND_SEQ_EVFLG_CONNECTION, + SND_SEQ_EVFLG_SAMPLE, + SND_SEQ_EVFLG_USERS, + SND_SEQ_EVFLG_INSTR, + SND_SEQ_EVFLG_QUOTE, + SND_SEQ_EVFLG_NONE, + SND_SEQ_EVFLG_RAW, + SND_SEQ_EVFLG_FIXED, + SND_SEQ_EVFLG_VARIABLE, + SND_SEQ_EVFLG_VARUSR +}; + +enum { + SND_SEQ_EVFLG_NOTE_ONEARG, + SND_SEQ_EVFLG_NOTE_TWOARG +}; + +enum { + SND_SEQ_EVFLG_QUEUE_NOARG, + SND_SEQ_EVFLG_QUEUE_TICK, + SND_SEQ_EVFLG_QUEUE_TIME, + SND_SEQ_EVFLG_QUEUE_VALUE +}; + +/** + * Exported event type table + * + * This table is referred by snd_seq_ev_is_xxx. + */ +extern const unsigned int snd_seq_event_types[]; + +#define _SND_SEQ_TYPE(x) (1<<(x)) /**< master type - 24bit */ +#define _SND_SEQ_TYPE_OPT(x) ((x)<<24) /**< optional type - 8bit */ + +/** check the event type */ +#define snd_seq_type_check(ev,x) (snd_seq_event_types[(ev)->type] & _SND_SEQ_TYPE(x)) + +/** event type check: result events */ +#define snd_seq_ev_is_result_type(ev) \ + snd_seq_type_check(ev, SND_SEQ_EVFLG_RESULT) +/** event type check: note events */ +#define snd_seq_ev_is_note_type(ev) \ + snd_seq_type_check(ev, SND_SEQ_EVFLG_NOTE) +/** event type check: control events */ +#define snd_seq_ev_is_control_type(ev) \ + snd_seq_type_check(ev, SND_SEQ_EVFLG_CONTROL) +/** event type check: channel specific events */ +#define snd_seq_ev_is_channel_type(ev) \ + (snd_seq_event_types[(ev)->type] & (_SND_SEQ_TYPE(SND_SEQ_EVFLG_NOTE) | _SND_SEQ_TYPE(SND_SEQ_EVFLG_CONTROL))) + +/** event type check: queue control events */ +#define snd_seq_ev_is_queue_type(ev) \ + snd_seq_type_check(ev, SND_SEQ_EVFLG_QUEUE) +/** event type check: system status messages */ +#define snd_seq_ev_is_message_type(ev) \ + snd_seq_type_check(ev, SND_SEQ_EVFLG_MESSAGE) +/** event type check: system status messages */ +#define snd_seq_ev_is_subscribe_type(ev) \ + snd_seq_type_check(ev, SND_SEQ_EVFLG_CONNECTION) +/** event type check: sample messages */ +#define snd_seq_ev_is_sample_type(ev) \ + snd_seq_type_check(ev, SND_SEQ_EVFLG_SAMPLE) +/** event type check: user-defined messages */ +#define snd_seq_ev_is_user_type(ev) \ + snd_seq_type_check(ev, SND_SEQ_EVFLG_USERS) +/** event type check: instrument layer events */ +#define snd_seq_ev_is_instr_type(ev) \ + snd_seq_type_check(ev, SND_SEQ_EVFLG_INSTR) +/** event type check: fixed length events */ +#define snd_seq_ev_is_fixed_type(ev) \ + snd_seq_type_check(ev, SND_SEQ_EVFLG_FIXED) +/** event type check: variable length events */ +#define snd_seq_ev_is_variable_type(ev) \ + snd_seq_type_check(ev, SND_SEQ_EVFLG_VARIABLE) +/** event type check: user pointer events */ +#define snd_seq_ev_is_varusr_type(ev) \ + snd_seq_type_check(ev, SND_SEQ_EVFLG_VARUSR) +/** event type check: reserved for kernel */ +#define snd_seq_ev_is_reserved(ev) \ + (! snd_seq_event_types[(ev)->type]) + +/** + * macros to check event flags + */ +/** prior events */ +#define snd_seq_ev_is_prior(ev) \ + (((ev)->flags & SND_SEQ_PRIORITY_MASK) == SND_SEQ_PRIORITY_HIGH) + +/** get the data length type */ +#define snd_seq_ev_length_type(ev) \ + ((ev)->flags & SND_SEQ_EVENT_LENGTH_MASK) +/** fixed length events */ +#define snd_seq_ev_is_fixed(ev) \ + (snd_seq_ev_length_type(ev) == SND_SEQ_EVENT_LENGTH_FIXED) +/** variable length events */ +#define snd_seq_ev_is_variable(ev) \ + (snd_seq_ev_length_type(ev) == SND_SEQ_EVENT_LENGTH_VARIABLE) +/** variable length on user-space */ +#define snd_seq_ev_is_varusr(ev) \ + (snd_seq_ev_length_type(ev) == SND_SEQ_EVENT_LENGTH_VARUSR) + +/** time-stamp type */ +#define snd_seq_ev_timestamp_type(ev) \ + ((ev)->flags & SND_SEQ_TIME_STAMP_MASK) +/** event is in tick time */ +#define snd_seq_ev_is_tick(ev) \ + (snd_seq_ev_timestamp_type(ev) == SND_SEQ_TIME_STAMP_TICK) +/** event is in real-time */ +#define snd_seq_ev_is_real(ev) \ + (snd_seq_ev_timestamp_type(ev) == SND_SEQ_TIME_STAMP_REAL) + +/** time-mode type */ +#define snd_seq_ev_timemode_type(ev) \ + ((ev)->flags & SND_SEQ_TIME_MODE_MASK) +/** scheduled in absolute time */ +#define snd_seq_ev_is_abstime(ev) \ + (snd_seq_ev_timemode_type(ev) == SND_SEQ_TIME_MODE_ABS) +/** scheduled in relative time */ +#define snd_seq_ev_is_reltime(ev) \ + (snd_seq_ev_timemode_type(ev) == SND_SEQ_TIME_MODE_REL) + +/** direct dispatched events */ +#define snd_seq_ev_is_direct(ev) \ + ((ev)->queue == SND_SEQ_QUEUE_DIRECT) + +/** \} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALSA_SEQ_H */ + diff --git a/thirdparty/linuxbsd_headers/alsa/seq_event.h b/thirdparty/linuxbsd_headers/alsa/seq_event.h new file mode 100644 index 0000000000..6bd0de3b5b --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/seq_event.h @@ -0,0 +1,325 @@ +/** + * \file include/seq_event.h + * \brief Application interface library for the ALSA driver + * \author Jaroslav Kysela <perex@perex.cz> + * \author Abramo Bagnara <abramo@alsa-project.org> + * \author Takashi Iwai <tiwai@suse.de> + * \date 1998-2001 + * + * Application interface library for the ALSA driver + */ +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_SEQ_EVENT_H +#define __ALSA_SEQ_EVENT_H + +/** + * \defgroup SeqEvents Sequencer Event Definitions + * Sequencer Event Definitions + * \ingroup Sequencer + * \{ + */ + +/** + * Sequencer event data type + */ +typedef unsigned char snd_seq_event_type_t; + +/** Sequencer event type */ +enum snd_seq_event_type { + /** system status; event data type = #snd_seq_result_t */ + SND_SEQ_EVENT_SYSTEM = 0, + /** returned result status; event data type = #snd_seq_result_t */ + SND_SEQ_EVENT_RESULT, + + /** note on and off with duration; event data type = #snd_seq_ev_note_t */ + SND_SEQ_EVENT_NOTE = 5, + /** note on; event data type = #snd_seq_ev_note_t */ + SND_SEQ_EVENT_NOTEON, + /** note off; event data type = #snd_seq_ev_note_t */ + SND_SEQ_EVENT_NOTEOFF, + /** key pressure change (aftertouch); event data type = #snd_seq_ev_note_t */ + SND_SEQ_EVENT_KEYPRESS, + + /** controller; event data type = #snd_seq_ev_ctrl_t */ + SND_SEQ_EVENT_CONTROLLER = 10, + /** program change; event data type = #snd_seq_ev_ctrl_t */ + SND_SEQ_EVENT_PGMCHANGE, + /** channel pressure; event data type = #snd_seq_ev_ctrl_t */ + SND_SEQ_EVENT_CHANPRESS, + /** pitchwheel; event data type = #snd_seq_ev_ctrl_t; data is from -8192 to 8191) */ + SND_SEQ_EVENT_PITCHBEND, + /** 14 bit controller value; event data type = #snd_seq_ev_ctrl_t */ + SND_SEQ_EVENT_CONTROL14, + /** 14 bit NRPN; event data type = #snd_seq_ev_ctrl_t */ + SND_SEQ_EVENT_NONREGPARAM, + /** 14 bit RPN; event data type = #snd_seq_ev_ctrl_t */ + SND_SEQ_EVENT_REGPARAM, + + /** SPP with LSB and MSB values; event data type = #snd_seq_ev_ctrl_t */ + SND_SEQ_EVENT_SONGPOS = 20, + /** Song Select with song ID number; event data type = #snd_seq_ev_ctrl_t */ + SND_SEQ_EVENT_SONGSEL, + /** midi time code quarter frame; event data type = #snd_seq_ev_ctrl_t */ + SND_SEQ_EVENT_QFRAME, + /** SMF Time Signature event; event data type = #snd_seq_ev_ctrl_t */ + SND_SEQ_EVENT_TIMESIGN, + /** SMF Key Signature event; event data type = #snd_seq_ev_ctrl_t */ + SND_SEQ_EVENT_KEYSIGN, + + /** MIDI Real Time Start message; event data type = #snd_seq_ev_queue_control_t */ + SND_SEQ_EVENT_START = 30, + /** MIDI Real Time Continue message; event data type = #snd_seq_ev_queue_control_t */ + SND_SEQ_EVENT_CONTINUE, + /** MIDI Real Time Stop message; event data type = #snd_seq_ev_queue_control_t */ + SND_SEQ_EVENT_STOP, + /** Set tick queue position; event data type = #snd_seq_ev_queue_control_t */ + SND_SEQ_EVENT_SETPOS_TICK, + /** Set real-time queue position; event data type = #snd_seq_ev_queue_control_t */ + SND_SEQ_EVENT_SETPOS_TIME, + /** (SMF) Tempo event; event data type = #snd_seq_ev_queue_control_t */ + SND_SEQ_EVENT_TEMPO, + /** MIDI Real Time Clock message; event data type = #snd_seq_ev_queue_control_t */ + SND_SEQ_EVENT_CLOCK, + /** MIDI Real Time Tick message; event data type = #snd_seq_ev_queue_control_t */ + SND_SEQ_EVENT_TICK, + /** Queue timer skew; event data type = #snd_seq_ev_queue_control_t */ + SND_SEQ_EVENT_QUEUE_SKEW, + /** Sync position changed; event data type = #snd_seq_ev_queue_control_t */ + SND_SEQ_EVENT_SYNC_POS, + + /** Tune request; event data type = none */ + SND_SEQ_EVENT_TUNE_REQUEST = 40, + /** Reset to power-on state; event data type = none */ + SND_SEQ_EVENT_RESET, + /** Active sensing event; event data type = none */ + SND_SEQ_EVENT_SENSING, + + /** Echo-back event; event data type = any type */ + SND_SEQ_EVENT_ECHO = 50, + /** OSS emulation raw event; event data type = any type */ + SND_SEQ_EVENT_OSS, + + /** New client has connected; event data type = #snd_seq_addr_t */ + SND_SEQ_EVENT_CLIENT_START = 60, + /** Client has left the system; event data type = #snd_seq_addr_t */ + SND_SEQ_EVENT_CLIENT_EXIT, + /** Client status/info has changed; event data type = #snd_seq_addr_t */ + SND_SEQ_EVENT_CLIENT_CHANGE, + /** New port was created; event data type = #snd_seq_addr_t */ + SND_SEQ_EVENT_PORT_START, + /** Port was deleted from system; event data type = #snd_seq_addr_t */ + SND_SEQ_EVENT_PORT_EXIT, + /** Port status/info has changed; event data type = #snd_seq_addr_t */ + SND_SEQ_EVENT_PORT_CHANGE, + + /** Ports connected; event data type = #snd_seq_connect_t */ + SND_SEQ_EVENT_PORT_SUBSCRIBED, + /** Ports disconnected; event data type = #snd_seq_connect_t */ + SND_SEQ_EVENT_PORT_UNSUBSCRIBED, + + /** user-defined event; event data type = any (fixed size) */ + SND_SEQ_EVENT_USR0 = 90, + /** user-defined event; event data type = any (fixed size) */ + SND_SEQ_EVENT_USR1, + /** user-defined event; event data type = any (fixed size) */ + SND_SEQ_EVENT_USR2, + /** user-defined event; event data type = any (fixed size) */ + SND_SEQ_EVENT_USR3, + /** user-defined event; event data type = any (fixed size) */ + SND_SEQ_EVENT_USR4, + /** user-defined event; event data type = any (fixed size) */ + SND_SEQ_EVENT_USR5, + /** user-defined event; event data type = any (fixed size) */ + SND_SEQ_EVENT_USR6, + /** user-defined event; event data type = any (fixed size) */ + SND_SEQ_EVENT_USR7, + /** user-defined event; event data type = any (fixed size) */ + SND_SEQ_EVENT_USR8, + /** user-defined event; event data type = any (fixed size) */ + SND_SEQ_EVENT_USR9, + + /** system exclusive data (variable length); event data type = #snd_seq_ev_ext_t */ + SND_SEQ_EVENT_SYSEX = 130, + /** error event; event data type = #snd_seq_ev_ext_t */ + SND_SEQ_EVENT_BOUNCE, + /** reserved for user apps; event data type = #snd_seq_ev_ext_t */ + SND_SEQ_EVENT_USR_VAR0 = 135, + /** reserved for user apps; event data type = #snd_seq_ev_ext_t */ + SND_SEQ_EVENT_USR_VAR1, + /** reserved for user apps; event data type = #snd_seq_ev_ext_t */ + SND_SEQ_EVENT_USR_VAR2, + /** reserved for user apps; event data type = #snd_seq_ev_ext_t */ + SND_SEQ_EVENT_USR_VAR3, + /** reserved for user apps; event data type = #snd_seq_ev_ext_t */ + SND_SEQ_EVENT_USR_VAR4, + + /** NOP; ignored in any case */ + SND_SEQ_EVENT_NONE = 255 +}; + + +/** Sequencer event address */ +typedef struct snd_seq_addr { + unsigned char client; /**< Client id */ + unsigned char port; /**< Port id */ +} snd_seq_addr_t; + +/** Connection (subscription) between ports */ +typedef struct snd_seq_connect { + snd_seq_addr_t sender; /**< sender address */ + snd_seq_addr_t dest; /**< destination address */ +} snd_seq_connect_t; + + +/** Real-time data record */ +typedef struct snd_seq_real_time { + unsigned int tv_sec; /**< seconds */ + unsigned int tv_nsec; /**< nanoseconds */ +} snd_seq_real_time_t; + +/** (MIDI) Tick-time data record */ +typedef unsigned int snd_seq_tick_time_t; + +/** unioned time stamp */ +typedef union snd_seq_timestamp { + snd_seq_tick_time_t tick; /**< tick-time */ + struct snd_seq_real_time time; /**< real-time */ +} snd_seq_timestamp_t; + + +/** + * Event mode flags + * + * NOTE: only 8 bits available! + */ +#define SND_SEQ_TIME_STAMP_TICK (0<<0) /**< timestamp in clock ticks */ +#define SND_SEQ_TIME_STAMP_REAL (1<<0) /**< timestamp in real time */ +#define SND_SEQ_TIME_STAMP_MASK (1<<0) /**< mask for timestamp bits */ + +#define SND_SEQ_TIME_MODE_ABS (0<<1) /**< absolute timestamp */ +#define SND_SEQ_TIME_MODE_REL (1<<1) /**< relative to current time */ +#define SND_SEQ_TIME_MODE_MASK (1<<1) /**< mask for time mode bits */ + +#define SND_SEQ_EVENT_LENGTH_FIXED (0<<2) /**< fixed event size */ +#define SND_SEQ_EVENT_LENGTH_VARIABLE (1<<2) /**< variable event size */ +#define SND_SEQ_EVENT_LENGTH_VARUSR (2<<2) /**< variable event size - user memory space */ +#define SND_SEQ_EVENT_LENGTH_MASK (3<<2) /**< mask for event length bits */ + +#define SND_SEQ_PRIORITY_NORMAL (0<<4) /**< normal priority */ +#define SND_SEQ_PRIORITY_HIGH (1<<4) /**< event should be processed before others */ +#define SND_SEQ_PRIORITY_MASK (1<<4) /**< mask for priority bits */ + + +/** Note event */ +typedef struct snd_seq_ev_note { + unsigned char channel; /**< channel number */ + unsigned char note; /**< note */ + unsigned char velocity; /**< velocity */ + unsigned char off_velocity; /**< note-off velocity; only for #SND_SEQ_EVENT_NOTE */ + unsigned int duration; /**< duration until note-off; only for #SND_SEQ_EVENT_NOTE */ +} snd_seq_ev_note_t; + +/** Controller event */ +typedef struct snd_seq_ev_ctrl { + unsigned char channel; /**< channel number */ + unsigned char unused[3]; /**< reserved */ + unsigned int param; /**< control parameter */ + signed int value; /**< control value */ +} snd_seq_ev_ctrl_t; + +/** generic set of bytes (12x8 bit) */ +typedef struct snd_seq_ev_raw8 { + unsigned char d[12]; /**< 8 bit value */ +} snd_seq_ev_raw8_t; + +/** generic set of integers (3x32 bit) */ +typedef struct snd_seq_ev_raw32 { + unsigned int d[3]; /**< 32 bit value */ +} snd_seq_ev_raw32_t; + +/** external stored data */ +struct snd_seq_ev_ext { + unsigned int len; /**< length of data */ + void *ptr; /**< pointer to data (note: can be 64-bit) */ +} __attribute__((packed)); +/** external stored data */ +typedef struct snd_seq_ev_ext snd_seq_ev_ext_t; +#ifdef DOC_HIDDEN +/* redefine typedef for stupid doxygen */ +typedef snd_seq_ev_ext snd_seq_ev_ext_t; +#endif + +/** Result events */ +typedef struct snd_seq_result { + int event; /**< processed event type */ + int result; /**< status */ +} snd_seq_result_t; + +/** Queue skew values */ +typedef struct snd_seq_queue_skew { + unsigned int value; /**< skew value */ + unsigned int base; /**< skew base */ +} snd_seq_queue_skew_t; + +/** queue timer control */ +typedef struct snd_seq_ev_queue_control { + unsigned char queue; /**< affected queue */ + unsigned char unused[3]; /**< reserved */ + union { + signed int value; /**< affected value (e.g. tempo) */ + snd_seq_timestamp_t time; /**< time */ + unsigned int position; /**< sync position */ + snd_seq_queue_skew_t skew; /**< queue skew */ + unsigned int d32[2]; /**< any data */ + unsigned char d8[8]; /**< any data */ + } param; /**< data value union */ +} snd_seq_ev_queue_control_t; + + +/** Sequencer event */ +typedef struct snd_seq_event { + snd_seq_event_type_t type; /**< event type */ + unsigned char flags; /**< event flags */ + unsigned char tag; /**< tag */ + + unsigned char queue; /**< schedule queue */ + snd_seq_timestamp_t time; /**< schedule time */ + + snd_seq_addr_t source; /**< source address */ + snd_seq_addr_t dest; /**< destination address */ + + union { + snd_seq_ev_note_t note; /**< note information */ + snd_seq_ev_ctrl_t control; /**< MIDI control information */ + snd_seq_ev_raw8_t raw8; /**< raw8 data */ + snd_seq_ev_raw32_t raw32; /**< raw32 data */ + snd_seq_ev_ext_t ext; /**< external data */ + snd_seq_ev_queue_control_t queue; /**< queue control */ + snd_seq_timestamp_t time; /**< timestamp */ + snd_seq_addr_t addr; /**< address */ + snd_seq_connect_t connect; /**< connect information */ + snd_seq_result_t result; /**< operation result code */ + } data; /**< event data... */ +} snd_seq_event_t; + + +/** \} */ + +#endif /* __ALSA_SEQ_EVENT_H */ + diff --git a/thirdparty/linuxbsd_headers/alsa/seq_midi_event.h b/thirdparty/linuxbsd_headers/alsa/seq_midi_event.h new file mode 100644 index 0000000000..9b8ee5963b --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/seq_midi_event.h @@ -0,0 +1,65 @@ +/** + * \file include/seq_midi_event.h + * \brief Application interface library for the ALSA driver + * \author Jaroslav Kysela <perex@perex.cz> + * \author Abramo Bagnara <abramo@alsa-project.org> + * \author Takashi Iwai <tiwai@suse.de> + * \date 1998-2001 + * + * Application interface library for the ALSA driver + */ +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_SEQ_MIDI_EVENT_H +#define __ALSA_SEQ_MIDI_EVENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup MIDI_Event Sequencer event <-> MIDI byte stream coder + * \ingroup Sequencer + * Sequencer event <-> MIDI byte stream coder + * \{ + */ + +/** container for sequencer midi event parsers */ +typedef struct snd_midi_event snd_midi_event_t; + +int snd_midi_event_new(size_t bufsize, snd_midi_event_t **rdev); +int snd_midi_event_resize_buffer(snd_midi_event_t *dev, size_t bufsize); +void snd_midi_event_free(snd_midi_event_t *dev); +void snd_midi_event_init(snd_midi_event_t *dev); +void snd_midi_event_reset_encode(snd_midi_event_t *dev); +void snd_midi_event_reset_decode(snd_midi_event_t *dev); +void snd_midi_event_no_status(snd_midi_event_t *dev, int on); +/* encode from byte stream - return number of written bytes if success */ +long snd_midi_event_encode(snd_midi_event_t *dev, const unsigned char *buf, long count, snd_seq_event_t *ev); +int snd_midi_event_encode_byte(snd_midi_event_t *dev, int c, snd_seq_event_t *ev); +/* decode from event to bytes - return number of written bytes if success */ +long snd_midi_event_decode(snd_midi_event_t *dev, unsigned char *buf, long count, const snd_seq_event_t *ev); + +/** \} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALSA_SEQ_MIDI_EVENT_H */ + diff --git a/thirdparty/linuxbsd_headers/alsa/seqmid.h b/thirdparty/linuxbsd_headers/alsa/seqmid.h new file mode 100644 index 0000000000..68069b2aa3 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/seqmid.h @@ -0,0 +1,490 @@ +/** + * \file include/seqmid.h + * \brief Application interface library for the ALSA driver + * \author Jaroslav Kysela <perex@perex.cz> + * \author Abramo Bagnara <abramo@alsa-project.org> + * \author Takashi Iwai <tiwai@suse.de> + * \date 1998-2001 + * + * Application interface library for the ALSA driver + */ +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_SEQMID_H +#define __ALSA_SEQMID_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup SeqMiddle Sequencer Middle Level Interface + * Sequencer Middle Level Interface + * \ingroup Sequencer + * \{ + */ + +/** + * \brief initialize event record + * \param ev event record pointer + * + * This macro clears the given event record pointer to the default status. + */ +#define snd_seq_ev_clear(ev) \ + memset(ev, 0, sizeof(snd_seq_event_t)) + +/** + * \brief set the tag for given event + * \param ev event record + * \param t event tag + * + * This macro sets the tag to the given event record. + */ +#define snd_seq_ev_set_tag(ev,t) \ + ((ev)->tag = (t)) + +/** + * \brief set the explicit destination + * \param ev event record + * \param c destination client id + * \param p destination port id + * + * This macro sets the client and port id numbers to the given event record. + * + * \sa snd_seq_ev_set_subs() + */ +#define snd_seq_ev_set_dest(ev,c,p) \ + ((ev)->dest.client = (c), (ev)->dest.port = (p)) + +/** + * \brief set broadcasting to subscribers + * \param ev event record + * + * This macro sets the destination as the subscribers. + * + * \sa snd_seq_ev_set_dest() + */ +#define snd_seq_ev_set_subs(ev) \ + ((ev)->dest.client = SND_SEQ_ADDRESS_SUBSCRIBERS,\ + (ev)->dest.port = SND_SEQ_ADDRESS_UNKNOWN) + +/** + * \brief set broadcasting to all clients/ports + * \param ev event record + * + * This macro sets the destination as the broadcasting. + * + * \sa snd_seq_ev_set_dest() + */ +#define snd_seq_ev_set_broadcast(ev) \ + ((ev)->dest.client = SND_SEQ_ADDRESS_BROADCAST,\ + (ev)->dest.port = SND_SEQ_ADDRESS_BROADCAST) + +/** + * \brief set the source port + * \param ev event record + * \param p source port id + * + * This macro sets the source port id number. + */ +#define snd_seq_ev_set_source(ev,p) \ + ((ev)->source.port = (p)) + +/** + * \brief set direct passing mode (without queued) + * \param ev event instance + * + * This macro sets the event to the direct passing mode + * to be delivered immediately without queueing. + * + * \sa snd_seq_ev_schedule_tick(), snd_seq_ev_schedule_real() + */ +#define snd_seq_ev_set_direct(ev) \ + ((ev)->queue = SND_SEQ_QUEUE_DIRECT) + +/** + * \brief set tick-scheduling mode on queue + * \param ev event instance + * \param q queue id to schedule + * \param relative relative time-stamp if non-zero + * \param ttick tick time-stamp to be delivered + * + * This macro sets the scheduling of the event in the + * MIDI tick mode. + * + * \sa snd_seq_ev_schedule_real(), snd_seq_ev_set_direct() + */ +#define snd_seq_ev_schedule_tick(ev, q, relative, ttick) \ + ((ev)->flags &= ~(SND_SEQ_TIME_STAMP_MASK | SND_SEQ_TIME_MODE_MASK),\ + (ev)->flags |= SND_SEQ_TIME_STAMP_TICK,\ + (ev)->flags |= (relative) ? SND_SEQ_TIME_MODE_REL : SND_SEQ_TIME_MODE_ABS,\ + (ev)->time.tick = (ttick),\ + (ev)->queue = (q)) + +/** + * \brief set real-time-scheduling mode on queue + * \param ev event instance + * \param q queue id to schedule + * \param relative relative time-stamp if non-zero + * \param rtime time-stamp to be delivered + * + * This macro sets the scheduling of the event in the + * realtime mode. + * + * \sa snd_seq_ev_schedule_tick(), snd_seq_ev_set_direct() + */ +#define snd_seq_ev_schedule_real(ev, q, relative, rtime) \ + ((ev)->flags &= ~(SND_SEQ_TIME_STAMP_MASK | SND_SEQ_TIME_MODE_MASK),\ + (ev)->flags |= SND_SEQ_TIME_STAMP_REAL,\ + (ev)->flags |= (relative) ? SND_SEQ_TIME_MODE_REL : SND_SEQ_TIME_MODE_ABS,\ + (ev)->time.time = *(rtime),\ + (ev)->queue = (q)) + +/** + * \brief set event priority + * \param ev event instance + * \param high_prior 1 for high priority mode + */ +#define snd_seq_ev_set_priority(ev, high_prior) \ + ((ev)->flags &= ~SND_SEQ_PRIORITY_MASK,\ + (ev)->flags |= (high_prior) ? SND_SEQ_PRIORITY_HIGH : SND_SEQ_PRIORITY_NORMAL) + +/** + * \brief set fixed data + * \param ev event instance + * + * Sets the event length mode as fixed size. + * + * \sa snd_seq_ev_set_variable(), snd_seq_ev_set_varusr() + */ +#define snd_seq_ev_set_fixed(ev) \ + ((ev)->flags &= ~SND_SEQ_EVENT_LENGTH_MASK,\ + (ev)->flags |= SND_SEQ_EVENT_LENGTH_FIXED) + +/** + * \brief set variable data + * \param ev event instance + * \param datalen length of the external data + * \param dataptr pointer of the external data + * + * Sets the event length mode as variable length and stores the data. + * + * \sa snd_seq_ev_set_fixed(), snd_seq_ev_set_varusr() + */ +#define snd_seq_ev_set_variable(ev, datalen, dataptr) \ + ((ev)->flags &= ~SND_SEQ_EVENT_LENGTH_MASK,\ + (ev)->flags |= SND_SEQ_EVENT_LENGTH_VARIABLE,\ + (ev)->data.ext.len = (datalen),\ + (ev)->data.ext.ptr = (dataptr)) + +/** + * \brief set varusr data + * \param ev event instance + * \param datalen length of the external data + * \param dataptr pointer of the external data + * + * Sets the event length mode as variable user-space data and stores the data. + * + * \sa snd_seq_ev_set_fixed(), snd_seq_ev_set_variable() + */ +#define snd_seq_ev_set_varusr(ev, datalen, dataptr) \ + ((ev)->flags &= ~SND_SEQ_EVENT_LENGTH_MASK,\ + (ev)->flags |= SND_SEQ_EVENT_LENGTH_VARUSR,\ + (ev)->data.ext.len = (datalen),\ + (ev)->data.ext.ptr = (dataptr)) + +/** + * \brief set queue controls + * \param ev event record + * \param typ event type + * \param q queue id + * \param val control value + */ +#define snd_seq_ev_set_queue_control(ev, typ, q, val) \ + ((ev)->type = (typ),\ + snd_seq_ev_set_dest(ev, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_TIMER),\ + (ev)->data.queue.queue = (q),\ + (ev)->data.queue.param.value = (val)) + +/** + * \brief set the start queue event + * \param ev event record + * \param q queue id to start + * + * \sa snd_seq_ev_set_queue_stop(), snd_seq_ev_set_queue_continue() + */ +#define snd_seq_ev_set_queue_start(ev, q) \ + snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_START, q, 0) + +/** + * \brief set the stop queue event + * \param ev event record + * \param q queue id to stop + * + * \sa snd_seq_ev_set_queue_start(), snd_seq_ev_set_queue_continue() + */ +#define snd_seq_ev_set_queue_stop(ev, q) \ + snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_STOP, q, 0) + +/** + * \brief set the stop queue event + * \param ev event record + * \param q queue id to continue + * + * \sa snd_seq_ev_set_queue_start(), snd_seq_ev_set_queue_stop() + */ +#define snd_seq_ev_set_queue_continue(ev, q) \ + snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_CONTINUE, q, 0) + +/** + * \brief set the stop queue event + * \param ev event record + * \param q queue id to change tempo + * \param val the new tempo value + */ +#define snd_seq_ev_set_queue_tempo(ev, q, val) \ + snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_TEMPO, q, val) + +/** + * \brief set the real-time position of a queue + * \param ev event record + * \param q queue id to change tempo + * \param rtime the new real-time pointer + */ +#define snd_seq_ev_set_queue_pos_real(ev, q, rtime) \ + ((ev)->type = SND_SEQ_EVENT_SETPOS_TIME,\ + snd_seq_ev_set_dest(ev, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_TIMER),\ + (ev)->data.queue.queue = (q),\ + (ev)->data.queue.param.time.time = *(rtime)) + +/** + * \brief set the tick-time position of a queue + * \param ev event record + * \param q queue id to change tempo + * \param ttime the new tick-time + */ +#define snd_seq_ev_set_queue_pos_tick(ev, q, ttime) \ + ((ev)->type = SND_SEQ_EVENT_SETPOS_TICK,\ + snd_seq_ev_set_dest(ev, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_TIMER),\ + (ev)->data.queue.queue = (q),\ + (ev)->data.queue.param.time.tick = (ttime)) + +/* set and send a queue control event */ +int snd_seq_control_queue(snd_seq_t *seq, int q, int type, int value, snd_seq_event_t *ev); + +/** + * \brief start the specified queue + * \param seq sequencer handle + * \param q queue id to start + * \param ev optional event record (see #snd_seq_control_queue) + */ +#define snd_seq_start_queue(seq, q, ev) \ + snd_seq_control_queue(seq, q, SND_SEQ_EVENT_START, 0, ev) + +/** + * \brief stop the specified queue + * \param seq sequencer handle + * \param q queue id to stop + * \param ev optional event record (see #snd_seq_control_queue) + */ +#define snd_seq_stop_queue(seq, q, ev) \ + snd_seq_control_queue(seq, q, SND_SEQ_EVENT_STOP, 0, ev) + +/** + * \brief continue the specified queue + * \param seq sequencer handle + * \param q queue id to continue + * \param ev optional event record (see #snd_seq_control_queue) + */ +#define snd_seq_continue_queue(seq, q, ev) \ + snd_seq_control_queue(seq, q, SND_SEQ_EVENT_CONTINUE, 0, ev) + +/** + * \brief change the tempo of the specified queue + * \param seq sequencer handle + * \param q queue id + * \param tempo the new tempo value + * \param ev optional event record (see #snd_seq_control_queue) + */ +#define snd_seq_change_queue_tempo(seq, q, tempo, ev) \ + snd_seq_control_queue(seq, q, SND_SEQ_EVENT_TEMPO, tempo, ev) + +/* create a port - simple version - return the port number */ +int snd_seq_create_simple_port(snd_seq_t *seq, const char *name, + unsigned int caps, unsigned int type); +/* delete the port */ +int snd_seq_delete_simple_port(snd_seq_t *seq, int port); + +/* simple subscription between this port and another port + (w/o exclusive & time conversion) + */ +int snd_seq_connect_from(snd_seq_t *seq, int my_port, int src_client, int src_port); +int snd_seq_connect_to(snd_seq_t *seq, int my_port, int dest_client, int dest_port); +int snd_seq_disconnect_from(snd_seq_t *seq, int my_port, int src_client, int src_port); +int snd_seq_disconnect_to(snd_seq_t *seq, int my_port, int dest_client, int dest_port); + +/* + * set client information + */ +int snd_seq_set_client_name(snd_seq_t *seq, const char *name); +int snd_seq_set_client_event_filter(snd_seq_t *seq, int event_type); +int snd_seq_set_client_pool_output(snd_seq_t *seq, size_t size); +int snd_seq_set_client_pool_output_room(snd_seq_t *seq, size_t size); +int snd_seq_set_client_pool_input(snd_seq_t *seq, size_t size); +/* sync output queue */ +int snd_seq_sync_output_queue(snd_seq_t *seq); + +/* + * parse the given string and get the sequencer address + */ +int snd_seq_parse_address(snd_seq_t *seq, snd_seq_addr_t *addr, const char *str); + +/* + * reset client input/output pool + */ +int snd_seq_reset_pool_output(snd_seq_t *seq); +int snd_seq_reset_pool_input(snd_seq_t *seq); + +/** + * \brief set note event + * \param ev event record + * \param ch channel number + * \param key note key + * \param vel velocity + * \param dur duration (in tick or msec) + */ +#define snd_seq_ev_set_note(ev, ch, key, vel, dur) \ + ((ev)->type = SND_SEQ_EVENT_NOTE,\ + snd_seq_ev_set_fixed(ev),\ + (ev)->data.note.channel = (ch),\ + (ev)->data.note.note = (key),\ + (ev)->data.note.velocity = (vel),\ + (ev)->data.note.duration = (dur)) + +/** + * \brief set note-on event + * \param ev event record + * \param ch channel number + * \param key note key + * \param vel velocity + */ +#define snd_seq_ev_set_noteon(ev, ch, key, vel) \ + ((ev)->type = SND_SEQ_EVENT_NOTEON,\ + snd_seq_ev_set_fixed(ev),\ + (ev)->data.note.channel = (ch),\ + (ev)->data.note.note = (key),\ + (ev)->data.note.velocity = (vel)) + +/** + * \brief set note-off event + * \param ev event record + * \param ch channel number + * \param key note key + * \param vel velocity + */ +#define snd_seq_ev_set_noteoff(ev, ch, key, vel) \ + ((ev)->type = SND_SEQ_EVENT_NOTEOFF,\ + snd_seq_ev_set_fixed(ev),\ + (ev)->data.note.channel = (ch),\ + (ev)->data.note.note = (key),\ + (ev)->data.note.velocity = (vel)) + +/** + * \brief set key-pressure event + * \param ev event record + * \param ch channel number + * \param key note key + * \param vel velocity + */ +#define snd_seq_ev_set_keypress(ev,ch,key,vel) \ + ((ev)->type = SND_SEQ_EVENT_KEYPRESS,\ + snd_seq_ev_set_fixed(ev),\ + (ev)->data.note.channel = (ch),\ + (ev)->data.note.note = (key),\ + (ev)->data.note.velocity = (vel)) + +/** + * \brief set MIDI controller event + * \param ev event record + * \param ch channel number + * \param cc controller number + * \param val control value + */ +#define snd_seq_ev_set_controller(ev,ch,cc,val) \ + ((ev)->type = SND_SEQ_EVENT_CONTROLLER,\ + snd_seq_ev_set_fixed(ev),\ + (ev)->data.control.channel = (ch),\ + (ev)->data.control.param = (cc),\ + (ev)->data.control.value = (val)) + +/** + * \brief set program change event + * \param ev event record + * \param ch channel number + * \param val program number + */ +#define snd_seq_ev_set_pgmchange(ev,ch,val) \ + ((ev)->type = SND_SEQ_EVENT_PGMCHANGE,\ + snd_seq_ev_set_fixed(ev),\ + (ev)->data.control.channel = (ch),\ + (ev)->data.control.value = (val)) + +/** + * \brief set pitch-bend event + * \param ev event record + * \param ch channel number + * \param val pitch bend; zero centered from -8192 to 8191 + */ +#define snd_seq_ev_set_pitchbend(ev,ch,val) \ + ((ev)->type = SND_SEQ_EVENT_PITCHBEND,\ + snd_seq_ev_set_fixed(ev),\ + (ev)->data.control.channel = (ch),\ + (ev)->data.control.value = (val)) + +/** + * \brief set channel pressure event + * \param ev event record + * \param ch channel number + * \param val channel pressure value + */ +#define snd_seq_ev_set_chanpress(ev,ch,val) \ + ((ev)->type = SND_SEQ_EVENT_CHANPRESS,\ + snd_seq_ev_set_fixed(ev),\ + (ev)->data.control.channel = (ch),\ + (ev)->data.control.value = (val)) + +/** + * \brief set sysex event + * \param ev event record + * \param datalen length of sysex data + * \param dataptr sysex data pointer + * + * the sysex data must contain the start byte 0xf0 and the end byte 0xf7. + */ +#define snd_seq_ev_set_sysex(ev,datalen,dataptr) \ + ((ev)->type = SND_SEQ_EVENT_SYSEX,\ + snd_seq_ev_set_variable(ev, datalen, dataptr)) + +/** \} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALSA_SEQMID_H */ + diff --git a/thirdparty/linuxbsd_headers/alsa/sound/asoc.h b/thirdparty/linuxbsd_headers/alsa/sound/asoc.h new file mode 100644 index 0000000000..082c542913 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/sound/asoc.h @@ -0,0 +1,543 @@ +/* + * uapi/sound/asoc.h -- ALSA SoC Firmware Controls and DAPM + * + * Copyright (C) 2012 Texas Instruments Inc. + * Copyright (C) 2015 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Simple file API to load FW that includes mixers, coefficients, DAPM graphs, + * algorithms, equalisers, DAIs, widgets etc. +*/ + +#ifndef __LINUX_UAPI_SND_ASOC_H +#define __LINUX_UAPI_SND_ASOC_H + +/* + * Maximum number of channels topology kcontrol can represent. + */ +#define SND_SOC_TPLG_MAX_CHAN 8 + +/* + * Maximum number of PCM formats capability + */ +#define SND_SOC_TPLG_MAX_FORMATS 16 + +/* + * Maximum number of PCM stream configs + */ +#define SND_SOC_TPLG_STREAM_CONFIG_MAX 8 + +/* + * Maximum number of physical link's hardware configs + */ +#define SND_SOC_TPLG_HW_CONFIG_MAX 8 + +/* individual kcontrol info types - can be mixed with other types */ +#define SND_SOC_TPLG_CTL_VOLSW 1 +#define SND_SOC_TPLG_CTL_VOLSW_SX 2 +#define SND_SOC_TPLG_CTL_VOLSW_XR_SX 3 +#define SND_SOC_TPLG_CTL_ENUM 4 +#define SND_SOC_TPLG_CTL_BYTES 5 +#define SND_SOC_TPLG_CTL_ENUM_VALUE 6 +#define SND_SOC_TPLG_CTL_RANGE 7 +#define SND_SOC_TPLG_CTL_STROBE 8 + + +/* individual widget kcontrol info types - can be mixed with other types */ +#define SND_SOC_TPLG_DAPM_CTL_VOLSW 64 +#define SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE 65 +#define SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT 66 +#define SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE 67 +#define SND_SOC_TPLG_DAPM_CTL_PIN 68 + +/* DAPM widget types - add new items to the end */ +#define SND_SOC_TPLG_DAPM_INPUT 0 +#define SND_SOC_TPLG_DAPM_OUTPUT 1 +#define SND_SOC_TPLG_DAPM_MUX 2 +#define SND_SOC_TPLG_DAPM_MIXER 3 +#define SND_SOC_TPLG_DAPM_PGA 4 +#define SND_SOC_TPLG_DAPM_OUT_DRV 5 +#define SND_SOC_TPLG_DAPM_ADC 6 +#define SND_SOC_TPLG_DAPM_DAC 7 +#define SND_SOC_TPLG_DAPM_SWITCH 8 +#define SND_SOC_TPLG_DAPM_PRE 9 +#define SND_SOC_TPLG_DAPM_POST 10 +#define SND_SOC_TPLG_DAPM_AIF_IN 11 +#define SND_SOC_TPLG_DAPM_AIF_OUT 12 +#define SND_SOC_TPLG_DAPM_DAI_IN 13 +#define SND_SOC_TPLG_DAPM_DAI_OUT 14 +#define SND_SOC_TPLG_DAPM_DAI_LINK 15 +#define SND_SOC_TPLG_DAPM_LAST SND_SOC_TPLG_DAPM_DAI_LINK + +/* Header magic number and string sizes */ +#define SND_SOC_TPLG_MAGIC 0x41536F43 /* ASoC */ + +/* string sizes */ +#define SND_SOC_TPLG_NUM_TEXTS 16 + +/* ABI version */ +#define SND_SOC_TPLG_ABI_VERSION 0x5 /* current version */ +#define SND_SOC_TPLG_ABI_VERSION_MIN 0x4 /* oldest version supported */ + +/* Max size of TLV data */ +#define SND_SOC_TPLG_TLV_SIZE 32 + +/* + * File and Block header data types. + * Add new generic and vendor types to end of list. + * Generic types are handled by the core whilst vendors types are passed + * to the component drivers for handling. + */ +#define SND_SOC_TPLG_TYPE_MIXER 1 +#define SND_SOC_TPLG_TYPE_BYTES 2 +#define SND_SOC_TPLG_TYPE_ENUM 3 +#define SND_SOC_TPLG_TYPE_DAPM_GRAPH 4 +#define SND_SOC_TPLG_TYPE_DAPM_WIDGET 5 +#define SND_SOC_TPLG_TYPE_DAI_LINK 6 +#define SND_SOC_TPLG_TYPE_PCM 7 +#define SND_SOC_TPLG_TYPE_MANIFEST 8 +#define SND_SOC_TPLG_TYPE_CODEC_LINK 9 +#define SND_SOC_TPLG_TYPE_BACKEND_LINK 10 +#define SND_SOC_TPLG_TYPE_PDATA 11 +#define SND_SOC_TPLG_TYPE_DAI 12 +#define SND_SOC_TPLG_TYPE_MAX SND_SOC_TPLG_TYPE_DAI + +/* vendor block IDs - please add new vendor types to end */ +#define SND_SOC_TPLG_TYPE_VENDOR_FW 1000 +#define SND_SOC_TPLG_TYPE_VENDOR_CONFIG 1001 +#define SND_SOC_TPLG_TYPE_VENDOR_COEFF 1002 +#define SND_SOC_TPLG_TYPEVENDOR_CODEC 1003 + +#define SND_SOC_TPLG_STREAM_PLAYBACK 0 +#define SND_SOC_TPLG_STREAM_CAPTURE 1 + +/* vendor tuple types */ +#define SND_SOC_TPLG_TUPLE_TYPE_UUID 0 +#define SND_SOC_TPLG_TUPLE_TYPE_STRING 1 +#define SND_SOC_TPLG_TUPLE_TYPE_BOOL 2 +#define SND_SOC_TPLG_TUPLE_TYPE_BYTE 3 +#define SND_SOC_TPLG_TUPLE_TYPE_WORD 4 +#define SND_SOC_TPLG_TUPLE_TYPE_SHORT 5 + +/* DAI flags */ +#define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES (1 << 0) +#define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS (1 << 1) +#define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS (1 << 2) + +/* DAI physical PCM data formats. + * Add new formats to the end of the list. + */ +#define SND_SOC_DAI_FORMAT_I2S 1 /* I2S mode */ +#define SND_SOC_DAI_FORMAT_RIGHT_J 2 /* Right Justified mode */ +#define SND_SOC_DAI_FORMAT_LEFT_J 3 /* Left Justified mode */ +#define SND_SOC_DAI_FORMAT_DSP_A 4 /* L data MSB after FRM LRC */ +#define SND_SOC_DAI_FORMAT_DSP_B 5 /* L data MSB during FRM LRC */ +#define SND_SOC_DAI_FORMAT_AC97 6 /* AC97 */ +#define SND_SOC_DAI_FORMAT_PDM 7 /* Pulse density modulation */ + +/* left and right justified also known as MSB and LSB respectively */ +#define SND_SOC_DAI_FORMAT_MSB SND_SOC_DAI_FORMAT_LEFT_J +#define SND_SOC_DAI_FORMAT_LSB SND_SOC_DAI_FORMAT_RIGHT_J + +/* DAI link flags */ +#define SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_RATES (1 << 0) +#define SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_CHANNELS (1 << 1) +#define SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_SAMPLEBITS (1 << 2) +#define SND_SOC_TPLG_LNK_FLGBIT_VOICE_WAKEUP (1 << 3) + +/* + * Block Header. + * This header precedes all object and object arrays below. + */ +struct snd_soc_tplg_hdr { + __le32 magic; /* magic number */ + __le32 abi; /* ABI version */ + __le32 version; /* optional vendor specific version details */ + __le32 type; /* SND_SOC_TPLG_TYPE_ */ + __le32 size; /* size of this structure */ + __le32 vendor_type; /* optional vendor specific type info */ + __le32 payload_size; /* data bytes, excluding this header */ + __le32 index; /* identifier for block */ + __le32 count; /* number of elements in block */ +} __attribute__((packed)); + +/* vendor tuple for uuid */ +struct snd_soc_tplg_vendor_uuid_elem { + __le32 token; + char uuid[16]; +} __attribute__((packed)); + +/* vendor tuple for a bool/byte/short/word value */ +struct snd_soc_tplg_vendor_value_elem { + __le32 token; + __le32 value; +} __attribute__((packed)); + +/* vendor tuple for string */ +struct snd_soc_tplg_vendor_string_elem { + __le32 token; + char string[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; +} __attribute__((packed)); + +struct snd_soc_tplg_vendor_array { + __le32 size; /* size in bytes of the array, including all elements */ + __le32 type; /* SND_SOC_TPLG_TUPLE_TYPE_ */ + __le32 num_elems; /* number of elements in array */ + union { + struct snd_soc_tplg_vendor_uuid_elem uuid[0]; + struct snd_soc_tplg_vendor_value_elem value[0]; + struct snd_soc_tplg_vendor_string_elem string[0]; + }; +} __attribute__((packed)); + +/* + * Private data. + * All topology objects may have private data that can be used by the driver or + * firmware. Core will ignore this data. + */ +struct snd_soc_tplg_private { + __le32 size; /* in bytes of private data */ + union { + char data[0]; + struct snd_soc_tplg_vendor_array array[0]; + }; +} __attribute__((packed)); + +/* + * Kcontrol TLV data. + */ +struct snd_soc_tplg_tlv_dbscale { + __le32 min; + __le32 step; + __le32 mute; +} __attribute__((packed)); + +struct snd_soc_tplg_ctl_tlv { + __le32 size; /* in bytes of this structure */ + __le32 type; /* SNDRV_CTL_TLVT_*, type of TLV */ + union { + __le32 data[SND_SOC_TPLG_TLV_SIZE]; + struct snd_soc_tplg_tlv_dbscale scale; + }; +} __attribute__((packed)); + +/* + * Kcontrol channel data + */ +struct snd_soc_tplg_channel { + __le32 size; /* in bytes of this structure */ + __le32 reg; + __le32 shift; + __le32 id; /* ID maps to Left, Right, LFE etc */ +} __attribute__((packed)); + +/* + * Genericl Operations IDs, for binding Kcontrol or Bytes ext ops + * Kcontrol ops need get/put/info. + * Bytes ext ops need get/put. + */ +struct snd_soc_tplg_io_ops { + __le32 get; + __le32 put; + __le32 info; +} __attribute__((packed)); + +/* + * kcontrol header + */ +struct snd_soc_tplg_ctl_hdr { + __le32 size; /* in bytes of this structure */ + __le32 type; + char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + __le32 access; + struct snd_soc_tplg_io_ops ops; + struct snd_soc_tplg_ctl_tlv tlv; +} __attribute__((packed)); + +/* + * Stream Capabilities + */ +struct snd_soc_tplg_stream_caps { + __le32 size; /* in bytes of this structure */ + char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + __le64 formats; /* supported formats SNDRV_PCM_FMTBIT_* */ + __le32 rates; /* supported rates SNDRV_PCM_RATE_* */ + __le32 rate_min; /* min rate */ + __le32 rate_max; /* max rate */ + __le32 channels_min; /* min channels */ + __le32 channels_max; /* max channels */ + __le32 periods_min; /* min number of periods */ + __le32 periods_max; /* max number of periods */ + __le32 period_size_min; /* min period size bytes */ + __le32 period_size_max; /* max period size bytes */ + __le32 buffer_size_min; /* min buffer size bytes */ + __le32 buffer_size_max; /* max buffer size bytes */ + __le32 sig_bits; /* number of bits of content */ +} __attribute__((packed)); + +/* + * FE or BE Stream configuration supported by SW/FW + */ +struct snd_soc_tplg_stream { + __le32 size; /* in bytes of this structure */ + char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* Name of the stream */ + __le64 format; /* SNDRV_PCM_FMTBIT_* */ + __le32 rate; /* SNDRV_PCM_RATE_* */ + __le32 period_bytes; /* size of period in bytes */ + __le32 buffer_bytes; /* size of buffer in bytes */ + __le32 channels; /* channels */ +} __attribute__((packed)); + + +/* + * Describes a physical link's runtime supported hardware config, + * i.e. hardware audio formats. + */ +struct snd_soc_tplg_hw_config { + __le32 size; /* in bytes of this structure */ + __le32 id; /* unique ID - - used to match */ + __le32 fmt; /* SND_SOC_DAI_FORMAT_ format value */ + __u8 clock_gated; /* 1 if clock can be gated to save power */ + __u8 invert_bclk; /* 1 for inverted BCLK, 0 for normal */ + __u8 invert_fsync; /* 1 for inverted frame clock, 0 for normal */ + __u8 bclk_master; /* 1 for master of BCLK, 0 for slave */ + __u8 fsync_master; /* 1 for master of FSYNC, 0 for slave */ + __u8 mclk_direction; /* 0 for input, 1 for output */ + __le16 reserved; /* for 32bit alignment */ + __le32 mclk_rate; /* MCLK or SYSCLK freqency in Hz */ + __le32 bclk_rate; /* BCLK freqency in Hz */ + __le32 fsync_rate; /* frame clock in Hz */ + __le32 tdm_slots; /* number of TDM slots in use */ + __le32 tdm_slot_width; /* width in bits for each slot */ + __le32 tx_slots; /* bit mask for active Tx slots */ + __le32 rx_slots; /* bit mask for active Rx slots */ + __le32 tx_channels; /* number of Tx channels */ + __le32 tx_chanmap[SND_SOC_TPLG_MAX_CHAN]; /* array of slot number */ + __le32 rx_channels; /* number of Rx channels */ + __le32 rx_chanmap[SND_SOC_TPLG_MAX_CHAN]; /* array of slot number */ +} __attribute__((packed)); + +/* + * Manifest. List totals for each payload type. Not used in parsing, but will + * be passed to the component driver before any other objects in order for any + * global component resource allocations. + * + * File block representation for manifest :- + * +-----------------------------------+----+ + * | struct snd_soc_tplg_hdr | 1 | + * +-----------------------------------+----+ + * | struct snd_soc_tplg_manifest | 1 | + * +-----------------------------------+----+ + */ +struct snd_soc_tplg_manifest { + __le32 size; /* in bytes of this structure */ + __le32 control_elems; /* number of control elements */ + __le32 widget_elems; /* number of widget elements */ + __le32 graph_elems; /* number of graph elements */ + __le32 pcm_elems; /* number of PCM elements */ + __le32 dai_link_elems; /* number of DAI link elements */ + __le32 dai_elems; /* number of physical DAI elements */ + __le32 reserved[20]; /* reserved for new ABI element types */ + struct snd_soc_tplg_private priv; +} __attribute__((packed)); + +/* + * Mixer kcontrol. + * + * File block representation for mixer kcontrol :- + * +-----------------------------------+----+ + * | struct snd_soc_tplg_hdr | 1 | + * +-----------------------------------+----+ + * | struct snd_soc_tplg_mixer_control | N | + * +-----------------------------------+----+ + */ +struct snd_soc_tplg_mixer_control { + struct snd_soc_tplg_ctl_hdr hdr; + __le32 size; /* in bytes of this structure */ + __le32 min; + __le32 max; + __le32 platform_max; + __le32 invert; + __le32 num_channels; + struct snd_soc_tplg_channel channel[SND_SOC_TPLG_MAX_CHAN]; + struct snd_soc_tplg_private priv; +} __attribute__((packed)); + +/* + * Enumerated kcontrol + * + * File block representation for enum kcontrol :- + * +-----------------------------------+----+ + * | struct snd_soc_tplg_hdr | 1 | + * +-----------------------------------+----+ + * | struct snd_soc_tplg_enum_control | N | + * +-----------------------------------+----+ + */ +struct snd_soc_tplg_enum_control { + struct snd_soc_tplg_ctl_hdr hdr; + __le32 size; /* in bytes of this structure */ + __le32 num_channels; + struct snd_soc_tplg_channel channel[SND_SOC_TPLG_MAX_CHAN]; + __le32 items; + __le32 mask; + __le32 count; + char texts[SND_SOC_TPLG_NUM_TEXTS][SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + __le32 values[SND_SOC_TPLG_NUM_TEXTS * SNDRV_CTL_ELEM_ID_NAME_MAXLEN / 4]; + struct snd_soc_tplg_private priv; +} __attribute__((packed)); + +/* + * Bytes kcontrol + * + * File block representation for bytes kcontrol :- + * +-----------------------------------+----+ + * | struct snd_soc_tplg_hdr | 1 | + * +-----------------------------------+----+ + * | struct snd_soc_tplg_bytes_control | N | + * +-----------------------------------+----+ + */ +struct snd_soc_tplg_bytes_control { + struct snd_soc_tplg_ctl_hdr hdr; + __le32 size; /* in bytes of this structure */ + __le32 max; + __le32 mask; + __le32 base; + __le32 num_regs; + struct snd_soc_tplg_io_ops ext_ops; + struct snd_soc_tplg_private priv; +} __attribute__((packed)); + +/* + * DAPM Graph Element + * + * File block representation for DAPM graph elements :- + * +-------------------------------------+----+ + * | struct snd_soc_tplg_hdr | 1 | + * +-------------------------------------+----+ + * | struct snd_soc_tplg_dapm_graph_elem | N | + * +-------------------------------------+----+ + */ +struct snd_soc_tplg_dapm_graph_elem { + char sink[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + char control[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + char source[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; +} __attribute__((packed)); + +/* + * DAPM Widget. + * + * File block representation for DAPM widget :- + * +-------------------------------------+-----+ + * | struct snd_soc_tplg_hdr | 1 | + * +-------------------------------------+-----+ + * | struct snd_soc_tplg_dapm_widget | N | + * +-------------------------------------+-----+ + * | struct snd_soc_tplg_enum_control | 0|1 | + * | struct snd_soc_tplg_mixer_control | 0|N | + * +-------------------------------------+-----+ + * + * Optional enum or mixer control can be appended to the end of each widget + * in the block. + */ +struct snd_soc_tplg_dapm_widget { + __le32 size; /* in bytes of this structure */ + __le32 id; /* SND_SOC_DAPM_CTL */ + char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + char sname[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + + __le32 reg; /* negative reg = no direct dapm */ + __le32 shift; /* bits to shift */ + __le32 mask; /* non-shifted mask */ + __le32 subseq; /* sort within widget type */ + __le32 invert; /* invert the power bit */ + __le32 ignore_suspend; /* kept enabled over suspend */ + __le16 event_flags; + __le16 event_type; + __le32 num_kcontrols; + struct snd_soc_tplg_private priv; + /* + * kcontrols that relate to this widget + * follow here after widget private data + */ +} __attribute__((packed)); + + +/* + * Describes SW/FW specific features of PCM (FE DAI & DAI link). + * + * File block representation for PCM :- + * +-----------------------------------+-----+ + * | struct snd_soc_tplg_hdr | 1 | + * +-----------------------------------+-----+ + * | struct snd_soc_tplg_pcm | N | + * +-----------------------------------+-----+ + */ +struct snd_soc_tplg_pcm { + __le32 size; /* in bytes of this structure */ + char pcm_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + __le32 pcm_id; /* unique ID - used to match with DAI link */ + __le32 dai_id; /* unique ID - used to match */ + __le32 playback; /* supports playback mode */ + __le32 capture; /* supports capture mode */ + __le32 compress; /* 1 = compressed; 0 = PCM */ + struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* for DAI link */ + __le32 num_streams; /* number of streams */ + struct snd_soc_tplg_stream_caps caps[2]; /* playback and capture for DAI */ + __le32 flag_mask; /* bitmask of flags to configure */ + __le32 flags; /* SND_SOC_TPLG_LNK_FLGBIT_* flag value */ + struct snd_soc_tplg_private priv; +} __attribute__((packed)); + + +/* + * Describes the physical link runtime supported configs or params + * + * File block representation for physical link config :- + * +-----------------------------------+-----+ + * | struct snd_soc_tplg_hdr | 1 | + * +-----------------------------------+-----+ + * | struct snd_soc_tplg_link_config | N | + * +-----------------------------------+-----+ + */ +struct snd_soc_tplg_link_config { + __le32 size; /* in bytes of this structure */ + __le32 id; /* unique ID - used to match */ + char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* name - used to match */ + char stream_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* stream name - used to match */ + struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* supported configs playback and captrure */ + __le32 num_streams; /* number of streams */ + struct snd_soc_tplg_hw_config hw_config[SND_SOC_TPLG_HW_CONFIG_MAX]; /* hw configs */ + __le32 num_hw_configs; /* number of hw configs */ + __le32 default_hw_config_id; /* default hw config ID for init */ + __le32 flag_mask; /* bitmask of flags to configure */ + __le32 flags; /* SND_SOC_TPLG_LNK_FLGBIT_* flag value */ + struct snd_soc_tplg_private priv; +} __attribute__((packed)); + +/* + * Describes SW/FW specific features of physical DAI. + * It can be used to configure backend DAIs for DPCM. + * + * File block representation for physical DAI :- + * +-----------------------------------+-----+ + * | struct snd_soc_tplg_hdr | 1 | + * +-----------------------------------+-----+ + * | struct snd_soc_tplg_dai | N | + * +-----------------------------------+-----+ + */ +struct snd_soc_tplg_dai { + __le32 size; /* in bytes of this structure */ + char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* name - used to match */ + __le32 dai_id; /* unique ID - used to match */ + __le32 playback; /* supports playback mode */ + __le32 capture; /* supports capture mode */ + struct snd_soc_tplg_stream_caps caps[2]; /* playback and capture for DAI */ + __le32 flag_mask; /* bitmask of flags to configure */ + __le32 flags; /* SND_SOC_TPLG_DAI_FLGBIT_* */ + struct snd_soc_tplg_private priv; +} __attribute__((packed)); +#endif diff --git a/thirdparty/linuxbsd_headers/alsa/sound/asound_fm.h b/thirdparty/linuxbsd_headers/alsa/sound/asound_fm.h new file mode 100644 index 0000000000..c2a4b967d5 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/sound/asound_fm.h @@ -0,0 +1,134 @@ +#ifndef __SOUND_ASOUND_FM_H +#define __SOUND_ASOUND_FM_H + +/* + * Advanced Linux Sound Architecture - ALSA + * + * Interface file between ALSA driver & user space + * Copyright (c) 1994-98 by Jaroslav Kysela <perex@perex.cz>, + * 4Front Technologies + * + * Direct FM control + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define SNDRV_DM_FM_MODE_OPL2 0x00 +#define SNDRV_DM_FM_MODE_OPL3 0x01 + +struct snd_dm_fm_info { + unsigned char fm_mode; /* OPL mode, see SNDRV_DM_FM_MODE_XXX */ + unsigned char rhythm; /* percussion mode flag */ +}; + +/* + * Data structure composing an FM "note" or sound event. + */ + +struct snd_dm_fm_voice { + unsigned char op; /* operator cell (0 or 1) */ + unsigned char voice; /* FM voice (0 to 17) */ + + unsigned char am; /* amplitude modulation */ + unsigned char vibrato; /* vibrato effect */ + unsigned char do_sustain; /* sustain phase */ + unsigned char kbd_scale; /* keyboard scaling */ + unsigned char harmonic; /* 4 bits: harmonic and multiplier */ + unsigned char scale_level; /* 2 bits: decrease output freq rises */ + unsigned char volume; /* 6 bits: volume */ + + unsigned char attack; /* 4 bits: attack rate */ + unsigned char decay; /* 4 bits: decay rate */ + unsigned char sustain; /* 4 bits: sustain level */ + unsigned char release; /* 4 bits: release rate */ + + unsigned char feedback; /* 3 bits: feedback for op0 */ + unsigned char connection; /* 0 for serial, 1 for parallel */ + unsigned char left; /* stereo left */ + unsigned char right; /* stereo right */ + unsigned char waveform; /* 3 bits: waveform shape */ +}; + +/* + * This describes an FM note by its voice, octave, frequency number (10bit) + * and key on/off. + */ + +struct snd_dm_fm_note { + unsigned char voice; /* 0-17 voice channel */ + unsigned char octave; /* 3 bits: what octave to play */ + unsigned int fnum; /* 10 bits: frequency number */ + unsigned char key_on; /* set for active, clear for silent */ +}; + +/* + * FM parameters that apply globally to all voices, and thus are not "notes" + */ + +struct snd_dm_fm_params { + unsigned char am_depth; /* amplitude modulation depth (1=hi) */ + unsigned char vib_depth; /* vibrato depth (1=hi) */ + unsigned char kbd_split; /* keyboard split */ + unsigned char rhythm; /* percussion mode select */ + + /* This block is the percussion instrument data */ + unsigned char bass; + unsigned char snare; + unsigned char tomtom; + unsigned char cymbal; + unsigned char hihat; +}; + +/* + * FM mode ioctl settings + */ + +#define SNDRV_DM_FM_IOCTL_INFO _IOR('H', 0x20, struct snd_dm_fm_info) +#define SNDRV_DM_FM_IOCTL_RESET _IO ('H', 0x21) +#define SNDRV_DM_FM_IOCTL_PLAY_NOTE _IOW('H', 0x22, struct snd_dm_fm_note) +#define SNDRV_DM_FM_IOCTL_SET_VOICE _IOW('H', 0x23, struct snd_dm_fm_voice) +#define SNDRV_DM_FM_IOCTL_SET_PARAMS _IOW('H', 0x24, struct snd_dm_fm_params) +#define SNDRV_DM_FM_IOCTL_SET_MODE _IOW('H', 0x25, int) +/* for OPL3 only */ +#define SNDRV_DM_FM_IOCTL_SET_CONNECTION _IOW('H', 0x26, int) +/* SBI patch management */ +#define SNDRV_DM_FM_IOCTL_CLEAR_PATCHES _IO ('H', 0x40) + +#define SNDRV_DM_FM_OSS_IOCTL_RESET 0x20 +#define SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE 0x21 +#define SNDRV_DM_FM_OSS_IOCTL_SET_VOICE 0x22 +#define SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS 0x23 +#define SNDRV_DM_FM_OSS_IOCTL_SET_MODE 0x24 +#define SNDRV_DM_FM_OSS_IOCTL_SET_OPL 0x25 + +/* + * Patch Record - fixed size for write + */ + +#define FM_KEY_SBI "SBI\032" +#define FM_KEY_2OP "2OP\032" +#define FM_KEY_4OP "4OP\032" + +struct sbi_patch { + unsigned char prog; + unsigned char bank; + char key[4]; + char name[25]; + char extension[7]; + unsigned char data[32]; +}; + +#endif /* __SOUND_ASOUND_FM_H */ diff --git a/thirdparty/linuxbsd_headers/alsa/sound/emu10k1.h b/thirdparty/linuxbsd_headers/alsa/sound/emu10k1.h new file mode 100644 index 0000000000..94018b74dc --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/sound/emu10k1.h @@ -0,0 +1,349 @@ +#ifndef __SOUND_EMU10K1_H +#define __SOUND_EMU10K1_H + +/* + * Copyright (c) by Jaroslav Kysela <perex@perex.cz>, + * Creative Labs, Inc. + * Definitions for EMU10K1 (SB Live!) chips + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <stdint.h> + +/* + * ---- FX8010 ---- + */ + +#define EMU10K1_CARD_CREATIVE 0x00000000 +#define EMU10K1_CARD_EMUAPS 0x00000001 + +#define EMU10K1_FX8010_PCM_COUNT 8 + +/* instruction set */ +#define iMAC0 0x00 /* R = A + (X * Y >> 31) ; saturation */ +#define iMAC1 0x01 /* R = A + (-X * Y >> 31) ; saturation */ +#define iMAC2 0x02 /* R = A + (X * Y >> 31) ; wraparound */ +#define iMAC3 0x03 /* R = A + (-X * Y >> 31) ; wraparound */ +#define iMACINT0 0x04 /* R = A + X * Y ; saturation */ +#define iMACINT1 0x05 /* R = A + X * Y ; wraparound (31-bit) */ +#define iACC3 0x06 /* R = A + X + Y ; saturation */ +#define iMACMV 0x07 /* R = A, acc += X * Y >> 31 */ +#define iANDXOR 0x08 /* R = (A & X) ^ Y */ +#define iTSTNEG 0x09 /* R = (A >= Y) ? X : ~X */ +#define iLIMITGE 0x0a /* R = (A >= Y) ? X : Y */ +#define iLIMITLT 0x0b /* R = (A < Y) ? X : Y */ +#define iLOG 0x0c /* R = linear_data, A (log_data), X (max_exp), Y (format_word) */ +#define iEXP 0x0d /* R = log_data, A (linear_data), X (max_exp), Y (format_word) */ +#define iINTERP 0x0e /* R = A + (X * (Y - A) >> 31) ; saturation */ +#define iSKIP 0x0f /* R = A (cc_reg), X (count), Y (cc_test) */ + +/* GPRs */ +#define FXBUS(x) (0x00 + (x)) /* x = 0x00 - 0x0f */ +#define EXTIN(x) (0x10 + (x)) /* x = 0x00 - 0x0f */ +#define EXTOUT(x) (0x20 + (x)) /* x = 0x00 - 0x0f */ +#define C_00000000 0x40 +#define C_00000001 0x41 +#define C_00000002 0x42 +#define C_00000003 0x43 +#define C_00000004 0x44 +#define C_00000008 0x45 +#define C_00000010 0x46 +#define C_00000020 0x47 +#define C_00000100 0x48 +#define C_00010000 0x49 +#define C_00080000 0x4a +#define C_10000000 0x4b +#define C_20000000 0x4c +#define C_40000000 0x4d +#define C_80000000 0x4e +#define C_7fffffff 0x4f +#define C_ffffffff 0x50 +#define C_fffffffe 0x51 +#define C_c0000000 0x52 +#define C_4f1bbcdc 0x53 +#define C_5a7ef9db 0x54 +#define C_00100000 0x55 /* ?? */ +#define GPR_ACCU 0x56 /* ACCUM, accumulator */ +#define GPR_COND 0x57 /* CCR, condition register */ +#define GPR_NOISE0 0x58 /* noise source */ +#define GPR_NOISE1 0x59 /* noise source */ +#define GPR_IRQ 0x5a /* IRQ register */ +#define GPR_DBAC 0x5b /* TRAM Delay Base Address Counter */ +#define GPR(x) (FXGPREGBASE + (x)) /* free GPRs: x = 0x00 - 0xff */ +#define ITRAM_DATA(x) (TANKMEMDATAREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */ +#define ETRAM_DATA(x) (TANKMEMDATAREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */ +#define ITRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */ +#define ETRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */ + +#define A_FXBUS(x) (0x00 + (x)) /* x = 0x00 - 0x3f? */ +#define A_EXTIN(x) (0x40 + (x)) /* x = 0x00 - 0x1f? */ +#define A_EXTOUT(x) (0x60 + (x)) /* x = 0x00 - 0x1f? */ +#define A_GPR(x) (A_FXGPREGBASE + (x)) + +/* cc_reg constants */ +#define CC_REG_NORMALIZED C_00000001 +#define CC_REG_BORROW C_00000002 +#define CC_REG_MINUS C_00000004 +#define CC_REG_ZERO C_00000008 +#define CC_REG_SATURATE C_00000010 +#define CC_REG_NONZERO C_00000100 + +/* FX buses */ +#define FXBUS_PCM_LEFT 0x00 +#define FXBUS_PCM_RIGHT 0x01 +#define FXBUS_PCM_LEFT_REAR 0x02 +#define FXBUS_PCM_RIGHT_REAR 0x03 +#define FXBUS_MIDI_LEFT 0x04 +#define FXBUS_MIDI_RIGHT 0x05 +#define FXBUS_PCM_CENTER 0x06 +#define FXBUS_PCM_LFE 0x07 +#define FXBUS_PCM_LEFT_FRONT 0x08 +#define FXBUS_PCM_RIGHT_FRONT 0x09 +#define FXBUS_MIDI_REVERB 0x0c +#define FXBUS_MIDI_CHORUS 0x0d +#define FXBUS_PCM_LEFT_SIDE 0x0e +#define FXBUS_PCM_RIGHT_SIDE 0x0f +#define FXBUS_PT_LEFT 0x14 +#define FXBUS_PT_RIGHT 0x15 + +/* Inputs */ +#define EXTIN_AC97_L 0x00 /* AC'97 capture channel - left */ +#define EXTIN_AC97_R 0x01 /* AC'97 capture channel - right */ +#define EXTIN_SPDIF_CD_L 0x02 /* internal S/PDIF CD - onboard - left */ +#define EXTIN_SPDIF_CD_R 0x03 /* internal S/PDIF CD - onboard - right */ +#define EXTIN_ZOOM_L 0x04 /* Zoom Video I2S - left */ +#define EXTIN_ZOOM_R 0x05 /* Zoom Video I2S - right */ +#define EXTIN_TOSLINK_L 0x06 /* LiveDrive - TOSLink Optical - left */ +#define EXTIN_TOSLINK_R 0x07 /* LiveDrive - TOSLink Optical - right */ +#define EXTIN_LINE1_L 0x08 /* LiveDrive - Line/Mic 1 - left */ +#define EXTIN_LINE1_R 0x09 /* LiveDrive - Line/Mic 1 - right */ +#define EXTIN_COAX_SPDIF_L 0x0a /* LiveDrive - Coaxial S/PDIF - left */ +#define EXTIN_COAX_SPDIF_R 0x0b /* LiveDrive - Coaxial S/PDIF - right */ +#define EXTIN_LINE2_L 0x0c /* LiveDrive - Line/Mic 2 - left */ +#define EXTIN_LINE2_R 0x0d /* LiveDrive - Line/Mic 2 - right */ + +/* Outputs */ +#define EXTOUT_AC97_L 0x00 /* AC'97 playback channel - left */ +#define EXTOUT_AC97_R 0x01 /* AC'97 playback channel - right */ +#define EXTOUT_TOSLINK_L 0x02 /* LiveDrive - TOSLink Optical - left */ +#define EXTOUT_TOSLINK_R 0x03 /* LiveDrive - TOSLink Optical - right */ +#define EXTOUT_AC97_CENTER 0x04 /* SB Live 5.1 - center */ +#define EXTOUT_AC97_LFE 0x05 /* SB Live 5.1 - LFE */ +#define EXTOUT_HEADPHONE_L 0x06 /* LiveDrive - Headphone - left */ +#define EXTOUT_HEADPHONE_R 0x07 /* LiveDrive - Headphone - right */ +#define EXTOUT_REAR_L 0x08 /* Rear channel - left */ +#define EXTOUT_REAR_R 0x09 /* Rear channel - right */ +#define EXTOUT_ADC_CAP_L 0x0a /* ADC Capture buffer - left */ +#define EXTOUT_ADC_CAP_R 0x0b /* ADC Capture buffer - right */ +#define EXTOUT_MIC_CAP 0x0c /* MIC Capture buffer */ +#define EXTOUT_AC97_REAR_L 0x0d /* SB Live 5.1 (c) 2003 - Rear Left */ +#define EXTOUT_AC97_REAR_R 0x0e /* SB Live 5.1 (c) 2003 - Rear Right */ +#define EXTOUT_ACENTER 0x11 /* Analog Center */ +#define EXTOUT_ALFE 0x12 /* Analog LFE */ + +/* Audigy Inputs */ +#define A_EXTIN_AC97_L 0x00 /* AC'97 capture channel - left */ +#define A_EXTIN_AC97_R 0x01 /* AC'97 capture channel - right */ +#define A_EXTIN_SPDIF_CD_L 0x02 /* digital CD left */ +#define A_EXTIN_SPDIF_CD_R 0x03 /* digital CD left */ +#define A_EXTIN_OPT_SPDIF_L 0x04 /* audigy drive Optical SPDIF - left */ +#define A_EXTIN_OPT_SPDIF_R 0x05 /* right */ +#define A_EXTIN_LINE2_L 0x08 /* audigy drive line2/mic2 - left */ +#define A_EXTIN_LINE2_R 0x09 /* right */ +#define A_EXTIN_ADC_L 0x0a /* Philips ADC - left */ +#define A_EXTIN_ADC_R 0x0b /* right */ +#define A_EXTIN_AUX2_L 0x0c /* audigy drive aux2 - left */ +#define A_EXTIN_AUX2_R 0x0d /* - right */ + +/* Audigiy Outputs */ +#define A_EXTOUT_FRONT_L 0x00 /* digital front left */ +#define A_EXTOUT_FRONT_R 0x01 /* right */ +#define A_EXTOUT_CENTER 0x02 /* digital front center */ +#define A_EXTOUT_LFE 0x03 /* digital front lfe */ +#define A_EXTOUT_HEADPHONE_L 0x04 /* headphone audigy drive left */ +#define A_EXTOUT_HEADPHONE_R 0x05 /* right */ +#define A_EXTOUT_REAR_L 0x06 /* digital rear left */ +#define A_EXTOUT_REAR_R 0x07 /* right */ +#define A_EXTOUT_AFRONT_L 0x08 /* analog front left */ +#define A_EXTOUT_AFRONT_R 0x09 /* right */ +#define A_EXTOUT_ACENTER 0x0a /* analog center */ +#define A_EXTOUT_ALFE 0x0b /* analog LFE */ +#define A_EXTOUT_ASIDE_L 0x0c /* analog side left - Audigy 2 ZS */ +#define A_EXTOUT_ASIDE_R 0x0d /* right - Audigy 2 ZS */ +#define A_EXTOUT_AREAR_L 0x0e /* analog rear left */ +#define A_EXTOUT_AREAR_R 0x0f /* right */ +#define A_EXTOUT_AC97_L 0x10 /* AC97 left (front) */ +#define A_EXTOUT_AC97_R 0x11 /* right */ +#define A_EXTOUT_ADC_CAP_L 0x16 /* ADC capture buffer left */ +#define A_EXTOUT_ADC_CAP_R 0x17 /* right */ +#define A_EXTOUT_MIC_CAP 0x18 /* Mic capture buffer */ + +/* Audigy constants */ +#define A_C_00000000 0xc0 +#define A_C_00000001 0xc1 +#define A_C_00000002 0xc2 +#define A_C_00000003 0xc3 +#define A_C_00000004 0xc4 +#define A_C_00000008 0xc5 +#define A_C_00000010 0xc6 +#define A_C_00000020 0xc7 +#define A_C_00000100 0xc8 +#define A_C_00010000 0xc9 +#define A_C_00000800 0xca +#define A_C_10000000 0xcb +#define A_C_20000000 0xcc +#define A_C_40000000 0xcd +#define A_C_80000000 0xce +#define A_C_7fffffff 0xcf +#define A_C_ffffffff 0xd0 +#define A_C_fffffffe 0xd1 +#define A_C_c0000000 0xd2 +#define A_C_4f1bbcdc 0xd3 +#define A_C_5a7ef9db 0xd4 +#define A_C_00100000 0xd5 +#define A_GPR_ACCU 0xd6 /* ACCUM, accumulator */ +#define A_GPR_COND 0xd7 /* CCR, condition register */ +#define A_GPR_NOISE0 0xd8 /* noise source */ +#define A_GPR_NOISE1 0xd9 /* noise source */ +#define A_GPR_IRQ 0xda /* IRQ register */ +#define A_GPR_DBAC 0xdb /* TRAM Delay Base Address Counter - internal */ +#define A_GPR_DBACE 0xde /* TRAM Delay Base Address Counter - external */ + +/* definitions for debug register */ +#define EMU10K1_DBG_ZC 0x80000000 /* zero tram counter */ +#define EMU10K1_DBG_SATURATION_OCCURED 0x02000000 /* saturation control */ +#define EMU10K1_DBG_SATURATION_ADDR 0x01ff0000 /* saturation address */ +#define EMU10K1_DBG_SINGLE_STEP 0x00008000 /* single step mode */ +#define EMU10K1_DBG_STEP 0x00004000 /* start single step */ +#define EMU10K1_DBG_CONDITION_CODE 0x00003e00 /* condition code */ +#define EMU10K1_DBG_SINGLE_STEP_ADDR 0x000001ff /* single step address */ + +/* tank memory address line */ +#ifndef __KERNEL__ +#define TANKMEMADDRREG_ADDR_MASK 0x000fffff /* 20 bit tank address field */ +#define TANKMEMADDRREG_CLEAR 0x00800000 /* Clear tank memory */ +#define TANKMEMADDRREG_ALIGN 0x00400000 /* Align read or write relative to tank access */ +#define TANKMEMADDRREG_WRITE 0x00200000 /* Write to tank memory */ +#define TANKMEMADDRREG_READ 0x00100000 /* Read from tank memory */ +#endif + +typedef struct { + unsigned int internal_tram_size; /* in samples */ + unsigned int external_tram_size; /* in samples */ + char fxbus_names[16][32]; /* names of FXBUSes */ + char extin_names[16][32]; /* names of external inputs */ + char extout_names[32][32]; /* names of external outputs */ + unsigned int gpr_controls; /* count of GPR controls */ +} emu10k1_fx8010_info_t; + +#define EMU10K1_GPR_TRANSLATION_NONE 0 +#define EMU10K1_GPR_TRANSLATION_TABLE100 1 +#define EMU10K1_GPR_TRANSLATION_BASS 2 +#define EMU10K1_GPR_TRANSLATION_TREBLE 3 +#define EMU10K1_GPR_TRANSLATION_ONOFF 4 + +enum emu10k1_ctl_elem_iface { + EMU10K1_CTL_ELEM_IFACE_MIXER = 2, /* virtual mixer device */ + EMU10K1_CTL_ELEM_IFACE_PCM = 3, /* PCM device */ +}; + +typedef struct { + unsigned int pad; /* don't use */ + int iface; /* interface identifier */ + unsigned int device; /* device/client number */ + unsigned int subdevice; /* subdevice (substream) number */ + unsigned char name[44]; /* ASCII name of item */ + unsigned int index; /* index of item */ +} emu10k1_ctl_elem_id_t; + +typedef struct { + emu10k1_ctl_elem_id_t id; /* full control ID definition */ + unsigned int vcount; /* visible count */ + unsigned int count; /* count of GPR (1..16) */ + unsigned short gpr[32]; /* GPR number(s) */ + unsigned int value[32]; /* initial values */ + unsigned int min; /* minimum range */ + unsigned int max; /* maximum range */ + unsigned int translation; /* translation type (EMU10K1_GPR_TRANSLATION*) */ + unsigned int *tlv; +} emu10k1_fx8010_control_gpr_t; + +typedef struct { + char name[128]; + + unsigned long gpr_valid[0x200/(sizeof(unsigned long)*8)]; /* bitmask of valid initializers */ + uint32_t *gpr_map; /* initializers */ + + unsigned int gpr_add_control_count; /* count of GPR controls to add/replace */ + emu10k1_fx8010_control_gpr_t *gpr_add_controls; /* GPR controls to add/replace */ + + unsigned int gpr_del_control_count; /* count of GPR controls to remove */ + emu10k1_ctl_elem_id_t *gpr_del_controls; /* IDs of GPR controls to remove */ + + unsigned int gpr_list_control_count; /* count of GPR controls to list */ + unsigned int gpr_list_control_total; /* total count of GPR controls */ + emu10k1_fx8010_control_gpr_t *gpr_list_controls; /* listed GPR controls */ + + unsigned long tram_valid[0x100/(sizeof(unsigned long)*8)]; /* bitmask of valid initializers */ + uint32_t *tram_data_map; /* data initializers */ + uint32_t *tram_addr_map; /* map initializers */ + + unsigned long code_valid[1024/(sizeof(unsigned long)*8)]; /* bitmask of valid instructions */ + uint32_t *code; /* one instruction - 64 bits */ +} emu10k1_fx8010_code_t; + +typedef struct { + unsigned int address; /* 31.bit == 1 -> external TRAM */ + unsigned int size; /* size in samples (4 bytes) */ + unsigned int *samples; /* pointer to samples (20-bit) */ + /* NULL->clear memory */ +} emu10k1_fx8010_tram_t; + +typedef struct { + unsigned int substream; /* substream number */ + unsigned int res1; /* reserved */ + unsigned int channels; /* 16-bit channels count, zero = remove this substream */ + unsigned int tram_start; /* ring buffer position in TRAM (in samples) */ + unsigned int buffer_size; /* count of buffered samples */ + unsigned short gpr_size; /* GPR containing size of ringbuffer in samples (host) */ + unsigned short gpr_ptr; /* GPR containing current pointer in the ring buffer (host = reset, FX8010) */ + unsigned short gpr_count; /* GPR containing count of samples between two interrupts (host) */ + unsigned short gpr_tmpcount; /* GPR containing current count of samples to interrupt (host = set, FX8010) */ + unsigned short gpr_trigger; /* GPR containing trigger (activate) information (host) */ + unsigned short gpr_running; /* GPR containing info if PCM is running (FX8010) */ + unsigned char pad; /* reserved */ + unsigned char etram[32]; /* external TRAM address & data (one per channel) */ + unsigned int res2; /* reserved */ +} emu10k1_fx8010_pcm_t; + +#define SNDRV_EMU10K1_IOCTL_INFO _IOR ('H', 0x10, emu10k1_fx8010_info_t) +#define SNDRV_EMU10K1_IOCTL_CODE_POKE _IOW ('H', 0x11, emu10k1_fx8010_code_t) +#define SNDRV_EMU10K1_IOCTL_CODE_PEEK _IOWR('H', 0x12, emu10k1_fx8010_code_t) +#define SNDRV_EMU10K1_IOCTL_TRAM_SETUP _IOW ('H', 0x20, int) +#define SNDRV_EMU10K1_IOCTL_TRAM_POKE _IOW ('H', 0x21, emu10k1_fx8010_tram_t) +#define SNDRV_EMU10K1_IOCTL_TRAM_PEEK _IOWR('H', 0x22, emu10k1_fx8010_tram_t) +#define SNDRV_EMU10K1_IOCTL_PCM_POKE _IOW ('H', 0x30, emu10k1_fx8010_pcm_t) +#define SNDRV_EMU10K1_IOCTL_PCM_PEEK _IOWR('H', 0x31, emu10k1_fx8010_pcm_t) +#define SNDRV_EMU10K1_IOCTL_PVERSION _IOR ('H', 0x40, int) +#define SNDRV_EMU10K1_IOCTL_STOP _IO ('H', 0x80) +#define SNDRV_EMU10K1_IOCTL_CONTINUE _IO ('H', 0x81) +#define SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER _IO ('H', 0x82) +#define SNDRV_EMU10K1_IOCTL_SINGLE_STEP _IOW ('H', 0x83, int) +#define SNDRV_EMU10K1_IOCTL_DBG_READ _IOR ('H', 0x84, int) + +#endif /* __SOUND_EMU10K1_H */ diff --git a/thirdparty/linuxbsd_headers/alsa/sound/hdsp.h b/thirdparty/linuxbsd_headers/alsa/sound/hdsp.h new file mode 100644 index 0000000000..5adaf7b0ef --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/sound/hdsp.h @@ -0,0 +1,113 @@ +#ifndef __SOUND_HDSP_H +#define __SOUND_HDSP_H + +/* + * Copyright (C) 2003 Thomas Charbonnel (thomas@undata.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <stdint.h> + +#define HDSP_MATRIX_MIXER_SIZE 2048 + +typedef enum { + Digiface, + Multiface, + H9652, + H9632, + RPM, + Undefined, +} HDSP_IO_Type; + +typedef struct _snd_hdsp_peak_rms hdsp_peak_rms_t; + +struct _snd_hdsp_peak_rms { + uint32_t input_peaks[26]; + uint32_t playback_peaks[26]; + uint32_t output_peaks[28]; + uint64_t input_rms[26]; + uint64_t playback_rms[26]; + /* These are only used for H96xx cards */ + uint64_t output_rms[26]; +}; + +#define SNDRV_HDSP_IOCTL_GET_PEAK_RMS _IOR('H', 0x40, hdsp_peak_rms_t) + +typedef struct _snd_hdsp_config_info hdsp_config_info_t; + +struct _snd_hdsp_config_info { + unsigned char pref_sync_ref; + unsigned char wordclock_sync_check; + unsigned char spdif_sync_check; + unsigned char adatsync_sync_check; + unsigned char adat_sync_check[3]; + unsigned char spdif_in; + unsigned char spdif_out; + unsigned char spdif_professional; + unsigned char spdif_emphasis; + unsigned char spdif_nonaudio; + unsigned int spdif_sample_rate; + unsigned int system_sample_rate; + unsigned int autosync_sample_rate; + unsigned char system_clock_mode; + unsigned char clock_source; + unsigned char autosync_ref; + unsigned char line_out; + unsigned char passthru; + unsigned char da_gain; + unsigned char ad_gain; + unsigned char phone_gain; + unsigned char xlr_breakout_cable; + unsigned char analog_extension_board; +}; + +#define SNDRV_HDSP_IOCTL_GET_CONFIG_INFO _IOR('H', 0x41, hdsp_config_info_t) + +typedef struct _snd_hdsp_firmware hdsp_firmware_t; + +struct _snd_hdsp_firmware { + void *firmware_data; /* 24413 x 4 bytes */ +}; + +#define SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE _IOW('H', 0x42, hdsp_firmware_t) + +typedef struct _snd_hdsp_version hdsp_version_t; + +struct _snd_hdsp_version { + HDSP_IO_Type io_type; + unsigned short firmware_rev; +}; + +#define SNDRV_HDSP_IOCTL_GET_VERSION _IOR('H', 0x43, hdsp_version_t) + +typedef struct _snd_hdsp_mixer hdsp_mixer_t; + +struct _snd_hdsp_mixer { + unsigned short matrix[HDSP_MATRIX_MIXER_SIZE]; +}; + +#define SNDRV_HDSP_IOCTL_GET_MIXER _IOR('H', 0x44, hdsp_mixer_t) + +typedef struct _snd_hdsp_9632_aeb hdsp_9632_aeb_t; + +struct _snd_hdsp_9632_aeb { + int aebi; + int aebo; +}; + +#define SNDRV_HDSP_IOCTL_GET_9632_AEB _IOR('H', 0x45, hdsp_9632_aeb_t) + +#endif /* __SOUND_HDSP_H */ diff --git a/thirdparty/linuxbsd_headers/alsa/sound/hdspm.h b/thirdparty/linuxbsd_headers/alsa/sound/hdspm.h new file mode 100644 index 0000000000..fe9c5f695f --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/sound/hdspm.h @@ -0,0 +1,229 @@ +#ifndef __SOUND_HDSPM_H +#define __SOUND_HDSPM_H +/* + * Copyright (C) 2003 Winfried Ritsch (IEM) + * based on hdsp.h from Thomas Charbonnel (thomas@undata.org) + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* Maximum channels is 64 even on 56Mode you have 64playbacks to matrix */ +#define HDSPM_MAX_CHANNELS 64 + +enum hdspm_io_type { + MADI, + MADIface, + AIO, + AES32, + RayDAT +}; + +enum hdspm_speed { + ss, + ds, + qs +}; + +/* -------------------- IOCTL Peak/RMS Meters -------------------- */ + +struct hdspm_peak_rms { + uint32_t input_peaks[64]; + uint32_t playback_peaks[64]; + uint32_t output_peaks[64]; + + uint64_t input_rms[64]; + uint64_t playback_rms[64]; + uint64_t output_rms[64]; + + uint8_t speed; /* enum {ss, ds, qs} */ + int status2; +}; + +#define SNDRV_HDSPM_IOCTL_GET_PEAK_RMS \ + _IOR('H', 0x42, struct hdspm_peak_rms) + +/* ------------ CONFIG block IOCTL ---------------------- */ + +struct hdspm_config { + unsigned char pref_sync_ref; + unsigned char wordclock_sync_check; + unsigned char madi_sync_check; + unsigned int system_sample_rate; + unsigned int autosync_sample_rate; + unsigned char system_clock_mode; + unsigned char clock_source; + unsigned char autosync_ref; + unsigned char line_out; + unsigned int passthru; + unsigned int analog_out; +}; + +#define SNDRV_HDSPM_IOCTL_GET_CONFIG \ + _IOR('H', 0x41, struct hdspm_config) + +/** + * If there's a TCO (TimeCode Option) board installed, + * there are further options and status data available. + * The hdspm_ltc structure contains the current SMPTE + * timecode and some status information and can be + * obtained via SNDRV_HDSPM_IOCTL_GET_LTC or in the + * hdspm_status struct. + **/ + +enum hdspm_ltc_format { + format_invalid, + fps_24, + fps_25, + fps_2997, + fps_30 +}; + +enum hdspm_ltc_frame { + frame_invalid, + drop_frame, + full_frame +}; + +enum hdspm_ltc_input_format { + ntsc, + pal, + no_video +}; + +struct hdspm_ltc { + unsigned int ltc; + + enum hdspm_ltc_format format; + enum hdspm_ltc_frame frame; + enum hdspm_ltc_input_format input_format; +}; + +#define SNDRV_HDSPM_IOCTL_GET_LTC _IOR('H', 0x46, struct hdspm_ltc) + +/** + * The status data reflects the device's current state + * as determined by the card's configuration and + * connection status. + **/ + +enum hdspm_sync { + hdspm_sync_no_lock = 0, + hdspm_sync_lock = 1, + hdspm_sync_sync = 2 +}; + +enum hdspm_madi_input { + hdspm_input_optical = 0, + hdspm_input_coax = 1 +}; + +enum hdspm_madi_channel_format { + hdspm_format_ch_64 = 0, + hdspm_format_ch_56 = 1 +}; + +enum hdspm_madi_frame_format { + hdspm_frame_48 = 0, + hdspm_frame_96 = 1 +}; + +enum hdspm_syncsource { + syncsource_wc = 0, + syncsource_madi = 1, + syncsource_tco = 2, + syncsource_sync = 3, + syncsource_none = 4 +}; + +struct hdspm_status { + uint8_t card_type; /* enum hdspm_io_type */ + enum hdspm_syncsource autosync_source; + + uint64_t card_clock; + uint32_t master_period; + + union { + struct { + uint8_t sync_wc; /* enum hdspm_sync */ + uint8_t sync_madi; /* enum hdspm_sync */ + uint8_t sync_tco; /* enum hdspm_sync */ + uint8_t sync_in; /* enum hdspm_sync */ + uint8_t madi_input; /* enum hdspm_madi_input */ + uint8_t channel_format; /* enum hdspm_madi_channel_format */ + uint8_t frame_format; /* enum hdspm_madi_frame_format */ + } madi; + } card_specific; +}; + +#define SNDRV_HDSPM_IOCTL_GET_STATUS \ + _IOR('H', 0x47, struct hdspm_status) + +/** + * Get information about the card and its add-ons. + **/ + +#define HDSPM_ADDON_TCO 1 + +struct hdspm_version { + uint8_t card_type; /* enum hdspm_io_type */ + char cardname[20]; + unsigned int serial; + unsigned short firmware_rev; + int addons; +}; + +#define SNDRV_HDSPM_IOCTL_GET_VERSION _IOR('H', 0x48, struct hdspm_version) + +/* ------------- get Matrix Mixer IOCTL --------------- */ + +/* MADI mixer: 64inputs+64playback in 64outputs = 8192 => *4Byte = + * 32768 Bytes + */ + +/* organisation is 64 channelfader in a continous memory block */ +/* equivalent to hardware definition, maybe for future feature of mmap of + * them + */ +/* each of 64 outputs has 64 infader and 64 outfader: + Ins to Outs mixer[out].in[in], Outstreams to Outs mixer[out].pb[pb] */ + +#define HDSPM_MIXER_CHANNELS HDSPM_MAX_CHANNELS + +struct hdspm_channelfader { + unsigned int in[HDSPM_MIXER_CHANNELS]; + unsigned int pb[HDSPM_MIXER_CHANNELS]; +}; + +struct hdspm_mixer { + struct hdspm_channelfader ch[HDSPM_MIXER_CHANNELS]; +}; + +struct hdspm_mixer_ioctl { + struct hdspm_mixer *mixer; +}; + +/* use indirect access due to the limit of ioctl bit size */ +#define SNDRV_HDSPM_IOCTL_GET_MIXER _IOR('H', 0x44, struct hdspm_mixer_ioctl) + +/* typedefs for compatibility to user-space */ +typedef struct hdspm_peak_rms hdspm_peak_rms_t; +typedef struct hdspm_config_info hdspm_config_info_t; +typedef struct hdspm_version hdspm_version_t; +typedef struct hdspm_channelfader snd_hdspm_channelfader_t; +typedef struct hdspm_mixer hdspm_mixer_t; + + +#endif diff --git a/thirdparty/linuxbsd_headers/alsa/sound/sb16_csp.h b/thirdparty/linuxbsd_headers/alsa/sound/sb16_csp.h new file mode 100644 index 0000000000..78817b40c0 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/sound/sb16_csp.h @@ -0,0 +1,115 @@ +#ifndef __SOUND_SB16_CSP_H +#define __SOUND_SB16_CSP_H + +/* + * Copyright (c) 1999 by Uros Bizjak <uros@kss-loka.si> + * Takashi Iwai <tiwai@suse.de> + * + * SB16ASP/AWE32 CSP control + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* CSP modes */ +#define SNDRV_SB_CSP_MODE_NONE 0x00 +#define SNDRV_SB_CSP_MODE_DSP_READ 0x01 /* Record from DSP */ +#define SNDRV_SB_CSP_MODE_DSP_WRITE 0x02 /* Play to DSP */ +#define SNDRV_SB_CSP_MODE_QSOUND 0x04 /* QSound */ + +/* CSP load flags */ +#define SNDRV_SB_CSP_LOAD_FROMUSER 0x01 +#define SNDRV_SB_CSP_LOAD_INITBLOCK 0x02 + +/* CSP sample width */ +#define SNDRV_SB_CSP_SAMPLE_8BIT 0x01 +#define SNDRV_SB_CSP_SAMPLE_16BIT 0x02 + +/* CSP channels */ +#define SNDRV_SB_CSP_MONO 0x01 +#define SNDRV_SB_CSP_STEREO 0x02 + +/* CSP rates */ +#define SNDRV_SB_CSP_RATE_8000 0x01 +#define SNDRV_SB_CSP_RATE_11025 0x02 +#define SNDRV_SB_CSP_RATE_22050 0x04 +#define SNDRV_SB_CSP_RATE_44100 0x08 +#define SNDRV_SB_CSP_RATE_ALL 0x0f + +/* CSP running state */ +#define SNDRV_SB_CSP_ST_IDLE 0x00 +#define SNDRV_SB_CSP_ST_LOADED 0x01 +#define SNDRV_SB_CSP_ST_RUNNING 0x02 +#define SNDRV_SB_CSP_ST_PAUSED 0x04 +#define SNDRV_SB_CSP_ST_AUTO 0x08 +#define SNDRV_SB_CSP_ST_QSOUND 0x10 + +/* maximum QSound value (180 degrees right) */ +#define SNDRV_SB_CSP_QSOUND_MAX_RIGHT 0x20 + +/* maximum microcode RIFF file size */ +#define SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE 0x3000 + +/* microcode header */ +typedef struct snd_sb_csp_mc_header { + char codec_name[16]; /* id name of codec */ + unsigned short func_req; /* requested function */ +} snd_sb_csp_mc_header_t; + +/* microcode to be loaded */ +typedef struct snd_sb_csp_microcode { + snd_sb_csp_mc_header_t info; + unsigned char data[SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE]; +} snd_sb_csp_microcode_t; + +/* start CSP with sample_width in mono/stereo */ +typedef struct snd_sb_csp_start { + int sample_width; /* sample width, look above */ + int channels; /* channels, look above */ +} snd_sb_csp_start_t; + +/* CSP information */ +typedef struct snd_sb_csp_info { + char codec_name[16]; /* id name of codec */ + unsigned short func_nr; /* function number */ + unsigned int acc_format; /* accepted PCM formats */ + unsigned short acc_channels; /* accepted channels */ + unsigned short acc_width; /* accepted sample width */ + unsigned short acc_rates; /* accepted sample rates */ + unsigned short csp_mode; /* CSP mode, see above */ + unsigned short run_channels; /* current channels */ + unsigned short run_width; /* current sample width */ + unsigned short version; /* version id: 0x10 - 0x1f */ + unsigned short state; /* state bits */ +} snd_sb_csp_info_t; + +/* HWDEP controls */ +/* get CSP information */ +#define SNDRV_SB_CSP_IOCTL_INFO _IOR('H', 0x10, snd_sb_csp_info_t) +/* load microcode to CSP */ +#define SNDRV_SB_CSP_IOCTL_LOAD_CODE _IOW('H', 0x11, snd_sb_csp_microcode_t) +/* unload microcode from CSP */ +#define SNDRV_SB_CSP_IOCTL_UNLOAD_CODE _IO('H', 0x12) +/* start CSP */ +#define SNDRV_SB_CSP_IOCTL_START _IOW('H', 0x13, snd_sb_csp_start_t) +/* stop CSP */ +#define SNDRV_SB_CSP_IOCTL_STOP _IO('H', 0x14) +/* pause CSP and DMA transfer */ +#define SNDRV_SB_CSP_IOCTL_PAUSE _IO('H', 0x15) +/* restart CSP and DMA transfer */ +#define SNDRV_SB_CSP_IOCTL_RESTART _IO('H', 0x16) + + +#endif /* __SOUND_SB16_CSP */ diff --git a/thirdparty/linuxbsd_headers/alsa/sound/sscape_ioctl.h b/thirdparty/linuxbsd_headers/alsa/sound/sscape_ioctl.h new file mode 100644 index 0000000000..c6653ebfb2 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/sound/sscape_ioctl.h @@ -0,0 +1,21 @@ +#ifndef SSCAPE_IOCTL_H +#define SSCAPE_IOCTL_H + + +struct sscape_bootblock +{ + unsigned char code[256]; + unsigned version; +}; + +#define SSCAPE_MICROCODE_SIZE 65536 + +struct sscape_microcode +{ + unsigned char *code; +}; + +#define SND_SSCAPE_LOAD_BOOTB _IOWR('P', 100, struct sscape_bootblock) +#define SND_SSCAPE_LOAD_MCODE _IOW ('P', 101, struct sscape_microcode) + +#endif diff --git a/thirdparty/linuxbsd_headers/alsa/sound/tlv.h b/thirdparty/linuxbsd_headers/alsa/sound/tlv.h new file mode 100644 index 0000000000..b4df440c01 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/sound/tlv.h @@ -0,0 +1,100 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __UAPI_SOUND_TLV_H +#define __UAPI_SOUND_TLV_H + +#define SNDRV_CTL_TLVT_CONTAINER 0 /* one level down - group of TLVs */ +#define SNDRV_CTL_TLVT_DB_SCALE 1 /* dB scale */ +#define SNDRV_CTL_TLVT_DB_LINEAR 2 /* linear volume */ +#define SNDRV_CTL_TLVT_DB_RANGE 3 /* dB range container */ +#define SNDRV_CTL_TLVT_DB_MINMAX 4 /* dB scale with min/max */ +#define SNDRV_CTL_TLVT_DB_MINMAX_MUTE 5 /* dB scale with min/max with mute */ + +/* + * channel-mapping TLV items + * TLV length must match with num_channels + */ +#define SNDRV_CTL_TLVT_CHMAP_FIXED 0x101 /* fixed channel position */ +#define SNDRV_CTL_TLVT_CHMAP_VAR 0x102 /* channels freely swappable */ +#define SNDRV_CTL_TLVT_CHMAP_PAIRED 0x103 /* pair-wise swappable */ + +/* + * TLV structure is right behind the struct snd_ctl_tlv: + * unsigned int type - see SNDRV_CTL_TLVT_* + * unsigned int length + * .... data aligned to sizeof(unsigned int), use + * block_length = (length + (sizeof(unsigned int) - 1)) & + * ~(sizeof(unsigned int) - 1)) .... + */ +#define SNDRV_CTL_TLVD_ITEM(type, ...) \ + (type), SNDRV_CTL_TLVD_LENGTH(__VA_ARGS__), __VA_ARGS__ +#define SNDRV_CTL_TLVD_LENGTH(...) \ + ((unsigned int)sizeof((const unsigned int[]) { __VA_ARGS__ })) + +#define SNDRV_CTL_TLVD_CONTAINER_ITEM(...) \ + SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_CONTAINER, __VA_ARGS__) +#define SNDRV_CTL_TLVD_DECLARE_CONTAINER(name, ...) \ + unsigned int name[] = { \ + SNDRV_CTL_TLVD_CONTAINER_ITEM(__VA_ARGS__) \ + } + +#define SNDRV_CTL_TLVD_DB_SCALE_MASK 0xffff +#define SNDRV_CTL_TLVD_DB_SCALE_MUTE 0x10000 +#define SNDRV_CTL_TLVD_DB_SCALE_ITEM(min, step, mute) \ + SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_SCALE, \ + (min), \ + ((step) & SNDRV_CTL_TLVD_DB_SCALE_MASK) | \ + ((mute) ? SNDRV_CTL_TLVD_DB_SCALE_MUTE : 0)) +#define SNDRV_CTL_TLVD_DECLARE_DB_SCALE(name, min, step, mute) \ + unsigned int name[] = { \ + SNDRV_CTL_TLVD_DB_SCALE_ITEM(min, step, mute) \ + } + +/* dB scale specified with min/max values instead of step */ +#define SNDRV_CTL_TLVD_DB_MINMAX_ITEM(min_dB, max_dB) \ + SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_MINMAX, (min_dB), (max_dB)) +#define SNDRV_CTL_TLVD_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) \ + SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_MINMAX_MUTE, (min_dB), (max_dB)) +#define SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(name, min_dB, max_dB) \ + unsigned int name[] = { \ + SNDRV_CTL_TLVD_DB_MINMAX_ITEM(min_dB, max_dB) \ + } +#define SNDRV_CTL_TLVD_DECLARE_DB_MINMAX_MUTE(name, min_dB, max_dB) \ + unsigned int name[] = { \ + SNDRV_CTL_TLVD_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) \ + } + +/* linear volume between min_dB and max_dB (.01dB unit) */ +#define SNDRV_CTL_TLVD_DB_LINEAR_ITEM(min_dB, max_dB) \ + SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_LINEAR, (min_dB), (max_dB)) +#define SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(name, min_dB, max_dB) \ + unsigned int name[] = { \ + SNDRV_CTL_TLVD_DB_LINEAR_ITEM(min_dB, max_dB) \ + } + +/* dB range container: + * Items in dB range container must be ordered by their values and by their + * dB values. This implies that larger values must correspond with larger + * dB values (which is also required for all other mixer controls). + */ +/* Each item is: <min> <max> <TLV> */ +#define SNDRV_CTL_TLVD_DB_RANGE_ITEM(...) \ + SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_RANGE, __VA_ARGS__) +#define SNDRV_CTL_TLVD_DECLARE_DB_RANGE(name, ...) \ + unsigned int name[] = { \ + SNDRV_CTL_TLVD_DB_RANGE_ITEM(__VA_ARGS__) \ + } + +#define SNDRV_CTL_TLVD_DB_GAIN_MUTE -9999999 + +#endif diff --git a/thirdparty/linuxbsd_headers/alsa/sound/type_compat.h b/thirdparty/linuxbsd_headers/alsa/sound/type_compat.h new file mode 100644 index 0000000000..e973ff3139 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/sound/type_compat.h @@ -0,0 +1,42 @@ +#ifndef __TYPE_COMPAT_H +#define __TYPE_COMPAT_H + +#ifndef DOC_HIDDEN +#include <stdint.h> +typedef uint8_t __u8; +typedef uint16_t __u16; +typedef uint32_t __u32; +typedef int8_t __s8; +typedef int16_t __s16; +typedef int32_t __s32; + +#include <endian.h> +#include <byteswap.h> +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define __cpu_to_le32(x) (x) +#define __cpu_to_be32(x) bswap_32(x) +#define __cpu_to_le16(x) (x) +#define __cpu_to_be16(x) bswap_16(x) +#else +#define __cpu_to_le32(x) bswap_32(x) +#define __cpu_to_be32(x) (x) +#define __cpu_to_le16(x) bswap_16(x) +#define __cpu_to_be16(x) (x) +#endif + +#define __le32_to_cpu __cpu_to_le32 +#define __be32_to_cpu __cpu_to_be32 +#define __le16_to_cpu __cpu_to_le16 +#define __be16_to_cpu __cpu_to_be16 + +#define __le64 __u64 +#define __le32 __u32 +#define __le16 __u16 +#define __le8 __u8 +#define __be64 __u64 +#define __be32 __u32 +#define __be16 __u16 +#define __be8 __u8 +#endif /* DOC_HIDDEN */ + +#endif /* __TYPE_COMPAT_H */ diff --git a/thirdparty/linuxbsd_headers/alsa/timer.h b/thirdparty/linuxbsd_headers/alsa/timer.h new file mode 100644 index 0000000000..2803f53273 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/timer.h @@ -0,0 +1,259 @@ +/** + * \file include/timer.h + * \brief Application interface library for the ALSA driver + * \author Jaroslav Kysela <perex@perex.cz> + * \author Abramo Bagnara <abramo@alsa-project.org> + * \author Takashi Iwai <tiwai@suse.de> + * \date 1998-2001 + * + * Application interface library for the ALSA driver + */ +/* + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ALSA_TIMER_H +#define __ALSA_TIMER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup Timer Timer Interface + * Timer Interface. See \ref timer page for more details. + * \{ + */ + +/** dlsym version for interface entry callback */ +#define SND_TIMER_DLSYM_VERSION _dlsym_timer_001 +/** dlsym version for interface entry callback */ +#define SND_TIMER_QUERY_DLSYM_VERSION _dlsym_timer_query_001 + +/** timer identification structure */ +typedef struct _snd_timer_id snd_timer_id_t; +/** timer global info structure */ +typedef struct _snd_timer_ginfo snd_timer_ginfo_t; +/** timer global params structure */ +typedef struct _snd_timer_gparams snd_timer_gparams_t; +/** timer global status structure */ +typedef struct _snd_timer_gstatus snd_timer_gstatus_t; +/** timer info structure */ +typedef struct _snd_timer_info snd_timer_info_t; +/** timer params structure */ +typedef struct _snd_timer_params snd_timer_params_t; +/** timer status structure */ +typedef struct _snd_timer_status snd_timer_status_t; +/** timer master class */ +typedef enum _snd_timer_class { + SND_TIMER_CLASS_NONE = -1, /**< invalid */ + SND_TIMER_CLASS_SLAVE = 0, /**< slave timer */ + SND_TIMER_CLASS_GLOBAL, /**< global timer */ + SND_TIMER_CLASS_CARD, /**< card timer */ + SND_TIMER_CLASS_PCM, /**< PCM timer */ + SND_TIMER_CLASS_LAST = SND_TIMER_CLASS_PCM /**< last timer */ +} snd_timer_class_t; + +/** timer slave class */ +typedef enum _snd_timer_slave_class { + SND_TIMER_SCLASS_NONE = 0, /**< none */ + SND_TIMER_SCLASS_APPLICATION, /**< for internal use */ + SND_TIMER_SCLASS_SEQUENCER, /**< sequencer timer */ + SND_TIMER_SCLASS_OSS_SEQUENCER, /**< OSS sequencer timer */ + SND_TIMER_SCLASS_LAST = SND_TIMER_SCLASS_OSS_SEQUENCER /**< last slave timer */ +} snd_timer_slave_class_t; + +/** timer read event identification */ +typedef enum _snd_timer_event { + SND_TIMER_EVENT_RESOLUTION = 0, /* val = resolution in ns */ + SND_TIMER_EVENT_TICK, /* val = ticks */ + SND_TIMER_EVENT_START, /* val = resolution in ns */ + SND_TIMER_EVENT_STOP, /* val = 0 */ + SND_TIMER_EVENT_CONTINUE, /* val = resolution in ns */ + SND_TIMER_EVENT_PAUSE, /* val = 0 */ + SND_TIMER_EVENT_EARLY, /* val = 0 */ + SND_TIMER_EVENT_SUSPEND, /* val = 0 */ + SND_TIMER_EVENT_RESUME, /* val = resolution in ns */ + /* master timer events for slave timer instances */ + SND_TIMER_EVENT_MSTART = SND_TIMER_EVENT_START + 10, + SND_TIMER_EVENT_MSTOP = SND_TIMER_EVENT_STOP + 10, + SND_TIMER_EVENT_MCONTINUE = SND_TIMER_EVENT_CONTINUE + 10, + SND_TIMER_EVENT_MPAUSE = SND_TIMER_EVENT_PAUSE + 10, + SND_TIMER_EVENT_MSUSPEND = SND_TIMER_EVENT_SUSPEND + 10, + SND_TIMER_EVENT_MRESUME = SND_TIMER_EVENT_RESUME + 10 +} snd_timer_event_t; + +/** timer read structure */ +typedef struct _snd_timer_read { + unsigned int resolution; /**< tick resolution in nanoseconds */ + unsigned int ticks; /**< count of happened ticks */ +} snd_timer_read_t; + +/** timer tstamp + event read structure */ +typedef struct _snd_timer_tread { + snd_timer_event_t event; /**< Timer event */ + snd_htimestamp_t tstamp; /**< Time stamp of each event */ + unsigned int val; /**< Event value */ +} snd_timer_tread_t; + +/** global timer - system */ +#define SND_TIMER_GLOBAL_SYSTEM 0 +/** global timer - RTC */ +#define SND_TIMER_GLOBAL_RTC 1 +/** global timer - HPET */ +#define SND_TIMER_GLOBAL_HPET 2 +/** global timer - HRTIMER */ +#define SND_TIMER_GLOBAL_HRTIMER 3 + +/** timer open mode flag - non-blocking behaviour */ +#define SND_TIMER_OPEN_NONBLOCK (1<<0) +/** use timestamps and event notification - enhanced read */ +#define SND_TIMER_OPEN_TREAD (1<<1) + +/** timer handle type */ +typedef enum _snd_timer_type { + /** Kernel level HwDep */ + SND_TIMER_TYPE_HW = 0, + /** Shared memory client timer (not yet implemented) */ + SND_TIMER_TYPE_SHM, + /** INET client timer (not yet implemented) */ + SND_TIMER_TYPE_INET +} snd_timer_type_t; + +/** timer query handle */ +typedef struct _snd_timer_query snd_timer_query_t; +/** timer handle */ +typedef struct _snd_timer snd_timer_t; + + +int snd_timer_query_open(snd_timer_query_t **handle, const char *name, int mode); +int snd_timer_query_open_lconf(snd_timer_query_t **handle, const char *name, int mode, snd_config_t *lconf); +int snd_timer_query_close(snd_timer_query_t *handle); +int snd_timer_query_next_device(snd_timer_query_t *handle, snd_timer_id_t *tid); +int snd_timer_query_info(snd_timer_query_t *handle, snd_timer_ginfo_t *info); +int snd_timer_query_params(snd_timer_query_t *handle, snd_timer_gparams_t *params); +int snd_timer_query_status(snd_timer_query_t *handle, snd_timer_gstatus_t *status); + +int snd_timer_open(snd_timer_t **handle, const char *name, int mode); +int snd_timer_open_lconf(snd_timer_t **handle, const char *name, int mode, snd_config_t *lconf); +int snd_timer_close(snd_timer_t *handle); +int snd_async_add_timer_handler(snd_async_handler_t **handler, snd_timer_t *timer, + snd_async_callback_t callback, void *private_data); +snd_timer_t *snd_async_handler_get_timer(snd_async_handler_t *handler); +int snd_timer_poll_descriptors_count(snd_timer_t *handle); +int snd_timer_poll_descriptors(snd_timer_t *handle, struct pollfd *pfds, unsigned int space); +int snd_timer_poll_descriptors_revents(snd_timer_t *timer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); +int snd_timer_info(snd_timer_t *handle, snd_timer_info_t *timer); +int snd_timer_params(snd_timer_t *handle, snd_timer_params_t *params); +int snd_timer_status(snd_timer_t *handle, snd_timer_status_t *status); +int snd_timer_start(snd_timer_t *handle); +int snd_timer_stop(snd_timer_t *handle); +int snd_timer_continue(snd_timer_t *handle); +ssize_t snd_timer_read(snd_timer_t *handle, void *buffer, size_t size); + +size_t snd_timer_id_sizeof(void); +/** allocate #snd_timer_id_t container on stack */ +#define snd_timer_id_alloca(ptr) __snd_alloca(ptr, snd_timer_id) +int snd_timer_id_malloc(snd_timer_id_t **ptr); +void snd_timer_id_free(snd_timer_id_t *obj); +void snd_timer_id_copy(snd_timer_id_t *dst, const snd_timer_id_t *src); + +void snd_timer_id_set_class(snd_timer_id_t *id, int dev_class); +int snd_timer_id_get_class(snd_timer_id_t *id); +void snd_timer_id_set_sclass(snd_timer_id_t *id, int dev_sclass); +int snd_timer_id_get_sclass(snd_timer_id_t *id); +void snd_timer_id_set_card(snd_timer_id_t *id, int card); +int snd_timer_id_get_card(snd_timer_id_t *id); +void snd_timer_id_set_device(snd_timer_id_t *id, int device); +int snd_timer_id_get_device(snd_timer_id_t *id); +void snd_timer_id_set_subdevice(snd_timer_id_t *id, int subdevice); +int snd_timer_id_get_subdevice(snd_timer_id_t *id); + +size_t snd_timer_ginfo_sizeof(void); +/** allocate #snd_timer_ginfo_t container on stack */ +#define snd_timer_ginfo_alloca(ptr) __snd_alloca(ptr, snd_timer_ginfo) +int snd_timer_ginfo_malloc(snd_timer_ginfo_t **ptr); +void snd_timer_ginfo_free(snd_timer_ginfo_t *obj); +void snd_timer_ginfo_copy(snd_timer_ginfo_t *dst, const snd_timer_ginfo_t *src); + +int snd_timer_ginfo_set_tid(snd_timer_ginfo_t *obj, snd_timer_id_t *tid); +snd_timer_id_t *snd_timer_ginfo_get_tid(snd_timer_ginfo_t *obj); +unsigned int snd_timer_ginfo_get_flags(snd_timer_ginfo_t *obj); +int snd_timer_ginfo_get_card(snd_timer_ginfo_t *obj); +char *snd_timer_ginfo_get_id(snd_timer_ginfo_t *obj); +char *snd_timer_ginfo_get_name(snd_timer_ginfo_t *obj); +unsigned long snd_timer_ginfo_get_resolution(snd_timer_ginfo_t *obj); +unsigned long snd_timer_ginfo_get_resolution_min(snd_timer_ginfo_t *obj); +unsigned long snd_timer_ginfo_get_resolution_max(snd_timer_ginfo_t *obj); +unsigned int snd_timer_ginfo_get_clients(snd_timer_ginfo_t *obj); + +size_t snd_timer_info_sizeof(void); +/** allocate #snd_timer_info_t container on stack */ +#define snd_timer_info_alloca(ptr) __snd_alloca(ptr, snd_timer_info) +int snd_timer_info_malloc(snd_timer_info_t **ptr); +void snd_timer_info_free(snd_timer_info_t *obj); +void snd_timer_info_copy(snd_timer_info_t *dst, const snd_timer_info_t *src); + +int snd_timer_info_is_slave(snd_timer_info_t * info); +int snd_timer_info_get_card(snd_timer_info_t * info); +const char *snd_timer_info_get_id(snd_timer_info_t * info); +const char *snd_timer_info_get_name(snd_timer_info_t * info); +long snd_timer_info_get_resolution(snd_timer_info_t * info); + +size_t snd_timer_params_sizeof(void); +/** allocate #snd_timer_params_t container on stack */ +#define snd_timer_params_alloca(ptr) __snd_alloca(ptr, snd_timer_params) +int snd_timer_params_malloc(snd_timer_params_t **ptr); +void snd_timer_params_free(snd_timer_params_t *obj); +void snd_timer_params_copy(snd_timer_params_t *dst, const snd_timer_params_t *src); + +int snd_timer_params_set_auto_start(snd_timer_params_t * params, int auto_start); +int snd_timer_params_get_auto_start(snd_timer_params_t * params); +int snd_timer_params_set_exclusive(snd_timer_params_t * params, int exclusive); +int snd_timer_params_get_exclusive(snd_timer_params_t * params); +int snd_timer_params_set_early_event(snd_timer_params_t * params, int early_event); +int snd_timer_params_get_early_event(snd_timer_params_t * params); +void snd_timer_params_set_ticks(snd_timer_params_t * params, long ticks); +long snd_timer_params_get_ticks(snd_timer_params_t * params); +void snd_timer_params_set_queue_size(snd_timer_params_t * params, long queue_size); +long snd_timer_params_get_queue_size(snd_timer_params_t * params); +void snd_timer_params_set_filter(snd_timer_params_t * params, unsigned int filter); +unsigned int snd_timer_params_get_filter(snd_timer_params_t * params); + +size_t snd_timer_status_sizeof(void); +/** allocate #snd_timer_status_t container on stack */ +#define snd_timer_status_alloca(ptr) __snd_alloca(ptr, snd_timer_status) +int snd_timer_status_malloc(snd_timer_status_t **ptr); +void snd_timer_status_free(snd_timer_status_t *obj); +void snd_timer_status_copy(snd_timer_status_t *dst, const snd_timer_status_t *src); + +snd_htimestamp_t snd_timer_status_get_timestamp(snd_timer_status_t * status); +long snd_timer_status_get_resolution(snd_timer_status_t * status); +long snd_timer_status_get_lost(snd_timer_status_t * status); +long snd_timer_status_get_overrun(snd_timer_status_t * status); +long snd_timer_status_get_queue(snd_timer_status_t * status); + +/* deprecated functions, for compatibility */ +long snd_timer_info_get_ticks(snd_timer_info_t * info); + +/** \} */ + +#ifdef __cplusplus +} +#endif + +#endif /** __ALSA_TIMER_H */ + diff --git a/thirdparty/linuxbsd_headers/alsa/topology.h b/thirdparty/linuxbsd_headers/alsa/topology.h new file mode 100644 index 0000000000..593eaa6155 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/topology.h @@ -0,0 +1,1096 @@ +/* + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Copyright (C) 2015 Intel Corporation + * + */ + +#ifndef __ALSA_TOPOLOGY_H +#define __ALSA_TOPOLOGY_H + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup topology Topology Interface + * \{ + */ + +/*! \page topology ALSA Topology Interface + * + * The topology interface allows developers to define DSP topologies in a text + * file format and to convert the text topology to a binary topology + * representation that can be understood by the kernel. The topology core + * currently recognises the following object types :- + * + * * Controls (mixer, enumerated and byte) including TLV data. + * * PCMs (Front End DAI & DAI link) + * * DAPM widgets + * * DAPM graph elements. + * * Physical DAI & DAI links + * * Private data for each object type. + * * Manifest (containing count of each object type) + * + * <h3>Topology File Format</h3> + * + * The topology text format uses the standard ALSA configuration file format to + * describe each topology object type. This allows topology objects to include + * other topology objects as part of their definition. i.e. a TLV data object + * can be shared amongst many control objects that use the same TLV data. + * + * + * <h4>Controls</h4> + * Topology audio controls can belong to three different types :- + * * Mixer control + * * Enumerated control + * * Byte control + * + * Each control type can contain TLV data, private data, operations and also + * belong to widget objects.<br> + * + * <h5>Control Operations</h5> + * Driver Kcontrol callback info(), get() and put() operations are mapped with + * the CTL ops section in topology configuration files. The ctl ops section can + * assign operations using the standard names (listed below) for the standard + * kcontrol types or use ID numbers (>256) to map to bespoke driver controls.<br> + * + * <pre> + * + * ops."ctl" { + * info "volsw" + * get "257" + * put "257" + * } + * + * </pre> + * + * This mapping shows info() using the standard "volsw" info callback whilst + * the get() and put() are mapped to bespoke driver callbacks. <br> + * + * The Standard operations names for control get(), put() and info calls + * are :- + * * volsw + * * volsw_sx + * * volsw_xr_sx + * * enum + * * bytes + * * enum_value + * * range + * * strobe + * +* <h5>Control Access</h5> + * Controls access can be specified using the "access" section. If no "access" + * section is defined then default RW access flags are set for normal and TLV + * controls. + * + * <pre> + * access [ + * read + * write + * tlv_command + * ] + * </pre> + * + * The standard access flags are as follows :- + * * read + * * write + * * read_write + * * volatile + * * timestamp + * * tlv_read + * * tlv_write + * * tlv_read_write + * * tlv_command + * * inactive + * * lock + * * owner + * * tlv_callback + * * user + * + * <h5>Control TLV Data</h5> + * Controls can also use TLV data to represent dB information. This can be done + * by defining a TLV section and using the TLV section within the control. + * The TLV data for DBScale types are defined as follows :- + * + * <pre> + * scale { + * min "-9000" + * step "300" + * mute "1" + * } + * </pre> + * + * Where the meanings and values for min, step and mute are exactly the same + * as defined in driver code. + * + * <h5>Control Channel Mapping</h5> + * Controls can also specify which channels they are mapped with. This is useful + * for userspace as it allows applications to determine the correct control + * channel for Left and Right etc. Channel maps are defined as follows :- + * + * <pre> + * channel."name" { + * reg "0" + * shift "0" + * } + * </pre> + * + * The channel map reg is the register offset for the control, shift is the + * bit shift within the register for the channel and the section name is the + * channel name and can be one of the following :- + * + * <pre> + * * mono # mono stream + * * fl # front left + * * fr # front right + * * rl # rear left + * * rr # rear right + * * fc # front center + * * lfe # LFE + * * sl # side left + * * sr # side right + * * rc # rear center + * * flc # front left center + * * frc # front right center + * * rlc # rear left center + * * rrc # rear right center + * * flw # front left wide + * * frw # front right wide + * * flh # front left high + * * fch # front center high + * * frh # front right high + * * tc # top center + * * tfl # top front left + * * tfr # top front right + * * tfc # top front center + * * trl # top rear left + * * trr # top rear right + * * trc # top rear center + * * tflc # top front left center + * * tfrc # top front right center + * * tsl # top side left + * * tsr # top side right + * * llfe # left LFE + * * rlfe # right LFE + * * bc # bottom center + * * blc # bottom left center + * * brc # bottom right center + * </pre> + * + * <h5>Control Private Data</h5> + * Controls can also have private data. This can be done by defining a private + * data section and including the section within the control. The private data + * section is defined as follows :- + * + * <pre> + * SectionData."pdata for EQU1" { + * file "/path/to/file" + * bytes "0x12,0x34,0x56,0x78" + * shorts "0x1122,0x3344,0x5566,0x7788" + * words "0xaabbccdd,0x11223344,0x66aa77bb,0xefef1234" + * tuples "section id of the vendor tuples" + * }; + * </pre> + * The file, bytes, shorts, words and tuples keywords are all mutually + * exclusive as the private data should only be taken from one source. + * The private data can either be read from a separate file or defined in + * the topology file using the bytes, shorts, words or tuples keywords. + * The keyword tuples is to define vendor specific tuples. Please refer to + * section Vendor Tokens and Vendor tuples. + * + * <h5>How to define an element with private data</h5> + * An element can refer to a single data section or multiple data + * sections. + * + * <h6>To refer to a single data section:</h6> + * <pre> + * Sectionxxx."element name" { + * ... + * data "name of data section" # optional private data + * } + * </pre> + * + * <h6>To refer to multiple data sections:</h6> + * <pre> + * Sectionxxx."element name" { + * ... + * data [ # optional private data + * "name of 1st data section" + * "name of 2nd data section" + * ... + * ] + * } + * </pre> + * And data of these sections will be merged in the same order as they are + * in the list, as the element's private data for kernel. + * + * </pre> + * + * <h6>Vendor Tokens</h6> + * A vendor token list is defined as a new section. Each token element is + * a pair of string ID and integer value. And both the ID and value are + * vendor-specific. + * + * <pre> + * SectionVendorTokens."id of the vendor tokens" { + * comment "optional comments" + * VENDOR_TOKEN_ID1 "1" + * VENDOR_TOKEN_ID2 "2" + * VENDOR_TOKEN_ID3 "3" + * ... + * } + * </pre> + * + * <h6>Vendor Tuples</h6> + * Vendor tuples are defined as a new section. It contains a reference to + * a vendor token list and several tuple arrays. + * All arrays share a vendor token list, defined by the tokens keyword. + * Each tuple array is for a specific type, defined by the string following + * the tuples keyword. Supported types are: string, uuid, bool, byte, + * short and word. + * + * <pre> + * SectionVendorTuples."id of the vendor tuples" { + * tokens "id of the vendor tokens" + * + * tuples."string" { + * VENDOR_TOKEN_ID1 "character string" + * ... + * } + * + * tuples."uuid" { # 16 characters separated by commas + * VENDOR_TOKEN_ID2 "0x01,0x02,...,0x0f" + * ... + * } + * + * tuples."bool" { + * VENDOR_TOKEN_ID3 "true/false" + * ... + * } + * + * tuples."byte" { + * VENDOR_TOKEN_ID4 "0x11" + * VENDOR_TOKEN_ID5 "0x22" + * ... + * } + * + * tuples."short" { + * VENDOR_TOKEN_ID6 "0x1122" + * VENDOR_TOKEN_ID7 "0x3344" + * ... + * } + * + * tuples."word" { + * VENDOR_TOKEN_ID8 "0x11223344" + * VENDOR_TOKEN_ID9 "0x55667788" + * ... + * } + * } + * </pre> + * To define multiple vendor tuples of same type, please append some + * characters after the type string ("string", "uuid", "bool", "byte", "short" + * or "word"), to avoid ID duplication in the SectionVendorTuples.<br> + * The parser will check the first few characters in ID to get the tuple type. + * Here is an example: + * <pre> + * SectionVendorTuples."id of the vendor tuples" { + * ... + * tuples."word.module0" { + * VENDOR_TOKEN_PARAM_ID1 "0x00112233" + * VENDOR_TOKEN_PARAM_ID2 "0x44556677" + * ... + * } + * + * tuples."word.module2" { + * VENDOR_TOKEN_PARAM_ID1 "0x11223344" + * VENDOR_TOKEN_PARAM_ID2 "0x55667788" + * ... + * } + * ... + * } + * + * </pre> + * + * <h5>Mixer Controls</h5> + * A mixer control is defined as a new section that can include channel mapping, + * TLV data, callback operations and private data. The mixer section also + * includes a few other config options that are shown here :- + * + * <pre> + * SectionControlMixer."mixer name" { + * comment "optional comments" + * + * index "1" # Index number + * + * channel."name" { # Channel maps + * .... + * } + * + * ops."ctl" { # Ops callback functions + * .... + * } + * + * max "32" # Max control value + * invert "0" # Whether control values are inverted + * + * tlv "tld_data" # optional TLV data + * + * data "pdata for mixer1" # optional private data + * } + * </pre> + * + * The section name is used to define the mixer name. The index number can be + * used to identify topology objects groups. This allows driver operations on + * objects with index number N and can be used to add/remove pipelines of + * objects whilst other objects are unaffected. + * + * <h5>Byte Controls</h5> + * A byte control is defined as a new section that can include channel mapping, + * TLV data, callback operations and private data. The bytes section also + * includes a few other config options that are shown here :- + * + * <pre> + * SectionControlBytes."name" { + * comment "optional comments" + * + * index "1" # Index number + * + * channel."name" { # Channel maps + * .... + * } + * + * ops."ctl" { # Ops callback functions + * .... + * } + * + * base "0" # Register base + * num_regs "16" # Number of registers + * mask "0xff" # Mask + * max "255" # Maximum value + * + * tlv "tld_data" # optional TLV data + * + * data "pdata for mixer1" # optional private data + * } + * </pre> + * + * <h5>Enumerated Controls</h5> + * A enumerated control is defined as a new section (like mixer and byte) that + * can include channel mapping, callback operations, private data and + * text strings to represent the enumerated control options.<br> + * + * The text strings for the enumerated controls are defined in a separate + * section as follows :- + * + * <pre> + * SectionText."name" { + * + * Values [ + * "value1" + * "value2" + "value3" + * ] + * } + * </pre> + * + * All the enumerated text values are listed in the values list.<br> + * The enumerated control is similar to the other controls and defined as + * follows :- + * + * <pre> + * SectionControlMixer."name" { + * comment "optional comments" + * + * index "1" # Index number + * + * texts "EQU1" # Enumerated text items + * + * channel."name" { # Channel maps + * .... + * } + * + * ops."ctl" { # Ops callback functions + * .... + * } + * + * data "pdata for mixer1" # optional private data + * } + * </pre> + * + * <h4>DAPM Graph</h4> + * DAPM graphs can easily be defined using the topology file. The format is + * very similar to the DAPM graph kernel format. :- + * + * <pre> + * SectionGraph."dsp" { + * index "1" # Index number + * + * lines [ + * "sink1, control, source1" + * "sink2, , source2" + * ] + * } + * </pre> + * + * The lines in the graph are defined as a variable size list of sinks, + * controls and sources. The control name is optional as some graph lines have + * no associated controls. The section name can be used to differentiate the + * graph with other graphs, it's not used by the kernel atm. + * + * <h4>DAPM Widgets</h4> + * DAPM widgets are similar to controls in that they can include many other + * objects. Widgets can contain private data, mixer controls and enum controls. + * + * The following widget types are supported and match the driver types :- + * + * * input + * * output + * * mux + * * mixer + * * pga + * * out_drv + * * adc + * * dac + * * switch + * * pre + * * post + * * aif_in + * * aif_out + * * dai_in + * * dai_out + * * dai_link + * + * Widgets are defined as follows :- + * + * <pre> + * SectionWidget."name" { + * + * index "1" # Index number + * + * type "aif_in" # Widget type - detailed above + * stream_name "name" # Stream name + * + * no_pm "true" # No PM control bit. + * reg "20" # PM bit register offset + * shift "0" # PM bit register shift + * invert "1 # PM bit is inverted + * subseq "8" # subsequence number + * + * event_type "1" # DAPM widget event type + * event_flags "1" # DAPM widget event flags + * + * mixer "name" # Optional Mixer Control + * enum "name" # Optional Enum Control + * + * data "name" # optional private data + * } + * </pre> + * + * The section name is the widget name. The mixer and enum fields are mutually + * exclusive and used to include controls into the widget. The index and data + * fields are the same for widgets as they are for controls whilst the other + * fields map on very closely to the driver widget fields. + * + * <h5>Widget Private Data</h5> + * Widget can have private data. For the format of the private data, please + * refer to section Control Private Data. + * + * <h4>PCM Capabilities</h4> + * Topology can also define the PCM capabilities of front end or physical DAIs. + * Capabilities can be defined with the following section :- + * + * <pre> + * SectionPCMCapabilities."name" { + * + * formats "S24_LE,S16_LE" # Supported formats + * rate_min "48000" # Max supported sample rate + * rate_max "48000" # Min supported sample rate + * channels_min "2" # Min number of channels + * channels_max "2" # max number of channels + * } + * </pre> + * The supported formats use the same naming convention as the driver macros. + * The PCM capabilities name can be referred to and included by PCM and + * physical DAI sections. + * + * <h4>PCM Configurations</h4> + * PCM runtime configurations can be defined for playback and capture stream + * directions with the following section :- + * + * <pre> + * SectionPCMConfig."name" { + * + * config."playback" { # playback config + * format "S16_LE" # playback format + * rate "48000" # playback sample rate + * channels "2" # playback channels + * tdm_slot "0xf" # playback TDM slot + * } + * + * config."capture" { # capture config + * format "S16_LE" # capture format + * rate "48000" # capture sample rate + * channels "2" # capture channels + * tdm_slot "0xf" # capture TDM slot + * } + * } + * </pre> + * + * The supported formats use the same naming convention as the driver macros. + * The PCM configuration name can be referred to and included by PCM and + * physical link sections. + * + * <h4>PCM (Front-end DAI & DAI link) </h4> + * PCM sections define the supported capabilities and configurations for + * supported playback and capture streams, names and flags for front end + * DAI & DAI links. Topology kernel driver will use a PCM object to create + * a pair of FE DAI & DAI links. + * + * <pre> + * SectionPCM."name" { + * + * index "1" # Index number + * + * id "0" # used for binding to the PCM + * + * dai."name of front-end DAI" { + * id "0" # used for binding to the front-end DAI + * } + * + * pcm."playback" { + * capabilities "capabilities1" # capabilities for playback + * + * configs [ # supported configs for playback + * "config1" + * "config2" + * ] + * } + * + * pcm."capture" { + * capabilities "capabilities2" # capabilities for capture + * + * configs [ # supported configs for capture + * "config1" + * "config2" + * "config3" + * ] + * } + * + * # Optional boolean flags + * symmetric_rates "true" + * symmetric_channels "true" + * symmetric_sample_bits "false" + * + * data "name" # optional private data + * } + * </pre> + * + * <h4>Physical DAI Link Configurations</h4> + * The runtime configurations of a physical DAI link can be defined by + * SectionLink. <br> Backend DAI links belong to physical links, and can + * be configured by either SectionLink or SectionBE, with same syntax. + * But SectionBE is deprecated atm since the internal processing is + * actually same. + * + * <pre> + * SectionLink."name" { + * + * index "1" # Index number + * + * id "0" # used for binding to the link + * + * stream_name "name" # used for binding to the link + * + * hw_configs [ # runtime supported HW configurations, optional + * "config1" + * "config2" + * ... + * ] + * + * default_hw_conf_id "1" #default HW config ID for init + * + * # Optional boolean flags + * symmetric_rates "true" + * symmetric_channels "false" + * symmetric_sample_bits "true" + * + * data "name" # optional private data + * } + * </pre> + * + * A physical link can refer to multiple runtime supported hardware + * configurations, which is defined by SectionHWConfig. + * + * <pre> + * SectionHWConfig."name" { + * + * id "1" # used for binding to the config + * format "I2S" # physical audio format. + * bclk "master" # Platform is master of bit clock + * fsync "slave" # Platform is slave of fsync + * } + * </pre> + * + * <h4>Physical DAI</h4> + * A physical DAI (e.g. backend DAI for DPCM) is defined as a new section + * that can include a unique ID, playback and capture stream capabilities, + * optional flags, and private data. <br> + * Its PCM stream capablities are same as those for PCM objects, + * please refer to section 'PCM Capabilities'. + * + * <pre> + * SectionDAI."name" { + * + * index "1" # Index number + * + * id "0" # used for binding to the Backend DAI + * + * pcm."playback" { + * capabilities "capabilities1" # capabilities for playback + * } + * + * pcm."capture" { + * capabilities "capabilities2" # capabilities for capture + * } + * + * symmetric_rates "true" # optional flags + * symmetric_channels "true" + * symmetric_sample_bits "false" + * + * data "name" # optional private data + * } + * </pre> + * + * <h4>Manifest Private Data</h4> + * Manfiest may have private data. Users need to define a manifest section + * and add the references to 1 or multiple data sections. Please refer to + * section 'How to define an element with private data'. <br> + * And the text conf file can have at most 1 manifest section. <br><br> + * + * Manifest section is defined as follows :- + * + * <pre> + * SectionManifest"name" { + * + * data "name" # optional private data + * } + * </pre> + * + * <h4>Include other files</h4> + * Users may include other files in a text conf file via alsaconf syntax + * <path/to/configuration-file>. This allows users to define common info + * in separate files (e.g. vendor tokens, tuples) and share them for + * different platforms, thus save the total size of config files. <br> + * Users can also specifiy additional configuraiton directories relative + * to "/usr/share/alsa/" to search the included files, via alsaconf syntax + * <searchfdir:/relative-path/to/usr/share/alsa>. <br><br> + * + * For example, file A and file B are two text conf files for platform X, + * they will be installed to /usr/share/alsa/topology/platformx. If we + * need file A to include file B, in file A we can add: <br> + * + * <searchdir:topology/platformx> <br> + * <name-of-file-B> <br><br> + * + * ALSA conf will search and open an included file in the following order + * of priority: + * 1. directly open the file by its name; + * 2. search for the file name in "/usr/share/alsa"; + * 3. search for the file name in user specified subdirectories under + * "/usr/share/alsa". + * + * The order of the included files need not to be same as their + * dependencies, since the topology library will load them all before + * parsing their dependencies. <br> + * + * The configuration directories defined by a file will only be used to search + * the files included by this file. + */ + +/** Maximum number of channels supported in one control */ +#define SND_TPLG_MAX_CHAN 8 + +/** Topology context */ +typedef struct snd_tplg snd_tplg_t; + +/** Topology object types */ +enum snd_tplg_type { + SND_TPLG_TYPE_TLV = 0, /*!< TLV Data */ + SND_TPLG_TYPE_MIXER, /*!< Mixer control*/ + SND_TPLG_TYPE_ENUM, /*!< Enumerated control */ + SND_TPLG_TYPE_TEXT, /*!< Text data */ + SND_TPLG_TYPE_DATA, /*!< Private data */ + SND_TPLG_TYPE_BYTES, /*!< Byte control */ + SND_TPLG_TYPE_STREAM_CONFIG, /*!< PCM Stream configuration */ + SND_TPLG_TYPE_STREAM_CAPS, /*!< PCM Stream capabilities */ + SND_TPLG_TYPE_PCM, /*!< PCM stream device */ + SND_TPLG_TYPE_DAPM_WIDGET, /*!< DAPM widget */ + SND_TPLG_TYPE_DAPM_GRAPH, /*!< DAPM graph elements */ + SND_TPLG_TYPE_BE, /*!< BE DAI link */ + SND_TPLG_TYPE_CC, /*!< Hostless codec <-> codec link */ + SND_TPLG_TYPE_MANIFEST, /*!< Topology manifest */ + SND_TPLG_TYPE_TOKEN, /*!< Vendor tokens */ + SND_TPLG_TYPE_TUPLE, /*!< Vendor tuples */ + SND_TPLG_TYPE_LINK, /*!< Physical DAI link */ + SND_TPLG_TYPE_HW_CONFIG, /*!< Link HW config */ + SND_TPLG_TYPE_DAI, /*!< Physical DAI */ +}; + +/** + * \brief Create a new topology parser instance. + * \return New topology parser instance + */ +snd_tplg_t *snd_tplg_new(void); + +/** + * \brief Free a topology parser instance. + * \param tplg Topology parser instance + */ +void snd_tplg_free(snd_tplg_t *tplg); + +/** + * \brief Parse and build topology text file into binary file. + * \param tplg Topology instance. + * \param infile Topology text input file to be parsed + * \param outfile Binary topology output file. + * \return Zero on success, otherwise a negative error code + */ +int snd_tplg_build_file(snd_tplg_t *tplg, const char *infile, + const char *outfile); + +/** + * \brief Enable verbose reporting of binary file output + * \param tplg Topology Instance + * \param verbose Enable verbose output level if non zero + */ +void snd_tplg_verbose(snd_tplg_t *tplg, int verbose); + +/** \struct snd_tplg_tlv_template + * \brief Template type for all TLV objects. + */ +struct snd_tplg_tlv_template { + int type; /*!< TLV type SNDRV_CTL_TLVT_ */ +}; + +/** \struct snd_tplg_tlv_dbscale_template + * \brief Template type for TLV Scale objects. + */ +struct snd_tplg_tlv_dbscale_template { + struct snd_tplg_tlv_template hdr; /*!< TLV type header */ + int min; /*!< dB minimum value in 0.1dB */ + int step; /*!< dB step size in 0.1dB */ + int mute; /*!< is min dB value mute ? */ +}; + +/** \struct snd_tplg_channel_template + * \brief Template type for single channel mapping. + */ +struct snd_tplg_channel_elem { + int size; /*!< size in bytes of this structure */ + int reg; /*!< channel control register */ + int shift; /*!< channel shift for control bits */ + int id; /*!< ID maps to Left, Right, LFE etc */ +}; + +/** \struct snd_tplg_channel_map_template + * \brief Template type for channel mapping. + */ +struct snd_tplg_channel_map_template { + int num_channels; /*!< number of channel mappings */ + struct snd_tplg_channel_elem channel[SND_TPLG_MAX_CHAN]; /*!< mapping */ +}; + +/** \struct snd_tplg_pdata_template + * \brief Template type for private data objects. + */ +struct snd_tplg_pdata_template { + unsigned int length; /*!< data length */ + const void *data; /*!< data */ +}; + +/** \struct snd_tplg_io_ops_template + * \brief Template type for object operations mapping. + */ +struct snd_tplg_io_ops_template { + int get; /*!< get callback ID */ + int put; /*!< put callback ID */ + int info; /*!< info callback ID */ +}; + +/** \struct snd_tplg_ctl_template + * \brief Template type for control objects. + */ +struct snd_tplg_ctl_template { + int type; /*!< Control type */ + const char *name; /*!< Control name */ + int access; /*!< Control access */ + struct snd_tplg_io_ops_template ops; /*!< operations */ + struct snd_tplg_tlv_template *tlv; /*!< non NULL means we have TLV data */ +}; + +/** \struct snd_tplg_mixer_template + * \brief Template type for mixer control objects. + */ +struct snd_tplg_mixer_template { + struct snd_tplg_ctl_template hdr; /*!< control type header */ + struct snd_tplg_channel_map_template *map; /*!< channel map */ + int min; /*!< min value for mixer */ + int max; /*!< max value for mixer */ + int platform_max; /*!< max value for platform control */ + int invert; /*!< whether controls bits are inverted */ + struct snd_soc_tplg_private *priv; /*!< control private data */ +}; + +/** \struct snd_tplg_enum_template + * \brief Template type for enumerated control objects. + */ +struct snd_tplg_enum_template { + struct snd_tplg_ctl_template hdr; /*!< control type header */ + struct snd_tplg_channel_map_template *map; /*!< channel map */ + int items; /*!< number of enumerated items in control */ + int mask; /*!< register mask size */ + const char **texts; /*!< control text items */ + const int **values; /*!< control value items */ + struct snd_soc_tplg_private *priv; /*!< control private data */ +}; + +/** \struct snd_tplg_bytes_template + * \brief Template type for TLV Scale objects. + */ +struct snd_tplg_bytes_template { + struct snd_tplg_ctl_template hdr; /*!< control type header */ + int max; /*!< max byte control value */ + int mask; /*!< byte control mask */ + int base; /*!< base register */ + int num_regs; /*!< number of registers */ + struct snd_tplg_io_ops_template ext_ops; /*!< ops mapping */ + struct snd_soc_tplg_private *priv; /*!< control private data */ +}; + +/** \struct snd_tplg_graph_elem + * \brief Template type for single DAPM graph element. + */ +struct snd_tplg_graph_elem { + const char *src; /*!< source widget name */ + const char *ctl; /*!< control name or NULL if no control */ + const char *sink; /*!< sink widget name */ +}; + +/** \struct snd_tplg_graph_template + * \brief Template type for array of DAPM graph elements. + */ +struct snd_tplg_graph_template { + int count; /*!< Number of graph elements */ + struct snd_tplg_graph_elem elem[0]; /*!< graph elements */ +}; + +/** \struct snd_tplg_widget_template + * \brief Template type for DAPM widget objects. + */ +struct snd_tplg_widget_template { + int id; /*!< SND_SOC_DAPM_CTL */ + const char *name; /*!< widget name */ + const char *sname; /*!< stream name (certain widgets only) */ + int reg; /*!< negative reg = no direct dapm */ + int shift; /*!< bits to shift */ + int mask; /*!< non-shifted mask */ + int subseq; /*!< sort within widget type */ + unsigned int invert; /*!< invert the power bit */ + unsigned int ignore_suspend; /*!< kept enabled over suspend */ + unsigned short event_flags; /*!< PM event sequence flags */ + unsigned short event_type; /*!< PM event sequence type */ + struct snd_soc_tplg_private *priv; /*!< widget private data */ + int num_ctls; /*!< Number of controls used by widget */ + struct snd_tplg_ctl_template *ctl[0]; /*!< array of widget controls */ +}; + +/** \struct snd_tplg_stream_template + * \brief Stream configurations. + */ +struct snd_tplg_stream_template { + const char *name; /*!< name of the stream config */ + int format; /*!< SNDRV_PCM_FMTBIT_* */ + int rate; /*!< SNDRV_PCM_RATE_* */ + int period_bytes; /*!< size of period in bytes */ + int buffer_bytes; /*!< size of buffer in bytes. */ + int channels; /*!< number of channels */ +}; + +/** \struct snd_tplg_stream_caps_template + * \brief Stream Capabilities. + */ +struct snd_tplg_stream_caps_template { + const char *name; /*!< name of the stream caps */ + uint64_t formats; /*!< supported formats SNDRV_PCM_FMTBIT_* */ + unsigned int rates; /*!< supported rates SNDRV_PCM_RATE_* */ + unsigned int rate_min; /*!< min rate */ + unsigned int rate_max; /*!< max rate */ + unsigned int channels_min; /*!< min channels */ + unsigned int channels_max; /*!< max channels */ + unsigned int periods_min; /*!< min number of periods */ + unsigned int periods_max; /*!< max number of periods */ + unsigned int period_size_min; /*!< min period size bytes */ + unsigned int period_size_max; /*!< max period size bytes */ + unsigned int buffer_size_min; /*!< min buffer size bytes */ + unsigned int buffer_size_max; /*!< max buffer size bytes */ + unsigned int sig_bits; /*!< number of bits of content */ +}; + +/** \struct snd_tplg_pcm_template + * \brief Template type for PCM (FE DAI & DAI links). + */ +struct snd_tplg_pcm_template { + const char *pcm_name; /*!< PCM stream name */ + const char *dai_name; /*!< DAI name */ + unsigned int pcm_id; /*!< unique ID - used to match */ + unsigned int dai_id; /*!< unique ID - used to match */ + unsigned int playback; /*!< supports playback mode */ + unsigned int capture; /*!< supports capture mode */ + unsigned int compress; /*!< 1 = compressed; 0 = PCM */ + struct snd_tplg_stream_caps_template *caps[2]; /*!< playback & capture for DAI */ + unsigned int flag_mask; /*!< bitmask of flags to configure */ + unsigned int flags; /*!< flag value SND_SOC_TPLG_LNK_FLGBIT_* */ + struct snd_soc_tplg_private *priv; /*!< private data */ + int num_streams; /*!< number of supported configs */ + struct snd_tplg_stream_template stream[0]; /*!< supported configs */ +}; + + /** \struct snd_tplg_hw_config_template + * \brief Template type to describe a physical link runtime supported + * hardware config, i.e. hardware audio formats. + */ +struct snd_tplg_hw_config_template { + int id; /* unique ID - - used to match */ + unsigned int fmt; /* SND_SOC_DAI_FORMAT_ format value */ + unsigned char clock_gated; /* 1 if clock can be gated to save power */ + unsigned char invert_bclk; /* 1 for inverted BCLK, 0 for normal */ + unsigned char invert_fsync; /* 1 for inverted frame clock, 0 for normal */ + unsigned char bclk_master; /* 1 for master of BCLK, 0 for slave */ + unsigned char fsync_master; /* 1 for master of FSYNC, 0 for slave */ + unsigned char mclk_direction; /* 0 for input, 1 for output */ + unsigned short reserved; /* for 32bit alignment */ + unsigned int mclk_rate; /* MCLK or SYSCLK freqency in Hz */ + unsigned int bclk_rate; /* BCLK freqency in Hz */ + unsigned int fsync_rate; /* frame clock in Hz */ + unsigned int tdm_slots; /* number of TDM slots in use */ + unsigned int tdm_slot_width; /* width in bits for each slot */ + unsigned int tx_slots; /* bit mask for active Tx slots */ + unsigned int rx_slots; /* bit mask for active Rx slots */ + unsigned int tx_channels; /* number of Tx channels */ + unsigned int *tx_chanmap; /* array of slot number */ + unsigned int rx_channels; /* number of Rx channels */ + unsigned int *rx_chanmap; /* array of slot number */ +}; + +/** \struct snd_tplg_dai_template + * \brief Template type for physical DAI. + * It can be used to configure backend DAIs for DPCM. + */ +struct snd_tplg_dai_template { + const char *dai_name; /*!< DAI name */ + unsigned int dai_id; /*!< unique ID - used to match */ + unsigned int playback; /*!< supports playback mode */ + unsigned int capture; /*!< supports capture mode */ + struct snd_tplg_stream_caps_template *caps[2]; /*!< playback & capture for DAI */ + unsigned int flag_mask; /*!< bitmask of flags to configure */ + unsigned int flags; /*!< SND_SOC_TPLG_DAI_FLGBIT_* */ + struct snd_soc_tplg_private *priv; /*!< private data */ + +}; + +/** \struct snd_tplg_link_template + * \brief Template type for physical DAI Links. + */ +struct snd_tplg_link_template { + const char *name; /*!< link name, used to match */ + int id; /*!< unique ID - used to match with existing physical links */ + const char *stream_name; /*!< link stream name, used to match */ + + int num_streams; /*!< number of configs */ + struct snd_tplg_stream_template *stream; /*!< supported configs */ + + struct snd_tplg_hw_config_template *hw_config; /*!< supported HW configs */ + int num_hw_configs; /* number of hw configs */ + int default_hw_config_id; /* default hw config ID for init */ + + unsigned int flag_mask; /* bitmask of flags to configure */ + unsigned int flags; /* SND_SOC_TPLG_LNK_FLGBIT_* flag value */ + struct snd_soc_tplg_private *priv; /*!< private data */ +}; + +/** \struct snd_tplg_obj_template + * \brief Generic Template Object + */ +typedef struct snd_tplg_obj_template { + enum snd_tplg_type type; /*!< template object type */ + int index; /*!< group index for object */ + int version; /*!< optional vendor specific version details */ + int vendor_type; /*!< optional vendor specific type info */ + union { + struct snd_tplg_widget_template *widget; /*!< DAPM widget */ + struct snd_tplg_mixer_template *mixer; /*!< Mixer control */ + struct snd_tplg_bytes_template *bytes_ctl; /*!< Bytes control */ + struct snd_tplg_enum_template *enum_ctl; /*!< Enum control */ + struct snd_tplg_graph_template *graph; /*!< Graph elements */ + struct snd_tplg_pcm_template *pcm; /*!< PCM elements */ + struct snd_tplg_link_template *link; /*!< physical DAI Links */ + struct snd_tplg_dai_template *dai; /*!< Physical DAI */ + }; +} snd_tplg_obj_template_t; + +/** + * \brief Register topology template object. + * \param tplg Topology instance. + * \param t Template object. + * \return Zero on success, otherwise a negative error code + */ +int snd_tplg_add_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t); + +/** + * \brief Build all registered topology data into binary file. + * \param tplg Topology instance. + * \param outfile Binary topology output file. + * \return Zero on success, otherwise a negative error code + */ +int snd_tplg_build(snd_tplg_t *tplg, const char *outfile); + +/** + * \brief Attach private data to topology manifest. + * \param tplg Topology instance. + * \param data Private data. + * \param len Length of data in bytes. + * \return Zero on success, otherwise a negative error code + */ +int snd_tplg_set_manifest_data(snd_tplg_t *tplg, const void *data, int len); + +/** + * \brief Set an optional vendor specific version number. + * \param tplg Topology instance. + * \param version Vendor specific version number. + * \return Zero on success, otherwise a negative error code + */ +int snd_tplg_set_version(snd_tplg_t *tplg, unsigned int version); + +/* \} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALSA_TOPOLOGY_H */ diff --git a/thirdparty/linuxbsd_headers/alsa/use-case.h b/thirdparty/linuxbsd_headers/alsa/use-case.h new file mode 100644 index 0000000000..8911645b5c --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/use-case.h @@ -0,0 +1,432 @@ +/** + * \file include/use-case.h + * \brief use case interface for the ALSA driver + * \author Liam Girdwood <lrg@slimlogic.co.uk> + * \author Stefan Schmidt <stefan@slimlogic.co.uk> + * \author Jaroslav Kysela <perex@perex.cz> + * \author Justin Xu <justinx@slimlogic.co.uk> + * \date 2008-2010 + */ +/* + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Copyright (C) 2008-2010 SlimLogic Ltd + * Copyright (C) 2010 Wolfson Microelectronics PLC + * Copyright (C) 2010 Texas Instruments Inc. + * + * Support for the verb/device/modifier core logic and API, + * command line tool and file parser was kindly sponsored by + * Texas Instruments Inc. + * Support for multiple active modifiers and devices, + * transition sequences, multiple client access and user defined use + * cases was kindly sponsored by Wolfson Microelectronics PLC. + */ + +#ifndef __ALSA_USE_CASE_H +#define __ALSA_USE_CASE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup ucm Use Case Interface + * The ALSA Use Case manager interface. + * See \ref Usecase page for more details. + * \{ + */ + +/*! \page Usecase ALSA Use Case Interface + * + * The use case manager works by configuring the sound card ALSA kcontrols to + * change the hardware digital and analog audio routing to match the requested + * device use case. The use case manager kcontrol configurations are stored in + * easy to modify text files. + * + * An audio use case can be defined by a verb and device parameter. The verb + * describes the use case action i.e. a phone call, listening to music, recording + * a conversation etc. The device describes the physical audio capture and playback + * hardware i.e. headphones, phone handset, bluetooth headset, etc. + * + * It's intended clients will mostly only need to set the use case verb and + * device for each system use case change (as the verb and device parameters + * cover most audio use cases). + * + * However there are times when a use case has to be modified at runtime. e.g. + * + * + Incoming phone call when the device is playing music + * + Recording sections of a phone call + * + Playing tones during a call. + * + * In order to allow asynchronous runtime use case adaptations, we have a third + * optional modifier parameter that can be used to further configure + * the use case during live audio runtime. + * + * This interface allows clients to :- + * + * + Query the supported use case verbs, devices and modifiers for the machine. + * + Set and Get use case verbs, devices and modifiers for the machine. + * + Get the ALSA PCM playback and capture device PCMs for use case verb, + * use case device and modifier. + * + Get the TQ parameter for each use case verb, use case device and + * modifier. + * + Get the ALSA master playback and capture volume/switch kcontrols + * for each use case. + */ + + +/* + * Use Case Verb. + * + * The use case verb is the main device audio action. e.g. the "HiFi" use + * case verb will configure the audio hardware for HiFi Music playback + * and capture. + */ +#define SND_USE_CASE_VERB_INACTIVE "Inactive" /**< Inactive Verb */ +#define SND_USE_CASE_VERB_HIFI "HiFi" /**< HiFi Verb */ +#define SND_USE_CASE_VERB_HIFI_LOW_POWER "HiFi Low Power" /**< HiFi Low Power Verb */ +#define SND_USE_CASE_VERB_VOICE "Voice" /**< Voice Verb */ +#define SND_USE_CASE_VERB_VOICE_LOW_POWER "Voice Low Power" /**< Voice Low Power Verb */ +#define SND_USE_CASE_VERB_VOICECALL "Voice Call" /**< Voice Call Verb */ +#define SND_USE_CASE_VERB_IP_VOICECALL "Voice Call IP" /**< Voice Call IP Verb */ +#define SND_USE_CASE_VERB_ANALOG_RADIO "FM Analog Radio" /**< FM Analog Radio Verb */ +#define SND_USE_CASE_VERB_DIGITAL_RADIO "FM Digital Radio" /**< FM Digital Radio Verb */ +/* add new verbs to end of list */ + + +/* + * Use Case Device. + * + * Physical system devices the render and capture audio. Devices can be OR'ed + * together to support audio on simultaneous devices. + */ +#define SND_USE_CASE_DEV_NONE "None" /**< None Device */ +#define SND_USE_CASE_DEV_SPEAKER "Speaker" /**< Speaker Device */ +#define SND_USE_CASE_DEV_LINE "Line" /**< Line Device */ +#define SND_USE_CASE_DEV_HEADPHONES "Headphones" /**< Headphones Device */ +#define SND_USE_CASE_DEV_HEADSET "Headset" /**< Headset Device */ +#define SND_USE_CASE_DEV_HANDSET "Handset" /**< Handset Device */ +#define SND_USE_CASE_DEV_BLUETOOTH "Bluetooth" /**< Bluetooth Device */ +#define SND_USE_CASE_DEV_EARPIECE "Earpiece" /**< Earpiece Device */ +#define SND_USE_CASE_DEV_SPDIF "SPDIF" /**< SPDIF Device */ +#define SND_USE_CASE_DEV_HDMI "HDMI" /**< HDMI Device */ +/* add new devices to end of list */ + + +/* + * Use Case Modifiers. + * + * The use case modifier allows runtime configuration changes to deal with + * asynchronous events. + * + * e.g. to record a voice call :- + * 1. Set verb to SND_USE_CASE_VERB_VOICECALL (for voice call) + * 2. Set modifier SND_USE_CASE_MOD_CAPTURE_VOICE when capture required. + * 3. Call snd_use_case_get("CapturePCM") to get ALSA source PCM name + * with captured voice pcm data. + * + * e.g. to play a ring tone when listenin to MP3 Music :- + * 1. Set verb to SND_USE_CASE_VERB_HIFI (for MP3 playback) + * 2. Set modifier to SND_USE_CASE_MOD_PLAY_TONE when incoming call happens. + * 3. Call snd_use_case_get("PlaybackPCM") to get ALSA PCM sink name for + * ringtone pcm data. + */ +#define SND_USE_CASE_MOD_CAPTURE_VOICE "Capture Voice" /**< Capture Voice Modifier */ +#define SND_USE_CASE_MOD_CAPTURE_MUSIC "Capture Music" /**< Capture Music Modifier */ +#define SND_USE_CASE_MOD_PLAY_MUSIC "Play Music" /**< Play Music Modifier */ +#define SND_USE_CASE_MOD_PLAY_VOICE "Play Voice" /**< Play Voice Modifier */ +#define SND_USE_CASE_MOD_PLAY_TONE "Play Tone" /**< Play Tone Modifier */ +#define SND_USE_CASE_MOD_ECHO_REF "Echo Reference" /**< Echo Reference Modifier */ +/* add new modifiers to end of list */ + + +/** + * TQ - Tone Quality + * + * The interface allows clients to determine the audio TQ required for each + * use case verb and modifier. It's intended as an optional hint to the + * audio driver in order to lower power consumption. + * + */ +#define SND_USE_CASE_TQ_MUSIC "Music" /**< Music Tone Quality */ +#define SND_USE_CASE_TQ_VOICE "Voice" /**< Voice Tone Quality */ +#define SND_USE_CASE_TQ_TONES "Tones" /**< Tones Tone Quality */ + +/** use case container */ +typedef struct snd_use_case_mgr snd_use_case_mgr_t; + +/** + * \brief Create an identifier + * \param fmt Format (sprintf like) + * \param ... Optional arguments for sprintf like format + * \return Allocated string identifier or NULL on error + */ +char *snd_use_case_identifier(const char *fmt, ...); + +/** + * \brief Free a string list + * \param list The string list to free + * \param items Count of strings + * \return Zero if success, otherwise a negative error code + */ +int snd_use_case_free_list(const char *list[], int items); + +/** + * \brief Obtain a list of entries + * \param uc_mgr Use case manager (may be NULL - card list) + * \param identifier (may be NULL - card list) + * \param list Returned allocated list + * \return Number of list entries if success, otherwise a negative error code + * + * Defined identifiers: + * - NULL - get card list + * (in pair cardname+comment) + * - _verbs - get verb list + * (in pair verb+comment) + * - _devices[/{verb}] - get list of supported devices + * (in pair device+comment) + * - _modifiers[/{verb}] - get list of supported modifiers + * (in pair modifier+comment) + * - TQ[/{verb}] - get list of TQ identifiers + * - _enadevs - get list of enabled devices + * - _enamods - get list of enabled modifiers + * + * - _supporteddevs/{modifier}|{device}[/{verb}] - list of supported devices + * - _conflictingdevs/{modifier}|{device}[/{verb}] - list of conflicting devices + * + * Note that at most one of the supported/conflicting devs lists has + * any entries, and when neither is present, all devices are supported. + * + */ +int snd_use_case_get_list(snd_use_case_mgr_t *uc_mgr, + const char *identifier, + const char **list[]); + + +/** + * \brief Get current - string + * \param uc_mgr Use case manager + * \param identifier + * \param value Value pointer + * \return Zero if success, otherwise a negative error code + * + * Note: The returned string is dynamically allocated, use free() to + * deallocate this string. (Yes, the value parameter shouldn't be marked as + * "const", but it's too late to fix it, sorry about that.) + * + * Known identifiers: + * - NULL - return current card + * - _verb - return current verb + * + * - [=]{NAME}[/[{modifier}|{/device}][/{verb}]] + * - value identifier {NAME} + * - Search starts at given modifier or device if any, + * else at a verb + * - Search starts at given verb if any, + * else current verb + * - Searches modifier/device, then verb, then defaults + * - Specify a leading "=" to search only the exact + * device/modifier/verb specified, and not search + * through each object in turn. + * - Examples: + * - "PlaybackPCM/Play Music" + * - "CapturePCM/SPDIF" + * - From ValueDefaults only: + * "=Variable" + * - From current active verb: + * "=Variable//" + * - From verb "Verb": + * "=Variable//Verb" + * - From "Modifier" in current active verb: + * "=Variable/Modifier/" + * - From "Modifier" in "Verb": + * "=Variable/Modifier/Verb" + * + * Recommended names for values: + * - TQ + * - Tone Quality + * - PlaybackPCM + * - full PCM playback device name + * - PlaybackPCMIsDummy + * - Valid values: "yes" and "no". If set to "yes", the PCM named by the + * PlaybackPCM value is a dummy device, meaning that opening it enables + * an audio path in the hardware, but writing to the PCM device has no + * effect. + * - CapturePCM + * - full PCM capture device name + * - CapturePCMIsDummy + * - Valid values: "yes" and "no". If set to "yes", the PCM named by the + * CapturePCM value is a dummy device, meaning that opening it enables + * an audio path in the hardware, but reading from the PCM device has no + * effect. + * - PlaybackRate + * - playback device sample rate + * - PlaybackChannels + * - playback device channel count + * - PlaybackCTL + * - playback control device name + * - PlaybackVolume + * - playback control volume ID string + * - PlaybackSwitch + * - playback control switch ID string + * - CaptureRate + * - capture device sample rate + * - CaptureChannels + * - capture device channel count + * - CaptureCTL + * - capture control device name + * - CaptureVolume + * - capture control volume ID string + * - CaptureSwitch + * - capture control switch ID string + * - PlaybackMixer + * - name of playback mixer + * - PlaybackMixerID + * - mixer playback ID + * - CaptureMixer + * - name of capture mixer + * - CaptureMixerID + * - mixer capture ID + * - JackControl, JackDev, JackHWMute + * - Jack information for a device. The jack status can be reported via + * a kcontrol and/or via an input device. **JackControl** is the + * kcontrol name of the jack, and **JackDev** is the input device id of + * the jack (if the full input device path is /dev/input/by-id/foo, the + * JackDev value should be "foo"). UCM configuration files should + * contain both JackControl and JackDev when possible, because + * applications are likely to support only one or the other. + * + * If **JackHWMute** is set, it indicates that when the jack is plugged + * in, the hardware automatically mutes some other device(s). The + * JackHWMute value is a space-separated list of device names (this + * isn't compatible with device names with spaces in them, so don't use + * such device names!). Note that JackHWMute should be used only when + * the hardware enforces the automatic muting. If the hardware doesn't + * enforce any muting, it may still be tempting to set JackHWMute to + * trick upper software layers to e.g. automatically mute speakers when + * headphones are plugged in, but that's application policy + * configuration that doesn't belong to UCM configuration files. + */ +int snd_use_case_get(snd_use_case_mgr_t *uc_mgr, + const char *identifier, + const char **value); + +/** + * \brief Get current - integer + * \param uc_mgr Use case manager + * \param identifier + * \param value result + * \return Zero if success, otherwise a negative error code + * + * Known identifiers: + * - _devstatus/{device} - return status for given device + * - _modstatus/{modifier} - return status for given modifier + */ +int snd_use_case_geti(snd_use_case_mgr_t *uc_mgr, + const char *identifier, + long *value); + +/** + * \brief Set new + * \param uc_mgr Use case manager + * \param identifier + * \param value Value + * \return Zero if success, otherwise a negative error code + * + * Known identifiers: + * - _verb - set current verb = value + * - _enadev - enable given device = value + * - _disdev - disable given device = value + * - _swdev/{old_device} - new_device = value + * - disable old_device and then enable new_device + * - if old_device is not enabled just return + * - check transmit sequence firstly + * - _enamod - enable given modifier = value + * - _dismod - disable given modifier = value + * - _swmod/{old_modifier} - new_modifier = value + * - disable old_modifier and then enable new_modifier + * - if old_modifier is not enabled just return + * - check transmit sequence firstly + */ +int snd_use_case_set(snd_use_case_mgr_t *uc_mgr, + const char *identifier, + const char *value); + +/** + * \brief Open and initialise use case core for sound card + * \param uc_mgr Returned use case manager pointer + * \param card_name Sound card name. + * \return zero if success, otherwise a negative error code + */ +int snd_use_case_mgr_open(snd_use_case_mgr_t **uc_mgr, const char *card_name); + + +/** + * \brief Reload and re-parse use case configuration files for sound card. + * \param uc_mgr Use case manager + * \return zero if success, otherwise a negative error code + */ +int snd_use_case_mgr_reload(snd_use_case_mgr_t *uc_mgr); + +/** + * \brief Close use case manager + * \param uc_mgr Use case manager + * \return zero if success, otherwise a negative error code + */ +int snd_use_case_mgr_close(snd_use_case_mgr_t *uc_mgr); + +/** + * \brief Reset use case manager verb, device, modifier to deafult settings. + * \param uc_mgr Use case manager + * \return zero if success, otherwise a negative error code + */ +int snd_use_case_mgr_reset(snd_use_case_mgr_t *uc_mgr); + +/* + * helper functions + */ + +/** + * \brief Obtain a list of cards + * \param list Returned allocated list + * \return Number of list entries if success, otherwise a negative error code + */ +static __inline__ int snd_use_case_card_list(const char **list[]) +{ + return snd_use_case_get_list(NULL, NULL, list); +} + +/** + * \brief Obtain a list of verbs + * \param uc_mgr Use case manager + * \param list Returned list of verbs + * \return Number of list entries if success, otherwise a negative error code + */ +static __inline__ int snd_use_case_verb_list(snd_use_case_mgr_t *uc_mgr, + const char **list[]) +{ + return snd_use_case_get_list(uc_mgr, "_verbs", list); +} + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALSA_USE_CASE_H */ diff --git a/thirdparty/linuxbsd_headers/alsa/version.h b/thirdparty/linuxbsd_headers/alsa/version.h new file mode 100644 index 0000000000..661ec6c8e2 --- /dev/null +++ b/thirdparty/linuxbsd_headers/alsa/version.h @@ -0,0 +1,15 @@ +/* + * version.h + */ + +#define SND_LIB_MAJOR 1 /**< major number of library version */ +#define SND_LIB_MINOR 1 /**< minor number of library version */ +#define SND_LIB_SUBMINOR 3 /**< subminor number of library version */ +#define SND_LIB_EXTRAVER 1000000 /**< extra version number, used mainly for betas */ +/** library version */ +#define SND_LIB_VERSION ((SND_LIB_MAJOR<<16)|\ + (SND_LIB_MINOR<<8)|\ + SND_LIB_SUBMINOR) +/** library version (string) */ +#define SND_LIB_VERSION_STR "1.1.3" + diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-address.h b/thirdparty/linuxbsd_headers/dbus/dbus-address.h new file mode 100644 index 0000000000..fefb320ea3 --- /dev/null +++ b/thirdparty/linuxbsd_headers/dbus/dbus-address.h @@ -0,0 +1,86 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-address.h Server address parser. + * + * Copyright (C) 2003 CodeFactory AB + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_ADDRESS_H +#define DBUS_ADDRESS_H + +#include <dbus/dbus-types.h> +#include <dbus/dbus-errors.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusAddress + * @{ + */ + +/** Opaque type representing one of the semicolon-separated items in an address */ +typedef struct DBusAddressEntry DBusAddressEntry; + +DBUS_EXPORT +dbus_bool_t dbus_parse_address (const char *address, + DBusAddressEntry ***entry_result, + int *array_len, + DBusError *error); +DBUS_EXPORT +const char *dbus_address_entry_get_value (DBusAddressEntry *entry, + const char *key); +DBUS_EXPORT +const char *dbus_address_entry_get_method (DBusAddressEntry *entry); +DBUS_EXPORT +void dbus_address_entries_free (DBusAddressEntry **entries); + +DBUS_EXPORT +char* dbus_address_escape_value (const char *value); +DBUS_EXPORT +char* dbus_address_unescape_value (const char *value, + DBusError *error); + +/** + * Clear a variable or struct member that contains an array of #DBusAddressEntry. + * If it does not contain #NULL, the entries that were previously + * there are freed with dbus_address_entries_free(). + * + * This is similar to dbus_clear_connection(): see that function + * for more details. + * + * @param pointer_to_entries A pointer to a variable or struct member. + * pointer_to_entries must not be #NULL, but *pointer_to_entries + * may be #NULL. + */ +static inline void +dbus_clear_address_entries (DBusAddressEntry ***pointer_to_entries) +{ + _dbus_clear_pointer_impl (DBusAddressEntry *, pointer_to_entries, + dbus_address_entries_free); +} + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_ADDRESS_H */ + diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-arch-deps.h b/thirdparty/linuxbsd_headers/dbus/dbus-arch-deps.h new file mode 100644 index 0000000000..37010b3b5d --- /dev/null +++ b/thirdparty/linuxbsd_headers/dbus/dbus-arch-deps.h @@ -0,0 +1,61 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-arch-deps.h Header with architecture/compiler specific information, installed to libdir + * + * Copyright (C) 2003 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.0 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_ARCH_DEPS_H +#define DBUS_ARCH_DEPS_H + +#include <dbus/dbus-macros.h> + +DBUS_BEGIN_DECLS + +/* D-Bus no longer supports platforms with no 64-bit integer type. */ +#define DBUS_HAVE_INT64 1 +_DBUS_GNUC_EXTENSION typedef long dbus_int64_t; +_DBUS_GNUC_EXTENSION typedef unsigned long dbus_uint64_t; + +#define DBUS_INT64_CONSTANT(val) (_DBUS_GNUC_EXTENSION (val##L)) +#define DBUS_UINT64_CONSTANT(val) (_DBUS_GNUC_EXTENSION (val##UL)) + +typedef int dbus_int32_t; +typedef unsigned int dbus_uint32_t; + +typedef short dbus_int16_t; +typedef unsigned short dbus_uint16_t; + +/* This is not really arch-dependent, but it's not worth + * creating an additional generated header just for this + */ +#define DBUS_MAJOR_VERSION 1 +#define DBUS_MINOR_VERSION 12 +#define DBUS_MICRO_VERSION 2 + +#define DBUS_VERSION_STRING "1.12.2" + +#define DBUS_VERSION ((1 << 16) | (12 << 8) | (2)) + +DBUS_END_DECLS + +#endif /* DBUS_ARCH_DEPS_H */ diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-bus.h b/thirdparty/linuxbsd_headers/dbus/dbus-bus.h new file mode 100644 index 0000000000..02a95711d0 --- /dev/null +++ b/thirdparty/linuxbsd_headers/dbus/dbus-bus.h @@ -0,0 +1,95 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-bus.h Convenience functions for communicating with the bus. + * + * Copyright (C) 2003 CodeFactory AB + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_BUS_H +#define DBUS_BUS_H + +#include <dbus/dbus-connection.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusBus + * @{ + */ + +DBUS_EXPORT +DBusConnection *dbus_bus_get (DBusBusType type, + DBusError *error); +DBUS_EXPORT +DBusConnection *dbus_bus_get_private (DBusBusType type, + DBusError *error); + +DBUS_EXPORT +dbus_bool_t dbus_bus_register (DBusConnection *connection, + DBusError *error); +DBUS_EXPORT +dbus_bool_t dbus_bus_set_unique_name (DBusConnection *connection, + const char *unique_name); +DBUS_EXPORT +const char* dbus_bus_get_unique_name (DBusConnection *connection); +DBUS_EXPORT +unsigned long dbus_bus_get_unix_user (DBusConnection *connection, + const char *name, + DBusError *error); +DBUS_EXPORT +char* dbus_bus_get_id (DBusConnection *connection, + DBusError *error); +DBUS_EXPORT +int dbus_bus_request_name (DBusConnection *connection, + const char *name, + unsigned int flags, + DBusError *error); +DBUS_EXPORT +int dbus_bus_release_name (DBusConnection *connection, + const char *name, + DBusError *error); +DBUS_EXPORT +dbus_bool_t dbus_bus_name_has_owner (DBusConnection *connection, + const char *name, + DBusError *error); + +DBUS_EXPORT +dbus_bool_t dbus_bus_start_service_by_name (DBusConnection *connection, + const char *name, + dbus_uint32_t flags, + dbus_uint32_t *reply, + DBusError *error); + +DBUS_EXPORT +void dbus_bus_add_match (DBusConnection *connection, + const char *rule, + DBusError *error); +DBUS_EXPORT +void dbus_bus_remove_match (DBusConnection *connection, + const char *rule, + DBusError *error); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_BUS_H */ diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-connection.h b/thirdparty/linuxbsd_headers/dbus/dbus-connection.h new file mode 100644 index 0000000000..bed5424216 --- /dev/null +++ b/thirdparty/linuxbsd_headers/dbus/dbus-connection.h @@ -0,0 +1,526 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-connection.h DBusConnection object + * + * Copyright (C) 2002, 2003 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_CONNECTION_H +#define DBUS_CONNECTION_H + +#include <dbus/dbus-errors.h> +#include <dbus/dbus-macros.h> +#include <dbus/dbus-memory.h> +#include <dbus/dbus-message.h> +#include <dbus/dbus-shared.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusConnection + * @{ + */ + +/* documented in dbus-watch.c */ +typedef struct DBusWatch DBusWatch; +/* documented in dbus-timeout.c */ +typedef struct DBusTimeout DBusTimeout; +/** Opaque type representing preallocated resources so a message can be sent without further memory allocation. */ +typedef struct DBusPreallocatedSend DBusPreallocatedSend; +/** Opaque type representing a method call that has not yet received a reply. */ +typedef struct DBusPendingCall DBusPendingCall; +/** Opaque type representing a connection to a remote application and associated incoming/outgoing message queues. */ +typedef struct DBusConnection DBusConnection; +/** Set of functions that must be implemented to handle messages sent to a particular object path. */ +typedef struct DBusObjectPathVTable DBusObjectPathVTable; + +/** + * Indicates the status of a #DBusWatch. + */ +typedef enum +{ + DBUS_WATCH_READABLE = 1 << 0, /**< As in POLLIN */ + DBUS_WATCH_WRITABLE = 1 << 1, /**< As in POLLOUT */ + DBUS_WATCH_ERROR = 1 << 2, /**< As in POLLERR (can't watch for + * this, but can be present in + * current state passed to + * dbus_watch_handle()). + */ + DBUS_WATCH_HANGUP = 1 << 3 /**< As in POLLHUP (can't watch for + * it, but can be present in current + * state passed to + * dbus_watch_handle()). + */ + /* Internal to libdbus, there is also _DBUS_WATCH_NVAL in dbus-watch.h */ +} DBusWatchFlags; + +/** + * Indicates the status of incoming data on a #DBusConnection. This determines whether + * dbus_connection_dispatch() needs to be called. + */ +typedef enum +{ + DBUS_DISPATCH_DATA_REMAINS, /**< There is more data to potentially convert to messages. */ + DBUS_DISPATCH_COMPLETE, /**< All currently available data has been processed. */ + DBUS_DISPATCH_NEED_MEMORY /**< More memory is needed to continue. */ +} DBusDispatchStatus; + +/** Called when libdbus needs a new watch to be monitored by the main + * loop. Returns #FALSE if it lacks enough memory to add the + * watch. Set by dbus_connection_set_watch_functions() or + * dbus_server_set_watch_functions(). + */ +typedef dbus_bool_t (* DBusAddWatchFunction) (DBusWatch *watch, + void *data); +/** Called when dbus_watch_get_enabled() may return a different value + * than it did before. Set by dbus_connection_set_watch_functions() + * or dbus_server_set_watch_functions(). + */ +typedef void (* DBusWatchToggledFunction) (DBusWatch *watch, + void *data); +/** Called when libdbus no longer needs a watch to be monitored by the + * main loop. Set by dbus_connection_set_watch_functions() or + * dbus_server_set_watch_functions(). + */ +typedef void (* DBusRemoveWatchFunction) (DBusWatch *watch, + void *data); +/** Called when libdbus needs a new timeout to be monitored by the main + * loop. Returns #FALSE if it lacks enough memory to add the + * watch. Set by dbus_connection_set_timeout_functions() or + * dbus_server_set_timeout_functions(). + */ +typedef dbus_bool_t (* DBusAddTimeoutFunction) (DBusTimeout *timeout, + void *data); +/** Called when dbus_timeout_get_enabled() may return a different + * value than it did before. + * Set by dbus_connection_set_timeout_functions() or + * dbus_server_set_timeout_functions(). + */ +typedef void (* DBusTimeoutToggledFunction) (DBusTimeout *timeout, + void *data); +/** Called when libdbus no longer needs a timeout to be monitored by the + * main loop. Set by dbus_connection_set_timeout_functions() or + * dbus_server_set_timeout_functions(). + */ +typedef void (* DBusRemoveTimeoutFunction) (DBusTimeout *timeout, + void *data); +/** Called when the return value of dbus_connection_get_dispatch_status() + * may have changed. Set with dbus_connection_set_dispatch_status_function(). + */ +typedef void (* DBusDispatchStatusFunction) (DBusConnection *connection, + DBusDispatchStatus new_status, + void *data); +/** + * Called when the main loop's thread should be notified that there's now work + * to do. Set with dbus_connection_set_wakeup_main_function(). + */ +typedef void (* DBusWakeupMainFunction) (void *data); + +/** + * Called during authentication to check whether the given UNIX user + * ID is allowed to connect, if the client tried to auth as a UNIX + * user ID. Normally on Windows this would never happen. Set with + * dbus_connection_set_unix_user_function(). + */ +typedef dbus_bool_t (* DBusAllowUnixUserFunction) (DBusConnection *connection, + unsigned long uid, + void *data); + +/** + * Called during authentication to check whether the given Windows user + * ID is allowed to connect, if the client tried to auth as a Windows + * user ID. Normally on UNIX this would never happen. Set with + * dbus_connection_set_windows_user_function(). + */ +typedef dbus_bool_t (* DBusAllowWindowsUserFunction) (DBusConnection *connection, + const char *user_sid, + void *data); + + +/** + * Called when a pending call now has a reply available. Set with + * dbus_pending_call_set_notify(). + */ +typedef void (* DBusPendingCallNotifyFunction) (DBusPendingCall *pending, + void *user_data); + +/** + * Called when a message needs to be handled. The result indicates whether or + * not more handlers should be run. Set with dbus_connection_add_filter(). + */ +typedef DBusHandlerResult (* DBusHandleMessageFunction) (DBusConnection *connection, + DBusMessage *message, + void *user_data); +DBUS_EXPORT +DBusConnection* dbus_connection_open (const char *address, + DBusError *error); +DBUS_EXPORT +DBusConnection* dbus_connection_open_private (const char *address, + DBusError *error); +DBUS_EXPORT +DBusConnection* dbus_connection_ref (DBusConnection *connection); +DBUS_EXPORT +void dbus_connection_unref (DBusConnection *connection); +DBUS_EXPORT +void dbus_connection_close (DBusConnection *connection); +DBUS_EXPORT +dbus_bool_t dbus_connection_get_is_connected (DBusConnection *connection); +DBUS_EXPORT +dbus_bool_t dbus_connection_get_is_authenticated (DBusConnection *connection); +DBUS_EXPORT +dbus_bool_t dbus_connection_get_is_anonymous (DBusConnection *connection); +DBUS_EXPORT +char* dbus_connection_get_server_id (DBusConnection *connection); +DBUS_EXPORT +dbus_bool_t dbus_connection_can_send_type (DBusConnection *connection, + int type); + +DBUS_EXPORT +void dbus_connection_set_exit_on_disconnect (DBusConnection *connection, + dbus_bool_t exit_on_disconnect); +DBUS_EXPORT +void dbus_connection_flush (DBusConnection *connection); +DBUS_EXPORT +dbus_bool_t dbus_connection_read_write_dispatch (DBusConnection *connection, + int timeout_milliseconds); +DBUS_EXPORT +dbus_bool_t dbus_connection_read_write (DBusConnection *connection, + int timeout_milliseconds); +DBUS_EXPORT +DBusMessage* dbus_connection_borrow_message (DBusConnection *connection); +DBUS_EXPORT +void dbus_connection_return_message (DBusConnection *connection, + DBusMessage *message); +DBUS_EXPORT +void dbus_connection_steal_borrowed_message (DBusConnection *connection, + DBusMessage *message); +DBUS_EXPORT +DBusMessage* dbus_connection_pop_message (DBusConnection *connection); +DBUS_EXPORT +DBusDispatchStatus dbus_connection_get_dispatch_status (DBusConnection *connection); +DBUS_EXPORT +DBusDispatchStatus dbus_connection_dispatch (DBusConnection *connection); +DBUS_EXPORT +dbus_bool_t dbus_connection_has_messages_to_send (DBusConnection *connection); +DBUS_EXPORT +dbus_bool_t dbus_connection_send (DBusConnection *connection, + DBusMessage *message, + dbus_uint32_t *client_serial); +DBUS_EXPORT +dbus_bool_t dbus_connection_send_with_reply (DBusConnection *connection, + DBusMessage *message, + DBusPendingCall **pending_return, + int timeout_milliseconds); +DBUS_EXPORT +DBusMessage * dbus_connection_send_with_reply_and_block (DBusConnection *connection, + DBusMessage *message, + int timeout_milliseconds, + DBusError *error); +DBUS_EXPORT +dbus_bool_t dbus_connection_set_watch_functions (DBusConnection *connection, + DBusAddWatchFunction add_function, + DBusRemoveWatchFunction remove_function, + DBusWatchToggledFunction toggled_function, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +dbus_bool_t dbus_connection_set_timeout_functions (DBusConnection *connection, + DBusAddTimeoutFunction add_function, + DBusRemoveTimeoutFunction remove_function, + DBusTimeoutToggledFunction toggled_function, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +void dbus_connection_set_wakeup_main_function (DBusConnection *connection, + DBusWakeupMainFunction wakeup_main_function, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +void dbus_connection_set_dispatch_status_function (DBusConnection *connection, + DBusDispatchStatusFunction function, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +dbus_bool_t dbus_connection_get_unix_user (DBusConnection *connection, + unsigned long *uid); +DBUS_EXPORT +dbus_bool_t dbus_connection_get_unix_process_id (DBusConnection *connection, + unsigned long *pid); +DBUS_EXPORT +dbus_bool_t dbus_connection_get_adt_audit_session_data (DBusConnection *connection, + void **data, + dbus_int32_t *data_size); +DBUS_EXPORT +void dbus_connection_set_unix_user_function (DBusConnection *connection, + DBusAllowUnixUserFunction function, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +dbus_bool_t dbus_connection_get_windows_user (DBusConnection *connection, + char **windows_sid_p); +DBUS_EXPORT +void dbus_connection_set_windows_user_function (DBusConnection *connection, + DBusAllowWindowsUserFunction function, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +void dbus_connection_set_allow_anonymous (DBusConnection *connection, + dbus_bool_t value); +DBUS_EXPORT +void dbus_connection_set_route_peer_messages (DBusConnection *connection, + dbus_bool_t value); + + +/* Filters */ + +DBUS_EXPORT +dbus_bool_t dbus_connection_add_filter (DBusConnection *connection, + DBusHandleMessageFunction function, + void *user_data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +void dbus_connection_remove_filter (DBusConnection *connection, + DBusHandleMessageFunction function, + void *user_data); + + +/* Other */ +DBUS_EXPORT +dbus_bool_t dbus_connection_allocate_data_slot (dbus_int32_t *slot_p); +DBUS_EXPORT +void dbus_connection_free_data_slot (dbus_int32_t *slot_p); +DBUS_EXPORT +dbus_bool_t dbus_connection_set_data (DBusConnection *connection, + dbus_int32_t slot, + void *data, + DBusFreeFunction free_data_func); +DBUS_EXPORT +void* dbus_connection_get_data (DBusConnection *connection, + dbus_int32_t slot); + +DBUS_EXPORT +void dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe); + +DBUS_EXPORT +void dbus_connection_set_max_message_size (DBusConnection *connection, + long size); +DBUS_EXPORT +long dbus_connection_get_max_message_size (DBusConnection *connection); +DBUS_EXPORT +void dbus_connection_set_max_received_size (DBusConnection *connection, + long size); +DBUS_EXPORT +long dbus_connection_get_max_received_size (DBusConnection *connection); + +DBUS_EXPORT +void dbus_connection_set_max_message_unix_fds (DBusConnection *connection, + long n); +DBUS_EXPORT +long dbus_connection_get_max_message_unix_fds (DBusConnection *connection); +DBUS_EXPORT +void dbus_connection_set_max_received_unix_fds(DBusConnection *connection, + long n); +DBUS_EXPORT +long dbus_connection_get_max_received_unix_fds(DBusConnection *connection); + +DBUS_EXPORT +long dbus_connection_get_outgoing_size (DBusConnection *connection); +DBUS_EXPORT +long dbus_connection_get_outgoing_unix_fds (DBusConnection *connection); + +DBUS_EXPORT +DBusPreallocatedSend* dbus_connection_preallocate_send (DBusConnection *connection); +DBUS_EXPORT +void dbus_connection_free_preallocated_send (DBusConnection *connection, + DBusPreallocatedSend *preallocated); +DBUS_EXPORT +void dbus_connection_send_preallocated (DBusConnection *connection, + DBusPreallocatedSend *preallocated, + DBusMessage *message, + dbus_uint32_t *client_serial); + + +/* Object tree functionality */ + +/** + * Called when a #DBusObjectPathVTable is unregistered (or its connection is freed). + * Found in #DBusObjectPathVTable. + */ +typedef void (* DBusObjectPathUnregisterFunction) (DBusConnection *connection, + void *user_data); +/** + * Called when a message is sent to a registered object path. Found in + * #DBusObjectPathVTable which is registered with dbus_connection_register_object_path() + * or dbus_connection_register_fallback(). + */ +typedef DBusHandlerResult (* DBusObjectPathMessageFunction) (DBusConnection *connection, + DBusMessage *message, + void *user_data); + +/** + * Virtual table that must be implemented to handle a portion of the + * object path hierarchy. Attach the vtable to a particular path using + * dbus_connection_register_object_path() or + * dbus_connection_register_fallback(). + */ +struct DBusObjectPathVTable +{ + DBusObjectPathUnregisterFunction unregister_function; /**< Function to unregister this handler */ + DBusObjectPathMessageFunction message_function; /**< Function to handle messages */ + + void (* dbus_internal_pad1) (void *); /**< Reserved for future expansion */ + void (* dbus_internal_pad2) (void *); /**< Reserved for future expansion */ + void (* dbus_internal_pad3) (void *); /**< Reserved for future expansion */ + void (* dbus_internal_pad4) (void *); /**< Reserved for future expansion */ +}; + +DBUS_EXPORT +dbus_bool_t dbus_connection_try_register_object_path (DBusConnection *connection, + const char *path, + const DBusObjectPathVTable *vtable, + void *user_data, + DBusError *error); + +DBUS_EXPORT +dbus_bool_t dbus_connection_register_object_path (DBusConnection *connection, + const char *path, + const DBusObjectPathVTable *vtable, + void *user_data); + +DBUS_EXPORT +dbus_bool_t dbus_connection_try_register_fallback (DBusConnection *connection, + const char *path, + const DBusObjectPathVTable *vtable, + void *user_data, + DBusError *error); + +DBUS_EXPORT +dbus_bool_t dbus_connection_register_fallback (DBusConnection *connection, + const char *path, + const DBusObjectPathVTable *vtable, + void *user_data); +DBUS_EXPORT +dbus_bool_t dbus_connection_unregister_object_path (DBusConnection *connection, + const char *path); + +DBUS_EXPORT +dbus_bool_t dbus_connection_get_object_path_data (DBusConnection *connection, + const char *path, + void **data_p); + +DBUS_EXPORT +dbus_bool_t dbus_connection_list_registered (DBusConnection *connection, + const char *parent_path, + char ***child_entries); + +DBUS_EXPORT +dbus_bool_t dbus_connection_get_unix_fd (DBusConnection *connection, + int *fd); +DBUS_EXPORT +dbus_bool_t dbus_connection_get_socket (DBusConnection *connection, + int *fd); + +/** + * Clear a variable or struct member that contains a #DBusConnection. + * If it does not contain #NULL, the connection that was previously + * there is unreferenced with dbus_connection_unref(). + * + * For example, this function and the similar functions for + * other reference-counted types can be used in code like this: + * + * @code + * DBusConnection *conn = NULL; + * struct { ...; DBusMessage *m; ... } *larger_structure = ...; + * + * ... code that might set conn or m to be non-NULL ... + * + * dbus_clear_connection (&conn); + * dbus_clear_message (&larger_structure->m); + * @endcode + * + * @param pointer_to_connection A pointer to a variable or struct member. + * pointer_to_connection must not be #NULL, but *pointer_to_connection + * may be #NULL. + */ +static inline void +dbus_clear_connection (DBusConnection **pointer_to_connection) +{ + _dbus_clear_pointer_impl (DBusConnection, pointer_to_connection, + dbus_connection_unref); +} + +/** @} */ + + +/** + * @addtogroup DBusWatch + * @{ + */ + +#ifndef DBUS_DISABLE_DEPRECATED +DBUS_EXPORT +DBUS_DEPRECATED int dbus_watch_get_fd (DBusWatch *watch); +#endif + +DBUS_EXPORT +int dbus_watch_get_unix_fd (DBusWatch *watch); +DBUS_EXPORT +int dbus_watch_get_socket (DBusWatch *watch); +DBUS_EXPORT +unsigned int dbus_watch_get_flags (DBusWatch *watch); +DBUS_EXPORT +void* dbus_watch_get_data (DBusWatch *watch); +DBUS_EXPORT +void dbus_watch_set_data (DBusWatch *watch, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +dbus_bool_t dbus_watch_handle (DBusWatch *watch, + unsigned int flags); +DBUS_EXPORT +dbus_bool_t dbus_watch_get_enabled (DBusWatch *watch); + +/** @} */ + +/** + * @addtogroup DBusTimeout + * @{ + */ + +DBUS_EXPORT +int dbus_timeout_get_interval (DBusTimeout *timeout); +DBUS_EXPORT +void* dbus_timeout_get_data (DBusTimeout *timeout); +DBUS_EXPORT +void dbus_timeout_set_data (DBusTimeout *timeout, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +dbus_bool_t dbus_timeout_handle (DBusTimeout *timeout); +DBUS_EXPORT +dbus_bool_t dbus_timeout_get_enabled (DBusTimeout *timeout); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_CONNECTION_H */ diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-errors.h b/thirdparty/linuxbsd_headers/dbus/dbus-errors.h new file mode 100644 index 0000000000..3804085b9e --- /dev/null +++ b/thirdparty/linuxbsd_headers/dbus/dbus-errors.h @@ -0,0 +1,90 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-errors.h Error reporting + * + * Copyright (C) 2002 Red Hat Inc. + * Copyright (C) 2003 CodeFactory AB + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_ERROR_H +#define DBUS_ERROR_H + +#include <dbus/dbus-macros.h> +#include <dbus/dbus-types.h> +#include <dbus/dbus-protocol.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusErrors + * @{ + */ + +/** Mostly-opaque type representing an error that occurred */ +typedef struct DBusError DBusError; + +/** + * Object representing an exception. + */ +struct DBusError +{ + const char *name; /**< public error name field */ + const char *message; /**< public error message field */ + + unsigned int dummy1 : 1; /**< placeholder */ + unsigned int dummy2 : 1; /**< placeholder */ + unsigned int dummy3 : 1; /**< placeholder */ + unsigned int dummy4 : 1; /**< placeholder */ + unsigned int dummy5 : 1; /**< placeholder */ + + void *padding1; /**< placeholder */ +}; + +#define DBUS_ERROR_INIT { NULL, NULL, TRUE, 0, 0, 0, 0, NULL } + +DBUS_EXPORT +void dbus_error_init (DBusError *error); +DBUS_EXPORT +void dbus_error_free (DBusError *error); +DBUS_EXPORT +void dbus_set_error (DBusError *error, + const char *name, + const char *message, + ...) _DBUS_GNUC_PRINTF (3, 4); +DBUS_EXPORT +void dbus_set_error_const (DBusError *error, + const char *name, + const char *message); +DBUS_EXPORT +void dbus_move_error (DBusError *src, + DBusError *dest); +DBUS_EXPORT +dbus_bool_t dbus_error_has_name (const DBusError *error, + const char *name); +DBUS_EXPORT +dbus_bool_t dbus_error_is_set (const DBusError *error); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_ERROR_H */ diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-macros.h b/thirdparty/linuxbsd_headers/dbus/dbus-macros.h new file mode 100644 index 0000000000..2c8956e30e --- /dev/null +++ b/thirdparty/linuxbsd_headers/dbus/dbus-macros.h @@ -0,0 +1,240 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-macros.h generic macros + * + * Copyright (C) 2002 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_MACROS_H +#define DBUS_MACROS_H + +#ifdef __cplusplus +# define DBUS_BEGIN_DECLS extern "C" { +# define DBUS_END_DECLS } +#else +# define DBUS_BEGIN_DECLS +# define DBUS_END_DECLS +#endif + +#ifndef TRUE +# define TRUE 1 +#endif +#ifndef FALSE +# define FALSE 0 +#endif + +#ifndef NULL +# ifdef __cplusplus +# define NULL (0L) +# else /* !__cplusplus */ +# define NULL ((void*) 0) +# endif /* !__cplusplus */ +#endif + +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) +# define DBUS_DEPRECATED __attribute__ ((__deprecated__)) +#elif defined(_MSC_VER) && (_MSC_VER >= 1300) +# define DBUS_DEPRECATED __declspec(deprecated) +#else +# define DBUS_DEPRECATED +#endif + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8) +# define _DBUS_GNUC_EXTENSION __extension__ +#else +# define _DBUS_GNUC_EXTENSION +#endif + +#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)) || \ + defined(__clang__) +#define _DBUS_GNUC_PRINTF( format_idx, arg_idx ) \ + __attribute__((__format__ (__printf__, format_idx, arg_idx))) +#define _DBUS_GNUC_NORETURN \ + __attribute__((__noreturn__)) +#define _DBUS_GNUC_UNUSED \ + __attribute__((__unused__)) +#else /* !__GNUC__ */ +#define _DBUS_GNUC_PRINTF( format_idx, arg_idx ) +#define _DBUS_GNUC_NORETURN +#define _DBUS_GNUC_UNUSED +#endif /* !__GNUC__ */ + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) +#define DBUS_MALLOC __attribute__((__malloc__)) +#else +#define DBUS_MALLOC +#endif + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) +#define DBUS_ALLOC_SIZE(x) __attribute__((__alloc_size__(x))) +#define DBUS_ALLOC_SIZE2(x,y) __attribute__((__alloc_size__(x,y))) +#else +#define DBUS_ALLOC_SIZE(x) +#define DBUS_ALLOC_SIZE2(x,y) +#endif + +#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +#define _DBUS_GNUC_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +#define _DBUS_GNUC_WARN_UNUSED_RESULT +#endif + +/** @def _DBUS_GNUC_PRINTF + * used to tell gcc about printf format strings + */ +/** @def _DBUS_GNUC_NORETURN + * used to tell gcc about functions that never return, such as _dbus_abort() + */ +/** @def _DBUS_GNUC_WARN_UNUSED_RESULT + * used to tell gcc about functions whose result must be used + */ + +/* Normally docs are in .c files, but there isn't a .c file for this. */ +/** + * @defgroup DBusMacros Utility macros + * @ingroup DBus + * @brief #TRUE, #FALSE, #NULL, and so on + * + * Utility macros. + * + * @{ + */ + +/** + * @def DBUS_BEGIN_DECLS + * + * Macro used prior to declaring functions in the D-Bus header + * files. Expands to "extern "C"" when using a C++ compiler, + * and expands to nothing when using a C compiler. + * + * Please don't use this in your own code, consider it + * D-Bus internal. + */ +/** + * @def DBUS_END_DECLS + * + * Macro used after declaring functions in the D-Bus header + * files. Expands to "}" when using a C++ compiler, + * and expands to nothing when using a C compiler. + * + * Please don't use this in your own code, consider it + * D-Bus internal. + */ +/** + * @def TRUE + * + * Expands to "1" + */ +/** + * @def FALSE + * + * Expands to "0" + */ +/** + * @def NULL + * + * A null pointer, defined appropriately for C or C++. + */ +/** + * @def DBUS_DEPRECATED + * + * Tells the compiler to warn about a function or type if it's used. + * Code marked in this way should also be enclosed in + * @code + * #ifndef DBUS_DISABLE_DEPRECATED + * deprecated stuff here + * #endif + * @endcode + * + * Please don't use this in your own code, consider it + * D-Bus internal. + */ +/** + * @def _DBUS_GNUC_EXTENSION + * + * Tells gcc not to warn about extensions to the C standard in the + * following expression, even if compiling with -pedantic. Do not use + * this macro in your own code; please consider it to be internal to libdbus. + */ + +/* + * @def DBUS_EXPORT + * + * Declare the following symbol as public. This is currently a noop on + * platforms other than Windows. + */ + +#if defined(DBUS_EXPORT) + /* value forced by compiler command line, don't redefine */ +#elif defined(_WIN32) +# if defined(DBUS_STATIC_BUILD) +# define DBUS_EXPORT +# elif defined(dbus_1_EXPORTS) +# define DBUS_EXPORT __declspec(dllexport) +# else +# define DBUS_EXPORT __declspec(dllimport) +# endif +#elif defined(__GNUC__) && __GNUC__ >= 4 +# define DBUS_EXPORT __attribute__ ((__visibility__ ("default"))) +#else +#define DBUS_EXPORT +#endif + +#if defined(DBUS_PRIVATE_EXPORT) + /* value forced by compiler command line, don't redefine */ +#elif defined(_WIN32) +# if defined(DBUS_STATIC_BUILD) +# define DBUS_PRIVATE_EXPORT /* no decoration */ +# elif defined(dbus_1_EXPORTS) +# define DBUS_PRIVATE_EXPORT __declspec(dllexport) +# else +# define DBUS_PRIVATE_EXPORT __declspec(dllimport) +# endif +#elif defined(__GNUC__) && __GNUC__ >= 4 +# define DBUS_PRIVATE_EXPORT __attribute__ ((__visibility__ ("default"))) +#else +# define DBUS_PRIVATE_EXPORT /* no decoration */ +#endif + +/* Implementation for dbus_clear_message() etc. This is not API, + * do not use it directly. + * + * We're using a specific type (T ** and T *) instead of void ** and + * void * partly for type-safety, partly to be strict-aliasing-compliant, + * and partly to keep C++ compilers happy. This code is inlined into + * users of libdbus, so we can't rely on it having dbus' own compiler + * settings. */ +#define _dbus_clear_pointer_impl(T, pointer_to_pointer, destroy) \ + do { \ + T **_pp = (pointer_to_pointer); \ + T *_value = *_pp; \ + \ + *_pp = NULL; \ + \ + if (_value != NULL) \ + destroy (_value); \ + } while (0) +/* Not (destroy) (_value) in case destroy() is a function-like macro */ + +/** @} */ + +#endif /* DBUS_MACROS_H */ diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-memory.h b/thirdparty/linuxbsd_headers/dbus/dbus-memory.h new file mode 100644 index 0000000000..4fd56bd633 --- /dev/null +++ b/thirdparty/linuxbsd_headers/dbus/dbus-memory.h @@ -0,0 +1,73 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-memory.h D-Bus memory handling + * + * Copyright (C) 2002 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_MEMORY_H +#define DBUS_MEMORY_H + +#include <dbus/dbus-macros.h> +#include <stddef.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusMemory + * @{ + */ + +DBUS_EXPORT +DBUS_MALLOC +DBUS_ALLOC_SIZE(1) +void* dbus_malloc (size_t bytes); + +DBUS_EXPORT +DBUS_MALLOC +DBUS_ALLOC_SIZE(1) +void* dbus_malloc0 (size_t bytes); + +DBUS_EXPORT +DBUS_MALLOC +DBUS_ALLOC_SIZE(2) +void* dbus_realloc (void *memory, + size_t bytes); +DBUS_EXPORT +void dbus_free (void *memory); + +#define dbus_new(type, count) ((type*)dbus_malloc (sizeof (type) * (count))) +#define dbus_new0(type, count) ((type*)dbus_malloc0 (sizeof (type) * (count))) + +DBUS_EXPORT +void dbus_free_string_array (char **str_array); + +typedef void (* DBusFreeFunction) (void *memory); + +DBUS_EXPORT +void dbus_shutdown (void); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_MEMORY_H */ diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-message.h b/thirdparty/linuxbsd_headers/dbus/dbus-message.h new file mode 100644 index 0000000000..8a9d57a0f1 --- /dev/null +++ b/thirdparty/linuxbsd_headers/dbus/dbus-message.h @@ -0,0 +1,377 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-message.h DBusMessage object + * + * Copyright (C) 2002, 2003, 2005 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_MESSAGE_H +#define DBUS_MESSAGE_H + +#include <dbus/dbus-macros.h> +#include <dbus/dbus-types.h> +#include <dbus/dbus-arch-deps.h> +#include <dbus/dbus-memory.h> +#include <dbus/dbus-errors.h> +#include <stdarg.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusMessage + * @{ + */ + +typedef struct DBusMessage DBusMessage; +/** + * Opaque type representing a message iterator. Can be copied by value and + * allocated on the stack. + * + * A DBusMessageIter usually contains no allocated memory. However, there + * is one special case: after a successful call to + * dbus_message_iter_open_container(), the caller is responsible for calling + * either dbus_message_iter_close_container() or + * dbus_message_iter_abandon_container() exactly once, with the same pair + * of iterators. + */ +typedef struct DBusMessageIter DBusMessageIter; + +/** + * DBusMessageIter struct; contains no public fields. + */ +struct DBusMessageIter +{ + void *dummy1; /**< Don't use this */ + void *dummy2; /**< Don't use this */ + dbus_uint32_t dummy3; /**< Don't use this */ + int dummy4; /**< Don't use this */ + int dummy5; /**< Don't use this */ + int dummy6; /**< Don't use this */ + int dummy7; /**< Don't use this */ + int dummy8; /**< Don't use this */ + int dummy9; /**< Don't use this */ + int dummy10; /**< Don't use this */ + int dummy11; /**< Don't use this */ + int pad1; /**< Don't use this */ + void *pad2; /**< Don't use this */ + void *pad3; /**< Don't use this */ +}; + +/** + * A message iterator for which dbus_message_iter_abandon_container_if_open() + * is the only valid operation. + */ +#define DBUS_MESSAGE_ITER_INIT_CLOSED \ +{ \ + NULL, /* dummy1 */ \ + NULL, /* dummy2 */ \ + 0, /* dummy3 */ \ + 0, /* dummy4 */ \ + 0, /* dummy5 */ \ + 0, /* dummy6 */ \ + 0, /* dummy7 */ \ + 0, /* dummy8 */ \ + 0, /* dummy9 */ \ + 0, /* dummy10 */ \ + 0, /* dummy11 */ \ + 0, /* pad1 */ \ + NULL, /* pad2 */ \ + NULL /* pad3 */ \ +} + +DBUS_EXPORT +DBusMessage* dbus_message_new (int message_type); +DBUS_EXPORT +DBusMessage* dbus_message_new_method_call (const char *bus_name, + const char *path, + const char *iface, + const char *method); +DBUS_EXPORT +DBusMessage* dbus_message_new_method_return (DBusMessage *method_call); +DBUS_EXPORT +DBusMessage* dbus_message_new_signal (const char *path, + const char *iface, + const char *name); +DBUS_EXPORT +DBusMessage* dbus_message_new_error (DBusMessage *reply_to, + const char *error_name, + const char *error_message); +DBUS_EXPORT +DBusMessage* dbus_message_new_error_printf (DBusMessage *reply_to, + const char *error_name, + const char *error_format, + ...) _DBUS_GNUC_PRINTF (3, 4); + +DBUS_EXPORT +DBusMessage* dbus_message_copy (const DBusMessage *message); + +DBUS_EXPORT +DBusMessage* dbus_message_ref (DBusMessage *message); +DBUS_EXPORT +void dbus_message_unref (DBusMessage *message); +DBUS_EXPORT +int dbus_message_get_type (DBusMessage *message); +DBUS_EXPORT +dbus_bool_t dbus_message_set_path (DBusMessage *message, + const char *object_path); +DBUS_EXPORT +const char* dbus_message_get_path (DBusMessage *message); +DBUS_EXPORT +dbus_bool_t dbus_message_has_path (DBusMessage *message, + const char *object_path); +DBUS_EXPORT +dbus_bool_t dbus_message_set_interface (DBusMessage *message, + const char *iface); +DBUS_EXPORT +const char* dbus_message_get_interface (DBusMessage *message); +DBUS_EXPORT +dbus_bool_t dbus_message_has_interface (DBusMessage *message, + const char *iface); +DBUS_EXPORT +dbus_bool_t dbus_message_set_member (DBusMessage *message, + const char *member); +DBUS_EXPORT +const char* dbus_message_get_member (DBusMessage *message); +DBUS_EXPORT +dbus_bool_t dbus_message_has_member (DBusMessage *message, + const char *member); +DBUS_EXPORT +dbus_bool_t dbus_message_set_error_name (DBusMessage *message, + const char *name); +DBUS_EXPORT +const char* dbus_message_get_error_name (DBusMessage *message); +DBUS_EXPORT +dbus_bool_t dbus_message_set_destination (DBusMessage *message, + const char *destination); +DBUS_EXPORT +const char* dbus_message_get_destination (DBusMessage *message); +DBUS_EXPORT +dbus_bool_t dbus_message_set_sender (DBusMessage *message, + const char *sender); +DBUS_EXPORT +const char* dbus_message_get_sender (DBusMessage *message); +DBUS_EXPORT +const char* dbus_message_get_signature (DBusMessage *message); +DBUS_EXPORT +void dbus_message_set_no_reply (DBusMessage *message, + dbus_bool_t no_reply); +DBUS_EXPORT +dbus_bool_t dbus_message_get_no_reply (DBusMessage *message); +DBUS_EXPORT +dbus_bool_t dbus_message_is_method_call (DBusMessage *message, + const char *iface, + const char *method); +DBUS_EXPORT +dbus_bool_t dbus_message_is_signal (DBusMessage *message, + const char *iface, + const char *signal_name); +DBUS_EXPORT +dbus_bool_t dbus_message_is_error (DBusMessage *message, + const char *error_name); +DBUS_EXPORT +dbus_bool_t dbus_message_has_destination (DBusMessage *message, + const char *bus_name); +DBUS_EXPORT +dbus_bool_t dbus_message_has_sender (DBusMessage *message, + const char *unique_bus_name); +DBUS_EXPORT +dbus_bool_t dbus_message_has_signature (DBusMessage *message, + const char *signature); +DBUS_EXPORT +dbus_uint32_t dbus_message_get_serial (DBusMessage *message); +DBUS_EXPORT +void dbus_message_set_serial (DBusMessage *message, + dbus_uint32_t serial); +DBUS_EXPORT +dbus_bool_t dbus_message_set_reply_serial (DBusMessage *message, + dbus_uint32_t reply_serial); +DBUS_EXPORT +dbus_uint32_t dbus_message_get_reply_serial (DBusMessage *message); + +DBUS_EXPORT +void dbus_message_set_auto_start (DBusMessage *message, + dbus_bool_t auto_start); +DBUS_EXPORT +dbus_bool_t dbus_message_get_auto_start (DBusMessage *message); + +DBUS_EXPORT +dbus_bool_t dbus_message_get_path_decomposed (DBusMessage *message, + char ***path); + +DBUS_EXPORT +dbus_bool_t dbus_message_append_args (DBusMessage *message, + int first_arg_type, + ...); +DBUS_EXPORT +dbus_bool_t dbus_message_append_args_valist (DBusMessage *message, + int first_arg_type, + va_list var_args); +DBUS_EXPORT +dbus_bool_t dbus_message_get_args (DBusMessage *message, + DBusError *error, + int first_arg_type, + ...); +DBUS_EXPORT +dbus_bool_t dbus_message_get_args_valist (DBusMessage *message, + DBusError *error, + int first_arg_type, + va_list var_args); + +DBUS_EXPORT +dbus_bool_t dbus_message_contains_unix_fds (DBusMessage *message); + +DBUS_EXPORT +void dbus_message_iter_init_closed (DBusMessageIter *iter); +DBUS_EXPORT +dbus_bool_t dbus_message_iter_init (DBusMessage *message, + DBusMessageIter *iter); +DBUS_EXPORT +dbus_bool_t dbus_message_iter_has_next (DBusMessageIter *iter); +DBUS_EXPORT +dbus_bool_t dbus_message_iter_next (DBusMessageIter *iter); +DBUS_EXPORT +char* dbus_message_iter_get_signature (DBusMessageIter *iter); +DBUS_EXPORT +int dbus_message_iter_get_arg_type (DBusMessageIter *iter); +DBUS_EXPORT +int dbus_message_iter_get_element_type (DBusMessageIter *iter); +DBUS_EXPORT +void dbus_message_iter_recurse (DBusMessageIter *iter, + DBusMessageIter *sub); +DBUS_EXPORT +void dbus_message_iter_get_basic (DBusMessageIter *iter, + void *value); +DBUS_EXPORT +int dbus_message_iter_get_element_count(DBusMessageIter *iter); + +#ifndef DBUS_DISABLE_DEPRECATED +/* This function returns the wire protocol size of the array in bytes, + * you do not want to know that probably + */ +DBUS_EXPORT +DBUS_DEPRECATED int dbus_message_iter_get_array_len (DBusMessageIter *iter); +#endif +DBUS_EXPORT +void dbus_message_iter_get_fixed_array (DBusMessageIter *iter, + void *value, + int *n_elements); + + +DBUS_EXPORT +void dbus_message_iter_init_append (DBusMessage *message, + DBusMessageIter *iter); +DBUS_EXPORT +dbus_bool_t dbus_message_iter_append_basic (DBusMessageIter *iter, + int type, + const void *value); +DBUS_EXPORT +dbus_bool_t dbus_message_iter_append_fixed_array (DBusMessageIter *iter, + int element_type, + const void *value, + int n_elements); +DBUS_EXPORT +dbus_bool_t dbus_message_iter_open_container (DBusMessageIter *iter, + int type, + const char *contained_signature, + DBusMessageIter *sub); +DBUS_EXPORT +dbus_bool_t dbus_message_iter_close_container (DBusMessageIter *iter, + DBusMessageIter *sub); +DBUS_EXPORT +void dbus_message_iter_abandon_container (DBusMessageIter *iter, + DBusMessageIter *sub); + +DBUS_EXPORT +void dbus_message_iter_abandon_container_if_open (DBusMessageIter *iter, + DBusMessageIter *sub); + +DBUS_EXPORT +void dbus_message_lock (DBusMessage *message); + +DBUS_EXPORT +dbus_bool_t dbus_set_error_from_message (DBusError *error, + DBusMessage *message); + + +DBUS_EXPORT +dbus_bool_t dbus_message_allocate_data_slot (dbus_int32_t *slot_p); +DBUS_EXPORT +void dbus_message_free_data_slot (dbus_int32_t *slot_p); +DBUS_EXPORT +dbus_bool_t dbus_message_set_data (DBusMessage *message, + dbus_int32_t slot, + void *data, + DBusFreeFunction free_data_func); +DBUS_EXPORT +void* dbus_message_get_data (DBusMessage *message, + dbus_int32_t slot); + +DBUS_EXPORT +int dbus_message_type_from_string (const char *type_str); +DBUS_EXPORT +const char* dbus_message_type_to_string (int type); + +DBUS_EXPORT +dbus_bool_t dbus_message_marshal (DBusMessage *msg, + char **marshalled_data_p, + int *len_p); +DBUS_EXPORT +DBusMessage* dbus_message_demarshal (const char *str, + int len, + DBusError *error); + +DBUS_EXPORT +int dbus_message_demarshal_bytes_needed (const char *str, + int len); + +DBUS_EXPORT +void dbus_message_set_allow_interactive_authorization (DBusMessage *message, + dbus_bool_t allow); + +DBUS_EXPORT +dbus_bool_t dbus_message_get_allow_interactive_authorization ( + DBusMessage *message); + +/** + * Clear a variable or struct member that contains a #DBusMessage. + * If it does not contain #NULL, the message that was previously + * there is unreferenced with dbus_message_unref(). + * + * This is very similar to dbus_clear_connection(): see that function + * for more details. + * + * @param pointer_to_message A pointer to a variable or struct member. + * pointer_to_message must not be #NULL, but *pointer_to_message + * may be #NULL. + */ +static inline void +dbus_clear_message (DBusMessage **pointer_to_message) +{ + _dbus_clear_pointer_impl (DBusMessage, pointer_to_message, + dbus_message_unref); +} + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_MESSAGE_H */ diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-misc.h b/thirdparty/linuxbsd_headers/dbus/dbus-misc.h new file mode 100644 index 0000000000..d78d79931e --- /dev/null +++ b/thirdparty/linuxbsd_headers/dbus/dbus-misc.h @@ -0,0 +1,59 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-misc.h A few assorted public functions that don't fit elsewhere + * + * Copyright (C) 2006 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_MISC_H +#define DBUS_MISC_H + +#include <dbus/dbus-types.h> +#include <dbus/dbus-errors.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusMisc + * @{ + */ +DBUS_EXPORT +char* dbus_get_local_machine_id (void); + +DBUS_EXPORT +void dbus_get_version (int *major_version_p, + int *minor_version_p, + int *micro_version_p); + +DBUS_EXPORT +dbus_bool_t dbus_setenv (const char *variable, + const char *value); + +DBUS_EXPORT +char *dbus_try_get_local_machine_id (DBusError *error); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_MISC_H */ + diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-pending-call.h b/thirdparty/linuxbsd_headers/dbus/dbus-pending-call.h new file mode 100644 index 0000000000..5593397a3a --- /dev/null +++ b/thirdparty/linuxbsd_headers/dbus/dbus-pending-call.h @@ -0,0 +1,98 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-pending-call.h Object representing a call in progress. + * + * Copyright (C) 2002, 2003 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_PENDING_CALL_H +#define DBUS_PENDING_CALL_H + +#include <dbus/dbus-macros.h> +#include <dbus/dbus-types.h> +#include <dbus/dbus-connection.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusPendingCall + * @{ + */ + +#define DBUS_TIMEOUT_INFINITE ((int) 0x7fffffff) +#define DBUS_TIMEOUT_USE_DEFAULT (-1) + +DBUS_EXPORT +DBusPendingCall* dbus_pending_call_ref (DBusPendingCall *pending); +DBUS_EXPORT +void dbus_pending_call_unref (DBusPendingCall *pending); +DBUS_EXPORT +dbus_bool_t dbus_pending_call_set_notify (DBusPendingCall *pending, + DBusPendingCallNotifyFunction function, + void *user_data, + DBusFreeFunction free_user_data); +DBUS_EXPORT +void dbus_pending_call_cancel (DBusPendingCall *pending); +DBUS_EXPORT +dbus_bool_t dbus_pending_call_get_completed (DBusPendingCall *pending); +DBUS_EXPORT +DBusMessage* dbus_pending_call_steal_reply (DBusPendingCall *pending); +DBUS_EXPORT +void dbus_pending_call_block (DBusPendingCall *pending); + +DBUS_EXPORT +dbus_bool_t dbus_pending_call_allocate_data_slot (dbus_int32_t *slot_p); +DBUS_EXPORT +void dbus_pending_call_free_data_slot (dbus_int32_t *slot_p); +DBUS_EXPORT +dbus_bool_t dbus_pending_call_set_data (DBusPendingCall *pending, + dbus_int32_t slot, + void *data, + DBusFreeFunction free_data_func); +DBUS_EXPORT +void* dbus_pending_call_get_data (DBusPendingCall *pending, + dbus_int32_t slot); + +/** + * Clear a variable or struct member that contains a #DBusPendingCall. + * If it does not contain #NULL, the pending call that was previously + * there is unreferenced with dbus_pending_call_unref(). + * + * This is very similar to dbus_clear_connection(): see that function + * for more details. + * + * @param pointer_to_pending_call A pointer to a variable or struct member. + * pointer_to_pending_call must not be #NULL, but *pointer_to_pending_call + * may be #NULL. + */ +static inline void +dbus_clear_pending_call (DBusPendingCall **pointer_to_pending_call) +{ + _dbus_clear_pointer_impl (DBusPendingCall, pointer_to_pending_call, + dbus_pending_call_unref); +} + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_PENDING_CALL_H */ diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-protocol.h b/thirdparty/linuxbsd_headers/dbus/dbus-protocol.h new file mode 100644 index 0000000000..2b7fd2313a --- /dev/null +++ b/thirdparty/linuxbsd_headers/dbus/dbus-protocol.h @@ -0,0 +1,481 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-protocol.h D-Bus protocol constants + * + * Copyright (C) 2002, 2003 CodeFactory AB + * Copyright (C) 2004, 2005 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_PROTOCOL_H +#define DBUS_PROTOCOL_H + +/* Don't include anything in here from anywhere else. It's + * intended for use by any random library. + */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* avoids confusing emacs indentation */ +#endif +#endif + +/* Normally docs are in .c files, but there isn't a .c file for this. */ +/** + * @defgroup DBusProtocol Protocol constants + * @ingroup DBus + * + * @brief Defines constants which are part of the D-Bus protocol + * + * This header is intended for use by any library, not only libdbus. + * + * @{ + */ + + +/* Message byte order */ +#define DBUS_LITTLE_ENDIAN ('l') /**< Code marking LSB-first byte order in the wire protocol. */ +#define DBUS_BIG_ENDIAN ('B') /**< Code marking MSB-first byte order in the wire protocol. */ + +/** Protocol version. */ +#define DBUS_MAJOR_PROTOCOL_VERSION 1 + +/** Type code that is never equal to a legitimate type code */ +#define DBUS_TYPE_INVALID ((int) '\0') +/** #DBUS_TYPE_INVALID as a string literal instead of a int literal */ +#define DBUS_TYPE_INVALID_AS_STRING "\0" + +/* Primitive types */ +/** Type code marking an 8-bit unsigned integer */ +#define DBUS_TYPE_BYTE ((int) 'y') +/** #DBUS_TYPE_BYTE as a string literal instead of a int literal */ +#define DBUS_TYPE_BYTE_AS_STRING "y" +/** Type code marking a boolean */ +#define DBUS_TYPE_BOOLEAN ((int) 'b') +/** #DBUS_TYPE_BOOLEAN as a string literal instead of a int literal */ +#define DBUS_TYPE_BOOLEAN_AS_STRING "b" +/** Type code marking a 16-bit signed integer */ +#define DBUS_TYPE_INT16 ((int) 'n') +/** #DBUS_TYPE_INT16 as a string literal instead of a int literal */ +#define DBUS_TYPE_INT16_AS_STRING "n" +/** Type code marking a 16-bit unsigned integer */ +#define DBUS_TYPE_UINT16 ((int) 'q') +/** #DBUS_TYPE_UINT16 as a string literal instead of a int literal */ +#define DBUS_TYPE_UINT16_AS_STRING "q" +/** Type code marking a 32-bit signed integer */ +#define DBUS_TYPE_INT32 ((int) 'i') +/** #DBUS_TYPE_INT32 as a string literal instead of a int literal */ +#define DBUS_TYPE_INT32_AS_STRING "i" +/** Type code marking a 32-bit unsigned integer */ +#define DBUS_TYPE_UINT32 ((int) 'u') +/** #DBUS_TYPE_UINT32 as a string literal instead of a int literal */ +#define DBUS_TYPE_UINT32_AS_STRING "u" +/** Type code marking a 64-bit signed integer */ +#define DBUS_TYPE_INT64 ((int) 'x') +/** #DBUS_TYPE_INT64 as a string literal instead of a int literal */ +#define DBUS_TYPE_INT64_AS_STRING "x" +/** Type code marking a 64-bit unsigned integer */ +#define DBUS_TYPE_UINT64 ((int) 't') +/** #DBUS_TYPE_UINT64 as a string literal instead of a int literal */ +#define DBUS_TYPE_UINT64_AS_STRING "t" +/** Type code marking an 8-byte double in IEEE 754 format */ +#define DBUS_TYPE_DOUBLE ((int) 'd') +/** #DBUS_TYPE_DOUBLE as a string literal instead of a int literal */ +#define DBUS_TYPE_DOUBLE_AS_STRING "d" +/** Type code marking a UTF-8 encoded, nul-terminated Unicode string */ +#define DBUS_TYPE_STRING ((int) 's') +/** #DBUS_TYPE_STRING as a string literal instead of a int literal */ +#define DBUS_TYPE_STRING_AS_STRING "s" +/** Type code marking a D-Bus object path */ +#define DBUS_TYPE_OBJECT_PATH ((int) 'o') +/** #DBUS_TYPE_OBJECT_PATH as a string literal instead of a int literal */ +#define DBUS_TYPE_OBJECT_PATH_AS_STRING "o" +/** Type code marking a D-Bus type signature */ +#define DBUS_TYPE_SIGNATURE ((int) 'g') +/** #DBUS_TYPE_SIGNATURE as a string literal instead of a int literal */ +#define DBUS_TYPE_SIGNATURE_AS_STRING "g" +/** Type code marking a unix file descriptor */ +#define DBUS_TYPE_UNIX_FD ((int) 'h') +/** #DBUS_TYPE_UNIX_FD as a string literal instead of a int literal */ +#define DBUS_TYPE_UNIX_FD_AS_STRING "h" + +/* Compound types */ +/** Type code marking a D-Bus array type */ +#define DBUS_TYPE_ARRAY ((int) 'a') +/** #DBUS_TYPE_ARRAY as a string literal instead of a int literal */ +#define DBUS_TYPE_ARRAY_AS_STRING "a" +/** Type code marking a D-Bus variant type */ +#define DBUS_TYPE_VARIANT ((int) 'v') +/** #DBUS_TYPE_VARIANT as a string literal instead of a int literal */ +#define DBUS_TYPE_VARIANT_AS_STRING "v" + +/** STRUCT and DICT_ENTRY are sort of special since their codes can't + * appear in a type string, instead + * DBUS_STRUCT_BEGIN_CHAR/DBUS_DICT_ENTRY_BEGIN_CHAR have to appear + */ +/** Type code used to represent a struct; however, this type code does not appear + * in type signatures, instead #DBUS_STRUCT_BEGIN_CHAR and #DBUS_STRUCT_END_CHAR will + * appear in a signature. + */ +#define DBUS_TYPE_STRUCT ((int) 'r') +/** #DBUS_TYPE_STRUCT as a string literal instead of a int literal */ +#define DBUS_TYPE_STRUCT_AS_STRING "r" +/** Type code used to represent a dict entry; however, this type code does not appear + * in type signatures, instead #DBUS_DICT_ENTRY_BEGIN_CHAR and #DBUS_DICT_ENTRY_END_CHAR will + * appear in a signature. + */ +#define DBUS_TYPE_DICT_ENTRY ((int) 'e') +/** #DBUS_TYPE_DICT_ENTRY as a string literal instead of a int literal */ +#define DBUS_TYPE_DICT_ENTRY_AS_STRING "e" + +/** Does not include #DBUS_TYPE_INVALID, #DBUS_STRUCT_BEGIN_CHAR, #DBUS_STRUCT_END_CHAR, + * #DBUS_DICT_ENTRY_BEGIN_CHAR, or #DBUS_DICT_ENTRY_END_CHAR - i.e. it is the number of + * valid types, not the number of distinct characters that may appear in a type signature. + */ +#define DBUS_NUMBER_OF_TYPES (16) + +/* characters other than typecodes that appear in type signatures */ + +/** Code marking the start of a struct type in a type signature */ +#define DBUS_STRUCT_BEGIN_CHAR ((int) '(') +/** #DBUS_STRUCT_BEGIN_CHAR as a string literal instead of a int literal */ +#define DBUS_STRUCT_BEGIN_CHAR_AS_STRING "(" +/** Code marking the end of a struct type in a type signature */ +#define DBUS_STRUCT_END_CHAR ((int) ')') +/** #DBUS_STRUCT_END_CHAR a string literal instead of a int literal */ +#define DBUS_STRUCT_END_CHAR_AS_STRING ")" +/** Code marking the start of a dict entry type in a type signature */ +#define DBUS_DICT_ENTRY_BEGIN_CHAR ((int) '{') +/** #DBUS_DICT_ENTRY_BEGIN_CHAR as a string literal instead of a int literal */ +#define DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING "{" +/** Code marking the end of a dict entry type in a type signature */ +#define DBUS_DICT_ENTRY_END_CHAR ((int) '}') +/** #DBUS_DICT_ENTRY_END_CHAR as a string literal instead of a int literal */ +#define DBUS_DICT_ENTRY_END_CHAR_AS_STRING "}" + +/** Max length in bytes of a bus name, interface, or member (not object + * path, paths are unlimited). This is limited because lots of stuff + * is O(n) in this number, plus it would be obnoxious to type in a + * paragraph-long method name so most likely something like that would + * be an exploit. + */ +#define DBUS_MAXIMUM_NAME_LENGTH 255 + +/** This one is 255 so it fits in a byte */ +#define DBUS_MAXIMUM_SIGNATURE_LENGTH 255 + +/** Max length of a match rule string; to keep people from hosing the + * daemon with some huge rule + */ +#define DBUS_MAXIMUM_MATCH_RULE_LENGTH 1024 + +/** Max arg number you can match on in a match rule, e.g. + * arg0='hello' is OK, arg3489720987='hello' is not + */ +#define DBUS_MAXIMUM_MATCH_RULE_ARG_NUMBER 63 + +/** Max length of a marshaled array in bytes (64M, 2^26) We use signed + * int for lengths so must be INT_MAX or less. We need something a + * bit smaller than INT_MAX because the array is inside a message with + * header info, etc. so an INT_MAX array wouldn't allow the message + * overhead. The 64M number is an attempt at a larger number than + * we'd reasonably ever use, but small enough that your bus would chew + * through it fairly quickly without locking up forever. If you have + * data that's likely to be larger than this, you should probably be + * sending it in multiple incremental messages anyhow. + */ +#define DBUS_MAXIMUM_ARRAY_LENGTH (67108864) +/** Number of bits you need in an unsigned to store the max array size */ +#define DBUS_MAXIMUM_ARRAY_LENGTH_BITS 26 + +/** The maximum total message size including header and body; similar + * rationale to max array size. + */ +#define DBUS_MAXIMUM_MESSAGE_LENGTH (DBUS_MAXIMUM_ARRAY_LENGTH * 2) +/** Number of bits you need in an unsigned to store the max message size */ +#define DBUS_MAXIMUM_MESSAGE_LENGTH_BITS 27 + +/** The maximum total number of unix fds in a message. Similar + * rationale as DBUS_MAXIMUM_MESSAGE_LENGTH. However we divide by four + * given that one fd is an int and hence at least 32 bits. + */ +#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS (DBUS_MAXIMUM_MESSAGE_LENGTH/4) +/** Number of bits you need in an unsigned to store the max message unix fds */ +#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS_BITS (DBUS_MAXIMUM_MESSAGE_LENGTH_BITS-2) + +/** Depth of recursion in the type tree. This is automatically limited + * to DBUS_MAXIMUM_SIGNATURE_LENGTH since you could only have an array + * of array of array of ... that fit in the max signature. But that's + * probably a bit too large. + */ +#define DBUS_MAXIMUM_TYPE_RECURSION_DEPTH 32 + +/* Types of message */ + +/** This value is never a valid message type, see dbus_message_get_type() */ +#define DBUS_MESSAGE_TYPE_INVALID 0 +/** Message type of a method call message, see dbus_message_get_type() */ +#define DBUS_MESSAGE_TYPE_METHOD_CALL 1 +/** Message type of a method return message, see dbus_message_get_type() */ +#define DBUS_MESSAGE_TYPE_METHOD_RETURN 2 +/** Message type of an error reply message, see dbus_message_get_type() */ +#define DBUS_MESSAGE_TYPE_ERROR 3 +/** Message type of a signal message, see dbus_message_get_type() */ +#define DBUS_MESSAGE_TYPE_SIGNAL 4 + +#define DBUS_NUM_MESSAGE_TYPES 5 + +/* Header flags */ + +/** If set, this flag means that the sender of a message does not care about getting + * a reply, so the recipient need not send one. See dbus_message_set_no_reply(). + */ +#define DBUS_HEADER_FLAG_NO_REPLY_EXPECTED 0x1 +/** + * If set, this flag means that even if the message bus knows how to start an owner for + * the destination bus name (see dbus_message_set_destination()), it should not + * do so. If this flag is not set, the bus may launch a program to process the + * message. + */ +#define DBUS_HEADER_FLAG_NO_AUTO_START 0x2 +/** + * If set on a method call, this flag means that the caller is prepared to + * wait for interactive authorization. + */ +#define DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION 0x4 + +/* Header fields */ + +/** Not equal to any valid header field code */ +#define DBUS_HEADER_FIELD_INVALID 0 +/** Header field code for the path - the path is the object emitting a signal or the object receiving a method call. + * See dbus_message_set_path(). + */ +#define DBUS_HEADER_FIELD_PATH 1 +/** Header field code for the interface containing a member (method or signal). + * See dbus_message_set_interface(). + */ +#define DBUS_HEADER_FIELD_INTERFACE 2 +/** Header field code for a member (method or signal). See dbus_message_set_member(). */ +#define DBUS_HEADER_FIELD_MEMBER 3 +/** Header field code for an error name (found in #DBUS_MESSAGE_TYPE_ERROR messages). + * See dbus_message_set_error_name(). + */ +#define DBUS_HEADER_FIELD_ERROR_NAME 4 +/** Header field code for a reply serial, used to match a #DBUS_MESSAGE_TYPE_METHOD_RETURN message with the + * message that it's a reply to. See dbus_message_set_reply_serial(). + */ +#define DBUS_HEADER_FIELD_REPLY_SERIAL 5 +/** + * Header field code for the destination bus name of a message. See dbus_message_set_destination(). + */ +#define DBUS_HEADER_FIELD_DESTINATION 6 +/** + * Header field code for the sender of a message; usually initialized by the message bus. + * See dbus_message_set_sender(). + */ +#define DBUS_HEADER_FIELD_SENDER 7 +/** + * Header field code for the type signature of a message. + */ +#define DBUS_HEADER_FIELD_SIGNATURE 8 +/** + * Header field code for the number of unix file descriptors associated + * with this message. + */ +#define DBUS_HEADER_FIELD_UNIX_FDS 9 + + +/** + * Value of the highest-numbered header field code, can be used to determine + * the size of an array indexed by header field code. Remember though + * that unknown codes must be ignored, so check for that before + * indexing the array. + */ +#define DBUS_HEADER_FIELD_LAST DBUS_HEADER_FIELD_UNIX_FDS + +/** Header format is defined as a signature: + * byte byte order + * byte message type ID + * byte flags + * byte protocol version + * uint32 body length + * uint32 serial + * array of struct (byte,variant) (field name, value) + * + * The length of the header can be computed as the + * fixed size of the initial data, plus the length of + * the array at the end, plus padding to an 8-boundary. + */ +#define DBUS_HEADER_SIGNATURE \ + DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_UINT32_AS_STRING \ + DBUS_TYPE_UINT32_AS_STRING \ + DBUS_TYPE_ARRAY_AS_STRING \ + DBUS_STRUCT_BEGIN_CHAR_AS_STRING \ + DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_VARIANT_AS_STRING \ + DBUS_STRUCT_END_CHAR_AS_STRING + + +/** + * The smallest header size that can occur. (It won't be valid due to + * missing required header fields.) This is 4 bytes, two uint32, an + * array length. This isn't any kind of resource limit, just the + * necessary/logical outcome of the header signature. + */ +#define DBUS_MINIMUM_HEADER_SIZE 16 + +/* Errors */ +/* WARNING these get autoconverted to an enum in dbus-glib.h. Thus, + * if you change the order it breaks the ABI. Keep them in order. + * Also, don't change the formatting since that will break the sed + * script. + */ +/** A generic error; "something went wrong" - see the error message for more. */ +#define DBUS_ERROR_FAILED "org.freedesktop.DBus.Error.Failed" +/** There was not enough memory to complete an operation. */ +#define DBUS_ERROR_NO_MEMORY "org.freedesktop.DBus.Error.NoMemory" +/** The bus doesn't know how to launch a service to supply the bus name you wanted. */ +#define DBUS_ERROR_SERVICE_UNKNOWN "org.freedesktop.DBus.Error.ServiceUnknown" +/** The bus name you referenced doesn't exist (i.e. no application owns it). */ +#define DBUS_ERROR_NAME_HAS_NO_OWNER "org.freedesktop.DBus.Error.NameHasNoOwner" +/** No reply to a message expecting one, usually means a timeout occurred. */ +#define DBUS_ERROR_NO_REPLY "org.freedesktop.DBus.Error.NoReply" +/** Something went wrong reading or writing to a socket, for example. */ +#define DBUS_ERROR_IO_ERROR "org.freedesktop.DBus.Error.IOError" +/** A D-Bus bus address was malformed. */ +#define DBUS_ERROR_BAD_ADDRESS "org.freedesktop.DBus.Error.BadAddress" +/** Requested operation isn't supported (like ENOSYS on UNIX). */ +#define DBUS_ERROR_NOT_SUPPORTED "org.freedesktop.DBus.Error.NotSupported" +/** Some limited resource is exhausted. */ +#define DBUS_ERROR_LIMITS_EXCEEDED "org.freedesktop.DBus.Error.LimitsExceeded" +/** Security restrictions don't allow doing what you're trying to do. */ +#define DBUS_ERROR_ACCESS_DENIED "org.freedesktop.DBus.Error.AccessDenied" +/** Authentication didn't work. */ +#define DBUS_ERROR_AUTH_FAILED "org.freedesktop.DBus.Error.AuthFailed" +/** Unable to connect to server (probably caused by ECONNREFUSED on a socket). */ +#define DBUS_ERROR_NO_SERVER "org.freedesktop.DBus.Error.NoServer" +/** Certain timeout errors, possibly ETIMEDOUT on a socket. + * Note that #DBUS_ERROR_NO_REPLY is used for message reply timeouts. + * @warning this is confusingly-named given that #DBUS_ERROR_TIMED_OUT also exists. We can't fix + * it for compatibility reasons so just be careful. + */ +#define DBUS_ERROR_TIMEOUT "org.freedesktop.DBus.Error.Timeout" +/** No network access (probably ENETUNREACH on a socket). */ +#define DBUS_ERROR_NO_NETWORK "org.freedesktop.DBus.Error.NoNetwork" +/** Can't bind a socket since its address is in use (i.e. EADDRINUSE). */ +#define DBUS_ERROR_ADDRESS_IN_USE "org.freedesktop.DBus.Error.AddressInUse" +/** The connection is disconnected and you're trying to use it. */ +#define DBUS_ERROR_DISCONNECTED "org.freedesktop.DBus.Error.Disconnected" +/** Invalid arguments passed to a method call. */ +#define DBUS_ERROR_INVALID_ARGS "org.freedesktop.DBus.Error.InvalidArgs" +/** Missing file. */ +#define DBUS_ERROR_FILE_NOT_FOUND "org.freedesktop.DBus.Error.FileNotFound" +/** Existing file and the operation you're using does not silently overwrite. */ +#define DBUS_ERROR_FILE_EXISTS "org.freedesktop.DBus.Error.FileExists" +/** Method name you invoked isn't known by the object you invoked it on. */ +#define DBUS_ERROR_UNKNOWN_METHOD "org.freedesktop.DBus.Error.UnknownMethod" +/** Object you invoked a method on isn't known. */ +#define DBUS_ERROR_UNKNOWN_OBJECT "org.freedesktop.DBus.Error.UnknownObject" +/** Interface you invoked a method on isn't known by the object. */ +#define DBUS_ERROR_UNKNOWN_INTERFACE "org.freedesktop.DBus.Error.UnknownInterface" +/** Property you tried to access isn't known by the object. */ +#define DBUS_ERROR_UNKNOWN_PROPERTY "org.freedesktop.DBus.Error.UnknownProperty" +/** Property you tried to set is read-only. */ +#define DBUS_ERROR_PROPERTY_READ_ONLY "org.freedesktop.DBus.Error.PropertyReadOnly" +/** Certain timeout errors, e.g. while starting a service. + * @warning this is confusingly-named given that #DBUS_ERROR_TIMEOUT also exists. We can't fix + * it for compatibility reasons so just be careful. + */ +#define DBUS_ERROR_TIMED_OUT "org.freedesktop.DBus.Error.TimedOut" +/** Tried to remove or modify a match rule that didn't exist. */ +#define DBUS_ERROR_MATCH_RULE_NOT_FOUND "org.freedesktop.DBus.Error.MatchRuleNotFound" +/** The match rule isn't syntactically valid. */ +#define DBUS_ERROR_MATCH_RULE_INVALID "org.freedesktop.DBus.Error.MatchRuleInvalid" +/** While starting a new process, the exec() call failed. */ +#define DBUS_ERROR_SPAWN_EXEC_FAILED "org.freedesktop.DBus.Error.Spawn.ExecFailed" +/** While starting a new process, the fork() call failed. */ +#define DBUS_ERROR_SPAWN_FORK_FAILED "org.freedesktop.DBus.Error.Spawn.ForkFailed" +/** While starting a new process, the child exited with a status code. */ +#define DBUS_ERROR_SPAWN_CHILD_EXITED "org.freedesktop.DBus.Error.Spawn.ChildExited" +/** While starting a new process, the child exited on a signal. */ +#define DBUS_ERROR_SPAWN_CHILD_SIGNALED "org.freedesktop.DBus.Error.Spawn.ChildSignaled" +/** While starting a new process, something went wrong. */ +#define DBUS_ERROR_SPAWN_FAILED "org.freedesktop.DBus.Error.Spawn.Failed" +/** We failed to setup the environment correctly. */ +#define DBUS_ERROR_SPAWN_SETUP_FAILED "org.freedesktop.DBus.Error.Spawn.FailedToSetup" +/** We failed to setup the config parser correctly. */ +#define DBUS_ERROR_SPAWN_CONFIG_INVALID "org.freedesktop.DBus.Error.Spawn.ConfigInvalid" +/** Bus name was not valid. */ +#define DBUS_ERROR_SPAWN_SERVICE_INVALID "org.freedesktop.DBus.Error.Spawn.ServiceNotValid" +/** Service file not found in system-services directory. */ +#define DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND "org.freedesktop.DBus.Error.Spawn.ServiceNotFound" +/** Permissions are incorrect on the setuid helper. */ +#define DBUS_ERROR_SPAWN_PERMISSIONS_INVALID "org.freedesktop.DBus.Error.Spawn.PermissionsInvalid" +/** Service file invalid (Name, User or Exec missing). */ +#define DBUS_ERROR_SPAWN_FILE_INVALID "org.freedesktop.DBus.Error.Spawn.FileInvalid" +/** Tried to get a UNIX process ID and it wasn't available. */ +#define DBUS_ERROR_SPAWN_NO_MEMORY "org.freedesktop.DBus.Error.Spawn.NoMemory" +/** Tried to get a UNIX process ID and it wasn't available. */ +#define DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN "org.freedesktop.DBus.Error.UnixProcessIdUnknown" +/** A type signature is not valid. */ +#define DBUS_ERROR_INVALID_SIGNATURE "org.freedesktop.DBus.Error.InvalidSignature" +/** A file contains invalid syntax or is otherwise broken. */ +#define DBUS_ERROR_INVALID_FILE_CONTENT "org.freedesktop.DBus.Error.InvalidFileContent" +/** Asked for SELinux security context and it wasn't available. */ +#define DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown" +/** Asked for AppArmor security context and it wasn't available. */ +#define DBUS_ERROR_APPARMOR_SECURITY_CONTEXT_UNKNOWN "org.freedesktop.DBus.Error.AppArmorSecurityContextUnknown" +/** Asked for ADT audit data and it wasn't available. */ +#define DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN "org.freedesktop.DBus.Error.AdtAuditDataUnknown" +/** There's already an object with the requested object path. */ +#define DBUS_ERROR_OBJECT_PATH_IN_USE "org.freedesktop.DBus.Error.ObjectPathInUse" +/** The message meta data does not match the payload. e.g. expected + number of file descriptors were not sent over the socket this message was received on. */ +#define DBUS_ERROR_INCONSISTENT_MESSAGE "org.freedesktop.DBus.Error.InconsistentMessage" +/** The message is not allowed without performing interactive authorization, + * but could have succeeded if an interactive authorization step was + * allowed. */ +#define DBUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED "org.freedesktop.DBus.Error.InteractiveAuthorizationRequired" + +/* XML introspection format */ + +/** XML namespace of the introspection format version 1.0 */ +#define DBUS_INTROSPECT_1_0_XML_NAMESPACE "http://www.freedesktop.org/standards/dbus" +/** XML public identifier of the introspection format version 1.0 */ +#define DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" +/** XML system identifier of the introspection format version 1.0 */ +#define DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd" +/** XML document type declaration of the introspection format version 1.0 */ +#define DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE "<!DOCTYPE node PUBLIC \"" DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER "\"\n\"" DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER "\">\n" + +/** @} */ + +#ifdef __cplusplus +#if 0 +{ /* avoids confusing emacs indentation */ +#endif +} +#endif + +#endif /* DBUS_PROTOCOL_H */ diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-server.h b/thirdparty/linuxbsd_headers/dbus/dbus-server.h new file mode 100644 index 0000000000..7d8f04e496 --- /dev/null +++ b/thirdparty/linuxbsd_headers/dbus/dbus-server.h @@ -0,0 +1,125 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-server.h DBusServer object + * + * Copyright (C) 2002, 2003 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_SERVER_H +#define DBUS_SERVER_H + +#include <dbus/dbus-errors.h> +#include <dbus/dbus-macros.h> +#include <dbus/dbus-message.h> +#include <dbus/dbus-connection.h> +#include <dbus/dbus-protocol.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusServer + * @{ + */ + +typedef struct DBusServer DBusServer; + +/** Called when a new connection to the server is available. Must reference and save the new + * connection, or close the new connection. Set with dbus_server_set_new_connection_function(). + */ +typedef void (* DBusNewConnectionFunction) (DBusServer *server, + DBusConnection *new_connection, + void *data); + +DBUS_EXPORT +DBusServer* dbus_server_listen (const char *address, + DBusError *error); +DBUS_EXPORT +DBusServer* dbus_server_ref (DBusServer *server); +DBUS_EXPORT +void dbus_server_unref (DBusServer *server); +DBUS_EXPORT +void dbus_server_disconnect (DBusServer *server); +DBUS_EXPORT +dbus_bool_t dbus_server_get_is_connected (DBusServer *server); +DBUS_EXPORT +char* dbus_server_get_address (DBusServer *server); +DBUS_EXPORT +char* dbus_server_get_id (DBusServer *server); +DBUS_EXPORT +void dbus_server_set_new_connection_function (DBusServer *server, + DBusNewConnectionFunction function, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +dbus_bool_t dbus_server_set_watch_functions (DBusServer *server, + DBusAddWatchFunction add_function, + DBusRemoveWatchFunction remove_function, + DBusWatchToggledFunction toggled_function, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +dbus_bool_t dbus_server_set_timeout_functions (DBusServer *server, + DBusAddTimeoutFunction add_function, + DBusRemoveTimeoutFunction remove_function, + DBusTimeoutToggledFunction toggled_function, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +dbus_bool_t dbus_server_set_auth_mechanisms (DBusServer *server, + const char **mechanisms); + +DBUS_EXPORT +dbus_bool_t dbus_server_allocate_data_slot (dbus_int32_t *slot_p); +DBUS_EXPORT +void dbus_server_free_data_slot (dbus_int32_t *slot_p); +DBUS_EXPORT +dbus_bool_t dbus_server_set_data (DBusServer *server, + int slot, + void *data, + DBusFreeFunction free_data_func); +DBUS_EXPORT +void* dbus_server_get_data (DBusServer *server, + int slot); + +/** + * Clear a variable or struct member that contains a #DBusServer. + * If it does not contain #NULL, the server that was previously + * there is unreferenced with dbus_server_unref(). + * + * This is very similar to dbus_clear_connection(): see that function + * for more details. + * + * @param pointer_to_server A pointer to a variable or struct member. + * pointer_to_server must not be #NULL, but *pointer_to_server + * may be #NULL. + */ +static inline void +dbus_clear_server (DBusServer **pointer_to_server) +{ + _dbus_clear_pointer_impl (DBusServer, pointer_to_server, dbus_server_unref); +} + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_SERVER_H */ diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-shared.h b/thirdparty/linuxbsd_headers/dbus/dbus-shared.h new file mode 100644 index 0000000000..7ab91035ea --- /dev/null +++ b/thirdparty/linuxbsd_headers/dbus/dbus-shared.h @@ -0,0 +1,136 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-shared.h Stuff used by both dbus/dbus.h low-level and C/C++ binding APIs + * + * Copyright (C) 2004 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_SHARED_H +#define DBUS_SHARED_H + +/* Don't include anything in here from anywhere else. It's + * intended for use by any random library. + */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* avoids confusing emacs indentation */ +#endif +#endif + +/* Normally docs are in .c files, but there isn't a .c file for this. */ +/** + * @defgroup DBusShared Shared constants + * @ingroup DBus + * + * @brief Shared header included by both libdbus and C/C++ bindings such as the GLib bindings. + * + * Usually a C/C++ binding such as the GLib or Qt binding won't want to include dbus.h in its + * public headers. However, a few constants and macros may be useful to include; those are + * found here and in dbus-protocol.h + * + * @{ + */ + + +/** + * Well-known bus types. See dbus_bus_get(). + */ +typedef enum +{ + DBUS_BUS_SESSION, /**< The login session bus */ + DBUS_BUS_SYSTEM, /**< The systemwide bus */ + DBUS_BUS_STARTER /**< The bus that started us, if any */ +} DBusBusType; + +/** + * Results that a message handler can return. + */ +typedef enum +{ + DBUS_HANDLER_RESULT_HANDLED, /**< Message has had its effect - no need to run more handlers. */ + DBUS_HANDLER_RESULT_NOT_YET_HANDLED, /**< Message has not had any effect - see if other handlers want it. */ + DBUS_HANDLER_RESULT_NEED_MEMORY /**< Need more memory in order to return #DBUS_HANDLER_RESULT_HANDLED or #DBUS_HANDLER_RESULT_NOT_YET_HANDLED. Please try again later with more memory. */ +} DBusHandlerResult; + +/* Bus names */ + +/** The bus name used to talk to the bus itself. */ +#define DBUS_SERVICE_DBUS "org.freedesktop.DBus" + +/* Paths */ +/** The object path used to talk to the bus itself. */ +#define DBUS_PATH_DBUS "/org/freedesktop/DBus" +/** The object path used in local/in-process-generated messages. */ +#define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local" + +/* Interfaces, these #define don't do much other than + * catch typos at compile time + */ +/** The interface exported by the object with #DBUS_SERVICE_DBUS and #DBUS_PATH_DBUS */ +#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus" +/** The monitoring interface exported by the dbus-daemon */ +#define DBUS_INTERFACE_MONITORING "org.freedesktop.DBus.Monitoring" + +/** The verbose interface exported by the dbus-daemon */ +#define DBUS_INTERFACE_VERBOSE "org.freedesktop.DBus.Verbose" +/** The interface supported by introspectable objects */ +#define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable" +/** The interface supported by objects with properties */ +#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties" +/** The interface supported by most dbus peers */ +#define DBUS_INTERFACE_PEER "org.freedesktop.DBus.Peer" + +/** This is a special interface whose methods can only be invoked + * by the local implementation (messages from remote apps aren't + * allowed to specify this interface). + */ +#define DBUS_INTERFACE_LOCAL "org.freedesktop.DBus.Local" + +/* Owner flags */ +#define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 /**< Allow another service to become the primary owner if requested */ +#define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2 /**< Request to replace the current primary owner */ +#define DBUS_NAME_FLAG_DO_NOT_QUEUE 0x4 /**< If we can not become the primary owner do not place us in the queue */ + +/* Replies to request for a name */ +#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1 /**< Service has become the primary owner of the requested name */ +#define DBUS_REQUEST_NAME_REPLY_IN_QUEUE 2 /**< Service could not become the primary owner and has been placed in the queue */ +#define DBUS_REQUEST_NAME_REPLY_EXISTS 3 /**< Service is already in the queue */ +#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4 /**< Service is already the primary owner */ + +/* Replies to releasing a name */ +#define DBUS_RELEASE_NAME_REPLY_RELEASED 1 /**< Service was released from the given name */ +#define DBUS_RELEASE_NAME_REPLY_NON_EXISTENT 2 /**< The given name does not exist on the bus */ +#define DBUS_RELEASE_NAME_REPLY_NOT_OWNER 3 /**< Service is not an owner of the given name */ + +/* Replies to service starts */ +#define DBUS_START_REPLY_SUCCESS 1 /**< Service was auto started */ +#define DBUS_START_REPLY_ALREADY_RUNNING 2 /**< Service was already running */ + +/** @} */ + +#ifdef __cplusplus +#if 0 +{ /* avoids confusing emacs indentation */ +#endif +} +#endif + +#endif /* DBUS_SHARED_H */ diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-signature.h b/thirdparty/linuxbsd_headers/dbus/dbus-signature.h new file mode 100644 index 0000000000..443941c81b --- /dev/null +++ b/thirdparty/linuxbsd_headers/dbus/dbus-signature.h @@ -0,0 +1,95 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-signatures.h utility functions for D-Bus types + * + * Copyright (C) 2005 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_SIGNATURES_H +#define DBUS_SIGNATURES_H + +#include <dbus/dbus-macros.h> +#include <dbus/dbus-types.h> +#include <dbus/dbus-errors.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusSignature + * @{ + */ + +/** + * DBusSignatureIter struct; contains no public fields + */ +typedef struct +{ + void *dummy1; /**< Don't use this */ + void *dummy2; /**< Don't use this */ + dbus_uint32_t dummy8; /**< Don't use this */ + int dummy12; /**< Don't use this */ + int dummy17; /**< Don't use this */ +} DBusSignatureIter; + +DBUS_EXPORT +void dbus_signature_iter_init (DBusSignatureIter *iter, + const char *signature); + +DBUS_EXPORT +int dbus_signature_iter_get_current_type (const DBusSignatureIter *iter); + +DBUS_EXPORT +char * dbus_signature_iter_get_signature (const DBusSignatureIter *iter); + +DBUS_EXPORT +int dbus_signature_iter_get_element_type (const DBusSignatureIter *iter); + +DBUS_EXPORT +dbus_bool_t dbus_signature_iter_next (DBusSignatureIter *iter); + +DBUS_EXPORT +void dbus_signature_iter_recurse (const DBusSignatureIter *iter, + DBusSignatureIter *subiter); + +DBUS_EXPORT +dbus_bool_t dbus_signature_validate (const char *signature, + DBusError *error); + +DBUS_EXPORT +dbus_bool_t dbus_signature_validate_single (const char *signature, + DBusError *error); + +DBUS_EXPORT +dbus_bool_t dbus_type_is_valid (int typecode); + +DBUS_EXPORT +dbus_bool_t dbus_type_is_basic (int typecode); +DBUS_EXPORT +dbus_bool_t dbus_type_is_container (int typecode); +DBUS_EXPORT +dbus_bool_t dbus_type_is_fixed (int typecode); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_SIGNATURE_H */ diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-syntax.h b/thirdparty/linuxbsd_headers/dbus/dbus-syntax.h new file mode 100644 index 0000000000..daf20f06e1 --- /dev/null +++ b/thirdparty/linuxbsd_headers/dbus/dbus-syntax.h @@ -0,0 +1,58 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-syntax.h - utility functions for strings with special syntax + * + * Author: Simon McVittie <simon.mcvittie@collabora.co.uk> + * Copyright © 2011 Nokia Corporation + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_SYNTAX_H +#define DBUS_SYNTAX_H + +#include <dbus/dbus-macros.h> +#include <dbus/dbus-types.h> +#include <dbus/dbus-errors.h> + +DBUS_BEGIN_DECLS + +DBUS_EXPORT +dbus_bool_t dbus_validate_path (const char *path, + DBusError *error); +DBUS_EXPORT +dbus_bool_t dbus_validate_interface (const char *name, + DBusError *error); +DBUS_EXPORT +dbus_bool_t dbus_validate_member (const char *name, + DBusError *error); +DBUS_EXPORT +dbus_bool_t dbus_validate_error_name (const char *name, + DBusError *error); +DBUS_EXPORT +dbus_bool_t dbus_validate_bus_name (const char *name, + DBusError *error); +DBUS_EXPORT +dbus_bool_t dbus_validate_utf8 (const char *alleged_utf8, + DBusError *error); + +DBUS_END_DECLS + +#endif /* multiple-inclusion guard */ diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-threads.h b/thirdparty/linuxbsd_headers/dbus/dbus-threads.h new file mode 100644 index 0000000000..6d28a0b631 --- /dev/null +++ b/thirdparty/linuxbsd_headers/dbus/dbus-threads.h @@ -0,0 +1,189 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-threads.h D-Bus threads handling + * + * Copyright (C) 2002 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_THREADS_H +#define DBUS_THREADS_H + +#include <dbus/dbus-macros.h> +#include <dbus/dbus-types.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusThreads + * @{ + */ + +/** An opaque mutex type provided by the #DBusThreadFunctions implementation installed by dbus_threads_init(). */ +typedef struct DBusMutex DBusMutex; +/** An opaque condition variable type provided by the #DBusThreadFunctions implementation installed by dbus_threads_init(). */ +typedef struct DBusCondVar DBusCondVar; + +/** Deprecated, provide DBusRecursiveMutexNewFunction instead. */ +typedef DBusMutex* (* DBusMutexNewFunction) (void); +/** Deprecated, provide DBusRecursiveMutexFreeFunction instead. */ +typedef void (* DBusMutexFreeFunction) (DBusMutex *mutex); +/** Deprecated, provide DBusRecursiveMutexLockFunction instead. Return value is lock success, but gets ignored in practice. */ +typedef dbus_bool_t (* DBusMutexLockFunction) (DBusMutex *mutex); +/** Deprecated, provide DBusRecursiveMutexUnlockFunction instead. Return value is unlock success, but gets ignored in practice. */ +typedef dbus_bool_t (* DBusMutexUnlockFunction) (DBusMutex *mutex); + +/** Creates a new recursively-lockable mutex, or returns #NULL if not + * enough memory. Can only fail due to lack of memory. Found in + * #DBusThreadFunctions. Do not just use PTHREAD_MUTEX_RECURSIVE for + * this, because it does not save/restore the recursion count when + * waiting on a condition. libdbus requires the Java-style behavior + * where the mutex is fully unlocked to wait on a condition. + */ +typedef DBusMutex* (* DBusRecursiveMutexNewFunction) (void); +/** Frees a recursively-lockable mutex. Found in #DBusThreadFunctions. + */ +typedef void (* DBusRecursiveMutexFreeFunction) (DBusMutex *mutex); +/** Locks a recursively-lockable mutex. Found in #DBusThreadFunctions. + * Can only fail due to lack of memory. + */ +typedef void (* DBusRecursiveMutexLockFunction) (DBusMutex *mutex); +/** Unlocks a recursively-lockable mutex. Found in #DBusThreadFunctions. + * Can only fail due to lack of memory. + */ +typedef void (* DBusRecursiveMutexUnlockFunction) (DBusMutex *mutex); + +/** Creates a new condition variable. Found in #DBusThreadFunctions. + * Can only fail (returning #NULL) due to lack of memory. + */ +typedef DBusCondVar* (* DBusCondVarNewFunction) (void); +/** Frees a condition variable. Found in #DBusThreadFunctions. + */ +typedef void (* DBusCondVarFreeFunction) (DBusCondVar *cond); + +/** Waits on a condition variable. Found in + * #DBusThreadFunctions. Must work with either a recursive or + * nonrecursive mutex, whichever the thread implementation + * provides. Note that PTHREAD_MUTEX_RECURSIVE does not work with + * condition variables (does not save/restore the recursion count) so + * don't try using simply pthread_cond_wait() and a + * PTHREAD_MUTEX_RECURSIVE to implement this, it won't work right. + * + * Has no error conditions. Must succeed if it returns. + */ +typedef void (* DBusCondVarWaitFunction) (DBusCondVar *cond, + DBusMutex *mutex); + +/** Waits on a condition variable with a timeout. Found in + * #DBusThreadFunctions. Returns #TRUE if the wait did not + * time out, and #FALSE if it did. + * + * Has no error conditions. Must succeed if it returns. + */ +typedef dbus_bool_t (* DBusCondVarWaitTimeoutFunction) (DBusCondVar *cond, + DBusMutex *mutex, + int timeout_milliseconds); +/** Wakes one waiting thread on a condition variable. Found in #DBusThreadFunctions. + * + * Has no error conditions. Must succeed if it returns. + */ +typedef void (* DBusCondVarWakeOneFunction) (DBusCondVar *cond); + +/** Wakes all waiting threads on a condition variable. Found in #DBusThreadFunctions. + * + * Has no error conditions. Must succeed if it returns. + */ +typedef void (* DBusCondVarWakeAllFunction) (DBusCondVar *cond); + +/** + * Flags indicating which functions are present in #DBusThreadFunctions. Used to allow + * the library to detect older callers of dbus_threads_init() if new possible functions + * are added to #DBusThreadFunctions. + */ +typedef enum +{ + DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK = 1 << 0, + DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK = 1 << 1, + DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK = 1 << 2, + DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK = 1 << 3, + DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK = 1 << 4, + DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK = 1 << 5, + DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK = 1 << 6, + DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK = 1 << 7, + DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK = 1 << 8, + DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK = 1 << 9, + DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK = 1 << 10, + DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK = 1 << 11, + DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK = 1 << 12, + DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK = 1 << 13, + DBUS_THREAD_FUNCTIONS_ALL_MASK = (1 << 14) - 1 +} DBusThreadFunctionsMask; + +/** + * Functions that must be implemented to make the D-Bus library + * thread-aware. + * + * If you supply both recursive and non-recursive mutexes, + * libdbus will use the non-recursive version for condition variables, + * and the recursive version in other contexts. + * + * The condition variable functions have to work with nonrecursive + * mutexes if you provide those, or with recursive mutexes if you + * don't. + */ +typedef struct +{ + unsigned int mask; /**< Mask indicating which functions are present. */ + + DBusMutexNewFunction mutex_new; /**< Function to create a mutex; optional and deprecated. */ + DBusMutexFreeFunction mutex_free; /**< Function to free a mutex; optional and deprecated. */ + DBusMutexLockFunction mutex_lock; /**< Function to lock a mutex; optional and deprecated. */ + DBusMutexUnlockFunction mutex_unlock; /**< Function to unlock a mutex; optional and deprecated. */ + + DBusCondVarNewFunction condvar_new; /**< Function to create a condition variable */ + DBusCondVarFreeFunction condvar_free; /**< Function to free a condition variable */ + DBusCondVarWaitFunction condvar_wait; /**< Function to wait on a condition */ + DBusCondVarWaitTimeoutFunction condvar_wait_timeout; /**< Function to wait on a condition with a timeout */ + DBusCondVarWakeOneFunction condvar_wake_one; /**< Function to wake one thread waiting on the condition */ + DBusCondVarWakeAllFunction condvar_wake_all; /**< Function to wake all threads waiting on the condition */ + + DBusRecursiveMutexNewFunction recursive_mutex_new; /**< Function to create a recursive mutex */ + DBusRecursiveMutexFreeFunction recursive_mutex_free; /**< Function to free a recursive mutex */ + DBusRecursiveMutexLockFunction recursive_mutex_lock; /**< Function to lock a recursive mutex */ + DBusRecursiveMutexUnlockFunction recursive_mutex_unlock; /**< Function to unlock a recursive mutex */ + + void (* padding1) (void); /**< Reserved for future expansion */ + void (* padding2) (void); /**< Reserved for future expansion */ + void (* padding3) (void); /**< Reserved for future expansion */ + void (* padding4) (void); /**< Reserved for future expansion */ + +} DBusThreadFunctions; + +DBUS_EXPORT +dbus_bool_t dbus_threads_init (const DBusThreadFunctions *functions); +DBUS_EXPORT +dbus_bool_t dbus_threads_init_default (void); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_THREADS_H */ diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-types.h b/thirdparty/linuxbsd_headers/dbus/dbus-types.h new file mode 100644 index 0000000000..021a55af90 --- /dev/null +++ b/thirdparty/linuxbsd_headers/dbus/dbus-types.h @@ -0,0 +1,156 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-types.h types such as dbus_bool_t + * + * Copyright (C) 2002 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_TYPES_H +#define DBUS_TYPES_H + +#include <stddef.h> +#include <dbus/dbus-arch-deps.h> + +typedef dbus_uint32_t dbus_unichar_t; +/* boolean size must be fixed at 4 bytes due to wire protocol! */ +typedef dbus_uint32_t dbus_bool_t; + +/* Normally docs are in .c files, but there isn't a .c file for this. */ +/** + * @defgroup DBusTypes Basic types + * @ingroup DBus + * @brief dbus_bool_t, dbus_int32_t, etc. + * + * Typedefs for common primitive types. + * + * @{ + */ + +/** + * @typedef dbus_bool_t + * + * A boolean, valid values are #TRUE and #FALSE. + */ + +/** + * @typedef dbus_uint32_t + * + * A 32-bit unsigned integer on all platforms. + */ + +/** + * @typedef dbus_int32_t + * + * A 32-bit signed integer on all platforms. + */ + +/** + * @typedef dbus_uint16_t + * + * A 16-bit unsigned integer on all platforms. + */ + +/** + * @typedef dbus_int16_t + * + * A 16-bit signed integer on all platforms. + */ + + +/** + * @typedef dbus_uint64_t + * + * A 64-bit unsigned integer. + */ + +/** + * @typedef dbus_int64_t + * + * A 64-bit signed integer. + */ + +/** + * @def DBUS_HAVE_INT64 + * + * Always defined. + * + * In older libdbus versions, this would be undefined if there was no + * 64-bit integer type on that platform. libdbus no longer supports + * such platforms. + */ + +/** + * @def DBUS_INT64_CONSTANT + * + * Declare a 64-bit signed integer constant. The macro + * adds the necessary "LL" or whatever after the integer, + * giving a literal such as "325145246765LL" + */ + +/** + * @def DBUS_UINT64_CONSTANT + * + * Declare a 64-bit unsigned integer constant. The macro + * adds the necessary "ULL" or whatever after the integer, + * giving a literal such as "325145246765ULL" + */ + +/** + * An 8-byte struct you could use to access int64 without having + * int64 support. Use #dbus_int64_t or #dbus_uint64_t instead. + */ +typedef struct +{ + dbus_uint32_t first32; /**< first 32 bits in the 8 bytes (beware endian issues) */ + dbus_uint32_t second32; /**< second 32 bits in the 8 bytes (beware endian issues) */ +} DBus8ByteStruct; + +/** + * A simple value union that lets you access bytes as if they + * were various types; useful when dealing with basic types via + * void pointers and varargs. + * + * This union also contains a pointer member (which can be used + * to retrieve a string from dbus_message_iter_get_basic(), for + * instance), so on future platforms it could conceivably be larger + * than 8 bytes. + */ +typedef union +{ + unsigned char bytes[8]; /**< as 8 individual bytes */ + dbus_int16_t i16; /**< as int16 */ + dbus_uint16_t u16; /**< as int16 */ + dbus_int32_t i32; /**< as int32 */ + dbus_uint32_t u32; /**< as int32 */ + dbus_bool_t bool_val; /**< as boolean */ + dbus_int64_t i64; /**< as int64 */ + dbus_uint64_t u64; /**< as int64 */ + DBus8ByteStruct eight; /**< as 8-byte struct */ + double dbl; /**< as double */ + unsigned char byt; /**< as byte */ + char *str; /**< as char* (string, object path or signature) */ + int fd; /**< as Unix file descriptor */ +} DBusBasicValue; + +/** @} */ + +#endif /* DBUS_TYPES_H */ diff --git a/thirdparty/linuxbsd_headers/dbus/dbus.h b/thirdparty/linuxbsd_headers/dbus/dbus.h new file mode 100644 index 0000000000..932ceab383 --- /dev/null +++ b/thirdparty/linuxbsd_headers/dbus/dbus.h @@ -0,0 +1,104 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus.h Convenience header including all other headers + * + * Copyright (C) 2002, 2003 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_H +#define DBUS_H + +#define DBUS_INSIDE_DBUS_H 1 + +#include <dbus/dbus-arch-deps.h> +#include <dbus/dbus-address.h> +#include <dbus/dbus-bus.h> +#include <dbus/dbus-connection.h> +#include <dbus/dbus-errors.h> +#include <dbus/dbus-macros.h> +#include <dbus/dbus-message.h> +#include <dbus/dbus-misc.h> +#include <dbus/dbus-pending-call.h> +#include <dbus/dbus-protocol.h> +#include <dbus/dbus-server.h> +#include <dbus/dbus-shared.h> +#include <dbus/dbus-signature.h> +#include <dbus/dbus-syntax.h> +#include <dbus/dbus-threads.h> +#include <dbus/dbus-types.h> + +#undef DBUS_INSIDE_DBUS_H + +/** + * @defgroup DBus D-Bus low-level public API + * @brief The low-level public API of the D-Bus library + * + * libdbus provides a low-level C API intended primarily for use by + * bindings to specific object systems and languages. D-Bus is most + * convenient when used with the GLib bindings, Python bindings, Qt + * bindings, Mono bindings, and so forth. This low-level API has a + * lot of complexity useful only for bindings. + * + * @{ + */ + +/** @} */ + +/** + * @mainpage + * + * This manual documents the <em>low-level</em> D-Bus C API. <b>If you use + * this low-level API directly, you're signing up for some pain.</b> + * + * Caveats aside, you might get started learning the low-level API by reading + * about @ref DBusConnection and @ref DBusMessage. + * + * There are several other places to look for D-Bus information, such + * as the tutorial and the specification; those can be found at <a + * href="http://www.freedesktop.org/wiki/Software/dbus">the D-Bus + * website</a>. If you're interested in a sysadmin or package + * maintainer's perspective on the dbus-daemon itself and its + * configuration, be sure to check out the man pages as well. + * + * The low-level API documented in this manual deliberately lacks + * most convenience functions - those are left up to higher-level libraries + * based on frameworks such as GLib, Qt, Python, Mono, Java, + * etc. These higher-level libraries (often called "D-Bus bindings") + * have features such as object systems and main loops that allow a + * <em>much</em> more convenient API. + * + * The low-level API also contains plenty of clutter to support + * integration with arbitrary object systems, languages, main loops, + * and so forth. These features add a lot of noise to the API that you + * probably don't care about unless you're coding a binding. + * + * This manual also contains docs for @ref DBusInternals "D-Bus internals", + * so you can use it to get oriented to the D-Bus source code if you're + * interested in patching the code. You should also read the + * file HACKING which comes with the source code if you plan to contribute to + * D-Bus. + * + * As you read the code, you can identify internal D-Bus functions + * because they start with an underscore ('_') character. Also, any + * identifier or macro that lacks a DBus, dbus_, or DBUS_ namepace + * prefix is internal, with a couple of exceptions such as #NULL, + * #TRUE, and #FALSE. + */ + +#endif /* DBUS_H */ diff --git a/thirdparty/linuxbsd_headers/fontconfig/fcfreetype.h b/thirdparty/linuxbsd_headers/fontconfig/fcfreetype.h new file mode 100644 index 0000000000..753fdf9da8 --- /dev/null +++ b/thirdparty/linuxbsd_headers/fontconfig/fcfreetype.h @@ -0,0 +1,59 @@ +/* + * fontconfig/fontconfig/fcfreetype.h + * + * Copyright © 2001 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the author(s) not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The authors make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _FCFREETYPE_H_ +#define _FCFREETYPE_H_ +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifndef FcPublic +#define FcPublic +#endif + +_FCFUNCPROTOBEGIN + +FcPublic FT_UInt +FcFreeTypeCharIndex (FT_Face face, FcChar32 ucs4); + +FcPublic FcCharSet * +FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing); + +FcPublic FcCharSet * +FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks); + +FcPublic FcResult +FcPatternGetFTFace (const FcPattern *p, const char *object, int n, FT_Face *f); + +FcPublic FcBool +FcPatternAddFTFace (FcPattern *p, const char *object, const FT_Face f); + +FcPublic FcPattern * +FcFreeTypeQueryFace (const FT_Face face, + const FcChar8 *file, + int id, + FcBlanks *blanks); + +_FCFUNCPROTOEND + +#endif diff --git a/thirdparty/linuxbsd_headers/fontconfig/fcprivate.h b/thirdparty/linuxbsd_headers/fontconfig/fcprivate.h new file mode 100644 index 0000000000..a6ee5c2349 --- /dev/null +++ b/thirdparty/linuxbsd_headers/fontconfig/fcprivate.h @@ -0,0 +1,127 @@ +/* + * fontconfig/fontconfig/fcprivate.h + * + * Copyright © 2001 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the author(s) not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The authors make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _FCPRIVATE_H_ +#define _FCPRIVATE_H_ + +/* + * I tried this with functions that took va_list* arguments + * but portability concerns made me change these functions + * into macros (sigh). + */ + +#define FcPatternVapBuild(result, orig, va) \ +{ \ + FcPattern *__p__ = (orig); \ + const char *__o__; \ + FcValue __v__; \ + \ + if (!__p__) \ + { \ + __p__ = FcPatternCreate (); \ + if (!__p__) \ + goto _FcPatternVapBuild_bail0; \ + } \ + for (;;) \ + { \ + __o__ = va_arg (va, const char *); \ + if (!__o__) \ + break; \ + __v__.type = va_arg (va, int); \ + switch (__v__.type) { \ + case FcTypeUnknown: \ + case FcTypeVoid: \ + goto _FcPatternVapBuild_bail1; \ + case FcTypeInteger: \ + __v__.u.i = va_arg (va, int); \ + break; \ + case FcTypeDouble: \ + __v__.u.d = va_arg (va, double); \ + break; \ + case FcTypeString: \ + __v__.u.s = va_arg (va, const FcChar8 *); \ + break; \ + case FcTypeBool: \ + __v__.u.b = va_arg (va, FcBool); \ + break; \ + case FcTypeMatrix: \ + __v__.u.m = va_arg (va, const FcMatrix *); \ + break; \ + case FcTypeCharSet: \ + __v__.u.c = va_arg (va, const FcCharSet *); \ + break; \ + case FcTypeFTFace: \ + __v__.u.f = va_arg (va, FT_Face); \ + break; \ + case FcTypeLangSet: \ + __v__.u.l = va_arg (va, const FcLangSet *); \ + break; \ + case FcTypeRange: \ + __v__.u.r = va_arg (va, const FcRange *); \ + break; \ + } \ + if (!FcPatternAdd (__p__, __o__, __v__, FcTrue)) \ + goto _FcPatternVapBuild_bail1; \ + } \ + result = __p__; \ + goto _FcPatternVapBuild_return; \ + \ +_FcPatternVapBuild_bail1: \ + if (!orig) \ + FcPatternDestroy (__p__); \ +_FcPatternVapBuild_bail0: \ + result = (void*)0; \ + \ +_FcPatternVapBuild_return: \ + ; \ +} + + +#define FcObjectSetVapBuild(__ret__, __first__, __va__) \ +{ \ + FcObjectSet *__os__; \ + const char *__ob__; \ + \ + __ret__ = 0; \ + __os__ = FcObjectSetCreate (); \ + if (!__os__) \ + goto _FcObjectSetVapBuild_bail0; \ + __ob__ = __first__; \ + while (__ob__) \ + { \ + if (!FcObjectSetAdd (__os__, __ob__)) \ + goto _FcObjectSetVapBuild_bail1; \ + __ob__ = va_arg (__va__, const char *); \ + } \ + __ret__ = __os__; \ + \ +_FcObjectSetVapBuild_bail1: \ + if (!__ret__ && __os__) \ + FcObjectSetDestroy (__os__); \ +_FcObjectSetVapBuild_bail0: \ + ; \ +} + +#endif /* _FCPRIVATE_H_ */ + diff --git a/thirdparty/linuxbsd_headers/fontconfig/fontconfig.h b/thirdparty/linuxbsd_headers/fontconfig/fontconfig.h new file mode 100644 index 0000000000..58bc3e2a8e --- /dev/null +++ b/thirdparty/linuxbsd_headers/fontconfig/fontconfig.h @@ -0,0 +1,1067 @@ +/* + * fontconfig/fontconfig/fontconfig.h + * + * Copyright © 2001 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the author(s) not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The authors make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _FONTCONFIG_H_ +#define _FONTCONFIG_H_ + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdarg.h> +#include <limits.h> + +#if defined(__GNUC__) && (__GNUC__ >= 4) +#define FC_ATTRIBUTE_SENTINEL(x) __attribute__((__sentinel__(0))) +#else +#define FC_ATTRIBUTE_SENTINEL(x) +#endif + +#ifndef FcPublic +#define FcPublic +#endif + +typedef unsigned char FcChar8; +typedef unsigned short FcChar16; +typedef unsigned int FcChar32; +typedef int FcBool; + +/* + * Current Fontconfig version number. This same number + * must appear in the fontconfig configure.in file. Yes, + * it'a a pain to synchronize version numbers like this. + */ + +#define FC_MAJOR 2 +#define FC_MINOR 12 +#define FC_REVISION 6 + +#define FC_VERSION ((FC_MAJOR * 10000) + (FC_MINOR * 100) + (FC_REVISION)) + +/* + * Current font cache file format version + * This is appended to the cache files so that multiple + * versions of the library will peacefully coexist + * + * Change this value whenever the disk format for the cache file + * changes in any non-compatible way. Try to avoid such changes as + * it means multiple copies of the font information. + */ + +#define FC_CACHE_VERSION_NUMBER 7 +#define _FC_STRINGIFY_(s) #s +#define _FC_STRINGIFY(s) _FC_STRINGIFY_(s) +#define FC_CACHE_VERSION _FC_STRINGIFY(FC_CACHE_VERSION_NUMBER) + +#define FcTrue 1 +#define FcFalse 0 + +#define FC_FAMILY "family" /* String */ +#define FC_STYLE "style" /* String */ +#define FC_SLANT "slant" /* Int */ +#define FC_WEIGHT "weight" /* Int */ +#define FC_SIZE "size" /* Range (double) */ +#define FC_ASPECT "aspect" /* Double */ +#define FC_PIXEL_SIZE "pixelsize" /* Double */ +#define FC_SPACING "spacing" /* Int */ +#define FC_FOUNDRY "foundry" /* String */ +#define FC_ANTIALIAS "antialias" /* Bool (depends) */ +#define FC_HINTING "hinting" /* Bool (true) */ +#define FC_HINT_STYLE "hintstyle" /* Int */ +#define FC_VERTICAL_LAYOUT "verticallayout" /* Bool (false) */ +#define FC_AUTOHINT "autohint" /* Bool (false) */ +/* FC_GLOBAL_ADVANCE is deprecated. this is simply ignored on freetype 2.4.5 or later */ +#define FC_GLOBAL_ADVANCE "globaladvance" /* Bool (true) */ +#define FC_WIDTH "width" /* Int */ +#define FC_FILE "file" /* String */ +#define FC_INDEX "index" /* Int */ +#define FC_FT_FACE "ftface" /* FT_Face */ +#define FC_RASTERIZER "rasterizer" /* String (deprecated) */ +#define FC_OUTLINE "outline" /* Bool */ +#define FC_SCALABLE "scalable" /* Bool */ +#define FC_COLOR "color" /* Bool */ +#define FC_SCALE "scale" /* double (deprecated) */ +#define FC_SYMBOL "symbol" /* Bool */ +#define FC_DPI "dpi" /* double */ +#define FC_RGBA "rgba" /* Int */ +#define FC_MINSPACE "minspace" /* Bool use minimum line spacing */ +#define FC_SOURCE "source" /* String (deprecated) */ +#define FC_CHARSET "charset" /* CharSet */ +#define FC_LANG "lang" /* String RFC 3066 langs */ +#define FC_FONTVERSION "fontversion" /* Int from 'head' table */ +#define FC_FULLNAME "fullname" /* String */ +#define FC_FAMILYLANG "familylang" /* String RFC 3066 langs */ +#define FC_STYLELANG "stylelang" /* String RFC 3066 langs */ +#define FC_FULLNAMELANG "fullnamelang" /* String RFC 3066 langs */ +#define FC_CAPABILITY "capability" /* String */ +#define FC_FONTFORMAT "fontformat" /* String */ +#define FC_EMBOLDEN "embolden" /* Bool - true if emboldening needed*/ +#define FC_EMBEDDED_BITMAP "embeddedbitmap" /* Bool - true to enable embedded bitmaps */ +#define FC_DECORATIVE "decorative" /* Bool - true if style is a decorative variant */ +#define FC_LCD_FILTER "lcdfilter" /* Int */ +#define FC_FONT_FEATURES "fontfeatures" /* String */ +#define FC_NAMELANG "namelang" /* String RFC 3866 langs */ +#define FC_PRGNAME "prgname" /* String */ +#define FC_HASH "hash" /* String (deprecated) */ +#define FC_POSTSCRIPT_NAME "postscriptname" /* String */ + +#define FC_CACHE_SUFFIX ".cache-" FC_CACHE_VERSION +#define FC_DIR_CACHE_FILE "fonts.cache-" FC_CACHE_VERSION +#define FC_USER_CACHE_FILE ".fonts.cache-" FC_CACHE_VERSION + +/* Adjust outline rasterizer */ +#define FC_CHARWIDTH "charwidth" /* Int */ +#define FC_CHAR_WIDTH FC_CHARWIDTH +#define FC_CHAR_HEIGHT "charheight"/* Int */ +#define FC_MATRIX "matrix" /* FcMatrix */ + +#define FC_WEIGHT_THIN 0 +#define FC_WEIGHT_EXTRALIGHT 40 +#define FC_WEIGHT_ULTRALIGHT FC_WEIGHT_EXTRALIGHT +#define FC_WEIGHT_LIGHT 50 +#define FC_WEIGHT_DEMILIGHT 55 +#define FC_WEIGHT_SEMILIGHT FC_WEIGHT_DEMILIGHT +#define FC_WEIGHT_BOOK 75 +#define FC_WEIGHT_REGULAR 80 +#define FC_WEIGHT_NORMAL FC_WEIGHT_REGULAR +#define FC_WEIGHT_MEDIUM 100 +#define FC_WEIGHT_DEMIBOLD 180 +#define FC_WEIGHT_SEMIBOLD FC_WEIGHT_DEMIBOLD +#define FC_WEIGHT_BOLD 200 +#define FC_WEIGHT_EXTRABOLD 205 +#define FC_WEIGHT_ULTRABOLD FC_WEIGHT_EXTRABOLD +#define FC_WEIGHT_BLACK 210 +#define FC_WEIGHT_HEAVY FC_WEIGHT_BLACK +#define FC_WEIGHT_EXTRABLACK 215 +#define FC_WEIGHT_ULTRABLACK FC_WEIGHT_EXTRABLACK + +#define FC_SLANT_ROMAN 0 +#define FC_SLANT_ITALIC 100 +#define FC_SLANT_OBLIQUE 110 + +#define FC_WIDTH_ULTRACONDENSED 50 +#define FC_WIDTH_EXTRACONDENSED 63 +#define FC_WIDTH_CONDENSED 75 +#define FC_WIDTH_SEMICONDENSED 87 +#define FC_WIDTH_NORMAL 100 +#define FC_WIDTH_SEMIEXPANDED 113 +#define FC_WIDTH_EXPANDED 125 +#define FC_WIDTH_EXTRAEXPANDED 150 +#define FC_WIDTH_ULTRAEXPANDED 200 + +#define FC_PROPORTIONAL 0 +#define FC_DUAL 90 +#define FC_MONO 100 +#define FC_CHARCELL 110 + +/* sub-pixel order */ +#define FC_RGBA_UNKNOWN 0 +#define FC_RGBA_RGB 1 +#define FC_RGBA_BGR 2 +#define FC_RGBA_VRGB 3 +#define FC_RGBA_VBGR 4 +#define FC_RGBA_NONE 5 + +/* hinting style */ +#define FC_HINT_NONE 0 +#define FC_HINT_SLIGHT 1 +#define FC_HINT_MEDIUM 2 +#define FC_HINT_FULL 3 + +/* LCD filter */ +#define FC_LCD_NONE 0 +#define FC_LCD_DEFAULT 1 +#define FC_LCD_LIGHT 2 +#define FC_LCD_LEGACY 3 + +typedef enum _FcType { + FcTypeUnknown = -1, + FcTypeVoid, + FcTypeInteger, + FcTypeDouble, + FcTypeString, + FcTypeBool, + FcTypeMatrix, + FcTypeCharSet, + FcTypeFTFace, + FcTypeLangSet, + FcTypeRange +} FcType; + +typedef struct _FcMatrix { + double xx, xy, yx, yy; +} FcMatrix; + +#define FcMatrixInit(m) ((m)->xx = (m)->yy = 1, \ + (m)->xy = (m)->yx = 0) + +/* + * A data structure to represent the available glyphs in a font. + * This is represented as a sparse boolean btree. + */ + +typedef struct _FcCharSet FcCharSet; + +typedef struct _FcObjectType { + char *object; + FcType type; +} FcObjectType; + +typedef struct _FcConstant { + const FcChar8 *name; + const char *object; + int value; +} FcConstant; + +typedef enum _FcResult { + FcResultMatch, FcResultNoMatch, FcResultTypeMismatch, FcResultNoId, + FcResultOutOfMemory +} FcResult; + +typedef enum _FcValueBinding { + FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame, + /* to make sure sizeof (FcValueBinding) == 4 even with -fshort-enums */ + FcValueBindingEnd = INT_MAX +} FcValueBinding; + +typedef struct _FcPattern FcPattern; + +typedef struct _FcLangSet FcLangSet; + +typedef struct _FcRange FcRange; + +typedef struct _FcValue { + FcType type; + union { + const FcChar8 *s; + int i; + FcBool b; + double d; + const FcMatrix *m; + const FcCharSet *c; + void *f; + const FcLangSet *l; + const FcRange *r; + } u; +} FcValue; + +typedef struct _FcFontSet { + int nfont; + int sfont; + FcPattern **fonts; +} FcFontSet; + +typedef struct _FcObjectSet { + int nobject; + int sobject; + const char **objects; +} FcObjectSet; + +typedef enum _FcMatchKind { + FcMatchPattern, FcMatchFont, FcMatchScan +} FcMatchKind; + +typedef enum _FcLangResult { + FcLangEqual = 0, + FcLangDifferentCountry = 1, + FcLangDifferentTerritory = 1, + FcLangDifferentLang = 2 +} FcLangResult; + +typedef enum _FcSetName { + FcSetSystem = 0, + FcSetApplication = 1 +} FcSetName; + +typedef struct _FcAtomic FcAtomic; + +#if defined(__cplusplus) || defined(c_plusplus) /* for C++ V2.0 */ +#define _FCFUNCPROTOBEGIN extern "C" { /* do not leave open across includes */ +#define _FCFUNCPROTOEND } +#else +#define _FCFUNCPROTOBEGIN +#define _FCFUNCPROTOEND +#endif + +typedef enum { FcEndianBig, FcEndianLittle } FcEndian; + +typedef struct _FcConfig FcConfig; + +typedef struct _FcGlobalCache FcFileCache; + +typedef struct _FcBlanks FcBlanks; + +typedef struct _FcStrList FcStrList; + +typedef struct _FcStrSet FcStrSet; + +typedef struct _FcCache FcCache; + +_FCFUNCPROTOBEGIN + +/* fcblanks.c */ +FcPublic FcBlanks * +FcBlanksCreate (void); + +FcPublic void +FcBlanksDestroy (FcBlanks *b); + +FcPublic FcBool +FcBlanksAdd (FcBlanks *b, FcChar32 ucs4); + +FcPublic FcBool +FcBlanksIsMember (FcBlanks *b, FcChar32 ucs4); + +/* fccache.c */ + +FcPublic const FcChar8 * +FcCacheDir(const FcCache *c); + +FcPublic FcFontSet * +FcCacheCopySet(const FcCache *c); + +FcPublic const FcChar8 * +FcCacheSubdir (const FcCache *c, int i); + +FcPublic int +FcCacheNumSubdir (const FcCache *c); + +FcPublic int +FcCacheNumFont (const FcCache *c); + +FcPublic FcBool +FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config); + +FcPublic FcBool +FcDirCacheValid (const FcChar8 *cache_file); + +FcPublic FcBool +FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose); + +FcPublic void +FcCacheCreateTagFile (const FcConfig *config); + +/* fccfg.c */ +FcPublic FcChar8 * +FcConfigHome (void); + +FcPublic FcBool +FcConfigEnableHome (FcBool enable); + +FcPublic FcChar8 * +FcConfigFilename (const FcChar8 *url); + +FcPublic FcConfig * +FcConfigCreate (void); + +FcPublic FcConfig * +FcConfigReference (FcConfig *config); + +FcPublic void +FcConfigDestroy (FcConfig *config); + +FcPublic FcBool +FcConfigSetCurrent (FcConfig *config); + +FcPublic FcConfig * +FcConfigGetCurrent (void); + +FcPublic FcBool +FcConfigUptoDate (FcConfig *config); + +FcPublic FcBool +FcConfigBuildFonts (FcConfig *config); + +FcPublic FcStrList * +FcConfigGetFontDirs (FcConfig *config); + +FcPublic FcStrList * +FcConfigGetConfigDirs (FcConfig *config); + +FcPublic FcStrList * +FcConfigGetConfigFiles (FcConfig *config); + +FcPublic FcChar8 * +FcConfigGetCache (FcConfig *config); + +FcPublic FcBlanks * +FcConfigGetBlanks (FcConfig *config); + +FcPublic FcStrList * +FcConfigGetCacheDirs (const FcConfig *config); + +FcPublic int +FcConfigGetRescanInterval (FcConfig *config); + +FcPublic FcBool +FcConfigSetRescanInterval (FcConfig *config, int rescanInterval); + +FcPublic FcFontSet * +FcConfigGetFonts (FcConfig *config, + FcSetName set); + +FcPublic FcBool +FcConfigAppFontAddFile (FcConfig *config, + const FcChar8 *file); + +FcPublic FcBool +FcConfigAppFontAddDir (FcConfig *config, + const FcChar8 *dir); + +FcPublic void +FcConfigAppFontClear (FcConfig *config); + +FcPublic FcBool +FcConfigSubstituteWithPat (FcConfig *config, + FcPattern *p, + FcPattern *p_pat, + FcMatchKind kind); + +FcPublic FcBool +FcConfigSubstitute (FcConfig *config, + FcPattern *p, + FcMatchKind kind); + +FcPublic const FcChar8 * +FcConfigGetSysRoot (const FcConfig *config); + +FcPublic void +FcConfigSetSysRoot (FcConfig *config, + const FcChar8 *sysroot); + +/* fccharset.c */ +FcPublic FcCharSet* +FcCharSetCreate (void); + +/* deprecated alias for FcCharSetCreate */ +FcPublic FcCharSet * +FcCharSetNew (void); + +FcPublic void +FcCharSetDestroy (FcCharSet *fcs); + +FcPublic FcBool +FcCharSetAddChar (FcCharSet *fcs, FcChar32 ucs4); + +FcPublic FcBool +FcCharSetDelChar (FcCharSet *fcs, FcChar32 ucs4); + +FcPublic FcCharSet* +FcCharSetCopy (FcCharSet *src); + +FcPublic FcBool +FcCharSetEqual (const FcCharSet *a, const FcCharSet *b); + +FcPublic FcCharSet* +FcCharSetIntersect (const FcCharSet *a, const FcCharSet *b); + +FcPublic FcCharSet* +FcCharSetUnion (const FcCharSet *a, const FcCharSet *b); + +FcPublic FcCharSet* +FcCharSetSubtract (const FcCharSet *a, const FcCharSet *b); + +FcPublic FcBool +FcCharSetMerge (FcCharSet *a, const FcCharSet *b, FcBool *changed); + +FcPublic FcBool +FcCharSetHasChar (const FcCharSet *fcs, FcChar32 ucs4); + +FcPublic FcChar32 +FcCharSetCount (const FcCharSet *a); + +FcPublic FcChar32 +FcCharSetIntersectCount (const FcCharSet *a, const FcCharSet *b); + +FcPublic FcChar32 +FcCharSetSubtractCount (const FcCharSet *a, const FcCharSet *b); + +FcPublic FcBool +FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b); + +#define FC_CHARSET_MAP_SIZE (256/32) +#define FC_CHARSET_DONE ((FcChar32) -1) + +FcPublic FcChar32 +FcCharSetFirstPage (const FcCharSet *a, + FcChar32 map[FC_CHARSET_MAP_SIZE], + FcChar32 *next); + +FcPublic FcChar32 +FcCharSetNextPage (const FcCharSet *a, + FcChar32 map[FC_CHARSET_MAP_SIZE], + FcChar32 *next); + +/* + * old coverage API, rather hard to use correctly + */ + +FcPublic FcChar32 +FcCharSetCoverage (const FcCharSet *a, FcChar32 page, FcChar32 *result); + +/* fcdbg.c */ +FcPublic void +FcValuePrint (const FcValue v); + +FcPublic void +FcPatternPrint (const FcPattern *p); + +FcPublic void +FcFontSetPrint (const FcFontSet *s); + +/* fcdefault.c */ +FcPublic FcStrSet * +FcGetDefaultLangs (void); + +FcPublic void +FcDefaultSubstitute (FcPattern *pattern); + +/* fcdir.c */ +FcPublic FcBool +FcFileIsDir (const FcChar8 *file); + +FcPublic FcBool +FcFileScan (FcFontSet *set, + FcStrSet *dirs, + FcFileCache *cache, + FcBlanks *blanks, + const FcChar8 *file, + FcBool force); + +FcPublic FcBool +FcDirScan (FcFontSet *set, + FcStrSet *dirs, + FcFileCache *cache, + FcBlanks *blanks, + const FcChar8 *dir, + FcBool force); + +FcPublic FcBool +FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir); + +FcPublic FcCache * +FcDirCacheLoad (const FcChar8 *dir, FcConfig *config, FcChar8 **cache_file); + +FcPublic FcCache * +FcDirCacheRescan (const FcChar8 *dir, FcConfig *config); + +FcPublic FcCache * +FcDirCacheRead (const FcChar8 *dir, FcBool force, FcConfig *config); + +FcPublic FcCache * +FcDirCacheLoadFile (const FcChar8 *cache_file, struct stat *file_stat); + +FcPublic void +FcDirCacheUnload (FcCache *cache); + +/* fcfreetype.c */ +FcPublic FcPattern * +FcFreeTypeQuery (const FcChar8 *file, int id, FcBlanks *blanks, int *count); + +/* fcfs.c */ + +FcPublic FcFontSet * +FcFontSetCreate (void); + +FcPublic void +FcFontSetDestroy (FcFontSet *s); + +FcPublic FcBool +FcFontSetAdd (FcFontSet *s, FcPattern *font); + +/* fcinit.c */ +FcPublic FcConfig * +FcInitLoadConfig (void); + +FcPublic FcConfig * +FcInitLoadConfigAndFonts (void); + +FcPublic FcBool +FcInit (void); + +FcPublic void +FcFini (void); + +FcPublic int +FcGetVersion (void); + +FcPublic FcBool +FcInitReinitialize (void); + +FcPublic FcBool +FcInitBringUptoDate (void); + +/* fclang.c */ +FcPublic FcStrSet * +FcGetLangs (void); + +FcPublic FcChar8 * +FcLangNormalize (const FcChar8 *lang); + +FcPublic const FcCharSet * +FcLangGetCharSet (const FcChar8 *lang); + +FcPublic FcLangSet* +FcLangSetCreate (void); + +FcPublic void +FcLangSetDestroy (FcLangSet *ls); + +FcPublic FcLangSet* +FcLangSetCopy (const FcLangSet *ls); + +FcPublic FcBool +FcLangSetAdd (FcLangSet *ls, const FcChar8 *lang); + +FcPublic FcBool +FcLangSetDel (FcLangSet *ls, const FcChar8 *lang); + +FcPublic FcLangResult +FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang); + +FcPublic FcLangResult +FcLangSetCompare (const FcLangSet *lsa, const FcLangSet *lsb); + +FcPublic FcBool +FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb); + +FcPublic FcBool +FcLangSetEqual (const FcLangSet *lsa, const FcLangSet *lsb); + +FcPublic FcChar32 +FcLangSetHash (const FcLangSet *ls); + +FcPublic FcStrSet * +FcLangSetGetLangs (const FcLangSet *ls); + +FcPublic FcLangSet * +FcLangSetUnion (const FcLangSet *a, const FcLangSet *b); + +FcPublic FcLangSet * +FcLangSetSubtract (const FcLangSet *a, const FcLangSet *b); + +/* fclist.c */ +FcPublic FcObjectSet * +FcObjectSetCreate (void); + +FcPublic FcBool +FcObjectSetAdd (FcObjectSet *os, const char *object); + +FcPublic void +FcObjectSetDestroy (FcObjectSet *os); + +FcPublic FcObjectSet * +FcObjectSetVaBuild (const char *first, va_list va); + +FcPublic FcObjectSet * +FcObjectSetBuild (const char *first, ...) FC_ATTRIBUTE_SENTINEL(0); + +FcPublic FcFontSet * +FcFontSetList (FcConfig *config, + FcFontSet **sets, + int nsets, + FcPattern *p, + FcObjectSet *os); + +FcPublic FcFontSet * +FcFontList (FcConfig *config, + FcPattern *p, + FcObjectSet *os); + +/* fcatomic.c */ + +FcPublic FcAtomic * +FcAtomicCreate (const FcChar8 *file); + +FcPublic FcBool +FcAtomicLock (FcAtomic *atomic); + +FcPublic FcChar8 * +FcAtomicNewFile (FcAtomic *atomic); + +FcPublic FcChar8 * +FcAtomicOrigFile (FcAtomic *atomic); + +FcPublic FcBool +FcAtomicReplaceOrig (FcAtomic *atomic); + +FcPublic void +FcAtomicDeleteNew (FcAtomic *atomic); + +FcPublic void +FcAtomicUnlock (FcAtomic *atomic); + +FcPublic void +FcAtomicDestroy (FcAtomic *atomic); + +/* fcmatch.c */ +FcPublic FcPattern * +FcFontSetMatch (FcConfig *config, + FcFontSet **sets, + int nsets, + FcPattern *p, + FcResult *result); + +FcPublic FcPattern * +FcFontMatch (FcConfig *config, + FcPattern *p, + FcResult *result); + +FcPublic FcPattern * +FcFontRenderPrepare (FcConfig *config, + FcPattern *pat, + FcPattern *font); + +FcPublic FcFontSet * +FcFontSetSort (FcConfig *config, + FcFontSet **sets, + int nsets, + FcPattern *p, + FcBool trim, + FcCharSet **csp, + FcResult *result); + +FcPublic FcFontSet * +FcFontSort (FcConfig *config, + FcPattern *p, + FcBool trim, + FcCharSet **csp, + FcResult *result); + +FcPublic void +FcFontSetSortDestroy (FcFontSet *fs); + +/* fcmatrix.c */ +FcPublic FcMatrix * +FcMatrixCopy (const FcMatrix *mat); + +FcPublic FcBool +FcMatrixEqual (const FcMatrix *mat1, const FcMatrix *mat2); + +FcPublic void +FcMatrixMultiply (FcMatrix *result, const FcMatrix *a, const FcMatrix *b); + +FcPublic void +FcMatrixRotate (FcMatrix *m, double c, double s); + +FcPublic void +FcMatrixScale (FcMatrix *m, double sx, double sy); + +FcPublic void +FcMatrixShear (FcMatrix *m, double sh, double sv); + +/* fcname.c */ + +/* Deprecated. Does nothing. Returns FcFalse. */ +FcPublic FcBool +FcNameRegisterObjectTypes (const FcObjectType *types, int ntype); + +/* Deprecated. Does nothing. Returns FcFalse. */ +FcPublic FcBool +FcNameUnregisterObjectTypes (const FcObjectType *types, int ntype); + +FcPublic const FcObjectType * +FcNameGetObjectType (const char *object); + +/* Deprecated. Does nothing. Returns FcFalse. */ +FcPublic FcBool +FcNameRegisterConstants (const FcConstant *consts, int nconsts); + +/* Deprecated. Does nothing. Returns FcFalse. */ +FcPublic FcBool +FcNameUnregisterConstants (const FcConstant *consts, int nconsts); + +FcPublic const FcConstant * +FcNameGetConstant (const FcChar8 *string); + +FcPublic FcBool +FcNameConstant (const FcChar8 *string, int *result); + +FcPublic FcPattern * +FcNameParse (const FcChar8 *name); + +FcPublic FcChar8 * +FcNameUnparse (FcPattern *pat); + +/* fcpat.c */ +FcPublic FcPattern * +FcPatternCreate (void); + +FcPublic FcPattern * +FcPatternDuplicate (const FcPattern *p); + +FcPublic void +FcPatternReference (FcPattern *p); + +FcPublic FcPattern * +FcPatternFilter (FcPattern *p, const FcObjectSet *os); + +FcPublic void +FcValueDestroy (FcValue v); + +FcPublic FcBool +FcValueEqual (FcValue va, FcValue vb); + +FcPublic FcValue +FcValueSave (FcValue v); + +FcPublic void +FcPatternDestroy (FcPattern *p); + +FcPublic FcBool +FcPatternEqual (const FcPattern *pa, const FcPattern *pb); + +FcPublic FcBool +FcPatternEqualSubset (const FcPattern *pa, const FcPattern *pb, const FcObjectSet *os); + +FcPublic FcChar32 +FcPatternHash (const FcPattern *p); + +FcPublic FcBool +FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append); + +FcPublic FcBool +FcPatternAddWeak (FcPattern *p, const char *object, FcValue value, FcBool append); + +FcPublic FcResult +FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v); + +FcPublic FcResult +FcPatternGetWithBinding (const FcPattern *p, const char *object, int id, FcValue *v, FcValueBinding *b); + +FcPublic FcBool +FcPatternDel (FcPattern *p, const char *object); + +FcPublic FcBool +FcPatternRemove (FcPattern *p, const char *object, int id); + +FcPublic FcBool +FcPatternAddInteger (FcPattern *p, const char *object, int i); + +FcPublic FcBool +FcPatternAddDouble (FcPattern *p, const char *object, double d); + +FcPublic FcBool +FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s); + +FcPublic FcBool +FcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s); + +FcPublic FcBool +FcPatternAddCharSet (FcPattern *p, const char *object, const FcCharSet *c); + +FcPublic FcBool +FcPatternAddBool (FcPattern *p, const char *object, FcBool b); + +FcPublic FcBool +FcPatternAddLangSet (FcPattern *p, const char *object, const FcLangSet *ls); + +FcPublic FcBool +FcPatternAddRange (FcPattern *p, const char *object, const FcRange *r); + +FcPublic FcResult +FcPatternGetInteger (const FcPattern *p, const char *object, int n, int *i); + +FcPublic FcResult +FcPatternGetDouble (const FcPattern *p, const char *object, int n, double *d); + +FcPublic FcResult +FcPatternGetString (const FcPattern *p, const char *object, int n, FcChar8 ** s); + +FcPublic FcResult +FcPatternGetMatrix (const FcPattern *p, const char *object, int n, FcMatrix **s); + +FcPublic FcResult +FcPatternGetCharSet (const FcPattern *p, const char *object, int n, FcCharSet **c); + +FcPublic FcResult +FcPatternGetBool (const FcPattern *p, const char *object, int n, FcBool *b); + +FcPublic FcResult +FcPatternGetLangSet (const FcPattern *p, const char *object, int n, FcLangSet **ls); + +FcPublic FcResult +FcPatternGetRange (const FcPattern *p, const char *object, int id, FcRange **r); + +FcPublic FcPattern * +FcPatternVaBuild (FcPattern *p, va_list va); + +FcPublic FcPattern * +FcPatternBuild (FcPattern *p, ...) FC_ATTRIBUTE_SENTINEL(0); + +FcPublic FcChar8 * +FcPatternFormat (FcPattern *pat, const FcChar8 *format); + +/* fcrange.c */ +FcPublic FcRange * +FcRangeCreateDouble (double begin, double end); + +FcPublic FcRange * +FcRangeCreateInteger (FcChar32 begin, FcChar32 end); + +FcPublic void +FcRangeDestroy (FcRange *range); + +FcPublic FcRange * +FcRangeCopy (const FcRange *r); + +FcPublic FcBool +FcRangeGetDouble(const FcRange *range, double *begin, double *end); + +/* fcweight.c */ + +FcPublic int +FcWeightFromOpenType (int ot_weight); + +FcPublic int +FcWeightToOpenType (int fc_weight); + +/* fcstr.c */ + +FcPublic FcChar8 * +FcStrCopy (const FcChar8 *s); + +FcPublic FcChar8 * +FcStrCopyFilename (const FcChar8 *s); + +FcPublic FcChar8 * +FcStrPlus (const FcChar8 *s1, const FcChar8 *s2); + +FcPublic void +FcStrFree (FcChar8 *s); + +/* These are ASCII only, suitable only for pattern element names */ +#define FcIsUpper(c) ((0101 <= (c) && (c) <= 0132)) +#define FcIsLower(c) ((0141 <= (c) && (c) <= 0172)) +#define FcToLower(c) (FcIsUpper(c) ? (c) - 0101 + 0141 : (c)) + +FcPublic FcChar8 * +FcStrDowncase (const FcChar8 *s); + +FcPublic int +FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2); + +FcPublic int +FcStrCmp (const FcChar8 *s1, const FcChar8 *s2); + +FcPublic const FcChar8 * +FcStrStrIgnoreCase (const FcChar8 *s1, const FcChar8 *s2); + +FcPublic const FcChar8 * +FcStrStr (const FcChar8 *s1, const FcChar8 *s2); + +FcPublic int +FcUtf8ToUcs4 (const FcChar8 *src_orig, + FcChar32 *dst, + int len); + +FcPublic FcBool +FcUtf8Len (const FcChar8 *string, + int len, + int *nchar, + int *wchar); + +#define FC_UTF8_MAX_LEN 6 + +FcPublic int +FcUcs4ToUtf8 (FcChar32 ucs4, + FcChar8 dest[FC_UTF8_MAX_LEN]); + +FcPublic int +FcUtf16ToUcs4 (const FcChar8 *src_orig, + FcEndian endian, + FcChar32 *dst, + int len); /* in bytes */ + +FcPublic FcBool +FcUtf16Len (const FcChar8 *string, + FcEndian endian, + int len, /* in bytes */ + int *nchar, + int *wchar); + +FcPublic FcChar8 * +FcStrDirname (const FcChar8 *file); + +FcPublic FcChar8 * +FcStrBasename (const FcChar8 *file); + +FcPublic FcStrSet * +FcStrSetCreate (void); + +FcPublic FcBool +FcStrSetMember (FcStrSet *set, const FcChar8 *s); + +FcPublic FcBool +FcStrSetEqual (FcStrSet *sa, FcStrSet *sb); + +FcPublic FcBool +FcStrSetAdd (FcStrSet *set, const FcChar8 *s); + +FcPublic FcBool +FcStrSetAddFilename (FcStrSet *set, const FcChar8 *s); + +FcPublic FcBool +FcStrSetDel (FcStrSet *set, const FcChar8 *s); + +FcPublic void +FcStrSetDestroy (FcStrSet *set); + +FcPublic FcStrList * +FcStrListCreate (FcStrSet *set); + +FcPublic void +FcStrListFirst (FcStrList *list); + +FcPublic FcChar8 * +FcStrListNext (FcStrList *list); + +FcPublic void +FcStrListDone (FcStrList *list); + +/* fcxml.c */ +FcPublic FcBool +FcConfigParseAndLoad (FcConfig *config, const FcChar8 *file, FcBool complain); + +FcPublic FcBool +FcConfigParseAndLoadFromMemory (FcConfig *config, + const FcChar8 *buffer, + FcBool complain); + +_FCFUNCPROTOEND + +#undef FC_ATTRIBUTE_SENTINEL + + +#ifndef _FCINT_H_ + +/* + * Deprecated functions are placed here to help users fix their code without + * digging through documentation + */ + +#define FcConfigGetRescanInverval FcConfigGetRescanInverval_REPLACE_BY_FcConfigGetRescanInterval +#define FcConfigSetRescanInverval FcConfigSetRescanInverval_REPLACE_BY_FcConfigSetRescanInterval + +#endif + +#endif /* _FONTCONFIG_H_ */ diff --git a/thirdparty/linuxbsd_headers/pulse/cdecl.h b/thirdparty/linuxbsd_headers/pulse/cdecl.h new file mode 100644 index 0000000000..ac817d5d03 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/cdecl.h @@ -0,0 +1,40 @@ +#ifndef foopulsecdeclhfoo +#define foopulsecdeclhfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +/** \file + * C++ compatibility support */ + +#ifdef __cplusplus +/** If using C++ this macro enables C mode, otherwise does nothing */ +#define PA_C_DECL_BEGIN extern "C" { +/** If using C++ this macros switches back to C++ mode, otherwise does nothing */ +#define PA_C_DECL_END } + +#else +/** If using C++ this macro enables C mode, otherwise does nothing */ +#define PA_C_DECL_BEGIN +/** If using C++ this macros switches back to C++ mode, otherwise does nothing */ +#define PA_C_DECL_END + +#endif + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/channelmap.h b/thirdparty/linuxbsd_headers/pulse/channelmap.h new file mode 100644 index 0000000000..6eabe20bad --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/channelmap.h @@ -0,0 +1,366 @@ +#ifndef foochannelmaphfoo +#define foochannelmaphfoo + +/*** + This file is part of PulseAudio. + + Copyright 2005-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <pulse/sample.h> +#include <pulse/cdecl.h> +#include <pulse/gccmacro.h> +#include <pulse/version.h> + +/** \page channelmap Channel Maps + * + * \section overv_sec Overview + * + * Channel maps provide a way to associate channels in a stream with a + * specific speaker position. This relieves applications of having to + * make sure their channel order is identical to the final output. + * + * \section init_sec Initialisation + * + * A channel map consists of an array of \ref pa_channel_position values, + * one for each channel. This array is stored together with a channel count + * in a pa_channel_map structure. + * + * Before filling the structure, the application must initialise it using + * pa_channel_map_init(). There are also a number of convenience functions + * for standard channel mappings: + * + * \li pa_channel_map_init_mono() - Create a channel map with only mono audio. + * \li pa_channel_map_init_stereo() - Create a standard stereo mapping. + * \li pa_channel_map_init_auto() - Create a standard channel map for a specific number of channels + * \li pa_channel_map_init_extend() - Similar to + * pa_channel_map_init_auto() but synthesize a channel map if no + * predefined one is known for the specified number of channels. + * + * \section conv_sec Convenience Functions + * + * The library contains a number of convenience functions for dealing with + * channel maps: + * + * \li pa_channel_map_valid() - Tests if a channel map is valid. + * \li pa_channel_map_equal() - Tests if two channel maps are identical. + * \li pa_channel_map_snprint() - Creates a textual description of a channel + * map. + */ + +/** \file + * Constants and routines for channel mapping handling + * + * See also \subpage channelmap + */ + +PA_C_DECL_BEGIN + +/** A list of channel labels */ +typedef enum pa_channel_position { + PA_CHANNEL_POSITION_INVALID = -1, + PA_CHANNEL_POSITION_MONO = 0, + + PA_CHANNEL_POSITION_FRONT_LEFT, /**< Apple, Dolby call this 'Left' */ + PA_CHANNEL_POSITION_FRONT_RIGHT, /**< Apple, Dolby call this 'Right' */ + PA_CHANNEL_POSITION_FRONT_CENTER, /**< Apple, Dolby call this 'Center' */ + +/** \cond fulldocs */ + PA_CHANNEL_POSITION_LEFT = PA_CHANNEL_POSITION_FRONT_LEFT, + PA_CHANNEL_POSITION_RIGHT = PA_CHANNEL_POSITION_FRONT_RIGHT, + PA_CHANNEL_POSITION_CENTER = PA_CHANNEL_POSITION_FRONT_CENTER, +/** \endcond */ + + PA_CHANNEL_POSITION_REAR_CENTER, /**< Microsoft calls this 'Back Center', Apple calls this 'Center Surround', Dolby calls this 'Surround Rear Center' */ + PA_CHANNEL_POSITION_REAR_LEFT, /**< Microsoft calls this 'Back Left', Apple calls this 'Left Surround' (!), Dolby calls this 'Surround Rear Left' */ + PA_CHANNEL_POSITION_REAR_RIGHT, /**< Microsoft calls this 'Back Right', Apple calls this 'Right Surround' (!), Dolby calls this 'Surround Rear Right' */ + + PA_CHANNEL_POSITION_LFE, /**< Microsoft calls this 'Low Frequency', Apple calls this 'LFEScreen' */ +/** \cond fulldocs */ + PA_CHANNEL_POSITION_SUBWOOFER = PA_CHANNEL_POSITION_LFE, +/** \endcond */ + + PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, /**< Apple, Dolby call this 'Left Center' */ + PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, /**< Apple, Dolby call this 'Right Center */ + + PA_CHANNEL_POSITION_SIDE_LEFT, /**< Apple calls this 'Left Surround Direct', Dolby calls this 'Surround Left' (!) */ + PA_CHANNEL_POSITION_SIDE_RIGHT, /**< Apple calls this 'Right Surround Direct', Dolby calls this 'Surround Right' (!) */ + + PA_CHANNEL_POSITION_AUX0, + PA_CHANNEL_POSITION_AUX1, + PA_CHANNEL_POSITION_AUX2, + PA_CHANNEL_POSITION_AUX3, + PA_CHANNEL_POSITION_AUX4, + PA_CHANNEL_POSITION_AUX5, + PA_CHANNEL_POSITION_AUX6, + PA_CHANNEL_POSITION_AUX7, + PA_CHANNEL_POSITION_AUX8, + PA_CHANNEL_POSITION_AUX9, + PA_CHANNEL_POSITION_AUX10, + PA_CHANNEL_POSITION_AUX11, + PA_CHANNEL_POSITION_AUX12, + PA_CHANNEL_POSITION_AUX13, + PA_CHANNEL_POSITION_AUX14, + PA_CHANNEL_POSITION_AUX15, + PA_CHANNEL_POSITION_AUX16, + PA_CHANNEL_POSITION_AUX17, + PA_CHANNEL_POSITION_AUX18, + PA_CHANNEL_POSITION_AUX19, + PA_CHANNEL_POSITION_AUX20, + PA_CHANNEL_POSITION_AUX21, + PA_CHANNEL_POSITION_AUX22, + PA_CHANNEL_POSITION_AUX23, + PA_CHANNEL_POSITION_AUX24, + PA_CHANNEL_POSITION_AUX25, + PA_CHANNEL_POSITION_AUX26, + PA_CHANNEL_POSITION_AUX27, + PA_CHANNEL_POSITION_AUX28, + PA_CHANNEL_POSITION_AUX29, + PA_CHANNEL_POSITION_AUX30, + PA_CHANNEL_POSITION_AUX31, + + PA_CHANNEL_POSITION_TOP_CENTER, /**< Apple calls this 'Top Center Surround' */ + + PA_CHANNEL_POSITION_TOP_FRONT_LEFT, /**< Apple calls this 'Vertical Height Left' */ + PA_CHANNEL_POSITION_TOP_FRONT_RIGHT, /**< Apple calls this 'Vertical Height Right' */ + PA_CHANNEL_POSITION_TOP_FRONT_CENTER, /**< Apple calls this 'Vertical Height Center' */ + + PA_CHANNEL_POSITION_TOP_REAR_LEFT, /**< Microsoft and Apple call this 'Top Back Left' */ + PA_CHANNEL_POSITION_TOP_REAR_RIGHT, /**< Microsoft and Apple call this 'Top Back Right' */ + PA_CHANNEL_POSITION_TOP_REAR_CENTER, /**< Microsoft and Apple call this 'Top Back Center' */ + + PA_CHANNEL_POSITION_MAX +} pa_channel_position_t; + +/** \cond fulldocs */ +#define PA_CHANNEL_POSITION_INVALID PA_CHANNEL_POSITION_INVALID +#define PA_CHANNEL_POSITION_MONO PA_CHANNEL_POSITION_MONO +#define PA_CHANNEL_POSITION_LEFT PA_CHANNEL_POSITION_LEFT +#define PA_CHANNEL_POSITION_RIGHT PA_CHANNEL_POSITION_RIGHT +#define PA_CHANNEL_POSITION_CENTER PA_CHANNEL_POSITION_CENTER +#define PA_CHANNEL_POSITION_FRONT_LEFT PA_CHANNEL_POSITION_FRONT_LEFT +#define PA_CHANNEL_POSITION_FRONT_RIGHT PA_CHANNEL_POSITION_FRONT_RIGHT +#define PA_CHANNEL_POSITION_FRONT_CENTER PA_CHANNEL_POSITION_FRONT_CENTER +#define PA_CHANNEL_POSITION_REAR_CENTER PA_CHANNEL_POSITION_REAR_CENTER +#define PA_CHANNEL_POSITION_REAR_LEFT PA_CHANNEL_POSITION_REAR_LEFT +#define PA_CHANNEL_POSITION_REAR_RIGHT PA_CHANNEL_POSITION_REAR_RIGHT +#define PA_CHANNEL_POSITION_LFE PA_CHANNEL_POSITION_LFE +#define PA_CHANNEL_POSITION_SUBWOOFER PA_CHANNEL_POSITION_SUBWOOFER +#define PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER +#define PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER +#define PA_CHANNEL_POSITION_SIDE_LEFT PA_CHANNEL_POSITION_SIDE_LEFT +#define PA_CHANNEL_POSITION_SIDE_RIGHT PA_CHANNEL_POSITION_SIDE_RIGHT +#define PA_CHANNEL_POSITION_AUX0 PA_CHANNEL_POSITION_AUX0 +#define PA_CHANNEL_POSITION_AUX1 PA_CHANNEL_POSITION_AUX1 +#define PA_CHANNEL_POSITION_AUX2 PA_CHANNEL_POSITION_AUX2 +#define PA_CHANNEL_POSITION_AUX3 PA_CHANNEL_POSITION_AUX3 +#define PA_CHANNEL_POSITION_AUX4 PA_CHANNEL_POSITION_AUX4 +#define PA_CHANNEL_POSITION_AUX5 PA_CHANNEL_POSITION_AUX5 +#define PA_CHANNEL_POSITION_AUX6 PA_CHANNEL_POSITION_AUX6 +#define PA_CHANNEL_POSITION_AUX7 PA_CHANNEL_POSITION_AUX7 +#define PA_CHANNEL_POSITION_AUX8 PA_CHANNEL_POSITION_AUX8 +#define PA_CHANNEL_POSITION_AUX9 PA_CHANNEL_POSITION_AUX9 +#define PA_CHANNEL_POSITION_AUX10 PA_CHANNEL_POSITION_AUX10 +#define PA_CHANNEL_POSITION_AUX11 PA_CHANNEL_POSITION_AUX11 +#define PA_CHANNEL_POSITION_AUX12 PA_CHANNEL_POSITION_AUX12 +#define PA_CHANNEL_POSITION_AUX13 PA_CHANNEL_POSITION_AUX13 +#define PA_CHANNEL_POSITION_AUX14 PA_CHANNEL_POSITION_AUX14 +#define PA_CHANNEL_POSITION_AUX15 PA_CHANNEL_POSITION_AUX15 +#define PA_CHANNEL_POSITION_AUX16 PA_CHANNEL_POSITION_AUX16 +#define PA_CHANNEL_POSITION_AUX17 PA_CHANNEL_POSITION_AUX17 +#define PA_CHANNEL_POSITION_AUX18 PA_CHANNEL_POSITION_AUX18 +#define PA_CHANNEL_POSITION_AUX19 PA_CHANNEL_POSITION_AUX19 +#define PA_CHANNEL_POSITION_AUX20 PA_CHANNEL_POSITION_AUX20 +#define PA_CHANNEL_POSITION_AUX21 PA_CHANNEL_POSITION_AUX21 +#define PA_CHANNEL_POSITION_AUX22 PA_CHANNEL_POSITION_AUX22 +#define PA_CHANNEL_POSITION_AUX23 PA_CHANNEL_POSITION_AUX23 +#define PA_CHANNEL_POSITION_AUX24 PA_CHANNEL_POSITION_AUX24 +#define PA_CHANNEL_POSITION_AUX25 PA_CHANNEL_POSITION_AUX25 +#define PA_CHANNEL_POSITION_AUX26 PA_CHANNEL_POSITION_AUX26 +#define PA_CHANNEL_POSITION_AUX27 PA_CHANNEL_POSITION_AUX27 +#define PA_CHANNEL_POSITION_AUX28 PA_CHANNEL_POSITION_AUX28 +#define PA_CHANNEL_POSITION_AUX29 PA_CHANNEL_POSITION_AUX29 +#define PA_CHANNEL_POSITION_AUX30 PA_CHANNEL_POSITION_AUX30 +#define PA_CHANNEL_POSITION_AUX31 PA_CHANNEL_POSITION_AUX31 +#define PA_CHANNEL_POSITION_TOP_CENTER PA_CHANNEL_POSITION_TOP_CENTER +#define PA_CHANNEL_POSITION_TOP_FRONT_LEFT PA_CHANNEL_POSITION_TOP_FRONT_LEFT +#define PA_CHANNEL_POSITION_TOP_FRONT_RIGHT PA_CHANNEL_POSITION_TOP_FRONT_RIGHT +#define PA_CHANNEL_POSITION_TOP_FRONT_CENTER PA_CHANNEL_POSITION_TOP_FRONT_CENTER +#define PA_CHANNEL_POSITION_TOP_REAR_LEFT PA_CHANNEL_POSITION_TOP_REAR_LEFT +#define PA_CHANNEL_POSITION_TOP_REAR_RIGHT PA_CHANNEL_POSITION_TOP_REAR_RIGHT +#define PA_CHANNEL_POSITION_TOP_REAR_CENTER PA_CHANNEL_POSITION_TOP_REAR_CENTER +#define PA_CHANNEL_POSITION_MAX PA_CHANNEL_POSITION_MAX +/** \endcond */ + +/** A mask of channel positions. \since 0.9.16 */ +typedef uint64_t pa_channel_position_mask_t; + +/** Makes a bit mask from a channel position. \since 0.9.16 */ +#define PA_CHANNEL_POSITION_MASK(f) ((pa_channel_position_mask_t) (1ULL << (f))) + +/** A list of channel mapping definitions for pa_channel_map_init_auto() */ +typedef enum pa_channel_map_def { + PA_CHANNEL_MAP_AIFF, + /**< The mapping from RFC3551, which is based on AIFF-C */ + +/** \cond fulldocs */ + PA_CHANNEL_MAP_ALSA, + /**< The default mapping used by ALSA. This mapping is probably + * not too useful since ALSA's default channel mapping depends on + * the device string used. */ +/** \endcond */ + + PA_CHANNEL_MAP_AUX, + /**< Only aux channels */ + + PA_CHANNEL_MAP_WAVEEX, + /**< Microsoft's WAVEFORMATEXTENSIBLE mapping. This mapping works + * as if all LSBs of dwChannelMask are set. */ + +/** \cond fulldocs */ + PA_CHANNEL_MAP_OSS, + /**< The default channel mapping used by OSS as defined in the OSS + * 4.0 API specs. This mapping is probably not too useful since + * the OSS API has changed in this respect and no longer knows a + * default channel mapping based on the number of channels. */ +/** \endcond */ + + /**< Upper limit of valid channel mapping definitions */ + PA_CHANNEL_MAP_DEF_MAX, + + PA_CHANNEL_MAP_DEFAULT = PA_CHANNEL_MAP_AIFF + /**< The default channel map */ +} pa_channel_map_def_t; + +/** \cond fulldocs */ +#define PA_CHANNEL_MAP_AIFF PA_CHANNEL_MAP_AIFF +#define PA_CHANNEL_MAP_ALSA PA_CHANNEL_MAP_ALSA +#define PA_CHANNEL_MAP_AUX PA_CHANNEL_MAP_AUX +#define PA_CHANNEL_MAP_WAVEEX PA_CHANNEL_MAP_WAVEEX +#define PA_CHANNEL_MAP_OSS PA_CHANNEL_MAP_OSS +#define PA_CHANNEL_MAP_DEF_MAX PA_CHANNEL_MAP_DEF_MAX +#define PA_CHANNEL_MAP_DEFAULT PA_CHANNEL_MAP_DEFAULT +/** \endcond */ + +/** A channel map which can be used to attach labels to specific + * channels of a stream. These values are relevant for conversion and + * mixing of streams */ +typedef struct pa_channel_map { + uint8_t channels; + /**< Number of channels */ + + pa_channel_position_t map[PA_CHANNELS_MAX]; + /**< Channel labels */ +} pa_channel_map; + +/** Initialize the specified channel map and return a pointer to + * it. The channel map will have a defined state but + * pa_channel_map_valid() will fail for it. */ +pa_channel_map* pa_channel_map_init(pa_channel_map *m); + +/** Initialize the specified channel map for monaural audio and return a pointer to it */ +pa_channel_map* pa_channel_map_init_mono(pa_channel_map *m); + +/** Initialize the specified channel map for stereophonic audio and return a pointer to it */ +pa_channel_map* pa_channel_map_init_stereo(pa_channel_map *m); + +/** Initialize the specified channel map for the specified number of + * channels using default labels and return a pointer to it. This call + * will fail (return NULL) if there is no default channel map known for this + * specific number of channels and mapping. */ +pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, pa_channel_map_def_t def); + +/** Similar to pa_channel_map_init_auto() but instead of failing if no + * default mapping is known with the specified parameters it will + * synthesize a mapping based on a known mapping with fewer channels + * and fill up the rest with AUX0...AUX31 channels \since 0.9.11 */ +pa_channel_map* pa_channel_map_init_extend(pa_channel_map *m, unsigned channels, pa_channel_map_def_t def); + +/** Return a text label for the specified channel position */ +const char* pa_channel_position_to_string(pa_channel_position_t pos) PA_GCC_PURE; + +/** The inverse of pa_channel_position_to_string(). \since 0.9.16 */ +pa_channel_position_t pa_channel_position_from_string(const char *s) PA_GCC_PURE; + +/** Return a human readable text label for the specified channel position. \since 0.9.7 */ +const char* pa_channel_position_to_pretty_string(pa_channel_position_t pos); + +/** The maximum length of strings returned by + * pa_channel_map_snprint(). Please note that this value can change + * with any release without warning and without being considered API + * or ABI breakage. You should not use this definition anywhere where + * it might become part of an ABI. */ +#define PA_CHANNEL_MAP_SNPRINT_MAX 336 + +/** Make a human readable string from the specified channel map */ +char* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map); + +/** Parse a channel position list or well-known mapping name into a + * channel map structure. This turns the output of + * pa_channel_map_snprint() and pa_channel_map_to_name() back into a + * pa_channel_map */ +pa_channel_map *pa_channel_map_parse(pa_channel_map *map, const char *s); + +/** Compare two channel maps. Return 1 if both match. */ +int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) PA_GCC_PURE; + +/** Return non-zero if the specified channel map is considered valid */ +int pa_channel_map_valid(const pa_channel_map *map) PA_GCC_PURE; + +/** Return non-zero if the specified channel map is compatible with + * the specified sample spec. \since 0.9.12 */ +int pa_channel_map_compatible(const pa_channel_map *map, const pa_sample_spec *ss) PA_GCC_PURE; + +/** Returns non-zero if every channel defined in b is also defined in a. \since 0.9.15 */ +int pa_channel_map_superset(const pa_channel_map *a, const pa_channel_map *b) PA_GCC_PURE; + +/** Returns non-zero if it makes sense to apply a volume 'balance' + * with this mapping, i.e.\ if there are left/right channels + * available. \since 0.9.15 */ +int pa_channel_map_can_balance(const pa_channel_map *map) PA_GCC_PURE; + +/** Returns non-zero if it makes sense to apply a volume 'fade' + * (i.e.\ 'balance' between front and rear) with this mapping, i.e.\ if + * there are front/rear channels available. \since 0.9.15 */ +int pa_channel_map_can_fade(const pa_channel_map *map) PA_GCC_PURE; + +/** Returns non-zero if it makes sense to apply a volume 'lfe balance' + * (i.e.\ 'balance' between LFE and non-LFE channels) with this mapping, + * i.e.\ if there are LFE and non-LFE channels available. \since 8.0 */ +int pa_channel_map_can_lfe_balance(const pa_channel_map *map) PA_GCC_PURE; + +/** Tries to find a well-known channel mapping name for this channel + * mapping, i.e.\ "stereo", "surround-71" and so on. If the channel + * mapping is unknown NULL will be returned. This name can be parsed + * with pa_channel_map_parse() \since 0.9.15 */ +const char* pa_channel_map_to_name(const pa_channel_map *map) PA_GCC_PURE; + +/** Tries to find a human readable text label for this channel +mapping, i.e.\ "Stereo", "Surround 7.1" and so on. If the channel +mapping is unknown NULL will be returned. \since 0.9.15 */ +const char* pa_channel_map_to_pretty_name(const pa_channel_map *map) PA_GCC_PURE; + +/** Returns non-zero if the specified channel position is available at + * least once in the channel map. \since 0.9.16 */ +int pa_channel_map_has_position(const pa_channel_map *map, pa_channel_position_t p) PA_GCC_PURE; + +/** Generates a bit mask from a channel map. \since 0.9.16 */ +pa_channel_position_mask_t pa_channel_map_mask(const pa_channel_map *map) PA_GCC_PURE; + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/context.h b/thirdparty/linuxbsd_headers/pulse/context.h new file mode 100644 index 0000000000..ae2a068250 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/context.h @@ -0,0 +1,291 @@ +#ifndef foocontexthfoo +#define foocontexthfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <pulse/sample.h> +#include <pulse/def.h> +#include <pulse/mainloop-api.h> +#include <pulse/cdecl.h> +#include <pulse/operation.h> +#include <pulse/proplist.h> +#include <pulse/version.h> + +/** \page async Asynchronous API + * + * \section overv_sec Overview + * + * The asynchronous API is the native interface to the PulseAudio library. + * It allows full access to all available functionality. This however means that + * it is rather complex and can take some time to fully master. + * + * \section mainloop_sec Main Loop Abstraction + * + * The API is based around an asynchronous event loop, or main loop, + * abstraction. This abstraction contains three basic elements: + * + * \li Deferred events - Events that will trigger as soon as possible. Note + * that some implementations may block all other events + * when a deferred event is active. + * \li I/O events - Events that trigger on file descriptor activities. + * \li Times events - Events that trigger after a fixed amount of time. + * + * The abstraction is represented as a number of function pointers in the + * pa_mainloop_api structure. + * + * To actually be able to use these functions, an implementation needs to + * be coupled to the abstraction. There are three of these shipped with + * PulseAudio, but any other can be used with a minimal amount of work, + * provided it supports the three basic events listed above. + * + * The implementations shipped with PulseAudio are: + * + * \li \subpage mainloop - A minimal but fast implementation based on poll(). + * \li \subpage threaded_mainloop - A special version of the previous + * implementation where all of PulseAudio's + * internal handling runs in a separate + * thread. + * \li \subpage glib-mainloop - A wrapper around GLib's main loop. + * + * UNIX signals may be hooked to a main loop using the functions from + * \ref mainloop-signal.h. These rely only on the main loop abstraction + * and can therefore be used with any of the implementations. + * + * \section refcnt_sec Reference Counting + * + * Almost all objects in PulseAudio are reference counted. What that means + * is that you rarely malloc() or free() any objects. Instead you increase + * and decrease their reference counts. Whenever an object's reference + * count reaches zero, that object gets destroy and any resources it uses + * get freed. + * + * The benefit of this design is that an application need not worry about + * whether or not it needs to keep an object around in case the library is + * using it internally. If it is, then it has made sure it has its own + * reference to it. + * + * Whenever the library creates an object, it will have an initial + * reference count of one. Most of the time, this single reference will be + * sufficient for the application, so all required reference count + * interaction will be a single call to the object's unref function. + * + * \section context_sec Context + * + * A context is the basic object for a connection to a PulseAudio server. + * It multiplexes commands, data streams and events through a single + * channel. + * + * There is no need for more than one context per application, unless + * connections to multiple servers are needed. + * + * \subsection ops_subsec Operations + * + * All operations on the context are performed asynchronously. I.e. the + * client will not wait for the server to complete the request. To keep + * track of all these in-flight operations, the application is given a + * pa_operation object for each asynchronous operation. + * + * There are only two actions (besides reference counting) that can be + * performed on a pa_operation: querying its state with + * pa_operation_get_state() and aborting it with pa_operation_cancel(). + * + * A pa_operation object is reference counted, so an application must + * make sure to unreference it, even if it has no intention of using it. + * + * \subsection conn_subsec Connecting + * + * A context must be connected to a server before any operation can be + * issued. Calling pa_context_connect() will initiate the connection + * procedure. Unlike most asynchronous operations, connecting does not + * result in a pa_operation object. Instead, the application should + * register a callback using pa_context_set_state_callback(). + * + * \subsection disc_subsec Disconnecting + * + * When the sound support is no longer needed, the connection needs to be + * closed using pa_context_disconnect(). This is an immediate function that + * works synchronously. + * + * Since the context object has references to other objects it must be + * disconnected after use or there is a high risk of memory leaks. If the + * connection has terminated by itself, then there is no need to explicitly + * disconnect the context using pa_context_disconnect(). + * + * \section Functions + * + * The sound server's functionality can be divided into a number of + * subsections: + * + * \li \subpage streams + * \li \subpage scache + * \li \subpage introspect + * \li \subpage subscribe + */ + +/** \file + * Connection contexts for asynchronous communication with a + * server. A pa_context object wraps a connection to a PulseAudio + * server using its native protocol. + * + * See also \subpage async + */ + +PA_C_DECL_BEGIN + +/** An opaque connection context to a daemon */ +typedef struct pa_context pa_context; + +/** Generic notification callback prototype */ +typedef void (*pa_context_notify_cb_t)(pa_context *c, void *userdata); + +/** A generic callback for operation completion */ +typedef void (*pa_context_success_cb_t) (pa_context *c, int success, void *userdata); + +/** A callback for asynchronous meta/policy event messages. The set + * of defined events can be extended at any time. Also, server modules + * may introduce additional message types so make sure that your + * callback function ignores messages it doesn't know. \since + * 0.9.15 */ +typedef void (*pa_context_event_cb_t)(pa_context *c, const char *name, pa_proplist *p, void *userdata); + +/** Instantiate a new connection context with an abstract mainloop API + * and an application name. It is recommended to use pa_context_new_with_proplist() + * instead and specify some initial properties.*/ +pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name); + +/** Instantiate a new connection context with an abstract mainloop API + * and an application name, and specify the initial client property + * list. \since 0.9.11 */ +pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, pa_proplist *proplist); + +/** Decrease the reference counter of the context by one */ +void pa_context_unref(pa_context *c); + +/** Increase the reference counter of the context by one */ +pa_context* pa_context_ref(pa_context *c); + +/** Set a callback function that is called whenever the context status changes */ +void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, void *userdata); + +/** Set a callback function that is called whenever a meta/policy + * control event is received. \since 0.9.15 */ +void pa_context_set_event_callback(pa_context *p, pa_context_event_cb_t cb, void *userdata); + +/** Return the error number of the last failed operation */ +int pa_context_errno(pa_context *c); + +/** Return non-zero if some data is pending to be written to the connection */ +int pa_context_is_pending(pa_context *c); + +/** Return the current context status */ +pa_context_state_t pa_context_get_state(pa_context *c); + +/** Connect the context to the specified server. If server is NULL, +connect to the default server. This routine may but will not always +return synchronously on error. Use pa_context_set_state_callback() to +be notified when the connection is established. If flags doesn't have +PA_CONTEXT_NOAUTOSPAWN set and no specific server is specified or +accessible a new daemon is spawned. If api is non-NULL, the functions +specified in the structure are used when forking a new child +process. */ +int pa_context_connect(pa_context *c, const char *server, pa_context_flags_t flags, const pa_spawn_api *api); + +/** Terminate the context connection immediately */ +void pa_context_disconnect(pa_context *c); + +/** Drain the context. If there is nothing to drain, the function returns NULL */ +pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *userdata); + +/** Tell the daemon to exit. The returned operation is unlikely to + * complete successfully, since the daemon probably died before + * returning a success notification */ +pa_operation* pa_context_exit_daemon(pa_context *c, pa_context_success_cb_t cb, void *userdata); + +/** Set the name of the default sink. */ +pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata); + +/** Set the name of the default source. */ +pa_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata); + +/** Returns 1 when the connection is to a local daemon. Returns negative when no connection has been made yet. */ +int pa_context_is_local(pa_context *c); + +/** Set a different application name for context on the server. */ +pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata); + +/** Return the server name this context is connected to. */ +const char* pa_context_get_server(pa_context *c); + +/** Return the protocol version of the library. */ +uint32_t pa_context_get_protocol_version(pa_context *c); + +/** Return the protocol version of the connected server. */ +uint32_t pa_context_get_server_protocol_version(pa_context *c); + +/** Update the property list of the client, adding new entries. Please + * note that it is highly recommended to set as much properties + * initially via pa_context_new_with_proplist() as possible instead a + * posteriori with this function, since that information may then be + * used to route streams of the client to the right device. \since 0.9.11 */ +pa_operation *pa_context_proplist_update(pa_context *c, pa_update_mode_t mode, pa_proplist *p, pa_context_success_cb_t cb, void *userdata); + +/** Update the property list of the client, remove entries. \since 0.9.11 */ +pa_operation *pa_context_proplist_remove(pa_context *c, const char *const keys[], pa_context_success_cb_t cb, void *userdata); + +/** Return the client index this context is + * identified in the server with. This is useful for usage with the + * introspection functions, such as pa_context_get_client_info(). \since 0.9.11 */ +uint32_t pa_context_get_index(pa_context *s); + +/** Create a new timer event source for the specified time (wrapper + * for mainloop->time_new). \since 0.9.16 */ +pa_time_event* pa_context_rttime_new(pa_context *c, pa_usec_t usec, pa_time_event_cb_t cb, void *userdata); + +/** Restart a running or expired timer event source (wrapper for + * mainloop->time_restart). \since 0.9.16 */ +void pa_context_rttime_restart(pa_context *c, pa_time_event *e, pa_usec_t usec); + +/** Return the optimal block size for passing around audio buffers. It + * is recommended to allocate buffers of the size returned here when + * writing audio data to playback streams, if the latency constraints + * permit this. It is not recommended writing larger blocks than this + * because usually they will then be split up internally into chunks + * of this size. It is not recommended writing smaller blocks than + * this (unless required due to latency demands) because this + * increases CPU usage. If ss is NULL you will be returned the + * byte-exact tile size. If you pass a valid ss, then the tile size + * will be rounded down to multiple of the frame size. This is + * supposed to be used in a construct such as + * pa_context_get_tile_size(pa_stream_get_context(s), + * pa_stream_get_sample_spec(ss)); \since 0.9.20 */ +size_t pa_context_get_tile_size(pa_context *c, const pa_sample_spec *ss); + +/** Load the authentication cookie from a file. This function is primarily + * meant for PulseAudio's own tunnel modules, which need to load the cookie + * from a custom location. Applications don't usually need to care about the + * cookie at all, but if it happens that you know what the authentication + * cookie is and your application needs to load it from a non-standard + * location, feel free to use this function. \since 5.0 */ +int pa_context_load_cookie_from_file(pa_context *c, const char *cookie_file_path); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/def.h b/thirdparty/linuxbsd_headers/pulse/def.h new file mode 100644 index 0000000000..680bdc9816 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/def.h @@ -0,0 +1,1052 @@ +#ifndef foodefhfoo +#define foodefhfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <inttypes.h> +#include <sys/time.h> + +#include <pulse/cdecl.h> +#include <pulse/sample.h> +#include <pulse/version.h> + +/** \file + * Global definitions */ + +PA_C_DECL_BEGIN + +/** The state of a connection context */ +typedef enum pa_context_state { + PA_CONTEXT_UNCONNECTED, /**< The context hasn't been connected yet */ + PA_CONTEXT_CONNECTING, /**< A connection is being established */ + PA_CONTEXT_AUTHORIZING, /**< The client is authorizing itself to the daemon */ + PA_CONTEXT_SETTING_NAME, /**< The client is passing its application name to the daemon */ + PA_CONTEXT_READY, /**< The connection is established, the context is ready to execute operations */ + PA_CONTEXT_FAILED, /**< The connection failed or was disconnected */ + PA_CONTEXT_TERMINATED /**< The connection was terminated cleanly */ +} pa_context_state_t; + +/** Return non-zero if the passed state is one of the connected states. \since 0.9.11 */ +static inline int PA_CONTEXT_IS_GOOD(pa_context_state_t x) { + return + x == PA_CONTEXT_CONNECTING || + x == PA_CONTEXT_AUTHORIZING || + x == PA_CONTEXT_SETTING_NAME || + x == PA_CONTEXT_READY; +} + +/** \cond fulldocs */ +#define PA_CONTEXT_UNCONNECTED PA_CONTEXT_UNCONNECTED +#define PA_CONTEXT_CONNECTING PA_CONTEXT_CONNECTING +#define PA_CONTEXT_AUTHORIZING PA_CONTEXT_AUTHORIZING +#define PA_CONTEXT_SETTING_NAME PA_CONTEXT_SETTING_NAME +#define PA_CONTEXT_READY PA_CONTEXT_READY +#define PA_CONTEXT_FAILED PA_CONTEXT_FAILED +#define PA_CONTEXT_TERMINATED PA_CONTEXT_TERMINATED +#define PA_CONTEXT_IS_GOOD PA_CONTEXT_IS_GOOD +/** \endcond */ + +/** The state of a stream */ +typedef enum pa_stream_state { + PA_STREAM_UNCONNECTED, /**< The stream is not yet connected to any sink or source */ + PA_STREAM_CREATING, /**< The stream is being created */ + PA_STREAM_READY, /**< The stream is established, you may pass audio data to it now */ + PA_STREAM_FAILED, /**< An error occurred that made the stream invalid */ + PA_STREAM_TERMINATED /**< The stream has been terminated cleanly */ +} pa_stream_state_t; + +/** Return non-zero if the passed state is one of the connected states. \since 0.9.11 */ +static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x) { + return + x == PA_STREAM_CREATING || + x == PA_STREAM_READY; +} + +/** \cond fulldocs */ +#define PA_STREAM_UNCONNECTED PA_STREAM_UNCONNECTED +#define PA_STREAM_CREATING PA_STREAM_CREATING +#define PA_STREAM_READY PA_STREAM_READY +#define PA_STREAM_FAILED PA_STREAM_FAILED +#define PA_STREAM_TERMINATED PA_STREAM_TERMINATED +#define PA_STREAM_IS_GOOD PA_STREAM_IS_GOOD +/** \endcond */ + +/** The state of an operation */ +typedef enum pa_operation_state { + PA_OPERATION_RUNNING, + /**< The operation is still running */ + PA_OPERATION_DONE, + /**< The operation has completed */ + PA_OPERATION_CANCELLED + /**< The operation has been cancelled. Operations may get cancelled by the + * application, or as a result of the context getting disconneted while the + * operation is pending. */ +} pa_operation_state_t; + +/** \cond fulldocs */ +#define PA_OPERATION_RUNNING PA_OPERATION_RUNNING +#define PA_OPERATION_DONE PA_OPERATION_DONE +#define PA_OPERATION_CANCELED PA_OPERATION_CANCELLED +#define PA_OPERATION_CANCELLED PA_OPERATION_CANCELLED +/** \endcond */ + +/** An invalid index */ +#define PA_INVALID_INDEX ((uint32_t) -1) + +/** Some special flags for contexts. */ +typedef enum pa_context_flags { + PA_CONTEXT_NOFLAGS = 0x0000U, + /**< Flag to pass when no specific options are needed (used to avoid casting) \since 0.9.19 */ + PA_CONTEXT_NOAUTOSPAWN = 0x0001U, + /**< Disabled autospawning of the PulseAudio daemon if required */ + PA_CONTEXT_NOFAIL = 0x0002U + /**< Don't fail if the daemon is not available when pa_context_connect() is called, instead enter PA_CONTEXT_CONNECTING state and wait for the daemon to appear. \since 0.9.15 */ +} pa_context_flags_t; + +/** \cond fulldocs */ +/* Allow clients to check with #ifdef for those flags */ +#define PA_CONTEXT_NOAUTOSPAWN PA_CONTEXT_NOAUTOSPAWN +#define PA_CONTEXT_NOFAIL PA_CONTEXT_NOFAIL +/** \endcond */ + +/** Direction bitfield - while we currently do not expose anything bidirectional, + one should test against the bit instead of the value (e.g.\ if (d & PA_DIRECTION_OUTPUT)), + because we might add bidirectional stuff in the future. \since 2.0 +*/ +typedef enum pa_direction { + PA_DIRECTION_OUTPUT = 0x0001U, /**< Output direction */ + PA_DIRECTION_INPUT = 0x0002U /**< Input direction */ +} pa_direction_t; + +/** \cond fulldocs */ +#define PA_DIRECTION_OUTPUT PA_DIRECTION_OUTPUT +#define PA_DIRECTION_INPUT PA_DIRECTION_INPUT +/** \endcond */ + +/** The type of device we are dealing with */ +typedef enum pa_device_type { + PA_DEVICE_TYPE_SINK, /**< Playback device */ + PA_DEVICE_TYPE_SOURCE /**< Recording device */ +} pa_device_type_t; + +/** \cond fulldocs */ +#define PA_DEVICE_TYPE_SINK PA_DEVICE_TYPE_SINK +#define PA_DEVICE_TYPE_SOURCE PA_DEVICE_TYPE_SOURCE +/** \endcond */ + +/** The direction of a pa_stream object */ +typedef enum pa_stream_direction { + PA_STREAM_NODIRECTION, /**< Invalid direction */ + PA_STREAM_PLAYBACK, /**< Playback stream */ + PA_STREAM_RECORD, /**< Record stream */ + PA_STREAM_UPLOAD /**< Sample upload stream */ +} pa_stream_direction_t; + +/** \cond fulldocs */ +#define PA_STREAM_NODIRECTION PA_STREAM_NODIRECTION +#define PA_STREAM_PLAYBACK PA_STREAM_PLAYBACK +#define PA_STREAM_RECORD PA_STREAM_RECORD +#define PA_STREAM_UPLOAD PA_STREAM_UPLOAD +/** \endcond */ + +/** Some special flags for stream connections. */ +typedef enum pa_stream_flags { + + PA_STREAM_NOFLAGS = 0x0000U, + /**< Flag to pass when no specific options are needed (used to avoid casting) \since 0.9.19 */ + + PA_STREAM_START_CORKED = 0x0001U, + /**< Create the stream corked, requiring an explicit + * pa_stream_cork() call to uncork it. */ + + PA_STREAM_INTERPOLATE_TIMING = 0x0002U, + /**< Interpolate the latency for this stream. When enabled, + * pa_stream_get_latency() and pa_stream_get_time() will try to + * estimate the current record/playback time based on the local + * time that passed since the last timing info update. Using this + * option has the advantage of not requiring a whole roundtrip + * when the current playback/recording time is needed. Consider + * using this option when requesting latency information + * frequently. This is especially useful on long latency network + * connections. It makes a lot of sense to combine this option + * with PA_STREAM_AUTO_TIMING_UPDATE. */ + + PA_STREAM_NOT_MONOTONIC = 0x0004U, + /**< Don't force the time to increase monotonically. If this + * option is enabled, pa_stream_get_time() will not necessarily + * return always monotonically increasing time values on each + * call. This may confuse applications which cannot deal with time + * going 'backwards', but has the advantage that bad transport + * latency estimations that caused the time to jump ahead can + * be corrected quickly, without the need to wait. (Please note + * that this flag was named PA_STREAM_NOT_MONOTONOUS in releases + * prior to 0.9.11. The old name is still defined too, for + * compatibility reasons. */ + + PA_STREAM_AUTO_TIMING_UPDATE = 0x0008U, + /**< If set timing update requests are issued periodically + * automatically. Combined with PA_STREAM_INTERPOLATE_TIMING you + * will be able to query the current time and latency with + * pa_stream_get_time() and pa_stream_get_latency() at all times + * without a packet round trip.*/ + + PA_STREAM_NO_REMAP_CHANNELS = 0x0010U, + /**< Don't remap channels by their name, instead map them simply + * by their index. Implies PA_STREAM_NO_REMIX_CHANNELS. Only + * supported when the server is at least PA 0.9.8. It is ignored + * on older servers.\since 0.9.8 */ + + PA_STREAM_NO_REMIX_CHANNELS = 0x0020U, + /**< When remapping channels by name, don't upmix or downmix them + * to related channels. Copy them into matching channels of the + * device 1:1. Only supported when the server is at least PA + * 0.9.8. It is ignored on older servers. \since 0.9.8 */ + + PA_STREAM_FIX_FORMAT = 0x0040U, + /**< Use the sample format of the sink/device this stream is being + * connected to, and possibly ignore the format the sample spec + * contains -- but you still have to pass a valid value in it as a + * hint to PulseAudio what would suit your stream best. If this is + * used you should query the used sample format after creating the + * stream by using pa_stream_get_sample_spec(). Also, if you + * specified manual buffer metrics it is recommended to update + * them with pa_stream_set_buffer_attr() to compensate for the + * changed frame sizes. Only supported when the server is at least + * PA 0.9.8. It is ignored on older servers. + * + * When creating streams with pa_stream_new_extended(), this flag has no + * effect. If you specify a format with PCM encoding, and you want the + * server to choose the sample format, then you should leave the sample + * format unspecified in the pa_format_info object. This also means that + * you can't use pa_format_info_from_sample_spec(), because that function + * always sets the sample format. + * + * \since 0.9.8 */ + + PA_STREAM_FIX_RATE = 0x0080U, + /**< Use the sample rate of the sink, and possibly ignore the rate + * the sample spec contains. Usage similar to + * PA_STREAM_FIX_FORMAT. Only supported when the server is at least + * PA 0.9.8. It is ignored on older servers. + * + * When creating streams with pa_stream_new_extended(), this flag has no + * effect. If you specify a format with PCM encoding, and you want the + * server to choose the sample rate, then you should leave the rate + * unspecified in the pa_format_info object. This also means that you can't + * use pa_format_info_from_sample_spec(), because that function always sets + * the sample rate. + * + * \since 0.9.8 */ + + PA_STREAM_FIX_CHANNELS = 0x0100, + /**< Use the number of channels and the channel map of the sink, + * and possibly ignore the number of channels and the map the + * sample spec and the passed channel map contains. Usage similar + * to PA_STREAM_FIX_FORMAT. Only supported when the server is at + * least PA 0.9.8. It is ignored on older servers. + * + * When creating streams with pa_stream_new_extended(), this flag has no + * effect. If you specify a format with PCM encoding, and you want the + * server to choose the channel count and/or channel map, then you should + * leave the channels and/or the channel map unspecified in the + * pa_format_info object. This also means that you can't use + * pa_format_info_from_sample_spec(), because that function always sets + * the channel count (but if you only want to leave the channel map + * unspecified, then pa_format_info_from_sample_spec() works, because it + * accepts a NULL channel map). + * + * \since 0.9.8 */ + + PA_STREAM_DONT_MOVE = 0x0200U, + /**< Don't allow moving of this stream to another + * sink/device. Useful if you use any of the PA_STREAM_FIX_ flags + * and want to make sure that resampling never takes place -- + * which might happen if the stream is moved to another + * sink/source with a different sample spec/channel map. Only + * supported when the server is at least PA 0.9.8. It is ignored + * on older servers. \since 0.9.8 */ + + PA_STREAM_VARIABLE_RATE = 0x0400U, + /**< Allow dynamic changing of the sampling rate during playback + * with pa_stream_update_sample_rate(). Only supported when the + * server is at least PA 0.9.8. It is ignored on older + * servers. \since 0.9.8 */ + + PA_STREAM_PEAK_DETECT = 0x0800U, + /**< Find peaks instead of resampling. \since 0.9.11 */ + + PA_STREAM_START_MUTED = 0x1000U, + /**< Create in muted state. If neither PA_STREAM_START_UNMUTED nor + * PA_STREAM_START_MUTED it is left to the server to decide + * whether to create the stream in muted or in unmuted + * state. \since 0.9.11 */ + + PA_STREAM_ADJUST_LATENCY = 0x2000U, + /**< Try to adjust the latency of the sink/source based on the + * requested buffer metrics and adjust buffer metrics + * accordingly. Also see pa_buffer_attr. This option may not be + * specified at the same time as PA_STREAM_EARLY_REQUESTS. \since + * 0.9.11 */ + + PA_STREAM_EARLY_REQUESTS = 0x4000U, + /**< Enable compatibility mode for legacy clients that rely on a + * "classic" hardware device fragment-style playback model. If + * this option is set, the minreq value of the buffer metrics gets + * a new meaning: instead of just specifying that no requests + * asking for less new data than this value will be made to the + * client it will also guarantee that requests are generated as + * early as this limit is reached. This flag should only be set in + * very few situations where compatibility with a fragment-based + * playback model needs to be kept and the client applications + * cannot deal with data requests that are delayed to the latest + * moment possible. (Usually these are programs that use usleep() + * or a similar call in their playback loops instead of sleeping + * on the device itself.) Also see pa_buffer_attr. This option may + * not be specified at the same time as + * PA_STREAM_ADJUST_LATENCY. \since 0.9.12 */ + + PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND = 0x8000U, + /**< If set this stream won't be taken into account when it is + * checked whether the device this stream is connected to should + * auto-suspend. \since 0.9.15 */ + + PA_STREAM_START_UNMUTED = 0x10000U, + /**< Create in unmuted state. If neither PA_STREAM_START_UNMUTED + * nor PA_STREAM_START_MUTED it is left to the server to decide + * whether to create the stream in muted or in unmuted + * state. \since 0.9.15 */ + + PA_STREAM_FAIL_ON_SUSPEND = 0x20000U, + /**< If the sink/source this stream is connected to is suspended + * during the creation of this stream, cause it to fail. If the + * sink/source is being suspended during creation of this stream, + * make sure this stream is terminated. \since 0.9.15 */ + + PA_STREAM_RELATIVE_VOLUME = 0x40000U, + /**< If a volume is passed when this stream is created, consider + * it relative to the sink's current volume, never as absolute + * device volume. If this is not specified the volume will be + * consider absolute when the sink is in flat volume mode, + * relative otherwise. \since 0.9.20 */ + + PA_STREAM_PASSTHROUGH = 0x80000U + /**< Used to tag content that will be rendered by passthrough sinks. + * The data will be left as is and not reformatted, resampled. + * \since 1.0 */ + +} pa_stream_flags_t; + +/** \cond fulldocs */ + +/* English is an evil language */ +#define PA_STREAM_NOT_MONOTONOUS PA_STREAM_NOT_MONOTONIC + +/* Allow clients to check with #ifdef for those flags */ +#define PA_STREAM_START_CORKED PA_STREAM_START_CORKED +#define PA_STREAM_INTERPOLATE_TIMING PA_STREAM_INTERPOLATE_TIMING +#define PA_STREAM_NOT_MONOTONIC PA_STREAM_NOT_MONOTONIC +#define PA_STREAM_AUTO_TIMING_UPDATE PA_STREAM_AUTO_TIMING_UPDATE +#define PA_STREAM_NO_REMAP_CHANNELS PA_STREAM_NO_REMAP_CHANNELS +#define PA_STREAM_NO_REMIX_CHANNELS PA_STREAM_NO_REMIX_CHANNELS +#define PA_STREAM_FIX_FORMAT PA_STREAM_FIX_FORMAT +#define PA_STREAM_FIX_RATE PA_STREAM_FIX_RATE +#define PA_STREAM_FIX_CHANNELS PA_STREAM_FIX_CHANNELS +#define PA_STREAM_DONT_MOVE PA_STREAM_DONT_MOVE +#define PA_STREAM_VARIABLE_RATE PA_STREAM_VARIABLE_RATE +#define PA_STREAM_PEAK_DETECT PA_STREAM_PEAK_DETECT +#define PA_STREAM_START_MUTED PA_STREAM_START_MUTED +#define PA_STREAM_ADJUST_LATENCY PA_STREAM_ADJUST_LATENCY +#define PA_STREAM_EARLY_REQUESTS PA_STREAM_EARLY_REQUESTS +#define PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND +#define PA_STREAM_START_UNMUTED PA_STREAM_START_UNMUTED +#define PA_STREAM_FAIL_ON_SUSPEND PA_STREAM_FAIL_ON_SUSPEND +#define PA_STREAM_RELATIVE_VOLUME PA_STREAM_RELATIVE_VOLUME +#define PA_STREAM_PASSTHROUGH PA_STREAM_PASSTHROUGH + +/** \endcond */ + +/** Playback and record buffer metrics */ +typedef struct pa_buffer_attr { + uint32_t maxlength; + /**< Maximum length of the buffer in bytes. Setting this to (uint32_t) -1 + * will initialize this to the maximum value supported by server, + * which is recommended. + * + * In strict low-latency playback scenarios you might want to set this to + * a lower value, likely together with the PA_STREAM_ADJUST_LATENCY flag. + * If you do so, you ensure that the latency doesn't grow beyond what is + * acceptable for the use case, at the cost of getting more underruns if + * the latency is lower than what the server can reliably handle. */ + + uint32_t tlength; + /**< Playback only: target length of the buffer. The server tries + * to assure that at least tlength bytes are always available in + * the per-stream server-side playback buffer. It is recommended + * to set this to (uint32_t) -1, which will initialize this to a + * value that is deemed sensible by the server. However, this + * value will default to something like 2s, i.e. for applications + * that have specific latency requirements this value should be + * set to the maximum latency that the application can deal + * with. When PA_STREAM_ADJUST_LATENCY is not set this value will + * influence only the per-stream playback buffer size. When + * PA_STREAM_ADJUST_LATENCY is set the overall latency of the sink + * plus the playback buffer size is configured to this value. Set + * PA_STREAM_ADJUST_LATENCY if you are interested in adjusting the + * overall latency. Don't set it if you are interested in + * configuring the server-side per-stream playback buffer + * size. */ + + uint32_t prebuf; + /**< Playback only: pre-buffering. The server does not start with + * playback before at least prebuf bytes are available in the + * buffer. It is recommended to set this to (uint32_t) -1, which + * will initialize this to the same value as tlength, whatever + * that may be. Initialize to 0 to enable manual start/stop + * control of the stream. This means that playback will not stop + * on underrun and playback will not start automatically. Instead + * pa_stream_cork() needs to be called explicitly. If you set + * this value to 0 you should also set PA_STREAM_START_CORKED. */ + + uint32_t minreq; + /**< Playback only: minimum request. The server does not request + * less than minreq bytes from the client, instead waits until the + * buffer is free enough to request more bytes at once. It is + * recommended to set this to (uint32_t) -1, which will initialize + * this to a value that is deemed sensible by the server. This + * should be set to a value that gives PulseAudio enough time to + * move the data from the per-stream playback buffer into the + * hardware playback buffer. */ + + uint32_t fragsize; + /**< Recording only: fragment size. The server sends data in + * blocks of fragsize bytes size. Large values diminish + * interactivity with other operations on the connection context + * but decrease control overhead. It is recommended to set this to + * (uint32_t) -1, which will initialize this to a value that is + * deemed sensible by the server. However, this value will default + * to something like 2s, i.e. for applications that have specific + * latency requirements this value should be set to the maximum + * latency that the application can deal with. If + * PA_STREAM_ADJUST_LATENCY is set the overall source latency will + * be adjusted according to this value. If it is not set the + * source latency is left unmodified. */ + +} pa_buffer_attr; + +/** Error values as used by pa_context_errno(). Use pa_strerror() to convert these values to human readable strings */ +typedef enum pa_error_code { + PA_OK = 0, /**< No error */ + PA_ERR_ACCESS, /**< Access failure */ + PA_ERR_COMMAND, /**< Unknown command */ + PA_ERR_INVALID, /**< Invalid argument */ + PA_ERR_EXIST, /**< Entity exists */ + PA_ERR_NOENTITY, /**< No such entity */ + PA_ERR_CONNECTIONREFUSED, /**< Connection refused */ + PA_ERR_PROTOCOL, /**< Protocol error */ + PA_ERR_TIMEOUT, /**< Timeout */ + PA_ERR_AUTHKEY, /**< No authentication key */ + PA_ERR_INTERNAL, /**< Internal error */ + PA_ERR_CONNECTIONTERMINATED, /**< Connection terminated */ + PA_ERR_KILLED, /**< Entity killed */ + PA_ERR_INVALIDSERVER, /**< Invalid server */ + PA_ERR_MODINITFAILED, /**< Module initialization failed */ + PA_ERR_BADSTATE, /**< Bad state */ + PA_ERR_NODATA, /**< No data */ + PA_ERR_VERSION, /**< Incompatible protocol version */ + PA_ERR_TOOLARGE, /**< Data too large */ + PA_ERR_NOTSUPPORTED, /**< Operation not supported \since 0.9.5 */ + PA_ERR_UNKNOWN, /**< The error code was unknown to the client */ + PA_ERR_NOEXTENSION, /**< Extension does not exist. \since 0.9.12 */ + PA_ERR_OBSOLETE, /**< Obsolete functionality. \since 0.9.15 */ + PA_ERR_NOTIMPLEMENTED, /**< Missing implementation. \since 0.9.15 */ + PA_ERR_FORKED, /**< The caller forked without calling execve() and tried to reuse the context. \since 0.9.15 */ + PA_ERR_IO, /**< An IO error happened. \since 0.9.16 */ + PA_ERR_BUSY, /**< Device or resource busy. \since 0.9.17 */ + PA_ERR_MAX /**< Not really an error but the first invalid error code */ +} pa_error_code_t; + +/** \cond fulldocs */ +#define PA_OK PA_OK +#define PA_ERR_ACCESS PA_ERR_ACCESS +#define PA_ERR_COMMAND PA_ERR_COMMAND +#define PA_ERR_INVALID PA_ERR_INVALID +#define PA_ERR_EXIST PA_ERR_EXIST +#define PA_ERR_NOENTITY PA_ERR_NOENTITY +#define PA_ERR_CONNECTIONREFUSED PA_ERR_CONNECTIONREFUSED +#define PA_ERR_PROTOCOL PA_ERR_PROTOCOL +#define PA_ERR_TIMEOUT PA_ERR_TIMEOUT +#define PA_ERR_AUTHKEY PA_ERR_AUTHKEY +#define PA_ERR_INTERNAL PA_ERR_INTERNAL +#define PA_ERR_CONNECTIONTERMINATED PA_ERR_CONNECTIONTERMINATED +#define PA_ERR_KILLED PA_ERR_KILLED +#define PA_ERR_INVALIDSERVER PA_ERR_INVALIDSERVER +#define PA_ERR_MODINITFAILED PA_ERR_MODINITFAILED +#define PA_ERR_BADSTATE PA_ERR_BADSTATE +#define PA_ERR_NODATA PA_ERR_NODATA +#define PA_ERR_VERSION PA_ERR_VERSION +#define PA_ERR_TOOLARGE PA_ERR_TOOLARGE +#define PA_ERR_NOTSUPPORTED PA_ERR_NOTSUPPORTED +#define PA_ERR_UNKNOWN PA_ERR_UNKNOWN +#define PA_ERR_NOEXTENSION PA_ERR_NOEXTENSION +#define PA_ERR_OBSOLETE PA_ERR_OBSOLETE +#define PA_ERR_NOTIMPLEMENTED PA_ERR_NOTIMPLEMENTED +#define PA_ERR_FORKED PA_ERR_FORKED +#define PA_ERR_MAX PA_ERR_MAX +/** \endcond */ + +/** Subscription event mask, as used by pa_context_subscribe() */ +typedef enum pa_subscription_mask { + PA_SUBSCRIPTION_MASK_NULL = 0x0000U, + /**< No events */ + + PA_SUBSCRIPTION_MASK_SINK = 0x0001U, + /**< Sink events */ + + PA_SUBSCRIPTION_MASK_SOURCE = 0x0002U, + /**< Source events */ + + PA_SUBSCRIPTION_MASK_SINK_INPUT = 0x0004U, + /**< Sink input events */ + + PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT = 0x0008U, + /**< Source output events */ + + PA_SUBSCRIPTION_MASK_MODULE = 0x0010U, + /**< Module events */ + + PA_SUBSCRIPTION_MASK_CLIENT = 0x0020U, + /**< Client events */ + + PA_SUBSCRIPTION_MASK_SAMPLE_CACHE = 0x0040U, + /**< Sample cache events */ + + PA_SUBSCRIPTION_MASK_SERVER = 0x0080U, + /**< Other global server changes. */ + +/** \cond fulldocs */ + PA_SUBSCRIPTION_MASK_AUTOLOAD = 0x0100U, + /**< \deprecated Autoload table events. */ +/** \endcond */ + + PA_SUBSCRIPTION_MASK_CARD = 0x0200U, + /**< Card events. \since 0.9.15 */ + + PA_SUBSCRIPTION_MASK_ALL = 0x02ffU + /**< Catch all events */ +} pa_subscription_mask_t; + +/** Subscription event types, as used by pa_context_subscribe() */ +typedef enum pa_subscription_event_type { + PA_SUBSCRIPTION_EVENT_SINK = 0x0000U, + /**< Event type: Sink */ + + PA_SUBSCRIPTION_EVENT_SOURCE = 0x0001U, + /**< Event type: Source */ + + PA_SUBSCRIPTION_EVENT_SINK_INPUT = 0x0002U, + /**< Event type: Sink input */ + + PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT = 0x0003U, + /**< Event type: Source output */ + + PA_SUBSCRIPTION_EVENT_MODULE = 0x0004U, + /**< Event type: Module */ + + PA_SUBSCRIPTION_EVENT_CLIENT = 0x0005U, + /**< Event type: Client */ + + PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE = 0x0006U, + /**< Event type: Sample cache item */ + + PA_SUBSCRIPTION_EVENT_SERVER = 0x0007U, + /**< Event type: Global server change, only occurring with PA_SUBSCRIPTION_EVENT_CHANGE. */ + +/** \cond fulldocs */ + PA_SUBSCRIPTION_EVENT_AUTOLOAD = 0x0008U, + /**< \deprecated Event type: Autoload table changes. */ +/** \endcond */ + + PA_SUBSCRIPTION_EVENT_CARD = 0x0009U, + /**< Event type: Card \since 0.9.15 */ + + PA_SUBSCRIPTION_EVENT_FACILITY_MASK = 0x000FU, + /**< A mask to extract the event type from an event value */ + + PA_SUBSCRIPTION_EVENT_NEW = 0x0000U, + /**< A new object was created */ + + PA_SUBSCRIPTION_EVENT_CHANGE = 0x0010U, + /**< A property of the object was modified */ + + PA_SUBSCRIPTION_EVENT_REMOVE = 0x0020U, + /**< An object was removed */ + + PA_SUBSCRIPTION_EVENT_TYPE_MASK = 0x0030U + /**< A mask to extract the event operation from an event value */ + +} pa_subscription_event_type_t; + +/** Return one if an event type t matches an event mask bitfield */ +#define pa_subscription_match_flags(m, t) (!!((m) & (1 << ((t) & PA_SUBSCRIPTION_EVENT_FACILITY_MASK)))) + +/** \cond fulldocs */ +#define PA_SUBSCRIPTION_MASK_NULL PA_SUBSCRIPTION_MASK_NULL +#define PA_SUBSCRIPTION_MASK_SINK PA_SUBSCRIPTION_MASK_SINK +#define PA_SUBSCRIPTION_MASK_SOURCE PA_SUBSCRIPTION_MASK_SOURCE +#define PA_SUBSCRIPTION_MASK_SINK_INPUT PA_SUBSCRIPTION_MASK_SINK_INPUT +#define PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT +#define PA_SUBSCRIPTION_MASK_MODULE PA_SUBSCRIPTION_MASK_MODULE +#define PA_SUBSCRIPTION_MASK_CLIENT PA_SUBSCRIPTION_MASK_CLIENT +#define PA_SUBSCRIPTION_MASK_SAMPLE_CACHE PA_SUBSCRIPTION_MASK_SAMPLE_CACHE +#define PA_SUBSCRIPTION_MASK_SERVER PA_SUBSCRIPTION_MASK_SERVER +#define PA_SUBSCRIPTION_MASK_AUTOLOAD PA_SUBSCRIPTION_MASK_AUTOLOAD +#define PA_SUBSCRIPTION_MASK_CARD PA_SUBSCRIPTION_MASK_CARD +#define PA_SUBSCRIPTION_MASK_ALL PA_SUBSCRIPTION_MASK_ALL +#define PA_SUBSCRIPTION_EVENT_SINK PA_SUBSCRIPTION_EVENT_SINK +#define PA_SUBSCRIPTION_EVENT_SOURCE PA_SUBSCRIPTION_EVENT_SOURCE +#define PA_SUBSCRIPTION_EVENT_SINK_INPUT PA_SUBSCRIPTION_EVENT_SINK_INPUT +#define PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT +#define PA_SUBSCRIPTION_EVENT_MODULE PA_SUBSCRIPTION_EVENT_MODULE +#define PA_SUBSCRIPTION_EVENT_CLIENT PA_SUBSCRIPTION_EVENT_CLIENT +#define PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE +#define PA_SUBSCRIPTION_EVENT_SERVER PA_SUBSCRIPTION_EVENT_SERVER +#define PA_SUBSCRIPTION_EVENT_AUTOLOAD PA_SUBSCRIPTION_EVENT_AUTOLOAD +#define PA_SUBSCRIPTION_EVENT_CARD PA_SUBSCRIPTION_EVENT_CARD +#define PA_SUBSCRIPTION_EVENT_FACILITY_MASK PA_SUBSCRIPTION_EVENT_FACILITY_MASK +#define PA_SUBSCRIPTION_EVENT_NEW PA_SUBSCRIPTION_EVENT_NEW +#define PA_SUBSCRIPTION_EVENT_CHANGE PA_SUBSCRIPTION_EVENT_CHANGE +#define PA_SUBSCRIPTION_EVENT_REMOVE PA_SUBSCRIPTION_EVENT_REMOVE +#define PA_SUBSCRIPTION_EVENT_TYPE_MASK PA_SUBSCRIPTION_EVENT_TYPE_MASK +/** \endcond */ + +/** A structure for all kinds of timing information of a stream. See + * pa_stream_update_timing_info() and pa_stream_get_timing_info(). The + * total output latency a sample that is written with + * pa_stream_write() takes to be played may be estimated by + * sink_usec+buffer_usec+transport_usec. (where buffer_usec is defined + * as pa_bytes_to_usec(write_index-read_index)) The output buffer + * which buffer_usec relates to may be manipulated freely (with + * pa_stream_write()'s seek argument, pa_stream_flush() and friends), + * the buffers sink_usec and source_usec relate to are first-in + * first-out (FIFO) buffers which cannot be flushed or manipulated in + * any way. The total input latency a sample that is recorded takes to + * be delivered to the application is: + * source_usec+buffer_usec+transport_usec-sink_usec. (Take care of + * sign issues!) When connected to a monitor source sink_usec contains + * the latency of the owning sink. The two latency estimations + * described here are implemented in pa_stream_get_latency(). Please + * note that this structure can be extended as part of evolutionary + * API updates at any time in any new release.*/ +typedef struct pa_timing_info { + struct timeval timestamp; + /**< The time when this timing info structure was current */ + + int synchronized_clocks; + /**< Non-zero if the local and the remote machine have + * synchronized clocks. If synchronized clocks are detected + * transport_usec becomes much more reliable. However, the code + * that detects synchronized clocks is very limited and unreliable + * itself. */ + + pa_usec_t sink_usec; + /**< Time in usecs a sample takes to be played on the sink. For + * playback streams and record streams connected to a monitor + * source. */ + + pa_usec_t source_usec; + /**< Time in usecs a sample takes from being recorded to being + * delivered to the application. Only for record streams. */ + + pa_usec_t transport_usec; + /**< Estimated time in usecs a sample takes to be transferred + * to/from the daemon. For both playback and record streams. */ + + int playing; + /**< Non-zero when the stream is currently not underrun and data + * is being passed on to the device. Only for playback + * streams. This field does not say whether the data is actually + * already being played. To determine this check whether + * since_underrun (converted to usec) is larger than sink_usec.*/ + + int write_index_corrupt; + /**< Non-zero if write_index is not up-to-date because a local + * write command that corrupted it has been issued in the time + * since this latency info was current . Only write commands with + * SEEK_RELATIVE_ON_READ and SEEK_RELATIVE_END can corrupt + * write_index. */ + + int64_t write_index; + /**< Current write index into the playback buffer in bytes. Think + * twice before using this for seeking purposes: it might be out + * of date a the time you want to use it. Consider using + * PA_SEEK_RELATIVE instead. */ + + int read_index_corrupt; + /**< Non-zero if read_index is not up-to-date because a local + * pause or flush request that corrupted it has been issued in the + * time since this latency info was current. */ + + int64_t read_index; + /**< Current read index into the playback buffer in bytes. Think + * twice before using this for seeking purposes: it might be out + * of date a the time you want to use it. Consider using + * PA_SEEK_RELATIVE_ON_READ instead. */ + + pa_usec_t configured_sink_usec; + /**< The configured latency for the sink. \since 0.9.11 */ + + pa_usec_t configured_source_usec; + /**< The configured latency for the source. \since 0.9.11 */ + + int64_t since_underrun; + /**< Bytes that were handed to the sink since the last underrun + * happened, or since playback started again after the last + * underrun. playing will tell you which case it is. \since + * 0.9.11 */ + +} pa_timing_info; + +/** A structure for the spawn api. This may be used to integrate auto + * spawned daemons into your application. For more information see + * pa_context_connect(). When spawning a new child process the + * waitpid() is used on the child's PID. The spawn routine will not + * block or ignore SIGCHLD signals, since this cannot be done in a + * thread compatible way. You might have to do this in + * prefork/postfork. */ +typedef struct pa_spawn_api { + void (*prefork)(void); + /**< Is called just before the fork in the parent process. May be + * NULL. */ + + void (*postfork)(void); + /**< Is called immediately after the fork in the parent + * process. May be NULL.*/ + + void (*atfork)(void); + /**< Is called immediately after the fork in the child + * process. May be NULL. It is not safe to close all file + * descriptors in this function unconditionally, since a UNIX + * socket (created using socketpair()) is passed to the new + * process. */ +} pa_spawn_api; + +/** Seek type for pa_stream_write(). */ +typedef enum pa_seek_mode { + PA_SEEK_RELATIVE = 0, + /**< Seek relatively to the write index */ + + PA_SEEK_ABSOLUTE = 1, + /**< Seek relatively to the start of the buffer queue */ + + PA_SEEK_RELATIVE_ON_READ = 2, + /**< Seek relatively to the read index. */ + + PA_SEEK_RELATIVE_END = 3 + /**< Seek relatively to the current end of the buffer queue. */ +} pa_seek_mode_t; + +/** \cond fulldocs */ +#define PA_SEEK_RELATIVE PA_SEEK_RELATIVE +#define PA_SEEK_ABSOLUTE PA_SEEK_ABSOLUTE +#define PA_SEEK_RELATIVE_ON_READ PA_SEEK_RELATIVE_ON_READ +#define PA_SEEK_RELATIVE_END PA_SEEK_RELATIVE_END +/** \endcond */ + +/** Special sink flags. */ +typedef enum pa_sink_flags { + PA_SINK_NOFLAGS = 0x0000U, + /**< Flag to pass when no specific options are needed (used to avoid casting) \since 0.9.19 */ + + PA_SINK_HW_VOLUME_CTRL = 0x0001U, + /**< Supports hardware volume control. This is a dynamic flag and may + * change at runtime after the sink has initialized */ + + PA_SINK_LATENCY = 0x0002U, + /**< Supports latency querying */ + + PA_SINK_HARDWARE = 0x0004U, + /**< Is a hardware sink of some kind, in contrast to + * "virtual"/software sinks \since 0.9.3 */ + + PA_SINK_NETWORK = 0x0008U, + /**< Is a networked sink of some kind. \since 0.9.7 */ + + PA_SINK_HW_MUTE_CTRL = 0x0010U, + /**< Supports hardware mute control. This is a dynamic flag and may + * change at runtime after the sink has initialized \since 0.9.11 */ + + PA_SINK_DECIBEL_VOLUME = 0x0020U, + /**< Volume can be translated to dB with pa_sw_volume_to_dB(). This is a + * dynamic flag and may change at runtime after the sink has initialized + * \since 0.9.11 */ + + PA_SINK_FLAT_VOLUME = 0x0040U, + /**< This sink is in flat volume mode, i.e.\ always the maximum of + * the volume of all connected inputs. \since 0.9.15 */ + + PA_SINK_DYNAMIC_LATENCY = 0x0080U, + /**< The latency can be adjusted dynamically depending on the + * needs of the connected streams. \since 0.9.15 */ + + PA_SINK_SET_FORMATS = 0x0100U, + /**< The sink allows setting what formats are supported by the connected + * hardware. The actual functionality to do this might be provided by an + * extension. \since 1.0 */ + +#ifdef __INCLUDED_FROM_PULSE_AUDIO +/** \cond fulldocs */ + /* PRIVATE: Server-side values -- do not try to use these at client-side. + * The server will filter out these flags anyway, so you should never see + * these flags in sinks. */ + + PA_SINK_SHARE_VOLUME_WITH_MASTER = 0x1000000U, + /**< This sink shares the volume with the master sink (used by some filter + * sinks). */ + + PA_SINK_DEFERRED_VOLUME = 0x2000000U, + /**< The HW volume changes are syncronized with SW volume. */ +/** \endcond */ +#endif + +} pa_sink_flags_t; + +/** \cond fulldocs */ +#define PA_SINK_HW_VOLUME_CTRL PA_SINK_HW_VOLUME_CTRL +#define PA_SINK_LATENCY PA_SINK_LATENCY +#define PA_SINK_HARDWARE PA_SINK_HARDWARE +#define PA_SINK_NETWORK PA_SINK_NETWORK +#define PA_SINK_HW_MUTE_CTRL PA_SINK_HW_MUTE_CTRL +#define PA_SINK_DECIBEL_VOLUME PA_SINK_DECIBEL_VOLUME +#define PA_SINK_FLAT_VOLUME PA_SINK_FLAT_VOLUME +#define PA_SINK_DYNAMIC_LATENCY PA_SINK_DYNAMIC_LATENCY +#define PA_SINK_SET_FORMATS PA_SINK_SET_FORMATS +#ifdef __INCLUDED_FROM_PULSE_AUDIO +#define PA_SINK_CLIENT_FLAGS_MASK 0xFFFFFF +#endif + +/** \endcond */ + +/** Sink state. \since 0.9.15 */ +typedef enum pa_sink_state { /* enum serialized in u8 */ + PA_SINK_INVALID_STATE = -1, + /**< This state is used when the server does not support sink state introspection \since 0.9.15 */ + + PA_SINK_RUNNING = 0, + /**< Running, sink is playing and used by at least one non-corked sink-input \since 0.9.15 */ + + PA_SINK_IDLE = 1, + /**< When idle, the sink is playing but there is no non-corked sink-input attached to it \since 0.9.15 */ + + PA_SINK_SUSPENDED = 2, + /**< When suspended, actual sink access can be closed, for instance \since 0.9.15 */ + +/** \cond fulldocs */ + /* PRIVATE: Server-side values -- DO NOT USE THIS ON THE CLIENT + * SIDE! These values are *not* considered part of the official PA + * API/ABI. If you use them your application might break when PA + * is upgraded. Also, please note that these values are not useful + * on the client side anyway. */ + + PA_SINK_INIT = -2, + /**< Initialization state */ + + PA_SINK_UNLINKED = -3 + /**< The state when the sink is getting unregistered and removed from client access */ +/** \endcond */ + +} pa_sink_state_t; + +/** Returns non-zero if sink is playing: running or idle. \since 0.9.15 */ +static inline int PA_SINK_IS_OPENED(pa_sink_state_t x) { + return x == PA_SINK_RUNNING || x == PA_SINK_IDLE; +} + +/** Returns non-zero if sink is running. \since 1.0 */ +static inline int PA_SINK_IS_RUNNING(pa_sink_state_t x) { + return x == PA_SINK_RUNNING; +} + +/** \cond fulldocs */ +#define PA_SINK_INVALID_STATE PA_SINK_INVALID_STATE +#define PA_SINK_RUNNING PA_SINK_RUNNING +#define PA_SINK_IDLE PA_SINK_IDLE +#define PA_SINK_SUSPENDED PA_SINK_SUSPENDED +#define PA_SINK_INIT PA_SINK_INIT +#define PA_SINK_UNLINKED PA_SINK_UNLINKED +#define PA_SINK_IS_OPENED PA_SINK_IS_OPENED +/** \endcond */ + +/** Special source flags. */ +typedef enum pa_source_flags { + PA_SOURCE_NOFLAGS = 0x0000U, + /**< Flag to pass when no specific options are needed (used to avoid casting) \since 0.9.19 */ + + PA_SOURCE_HW_VOLUME_CTRL = 0x0001U, + /**< Supports hardware volume control. This is a dynamic flag and may + * change at runtime after the source has initialized */ + + PA_SOURCE_LATENCY = 0x0002U, + /**< Supports latency querying */ + + PA_SOURCE_HARDWARE = 0x0004U, + /**< Is a hardware source of some kind, in contrast to + * "virtual"/software source \since 0.9.3 */ + + PA_SOURCE_NETWORK = 0x0008U, + /**< Is a networked source of some kind. \since 0.9.7 */ + + PA_SOURCE_HW_MUTE_CTRL = 0x0010U, + /**< Supports hardware mute control. This is a dynamic flag and may + * change at runtime after the source has initialized \since 0.9.11 */ + + PA_SOURCE_DECIBEL_VOLUME = 0x0020U, + /**< Volume can be translated to dB with pa_sw_volume_to_dB(). This is a + * dynamic flag and may change at runtime after the source has initialized + * \since 0.9.11 */ + + PA_SOURCE_DYNAMIC_LATENCY = 0x0040U, + /**< The latency can be adjusted dynamically depending on the + * needs of the connected streams. \since 0.9.15 */ + + PA_SOURCE_FLAT_VOLUME = 0x0080U, + /**< This source is in flat volume mode, i.e.\ always the maximum of + * the volume of all connected outputs. \since 1.0 */ + +#ifdef __INCLUDED_FROM_PULSE_AUDIO +/** \cond fulldocs */ + /* PRIVATE: Server-side values -- do not try to use these at client-side. + * The server will filter out these flags anyway, so you should never see + * these flags in sources. */ + + PA_SOURCE_SHARE_VOLUME_WITH_MASTER = 0x1000000U, + /**< This source shares the volume with the master source (used by some filter + * sources). */ + + PA_SOURCE_DEFERRED_VOLUME = 0x2000000U, + /**< The HW volume changes are syncronized with SW volume. */ +#endif +} pa_source_flags_t; + +/** \cond fulldocs */ +#define PA_SOURCE_HW_VOLUME_CTRL PA_SOURCE_HW_VOLUME_CTRL +#define PA_SOURCE_LATENCY PA_SOURCE_LATENCY +#define PA_SOURCE_HARDWARE PA_SOURCE_HARDWARE +#define PA_SOURCE_NETWORK PA_SOURCE_NETWORK +#define PA_SOURCE_HW_MUTE_CTRL PA_SOURCE_HW_MUTE_CTRL +#define PA_SOURCE_DECIBEL_VOLUME PA_SOURCE_DECIBEL_VOLUME +#define PA_SOURCE_DYNAMIC_LATENCY PA_SOURCE_DYNAMIC_LATENCY +#define PA_SOURCE_FLAT_VOLUME PA_SOURCE_FLAT_VOLUME +#ifdef __INCLUDED_FROM_PULSE_AUDIO +#define PA_SOURCE_CLIENT_FLAGS_MASK 0xFFFFFF +#endif + +/** \endcond */ + +/** Source state. \since 0.9.15 */ +typedef enum pa_source_state { + PA_SOURCE_INVALID_STATE = -1, + /**< This state is used when the server does not support source state introspection \since 0.9.15 */ + + PA_SOURCE_RUNNING = 0, + /**< Running, source is recording and used by at least one non-corked source-output \since 0.9.15 */ + + PA_SOURCE_IDLE = 1, + /**< When idle, the source is still recording but there is no non-corked source-output \since 0.9.15 */ + + PA_SOURCE_SUSPENDED = 2, + /**< When suspended, actual source access can be closed, for instance \since 0.9.15 */ + +/** \cond fulldocs */ + /* PRIVATE: Server-side values -- DO NOT USE THIS ON THE CLIENT + * SIDE! These values are *not* considered part of the official PA + * API/ABI. If you use them your application might break when PA + * is upgraded. Also, please note that these values are not useful + * on the client side anyway. */ + + PA_SOURCE_INIT = -2, + /**< Initialization state */ + + PA_SOURCE_UNLINKED = -3 + /**< The state when the source is getting unregistered and removed from client access */ +/** \endcond */ + +} pa_source_state_t; + +/** Returns non-zero if source is recording: running or idle. \since 0.9.15 */ +static inline int PA_SOURCE_IS_OPENED(pa_source_state_t x) { + return x == PA_SOURCE_RUNNING || x == PA_SOURCE_IDLE; +} + +/** Returns non-zero if source is running \since 1.0 */ +static inline int PA_SOURCE_IS_RUNNING(pa_source_state_t x) { + return x == PA_SOURCE_RUNNING; +} + +/** \cond fulldocs */ +#define PA_SOURCE_INVALID_STATE PA_SOURCE_INVALID_STATE +#define PA_SOURCE_RUNNING PA_SOURCE_RUNNING +#define PA_SOURCE_IDLE PA_SOURCE_IDLE +#define PA_SOURCE_SUSPENDED PA_SOURCE_SUSPENDED +#define PA_SOURCE_INIT PA_SOURCE_INIT +#define PA_SOURCE_UNLINKED PA_SOURCE_UNLINKED +#define PA_SOURCE_IS_OPENED PA_SOURCE_IS_OPENED +/** \endcond */ + +/** A generic free() like callback prototype */ +typedef void (*pa_free_cb_t)(void *p); + +/** A stream policy/meta event requesting that an application should + * cork a specific stream. See pa_stream_event_cb_t for more + * information. \since 0.9.15 */ +#define PA_STREAM_EVENT_REQUEST_CORK "request-cork" + +/** A stream policy/meta event requesting that an application should + * cork a specific stream. See pa_stream_event_cb_t for more + * information, \since 0.9.15 */ +#define PA_STREAM_EVENT_REQUEST_UNCORK "request-uncork" + +/** A stream event notifying that the stream is going to be + * disconnected because the underlying sink changed and no longer + * supports the format that was originally negotiated. Clients need + * to connect a new stream to renegotiate a format and continue + * playback. \since 1.0 */ +#define PA_STREAM_EVENT_FORMAT_LOST "format-lost" + +#ifndef __INCLUDED_FROM_PULSE_AUDIO +/** Port availability / jack detection status + * \since 2.0 */ +typedef enum pa_port_available { + PA_PORT_AVAILABLE_UNKNOWN = 0, /**< This port does not support jack detection \since 2.0 */ + PA_PORT_AVAILABLE_NO = 1, /**< This port is not available, likely because the jack is not plugged in. \since 2.0 */ + PA_PORT_AVAILABLE_YES = 2, /**< This port is available, likely because the jack is plugged in. \since 2.0 */ +} pa_port_available_t; + +/** \cond fulldocs */ +#define PA_PORT_AVAILABLE_UNKNOWN PA_PORT_AVAILABLE_UNKNOWN +#define PA_PORT_AVAILABLE_NO PA_PORT_AVAILABLE_NO +#define PA_PORT_AVAILABLE_YES PA_PORT_AVAILABLE_YES + +/** \endcond */ +#endif + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/direction.h b/thirdparty/linuxbsd_headers/pulse/direction.h new file mode 100644 index 0000000000..65ece6975a --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/direction.h @@ -0,0 +1,35 @@ +#ifndef foodirectionhfoo +#define foodirectionhfoo + +/*** + This file is part of PulseAudio. + + Copyright 2014 Intel Corporation + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <pulse/def.h> + +/** \file + * Utility functions for \ref pa_direction_t. */ + +/** Return non-zero if the given value is a valid direction (either input, + * output or bidirectional). \since 6.0 */ +int pa_direction_valid(pa_direction_t direction) PA_GCC_CONST; + +/** Return a textual representation of the direction. \since 6.0 */ +const char *pa_direction_to_string(pa_direction_t direction); + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/error.h b/thirdparty/linuxbsd_headers/pulse/error.h new file mode 100644 index 0000000000..7b9b84ad0e --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/error.h @@ -0,0 +1,37 @@ +#ifndef fooerrorhfoo +#define fooerrorhfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <pulse/cdecl.h> +#include <pulse/version.h> + +/** \file + * Error management */ + +PA_C_DECL_BEGIN + +/** Return a human readable error message for the specified numeric error code */ +const char* pa_strerror(int error); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/ext-device-manager.h b/thirdparty/linuxbsd_headers/pulse/ext-device-manager.h new file mode 100644 index 0000000000..8c05e1cc10 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/ext-device-manager.h @@ -0,0 +1,130 @@ +#ifndef foopulseextdevicemanagerhfoo +#define foopulseextdevicemanagerhfoo + +/*** + This file is part of PulseAudio. + + Copyright 2008 Lennart Poettering + Copyright 2009 Colin Guthrie + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <pulse/cdecl.h> +#include <pulse/context.h> +#include <pulse/version.h> + +/** \file + * + * Routines for controlling module-device-manager + */ + +PA_C_DECL_BEGIN + +/* Don't extend this struct! It will break binary compatibility, because + * pa_ext_device_manager_info.role_priorities points to an array of structs + * instead of an array of pointers to structs. */ +typedef struct pa_ext_device_manager_role_priority_info { + const char *role; + uint32_t priority; +} pa_ext_device_manager_role_priority_info; + +/** Stores information about one device in the device database that is + * maintained by module-device-manager. \since 0.9.21 */ +typedef struct pa_ext_device_manager_info { + const char *name; /**< Identifier string of the device. A string like "sink:" or similar followed by the name of the device. */ + const char *description; /**< The description of the device when it was last seen, if applicable and saved */ + const char *icon; /**< The icon given to the device */ + uint32_t index; /**< The device index if it is currently available or PA_INVALID_INDEX */ + uint32_t n_role_priorities; /**< How many role priorities do we have? */ + pa_ext_device_manager_role_priority_info *role_priorities; /**< An array of role priority structures or NULL */ +} pa_ext_device_manager_info; + +/** Callback prototype for pa_ext_device_manager_test(). \since 0.9.21 */ +typedef void (*pa_ext_device_manager_test_cb_t)( + pa_context *c, + uint32_t version, + void *userdata); + +/** Test if this extension module is available in the server. \since 0.9.21 */ +pa_operation *pa_ext_device_manager_test( + pa_context *c, + pa_ext_device_manager_test_cb_t cb, + void *userdata); + +/** Callback prototype for pa_ext_device_manager_read(). \since 0.9.21 */ +typedef void (*pa_ext_device_manager_read_cb_t)( + pa_context *c, + const pa_ext_device_manager_info *info, + int eol, + void *userdata); + +/** Read all entries from the device database. \since 0.9.21 */ +pa_operation *pa_ext_device_manager_read( + pa_context *c, + pa_ext_device_manager_read_cb_t cb, + void *userdata); + +/** Sets the description for a device. \since 0.9.21 */ +pa_operation *pa_ext_device_manager_set_device_description( + pa_context *c, + const char* device, + const char* description, + pa_context_success_cb_t cb, + void *userdata); + +/** Delete entries from the device database. \since 0.9.21 */ +pa_operation *pa_ext_device_manager_delete( + pa_context *c, + const char *const s[], + pa_context_success_cb_t cb, + void *userdata); + +/** Enable the role-based device-priority routing mode. \since 0.9.21 */ +pa_operation *pa_ext_device_manager_enable_role_device_priority_routing( + pa_context *c, + int enable, + pa_context_success_cb_t cb, + void *userdata); + +/** Prefer a given device in the priority list. \since 0.9.21 */ +pa_operation *pa_ext_device_manager_reorder_devices_for_role( + pa_context *c, + const char* role, + const char** devices, + pa_context_success_cb_t cb, + void *userdata); + +/** Subscribe to changes in the device database. \since 0.9.21 */ +pa_operation *pa_ext_device_manager_subscribe( + pa_context *c, + int enable, + pa_context_success_cb_t cb, + void *userdata); + +/** Callback prototype for pa_ext_device_manager_set_subscribe_cb(). \since 0.9.21 */ +typedef void (*pa_ext_device_manager_subscribe_cb_t)( + pa_context *c, + void *userdata); + +/** Set the subscription callback that is called when + * pa_ext_device_manager_subscribe() was called. \since 0.9.21 */ +void pa_ext_device_manager_set_subscribe_cb( + pa_context *c, + pa_ext_device_manager_subscribe_cb_t cb, + void *userdata); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/ext-device-restore.h b/thirdparty/linuxbsd_headers/pulse/ext-device-restore.h new file mode 100644 index 0000000000..246b06050a --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/ext-device-restore.h @@ -0,0 +1,110 @@ +#ifndef foopulseextdevicerestorehfoo +#define foopulseextdevicerestorehfoo + +/*** + This file is part of PulseAudio. + + Copyright 2008 Lennart Poettering + Copyright 2011 Colin Guthrie + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <pulse/context.h> +#include <pulse/format.h> +#include <pulse/version.h> + +/** \file + * + * Routines for controlling module-device-restore + */ + +PA_C_DECL_BEGIN + +/** Stores information about one device in the device database that is + * maintained by module-device-manager. \since 1.0 */ +typedef struct pa_ext_device_restore_info { + pa_device_type_t type; /**< Device type sink or source? */ + uint32_t index; /**< The device index */ + uint8_t n_formats; /**< How many formats do we have? */ + pa_format_info **formats; /**< An array of formats (may be NULL if n_formats == 0) */ +} pa_ext_device_restore_info; + +/** Callback prototype for pa_ext_device_restore_test(). \since 1.0 */ +typedef void (*pa_ext_device_restore_test_cb_t)( + pa_context *c, + uint32_t version, + void *userdata); + +/** Test if this extension module is available in the server. \since 1.0 */ +pa_operation *pa_ext_device_restore_test( + pa_context *c, + pa_ext_device_restore_test_cb_t cb, + void *userdata); + +/** Subscribe to changes in the device database. \since 1.0 */ +pa_operation *pa_ext_device_restore_subscribe( + pa_context *c, + int enable, + pa_context_success_cb_t cb, + void *userdata); + +/** Callback prototype for pa_ext_device_restore_set_subscribe_cb(). \since 1.0 */ +typedef void (*pa_ext_device_restore_subscribe_cb_t)( + pa_context *c, + pa_device_type_t type, + uint32_t idx, + void *userdata); + +/** Set the subscription callback that is called when + * pa_ext_device_restore_subscribe() was called. \since 1.0 */ +void pa_ext_device_restore_set_subscribe_cb( + pa_context *c, + pa_ext_device_restore_subscribe_cb_t cb, + void *userdata); + +/** Callback prototype for pa_ext_device_restore_read_formats(). \since 1.0 */ +typedef void (*pa_ext_device_restore_read_device_formats_cb_t)( + pa_context *c, + const pa_ext_device_restore_info *info, + int eol, + void *userdata); + +/** Read the formats for all present devices from the device database. \since 1.0 */ +pa_operation *pa_ext_device_restore_read_formats_all( + pa_context *c, + pa_ext_device_restore_read_device_formats_cb_t cb, + void *userdata); + +/** Read an entry from the device database. \since 1.0 */ +pa_operation *pa_ext_device_restore_read_formats( + pa_context *c, + pa_device_type_t type, + uint32_t idx, + pa_ext_device_restore_read_device_formats_cb_t cb, + void *userdata); + +/** Read an entry from the device database. \since 1.0 */ +pa_operation *pa_ext_device_restore_save_formats( + pa_context *c, + pa_device_type_t type, + uint32_t idx, + uint8_t n_formats, + pa_format_info **formats, + pa_context_success_cb_t cb, + void *userdata); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/ext-stream-restore.h b/thirdparty/linuxbsd_headers/pulse/ext-stream-restore.h new file mode 100644 index 0000000000..dd7f4ae4fe --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/ext-stream-restore.h @@ -0,0 +1,109 @@ +#ifndef foopulseextstreamrestorehfoo +#define foopulseextstreamrestorehfoo + +/*** + This file is part of PulseAudio. + + Copyright 2008 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <pulse/cdecl.h> +#include <pulse/context.h> +#include <pulse/version.h> +#include <pulse/volume.h> +#include <pulse/channelmap.h> + +/** \file + * + * Routines for controlling module-stream-restore + */ + +PA_C_DECL_BEGIN + +/** Stores information about one entry in the stream database that is + * maintained by module-stream-restore. \since 0.9.12 */ +typedef struct pa_ext_stream_restore_info { + const char *name; /**< Identifier string of the stream. A string like "sink-input-by-role:" or similar followed by some arbitrary property value. */ + pa_channel_map channel_map; /**< The channel map for the volume field, if applicable */ + pa_cvolume volume; /**< The volume of the stream when it was seen last, if applicable and saved */ + const char *device; /**< The sink/source of the stream when it was last seen, if applicable and saved */ + int mute; /**< The boolean mute state of the stream when it was last seen, if applicable and saved */ +} pa_ext_stream_restore_info; + +/** Callback prototype for pa_ext_stream_restore_test(). \since 0.9.12 */ +typedef void (*pa_ext_stream_restore_test_cb_t)( + pa_context *c, + uint32_t version, + void *userdata); + +/** Test if this extension module is available in the server. \since 0.9.12 */ +pa_operation *pa_ext_stream_restore_test( + pa_context *c, + pa_ext_stream_restore_test_cb_t cb, + void *userdata); + +/** Callback prototype for pa_ext_stream_restore_read(). \since 0.9.12 */ +typedef void (*pa_ext_stream_restore_read_cb_t)( + pa_context *c, + const pa_ext_stream_restore_info *info, + int eol, + void *userdata); + +/** Read all entries from the stream database. \since 0.9.12 */ +pa_operation *pa_ext_stream_restore_read( + pa_context *c, + pa_ext_stream_restore_read_cb_t cb, + void *userdata); + +/** Store entries in the stream database. \since 0.9.12 */ +pa_operation *pa_ext_stream_restore_write( + pa_context *c, + pa_update_mode_t mode, + const pa_ext_stream_restore_info data[], + unsigned n, + int apply_immediately, + pa_context_success_cb_t cb, + void *userdata); + +/** Delete entries from the stream database. \since 0.9.12 */ +pa_operation *pa_ext_stream_restore_delete( + pa_context *c, + const char *const s[], + pa_context_success_cb_t cb, + void *userdata); + +/** Subscribe to changes in the stream database. \since 0.9.12 */ +pa_operation *pa_ext_stream_restore_subscribe( + pa_context *c, + int enable, + pa_context_success_cb_t cb, + void *userdata); + +/** Callback prototype for pa_ext_stream_restore_set_subscribe_cb(). \since 0.9.12 */ +typedef void (*pa_ext_stream_restore_subscribe_cb_t)( + pa_context *c, + void *userdata); + +/** Set the subscription callback that is called when + * pa_ext_stream_restore_subscribe() was called. \since 0.9.12 */ +void pa_ext_stream_restore_set_subscribe_cb( + pa_context *c, + pa_ext_stream_restore_subscribe_cb_t cb, + void *userdata); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/format.h b/thirdparty/linuxbsd_headers/pulse/format.h new file mode 100644 index 0000000000..f606b3b5f8 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/format.h @@ -0,0 +1,262 @@ +#ifndef fooformathfoo +#define fooformathfoo + +/*** + This file is part of PulseAudio. + + Copyright 2011 Intel Corporation + Copyright 2011 Collabora Multimedia + Copyright 2011 Arun Raghavan <arun.raghavan@collabora.co.uk> + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <pulse/cdecl.h> +#include <pulse/gccmacro.h> +#include <pulse/proplist.h> +#include <pulse/sample.h> +#include <pulse/channelmap.h> + +/** \file + * Utility functions for handling a stream or sink format. */ + +PA_C_DECL_BEGIN + +/** Represents the type of encoding used in a stream or accepted by a sink. \since 1.0 */ +typedef enum pa_encoding { + PA_ENCODING_ANY, + /**< Any encoding format, PCM or compressed */ + + PA_ENCODING_PCM, + /**< Any PCM format */ + + PA_ENCODING_AC3_IEC61937, + /**< AC3 data encapsulated in IEC 61937 header/padding */ + + PA_ENCODING_EAC3_IEC61937, + /**< EAC3 data encapsulated in IEC 61937 header/padding */ + + PA_ENCODING_MPEG_IEC61937, + /**< MPEG-1 or MPEG-2 (Part 3, not AAC) data encapsulated in IEC 61937 header/padding */ + + PA_ENCODING_DTS_IEC61937, + /**< DTS data encapsulated in IEC 61937 header/padding */ + + PA_ENCODING_MPEG2_AAC_IEC61937, + /**< MPEG-2 AAC data encapsulated in IEC 61937 header/padding. \since 4.0 */ + + PA_ENCODING_MAX, + /**< Valid encoding types must be less than this value */ + + PA_ENCODING_INVALID = -1, + /**< Represents an invalid encoding */ +} pa_encoding_t; + +/** \cond fulldocs */ +#define PA_ENCODING_ANY PA_ENCODING_ANY +#define PA_ENCODING_PCM PA_ENCODING_PCM +#define PA_ENCODING_AC3_IEC61937 PA_ENCODING_AC3_IEC61937 +#define PA_ENCODING_EAC3_IEC61937 PA_ENCODING_EAC3_IEC61937 +#define PA_ENCODING_MPEG_IEC61937 PA_ENCODING_MPEG_IEC61937 +#define PA_ENCODING_DTS_IEC61937 PA_ENCODING_DTS_IEC61937 +#define PA_ENCODING_MPEG2_AAC_IEC61937 PA_ENCODING_MPEG2_AAC_IEC61937 +#define PA_ENCODING_MAX PA_ENCODING_MAX +#define PA_ENCODING_INVALID PA_ENCODING_INVALID +/** \endcond */ + +/** Returns a printable string representing the given encoding type. \since 1.0 */ +const char *pa_encoding_to_string(pa_encoding_t e) PA_GCC_CONST; + +/** Converts a string of the form returned by \a pa_encoding_to_string() back to a \a pa_encoding_t. \since 1.0 */ +pa_encoding_t pa_encoding_from_string(const char *encoding); + +/** Represents the format of data provided in a stream or processed by a sink. \since 1.0 */ +typedef struct pa_format_info { + pa_encoding_t encoding; + /**< The encoding used for the format */ + + pa_proplist *plist; + /**< Additional encoding-specific properties such as sample rate, bitrate, etc. */ +} pa_format_info; + +/** Allocates a new \a pa_format_info structure. Clients must initialise at least the encoding field themselves. \since 1.0 */ +pa_format_info* pa_format_info_new(void); + +/** Returns a new \a pa_format_info struct and representing the same format as \a src. \since 1.0 */ +pa_format_info* pa_format_info_copy(const pa_format_info *src); + +/** Frees a \a pa_format_info structure. \since 1.0 */ +void pa_format_info_free(pa_format_info *f); + +/** Returns non-zero when the format info structure is valid. \since 1.0 */ +int pa_format_info_valid(const pa_format_info *f); + +/** Returns non-zero when the format info structure represents a PCM (i.e.\ uncompressed data) format. \since 1.0 */ +int pa_format_info_is_pcm(const pa_format_info *f); + +/** Returns non-zero if the format represented by \a first is a subset of + * the format represented by \a second. This means that \a second must + * have all the fields that \a first does, but the reverse need not + * be true. This is typically expected to be used to check if a + * stream's format is compatible with a given sink. In such a case, + * \a first would be the sink's format and \a second would be the + * stream's. \since 1.0 */ +int pa_format_info_is_compatible(const pa_format_info *first, const pa_format_info *second); + +/** Maximum required string length for + * pa_format_info_snprint(). Please note that this value can change + * with any release without warning and without being considered API + * or ABI breakage. You should not use this definition anywhere where + * it might become part of an ABI. \since 1.0 */ +#define PA_FORMAT_INFO_SNPRINT_MAX 256 + +/** Return a human-readable string representing the given format. \since 1.0 */ +char *pa_format_info_snprint(char *s, size_t l, const pa_format_info *f); + +/** Parse a human-readable string of the form generated by + * \a pa_format_info_snprint() into a pa_format_info structure. \since 1.0 */ +pa_format_info* pa_format_info_from_string(const char *str); + +/** Utility function to take a \a pa_sample_spec and generate the corresponding + * \a pa_format_info. + * + * Note that if you want the server to choose some of the stream parameters, + * for example the sample rate, so that they match the device parameters, then + * you shouldn't use this function. In order to allow the server to choose + * a parameter value, that parameter must be left unspecified in the + * pa_format_info object, and this function always specifies all parameters. An + * exception is the channel map: if you pass NULL for the channel map, then the + * channel map will be left unspecified, allowing the server to choose it. + * + * \since 2.0 */ +pa_format_info* pa_format_info_from_sample_spec(const pa_sample_spec *ss, const pa_channel_map *map); + +/** Utility function to generate a \a pa_sample_spec and \a pa_channel_map corresponding to a given \a pa_format_info. The + * conversion for PCM formats is straight-forward. For non-PCM formats, if there is a fixed size-time conversion (i.e. all + * IEC61937-encapsulated formats), a "fake" sample spec whose size-time conversion corresponds to this format is provided and + * the channel map argument is ignored. For formats with variable size-time conversion, this function will fail. Returns a + * negative integer if conversion failed and 0 on success. \since 2.0 */ +int pa_format_info_to_sample_spec(const pa_format_info *f, pa_sample_spec *ss, pa_channel_map *map); + +/** Represents the type of value type of a property on a \ref pa_format_info. \since 2.0 */ +typedef enum pa_prop_type_t { + PA_PROP_TYPE_INT, + /**< Integer property */ + + PA_PROP_TYPE_INT_RANGE, + /**< Integer range property */ + + PA_PROP_TYPE_INT_ARRAY, + /**< Integer array property */ + + PA_PROP_TYPE_STRING, + /**< String property */ + + PA_PROP_TYPE_STRING_ARRAY, + /**< String array property */ + + PA_PROP_TYPE_INVALID = -1, + /**< Represents an invalid type */ +} pa_prop_type_t; + +/** \cond fulldocs */ +#define PA_PROP_TYPE_INT PA_PROP_TYPE_INT +#define PA_PROP_TYPE_INT_RANGE PA_PROP_TYPE_INT_RANGE +#define PA_PROP_TYPE_INT_ARRAY PA_PROP_TYPE_INT_ARRAY +#define PA_PROP_TYPE_STRING PA_PROP_TYPE_STRING +#define PA_PROP_TYPE_STRING_ARRAY PA_PROP_TYPE_STRING_ARRAY +#define PA_PROP_TYPE_INVALID PA_PROP_TYPE_INVALID +/** \endcond */ + +/** Gets the type of property \a key in a given \ref pa_format_info. \since 2.0 */ +pa_prop_type_t pa_format_info_get_prop_type(const pa_format_info *f, const char *key); + +/** Gets an integer property from the given format info. Returns 0 on success and a negative integer on failure. \since 2.0 */ +int pa_format_info_get_prop_int(const pa_format_info *f, const char *key, int *v); +/** Gets an integer range property from the given format info. Returns 0 on success and a negative integer on failure. + * \since 2.0 */ +int pa_format_info_get_prop_int_range(const pa_format_info *f, const char *key, int *min, int *max); +/** Gets an integer array property from the given format info. \a values contains the values and \a n_values contains the + * number of elements. The caller must free \a values using \ref pa_xfree. Returns 0 on success and a negative integer on + * failure. \since 2.0 */ +int pa_format_info_get_prop_int_array(const pa_format_info *f, const char *key, int **values, int *n_values); +/** Gets a string property from the given format info. The caller must free the returned string using \ref pa_xfree. Returns + * 0 on success and a negative integer on failure. \since 2.0 */ +int pa_format_info_get_prop_string(const pa_format_info *f, const char *key, char **v); +/** Gets a string array property from the given format info. \a values contains the values and \a n_values contains + * the number of elements. The caller must free \a values using \ref pa_format_info_free_string_array. Returns 0 on success and + * a negative integer on failure. \since 2.0 */ +int pa_format_info_get_prop_string_array(const pa_format_info *f, const char *key, char ***values, int *n_values); + +/** Frees a string array returned by \ref pa_format_info_get_prop_string_array. \since 2.0 */ +void pa_format_info_free_string_array(char **values, int n_values); + +/** Sets an integer property on the given format info. \since 1.0 */ +void pa_format_info_set_prop_int(pa_format_info *f, const char *key, int value); +/** Sets a property with a list of integer values on the given format info. \since 1.0 */ +void pa_format_info_set_prop_int_array(pa_format_info *f, const char *key, const int *values, int n_values); +/** Sets a property which can have any value in a given integer range on the given format info. \since 1.0 */ +void pa_format_info_set_prop_int_range(pa_format_info *f, const char *key, int min, int max); +/** Sets a string property on the given format info. \since 1.0 */ +void pa_format_info_set_prop_string(pa_format_info *f, const char *key, const char *value); +/** Sets a property with a list of string values on the given format info. \since 1.0 */ +void pa_format_info_set_prop_string_array(pa_format_info *f, const char *key, const char **values, int n_values); + +/** Convenience method to set the sample format as a property on the given + * format. + * + * Note for PCM: If the sample format is left unspecified in the pa_format_info + * object, then the server will select the stream sample format. In that case + * the stream sample format will most likely match the device sample format, + * meaning that sample format conversion will be avoided. + * + * \since 1.0 */ +void pa_format_info_set_sample_format(pa_format_info *f, pa_sample_format_t sf); + +/** Convenience method to set the sampling rate as a property on the given + * format. + * + * Note for PCM: If the sample rate is left unspecified in the pa_format_info + * object, then the server will select the stream sample rate. In that case the + * stream sample rate will most likely match the device sample rate, meaning + * that sample rate conversion will be avoided. + * + * \since 1.0 */ +void pa_format_info_set_rate(pa_format_info *f, int rate); + +/** Convenience method to set the number of channels as a property on the given + * format. + * + * Note for PCM: If the channel count is left unspecified in the pa_format_info + * object, then the server will select the stream channel count. In that case + * the stream channel count will most likely match the device channel count, + * meaning that up/downmixing will be avoided. + * + * \since 1.0 */ +void pa_format_info_set_channels(pa_format_info *f, int channels); + +/** Convenience method to set the channel map as a property on the given + * format. + * + * Note for PCM: If the channel map is left unspecified in the pa_format_info + * object, then the server will select the stream channel map. In that case the + * stream channel map will most likely match the device channel map, meaning + * that remixing will be avoided. + * + * \since 1.0 */ +void pa_format_info_set_channel_map(pa_format_info *f, const pa_channel_map *map); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/gccmacro.h b/thirdparty/linuxbsd_headers/pulse/gccmacro.h new file mode 100644 index 0000000000..e5ba5bd8fc --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/gccmacro.h @@ -0,0 +1,132 @@ +#ifndef foopulsegccmacrohfoo +#define foopulsegccmacrohfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +/** \file + * GCC attribute macros */ + +#if defined(__GNUC__) +#ifdef __MINGW32__ +/* libintl overrides printf with a #define. As this breaks this attribute, + * it has a workaround. However the workaround isn't enabled for MINGW + * builds (only cygwin) */ +#define PA_GCC_PRINTF_ATTR(a,b) __attribute__ ((format (__printf__, a, b))) +#else +#define PA_GCC_PRINTF_ATTR(a,b) __attribute__ ((format (printf, a, b))) +#endif +#else +/** If we're in GNU C, use some magic for detecting invalid format strings */ +#define PA_GCC_PRINTF_ATTR(a,b) +#endif + +#if defined(__GNUC__) && (__GNUC__ >= 4) +#define PA_GCC_SENTINEL __attribute__ ((sentinel)) +#else +/** Macro for usage of GCC's sentinel compilation warnings */ +#define PA_GCC_SENTINEL +#endif + +#ifdef __GNUC__ +#define PA_GCC_NORETURN __attribute__((noreturn)) +#else +/** Macro for no-return functions */ +#define PA_GCC_NORETURN +#endif + +#ifdef __GNUC__ +#define PA_GCC_UNUSED __attribute__ ((unused)) +#else +/** Macro for not used function, variable or parameter */ +#define PA_GCC_UNUSED +#endif + +#ifdef __GNUC__ +#define PA_GCC_DESTRUCTOR __attribute__ ((destructor)) +#else +/** Call this function when process terminates */ +#define PA_GCC_DESTRUCTOR +#endif + +#ifndef PA_GCC_PURE +#ifdef __GNUC__ +#define PA_GCC_PURE __attribute__ ((pure)) +#else +/** This function's return value depends only the arguments list and global state **/ +#define PA_GCC_PURE +#endif +#endif + +#ifndef PA_GCC_CONST +#ifdef __GNUC__ +#define PA_GCC_CONST __attribute__ ((const)) +#else +/** This function's return value depends only the arguments list (stricter version of PA_GCC_PURE) **/ +#define PA_GCC_CONST +#endif +#endif + +#ifndef PA_GCC_DEPRECATED +#ifdef __GNUC__ +#define PA_GCC_DEPRECATED __attribute__ ((deprecated)) +#else +/** This function is deprecated **/ +#define PA_GCC_DEPRECATED +#endif +#endif + +#ifndef PA_GCC_PACKED +#ifdef __GNUC__ +#define PA_GCC_PACKED __attribute__ ((packed)) +#else +/** Structure shall be packed in memory **/ +#define PA_GCC_PACKED +#endif +#endif + +#ifndef PA_GCC_ALLOC_SIZE +#if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 3) +#define PA_GCC_ALLOC_SIZE(x) __attribute__ ((__alloc_size__(x))) +#define PA_GCC_ALLOC_SIZE2(x,y) __attribute__ ((__alloc_size__(x,y))) +#else +/** Macro for usage of GCC's alloc_size attribute */ +#define PA_GCC_ALLOC_SIZE(x) +/** Macro for usage of GCC's alloc_size attribute */ +#define PA_GCC_ALLOC_SIZE2(x,y) +#endif +#endif + +#ifndef PA_GCC_MALLOC +#ifdef __GNUC__ +#define PA_GCC_MALLOC __attribute__ ((malloc)) +#else +/** Macro for usage of GCC's malloc attribute */ +#define PA_GCC_MALLOC +#endif +#endif + +#ifndef PA_GCC_WEAKREF +#if defined(__GNUC__) && defined(__ELF__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ > 1)) || (__GNUC__ > 4)) +/** Macro for usage of GCC's weakref attribute */ +#define PA_GCC_WEAKREF(x) __attribute__((weakref(#x))) +#endif +#endif + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/glib-mainloop.h b/thirdparty/linuxbsd_headers/pulse/glib-mainloop.h new file mode 100644 index 0000000000..52d9a75f90 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/glib-mainloop.h @@ -0,0 +1,67 @@ +#ifndef fooglibmainloophfoo +#define fooglibmainloophfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <glib.h> + +#include <pulse/mainloop-api.h> +#include <pulse/cdecl.h> +#include <pulse/version.h> + +/** \page glib-mainloop GLIB Main Loop Bindings + * + * \section overv_sec Overview + * + * The GLIB main loop bindings are extremely easy to use. All that is + * required is to create a pa_glib_mainloop object using + * pa_glib_mainloop_new(). When the main loop abstraction is needed, it is + * provided by pa_glib_mainloop_get_api(). + * + */ + +/** \file + * GLIB main loop support + * + * See also \subpage glib-mainloop + */ + +PA_C_DECL_BEGIN + +/** An opaque GLIB main loop object */ +typedef struct pa_glib_mainloop pa_glib_mainloop; + +/** Create a new GLIB main loop object for the specified GLIB main + * loop context. Takes an argument c for the + * GMainContext to use. If c is NULL the default context is used. */ +pa_glib_mainloop *pa_glib_mainloop_new(GMainContext *c); + +/** Free the GLIB main loop object */ +void pa_glib_mainloop_free(pa_glib_mainloop* g); + +/** Return the abstract main loop API vtable for the GLIB main loop + object. No need to free the API as it is owned by the loop + and is destroyed when the loop is freed. */ +pa_mainloop_api* pa_glib_mainloop_get_api(pa_glib_mainloop *g); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/introspect.h b/thirdparty/linuxbsd_headers/pulse/introspect.h new file mode 100644 index 0000000000..43389b7364 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/introspect.h @@ -0,0 +1,760 @@ +#ifndef foointrospecthfoo +#define foointrospecthfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <inttypes.h> + +#include <pulse/operation.h> +#include <pulse/context.h> +#include <pulse/cdecl.h> +#include <pulse/gccmacro.h> +#include <pulse/channelmap.h> +#include <pulse/volume.h> +#include <pulse/proplist.h> +#include <pulse/format.h> +#include <pulse/version.h> + +/** \page introspect Server Query and Control + * + * \section overv_sec Overview + * + * Sometimes it is necessary to query and modify global settings in the + * server. For this, PulseAudio has the introspection API. It can list sinks, + * sources, samples and other aspects of the server. It can also modify the + * attributes of the server that will affect operations on a global level, + * and not just the application's context. + * + * \section query_sec Querying + * + * All querying is done through callbacks. This approach is necessary to + * maintain an asynchronous design. The client will request the information + * and some time later, the server will respond with the desired data. + * + * Some objects can have multiple instances on the server. When requesting all + * of these at once, the callback will be called multiple times, once for + * each object. When the list has been exhausted, the callback will be called + * without an information structure and the eol parameter set to a positive + * value. + * + * Note that even if a single object is requested, and not the entire list, + * the terminating call will still be made. + * + * If an error occurs, the callback will be invoked without an information + * structure and eol set to a negative value.. + * + * Data members in the information structures are only valid during the + * duration of the callback. If they are required after the callback is + * finished, a deep copy of the information structure must be performed. + * + * \subsection server_subsec Server Information + * + * The server can be queried about its name, the environment it's running on + * and the currently active global defaults. Calling + * pa_context_get_server_info() provides access to a pa_server_info structure + * containing all of these. + * + * \subsection memstat_subsec Memory Usage + * + * Statistics about memory usage can be fetched using pa_context_stat(), + * giving a pa_stat_info structure. + * + * \subsection sinksrc_subsec Sinks and Sources + * + * The server can have an arbitrary number of sinks and sources. Each sink + * and source have both an index and a name associated with it. As such, + * there are three ways to get access to them: + * + * \li By index - pa_context_get_sink_info_by_index() / + * pa_context_get_source_info_by_index() + * \li By name - pa_context_get_sink_info_by_name() / + * pa_context_get_source_info_by_name() + * \li All - pa_context_get_sink_info_list() / + * pa_context_get_source_info_list() + * + * All three method use the same callback and will provide a pa_sink_info or + * pa_source_info structure. + * + * \subsection siso_subsec Sink Inputs and Source Outputs + * + * Sink inputs and source outputs are the representations of the client ends + * of streams inside the server. I.e. they connect a client stream to one of + * the global sinks or sources. + * + * Sink inputs and source outputs only have an index to identify them. As + * such, there are only two ways to get information about them: + * + * \li By index - pa_context_get_sink_input_info() / + * pa_context_get_source_output_info() + * \li All - pa_context_get_sink_input_info_list() / + * pa_context_get_source_output_info_list() + * + * The structure returned is the pa_sink_input_info or pa_source_output_info + * structure. + * + * \subsection samples_subsec Samples + * + * The list of cached samples can be retrieved from the server. Three methods + * exist for querying the sample cache list: + * + * \li By index - pa_context_get_sample_info_by_index() + * \li By name - pa_context_get_sample_info_by_name() + * \li All - pa_context_get_sample_info_list() + * + * Note that this only retrieves information about the sample, not the sample + * data itself. + * + * \subsection module_subsec Driver Modules + * + * PulseAudio driver modules are identified by index and are retrieved using either + * pa_context_get_module_info() or pa_context_get_module_info_list(). The + * information structure is called pa_module_info. + * + * \subsection client_subsec Clients + * + * PulseAudio clients are also identified by index and are retrieved using + * either pa_context_get_client_info() or pa_context_get_client_info_list(). + * The information structure is called pa_client_info. + * + * \section ctrl_sec Control + * + * Some parts of the server are only possible to read, but most can also be + * modified in different ways. Note that these changes will affect all + * connected clients and not just the one issuing the request. + * + * \subsection sinksrc_subsec Sinks and Sources + * + * The most common change one would want to apply to sinks and sources is to + * modify the volume of the audio. Identically to how sinks and sources can + * be queried, there are two ways of identifying them: + * + * \li By index - pa_context_set_sink_volume_by_index() / + * pa_context_set_source_volume_by_index() + * \li By name - pa_context_set_sink_volume_by_name() / + * pa_context_set_source_volume_by_name() + * + * It is also possible to mute a sink or source: + * + * \li By index - pa_context_set_sink_mute_by_index() / + * pa_context_set_source_mute_by_index() + * \li By name - pa_context_set_sink_mute_by_name() / + * pa_context_set_source_mute_by_name() + * + * \subsection siso_subsec Sink Inputs and Source Outputs + * + * If an application desires to modify the volume of just a single stream + * (commonly one of its own streams), this can be done by setting the volume + * of its associated sink input or source output, using + * pa_context_set_sink_input_volume() or pa_context_set_source_output_volume(). + * + * It is also possible to remove sink inputs and source outputs, terminating + * the streams associated with them: + * + * \li Sink input - pa_context_kill_sink_input() + * \li Source output - pa_context_kill_source_output() + * + * It is strongly recommended that all volume changes are done as a direct + * result of user input. With automated requests, such as those resulting + * from misguided attempts of crossfading, PulseAudio can store the stream + * volume at an inappropriate moment and restore it later. Besides, such + * attempts lead to OSD popups in some desktop environments. + * + * As a special case of the general rule above, it is recommended that your + * application leaves the task of saving and restoring the volume of its + * streams to PulseAudio and does not attempt to do it by itself. PulseAudio + * really knows better about events such as stream moving or headphone + * plugging that would make the volume stored by the application inapplicable + * to the new configuration. + * + * Another important case where setting a sink input volume may be a bad idea + * is related to interpreters that interpret potentially untrusted scripts. + * PulseAudio relies on your application not making malicious requests (such + * as repeatedly setting the volume to 100%). Thus, script interpreters that + * represent a security boundary must sandbox volume-changing requests coming + * from their scripts. In the worst case, it may be necessary to apply the + * script-requested volume to the script-produced sounds by altering the + * samples in the script interpreter and not touching the sink or sink input + * volume as seen by PulseAudio. + * + * If an application changes any volume, it should also listen to changes of + * the same volume originating from outside the application (e.g., from the + * system mixer application) and update its user interface accordingly. Use + * \ref subscribe to get such notifications. + * + * \subsection module_subsec Modules + * + * Server modules can be remotely loaded and unloaded using + * pa_context_load_module() and pa_context_unload_module(). + * + * \subsection client_subsec Clients + * + * The only operation supported on clients is the possibility of kicking + * them off the server using pa_context_kill_client(). + */ + +/** \file + * + * Routines for daemon introspection. + * + * See also \subpage introspect + */ + +PA_C_DECL_BEGIN + +/** @{ \name Sinks */ + +/** Stores information about a specific port of a sink. Please + * note that this structure can be extended as part of evolutionary + * API updates at any time in any new release. \since 0.9.16 */ +typedef struct pa_sink_port_info { + const char *name; /**< Name of this port */ + const char *description; /**< Description of this port */ + uint32_t priority; /**< The higher this value is, the more useful this port is as a default. */ + int available; /**< A flags (see #pa_port_available), indicating availability status of this port. \since 2.0 */ +} pa_sink_port_info; + +/** Stores information about sinks. Please note that this structure + * can be extended as part of evolutionary API updates at any time in + * any new release. */ +typedef struct pa_sink_info { + const char *name; /**< Name of the sink */ + uint32_t index; /**< Index of the sink */ + const char *description; /**< Description of this sink */ + pa_sample_spec sample_spec; /**< Sample spec of this sink */ + pa_channel_map channel_map; /**< Channel map */ + uint32_t owner_module; /**< Index of the owning module of this sink, or PA_INVALID_INDEX. */ + pa_cvolume volume; /**< Volume of the sink */ + int mute; /**< Mute switch of the sink */ + uint32_t monitor_source; /**< Index of the monitor source connected to this sink. */ + const char *monitor_source_name; /**< The name of the monitor source. */ + pa_usec_t latency; /**< Length of queued audio in the output buffer. */ + const char *driver; /**< Driver name */ + pa_sink_flags_t flags; /**< Flags */ + pa_proplist *proplist; /**< Property list \since 0.9.11 */ + pa_usec_t configured_latency; /**< The latency this device has been configured to. \since 0.9.11 */ + pa_volume_t base_volume; /**< Some kind of "base" volume that refers to unamplified/unattenuated volume in the context of the output device. \since 0.9.15 */ + pa_sink_state_t state; /**< State \since 0.9.15 */ + uint32_t n_volume_steps; /**< Number of volume steps for sinks which do not support arbitrary volumes. \since 0.9.15 */ + uint32_t card; /**< Card index, or PA_INVALID_INDEX. \since 0.9.15 */ + uint32_t n_ports; /**< Number of entries in port array \since 0.9.16 */ + pa_sink_port_info** ports; /**< Array of available ports, or NULL. Array is terminated by an entry set to NULL. The number of entries is stored in n_ports. \since 0.9.16 */ + pa_sink_port_info* active_port; /**< Pointer to active port in the array, or NULL. \since 0.9.16 */ + uint8_t n_formats; /**< Number of formats supported by the sink. \since 1.0 */ + pa_format_info **formats; /**< Array of formats supported by the sink. \since 1.0 */ +} pa_sink_info; + +/** Callback prototype for pa_context_get_sink_info_by_name() and friends */ +typedef void (*pa_sink_info_cb_t)(pa_context *c, const pa_sink_info *i, int eol, void *userdata); + +/** Get information about a sink by its name */ +pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name, pa_sink_info_cb_t cb, void *userdata); + +/** Get information about a sink by its index */ +pa_operation* pa_context_get_sink_info_by_index(pa_context *c, uint32_t idx, pa_sink_info_cb_t cb, void *userdata); + +/** Get the complete sink list */ +pa_operation* pa_context_get_sink_info_list(pa_context *c, pa_sink_info_cb_t cb, void *userdata); + +/** Set the volume of a sink device specified by its index */ +pa_operation* pa_context_set_sink_volume_by_index(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata); + +/** Set the volume of a sink device specified by its name */ +pa_operation* pa_context_set_sink_volume_by_name(pa_context *c, const char *name, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata); + +/** Set the mute switch of a sink device specified by its index */ +pa_operation* pa_context_set_sink_mute_by_index(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata); + +/** Set the mute switch of a sink device specified by its name */ +pa_operation* pa_context_set_sink_mute_by_name(pa_context *c, const char *name, int mute, pa_context_success_cb_t cb, void *userdata); + +/** Suspend/Resume a sink. \since 0.9.7 */ +pa_operation* pa_context_suspend_sink_by_name(pa_context *c, const char *sink_name, int suspend, pa_context_success_cb_t cb, void* userdata); + +/** Suspend/Resume a sink. If idx is PA_INVALID_INDEX all sinks will be suspended. \since 0.9.7 */ +pa_operation* pa_context_suspend_sink_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata); + +/** Change the profile of a sink. \since 0.9.16 */ +pa_operation* pa_context_set_sink_port_by_index(pa_context *c, uint32_t idx, const char*port, pa_context_success_cb_t cb, void *userdata); + +/** Change the profile of a sink. \since 0.9.15 */ +pa_operation* pa_context_set_sink_port_by_name(pa_context *c, const char*name, const char*port, pa_context_success_cb_t cb, void *userdata); + +/** @} */ + +/** @{ \name Sources */ + +/** Stores information about a specific port of a source. Please + * note that this structure can be extended as part of evolutionary + * API updates at any time in any new release. \since 0.9.16 */ +typedef struct pa_source_port_info { + const char *name; /**< Name of this port */ + const char *description; /**< Description of this port */ + uint32_t priority; /**< The higher this value is, the more useful this port is as a default. */ + int available; /**< A flags (see #pa_port_available), indicating availability status of this port. \since 2.0 */ +} pa_source_port_info; + +/** Stores information about sources. Please note that this structure + * can be extended as part of evolutionary API updates at any time in + * any new release. */ +typedef struct pa_source_info { + const char *name; /**< Name of the source */ + uint32_t index; /**< Index of the source */ + const char *description; /**< Description of this source */ + pa_sample_spec sample_spec; /**< Sample spec of this source */ + pa_channel_map channel_map; /**< Channel map */ + uint32_t owner_module; /**< Owning module index, or PA_INVALID_INDEX. */ + pa_cvolume volume; /**< Volume of the source */ + int mute; /**< Mute switch of the sink */ + uint32_t monitor_of_sink; /**< If this is a monitor source, the index of the owning sink, otherwise PA_INVALID_INDEX. */ + const char *monitor_of_sink_name; /**< Name of the owning sink, or NULL. */ + pa_usec_t latency; /**< Length of filled record buffer of this source. */ + const char *driver; /**< Driver name */ + pa_source_flags_t flags; /**< Flags */ + pa_proplist *proplist; /**< Property list \since 0.9.11 */ + pa_usec_t configured_latency; /**< The latency this device has been configured to. \since 0.9.11 */ + pa_volume_t base_volume; /**< Some kind of "base" volume that refers to unamplified/unattenuated volume in the context of the input device. \since 0.9.15 */ + pa_source_state_t state; /**< State \since 0.9.15 */ + uint32_t n_volume_steps; /**< Number of volume steps for sources which do not support arbitrary volumes. \since 0.9.15 */ + uint32_t card; /**< Card index, or PA_INVALID_INDEX. \since 0.9.15 */ + uint32_t n_ports; /**< Number of entries in port array \since 0.9.16 */ + pa_source_port_info** ports; /**< Array of available ports, or NULL. Array is terminated by an entry set to NULL. The number of entries is stored in n_ports. \since 0.9.16 */ + pa_source_port_info* active_port; /**< Pointer to active port in the array, or NULL. \since 0.9.16 */ + uint8_t n_formats; /**< Number of formats supported by the source. \since 1.0 */ + pa_format_info **formats; /**< Array of formats supported by the source. \since 1.0 */ +} pa_source_info; + +/** Callback prototype for pa_context_get_source_info_by_name() and friends */ +typedef void (*pa_source_info_cb_t)(pa_context *c, const pa_source_info *i, int eol, void *userdata); + +/** Get information about a source by its name */ +pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name, pa_source_info_cb_t cb, void *userdata); + +/** Get information about a source by its index */ +pa_operation* pa_context_get_source_info_by_index(pa_context *c, uint32_t idx, pa_source_info_cb_t cb, void *userdata); + +/** Get the complete source list */ +pa_operation* pa_context_get_source_info_list(pa_context *c, pa_source_info_cb_t cb, void *userdata); + +/** Set the volume of a source device specified by its index */ +pa_operation* pa_context_set_source_volume_by_index(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata); + +/** Set the volume of a source device specified by its name */ +pa_operation* pa_context_set_source_volume_by_name(pa_context *c, const char *name, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata); + +/** Set the mute switch of a source device specified by its index */ +pa_operation* pa_context_set_source_mute_by_index(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata); + +/** Set the mute switch of a source device specified by its name */ +pa_operation* pa_context_set_source_mute_by_name(pa_context *c, const char *name, int mute, pa_context_success_cb_t cb, void *userdata); + +/** Suspend/Resume a source. \since 0.9.7 */ +pa_operation* pa_context_suspend_source_by_name(pa_context *c, const char *source_name, int suspend, pa_context_success_cb_t cb, void* userdata); + +/** Suspend/Resume a source. If idx is PA_INVALID_INDEX, all sources will be suspended. \since 0.9.7 */ +pa_operation* pa_context_suspend_source_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata); + +/** Change the profile of a source. \since 0.9.16 */ +pa_operation* pa_context_set_source_port_by_index(pa_context *c, uint32_t idx, const char*port, pa_context_success_cb_t cb, void *userdata); + +/** Change the profile of a source. \since 0.9.15 */ +pa_operation* pa_context_set_source_port_by_name(pa_context *c, const char*name, const char*port, pa_context_success_cb_t cb, void *userdata); + +/** @} */ + +/** @{ \name Server */ + +/** Server information. Please note that this structure can be + * extended as part of evolutionary API updates at any time in any new + * release. */ +typedef struct pa_server_info { + const char *user_name; /**< User name of the daemon process */ + const char *host_name; /**< Host name the daemon is running on */ + const char *server_version; /**< Version string of the daemon */ + const char *server_name; /**< Server package name (usually "pulseaudio") */ + pa_sample_spec sample_spec; /**< Default sample specification */ + const char *default_sink_name; /**< Name of default sink. */ + const char *default_source_name; /**< Name of default source. */ + uint32_t cookie; /**< A random cookie for identifying this instance of PulseAudio. */ + pa_channel_map channel_map; /**< Default channel map. \since 0.9.15 */ +} pa_server_info; + +/** Callback prototype for pa_context_get_server_info() */ +typedef void (*pa_server_info_cb_t) (pa_context *c, const pa_server_info*i, void *userdata); + +/** Get some information about the server */ +pa_operation* pa_context_get_server_info(pa_context *c, pa_server_info_cb_t cb, void *userdata); + +/** @} */ + +/** @{ \name Modules */ + +/** Stores information about modules. Please note that this structure + * can be extended as part of evolutionary API updates at any time in + * any new release. */ +typedef struct pa_module_info { + uint32_t index; /**< Index of the module */ + const char*name, /**< Name of the module */ + *argument; /**< Argument string of the module */ + uint32_t n_used; /**< Usage counter or PA_INVALID_INDEX */ +/** \cond fulldocs */ + int auto_unload; /**< \deprecated Non-zero if this is an autoloaded module. */ +/** \endcond */ + pa_proplist *proplist; /**< Property list \since 0.9.15 */ +} pa_module_info; + +/** Callback prototype for pa_context_get_module_info() and friends */ +typedef void (*pa_module_info_cb_t) (pa_context *c, const pa_module_info*i, int eol, void *userdata); + +/** Get some information about a module by its index */ +pa_operation* pa_context_get_module_info(pa_context *c, uint32_t idx, pa_module_info_cb_t cb, void *userdata); + +/** Get the complete list of currently loaded modules */ +pa_operation* pa_context_get_module_info_list(pa_context *c, pa_module_info_cb_t cb, void *userdata); + +/** Callback prototype for pa_context_load_module() */ +typedef void (*pa_context_index_cb_t)(pa_context *c, uint32_t idx, void *userdata); + +/** Load a module. */ +pa_operation* pa_context_load_module(pa_context *c, const char*name, const char *argument, pa_context_index_cb_t cb, void *userdata); + +/** Unload a module. */ +pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata); + +/** @} */ + +/** @{ \name Clients */ + +/** Stores information about clients. Please note that this structure + * can be extended as part of evolutionary API updates at any time in + * any new release. */ +typedef struct pa_client_info { + uint32_t index; /**< Index of this client */ + const char *name; /**< Name of this client */ + uint32_t owner_module; /**< Index of the owning module, or PA_INVALID_INDEX. */ + const char *driver; /**< Driver name */ + pa_proplist *proplist; /**< Property list \since 0.9.11 */ +} pa_client_info; + +/** Callback prototype for pa_context_get_client_info() and friends */ +typedef void (*pa_client_info_cb_t) (pa_context *c, const pa_client_info*i, int eol, void *userdata); + +/** Get information about a client by its index */ +pa_operation* pa_context_get_client_info(pa_context *c, uint32_t idx, pa_client_info_cb_t cb, void *userdata); + +/** Get the complete client list */ +pa_operation* pa_context_get_client_info_list(pa_context *c, pa_client_info_cb_t cb, void *userdata); + +/** Kill a client. */ +pa_operation* pa_context_kill_client(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata); + +/** @} */ + +/** @{ \name Cards */ + +/** \deprecated Superseded by pa_card_profile_info2 \since 0.9.15 */ +typedef struct pa_card_profile_info { + const char *name; /**< Name of this profile */ + const char *description; /**< Description of this profile */ + uint32_t n_sinks; /**< Number of sinks this profile would create */ + uint32_t n_sources; /**< Number of sources this profile would create */ + uint32_t priority; /**< The higher this value is, the more useful this profile is as a default. */ +} pa_card_profile_info; + +/** Stores information about a specific profile of a card. Please + * note that this structure can be extended as part of evolutionary + * API updates at any time in any new release. \since 5.0 */ +typedef struct pa_card_profile_info2 { + const char *name; /**< Name of this profile */ + const char *description; /**< Description of this profile */ + uint32_t n_sinks; /**< Number of sinks this profile would create */ + uint32_t n_sources; /**< Number of sources this profile would create */ + uint32_t priority; /**< The higher this value is, the more useful this profile is as a default. */ + int available; + /**< Is this profile available? If this is zero, meaning "unavailable", + * then it makes no sense to try to activate this profile. If this is + * non-zero, it's still not a guarantee that activating the profile will + * result in anything useful, it just means that the server isn't aware of + * any reason why the profile would definitely be useless. \since 5.0 */ +} pa_card_profile_info2; + +/** Stores information about a specific port of a card. Please + * note that this structure can be extended as part of evolutionary + * API updates at any time in any new release. \since 2.0 */ +typedef struct pa_card_port_info { + const char *name; /**< Name of this port */ + const char *description; /**< Description of this port */ + uint32_t priority; /**< The higher this value is, the more useful this port is as a default. */ + int available; /**< A #pa_port_available enum, indicating availability status of this port. */ + int direction; /**< A #pa_direction enum, indicating the direction of this port. */ + uint32_t n_profiles; /**< Number of entries in profile array */ + pa_card_profile_info** profiles; /**< \deprecated Superseded by profiles2 */ + pa_proplist *proplist; /**< Property list */ + int64_t latency_offset; /**< Latency offset of the port that gets added to the sink/source latency when the port is active. \since 3.0 */ + pa_card_profile_info2** profiles2; /**< Array of pointers to available profiles, or NULL. Array is terminated by an entry set to NULL. \since 5.0 */ +} pa_card_port_info; + +/** Stores information about cards. Please note that this structure + * can be extended as part of evolutionary API updates at any time in + * any new release. \since 0.9.15 */ +typedef struct pa_card_info { + uint32_t index; /**< Index of this card */ + const char *name; /**< Name of this card */ + uint32_t owner_module; /**< Index of the owning module, or PA_INVALID_INDEX. */ + const char *driver; /**< Driver name */ + uint32_t n_profiles; /**< Number of entries in profile array */ + pa_card_profile_info* profiles; /**< \deprecated Superseded by profiles2 */ + pa_card_profile_info* active_profile; /**< \deprecated Superseded by active_profile2 */ + pa_proplist *proplist; /**< Property list */ + uint32_t n_ports; /**< Number of entries in port array */ + pa_card_port_info **ports; /**< Array of pointers to ports, or NULL. Array is terminated by an entry set to NULL. */ + pa_card_profile_info2** profiles2; /**< Array of pointers to available profiles, or NULL. Array is terminated by an entry set to NULL. \since 5.0 */ + pa_card_profile_info2* active_profile2; /**< Pointer to active profile in the array, or NULL. \since 5.0 */ +} pa_card_info; + +/** Callback prototype for pa_context_get_card_info_...() \since 0.9.15 */ +typedef void (*pa_card_info_cb_t) (pa_context *c, const pa_card_info*i, int eol, void *userdata); + +/** Get information about a card by its index \since 0.9.15 */ +pa_operation* pa_context_get_card_info_by_index(pa_context *c, uint32_t idx, pa_card_info_cb_t cb, void *userdata); + +/** Get information about a card by its name \since 0.9.15 */ +pa_operation* pa_context_get_card_info_by_name(pa_context *c, const char *name, pa_card_info_cb_t cb, void *userdata); + +/** Get the complete card list \since 0.9.15 */ +pa_operation* pa_context_get_card_info_list(pa_context *c, pa_card_info_cb_t cb, void *userdata); + +/** Change the profile of a card. \since 0.9.15 */ +pa_operation* pa_context_set_card_profile_by_index(pa_context *c, uint32_t idx, const char*profile, pa_context_success_cb_t cb, void *userdata); + +/** Change the profile of a card. \since 0.9.15 */ +pa_operation* pa_context_set_card_profile_by_name(pa_context *c, const char*name, const char*profile, pa_context_success_cb_t cb, void *userdata); + +/** Set the latency offset of a port. \since 3.0 */ +pa_operation* pa_context_set_port_latency_offset(pa_context *c, const char *card_name, const char *port_name, int64_t offset, pa_context_success_cb_t cb, void *userdata); + +/** @} */ + +/** @{ \name Sink Inputs */ + +/** Stores information about sink inputs. Please note that this structure + * can be extended as part of evolutionary API updates at any time in + * any new release. */ +typedef struct pa_sink_input_info { + uint32_t index; /**< Index of the sink input */ + const char *name; /**< Name of the sink input */ + uint32_t owner_module; /**< Index of the module this sink input belongs to, or PA_INVALID_INDEX when it does not belong to any module. */ + uint32_t client; /**< Index of the client this sink input belongs to, or PA_INVALID_INDEX when it does not belong to any client. */ + uint32_t sink; /**< Index of the connected sink */ + pa_sample_spec sample_spec; /**< The sample specification of the sink input. */ + pa_channel_map channel_map; /**< Channel map */ + pa_cvolume volume; /**< The volume of this sink input. */ + pa_usec_t buffer_usec; /**< Latency due to buffering in sink input, see pa_timing_info for details. */ + pa_usec_t sink_usec; /**< Latency of the sink device, see pa_timing_info for details. */ + const char *resample_method; /**< The resampling method used by this sink input. */ + const char *driver; /**< Driver name */ + int mute; /**< Stream muted \since 0.9.7 */ + pa_proplist *proplist; /**< Property list \since 0.9.11 */ + int corked; /**< Stream corked \since 1.0 */ + int has_volume; /**< Stream has volume. If not set, then the meaning of this struct's volume member is unspecified. \since 1.0 */ + int volume_writable; /**< The volume can be set. If not set, the volume can still change even though clients can't control the volume. \since 1.0 */ + pa_format_info *format; /**< Stream format information. \since 1.0 */ +} pa_sink_input_info; + +/** Callback prototype for pa_context_get_sink_input_info() and friends */ +typedef void (*pa_sink_input_info_cb_t) (pa_context *c, const pa_sink_input_info *i, int eol, void *userdata); + +/** Get some information about a sink input by its index */ +pa_operation* pa_context_get_sink_input_info(pa_context *c, uint32_t idx, pa_sink_input_info_cb_t cb, void *userdata); + +/** Get the complete sink input list */ +pa_operation* pa_context_get_sink_input_info_list(pa_context *c, pa_sink_input_info_cb_t cb, void *userdata); + +/** Move the specified sink input to a different sink. \since 0.9.5 */ +pa_operation* pa_context_move_sink_input_by_name(pa_context *c, uint32_t idx, const char *sink_name, pa_context_success_cb_t cb, void* userdata); + +/** Move the specified sink input to a different sink. \since 0.9.5 */ +pa_operation* pa_context_move_sink_input_by_index(pa_context *c, uint32_t idx, uint32_t sink_idx, pa_context_success_cb_t cb, void* userdata); + +/** Set the volume of a sink input stream */ +pa_operation* pa_context_set_sink_input_volume(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata); + +/** Set the mute switch of a sink input stream \since 0.9.7 */ +pa_operation* pa_context_set_sink_input_mute(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata); + +/** Kill a sink input. */ +pa_operation* pa_context_kill_sink_input(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata); + +/** @} */ + +/** @{ \name Source Outputs */ + +/** Stores information about source outputs. Please note that this structure + * can be extended as part of evolutionary API updates at any time in + * any new release. */ +typedef struct pa_source_output_info { + uint32_t index; /**< Index of the source output */ + const char *name; /**< Name of the source output */ + uint32_t owner_module; /**< Index of the module this source output belongs to, or PA_INVALID_INDEX when it does not belong to any module. */ + uint32_t client; /**< Index of the client this source output belongs to, or PA_INVALID_INDEX when it does not belong to any client. */ + uint32_t source; /**< Index of the connected source */ + pa_sample_spec sample_spec; /**< The sample specification of the source output */ + pa_channel_map channel_map; /**< Channel map */ + pa_usec_t buffer_usec; /**< Latency due to buffering in the source output, see pa_timing_info for details. */ + pa_usec_t source_usec; /**< Latency of the source device, see pa_timing_info for details. */ + const char *resample_method; /**< The resampling method used by this source output. */ + const char *driver; /**< Driver name */ + pa_proplist *proplist; /**< Property list \since 0.9.11 */ + int corked; /**< Stream corked \since 1.0 */ + pa_cvolume volume; /**< The volume of this source output \since 1.0 */ + int mute; /**< Stream muted \since 1.0 */ + int has_volume; /**< Stream has volume. If not set, then the meaning of this struct's volume member is unspecified. \since 1.0 */ + int volume_writable; /**< The volume can be set. If not set, the volume can still change even though clients can't control the volume. \since 1.0 */ + pa_format_info *format; /**< Stream format information. \since 1.0 */ +} pa_source_output_info; + +/** Callback prototype for pa_context_get_source_output_info() and friends */ +typedef void (*pa_source_output_info_cb_t) (pa_context *c, const pa_source_output_info *i, int eol, void *userdata); + +/** Get information about a source output by its index */ +pa_operation* pa_context_get_source_output_info(pa_context *c, uint32_t idx, pa_source_output_info_cb_t cb, void *userdata); + +/** Get the complete list of source outputs */ +pa_operation* pa_context_get_source_output_info_list(pa_context *c, pa_source_output_info_cb_t cb, void *userdata); + +/** Move the specified source output to a different source. \since 0.9.5 */ +pa_operation* pa_context_move_source_output_by_name(pa_context *c, uint32_t idx, const char *source_name, pa_context_success_cb_t cb, void* userdata); + +/** Move the specified source output to a different source. \since 0.9.5 */ +pa_operation* pa_context_move_source_output_by_index(pa_context *c, uint32_t idx, uint32_t source_idx, pa_context_success_cb_t cb, void* userdata); + +/** Set the volume of a source output stream \since 1.0 */ +pa_operation* pa_context_set_source_output_volume(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata); + +/** Set the mute switch of a source output stream \since 1.0 */ +pa_operation* pa_context_set_source_output_mute(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata); + +/** Kill a source output. */ +pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata); + +/** @} */ + +/** @{ \name Statistics */ + +/** Memory block statistics. Please note that this structure + * can be extended as part of evolutionary API updates at any time in + * any new release. */ +typedef struct pa_stat_info { + uint32_t memblock_total; /**< Currently allocated memory blocks */ + uint32_t memblock_total_size; /**< Current total size of allocated memory blocks */ + uint32_t memblock_allocated; /**< Allocated memory blocks during the whole lifetime of the daemon. */ + uint32_t memblock_allocated_size; /**< Total size of all memory blocks allocated during the whole lifetime of the daemon. */ + uint32_t scache_size; /**< Total size of all sample cache entries. */ +} pa_stat_info; + +/** Callback prototype for pa_context_stat() */ +typedef void (*pa_stat_info_cb_t) (pa_context *c, const pa_stat_info *i, void *userdata); + +/** Get daemon memory block statistics */ +pa_operation* pa_context_stat(pa_context *c, pa_stat_info_cb_t cb, void *userdata); + +/** @} */ + +/** @{ \name Cached Samples */ + +/** Stores information about sample cache entries. Please note that this structure + * can be extended as part of evolutionary API updates at any time in + * any new release. */ +typedef struct pa_sample_info { + uint32_t index; /**< Index of this entry */ + const char *name; /**< Name of this entry */ + pa_cvolume volume; /**< Default volume of this entry */ + pa_sample_spec sample_spec; /**< Sample specification of the sample */ + pa_channel_map channel_map; /**< The channel map */ + pa_usec_t duration; /**< Duration of this entry */ + uint32_t bytes; /**< Length of this sample in bytes. */ + int lazy; /**< Non-zero when this is a lazy cache entry. */ + const char *filename; /**< In case this is a lazy cache entry, the filename for the sound file to be loaded on demand. */ + pa_proplist *proplist; /**< Property list for this sample. \since 0.9.11 */ +} pa_sample_info; + +/** Callback prototype for pa_context_get_sample_info_by_name() and friends */ +typedef void (*pa_sample_info_cb_t)(pa_context *c, const pa_sample_info *i, int eol, void *userdata); + +/** Get information about a sample by its name */ +pa_operation* pa_context_get_sample_info_by_name(pa_context *c, const char *name, pa_sample_info_cb_t cb, void *userdata); + +/** Get information about a sample by its index */ +pa_operation* pa_context_get_sample_info_by_index(pa_context *c, uint32_t idx, pa_sample_info_cb_t cb, void *userdata); + +/** Get the complete list of samples stored in the daemon. */ +pa_operation* pa_context_get_sample_info_list(pa_context *c, pa_sample_info_cb_t cb, void *userdata); + +/** @} */ + +/** \cond fulldocs */ + +/** @{ \name Autoload Entries */ + +/** \deprecated Type of an autoload entry. */ +typedef enum pa_autoload_type { + PA_AUTOLOAD_SINK = 0, + PA_AUTOLOAD_SOURCE = 1 +} pa_autoload_type_t; + +/** \deprecated Stores information about autoload entries. Please note that this structure + * can be extended as part of evolutionary API updates at any time in + * any new release. */ +typedef struct pa_autoload_info { + uint32_t index; /**< Index of this autoload entry */ + const char *name; /**< Name of the sink or source */ + pa_autoload_type_t type; /**< Type of the autoload entry */ + const char *module; /**< Module name to load */ + const char *argument; /**< Argument string for module */ +} pa_autoload_info; + +/** \deprecated Callback prototype for pa_context_get_autoload_info_by_name() and friends */ +typedef void (*pa_autoload_info_cb_t)(pa_context *c, const pa_autoload_info *i, int eol, void *userdata); + +/** \deprecated Get info about a specific autoload entry. */ +pa_operation* pa_context_get_autoload_info_by_name(pa_context *c, const char *name, pa_autoload_type_t type, pa_autoload_info_cb_t cb, void *userdata) PA_GCC_DEPRECATED; + +/** \deprecated Get info about a specific autoload entry. */ +pa_operation* pa_context_get_autoload_info_by_index(pa_context *c, uint32_t idx, pa_autoload_info_cb_t cb, void *userdata) PA_GCC_DEPRECATED; + +/** \deprecated Get the complete list of autoload entries. */ +pa_operation* pa_context_get_autoload_info_list(pa_context *c, pa_autoload_info_cb_t cb, void *userdata) PA_GCC_DEPRECATED; + +/** \deprecated Add a new autoload entry. */ +pa_operation* pa_context_add_autoload(pa_context *c, const char *name, pa_autoload_type_t type, const char *module, const char*argument, pa_context_index_cb_t, void* userdata) PA_GCC_DEPRECATED; + +/** \deprecated Remove an autoload entry. */ +pa_operation* pa_context_remove_autoload_by_name(pa_context *c, const char *name, pa_autoload_type_t type, pa_context_success_cb_t cb, void* userdata) PA_GCC_DEPRECATED; + +/** \deprecated Remove an autoload entry. */ +pa_operation* pa_context_remove_autoload_by_index(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void* userdata) PA_GCC_DEPRECATED; + +/** @} */ + +/** \endcond */ + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/mainloop-api.h b/thirdparty/linuxbsd_headers/pulse/mainloop-api.h new file mode 100644 index 0000000000..4d847313a4 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/mainloop-api.h @@ -0,0 +1,124 @@ +#ifndef foomainloopapihfoo +#define foomainloopapihfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <sys/time.h> + +#include <pulse/cdecl.h> +#include <pulse/version.h> + +/** \file + * + * Main loop abstraction layer. Both the PulseAudio core and the + * PulseAudio client library use a main loop abstraction layer. Due to + * this it is possible to embed PulseAudio into other + * applications easily. Two main loop implementations are + * currently available: + * \li A minimal implementation based on the C library's poll() function (See \ref mainloop.h) + * \li A wrapper around the GLIB main loop. Use this to embed PulseAudio into your GLIB/GTK+/GNOME programs (See \ref glib-mainloop.h) + * + * The structure pa_mainloop_api is used as vtable for the main loop abstraction. + * + * This mainloop abstraction layer has no direct support for UNIX signals. Generic, mainloop implementation agnostic support is available through \ref mainloop-signal.h. + * */ + +PA_C_DECL_BEGIN + +/** An abstract mainloop API vtable */ +typedef struct pa_mainloop_api pa_mainloop_api; + +/** A bitmask for IO events */ +typedef enum pa_io_event_flags { + PA_IO_EVENT_NULL = 0, /**< No event */ + PA_IO_EVENT_INPUT = 1, /**< Input event */ + PA_IO_EVENT_OUTPUT = 2, /**< Output event */ + PA_IO_EVENT_HANGUP = 4, /**< Hangup event */ + PA_IO_EVENT_ERROR = 8 /**< Error event */ +} pa_io_event_flags_t; + +/** An opaque IO event source object */ +typedef struct pa_io_event pa_io_event; +/** An IO event callback prototype \since 0.9.3 */ +typedef void (*pa_io_event_cb_t)(pa_mainloop_api*ea, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata); +/** A IO event destroy callback prototype \since 0.9.3 */ +typedef void (*pa_io_event_destroy_cb_t)(pa_mainloop_api*a, pa_io_event *e, void *userdata); + +/** An opaque timer event source object */ +typedef struct pa_time_event pa_time_event; +/** A time event callback prototype \since 0.9.3 */ +typedef void (*pa_time_event_cb_t)(pa_mainloop_api*a, pa_time_event* e, const struct timeval *tv, void *userdata); +/** A time event destroy callback prototype \since 0.9.3 */ +typedef void (*pa_time_event_destroy_cb_t)(pa_mainloop_api*a, pa_time_event *e, void *userdata); + +/** An opaque deferred event source object. Events of this type are triggered once in every main loop iteration */ +typedef struct pa_defer_event pa_defer_event; +/** A defer event callback prototype \since 0.9.3 */ +typedef void (*pa_defer_event_cb_t)(pa_mainloop_api*a, pa_defer_event* e, void *userdata); +/** A defer event destroy callback prototype \since 0.9.3 */ +typedef void (*pa_defer_event_destroy_cb_t)(pa_mainloop_api*a, pa_defer_event *e, void *userdata); + +/** An abstract mainloop API vtable */ +struct pa_mainloop_api { + /** A pointer to some private, arbitrary data of the main loop implementation */ + void *userdata; + + /** Create a new IO event source object */ + pa_io_event* (*io_new)(pa_mainloop_api*a, int fd, pa_io_event_flags_t events, pa_io_event_cb_t cb, void *userdata); + /** Enable or disable IO events on this object */ + void (*io_enable)(pa_io_event* e, pa_io_event_flags_t events); + /** Free a IO event source object */ + void (*io_free)(pa_io_event* e); + /** Set a function that is called when the IO event source is destroyed. Use this to free the userdata argument if required */ + void (*io_set_destroy)(pa_io_event *e, pa_io_event_destroy_cb_t cb); + + /** Create a new timer event source object for the specified Unix time */ + pa_time_event* (*time_new)(pa_mainloop_api*a, const struct timeval *tv, pa_time_event_cb_t cb, void *userdata); + /** Restart a running or expired timer event source with a new Unix time */ + void (*time_restart)(pa_time_event* e, const struct timeval *tv); + /** Free a deferred timer event source object */ + void (*time_free)(pa_time_event* e); + /** Set a function that is called when the timer event source is destroyed. Use this to free the userdata argument if required */ + void (*time_set_destroy)(pa_time_event *e, pa_time_event_destroy_cb_t cb); + + /** Create a new deferred event source object */ + pa_defer_event* (*defer_new)(pa_mainloop_api*a, pa_defer_event_cb_t cb, void *userdata); + /** Enable or disable a deferred event source temporarily */ + void (*defer_enable)(pa_defer_event* e, int b); + /** Free a deferred event source object */ + void (*defer_free)(pa_defer_event* e); + /** Set a function that is called when the deferred event source is destroyed. Use this to free the userdata argument if required */ + void (*defer_set_destroy)(pa_defer_event *e, pa_defer_event_destroy_cb_t cb); + + /** Exit the main loop and return the specified retval*/ + void (*quit)(pa_mainloop_api*a, int retval); +}; + +/** Run the specified callback function once from the main loop using an + * anonymous defer event. If the mainloop runs in a different thread, you need + * to follow the mainloop implementation's rules regarding how to safely create + * defer events. In particular, if you're using \ref pa_threaded_mainloop, you + * must lock the mainloop before calling this function. */ +void pa_mainloop_api_once(pa_mainloop_api*m, void (*callback)(pa_mainloop_api*m, void *userdata), void *userdata); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/mainloop-signal.h b/thirdparty/linuxbsd_headers/pulse/mainloop-signal.h new file mode 100644 index 0000000000..0a7bdeb5c7 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/mainloop-signal.h @@ -0,0 +1,64 @@ +#ifndef foomainloopsignalhfoo +#define foomainloopsignalhfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2008 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <pulse/mainloop-api.h> +#include <pulse/cdecl.h> + +PA_C_DECL_BEGIN + +/** \file + * UNIX signal support for main loops. In contrast to other + * main loop event sources such as timer and IO events, UNIX signal + * support requires modification of the global process + * environment. Due to this the generic main loop abstraction layer as + * defined in \ref mainloop-api.h doesn't have direct support for UNIX + * signals. However, you may hook signal support into an abstract main loop via the routines defined herein. + */ + +/** An opaque UNIX signal event source object */ +typedef struct pa_signal_event pa_signal_event; + +/** Callback prototype for signal events */ +typedef void (*pa_signal_cb_t) (pa_mainloop_api *api, pa_signal_event*e, int sig, void *userdata); + +/** Destroy callback prototype for signal events */ +typedef void (*pa_signal_destroy_cb_t) (pa_mainloop_api *api, pa_signal_event*e, void *userdata); + +/** Initialize the UNIX signal subsystem and bind it to the specified main loop */ +int pa_signal_init(pa_mainloop_api *api); + +/** Cleanup the signal subsystem */ +void pa_signal_done(void); + +/** Create a new UNIX signal event source object */ +pa_signal_event* pa_signal_new(int sig, pa_signal_cb_t callback, void *userdata); + +/** Free a UNIX signal event source object */ +void pa_signal_free(pa_signal_event *e); + +/** Set a function that is called when the signal event source is destroyed. Use this to free the userdata argument if required */ +void pa_signal_set_destroy(pa_signal_event *e, pa_signal_destroy_cb_t callback); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/mainloop.h b/thirdparty/linuxbsd_headers/pulse/mainloop.h new file mode 100644 index 0000000000..6e2ca5f9bf --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/mainloop.h @@ -0,0 +1,131 @@ +#ifndef foomainloophfoo +#define foomainloophfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <pulse/mainloop-api.h> +#include <pulse/cdecl.h> + +PA_C_DECL_BEGIN + +struct pollfd; + +/** \page mainloop Main Loop + * + * \section overv_sec Overview + * + * The built-in main loop implementation is based on the poll() system call. + * It supports the functions defined in the main loop abstraction and very + * little else. + * + * The main loop is created using pa_mainloop_new() and destroyed using + * pa_mainloop_free(). To get access to the main loop abstraction, + * pa_mainloop_get_api() is used. + * + * \section iter_sec Iteration + * + * The main loop is designed around the concept of iterations. Each iteration + * consists of three steps that repeat during the application's entire + * lifetime: + * + * -# Prepare - Build a list of file descriptors + * that need to be monitored and calculate the next timeout. + * -# Poll - Execute the actual poll() system call. + * -# Dispatch - Dispatch any events that have fired. + * + * When using the main loop, the application can either execute each + * iteration, one at a time, using pa_mainloop_iterate(), or let the library + * iterate automatically using pa_mainloop_run(). + * + * \section thread_sec Threads + * + * The main loop functions are designed to be thread safe, but the objects + * are not. What this means is that multiple main loops can be used, but only + * one object per thread. + * + */ + +/** \file + * + * A minimal main loop implementation based on the C library's poll() + * function. Using the routines defined herein you may create a simple + * main loop supporting the generic main loop abstraction layer as + * defined in \ref mainloop-api.h. This implementation is thread safe + * as long as you access the main loop object from a single thread only. + * + * See also \subpage mainloop + */ + +/** An opaque main loop object */ +typedef struct pa_mainloop pa_mainloop; + +/** Allocate a new main loop object */ +pa_mainloop *pa_mainloop_new(void); + +/** Free a main loop object */ +void pa_mainloop_free(pa_mainloop* m); + +/** Prepare for a single iteration of the main loop. Returns a negative value +on error or exit request. timeout specifies a maximum timeout for the subsequent +poll, or -1 for blocking behaviour. .*/ +int pa_mainloop_prepare(pa_mainloop *m, int timeout); + +/** Execute the previously prepared poll. Returns a negative value on error.*/ +int pa_mainloop_poll(pa_mainloop *m); + +/** Dispatch timeout, io and deferred events from the previously executed poll. Returns +a negative value on error. On success returns the number of source dispatched. */ +int pa_mainloop_dispatch(pa_mainloop *m); + +/** Return the return value as specified with the main loop's quit() routine. */ +int pa_mainloop_get_retval(pa_mainloop *m); + +/** Run a single iteration of the main loop. This is a convenience function +for pa_mainloop_prepare(), pa_mainloop_poll() and pa_mainloop_dispatch(). +Returns a negative value on error or exit request. If block is nonzero, +block for events if none are queued. Optionally return the return value as +specified with the main loop's quit() routine in the integer variable retval points +to. On success returns the number of sources dispatched in this iteration. */ +int pa_mainloop_iterate(pa_mainloop *m, int block, int *retval); + +/** Run unlimited iterations of the main loop object until the main loop's quit() routine is called. */ +int pa_mainloop_run(pa_mainloop *m, int *retval); + +/** Return the abstract main loop abstraction layer vtable for this + main loop. No need to free the API as it is owned by the loop + and is destroyed when the loop is freed. */ +pa_mainloop_api* pa_mainloop_get_api(pa_mainloop*m); + +/** Shutdown the main loop with the specified return value */ +void pa_mainloop_quit(pa_mainloop *m, int retval); + +/** Interrupt a running poll (for threaded systems) */ +void pa_mainloop_wakeup(pa_mainloop *m); + +/** Generic prototype of a poll() like function */ +typedef int (*pa_poll_func)(struct pollfd *ufds, unsigned long nfds, int timeout, void*userdata); + +/** Change the poll() implementation */ +void pa_mainloop_set_poll_func(pa_mainloop *m, pa_poll_func poll_func, void *userdata); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/operation.h b/thirdparty/linuxbsd_headers/pulse/operation.h new file mode 100644 index 0000000000..edd7d76e54 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/operation.h @@ -0,0 +1,64 @@ +#ifndef foooperationhfoo +#define foooperationhfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <pulse/cdecl.h> +#include <pulse/def.h> +#include <pulse/version.h> + +/** \file + * Asynchronous operations */ + +PA_C_DECL_BEGIN + +/** An asynchronous operation object */ +typedef struct pa_operation pa_operation; + +/** A callback for operation state changes */ +typedef void (*pa_operation_notify_cb_t) (pa_operation *o, void *userdata); + +/** Increase the reference count by one */ +pa_operation *pa_operation_ref(pa_operation *o); + +/** Decrease the reference count by one */ +void pa_operation_unref(pa_operation *o); + +/** Cancel the operation. Beware! This will not necessarily cancel the + * execution of the operation on the server side. However it will make + * sure that the callback associated with this operation will not be + * called anymore, effectively disabling the operation from the client + * side's view. */ +void pa_operation_cancel(pa_operation *o); + +/** Return the current status of the operation */ +pa_operation_state_t pa_operation_get_state(pa_operation *o); + +/** Set the callback function that is called when the operation state + * changes. Usually this is not necessary, since the functions that + * create pa_operation objects already take a callback that is called + * when the operation finishes. Registering a state change callback is + * mainly useful, if you want to get called back also if the operation + * gets cancelled. \since 4.0 */ +void pa_operation_set_state_callback(pa_operation *o, pa_operation_notify_cb_t cb, void *userdata); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/proplist.h b/thirdparty/linuxbsd_headers/pulse/proplist.h new file mode 100644 index 0000000000..bc9e8f8ef3 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/proplist.h @@ -0,0 +1,409 @@ +#ifndef foopulseproplisthfoo +#define foopulseproplisthfoo + +/*** + This file is part of PulseAudio. + + Copyright 2007 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <sys/types.h> + +#include <pulse/cdecl.h> +#include <pulse/gccmacro.h> +#include <pulse/version.h> + +/** \file + * Property list constants and functions */ + +PA_C_DECL_BEGIN + +/** For streams: localized media name, formatted as UTF-8. E.g. "Guns'N'Roses: Civil War".*/ +#define PA_PROP_MEDIA_NAME "media.name" + +/** For streams: localized media title if applicable, formatted as UTF-8. E.g. "Civil War" */ +#define PA_PROP_MEDIA_TITLE "media.title" + +/** For streams: localized media artist if applicable, formatted as UTF-8. E.g. "Guns'N'Roses" */ +#define PA_PROP_MEDIA_ARTIST "media.artist" + +/** For streams: localized media copyright string if applicable, formatted as UTF-8. E.g. "Evil Record Corp." */ +#define PA_PROP_MEDIA_COPYRIGHT "media.copyright" + +/** For streams: localized media generator software string if applicable, formatted as UTF-8. E.g. "Foocrop AudioFrobnicator" */ +#define PA_PROP_MEDIA_SOFTWARE "media.software" + +/** For streams: media language if applicable, in standard POSIX format. E.g. "de_DE" */ +#define PA_PROP_MEDIA_LANGUAGE "media.language" + +/** For streams: source filename if applicable, in URI format or local path. E.g. "/home/lennart/music/foobar.ogg" */ +#define PA_PROP_MEDIA_FILENAME "media.filename" + +/** \cond fulldocs */ +/** For streams: icon for the media. A binary blob containing PNG image data */ +#define PA_PROP_MEDIA_ICON "media.icon" +/** \endcond */ + +/** For streams: an XDG icon name for the media. E.g. "audio-x-mp3" */ +#define PA_PROP_MEDIA_ICON_NAME "media.icon_name" + +/** For streams: logic role of this media. One of the strings "video", "music", "game", "event", "phone", "animation", "production", "a11y", "test" */ +#define PA_PROP_MEDIA_ROLE "media.role" + +/** For streams: the name of a filter that is desired, e.g.\ "echo-cancel" or "equalizer-sink". PulseAudio may choose to not apply the filter if it does not make sense (for example, applying echo-cancellation on a Bluetooth headset probably does not make sense. \since 1.0 */ +#define PA_PROP_FILTER_WANT "filter.want" + +/** For streams: the name of a filter that is desired, e.g.\ "echo-cancel" or "equalizer-sink". Differs from PA_PROP_FILTER_WANT in that it forces PulseAudio to apply the filter, regardless of whether PulseAudio thinks it makes sense to do so or not. If this is set, PA_PROP_FILTER_WANT is ignored. In other words, you almost certainly do not want to use this. \since 1.0 */ +#define PA_PROP_FILTER_APPLY "filter.apply" + +/** For streams: the name of a filter that should specifically suppressed (i.e.\ overrides PA_PROP_FILTER_WANT). Useful for the times that PA_PROP_FILTER_WANT is automatically added (e.g. echo-cancellation for phone streams when $VOIP_APP does its own, internal AEC) \since 1.0 */ +#define PA_PROP_FILTER_SUPPRESS "filter.suppress" + +/** For event sound streams: XDG event sound name. e.g.\ "message-new-email" (Event sound streams are those with media.role set to "event") */ +#define PA_PROP_EVENT_ID "event.id" + +/** For event sound streams: localized human readable one-line description of the event, formatted as UTF-8. E.g. "Email from lennart@example.com received." */ +#define PA_PROP_EVENT_DESCRIPTION "event.description" + +/** For event sound streams: absolute horizontal mouse position on the screen if the event sound was triggered by a mouse click, integer formatted as text string. E.g. "865" */ +#define PA_PROP_EVENT_MOUSE_X "event.mouse.x" + +/** For event sound streams: absolute vertical mouse position on the screen if the event sound was triggered by a mouse click, integer formatted as text string. E.g. "432" */ +#define PA_PROP_EVENT_MOUSE_Y "event.mouse.y" + +/** For event sound streams: relative horizontal mouse position on the screen if the event sound was triggered by a mouse click, float formatted as text string, ranging from 0.0 (left side of the screen) to 1.0 (right side of the screen). E.g. "0.65" */ +#define PA_PROP_EVENT_MOUSE_HPOS "event.mouse.hpos" + +/** For event sound streams: relative vertical mouse position on the screen if the event sound was triggered by a mouse click, float formatted as text string, ranging from 0.0 (top of the screen) to 1.0 (bottom of the screen). E.g. "0.43" */ +#define PA_PROP_EVENT_MOUSE_VPOS "event.mouse.vpos" + +/** For event sound streams: mouse button that triggered the event if applicable, integer formatted as string with 0=left, 1=middle, 2=right. E.g. "0" */ +#define PA_PROP_EVENT_MOUSE_BUTTON "event.mouse.button" + +/** For streams that belong to a window on the screen: localized window title. E.g. "Totem Music Player" */ +#define PA_PROP_WINDOW_NAME "window.name" + +/** For streams that belong to a window on the screen: a textual id for identifying a window logically. E.g. "org.gnome.Totem.MainWindow" */ +#define PA_PROP_WINDOW_ID "window.id" + +/** \cond fulldocs */ +/** For streams that belong to a window on the screen: window icon. A binary blob containing PNG image data */ +#define PA_PROP_WINDOW_ICON "window.icon" +/** \endcond */ + +/** For streams that belong to a window on the screen: an XDG icon name for the window. E.g. "totem" */ +#define PA_PROP_WINDOW_ICON_NAME "window.icon_name" + +/** For streams that belong to a window on the screen: absolute horizontal window position on the screen, integer formatted as text string. E.g. "865". \since 0.9.17 */ +#define PA_PROP_WINDOW_X "window.x" + +/** For streams that belong to a window on the screen: absolute vertical window position on the screen, integer formatted as text string. E.g. "343". \since 0.9.17 */ +#define PA_PROP_WINDOW_Y "window.y" + +/** For streams that belong to a window on the screen: window width on the screen, integer formatted as text string. e.g. "365". \since 0.9.17 */ +#define PA_PROP_WINDOW_WIDTH "window.width" + +/** For streams that belong to a window on the screen: window height on the screen, integer formatted as text string. E.g. "643". \since 0.9.17 */ +#define PA_PROP_WINDOW_HEIGHT "window.height" + +/** For streams that belong to a window on the screen: relative position of the window center on the screen, float formatted as text string, ranging from 0.0 (left side of the screen) to 1.0 (right side of the screen). E.g. "0.65". \since 0.9.17 */ +#define PA_PROP_WINDOW_HPOS "window.hpos" + +/** For streams that belong to a window on the screen: relative position of the window center on the screen, float formatted as text string, ranging from 0.0 (top of the screen) to 1.0 (bottom of the screen). E.g. "0.43". \since 0.9.17 */ +#define PA_PROP_WINDOW_VPOS "window.vpos" + +/** For streams that belong to a window on the screen: if the windowing system supports multiple desktops, a comma separated list of indexes of the desktops this window is visible on. If this property is an empty string, it is visible on all desktops (i.e. 'sticky'). The first desktop is 0. E.g. "0,2,3" \since 0.9.18 */ +#define PA_PROP_WINDOW_DESKTOP "window.desktop" + +/** For streams that belong to an X11 window on the screen: the X11 display string. E.g. ":0.0" */ +#define PA_PROP_WINDOW_X11_DISPLAY "window.x11.display" + +/** For streams that belong to an X11 window on the screen: the X11 screen the window is on, an integer formatted as string. E.g. "0" */ +#define PA_PROP_WINDOW_X11_SCREEN "window.x11.screen" + +/** For streams that belong to an X11 window on the screen: the X11 monitor the window is on, an integer formatted as string. E.g. "0" */ +#define PA_PROP_WINDOW_X11_MONITOR "window.x11.monitor" + +/** For streams that belong to an X11 window on the screen: the window XID, an integer formatted as string. E.g. "25632" */ +#define PA_PROP_WINDOW_X11_XID "window.x11.xid" + +/** For clients/streams: localized human readable application name. E.g. "Totem Music Player" */ +#define PA_PROP_APPLICATION_NAME "application.name" + +/** For clients/streams: a textual id for identifying an application logically. E.g. "org.gnome.Totem" */ +#define PA_PROP_APPLICATION_ID "application.id" + +/** For clients/streams: a version string, e.g.\ "0.6.88" */ +#define PA_PROP_APPLICATION_VERSION "application.version" + +/** \cond fulldocs */ +/** For clients/streams: application icon. A binary blob containing PNG image data */ +#define PA_PROP_APPLICATION_ICON "application.icon" +/** \endcond */ + +/** For clients/streams: an XDG icon name for the application. E.g. "totem" */ +#define PA_PROP_APPLICATION_ICON_NAME "application.icon_name" + +/** For clients/streams: application language if applicable, in standard POSIX format. E.g. "de_DE" */ +#define PA_PROP_APPLICATION_LANGUAGE "application.language" + +/** For clients/streams on UNIX: application process PID, an integer formatted as string. E.g. "4711" */ +#define PA_PROP_APPLICATION_PROCESS_ID "application.process.id" + +/** For clients/streams: application process name. E.g. "totem" */ +#define PA_PROP_APPLICATION_PROCESS_BINARY "application.process.binary" + +/** For clients/streams: application user name. E.g. "lennart" */ +#define PA_PROP_APPLICATION_PROCESS_USER "application.process.user" + +/** For clients/streams: host name the application runs on. E.g. "omega" */ +#define PA_PROP_APPLICATION_PROCESS_HOST "application.process.host" + +/** For clients/streams: the D-Bus host id the application runs on. E.g. "543679e7b01393ed3e3e650047d78f6e" */ +#define PA_PROP_APPLICATION_PROCESS_MACHINE_ID "application.process.machine_id" + +/** For clients/streams: an id for the login session the application runs in. On Unix the value of $XDG_SESSION_ID. E.g. "5" */ +#define PA_PROP_APPLICATION_PROCESS_SESSION_ID "application.process.session_id" + +/** For devices: device string in the underlying audio layer's format. E.g. "surround51:0" */ +#define PA_PROP_DEVICE_STRING "device.string" + +/** For devices: API this device is access with. E.g. "alsa" */ +#define PA_PROP_DEVICE_API "device.api" + +/** For devices: localized human readable device one-line description. E.g. "Foobar Industries USB Headset 2000+ Ultra" */ +#define PA_PROP_DEVICE_DESCRIPTION "device.description" + +/** For devices: bus path to the device in the OS' format. E.g. "/sys/bus/pci/devices/0000:00:1f.2" */ +#define PA_PROP_DEVICE_BUS_PATH "device.bus_path" + +/** For devices: serial number if applicable. E.g. "4711-0815-1234" */ +#define PA_PROP_DEVICE_SERIAL "device.serial" + +/** For devices: vendor ID if applicable. E.g. 1274 */ +#define PA_PROP_DEVICE_VENDOR_ID "device.vendor.id" + +/** For devices: vendor name if applicable. E.g. "Foocorp Heavy Industries" */ +#define PA_PROP_DEVICE_VENDOR_NAME "device.vendor.name" + +/** For devices: product ID if applicable. E.g. 4565 */ +#define PA_PROP_DEVICE_PRODUCT_ID "device.product.id" + +/** For devices: product name if applicable. E.g. "SuperSpeakers 2000 Pro" */ +#define PA_PROP_DEVICE_PRODUCT_NAME "device.product.name" + +/** For devices: device class. One of "sound", "modem", "monitor", "filter" */ +#define PA_PROP_DEVICE_CLASS "device.class" + +/** For devices: form factor if applicable. One of "internal", "speaker", "handset", "tv", "webcam", "microphone", "headset", "headphone", "hands-free", "car", "hifi", "computer", "portable" */ +#define PA_PROP_DEVICE_FORM_FACTOR "device.form_factor" + +/** For devices: bus of the device if applicable. One of "isa", "pci", "usb", "firewire", "bluetooth" */ +#define PA_PROP_DEVICE_BUS "device.bus" + +/** \cond fulldocs */ +/** For devices: icon for the device. A binary blob containing PNG image data */ +#define PA_PROP_DEVICE_ICON "device.icon" +/** \endcond */ + +/** For devices: an XDG icon name for the device. E.g. "sound-card-speakers-usb" */ +#define PA_PROP_DEVICE_ICON_NAME "device.icon_name" + +/** For devices: access mode of the device if applicable. One of "mmap", "mmap_rewrite", "serial" */ +#define PA_PROP_DEVICE_ACCESS_MODE "device.access_mode" + +/** For filter devices: master device id if applicable. */ +#define PA_PROP_DEVICE_MASTER_DEVICE "device.master_device" + +/** For devices: buffer size in bytes, integer formatted as string. */ +#define PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE "device.buffering.buffer_size" + +/** For devices: fragment size in bytes, integer formatted as string. */ +#define PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE "device.buffering.fragment_size" + +/** For devices: profile identifier for the profile this devices is in. E.g. "analog-stereo", "analog-surround-40", "iec958-stereo", ...*/ +#define PA_PROP_DEVICE_PROFILE_NAME "device.profile.name" + +/** For devices: intended use. A space separated list of roles (see PA_PROP_MEDIA_ROLE) this device is particularly well suited for, due to latency, quality or form factor. \since 0.9.16 */ +#define PA_PROP_DEVICE_INTENDED_ROLES "device.intended_roles" + +/** For devices: human readable one-line description of the profile this device is in. E.g. "Analog Stereo", ... */ +#define PA_PROP_DEVICE_PROFILE_DESCRIPTION "device.profile.description" + +/** For modules: the author's name, formatted as UTF-8 string. E.g. "Lennart Poettering" */ +#define PA_PROP_MODULE_AUTHOR "module.author" + +/** For modules: a human readable one-line description of the module's purpose formatted as UTF-8. E.g. "Frobnicate sounds with a flux compensator" */ +#define PA_PROP_MODULE_DESCRIPTION "module.description" + +/** For modules: a human readable usage description of the module's arguments formatted as UTF-8. */ +#define PA_PROP_MODULE_USAGE "module.usage" + +/** For modules: a version string for the module. E.g. "0.9.15" */ +#define PA_PROP_MODULE_VERSION "module.version" + +/** For PCM formats: the sample format used as returned by pa_sample_format_to_string() \since 1.0 */ +#define PA_PROP_FORMAT_SAMPLE_FORMAT "format.sample_format" + +/** For all formats: the sample rate (unsigned integer) \since 1.0 */ +#define PA_PROP_FORMAT_RATE "format.rate" + +/** For all formats: the number of channels (unsigned integer) \since 1.0 */ +#define PA_PROP_FORMAT_CHANNELS "format.channels" + +/** For PCM formats: the channel map of the stream as returned by pa_channel_map_snprint() \since 1.0 */ +#define PA_PROP_FORMAT_CHANNEL_MAP "format.channel_map" + +/** A property list object. Basically a dictionary with ASCII strings + * as keys and arbitrary data as values. \since 0.9.11 */ +typedef struct pa_proplist pa_proplist; + +/** Allocate a property list. \since 0.9.11 */ +pa_proplist* pa_proplist_new(void); + +/** Free the property list. \since 0.9.11 */ +void pa_proplist_free(pa_proplist* p); + +/** Returns a non-zero value if the key is valid. \since 3.0 */ +int pa_proplist_key_valid(const char *key); + +/** Append a new string entry to the property list, possibly + * overwriting an already existing entry with the same key. An + * internal copy of the data passed is made. Will accept only valid + * UTF-8. \since 0.9.11 */ +int pa_proplist_sets(pa_proplist *p, const char *key, const char *value); + +/** Append a new string entry to the property list, possibly + * overwriting an already existing entry with the same key. An + * internal copy of the data passed is made. Will accept only valid + * UTF-8. The string passed in must contain a '='. Left hand side of + * the '=' is used as key name, the right hand side as string + * data. \since 0.9.16 */ +int pa_proplist_setp(pa_proplist *p, const char *pair); + +/** Append a new string entry to the property list, possibly + * overwriting an already existing entry with the same key. An + * internal copy of the data passed is made. Will accept only valid + * UTF-8. The data can be passed as printf()-style format string with + * arguments. \since 0.9.11 */ +int pa_proplist_setf(pa_proplist *p, const char *key, const char *format, ...) PA_GCC_PRINTF_ATTR(3,4); + +/** Append a new arbitrary data entry to the property list, possibly + * overwriting an already existing entry with the same key. An + * internal copy of the data passed is made. \since 0.9.11 */ +int pa_proplist_set(pa_proplist *p, const char *key, const void *data, size_t nbytes); + +/** Return a string entry for the specified key. Will return NULL if + * the data is not valid UTF-8. Will return a NUL-terminated string in + * an internally allocated buffer. The caller should make a copy of + * the data before accessing the property list again. \since 0.9.11 */ +const char *pa_proplist_gets(pa_proplist *p, const char *key); + +/** Store the value for the specified key in \a data. Will store a + * NUL-terminated string for string entries. The \a data pointer returned will + * point to an internally allocated buffer. The caller should make a + * copy of the data before the property list is accessed again. \since + * 0.9.11 */ +int pa_proplist_get(pa_proplist *p, const char *key, const void **data, size_t *nbytes); + +/** Update mode enum for pa_proplist_update(). \since 0.9.11 */ +typedef enum pa_update_mode { + PA_UPDATE_SET + /**< Replace the entire property list with the new one. Don't keep + * any of the old data around. */, + + PA_UPDATE_MERGE + /**< Merge new property list into the existing one, not replacing + * any old entries if they share a common key with the new + * property list. */, + + PA_UPDATE_REPLACE + /**< Merge new property list into the existing one, replacing all + * old entries that share a common key with the new property + * list. */ +} pa_update_mode_t; + +/** \cond fulldocs */ +#define PA_UPDATE_SET PA_UPDATE_SET +#define PA_UPDATE_MERGE PA_UPDATE_MERGE +#define PA_UPDATE_REPLACE PA_UPDATE_REPLACE +/** \endcond */ + +/** Merge property list "other" into "p", adhering the merge mode as + * specified in "mode". \since 0.9.11 */ +void pa_proplist_update(pa_proplist *p, pa_update_mode_t mode, const pa_proplist *other); + +/** Removes a single entry from the property list, identified be the + * specified key name. \since 0.9.11 */ +int pa_proplist_unset(pa_proplist *p, const char *key); + +/** Similar to pa_proplist_unset() but takes an array of keys to + * remove. The array should be terminated by a NULL pointer. Returns -1 + * on failure, otherwise the number of entries actually removed (which + * might even be 0, if there were no matching entries to + * remove). \since 0.9.11 */ +int pa_proplist_unset_many(pa_proplist *p, const char * const keys[]); + +/** Iterate through the property list. The user should allocate a + * state variable of type void* and initialize it with NULL. A pointer + * to this variable should then be passed to pa_proplist_iterate() + * which should be called in a loop until it returns NULL which + * signifies EOL. The property list should not be modified during + * iteration through the list -- with the exception of deleting the + * current entry. On each invocation this function will return the + * key string for the next entry. The keys in the property list do not + * have any particular order. \since 0.9.11 */ +const char *pa_proplist_iterate(pa_proplist *p, void **state); + +/** Format the property list nicely as a human readable string. This + * works very much like pa_proplist_to_string_sep() and uses a newline + * as separator and appends one final one. Call pa_xfree() on the + * result. \since 0.9.11 */ +char *pa_proplist_to_string(pa_proplist *p); + +/** Format the property list nicely as a human readable string and + * choose the separator. Call pa_xfree() on the result. \since + * 0.9.15 */ +char *pa_proplist_to_string_sep(pa_proplist *p, const char *sep); + +/** Allocate a new property list and assign key/value from a human + * readable string. \since 0.9.15 */ +pa_proplist *pa_proplist_from_string(const char *str); + +/** Returns 1 if an entry for the specified key exists in the + * property list. \since 0.9.11 */ +int pa_proplist_contains(pa_proplist *p, const char *key); + +/** Remove all entries from the property list object. \since 0.9.11 */ +void pa_proplist_clear(pa_proplist *p); + +/** Allocate a new property list and copy over every single entry from + * the specified list. \since 0.9.11 */ +pa_proplist* pa_proplist_copy(const pa_proplist *p); + +/** Return the number of entries in the property list. \since 0.9.15 */ +unsigned pa_proplist_size(pa_proplist *p); + +/** Returns 0 when the proplist is empty, positive otherwise \since 0.9.15 */ +int pa_proplist_isempty(pa_proplist *p); + +/** Return non-zero when a and b have the same keys and values. + * \since 0.9.16 */ +int pa_proplist_equal(pa_proplist *a, pa_proplist *b); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/pulseaudio.h b/thirdparty/linuxbsd_headers/pulse/pulseaudio.h new file mode 100644 index 0000000000..063d5e230f --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/pulseaudio.h @@ -0,0 +1,180 @@ +#ifndef foopulseaudiohfoo +#define foopulseaudiohfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <pulse/direction.h> +#include <pulse/mainloop-api.h> +#include <pulse/sample.h> +#include <pulse/format.h> +#include <pulse/def.h> +#include <pulse/context.h> +#include <pulse/stream.h> +#include <pulse/introspect.h> +#include <pulse/subscribe.h> +#include <pulse/scache.h> +#include <pulse/version.h> +#include <pulse/error.h> +#include <pulse/operation.h> +#include <pulse/channelmap.h> +#include <pulse/volume.h> +#include <pulse/xmalloc.h> +#include <pulse/utf8.h> +#include <pulse/thread-mainloop.h> +#include <pulse/mainloop.h> +#include <pulse/mainloop-signal.h> +#include <pulse/util.h> +#include <pulse/timeval.h> +#include <pulse/proplist.h> +#include <pulse/rtclock.h> + +/** \file + * Include all libpulse header files at once. The following files are + * included: \ref direction.h, \ref mainloop-api.h, \ref sample.h, \ref def.h, + * \ref context.h, \ref stream.h, \ref introspect.h, \ref subscribe.h, \ref + * scache.h, \ref version.h, \ref error.h, \ref channelmap.h, \ref + * operation.h,\ref volume.h, \ref xmalloc.h, \ref utf8.h, \ref + * thread-mainloop.h, \ref mainloop.h, \ref util.h, \ref proplist.h, + * \ref timeval.h, \ref rtclock.h and \ref mainloop-signal.h at + * once */ + +/** \mainpage + * + * \section intro_sec Introduction + * + * This document describes the client API for the PulseAudio sound + * server. The API comes in two flavours to accommodate different styles + * of applications and different needs in complexity: + * + * \li The complete but somewhat complicated to use asynchronous API + * \li The simplified, easy to use, but limited synchronous API + * + * All strings in PulseAudio are in the UTF-8 encoding, regardless of current + * locale. Some functions will filter invalid sequences from the string, some + * will simply fail. To ensure reliable behaviour, make sure everything you + * pass to the API is already in UTF-8. + + * \section simple_sec Simple API + * + * Use this if you develop your program in synchronous style and just + * need a way to play or record data on the sound server. See + * \subpage simple for more details. + * + * \section async_sec Asynchronous API + * + * Use this if you develop your programs in asynchronous, event loop + * based style or if you want to use the advanced features of the + * PulseAudio API. A guide can be found in \subpage async. + * + * By using the built-in threaded main loop, it is possible to achieve a + * pseudo-synchronous API, which can be useful in synchronous applications + * where the simple API is insufficient. See the \ref async page for + * details. + * + * \section thread_sec Threads + * + * The PulseAudio client libraries are not designed to be directly + * thread-safe. They are however designed to be reentrant and + * threads-aware. + * + * To use the libraries in a threaded environment, you must assure that + * all objects are only used in one thread at a time. Normally, this means + * that all objects belonging to a single context must be accessed from the + * same thread. + * + * The included main loop implementation is also not thread safe. Take care + * to make sure event objects are not manipulated when any other code is + * using the main loop. + * + * \section error_sec Error Handling + * + * Every function should explicitly document how errors are reported to + * the caller. Unfortunately, currently a lot of that documentation is + * missing. Here is an overview of the general conventions used. + * + * The PulseAudio API indicates error conditions by returning a negative + * integer value or a NULL pointer. On success, zero or a positive integer + * value or a valid pointer is returned. + * + * Functions of the \ref simple generally return -1 or NULL on failure and + * can optionally store an error code (see ::pa_error_code) using a pointer + * argument. + * + * Functions of the \ref async return an negative error code or NULL on + * failure (see ::pa_error_code). In the later case, pa_context_errno() + * can be used to obtain the error code of the last failed operation. + * + * An error code can be turned into a human readable message using + * pa_strerror(). + * + * \section logging_sec Logging + * + * You can configure different logging parameters for the PulseAudio client + * libraries. The following environment variables are recognized: + * + * - `PULSE_LOG`: Maximum log level required. Bigger values result in a + * more verbose logging output. The following values are recognized: + * + `0`: Error messages + * + `1`: Warning messages + * + `2`: Notice messages + * + `3`: Info messages + * + `4`: Debug messages + * - `PULSE_LOG_SYSLOG`: If defined, force all client libraries to log + * their output using the syslog(3) mechanism. Default behavior is to + * log all output to stderr. + * - `PULSE_LOG_JOURNAL`: If defined, force all client libraries to log + * their output using the systemd journal. If both `PULSE_LOG_JOURNAL` + * and `PULSE_LOG_SYSLOG` are defined, logging to the systemd journal + * takes a higher precedence. Each message originating library file name + * and function are included by default through the journal fields + * `CODE_FILE`, `CODE_FUNC`, and `CODE_LINE`. Any backtrace attached to + * the logging message is sent through the PulseAudio-specific journal + * field `PULSE_BACKTRACE`. This environment variable has no effect if + * PulseAudio was compiled without systemd journal support. + * - `PULSE_LOG_COLORS`: If defined, enables colored logging output. + * - `PULSE_LOG_TIME`: If defined, include timestamps with each message. + * - `PULSE_LOG_FILE`: If defined, include each message originating file + * name. + * - `PULSE_LOG_META`: If defined, include each message originating file + * name and path relative to the PulseAudio source tree root. + * - `PULSE_LOG_LEVEL`: If defined, include a log level prefix with each + * message. Respectively, the prefixes "E", "W", "N", "I", "D" stands + * for Error, Warning, Notice, Info, and Debugging. + * - `PULSE_LOG_BACKTRACE`: Number of functions to display in the backtrace. + * If this variable is not defined, or has a value of zero, no backtrace + * is shown. + * - `PULSE_LOG_BACKTRACE_SKIP`: Number of backtrace levels to skip, from + * the function printing the log message downwards. + * - `PULSE_LOG_NO_RATE_LIMIT`: If defined, do not rate limit the logging + * output. Rate limiting skips certain log messages when their frequency + * is considered too high. + * + * \section pkgconfig pkg-config + * + * The PulseAudio libraries provide pkg-config snippets for the different + * modules: + * + * \li libpulse - The asynchronous API and the internal main loop implementation. + * \li libpulse-mainloop-glib - GLIB 2.x main loop bindings. + * \li libpulse-simple - The simple PulseAudio API. + */ + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/rtclock.h b/thirdparty/linuxbsd_headers/pulse/rtclock.h new file mode 100644 index 0000000000..da65076464 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/rtclock.h @@ -0,0 +1,38 @@ +#ifndef foortclockfoo +#define foortclockfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2009 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <pulse/cdecl.h> +#include <pulse/sample.h> + +/** \file + * Monotonic clock utilities. */ + +PA_C_DECL_BEGIN + +/** Return the current monotonic system time in usec, if such a clock + * is available. If it is not available this will return the + * wallclock time instead. \since 0.9.16 */ +pa_usec_t pa_rtclock_now(void); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/sample.h b/thirdparty/linuxbsd_headers/pulse/sample.h new file mode 100644 index 0000000000..4299eecff1 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/sample.h @@ -0,0 +1,354 @@ +#ifndef foosamplehfoo +#define foosamplehfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <inttypes.h> +#include <sys/types.h> +#include <sys/param.h> + +#include <pulse/gccmacro.h> +#include <pulse/cdecl.h> +#include <pulse/version.h> + +/** \page sample Sample Format Specifications + * + * \section overv_sec Overview + * + * PulseAudio is capable of handling a multitude of sample formats, rates + * and channels, transparently converting and mixing them as needed. + * + * \section format_sec Sample Format + * + * PulseAudio supports the following sample formats: + * + * \li PA_SAMPLE_U8 - Unsigned 8 bit integer PCM. + * \li PA_SAMPLE_S16LE - Signed 16 integer bit PCM, little endian. + * \li PA_SAMPLE_S16BE - Signed 16 integer bit PCM, big endian. + * \li PA_SAMPLE_FLOAT32LE - 32 bit IEEE floating point PCM, little endian. + * \li PA_SAMPLE_FLOAT32BE - 32 bit IEEE floating point PCM, big endian. + * \li PA_SAMPLE_ALAW - 8 bit a-Law. + * \li PA_SAMPLE_ULAW - 8 bit mu-Law. + * \li PA_SAMPLE_S32LE - Signed 32 bit integer PCM, little endian. + * \li PA_SAMPLE_S32BE - Signed 32 bit integer PCM, big endian. + * \li PA_SAMPLE_S24LE - Signed 24 bit integer PCM packed, little endian. + * \li PA_SAMPLE_S24BE - Signed 24 bit integer PCM packed, big endian. + * \li PA_SAMPLE_S24_32LE - Signed 24 bit integer PCM in LSB of 32 bit words, little endian. + * \li PA_SAMPLE_S24_32BE - Signed 24 bit integer PCM in LSB of 32 bit words, big endian. + * + * The floating point sample formats have the range from -1.0 to 1.0. + * + * The sample formats that are sensitive to endianness have convenience + * macros for native endian (NE), and reverse endian (RE). + * + * \section rate_sec Sample Rates + * + * PulseAudio supports any sample rate between 1 Hz and 192000 Hz. There is no + * point trying to exceed the sample rate of the output device though as the + * signal will only get downsampled, consuming CPU on the machine running the + * server. + * + * \section chan_sec Channels + * + * PulseAudio supports up to 32 individual channels. The order of the + * channels is up to the application, but they must be continuous. To map + * channels to speakers, see \ref channelmap. + * + * \section calc_sec Calculations + * + * The PulseAudio library contains a number of convenience functions to do + * calculations on sample formats: + * + * \li pa_bytes_per_second() - The number of bytes one second of audio will + * take given a sample format. + * \li pa_frame_size() - The size, in bytes, of one frame (i.e. one set of + * samples, one for each channel). + * \li pa_sample_size() - The size, in bytes, of one sample. + * \li pa_bytes_to_usec() - Calculate the time it would take to play a buffer + * of a certain size. + * + * \section util_sec Convenience Functions + * + * The library also contains a couple of other convenience functions: + * + * \li pa_sample_spec_valid() - Tests if a sample format specification is + * valid. + * \li pa_sample_spec_equal() - Tests if the sample format specifications are + * identical. + * \li pa_sample_format_to_string() - Return a textual description of a + * sample format. + * \li pa_parse_sample_format() - Parse a text string into a sample format. + * \li pa_sample_spec_snprint() - Create a textual description of a complete + * sample format specification. + * \li pa_bytes_snprint() - Pretty print a byte value (e.g. 2.5 MiB). + */ + +/** \file + * Constants and routines for sample type handling + * + * See also \subpage sample + */ + +PA_C_DECL_BEGIN + +#if !defined(WORDS_BIGENDIAN) + +#if defined(__BYTE_ORDER) +#if __BYTE_ORDER == __BIG_ENDIAN +#define WORDS_BIGENDIAN +#endif +#endif + +/* On Sparc, WORDS_BIGENDIAN needs to be set if _BIG_ENDIAN is defined. */ +#if defined(__sparc__) && defined(_BIG_ENDIAN) +#define WORDS_BIGENDIAN +#endif + +#endif + +/** Maximum number of allowed channels */ +#define PA_CHANNELS_MAX 32U + +/** Maximum allowed sample rate */ +#define PA_RATE_MAX (48000U*8U) + +/** Sample format */ +typedef enum pa_sample_format { + PA_SAMPLE_U8, + /**< Unsigned 8 Bit PCM */ + + PA_SAMPLE_ALAW, + /**< 8 Bit a-Law */ + + PA_SAMPLE_ULAW, + /**< 8 Bit mu-Law */ + + PA_SAMPLE_S16LE, + /**< Signed 16 Bit PCM, little endian (PC) */ + + PA_SAMPLE_S16BE, + /**< Signed 16 Bit PCM, big endian */ + + PA_SAMPLE_FLOAT32LE, + /**< 32 Bit IEEE floating point, little endian (PC), range -1.0 to 1.0 */ + + PA_SAMPLE_FLOAT32BE, + /**< 32 Bit IEEE floating point, big endian, range -1.0 to 1.0 */ + + PA_SAMPLE_S32LE, + /**< Signed 32 Bit PCM, little endian (PC) */ + + PA_SAMPLE_S32BE, + /**< Signed 32 Bit PCM, big endian */ + + PA_SAMPLE_S24LE, + /**< Signed 24 Bit PCM packed, little endian (PC). \since 0.9.15 */ + + PA_SAMPLE_S24BE, + /**< Signed 24 Bit PCM packed, big endian. \since 0.9.15 */ + + PA_SAMPLE_S24_32LE, + /**< Signed 24 Bit PCM in LSB of 32 Bit words, little endian (PC). \since 0.9.15 */ + + PA_SAMPLE_S24_32BE, + /**< Signed 24 Bit PCM in LSB of 32 Bit words, big endian. \since 0.9.15 */ + + PA_SAMPLE_MAX, + /**< Upper limit of valid sample types */ + + PA_SAMPLE_INVALID = -1 + /**< An invalid value */ +} pa_sample_format_t; + +#ifdef WORDS_BIGENDIAN +/** Signed 16 Bit PCM, native endian */ +#define PA_SAMPLE_S16NE PA_SAMPLE_S16BE +/** 32 Bit IEEE floating point, native endian */ +#define PA_SAMPLE_FLOAT32NE PA_SAMPLE_FLOAT32BE +/** Signed 32 Bit PCM, native endian */ +#define PA_SAMPLE_S32NE PA_SAMPLE_S32BE +/** Signed 24 Bit PCM packed, native endian. \since 0.9.15 */ +#define PA_SAMPLE_S24NE PA_SAMPLE_S24BE +/** Signed 24 Bit PCM in LSB of 32 Bit words, native endian. \since 0.9.15 */ +#define PA_SAMPLE_S24_32NE PA_SAMPLE_S24_32BE + +/** Signed 16 Bit PCM reverse endian */ +#define PA_SAMPLE_S16RE PA_SAMPLE_S16LE +/** 32 Bit IEEE floating point, reverse endian */ +#define PA_SAMPLE_FLOAT32RE PA_SAMPLE_FLOAT32LE +/** Signed 32 Bit PCM, reverse endian */ +#define PA_SAMPLE_S32RE PA_SAMPLE_S32LE +/** Signed 24 Bit PCM, packed reverse endian. \since 0.9.15 */ +#define PA_SAMPLE_S24RE PA_SAMPLE_S24LE +/** Signed 24 Bit PCM, in LSB of 32 Bit words, reverse endian. \since 0.9.15 */ +#define PA_SAMPLE_S24_32RE PA_SAMPLE_S24_32LE +#else +/** Signed 16 Bit PCM, native endian */ +#define PA_SAMPLE_S16NE PA_SAMPLE_S16LE +/** 32 Bit IEEE floating point, native endian */ +#define PA_SAMPLE_FLOAT32NE PA_SAMPLE_FLOAT32LE +/** Signed 32 Bit PCM, native endian */ +#define PA_SAMPLE_S32NE PA_SAMPLE_S32LE +/** Signed 24 Bit PCM packed, native endian. \since 0.9.15 */ +#define PA_SAMPLE_S24NE PA_SAMPLE_S24LE +/** Signed 24 Bit PCM in LSB of 32 Bit words, native endian. \since 0.9.15 */ +#define PA_SAMPLE_S24_32NE PA_SAMPLE_S24_32LE + +/** Signed 16 Bit PCM, reverse endian */ +#define PA_SAMPLE_S16RE PA_SAMPLE_S16BE +/** 32 Bit IEEE floating point, reverse endian */ +#define PA_SAMPLE_FLOAT32RE PA_SAMPLE_FLOAT32BE +/** Signed 32 Bit PCM, reverse endian */ +#define PA_SAMPLE_S32RE PA_SAMPLE_S32BE +/** Signed 24 Bit PCM, packed reverse endian. \since 0.9.15 */ +#define PA_SAMPLE_S24RE PA_SAMPLE_S24BE +/** Signed 24 Bit PCM, in LSB of 32 Bit words, reverse endian. \since 0.9.15 */ +#define PA_SAMPLE_S24_32RE PA_SAMPLE_S24_32BE +#endif + +/** A Shortcut for PA_SAMPLE_FLOAT32NE */ +#define PA_SAMPLE_FLOAT32 PA_SAMPLE_FLOAT32NE + +/** \cond fulldocs */ +/* Allow clients to check with #ifdef for these sample formats */ +#define PA_SAMPLE_U8 PA_SAMPLE_U8 +#define PA_SAMPLE_ALAW PA_SAMPLE_ALAW +#define PA_SAMPLE_ULAW PA_SAMPLE_ULAW +#define PA_SAMPLE_S16LE PA_SAMPLE_S16LE +#define PA_SAMPLE_S16BE PA_SAMPLE_S16BE +#define PA_SAMPLE_FLOAT32LE PA_SAMPLE_FLOAT32LE +#define PA_SAMPLE_FLOAT32BE PA_SAMPLE_FLOAT32BE +#define PA_SAMPLE_S32LE PA_SAMPLE_S32LE +#define PA_SAMPLE_S32BE PA_SAMPLE_S32BE +#define PA_SAMPLE_S24LE PA_SAMPLE_S24LE +#define PA_SAMPLE_S24BE PA_SAMPLE_S24BE +#define PA_SAMPLE_S24_32LE PA_SAMPLE_S24_32LE +#define PA_SAMPLE_S24_32BE PA_SAMPLE_S24_32BE +/** \endcond */ + +/** A sample format and attribute specification */ +typedef struct pa_sample_spec { + pa_sample_format_t format; + /**< The sample format */ + + uint32_t rate; + /**< The sample rate. (e.g. 44100) */ + + uint8_t channels; + /**< Audio channels. (1 for mono, 2 for stereo, ...) */ +} pa_sample_spec; + +/** Type for usec specifications (unsigned). Always 64 bit. */ +typedef uint64_t pa_usec_t; + +/** Return the amount of bytes playback of a second of audio with the specified sample type takes */ +size_t pa_bytes_per_second(const pa_sample_spec *spec) PA_GCC_PURE; + +/** Return the size of a frame with the specific sample type */ +size_t pa_frame_size(const pa_sample_spec *spec) PA_GCC_PURE; + +/** Return the size of a sample with the specific sample type */ +size_t pa_sample_size(const pa_sample_spec *spec) PA_GCC_PURE; + +/** Similar to pa_sample_size() but take a sample format instead of a + * full sample spec. \since 0.9.15 */ +size_t pa_sample_size_of_format(pa_sample_format_t f) PA_GCC_PURE; + +/** Calculate the time the specified bytes take to play with the + * specified sample type. The return value will always be rounded + * down for non-integral return values. */ +pa_usec_t pa_bytes_to_usec(uint64_t length, const pa_sample_spec *spec) PA_GCC_PURE; + +/** Calculates the number of bytes that are required for the specified + * time. The return value will always be rounded down for non-integral + * return values. \since 0.9 */ +size_t pa_usec_to_bytes(pa_usec_t t, const pa_sample_spec *spec) PA_GCC_PURE; + +/** Initialize the specified sample spec and return a pointer to + * it. The sample spec will have a defined state but + * pa_sample_spec_valid() will fail for it. \since 0.9.13 */ +pa_sample_spec* pa_sample_spec_init(pa_sample_spec *spec); + +/** Return non-zero if the given integer is a valid sample format. \since 5.0 */ +int pa_sample_format_valid(unsigned format) PA_GCC_PURE; + +/** Return non-zero if the rate is within the supported range. \since 5.0 */ +int pa_sample_rate_valid(uint32_t rate) PA_GCC_PURE; + +/** Return non-zero if the channel count is within the supported range. + * \since 5.0 */ +int pa_channels_valid(uint8_t channels) PA_GCC_PURE; + +/** Return non-zero when the sample type specification is valid */ +int pa_sample_spec_valid(const pa_sample_spec *spec) PA_GCC_PURE; + +/** Return non-zero when the two sample type specifications match */ +int pa_sample_spec_equal(const pa_sample_spec*a, const pa_sample_spec*b) PA_GCC_PURE; + +/** Return a descriptive string for the specified sample format. \since 0.8 */ +const char *pa_sample_format_to_string(pa_sample_format_t f) PA_GCC_PURE; + +/** Parse a sample format text. Inverse of pa_sample_format_to_string() */ +pa_sample_format_t pa_parse_sample_format(const char *format) PA_GCC_PURE; + +/** Maximum required string length for + * pa_sample_spec_snprint(). Please note that this value can change + * with any release without warning and without being considered API + * or ABI breakage. You should not use this definition anywhere where + * it might become part of an ABI. */ +#define PA_SAMPLE_SPEC_SNPRINT_MAX 32 + +/** Pretty print a sample type specification to a string */ +char* pa_sample_spec_snprint(char *s, size_t l, const pa_sample_spec *spec); + +/** Maximum required string length for pa_bytes_snprint(). Please note + * that this value can change with any release without warning and + * without being considered API or ABI breakage. You should not use + * this definition anywhere where it might become part of an + * ABI. \since 0.9.16 */ +#define PA_BYTES_SNPRINT_MAX 11 + +/** Pretty print a byte size value (i.e.\ "2.5 MiB") */ +char* pa_bytes_snprint(char *s, size_t l, unsigned v); + +/** Return 1 when the specified format is little endian, return -1 + * when endianness does not apply to this format. \since 0.9.16 */ +int pa_sample_format_is_le(pa_sample_format_t f) PA_GCC_PURE; + +/** Return 1 when the specified format is big endian, return -1 when + * endianness does not apply to this format. \since 0.9.16 */ +int pa_sample_format_is_be(pa_sample_format_t f) PA_GCC_PURE; + +#ifdef WORDS_BIGENDIAN +#define pa_sample_format_is_ne(f) pa_sample_format_is_be(f) +#define pa_sample_format_is_re(f) pa_sample_format_is_le(f) +#else +/** Return 1 when the specified format is native endian, return -1 + * when endianness does not apply to this format. \since 0.9.16 */ +#define pa_sample_format_is_ne(f) pa_sample_format_is_le(f) +/** Return 1 when the specified format is reverse endian, return -1 + * when endianness does not apply to this format. \since 0.9.16 */ +#define pa_sample_format_is_re(f) pa_sample_format_is_be(f) +#endif + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/scache.h b/thirdparty/linuxbsd_headers/pulse/scache.h new file mode 100644 index 0000000000..e799b1d140 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/scache.h @@ -0,0 +1,124 @@ +#ifndef fooscachehfoo +#define fooscachehfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <sys/types.h> + +#include <pulse/context.h> +#include <pulse/stream.h> +#include <pulse/cdecl.h> +#include <pulse/version.h> + +/** \page scache Sample Cache + * + * \section overv_sec Overview + * + * The sample cache provides a simple way of overcoming high network latencies + * and reducing bandwidth. Instead of streaming a sound precisely when it + * should be played, it is stored on the server and only the command to start + * playing it needs to be sent. + * + * \section create_sec Creation + * + * To create a sample, the normal stream API is used (see \ref streams). The + * function pa_stream_connect_upload() will make sure the stream is stored as + * a sample on the server. + * + * To complete the upload, pa_stream_finish_upload() is called and the sample + * will receive the same name as the stream. If the upload should be aborted, + * simply call pa_stream_disconnect(). + * + * \section play_sec Playing samples + * + * To play back a sample, simply call pa_context_play_sample(): + * + * \code + * pa_operation *o; + * + * o = pa_context_play_sample(my_context, + * "sample2", // Name of my sample + * NULL, // Use default sink + * PA_VOLUME_NORM, // Full volume + * NULL, // Don't need a callback + * NULL + * ); + * if (o) + * pa_operation_unref(o); + * \endcode + * + * \section rem_sec Removing samples + * + * When a sample is no longer needed, it should be removed on the server to + * save resources. The sample is deleted using pa_context_remove_sample(). + */ + +/** \file + * All sample cache related routines + * + * See also \subpage scache + */ + +PA_C_DECL_BEGIN + +/** Callback prototype for pa_context_play_sample_with_proplist(). The + * idx value is the index of the sink input object, or + * PA_INVALID_INDEX on failure. \since 0.9.11 */ +typedef void (*pa_context_play_sample_cb_t)(pa_context *c, uint32_t idx, void *userdata); + +/** Make this stream a sample upload stream */ +int pa_stream_connect_upload(pa_stream *s, size_t length); + +/** Finish the sample upload, the stream name will become the sample + * name. You cancel a sample upload by issuing + * pa_stream_disconnect() */ +int pa_stream_finish_upload(pa_stream *s); + +/** Remove a sample from the sample cache. Returns an operation object which may be used to cancel the operation while it is running */ +pa_operation* pa_context_remove_sample(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata); + +/** Play a sample from the sample cache to the specified device. If + * the latter is NULL use the default sink. Returns an operation + * object */ +pa_operation* pa_context_play_sample( + pa_context *c /**< Context */, + const char *name /**< Name of the sample to play */, + const char *dev /**< Sink to play this sample on */, + pa_volume_t volume /**< Volume to play this sample with. Starting with 0.9.15 you may pass here PA_VOLUME_INVALID which will leave the decision about the volume to the server side which is a good idea. */ , + pa_context_success_cb_t cb /**< Call this function after successfully starting playback, or NULL */, + void *userdata /**< Userdata to pass to the callback */); + +/** Play a sample from the sample cache to the specified device, + * allowing specification of a property list for the playback + * stream. If the latter is NULL use the default sink. Returns an + * operation object. \since 0.9.11 */ +pa_operation* pa_context_play_sample_with_proplist( + pa_context *c /**< Context */, + const char *name /**< Name of the sample to play */, + const char *dev /**< Sink to play this sample on */, + pa_volume_t volume /**< Volume to play this sample with. Starting with 0.9.15 you may pass here PA_VOLUME_INVALID which will leave the decision about the volume to the server side which is a good idea. */ , + pa_proplist *proplist /**< Property list for this sound. The property list of the cached entry will be merged into this property list */, + pa_context_play_sample_cb_t cb /**< Call this function after successfully starting playback, or NULL */, + void *userdata /**< Userdata to pass to the callback */); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/simple.h b/thirdparty/linuxbsd_headers/pulse/simple.h new file mode 100644 index 0000000000..7b84f71b55 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/simple.h @@ -0,0 +1,159 @@ +#ifndef foosimplehfoo +#define foosimplehfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <sys/types.h> + +#include <pulse/sample.h> +#include <pulse/channelmap.h> +#include <pulse/def.h> +#include <pulse/cdecl.h> +#include <pulse/version.h> + +/** \page simple Simple API + * + * \section overv_sec Overview + * + * The simple API is designed for applications with very basic sound + * playback or capture needs. It can only support a single stream per + * connection and has no support for handling of complex features like + * events, channel mappings and volume control. It is, however, very simple + * to use and quite sufficient for many programs. + * + * \section conn_sec Connecting + * + * The first step before using the sound system is to connect to the + * server. This is normally done this way: + * + * \code + * pa_simple *s; + * pa_sample_spec ss; + * + * ss.format = PA_SAMPLE_S16NE; + * ss.channels = 2; + * ss.rate = 44100; + * + * s = pa_simple_new(NULL, // Use the default server. + * "Fooapp", // Our application's name. + * PA_STREAM_PLAYBACK, + * NULL, // Use the default device. + * "Music", // Description of our stream. + * &ss, // Our sample format. + * NULL, // Use default channel map + * NULL, // Use default buffering attributes. + * NULL, // Ignore error code. + * ); + * \endcode + * + * At this point a connected object is returned, or NULL if there was a + * problem connecting. + * + * \section transfer_sec Transferring data + * + * Once the connection is established to the server, data can start flowing. + * Using the connection is very similar to the normal read() and write() + * system calls. The main difference is that they're called pa_simple_read() + * and pa_simple_write(). Note that these operations always block. + * + * \section ctrl_sec Buffer control + * + * \li pa_simple_get_latency() - Will return the total latency of + * the playback or record pipeline, respectively. + * \li pa_simple_flush() - Will throw away all data currently in buffers. + * + * If a playback stream is used then the following operation is available: + * + * \li pa_simple_drain() - Will wait for all sent data to finish playing. + * + * \section cleanup_sec Cleanup + * + * Once playback or capture is complete, the connection should be closed + * and resources freed. This is done through: + * + * \code + * pa_simple_free(s); + * \endcode + */ + +/** \file + * A simple but limited synchronous playback and recording + * API. This is a synchronous, simplified wrapper around the standard + * asynchronous API. + * + * See also \subpage simple + */ + +/** \example pacat-simple.c + * A simple playback tool using the simple API */ + +/** \example parec-simple.c + * A simple recording tool using the simple API */ + +PA_C_DECL_BEGIN + +/** \struct pa_simple + * An opaque simple connection object */ +typedef struct pa_simple pa_simple; + +/** Create a new connection to the server. */ +pa_simple* pa_simple_new( + const char *server, /**< Server name, or NULL for default */ + const char *name, /**< A descriptive name for this client (application name, ...) */ + pa_stream_direction_t dir, /**< Open this stream for recording or playback? */ + const char *dev, /**< Sink (resp. source) name, or NULL for default */ + const char *stream_name, /**< A descriptive name for this stream (application name, song title, ...) */ + const pa_sample_spec *ss, /**< The sample type to use */ + const pa_channel_map *map, /**< The channel map to use, or NULL for default */ + const pa_buffer_attr *attr, /**< Buffering attributes, or NULL for default */ + int *error /**< A pointer where the error code is stored when the routine returns NULL. It is OK to pass NULL here. */ + ); + +/** Close and free the connection to the server. The connection object becomes invalid when this is called. */ +void pa_simple_free(pa_simple *s); + +/** Write some data to the server. */ +int pa_simple_write(pa_simple *s, const void *data, size_t bytes, int *error); + +/** Wait until all data already written is played by the daemon. */ +int pa_simple_drain(pa_simple *s, int *error); + +/** Read some data from the server. This function blocks until \a bytes amount + * of data has been received from the server, or until an error occurs. + * Returns a negative value on failure. */ +int pa_simple_read( + pa_simple *s, /**< The connection object. */ + void *data, /**< A pointer to a buffer. */ + size_t bytes, /**< The number of bytes to read. */ + int *error + /**< A pointer where the error code is stored when the function returns + * a negative value. It is OK to pass NULL here. */ + ); + +/** Return the playback or record latency. */ +pa_usec_t pa_simple_get_latency(pa_simple *s, int *error); + +/** Flush the playback or record buffer. This discards any audio in the buffer. */ +int pa_simple_flush(pa_simple *s, int *error); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/stream.h b/thirdparty/linuxbsd_headers/pulse/stream.h new file mode 100644 index 0000000000..5dfdee1a02 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/stream.h @@ -0,0 +1,831 @@ +#ifndef foostreamhfoo +#define foostreamhfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <sys/types.h> + +#include <pulse/sample.h> +#include <pulse/format.h> +#include <pulse/channelmap.h> +#include <pulse/volume.h> +#include <pulse/def.h> +#include <pulse/cdecl.h> +#include <pulse/operation.h> +#include <pulse/context.h> +#include <pulse/proplist.h> + +/** \page streams Audio Streams + * + * \section overv_sec Overview + * + * Audio streams form the central functionality of the sound server. Data is + * routed, converted and mixed from several sources before it is passed along + * to a final output. Currently, there are three forms of audio streams: + * + * \li Playback streams - Data flows from the client to the server. + * \li Record streams - Data flows from the server to the client. + * \li Upload streams - Similar to playback streams, but the data is stored in + * the sample cache. See \ref scache for more information + * about controlling the sample cache. + * + * \section create_sec Creating + * + * To access a stream, a pa_stream object must be created using + * pa_stream_new() or pa_stream_new_extended(). pa_stream_new() is for PCM + * streams only, while pa_stream_new_extended() can be used for both PCM and + * compressed audio streams. At this point the application must specify what + * stream format(s) it supports. See \ref sample and \ref channelmap for more + * information on the stream format parameters. FIXME: Those references only + * talk about PCM parameters, we should also have an overview page for how the + * pa_format_info based stream format configuration works. Bug filed: + * https://bugs.freedesktop.org/show_bug.cgi?id=72265 + * + * This first step will only create a client-side object, representing the + * stream. To use the stream, a server-side object must be created and + * associated with the local object. Depending on which type of stream is + * desired, a different function is needed: + * + * \li Playback stream - pa_stream_connect_playback() + * \li Record stream - pa_stream_connect_record() + * \li Upload stream - pa_stream_connect_upload() (see \ref scache) + * + * Similar to how connections are done in contexts, connecting a stream will + * not generate a pa_operation object. Also like contexts, the application + * should register a state change callback, using + * pa_stream_set_state_callback(), and wait for the stream to enter an active + * state. + * + * Note: there is a user-controllable slider in mixer applications such as + * pavucontrol corresponding to each of the created streams. Multiple + * (especially identically named) volume sliders for the same application might + * confuse the user. Also, the server supports only a limited number of + * simultaneous streams. Because of this, it is not always appropriate to + * create multiple streams in one application that needs to output multiple + * sounds. The rough guideline is: if there is no use case that would require + * separate user-initiated volume changes for each stream, perform the mixing + * inside the application. + * + * \subsection bufattr_subsec Buffer Attributes + * + * Playback and record streams always have a server-side buffer as + * part of the data flow. The size of this buffer needs to be chosen + * in a compromise between low latency and sensitivity for buffer + * overflows/underruns. + * + * The buffer metrics may be controlled by the application. They are + * described with a pa_buffer_attr structure which contains a number + * of fields: + * + * \li maxlength - The absolute maximum number of bytes that can be + * stored in the buffer. If this value is exceeded + * then data will be lost. It is recommended to pass + * (uint32_t) -1 here which will cause the server to + * fill in the maximum possible value. + * + * \li tlength - The target fill level of the playback buffer. The + * server will only send requests for more data as long + * as the buffer has less than this number of bytes of + * data. If you pass (uint32_t) -1 (which is + * recommended) here the server will choose the longest + * target buffer fill level possible to minimize the + * number of necessary wakeups and maximize drop-out + * safety. This can exceed 2s of buffering. For + * low-latency applications or applications where + * latency matters you should pass a proper value here. + * + * \li prebuf - Number of bytes that need to be in the buffer before + * playback will commence. Start of playback can be + * forced using pa_stream_trigger() even though the + * prebuffer size hasn't been reached. If a buffer + * underrun occurs, this prebuffering will be again + * enabled. If the playback shall never stop in case of a + * buffer underrun, this value should be set to 0. In + * that case the read index of the output buffer + * overtakes the write index, and hence the fill level of + * the buffer is negative. If you pass (uint32_t) -1 here + * (which is recommended) the server will choose the same + * value as tlength here. + * + * \li minreq - Minimum number of free bytes in the playback + * buffer before the server will request more data. It is + * recommended to fill in (uint32_t) -1 here. This value + * influences how much time the sound server has to move + * data from the per-stream server-side playback buffer + * to the hardware playback buffer. + * + * \li fragsize - Maximum number of bytes that the server will push in + * one chunk for record streams. If you pass (uint32_t) + * -1 (which is recommended) here, the server will + * choose the longest fragment setting possible to + * minimize the number of necessary wakeups and + * maximize drop-out safety. This can exceed 2s of + * buffering. For low-latency applications or + * applications where latency matters you should pass a + * proper value here. + * + * If PA_STREAM_ADJUST_LATENCY is set, then the tlength/fragsize + * parameters will be interpreted slightly differently than described + * above when passed to pa_stream_connect_record() and + * pa_stream_connect_playback(): the overall latency that is comprised + * of both the server side playback buffer length, the hardware + * playback buffer length and additional latencies will be adjusted in + * a way that it matches tlength resp. fragsize. Set + * PA_STREAM_ADJUST_LATENCY if you want to control the overall + * playback latency for your stream. Unset it if you want to control + * only the latency induced by the server-side, rewritable playback + * buffer. The server will try to fulfill the client's latency requests + * as good as possible. However if the underlying hardware cannot + * change the hardware buffer length or only in a limited range, the + * actually resulting latency might be different from what the client + * requested. Thus, for synchronization clients always need to check + * the actual measured latency via pa_stream_get_latency() or a + * similar call, and not make any assumptions about the latency + * available. The function pa_stream_get_buffer_attr() will always + * return the actual size of the server-side per-stream buffer in + * tlength/fragsize, regardless whether PA_STREAM_ADJUST_LATENCY is + * set or not. + * + * The server-side per-stream playback buffers are indexed by a write and a read + * index. The application writes to the write index and the sound + * device reads from the read index. The read index is increased + * monotonically, while the write index may be freely controlled by + * the application. Subtracting the read index from the write index + * will give you the current fill level of the buffer. The read/write + * indexes are 64bit values and measured in bytes, they will never + * wrap. The current read/write index may be queried using + * pa_stream_get_timing_info() (see below for more information). In + * case of a buffer underrun the read index is equal or larger than + * the write index. Unless the prebuf value is 0, PulseAudio will + * temporarily pause playback in such a case, and wait until the + * buffer is filled up to prebuf bytes again. If prebuf is 0, the + * read index may be larger than the write index, in which case + * silence is played. If the application writes data to indexes lower + * than the read index, the data is immediately lost. + * + * \section transfer_sec Transferring Data + * + * Once the stream is up, data can start flowing between the client and the + * server. Two different access models can be used to transfer the data: + * + * \li Asynchronous - The application register a callback using + * pa_stream_set_write_callback() and + * pa_stream_set_read_callback() to receive notifications + * that data can either be written or read. + * \li Polled - Query the library for available data/space using + * pa_stream_writable_size() and pa_stream_readable_size() and + * transfer data as needed. The sizes are stored locally, in the + * client end, so there is no delay when reading them. + * + * It is also possible to mix the two models freely. + * + * Once there is data/space available, it can be transferred using either + * pa_stream_write() for playback, or pa_stream_peek() / pa_stream_drop() for + * record. Make sure you do not overflow the playback buffers as data will be + * dropped. + * + * \section bufctl_sec Buffer Control + * + * The transfer buffers can be controlled through a number of operations: + * + * \li pa_stream_cork() - Start or stop the playback or recording. + * \li pa_stream_trigger() - Start playback immediately and do not wait for + * the buffer to fill up to the set trigger level. + * \li pa_stream_prebuf() - Reenable the playback trigger level. + * \li pa_stream_drain() - Wait for the playback buffer to go empty. Will + * return a pa_operation object that will indicate when + * the buffer is completely drained. + * \li pa_stream_flush() - Drop all data from the playback or record buffer. Do not + * wait for it to finish playing. + * + * \section seek_modes Seeking in the Playback Buffer + * + * A client application may freely seek in the playback buffer. To + * accomplish that the pa_stream_write() function takes a seek mode + * and an offset argument. The seek mode is one of: + * + * \li PA_SEEK_RELATIVE - seek relative to the current write index + * \li PA_SEEK_ABSOLUTE - seek relative to the beginning of the playback buffer, (i.e. the first that was ever played in the stream) + * \li PA_SEEK_RELATIVE_ON_READ - seek relative to the current read index. Use this to write data to the output buffer that should be played as soon as possible + * \li PA_SEEK_RELATIVE_END - seek relative to the last byte ever written. + * + * If an application just wants to append some data to the output + * buffer, PA_SEEK_RELATIVE and an offset of 0 should be used. + * + * After a call to pa_stream_write() the write index will be left at + * the position right after the last byte of the written data. + * + * \section latency_sec Latency + * + * A major problem with networked audio is the increased latency caused by + * the network. To remedy this, PulseAudio supports an advanced system of + * monitoring the current latency. + * + * To get the raw data needed to calculate latencies, call + * pa_stream_get_timing_info(). This will give you a pa_timing_info + * structure that contains everything that is known about the server + * side buffer transport delays and the backend active in the + * server. (Besides other things it contains the write and read index + * values mentioned above.) + * + * This structure is updated every time a + * pa_stream_update_timing_info() operation is executed. (i.e. before + * the first call to this function the timing information structure is + * not available!) Since it is a lot of work to keep this structure + * up-to-date manually, PulseAudio can do that automatically for you: + * if PA_STREAM_AUTO_TIMING_UPDATE is passed when connecting the + * stream PulseAudio will automatically update the structure every + * 100ms and every time a function is called that might invalidate the + * previously known timing data (such as pa_stream_write() or + * pa_stream_flush()). Please note however, that there always is a + * short time window when the data in the timing information structure + * is out-of-date. PulseAudio tries to mark these situations by + * setting the write_index_corrupt and read_index_corrupt fields + * accordingly. + * + * The raw timing data in the pa_timing_info structure is usually hard + * to deal with. Therefore a simpler interface is available: + * you can call pa_stream_get_time() or pa_stream_get_latency(). The + * former will return the current playback time of the hardware since + * the stream has been started. The latter returns the overall time a sample + * that you write now takes to be played by the hardware. These two + * functions base their calculations on the same data that is returned + * by pa_stream_get_timing_info(). Hence the same rules for keeping + * the timing data up-to-date apply here. In case the write or read + * index is corrupted, these two functions will fail with + * -PA_ERR_NODATA set. + * + * Since updating the timing info structure usually requires a full + * network round trip and some applications monitor the timing very + * often PulseAudio offers a timing interpolation system. If + * PA_STREAM_INTERPOLATE_TIMING is passed when connecting the stream, + * pa_stream_get_time() and pa_stream_get_latency() will try to + * interpolate the current playback time/latency by estimating the + * number of samples that have been played back by the hardware since + * the last regular timing update. It is especially useful to combine + * this option with PA_STREAM_AUTO_TIMING_UPDATE, which will enable + * you to monitor the current playback time/latency very precisely and + * very frequently without requiring a network round trip every time. + * + * \section flow_sec Overflow and underflow + * + * Even with the best precautions, buffers will sometime over - or + * underflow. To handle this gracefully, the application can be + * notified when this happens. Callbacks are registered using + * pa_stream_set_overflow_callback() and + * pa_stream_set_underflow_callback(). + * + * \section sync_streams Synchronizing Multiple Playback Streams + * + * PulseAudio allows applications to fully synchronize multiple + * playback streams that are connected to the same output device. That + * means the streams will always be played back sample-by-sample + * synchronously. If stream operations like pa_stream_cork() are + * issued on one of the synchronized streams, they are simultaneously + * issued on the others. + * + * To synchronize a stream to another, just pass the "master" stream + * as last argument to pa_stream_connect_playback(). To make sure that + * the freshly created stream doesn't start playback right-away, make + * sure to pass PA_STREAM_START_CORKED and -- after all streams have + * been created -- uncork them all with a single call to + * pa_stream_cork() for the master stream. + * + * To make sure that a particular stream doesn't stop to play when a + * server side buffer underrun happens on it while the other + * synchronized streams continue playing and hence deviate, you need to + * pass a "prebuf" pa_buffer_attr of 0 when connecting it. + * + * \section disc_sec Disconnecting + * + * When a stream has served is purpose it must be disconnected with + * pa_stream_disconnect(). If you only unreference it, then it will live on + * and eat resources both locally and on the server until you disconnect the + * context. + * + */ + +/** \file + * Audio streams for input, output and sample upload + * + * See also \subpage streams + */ + +PA_C_DECL_BEGIN + +/** An opaque stream for playback or recording */ +typedef struct pa_stream pa_stream; + +/** A generic callback for operation completion */ +typedef void (*pa_stream_success_cb_t) (pa_stream*s, int success, void *userdata); + +/** A generic request callback */ +typedef void (*pa_stream_request_cb_t)(pa_stream *p, size_t nbytes, void *userdata); + +/** A generic notification callback */ +typedef void (*pa_stream_notify_cb_t)(pa_stream *p, void *userdata); + +/** A callback for asynchronous meta/policy event messages. Well known + * event names are PA_STREAM_EVENT_REQUEST_CORK and + * PA_STREAM_EVENT_REQUEST_UNCORK. The set of defined events can be + * extended at any time. Also, server modules may introduce additional + * message types so make sure that your callback function ignores messages + * it doesn't know. \since 0.9.15 */ +typedef void (*pa_stream_event_cb_t)(pa_stream *p, const char *name, pa_proplist *pl, void *userdata); + +/** Create a new, unconnected stream with the specified name and + * sample type. It is recommended to use pa_stream_new_with_proplist() + * instead and specify some initial properties. */ +pa_stream* pa_stream_new( + pa_context *c /**< The context to create this stream in */, + const char *name /**< A name for this stream */, + const pa_sample_spec *ss /**< The desired sample format */, + const pa_channel_map *map /**< The desired channel map, or NULL for default */); + +/** Create a new, unconnected stream with the specified name and + * sample type, and specify the initial stream property + * list. \since 0.9.11 */ +pa_stream* pa_stream_new_with_proplist( + pa_context *c /**< The context to create this stream in */, + const char *name /**< A name for this stream */, + const pa_sample_spec *ss /**< The desired sample format */, + const pa_channel_map *map /**< The desired channel map, or NULL for default */, + pa_proplist *p /**< The initial property list */); + +/** Create a new, unconnected stream with the specified name, the set of formats + * this client can provide, and an initial list of properties. While + * connecting, the server will select the most appropriate format which the + * client must then provide. \since 1.0 */ +pa_stream *pa_stream_new_extended( + pa_context *c /**< The context to create this stream in */, + const char *name /**< A name for this stream */, + pa_format_info * const * formats /**< The list of formats that can be provided */, + unsigned int n_formats /**< The number of formats being passed in */, + pa_proplist *p /**< The initial property list */); + +/** Decrease the reference counter by one. */ +void pa_stream_unref(pa_stream *s); + +/** Increase the reference counter by one. */ +pa_stream *pa_stream_ref(pa_stream *s); + +/** Return the current state of the stream. */ +pa_stream_state_t pa_stream_get_state(pa_stream *p); + +/** Return the context this stream is attached to. */ +pa_context* pa_stream_get_context(pa_stream *p); + +/** Return the sink input resp.\ source output index this stream is + * identified in the server with. This is useful with the + * introspection functions such as pa_context_get_sink_input_info() + * or pa_context_get_source_output_info(). */ +uint32_t pa_stream_get_index(pa_stream *s); + +/** Return the index of the sink or source this stream is connected to + * in the server. This is useful with the introspection + * functions such as pa_context_get_sink_info_by_index() or + * pa_context_get_source_info_by_index(). + * + * Please note that streams may be moved between sinks/sources and thus + * it is recommended to use pa_stream_set_moved_callback() to be notified + * about this. This function will return with -PA_ERR_NOTSUPPORTED when the + * server is older than 0.9.8. \since 0.9.8 */ +uint32_t pa_stream_get_device_index(pa_stream *s); + +/** Return the name of the sink or source this stream is connected to + * in the server. This is useful with the introspection + * functions such as pa_context_get_sink_info_by_name() + * or pa_context_get_source_info_by_name(). + * + * Please note that streams may be moved between sinks/sources and thus + * it is recommended to use pa_stream_set_moved_callback() to be notified + * about this. This function will return with -PA_ERR_NOTSUPPORTED when the + * server is older than 0.9.8. \since 0.9.8 */ +const char *pa_stream_get_device_name(pa_stream *s); + +/** Return 1 if the sink or source this stream is connected to has + * been suspended. This will return 0 if not, and a negative value on + * error. This function will return with -PA_ERR_NOTSUPPORTED when the + * server is older than 0.9.8. \since 0.9.8 */ +int pa_stream_is_suspended(pa_stream *s); + +/** Return 1 if the this stream has been corked. This will return 0 if + * not, and a negative value on error. \since 0.9.11 */ +int pa_stream_is_corked(pa_stream *s); + +/** Connect the stream to a sink. It is strongly recommended to pass + * NULL in both \a dev and \a volume and to set neither + * PA_STREAM_START_MUTED nor PA_STREAM_START_UNMUTED -- unless these + * options are directly dependent on user input or configuration. + * + * If you follow this rule then the sound server will have the full + * flexibility to choose the device, volume and mute status + * automatically, based on server-side policies, heuristics and stored + * information from previous uses. Also the server may choose to + * reconfigure audio devices to make other sinks/sources or + * capabilities available to be able to accept the stream. + * + * Before 0.9.20 it was not defined whether the \a volume parameter was + * interpreted relative to the sink's current volume or treated as + * an absolute device volume. Since 0.9.20 it is an absolute volume when + * the sink is in flat volume mode, and relative otherwise, thus + * making sure the volume passed here has always the same semantics as + * the volume passed to pa_context_set_sink_input_volume(). It is possible + * to figure out whether flat volume mode is in effect for a given sink + * by calling pa_context_get_sink_info_by_name(). + * + * Since 5.0, it's possible to specify a single-channel volume even if the + * stream has multiple channels. In that case the same volume is applied to all + * channels. */ +int pa_stream_connect_playback( + pa_stream *s /**< The stream to connect to a sink */, + const char *dev /**< Name of the sink to connect to, or NULL for default */ , + const pa_buffer_attr *attr /**< Buffering attributes, or NULL for default */, + pa_stream_flags_t flags /**< Additional flags, or 0 for default */, + const pa_cvolume *volume /**< Initial volume, or NULL for default */, + pa_stream *sync_stream /**< Synchronize this stream with the specified one, or NULL for a standalone stream */); + +/** Connect the stream to a source. */ +int pa_stream_connect_record( + pa_stream *s /**< The stream to connect to a source */ , + const char *dev /**< Name of the source to connect to, or NULL for default */, + const pa_buffer_attr *attr /**< Buffer attributes, or NULL for default */, + pa_stream_flags_t flags /**< Additional flags, or 0 for default */); + +/** Disconnect a stream from a source/sink. */ +int pa_stream_disconnect(pa_stream *s); + +/** Prepare writing data to the server (for playback streams). This + * function may be used to optimize the number of memory copies when + * doing playback ("zero-copy"). It is recommended to call this + * function before each call to pa_stream_write(). + * + * Pass in the address to a pointer and an address of the number of + * bytes you want to write. On return the two values will contain a + * pointer where you can place the data to write and the maximum number + * of bytes you can write. \a *nbytes can be smaller or have the same + * value as you passed in. You need to be able to handle both cases. + * Accessing memory beyond the returned \a *nbytes value is invalid. + * Accessing the memory returned after the following pa_stream_write() + * or pa_stream_cancel_write() is invalid. + * + * On invocation only \a *nbytes needs to be initialized, on return both + * *data and *nbytes will be valid. If you place (size_t) -1 in *nbytes + * on invocation the memory size will be chosen automatically (which is + * recommended to do). After placing your data in the memory area + * returned, call pa_stream_write() with \a data set to an address + * within this memory area and an \a nbytes value that is smaller or + * equal to what was returned by this function to actually execute the + * write. + * + * An invocation of pa_stream_write() should follow "quickly" on + * pa_stream_begin_write(). It is not recommended letting an unbounded + * amount of time pass after calling pa_stream_begin_write() and + * before calling pa_stream_write(). If you want to cancel a + * previously called pa_stream_begin_write() without calling + * pa_stream_write() use pa_stream_cancel_write(). Calling + * pa_stream_begin_write() twice without calling pa_stream_write() or + * pa_stream_cancel_write() in between will return exactly the same + * \a data pointer and \a nbytes values. \since 0.9.16 */ +int pa_stream_begin_write( + pa_stream *p, + void **data, + size_t *nbytes); + +/** Reverses the effect of pa_stream_begin_write() dropping all data + * that has already been placed in the memory area returned by + * pa_stream_begin_write(). Only valid to call if + * pa_stream_begin_write() was called before and neither + * pa_stream_cancel_write() nor pa_stream_write() have been called + * yet. Accessing the memory previously returned by + * pa_stream_begin_write() after this call is invalid. Any further + * explicit freeing of the memory area is not necessary. \since + * 0.9.16 */ +int pa_stream_cancel_write( + pa_stream *p); + +/** Write some data to the server (for playback streams). + * If \a free_cb is non-NULL this routine is called when all data has + * been written out. An internal reference to the specified data is + * kept, the data is not copied. If NULL, the data is copied into an + * internal buffer. + * + * The client may freely seek around in the output buffer. For + * most applications it is typical to pass 0 and PA_SEEK_RELATIVE + * as values for the arguments \a offset and \a seek. After the write + * call succeeded the write index will be at the position after where + * this chunk of data has been written to. + * + * As an optimization for avoiding needless memory copies you may call + * pa_stream_begin_write() before this call and then place your audio + * data directly in the memory area returned by that call. Then, pass + * a pointer to that memory area to pa_stream_write(). After the + * invocation of pa_stream_write() the memory area may no longer be + * accessed. Any further explicit freeing of the memory area is not + * necessary. It is OK to write the memory area returned by + * pa_stream_begin_write() only partially with this call, skipping + * bytes both at the end and at the beginning of the reserved memory + * area.*/ +int pa_stream_write( + pa_stream *p /**< The stream to use */, + const void *data /**< The data to write */, + size_t nbytes /**< The length of the data to write in bytes, must be in multiples of the stream's sample spec frame size */, + pa_free_cb_t free_cb /**< A cleanup routine for the data or NULL to request an internal copy */, + int64_t offset /**< Offset for seeking, must be 0 for upload streams, must be in multiples of the stream's sample spec frame size */, + pa_seek_mode_t seek /**< Seek mode, must be PA_SEEK_RELATIVE for upload streams */); + +/** Function does exactly the same as pa_stream_write() with the difference + * that free_cb_data is passed to free_cb instead of data. \since 6.0 */ +int pa_stream_write_ext_free( + pa_stream *p /**< The stream to use */, + const void *data /**< The data to write */, + size_t nbytes /**< The length of the data to write in bytes */, + pa_free_cb_t free_cb /**< A cleanup routine for the data or NULL to request an internal copy */, + void *free_cb_data /**< Argument passed to free_cb function */, + int64_t offset /**< Offset for seeking, must be 0 for upload streams */, + pa_seek_mode_t seek /**< Seek mode, must be PA_SEEK_RELATIVE for upload streams */); + +/** Read the next fragment from the buffer (for recording streams). + * If there is data at the current read index, \a data will point to + * the actual data and \a nbytes will contain the size of the data in + * bytes (which can be less or more than a complete fragment). + * + * If there is no data at the current read index, it means that either + * the buffer is empty or it contains a hole (that is, the write index + * is ahead of the read index but there's no data where the read index + * points at). If the buffer is empty, \a data will be NULL and + * \a nbytes will be 0. If there is a hole, \a data will be NULL and + * \a nbytes will contain the length of the hole. + * + * Use pa_stream_drop() to actually remove the data from the buffer + * and move the read index forward. pa_stream_drop() should not be + * called if the buffer is empty, but it should be called if there is + * a hole. */ +int pa_stream_peek( + pa_stream *p /**< The stream to use */, + const void **data /**< Pointer to pointer that will point to data */, + size_t *nbytes /**< The length of the data read in bytes */); + +/** Remove the current fragment on record streams. It is invalid to do this without first + * calling pa_stream_peek(). */ +int pa_stream_drop(pa_stream *p); + +/** Return the number of bytes requested by the server that have not yet + * been written. + * + * It is possible to write more than this amount, up to the stream's + * buffer_attr.maxlength bytes. This is usually not desirable, though, as + * it would increase stream latency to be higher than requested + * (buffer_attr.tlength). + */ +size_t pa_stream_writable_size(pa_stream *p); + +/** Return the number of bytes that may be read using pa_stream_peek(). */ +size_t pa_stream_readable_size(pa_stream *p); + +/** Drain a playback stream. Use this for notification when the + * playback buffer is empty after playing all the audio in the buffer. + * Please note that only one drain operation per stream may be issued + * at a time. */ +pa_operation* pa_stream_drain(pa_stream *s, pa_stream_success_cb_t cb, void *userdata); + +/** Request a timing info structure update for a stream. Use + * pa_stream_get_timing_info() to get access to the raw timing data, + * or pa_stream_get_time() or pa_stream_get_latency() to get cleaned + * up values. */ +pa_operation* pa_stream_update_timing_info(pa_stream *p, pa_stream_success_cb_t cb, void *userdata); + +/** Set the callback function that is called whenever the state of the stream changes. */ +void pa_stream_set_state_callback(pa_stream *s, pa_stream_notify_cb_t cb, void *userdata); + +/** Set the callback function that is called when new data may be + * written to the stream. */ +void pa_stream_set_write_callback(pa_stream *p, pa_stream_request_cb_t cb, void *userdata); + +/** Set the callback function that is called when new data is available from the stream. */ +void pa_stream_set_read_callback(pa_stream *p, pa_stream_request_cb_t cb, void *userdata); + +/** Set the callback function that is called when a buffer overflow happens. (Only for playback streams) */ +void pa_stream_set_overflow_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata); + +/** Return at what position the latest underflow occurred, or -1 if this information is not + * known (e.g.\ if no underflow has occurred, or server is older than 1.0). + * Can be used inside the underflow callback to get information about the current underflow. + * (Only for playback streams) \since 1.0 */ +int64_t pa_stream_get_underflow_index(pa_stream *p); + +/** Set the callback function that is called when a buffer underflow happens. (Only for playback streams) */ +void pa_stream_set_underflow_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata); + +/** Set the callback function that is called when a the server starts + * playback after an underrun or on initial startup. This only informs + * that audio is flowing again, it is no indication that audio started + * to reach the speakers already. (Only for playback streams) \since + * 0.9.11 */ +void pa_stream_set_started_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata); + +/** Set the callback function that is called whenever a latency + * information update happens. Useful on PA_STREAM_AUTO_TIMING_UPDATE + * streams only. */ +void pa_stream_set_latency_update_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata); + +/** Set the callback function that is called whenever the stream is + * moved to a different sink/source. Use pa_stream_get_device_name() or + * pa_stream_get_device_index() to query the new sink/source. This + * notification is only generated when the server is at least + * 0.9.8. \since 0.9.8 */ +void pa_stream_set_moved_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata); + +/** Set the callback function that is called whenever the sink/source + * this stream is connected to is suspended or resumed. Use + * pa_stream_is_suspended() to query the new suspend status. Please + * note that the suspend status might also change when the stream is + * moved between devices. Thus if you call this function you very + * likely want to call pa_stream_set_moved_callback() too. This + * notification is only generated when the server is at least + * 0.9.8. \since 0.9.8 */ +void pa_stream_set_suspended_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata); + +/** Set the callback function that is called whenever a meta/policy + * control event is received. \since 0.9.15 */ +void pa_stream_set_event_callback(pa_stream *p, pa_stream_event_cb_t cb, void *userdata); + +/** Set the callback function that is called whenever the buffer + * attributes on the server side change. Please note that the buffer + * attributes can change when moving a stream to a different + * sink/source too, hence if you use this callback you should use + * pa_stream_set_moved_callback() as well. \since 0.9.15 */ +void pa_stream_set_buffer_attr_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata); + +/** Pause (or resume) playback of this stream temporarily. Available + * on both playback and recording streams. If \a b is 1 the stream is + * paused. If \a b is 0 the stream is resumed. The pause/resume operation + * is executed as quickly as possible. If a cork is very quickly + * followed by an uncork or the other way round, this might not + * actually have any effect on the stream that is output. You can use + * pa_stream_is_corked() to find out whether the stream is currently + * paused or not. Normally a stream will be created in uncorked + * state. If you pass PA_STREAM_START_CORKED as a flag when connecting + * the stream, it will be created in corked state. */ +pa_operation* pa_stream_cork(pa_stream *s, int b, pa_stream_success_cb_t cb, void *userdata); + +/** Flush the playback or record buffer of this stream. This discards any audio data + * in the buffer. Most of the time you're better off using the parameter + * \a seek of pa_stream_write() instead of this function. */ +pa_operation* pa_stream_flush(pa_stream *s, pa_stream_success_cb_t cb, void *userdata); + +/** Reenable prebuffering if specified in the pa_buffer_attr + * structure. Available for playback streams only. */ +pa_operation* pa_stream_prebuf(pa_stream *s, pa_stream_success_cb_t cb, void *userdata); + +/** Request immediate start of playback on this stream. This disables + * prebuffering temporarily if specified in the pa_buffer_attr structure. + * Available for playback streams only. */ +pa_operation* pa_stream_trigger(pa_stream *s, pa_stream_success_cb_t cb, void *userdata); + +/** Rename the stream. */ +pa_operation* pa_stream_set_name(pa_stream *s, const char *name, pa_stream_success_cb_t cb, void *userdata); + +/** Return the current playback/recording time. This is based on the + * data in the timing info structure returned by + * pa_stream_get_timing_info(). + * + * This function will usually only return new data if a timing info + * update has been received. Only if timing interpolation has been + * requested (PA_STREAM_INTERPOLATE_TIMING) the data from the last + * timing update is used for an estimation of the current + * playback/recording time based on the local time that passed since + * the timing info structure has been acquired. + * + * The time value returned by this function is guaranteed to increase + * monotonically (the returned value is always greater + * or equal to the value returned by the last call). This behaviour + * can be disabled by using PA_STREAM_NOT_MONOTONIC. This may be + * desirable to better deal with bad estimations of transport + * latencies, but may have strange effects if the application is not + * able to deal with time going 'backwards'. + * + * The time interpolator activated by PA_STREAM_INTERPOLATE_TIMING + * favours 'smooth' time graphs over accurate ones to improve the + * smoothness of UI operations that are tied to the audio clock. If + * accuracy is more important to you, you might need to estimate your + * timing based on the data from pa_stream_get_timing_info() yourself + * or not work with interpolated timing at all and instead always + * query the server side for the most up to date timing with + * pa_stream_update_timing_info(). + * + * If no timing information has been + * received yet this call will return -PA_ERR_NODATA. For more details + * see pa_stream_get_timing_info(). */ +int pa_stream_get_time(pa_stream *s, pa_usec_t *r_usec); + +/** Determine the total stream latency. This function is based on + * pa_stream_get_time(). + * + * The latency is stored in \a *r_usec. In case the stream is a + * monitoring stream the result can be negative, i.e. the captured + * samples are not yet played. In this case \a *negative is set to 1. + * + * If no timing information has been received yet, this call will + * return -PA_ERR_NODATA. On success, it will return 0. + * + * For more details see pa_stream_get_timing_info() and + * pa_stream_get_time(). */ +int pa_stream_get_latency(pa_stream *s, pa_usec_t *r_usec, int *negative); + +/** Return the latest raw timing data structure. The returned pointer + * refers to an internal read-only instance of the timing + * structure. The user should make a copy of this structure if he + * wants to modify it. An in-place update to this data structure may + * be requested using pa_stream_update_timing_info(). + * + * If no timing information has been received before (i.e. by + * requesting pa_stream_update_timing_info() or by using + * PA_STREAM_AUTO_TIMING_UPDATE), this function will fail with + * -PA_ERR_NODATA. + * + * Please note that the write_index member field (and only this field) + * is updated on each pa_stream_write() call, not just when a timing + * update has been received. */ +const pa_timing_info* pa_stream_get_timing_info(pa_stream *s); + +/** Return a pointer to the stream's sample specification. */ +const pa_sample_spec* pa_stream_get_sample_spec(pa_stream *s); + +/** Return a pointer to the stream's channel map. */ +const pa_channel_map* pa_stream_get_channel_map(pa_stream *s); + +/** Return a pointer to the stream's format. \since 1.0 */ +const pa_format_info* pa_stream_get_format_info(pa_stream *s); + +/** Return the per-stream server-side buffer metrics of the + * stream. Only valid after the stream has been connected successfully + * and if the server is at least PulseAudio 0.9. This will return the + * actual configured buffering metrics, which may differ from what was + * requested during pa_stream_connect_record() or + * pa_stream_connect_playback(). This call will always return the + * actual per-stream server-side buffer metrics, regardless whether + * PA_STREAM_ADJUST_LATENCY is set or not. \since 0.9.0 */ +const pa_buffer_attr* pa_stream_get_buffer_attr(pa_stream *s); + +/** Change the buffer metrics of the stream during playback. The + * server might have chosen different buffer metrics then + * requested. The selected metrics may be queried with + * pa_stream_get_buffer_attr() as soon as the callback is called. Only + * valid after the stream has been connected successfully and if the + * server is at least PulseAudio 0.9.8. Please be aware of the + * slightly different semantics of the call depending whether + * PA_STREAM_ADJUST_LATENCY is set or not. \since 0.9.8 */ +pa_operation *pa_stream_set_buffer_attr(pa_stream *s, const pa_buffer_attr *attr, pa_stream_success_cb_t cb, void *userdata); + +/** Change the stream sampling rate during playback. You need to pass + * PA_STREAM_VARIABLE_RATE in the flags parameter of + * pa_stream_connect_playback() if you plan to use this function. Only valid + * after the stream has been connected successfully and if the server + * is at least PulseAudio 0.9.8. \since 0.9.8 */ +pa_operation *pa_stream_update_sample_rate(pa_stream *s, uint32_t rate, pa_stream_success_cb_t cb, void *userdata); + +/** Update the property list of the sink input/source output of this + * stream, adding new entries. Please note that it is highly + * recommended to set as many properties initially via + * pa_stream_new_with_proplist() as possible instead a posteriori with + * this function, since that information may be used to route + * this stream to the right device. \since 0.9.11 */ +pa_operation *pa_stream_proplist_update(pa_stream *s, pa_update_mode_t mode, pa_proplist *p, pa_stream_success_cb_t cb, void *userdata); + +/** Update the property list of the sink input/source output of this + * stream, remove entries. \since 0.9.11 */ +pa_operation *pa_stream_proplist_remove(pa_stream *s, const char *const keys[], pa_stream_success_cb_t cb, void *userdata); + +/** For record streams connected to a monitor source: monitor only a + * very specific sink input of the sink. This function needs to be + * called before pa_stream_connect_record() is called. \since + * 0.9.11 */ +int pa_stream_set_monitor_stream(pa_stream *s, uint32_t sink_input_idx); + +/** Return the sink input index previously set with + * pa_stream_set_monitor_stream(). + * \since 0.9.11 */ +uint32_t pa_stream_get_monitor_stream(pa_stream *s); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/subscribe.h b/thirdparty/linuxbsd_headers/pulse/subscribe.h new file mode 100644 index 0000000000..b43c8ea44e --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/subscribe.h @@ -0,0 +1,83 @@ +#ifndef foosubscribehfoo +#define foosubscribehfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <inttypes.h> + +#include <pulse/def.h> +#include <pulse/context.h> +#include <pulse/cdecl.h> +#include <pulse/version.h> + +/** \page subscribe Event Subscription + * + * \section overv_sec Overview + * + * The application can be notified, asynchronously, whenever the internal + * layout of the server changes. Possible notifications are described in the + * \ref pa_subscription_event_type and \ref pa_subscription_mask + * enumerations. + * + * The application sets the notification mask using pa_context_subscribe() + * and the function that will be called whenever a notification occurs using + * pa_context_set_subscribe_callback(). + * + * The callback will be called with a \ref pa_subscription_event_type_t + * representing the event that caused the callback. Clients can examine what + * object changed using \ref PA_SUBSCRIPTION_EVENT_FACILITY_MASK. The actual + * event type can then be extracted with \ref PA_SUBSCRIPTION_EVENT_TYPE_MASK. + * Please note that the masked values are integers, not flags (so you will + * check the object/event type using a comparison not a binary AND). For + * example, the callback might look something like: + * +@verbatim +void my_subscription_callback(pa_context *c, pa_subscription_event_type_t t, + uint32_t idx, void *userdata) { + if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE) { + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { + ... a source was added, let's do stuff! ... + } + } +} +@endverbatim + */ + +/** \file + * Daemon introspection event subscription subsystem. + * + * See also \subpage subscribe + */ + +PA_C_DECL_BEGIN + +/** Subscription event callback prototype */ +typedef void (*pa_context_subscribe_cb_t)(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata); + +/** Enable event notification */ +pa_operation* pa_context_subscribe(pa_context *c, pa_subscription_mask_t m, pa_context_success_cb_t cb, void *userdata); + +/** Set the context specific call back function that is called whenever the state of the daemon changes */ +void pa_context_set_subscribe_callback(pa_context *c, pa_context_subscribe_cb_t cb, void *userdata); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/thread-mainloop.h b/thirdparty/linuxbsd_headers/pulse/thread-mainloop.h new file mode 100644 index 0000000000..e69298aa07 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/thread-mainloop.h @@ -0,0 +1,317 @@ +#ifndef foothreadmainloophfoo +#define foothreadmainloophfoo + +/*** + This file is part of PulseAudio. + + Copyright 2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <pulse/mainloop-api.h> +#include <pulse/cdecl.h> +#include <pulse/version.h> + +PA_C_DECL_BEGIN + +/** \page threaded_mainloop Threaded Main Loop + * + * \section overv_sec Overview + * + * The threaded main loop implementation is a special version of the primary + * main loop implementation (see \ref mainloop). For the basic design, see + * its documentation. + * + * The added feature in the threaded main loop is that it spawns a new thread + * that runs the real main loop. This allows a synchronous application to use + * the asynchronous API without risking to stall the PulseAudio library. + * + * \section creat_sec Creation + * + * A pa_threaded_mainloop object is created using pa_threaded_mainloop_new(). + * This will only allocate the required structures though, so to use it the + * thread must also be started. This is done through + * pa_threaded_mainloop_start(), after which you can start using the main loop. + * + * \section destr_sec Destruction + * + * When the PulseAudio connection has been terminated, the thread must be + * stopped and the resources freed. Stopping the thread is done using + * pa_threaded_mainloop_stop(), which must be called without the lock (see + * below) held. When that function returns, the thread is stopped and the + * pa_threaded_mainloop object can be freed using pa_threaded_mainloop_free(). + * + * \section lock_sec Locking + * + * Since the PulseAudio API doesn't allow concurrent accesses to objects, + * a locking scheme must be used to guarantee safe usage. The threaded main + * loop API provides such a scheme through the functions + * pa_threaded_mainloop_lock() and pa_threaded_mainloop_unlock(). + * + * The lock is recursive, so it's safe to use it multiple times from the same + * thread. Just make sure you call pa_threaded_mainloop_unlock() the same + * number of times you called pa_threaded_mainloop_lock(). + * + * The lock needs to be held whenever you call any PulseAudio function that + * uses an object associated with this main loop. Make sure you do not hold + * on to the lock more than necessary though, as the threaded main loop stops + * while the lock is held. + * + * Example: + * + * \code + * void my_check_stream_func(pa_threaded_mainloop *m, pa_stream *s) { + * pa_stream_state_t state; + * + * pa_threaded_mainloop_lock(m); + * + * state = pa_stream_get_state(s); + * + * pa_threaded_mainloop_unlock(m); + * + * if (state == PA_STREAM_READY) + * printf("Stream is ready!"); + * else + * printf("Stream is not ready!"); + * } + * \endcode + * + * \section cb_sec Callbacks + * + * Callbacks in PulseAudio are asynchronous, so they require extra care when + * using them together with a threaded main loop. + * + * The easiest way to turn the callback based operations into synchronous + * ones, is to simply wait for the callback to be called and continue from + * there. This is the approach chosen in PulseAudio's threaded API. + * + * \subsection basic_subsec Basic callbacks + * + * For the basic case, where all that is required is to wait for the callback + * to be invoked, the code should look something like this: + * + * Example: + * + * \code + * static void my_drain_callback(pa_stream *s, int success, void *userdata) { + * pa_threaded_mainloop *m; + * + * m = userdata; + * assert(m); + * + * pa_threaded_mainloop_signal(m, 0); + * } + * + * void my_drain_stream_func(pa_threaded_mainloop *m, pa_stream *s) { + * pa_operation *o; + * + * pa_threaded_mainloop_lock(m); + * + * o = pa_stream_drain(s, my_drain_callback, m); + * assert(o); + * + * while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) + * pa_threaded_mainloop_wait(m); + * + * pa_operation_unref(o); + * + * pa_threaded_mainloop_unlock(m); + * } + * \endcode + * + * The main function, my_drain_stream_func(), will wait for the callback to + * be called using pa_threaded_mainloop_wait(). + * + * If your application is multi-threaded, then this waiting must be + * done inside a while loop. The reason for this is that multiple + * threads might be using pa_threaded_mainloop_wait() at the same + * time. Each thread must therefore verify that it was its callback + * that was invoked. Also the underlying OS synchronization primitives + * are usually not free of spurious wake-ups, so a + * pa_threaded_mainloop_wait() must be called within a loop even if + * you have only one thread waiting. + * + * The callback, my_drain_callback(), indicates to the main function that it + * has been called using pa_threaded_mainloop_signal(). + * + * As you can see, pa_threaded_mainloop_wait() may only be called with + * the lock held. The same thing is true for pa_threaded_mainloop_signal(), + * but as the lock is held before the callback is invoked, you do not have to + * deal with that. + * + * The functions will not dead lock because the wait function will release + * the lock before waiting and then regrab it once it has been signalled. + * For those of you familiar with threads, the behaviour is that of a + * condition variable. + * + * \subsection data_subsec Data callbacks + * + * For many callbacks, simply knowing that they have been called is + * insufficient. The callback also receives some data that is desired. To + * access this data safely, we must extend our example a bit: + * + * \code + * static int * volatile drain_result = NULL; + * + * static void my_drain_callback(pa_stream*s, int success, void *userdata) { + * pa_threaded_mainloop *m; + * + * m = userdata; + * assert(m); + * + * drain_result = &success; + * + * pa_threaded_mainloop_signal(m, 1); + * } + * + * void my_drain_stream_func(pa_threaded_mainloop *m, pa_stream *s) { + * pa_operation *o; + * + * pa_threaded_mainloop_lock(m); + * + * o = pa_stream_drain(s, my_drain_callback, m); + * assert(o); + * + * while (drain_result == NULL) + * pa_threaded_mainloop_wait(m); + * + * pa_operation_unref(o); + * + * if (*drain_result) + * printf("Success!"); + * else + * printf("Bitter defeat..."); + * + * pa_threaded_mainloop_accept(m); + * + * pa_threaded_mainloop_unlock(m); + * } + * \endcode + * + * The example is a bit silly as it would probably have been easier to just + * copy the contents of success, but for larger data structures this can be + * wasteful. + * + * The difference here compared to the basic callback is the value 1 passed + * to pa_threaded_mainloop_signal() and the call to + * pa_threaded_mainloop_accept(). What will happen is that + * pa_threaded_mainloop_signal() will signal the main function and then wait. + * The main function is then free to use the data in the callback until + * pa_threaded_mainloop_accept() is called, which will allow the callback + * to continue. + * + * Note that pa_threaded_mainloop_accept() must be called some time between + * exiting the while loop and unlocking the main loop! Failure to do so will + * result in a race condition. I.e. it is not ok to release the lock and + * regrab it before calling pa_threaded_mainloop_accept(). + * + * \subsection async_subsec Asynchronous callbacks + * + * PulseAudio also has callbacks that are completely asynchronous, meaning + * that they can be called at any time. The threaded main loop API provides + * the locking mechanism to handle concurrent accesses, but nothing else. + * Applications will have to handle communication from the callback to the + * main program through their own mechanisms. + * + * The callbacks that are completely asynchronous are: + * + * \li State callbacks for contexts, streams, etc. + * \li Subscription notifications + */ + +/** \file + * + * A thread based event loop implementation based on pa_mainloop. The + * event loop is run in a helper thread in the background. A few + * synchronization primitives are available to access the objects + * attached to the event loop safely. + * + * See also \subpage threaded_mainloop + */ + +/** An opaque threaded main loop object */ +typedef struct pa_threaded_mainloop pa_threaded_mainloop; + +/** Allocate a new threaded main loop object. You have to call + * pa_threaded_mainloop_start() before the event loop thread starts + * running. */ +pa_threaded_mainloop *pa_threaded_mainloop_new(void); + +/** Free a threaded main loop object. If the event loop thread is + * still running, terminate it with pa_threaded_mainloop_stop() + * first. */ +void pa_threaded_mainloop_free(pa_threaded_mainloop* m); + +/** Start the event loop thread. */ +int pa_threaded_mainloop_start(pa_threaded_mainloop *m); + +/** Terminate the event loop thread cleanly. Make sure to unlock the + * mainloop object before calling this function. */ +void pa_threaded_mainloop_stop(pa_threaded_mainloop *m); + +/** Lock the event loop object, effectively blocking the event loop + * thread from processing events. You can use this to enforce + * exclusive access to all objects attached to the event loop. This + * lock is recursive. This function may not be called inside the event + * loop thread. Events that are dispatched from the event loop thread + * are executed with this lock held. */ +void pa_threaded_mainloop_lock(pa_threaded_mainloop *m); + +/** Unlock the event loop object, inverse of pa_threaded_mainloop_lock(). */ +void pa_threaded_mainloop_unlock(pa_threaded_mainloop *m); + +/** Wait for an event to be signalled by the event loop thread. You + * can use this to pass data from the event loop thread to the main + * thread in a synchronized fashion. This function may not be called + * inside the event loop thread. Prior to this call the event loop + * object needs to be locked using pa_threaded_mainloop_lock(). While + * waiting the lock will be released. Immediately before returning it + * will be acquired again. This function may spuriously wake up even + * without pa_threaded_mainloop_signal() being called. You need to + * make sure to handle that! */ +void pa_threaded_mainloop_wait(pa_threaded_mainloop *m); + +/** Signal all threads waiting for a signalling event in + * pa_threaded_mainloop_wait(). If wait_for_accept is non-zero, do + * not return before the signal was accepted by a + * pa_threaded_mainloop_accept() call. While waiting for that condition + * the event loop object is unlocked. */ +void pa_threaded_mainloop_signal(pa_threaded_mainloop *m, int wait_for_accept); + +/** Accept a signal from the event thread issued with + * pa_threaded_mainloop_signal(). This call should only be used in + * conjunction with pa_threaded_mainloop_signal() with a non-zero + * wait_for_accept value. */ +void pa_threaded_mainloop_accept(pa_threaded_mainloop *m); + +/** Return the return value as specified with the main loop's + * pa_mainloop_quit() routine. */ +int pa_threaded_mainloop_get_retval(pa_threaded_mainloop *m); + +/** Return the main loop abstraction layer vtable for this main loop. + * There is no need to free this object as it is owned by the loop + * and is destroyed when the loop is freed. */ +pa_mainloop_api* pa_threaded_mainloop_get_api(pa_threaded_mainloop*m); + +/** Returns non-zero when called from within the event loop thread. \since 0.9.7 */ +int pa_threaded_mainloop_in_thread(pa_threaded_mainloop *m); + +/** Sets the name of the thread. \since 5.0 */ +void pa_threaded_mainloop_set_name(pa_threaded_mainloop *m, const char *name); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/timeval.h b/thirdparty/linuxbsd_headers/pulse/timeval.h new file mode 100644 index 0000000000..9ecf791127 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/timeval.h @@ -0,0 +1,87 @@ +#ifndef footimevalhfoo +#define footimevalhfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <pulse/cdecl.h> +#include <pulse/gccmacro.h> +#include <pulse/sample.h> +#include <pulse/version.h> + +/** \file + * Utility functions for handling timeval calculations */ + +PA_C_DECL_BEGIN + +/** The number of milliseconds in a second */ +#define PA_MSEC_PER_SEC ((pa_usec_t) 1000ULL) + +/** The number of microseconds in a second */ +#define PA_USEC_PER_SEC ((pa_usec_t) 1000000ULL) + +/** The number of nanoseconds in a second */ +#define PA_NSEC_PER_SEC ((unsigned long long) 1000000000ULL) + +/** The number of microseconds in a millisecond */ +#define PA_USEC_PER_MSEC ((pa_usec_t) 1000ULL) + +/** The number of nanoseconds in a millisecond */ +#define PA_NSEC_PER_MSEC ((unsigned long long) 1000000ULL) + +/** The number of nanoseconds in a microsecond */ +#define PA_NSEC_PER_USEC ((unsigned long long) 1000ULL) + +/** Invalid time in usec. \since 0.9.15 */ +#define PA_USEC_INVALID ((pa_usec_t) -1) + +/** Biggest time in usec. \since 0.9.18 */ +#define PA_USEC_MAX ((pa_usec_t) -2) + +struct timeval; + +/** Return the current wallclock timestamp, just like UNIX gettimeofday(). */ +struct timeval *pa_gettimeofday(struct timeval *tv); + +/** Calculate the difference between the two specified timeval + * structs. */ +pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) PA_GCC_PURE; + +/** Compare the two timeval structs and return 0 when equal, negative when a < b, positive otherwise */ +int pa_timeval_cmp(const struct timeval *a, const struct timeval *b) PA_GCC_PURE; + +/** Return the time difference between now and the specified timestamp */ +pa_usec_t pa_timeval_age(const struct timeval *tv); + +/** Add the specified time in microseconds to the specified timeval structure */ +struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v); + +/** Subtract the specified time in microseconds to the specified timeval structure. \since 0.9.11 */ +struct timeval* pa_timeval_sub(struct timeval *tv, pa_usec_t v); + +/** Store the specified usec value in the timeval struct. \since 0.9.7 */ +struct timeval* pa_timeval_store(struct timeval *tv, pa_usec_t v); + +/** Load the specified tv value and return it in usec. \since 0.9.7 */ +pa_usec_t pa_timeval_load(const struct timeval *tv); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/utf8.h b/thirdparty/linuxbsd_headers/pulse/utf8.h new file mode 100644 index 0000000000..a72097ad51 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/utf8.h @@ -0,0 +1,54 @@ +#ifndef fooutf8hfoo +#define fooutf8hfoo + +/*** + This file is part of PulseAudio. + + Copyright 2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <pulse/cdecl.h> +#include <pulse/gccmacro.h> +#include <pulse/version.h> + +/** \file + * UTF-8 validation functions + */ + +PA_C_DECL_BEGIN + +/** Test if the specified strings qualifies as valid UTF8. Return the string if so, otherwise NULL */ +char *pa_utf8_valid(const char *str) PA_GCC_PURE; + +/** Test if the specified strings qualifies as valid 7-bit ASCII. Return the string if so, otherwise NULL. \since 0.9.15 */ +char *pa_ascii_valid(const char *str) PA_GCC_PURE; + +/** Filter all invalid UTF8 characters from the specified string, returning a new fully UTF8 valid string. Don't forget to free the returned string with pa_xfree() */ +char *pa_utf8_filter(const char *str); + +/** Filter all invalid ASCII characters from the specified string, returning a new fully ASCII valid string. Don't forget to free the returned string with pa_xfree(). \since 0.9.15 */ +char *pa_ascii_filter(const char *str); + +/** Convert a UTF-8 string to the current locale. Free the string using pa_xfree(). */ +char* pa_utf8_to_locale (const char *str); + +/** Convert a string in the current locale to UTF-8. Free the string using pa_xfree(). */ +char* pa_locale_to_utf8 (const char *str); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/util.h b/thirdparty/linuxbsd_headers/pulse/util.h new file mode 100644 index 0000000000..e4a62da65b --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/util.h @@ -0,0 +1,59 @@ +#ifndef fooutilhfoo +#define fooutilhfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <stddef.h> + +#include <pulse/cdecl.h> +#include <pulse/version.h> + +/** \file + * Assorted utility functions */ + +PA_C_DECL_BEGIN + +/** Return the current username in the specified string buffer. */ +char *pa_get_user_name(char *s, size_t l); + +/** Return the current hostname in the specified buffer. */ +char *pa_get_host_name(char *s, size_t l); + +/** Return the fully qualified domain name in s */ +char *pa_get_fqdn(char *s, size_t l); + +/** Return the home directory of the current user */ +char *pa_get_home_dir(char *s, size_t l); + +/** Return the binary file name of the current process. This is not + * supported on all architectures, in which case NULL is returned. */ +char *pa_get_binary_name(char *s, size_t l); + +/** Return a pointer to the filename inside a path (which is the last + * component). If passed NULL will return NULL. */ +char *pa_path_get_filename(const char *p); + +/** Wait t milliseconds */ +int pa_msleep(unsigned long t); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/version.h b/thirdparty/linuxbsd_headers/pulse/version.h new file mode 100644 index 0000000000..2738cfe902 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/version.h @@ -0,0 +1,70 @@ +#ifndef fooversionhfoo /*-*-C-*-*/ +#define fooversionhfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +/* WARNING: Make sure to edit the real source file version.h.in! */ + +#include <pulse/cdecl.h> + +/** \file + * Define header version */ + +PA_C_DECL_BEGIN + +/** Return the version of the header files. Keep in mind that this is +a macro and not a function, so it is impossible to get the pointer of +it. */ +#define pa_get_headers_version() ("11.1.0") + +/** Return the version of the library the current application is + * linked to. */ +const char* pa_get_library_version(void); + +/** The current API version. Version 6 relates to Polypaudio + * 0.6. Prior versions (i.e. Polypaudio 0.5.1 and older) have + * PA_API_VERSION undefined. Please note that this is only ever + * increased on incompatible API changes! */ +#define PA_API_VERSION 12 + +/** The current protocol version. Version 8 relates to Polypaudio + * 0.8/PulseAudio 0.9. */ +#define PA_PROTOCOL_VERSION 32 + +/** The major version of PA. \since 0.9.15 */ +#define PA_MAJOR 11 + +/** The minor version of PA. \since 0.9.15 */ +#define PA_MINOR 1 + +/** The micro version of PA (will always be 0 from v1.0 onwards). \since 0.9.15 */ +#define PA_MICRO 0 + +/** Evaluates to TRUE if the PulseAudio library version is equal or + * newer than the specified. \since 0.9.16 */ +#define PA_CHECK_VERSION(major,minor,micro) \ + ((PA_MAJOR > (major)) || \ + (PA_MAJOR == (major) && PA_MINOR > (minor)) || \ + (PA_MAJOR == (major) && PA_MINOR == (minor) && PA_MICRO >= (micro))) + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/volume.h b/thirdparty/linuxbsd_headers/pulse/volume.h new file mode 100644 index 0000000000..8cf4fa45b6 --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/volume.h @@ -0,0 +1,436 @@ +#ifndef foovolumehfoo +#define foovolumehfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <inttypes.h> +#include <limits.h> + +#include <pulse/cdecl.h> +#include <pulse/gccmacro.h> +#include <pulse/sample.h> +#include <pulse/channelmap.h> +#include <pulse/version.h> + +/** \page volume Volume Control + * + * \section overv_sec Overview + * + * Sinks, sources, sink inputs and samples can all have their own volumes. + * To deal with these, The PulseAudio library contains a number of functions + * that ease handling. + * + * The basic volume type in PulseAudio is the \ref pa_volume_t type. Most of + * the time, applications will use the aggregated pa_cvolume structure that + * can store the volume of all channels at once. + * + * Volumes commonly span between muted (0%), and normal (100%). It is possible + * to set volumes to higher than 100%, but clipping might occur. + * + * There is no single well-defined meaning attached to the 100% volume for a + * sink input. In fact, it depends on the server configuration. With flat + * volumes enabled (the default in most Linux distributions), it means the + * maximum volume that the sound hardware is capable of, which is usually so + * high that you absolutely must not set sink input volume to 100% unless the + * the user explicitly requests that (note that usually you shouldn't set the + * volume anyway if the user doesn't explicitly request it, instead, let + * PulseAudio decide the volume for the sink input). With flat volumes disabled + * (the default in Ubuntu), the sink input volume is relative to the sink + * volume, so 100% sink input volume means that the sink input is played at the + * current sink volume level. In this case 100% is often a good default volume + * for a sink input, although you still should let PulseAudio decide the + * default volume. It is possible to figure out whether flat volume mode is in + * effect for a given sink by calling pa_context_get_sink_info_by_name(). + * + * \section calc_sec Calculations + * + * The volumes in PulseAudio are logarithmic in nature and applications + * shouldn't perform calculations with them directly. Instead, they should + * be converted to and from either dB or a linear scale: + * + * \li dB - pa_sw_volume_from_dB() / pa_sw_volume_to_dB() + * \li Linear - pa_sw_volume_from_linear() / pa_sw_volume_to_linear() + * + * For simple multiplication, pa_sw_volume_multiply() and + * pa_sw_cvolume_multiply() can be used. + * + * Calculations can only be reliably performed on software volumes + * as it is commonly unknown what scale hardware volumes relate to. + * + * The functions described above are only valid when used with + * software volumes. Hence it is usually a better idea to treat all + * volume values as opaque with a range from PA_VOLUME_MUTED (0%) to + * PA_VOLUME_NORM (100%) and to refrain from any calculations with + * them. + * + * \section conv_sec Convenience Functions + * + * To handle the pa_cvolume structure, the PulseAudio library provides a + * number of convenience functions: + * + * \li pa_cvolume_valid() - Tests if a pa_cvolume structure is valid. + * \li pa_cvolume_equal() - Tests if two pa_cvolume structures are identical. + * \li pa_cvolume_channels_equal_to() - Tests if all channels of a pa_cvolume + * structure have a given volume. + * \li pa_cvolume_is_muted() - Tests if all channels of a pa_cvolume + * structure are muted. + * \li pa_cvolume_is_norm() - Tests if all channels of a pa_cvolume structure + * are at a normal volume. + * \li pa_cvolume_set() - Set the first n channels of a pa_cvolume structure to + * a certain volume. + * \li pa_cvolume_reset() - Set the first n channels of a pa_cvolume structure + * to a normal volume. + * \li pa_cvolume_mute() - Set the first n channels of a pa_cvolume structure + * to a muted volume. + * \li pa_cvolume_avg() - Return the average volume of all channels. + * \li pa_cvolume_snprint() - Pretty print a pa_cvolume structure. + */ + +/** \file + * Constants and routines for volume handling + * + * See also \subpage volume + */ + +PA_C_DECL_BEGIN + +/** Volume specification: + * PA_VOLUME_MUTED: silence; + * < PA_VOLUME_NORM: decreased volume; + * PA_VOLUME_NORM: normal volume; + * > PA_VOLUME_NORM: increased volume */ +typedef uint32_t pa_volume_t; + +/** Normal volume (100%, 0 dB) */ +#define PA_VOLUME_NORM ((pa_volume_t) 0x10000U) + +/** Muted (minimal valid) volume (0%, -inf dB) */ +#define PA_VOLUME_MUTED ((pa_volume_t) 0U) + +/** Maximum valid volume we can store. \since 0.9.15 */ +#define PA_VOLUME_MAX ((pa_volume_t) UINT32_MAX/2) + +/** Recommended maximum volume to show in user facing UIs. + * Note: UIs should deal gracefully with volumes greater than this value + * and not cause feedback loops etc. - i.e. if the volume is more than + * this, the UI should not limit it and push the limited value back to + * the server. \since 0.9.23 */ +#define PA_VOLUME_UI_MAX (pa_sw_volume_from_dB(+11.0)) + +/** Special 'invalid' volume. \since 0.9.16 */ +#define PA_VOLUME_INVALID ((pa_volume_t) UINT32_MAX) + +/** Check if volume is valid. \since 1.0 */ +#define PA_VOLUME_IS_VALID(v) ((v) <= PA_VOLUME_MAX) + +/** Clamp volume to the permitted range. \since 1.0 */ +#define PA_CLAMP_VOLUME(v) (PA_CLAMP_UNLIKELY((v), PA_VOLUME_MUTED, PA_VOLUME_MAX)) + +/** A structure encapsulating a per-channel volume */ +typedef struct pa_cvolume { + uint8_t channels; /**< Number of channels */ + pa_volume_t values[PA_CHANNELS_MAX]; /**< Per-channel volume */ +} pa_cvolume; + +/** Return non-zero when *a == *b */ +int pa_cvolume_equal(const pa_cvolume *a, const pa_cvolume *b) PA_GCC_PURE; + +/** Initialize the specified volume and return a pointer to + * it. The sample spec will have a defined state but + * pa_cvolume_valid() will fail for it. \since 0.9.13 */ +pa_cvolume* pa_cvolume_init(pa_cvolume *a); + +/** Set the volume of the first n channels to PA_VOLUME_NORM */ +#define pa_cvolume_reset(a, n) pa_cvolume_set((a), (n), PA_VOLUME_NORM) + +/** Set the volume of the first n channels to PA_VOLUME_MUTED */ +#define pa_cvolume_mute(a, n) pa_cvolume_set((a), (n), PA_VOLUME_MUTED) + +/** Set the volume of the specified number of channels to the volume v */ +pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v); + +/** Maximum length of the strings returned by + * pa_cvolume_snprint(). Please note that this value can change with + * any release without warning and without being considered API or ABI + * breakage. You should not use this definition anywhere where it + * might become part of an ABI.*/ +#define PA_CVOLUME_SNPRINT_MAX 320 + +/** Pretty print a volume structure */ +char *pa_cvolume_snprint(char *s, size_t l, const pa_cvolume *c); + +/** Maximum length of the strings returned by + * pa_sw_cvolume_snprint_dB(). Please note that this value can change with + * any release without warning and without being considered API or ABI + * breakage. You should not use this definition anywhere where it + * might become part of an ABI. \since 0.9.13 */ +#define PA_SW_CVOLUME_SNPRINT_DB_MAX 448 + +/** Pretty print a volume structure but show dB values. \since 0.9.13 */ +char *pa_sw_cvolume_snprint_dB(char *s, size_t l, const pa_cvolume *c); + +/** Maximum length of the strings returned by pa_cvolume_snprint_verbose(). + * Please note that this value can change with any release without warning and + * without being considered API or ABI breakage. You should not use this + * definition anywhere where it might become part of an ABI. \since 5.0 */ +#define PA_CVOLUME_SNPRINT_VERBOSE_MAX 1984 + +/** Pretty print a volume structure in a verbose way. The volume for each + * channel is printed in several formats: the raw pa_volume_t value, + * percentage, and if print_dB is non-zero, also the dB value. If map is not + * NULL, the channel names will be printed. \since 5.0 */ +char *pa_cvolume_snprint_verbose(char *s, size_t l, const pa_cvolume *c, const pa_channel_map *map, int print_dB); + +/** Maximum length of the strings returned by + * pa_volume_snprint(). Please note that this value can change with + * any release without warning and without being considered API or ABI + * breakage. You should not use this definition anywhere where it + * might become part of an ABI. \since 0.9.15 */ +#define PA_VOLUME_SNPRINT_MAX 10 + +/** Pretty print a volume \since 0.9.15 */ +char *pa_volume_snprint(char *s, size_t l, pa_volume_t v); + +/** Maximum length of the strings returned by + * pa_sw_volume_snprint_dB(). Please note that this value can change with + * any release without warning and without being considered API or ABI + * breakage. You should not use this definition anywhere where it + * might become part of an ABI. \since 0.9.15 */ +#define PA_SW_VOLUME_SNPRINT_DB_MAX 11 + +/** Pretty print a volume but show dB values. \since 0.9.15 */ +char *pa_sw_volume_snprint_dB(char *s, size_t l, pa_volume_t v); + +/** Maximum length of the strings returned by pa_volume_snprint_verbose(). + * Please note that this value can change with any release without warning and + * withou being considered API or ABI breakage. You should not use this + * definition anywhere where it might become part of an ABI. \since 5.0 */ +#define PA_VOLUME_SNPRINT_VERBOSE_MAX 35 + +/** Pretty print a volume in a verbose way. The volume is printed in several + * formats: the raw pa_volume_t value, percentage, and if print_dB is non-zero, + * also the dB value. \since 5.0 */ +char *pa_volume_snprint_verbose(char *s, size_t l, pa_volume_t v, int print_dB); + +/** Return the average volume of all channels */ +pa_volume_t pa_cvolume_avg(const pa_cvolume *a) PA_GCC_PURE; + +/** Return the average volume of all channels that are included in the + * specified channel map with the specified channel position mask. If + * cm is NULL this call is identical to pa_cvolume_avg(). If no + * channel is selected the returned value will be + * PA_VOLUME_MUTED. \since 0.9.16 */ +pa_volume_t pa_cvolume_avg_mask(const pa_cvolume *a, const pa_channel_map *cm, pa_channel_position_mask_t mask) PA_GCC_PURE; + +/** Return the maximum volume of all channels. \since 0.9.12 */ +pa_volume_t pa_cvolume_max(const pa_cvolume *a) PA_GCC_PURE; + +/** Return the maximum volume of all channels that are included in the + * specified channel map with the specified channel position mask. If + * cm is NULL this call is identical to pa_cvolume_max(). If no + * channel is selected the returned value will be PA_VOLUME_MUTED. + * \since 0.9.16 */ +pa_volume_t pa_cvolume_max_mask(const pa_cvolume *a, const pa_channel_map *cm, pa_channel_position_mask_t mask) PA_GCC_PURE; + +/** Return the minimum volume of all channels. \since 0.9.16 */ +pa_volume_t pa_cvolume_min(const pa_cvolume *a) PA_GCC_PURE; + +/** Return the minimum volume of all channels that are included in the + * specified channel map with the specified channel position mask. If + * cm is NULL this call is identical to pa_cvolume_min(). If no + * channel is selected the returned value will be PA_VOLUME_MUTED. + * \since 0.9.16 */ +pa_volume_t pa_cvolume_min_mask(const pa_cvolume *a, const pa_channel_map *cm, pa_channel_position_mask_t mask) PA_GCC_PURE; + +/** Return non-zero when the passed cvolume structure is valid */ +int pa_cvolume_valid(const pa_cvolume *v) PA_GCC_PURE; + +/** Return non-zero if the volume of all channels is equal to the specified value */ +int pa_cvolume_channels_equal_to(const pa_cvolume *a, pa_volume_t v) PA_GCC_PURE; + +/** Return 1 if the specified volume has all channels muted */ +#define pa_cvolume_is_muted(a) pa_cvolume_channels_equal_to((a), PA_VOLUME_MUTED) + +/** Return 1 if the specified volume has all channels on normal level */ +#define pa_cvolume_is_norm(a) pa_cvolume_channels_equal_to((a), PA_VOLUME_NORM) + +/** Multiply two volume specifications, return the result. This uses + * PA_VOLUME_NORM as neutral element of multiplication. This is only + * valid for software volumes! */ +pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) PA_GCC_CONST; + +/** Multiply two per-channel volumes and return the result in + * *dest. This is only valid for software volumes! a, b and dest may + * point to the same structure. */ +pa_cvolume *pa_sw_cvolume_multiply(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b); + +/** Multiply a per-channel volume with a scalar volume and return the + * result in *dest. This is only valid for software volumes! a + * and dest may point to the same structure. \since + * 0.9.16 */ +pa_cvolume *pa_sw_cvolume_multiply_scalar(pa_cvolume *dest, const pa_cvolume *a, pa_volume_t b); + +/** Divide two volume specifications, return the result. This uses + * PA_VOLUME_NORM as neutral element of division. This is only valid + * for software volumes! If a division by zero is tried the result + * will be 0. \since 0.9.13 */ +pa_volume_t pa_sw_volume_divide(pa_volume_t a, pa_volume_t b) PA_GCC_CONST; + +/** Divide two per-channel volumes and return the result in + * *dest. This is only valid for software volumes! a, b + * and dest may point to the same structure. \since 0.9.13 */ +pa_cvolume *pa_sw_cvolume_divide(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b); + +/** Divide a per-channel volume by a scalar volume and return the + * result in *dest. This is only valid for software volumes! a + * and dest may point to the same structure. \since + * 0.9.16 */ +pa_cvolume *pa_sw_cvolume_divide_scalar(pa_cvolume *dest, const pa_cvolume *a, pa_volume_t b); + +/** Convert a decibel value to a volume (amplitude, not power). This is only valid for software volumes! */ +pa_volume_t pa_sw_volume_from_dB(double f) PA_GCC_CONST; + +/** Convert a volume to a decibel value (amplitude, not power). This is only valid for software volumes! */ +double pa_sw_volume_to_dB(pa_volume_t v) PA_GCC_CONST; + +/** Convert a linear factor to a volume. 0.0 and less is muted while + * 1.0 is PA_VOLUME_NORM. This is only valid for software volumes! */ +pa_volume_t pa_sw_volume_from_linear(double v) PA_GCC_CONST; + +/** Convert a volume to a linear factor. This is only valid for software volumes! */ +double pa_sw_volume_to_linear(pa_volume_t v) PA_GCC_CONST; + +#ifdef INFINITY +#define PA_DECIBEL_MININFTY ((double) -INFINITY) +#else +/** This floor value is used as minus infinity when using pa_sw_volume_to_dB() / pa_sw_volume_from_dB(). */ +#define PA_DECIBEL_MININFTY ((double) -200.0) +#endif + +/** Remap a volume from one channel mapping to a different channel mapping. \since 0.9.12 */ +pa_cvolume *pa_cvolume_remap(pa_cvolume *v, const pa_channel_map *from, const pa_channel_map *to); + +/** Return non-zero if the specified volume is compatible with the + * specified sample spec. \since 0.9.13 */ +int pa_cvolume_compatible(const pa_cvolume *v, const pa_sample_spec *ss) PA_GCC_PURE; + +/** Return non-zero if the specified volume is compatible with the + * specified sample spec. \since 0.9.15 */ +int pa_cvolume_compatible_with_channel_map(const pa_cvolume *v, const pa_channel_map *cm) PA_GCC_PURE; + +/** Calculate a 'balance' value for the specified volume with the + * specified channel map. The return value will range from -1.0f + * (left) to +1.0f (right). If no balance value is applicable to this + * channel map the return value will always be 0.0f. See + * pa_channel_map_can_balance(). \since 0.9.15 */ +float pa_cvolume_get_balance(const pa_cvolume *v, const pa_channel_map *map) PA_GCC_PURE; + +/** Adjust the 'balance' value for the specified volume with the + * specified channel map. v will be modified in place and + * returned. The balance is a value between -1.0f and +1.0f. This + * operation might not be reversible! Also, after this call + * pa_cvolume_get_balance() is not guaranteed to actually return the + * requested balance value (e.g. when the input volume was zero anyway for + * all channels). If no balance value is applicable to + * this channel map the volume will not be modified. See + * pa_channel_map_can_balance(). \since 0.9.15 */ +pa_cvolume* pa_cvolume_set_balance(pa_cvolume *v, const pa_channel_map *map, float new_balance); + +/** Calculate a 'fade' value (i.e.\ 'balance' between front and rear) + * for the specified volume with the specified channel map. The return + * value will range from -1.0f (rear) to +1.0f (left). If no fade + * value is applicable to this channel map the return value will + * always be 0.0f. See pa_channel_map_can_fade(). \since 0.9.15 */ +float pa_cvolume_get_fade(const pa_cvolume *v, const pa_channel_map *map) PA_GCC_PURE; + +/** Adjust the 'fade' value (i.e.\ 'balance' between front and rear) + * for the specified volume with the specified channel map. v will be + * modified in place and returned. The balance is a value between + * -1.0f and +1.0f. This operation might not be reversible! Also, + * after this call pa_cvolume_get_fade() is not guaranteed to actually + * return the requested fade value (e.g. when the input volume was + * zero anyway for all channels). If no fade value is applicable to + * this channel map the volume will not be modified. See + * pa_channel_map_can_fade(). \since 0.9.15 */ +pa_cvolume* pa_cvolume_set_fade(pa_cvolume *v, const pa_channel_map *map, float new_fade); + +/** Calculate a 'lfe balance' value for the specified volume with + * the specified channel map. The return value will range from + * -1.0f (no lfe) to +1.0f (only lfe), where 0.0f is balanced. + * If no value is applicable to this channel map the return value + * will always be 0.0f. See pa_channel_map_can_lfe_balance(). \since 8.0 */ +float pa_cvolume_get_lfe_balance(const pa_cvolume *v, const pa_channel_map *map) PA_GCC_PURE; + +/** Adjust the 'lfe balance' value for the specified volume with + * the specified channel map. v will be modified in place and returned. + * The balance is a value between -1.0f (no lfe) and +1.0f (only lfe). + * This operation might not be reversible! Also, after this call + * pa_cvolume_get_lfe_balance() is not guaranteed to actually + * return the requested value (e.g. when the input volume was + * zero anyway for all channels). If no lfe balance value is applicable to + * this channel map the volume will not be modified. See + * pa_channel_map_can_lfe_balance(). \since 8.0 */ +pa_cvolume* pa_cvolume_set_lfe_balance(pa_cvolume *v, const pa_channel_map *map, float new_balance); + +/** Scale the passed pa_cvolume structure so that the maximum volume + * of all channels equals max. The proportions between the channel + * volumes are kept. \since 0.9.15 */ +pa_cvolume* pa_cvolume_scale(pa_cvolume *v, pa_volume_t max); + +/** Scale the passed pa_cvolume structure so that the maximum volume + * of all channels selected via cm/mask equals max. This also modifies + * the volume of those channels that are unmasked. The proportions + * between the channel volumes are kept. \since 0.9.16 */ +pa_cvolume* pa_cvolume_scale_mask(pa_cvolume *v, pa_volume_t max, pa_channel_map *cm, pa_channel_position_mask_t mask); + +/** Set the passed volume to all channels at the specified channel + * position. Will return the updated volume struct, or NULL if there + * is no channel at the position specified. You can check if a channel + * map includes a specific position by calling + * pa_channel_map_has_position(). \since 0.9.16 */ +pa_cvolume* pa_cvolume_set_position(pa_cvolume *cv, const pa_channel_map *map, pa_channel_position_t t, pa_volume_t v); + +/** Get the maximum volume of all channels at the specified channel + * position. Will return 0 if there is no channel at the position + * specified. You can check if a channel map includes a specific + * position by calling pa_channel_map_has_position(). \since 0.9.16 */ +pa_volume_t pa_cvolume_get_position(pa_cvolume *cv, const pa_channel_map *map, pa_channel_position_t t) PA_GCC_PURE; + +/** This goes through all channels in a and b and sets the + * corresponding channel in dest to the greater volume of both. a, b + * and dest may point to the same structure. \since 0.9.16 */ +pa_cvolume* pa_cvolume_merge(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b); + +/** Increase the volume passed in by 'inc', but not exceeding 'limit'. + * The proportions between the channels are kept. \since 0.9.19 */ +pa_cvolume* pa_cvolume_inc_clamp(pa_cvolume *v, pa_volume_t inc, pa_volume_t limit); + +/** Increase the volume passed in by 'inc'. The proportions between + * the channels are kept. \since 0.9.16 */ +pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc); + +/** Decrease the volume passed in by 'dec'. The proportions between + * the channels are kept. \since 0.9.16 */ +pa_cvolume* pa_cvolume_dec(pa_cvolume *v, pa_volume_t dec); + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/pulse/xmalloc.h b/thirdparty/linuxbsd_headers/pulse/xmalloc.h new file mode 100644 index 0000000000..d1d6968a3f --- /dev/null +++ b/thirdparty/linuxbsd_headers/pulse/xmalloc.h @@ -0,0 +1,105 @@ +#ifndef foomemoryhfoo +#define foomemoryhfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#include <sys/types.h> +#include <stdlib.h> +#include <limits.h> +#include <assert.h> + +#include <pulse/cdecl.h> +#include <pulse/gccmacro.h> +#include <pulse/version.h> + +/** \file + * Memory allocation functions. + */ + +PA_C_DECL_BEGIN + +/** Allocate the specified number of bytes, just like malloc() does. However, in case of OOM, terminate */ +void* pa_xmalloc(size_t l) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE(1); + +/** Same as pa_xmalloc(), but initialize allocated memory to 0 */ +void *pa_xmalloc0(size_t l) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE(1); + +/** The combination of pa_xmalloc() and realloc() */ +void *pa_xrealloc(void *ptr, size_t size) PA_GCC_ALLOC_SIZE(2); + +/** Free allocated memory */ +void pa_xfree(void *p); + +/** Duplicate the specified string, allocating memory with pa_xmalloc() */ +char *pa_xstrdup(const char *s) PA_GCC_MALLOC; + +/** Duplicate the specified string, but truncate after l characters */ +char *pa_xstrndup(const char *s, size_t l) PA_GCC_MALLOC; + +/** Duplicate the specified memory block */ +void* pa_xmemdup(const void *p, size_t l) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE(2); + +/** Internal helper for pa_xnew() */ +static void* _pa_xnew_internal(size_t n, size_t k) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE2(1,2); + +static inline void* _pa_xnew_internal(size_t n, size_t k) { + assert(n < INT_MAX/k); + return pa_xmalloc(n*k); +} + +/** Allocate n new structures of the specified type. */ +#define pa_xnew(type, n) ((type*) _pa_xnew_internal((n), sizeof(type))) + +/** Internal helper for pa_xnew0() */ +static void* _pa_xnew0_internal(size_t n, size_t k) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE2(1,2); + +static inline void* _pa_xnew0_internal(size_t n, size_t k) { + assert(n < INT_MAX/k); + return pa_xmalloc0(n*k); +} + +/** Same as pa_xnew() but set the memory to zero */ +#define pa_xnew0(type, n) ((type*) _pa_xnew0_internal((n), sizeof(type))) + +/** Internal helper for pa_xnew0() */ +static void* _pa_xnewdup_internal(const void *p, size_t n, size_t k) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE2(2,3); + +static inline void* _pa_xnewdup_internal(const void *p, size_t n, size_t k) { + assert(n < INT_MAX/k); + return pa_xmemdup(p, n*k); +} + +/** Same as pa_xnew() but duplicate the specified data */ +#define pa_xnewdup(type, p, n) ((type*) _pa_xnewdup_internal((p), (n), sizeof(type))) + +/** Internal helper for pa_xrenew() */ +static void* _pa_xrenew_internal(void *p, size_t n, size_t k) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE2(2,3); + +static inline void* _pa_xrenew_internal(void *p, size_t n, size_t k) { + assert(n < INT_MAX/k); + return pa_xrealloc(p, n*k); +} + +/** Reallocate n new structures of the specified type. */ +#define pa_xrenew(type, p, n) ((type*) _pa_xrenew_internal(p, (n), sizeof(type))) + +PA_C_DECL_END + +#endif diff --git a/thirdparty/linuxbsd_headers/speechd/libspeechd.h b/thirdparty/linuxbsd_headers/speechd/libspeechd.h new file mode 100644 index 0000000000..21b9313cae --- /dev/null +++ b/thirdparty/linuxbsd_headers/speechd/libspeechd.h @@ -0,0 +1,248 @@ +/* + * libspeechd.h - Shared library for easy acces to Speech Dispatcher functions (header) + * + * Copyright (C) 2001, 2002, 2003, 2004 Brailcom, o.p.s. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this package; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * $Id: libspeechd.h,v 1.29 2008-07-30 09:47:00 hanke Exp $ + */ + +#ifndef _LIBSPEECHD_H +#define _LIBSPEECHD_H + +#include <stdio.h> +#include <stddef.h> +#include <pthread.h> + +#include "libspeechd_version.h" +#include "speechd_types.h" + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + /* Speech Dispatcher's default port for inet communication */ +#define SPEECHD_DEFAULT_PORT 6560 + + /* Arguments for spd_send_data() */ +#define SPD_WAIT_REPLY 1 /* Wait for reply */ +#define SPD_NO_REPLY 0 /* No reply requested */ + + /* --------------------- Public data types ------------------------ */ + +typedef enum { + SPD_MODE_SINGLE = 0, + SPD_MODE_THREADED = 1 +} SPDConnectionMode; + +typedef enum { + SPD_METHOD_UNIX_SOCKET = 0, + SPD_METHOD_INET_SOCKET = 1, +} SPDConnectionMethod; + +typedef struct { + SPDConnectionMethod method; + char *unix_socket_name; + char *inet_socket_host; + int inet_socket_port; + char *dbus_bus; +} SPDConnectionAddress; + +void SPDConnectionAddress__free(SPDConnectionAddress * address); + +typedef void (*SPDCallback) (size_t msg_id, size_t client_id, + SPDNotificationType state); +typedef void (*SPDCallbackIM) (size_t msg_id, size_t client_id, + SPDNotificationType state, char *index_mark); + +typedef struct { + + /* PUBLIC */ + SPDCallback callback_begin; + SPDCallback callback_end; + SPDCallback callback_cancel; + SPDCallback callback_pause; + SPDCallback callback_resume; + SPDCallbackIM callback_im; + + /* PRIVATE */ + int socket; + FILE *stream; + SPDConnectionMode mode; + + pthread_mutex_t *ssip_mutex; + + pthread_t *events_thread; + pthread_mutex_t *comm_mutex; + pthread_cond_t *cond_reply_ready; + pthread_mutex_t *mutex_reply_ready; + pthread_cond_t *cond_reply_ack; + pthread_mutex_t *mutex_reply_ack; + + char *reply; + +} SPDConnection; + +/* -------------- Public functions --------------------------*/ + +/* Opening and closing Speech Dispatcher connection */ +SPDConnectionAddress *spd_get_default_address(char **error); +SPDConnection *spd_open(const char *client_name, const char *connection_name, + const char *user_name, SPDConnectionMode mode); +SPDConnection *spd_open2(const char *client_name, const char *connection_name, + const char *user_name, SPDConnectionMode mode, + SPDConnectionAddress * address, int autospawn, + char **error_result); + +void spd_close(SPDConnection * connection); + +/* Speaking */ +int spd_say(SPDConnection * connection, SPDPriority priority, const char *text); +int spd_sayf(SPDConnection * connection, SPDPriority priority, + const char *format, ...); + +/* Speech flow */ +int spd_stop(SPDConnection * connection); +int spd_stop_all(SPDConnection * connection); +int spd_stop_uid(SPDConnection * connection, int target_uid); + +int spd_cancel(SPDConnection * connection); +int spd_cancel_all(SPDConnection * connection); +int spd_cancel_uid(SPDConnection * connection, int target_uid); + +int spd_pause(SPDConnection * connection); +int spd_pause_all(SPDConnection * connection); +int spd_pause_uid(SPDConnection * connection, int target_uid); + +int spd_resume(SPDConnection * connection); +int spd_resume_all(SPDConnection * connection); +int spd_resume_uid(SPDConnection * connection, int target_uid); + +/* Characters and keys */ +int spd_key(SPDConnection * connection, SPDPriority priority, + const char *key_name); +int spd_char(SPDConnection * connection, SPDPriority priority, + const char *character); +int spd_wchar(SPDConnection * connection, SPDPriority priority, + wchar_t wcharacter); + +/* Sound icons */ +int spd_sound_icon(SPDConnection * connection, SPDPriority priority, + const char *icon_name); + +/* Setting parameters */ +int spd_set_voice_type(SPDConnection *, SPDVoiceType type); +int spd_set_voice_type_all(SPDConnection *, SPDVoiceType type); +int spd_set_voice_type_uid(SPDConnection *, SPDVoiceType type, + unsigned int uid); +SPDVoiceType spd_get_voice_type(SPDConnection *); + +int spd_set_synthesis_voice(SPDConnection *, const char *voice_name); +int spd_set_synthesis_voice_all(SPDConnection *, const char *voice_name); +int spd_set_synthesis_voice_uid(SPDConnection *, const char *voice_name, + unsigned int uid); + +int spd_set_data_mode(SPDConnection * connection, SPDDataMode mode); + +int spd_set_notification_on(SPDConnection * connection, + SPDNotification notification); +int spd_set_notification_off(SPDConnection * connection, + SPDNotification notification); +int spd_set_notification(SPDConnection * connection, + SPDNotification notification, const char *state); + +int spd_set_voice_rate(SPDConnection * connection, signed int rate); +int spd_set_voice_rate_all(SPDConnection * connection, signed int rate); +int spd_set_voice_rate_uid(SPDConnection * connection, signed int rate, + unsigned int uid); +int spd_get_voice_rate(SPDConnection * connection); + +int spd_set_voice_pitch(SPDConnection * connection, signed int pitch); +int spd_set_voice_pitch_all(SPDConnection * connection, signed int pitch); +int spd_set_voice_pitch_uid(SPDConnection * connection, signed int pitch, + unsigned int uid); +int spd_get_voice_pitch(SPDConnection * connection); + +int spd_set_volume(SPDConnection * connection, signed int volume); +int spd_set_volume_all(SPDConnection * connection, signed int volume); +int spd_set_volume_uid(SPDConnection * connection, signed int volume, + unsigned int uid); +int spd_get_volume(SPDConnection * connection); + +int spd_set_punctuation(SPDConnection * connection, SPDPunctuation type); +int spd_set_punctuation_all(SPDConnection * connection, SPDPunctuation type); +int spd_set_punctuation_uid(SPDConnection * connection, SPDPunctuation type, + unsigned int uid); + +int spd_set_capital_letters(SPDConnection * connection, SPDCapitalLetters type); +int spd_set_capital_letters_all(SPDConnection * connection, + SPDCapitalLetters type); +int spd_set_capital_letters_uid(SPDConnection * connection, + SPDCapitalLetters type, unsigned int uid); + +int spd_set_spelling(SPDConnection * connection, SPDSpelling type); +int spd_set_spelling_all(SPDConnection * connection, SPDSpelling type); +int spd_set_spelling_uid(SPDConnection * connection, SPDSpelling type, + unsigned int uid); + +int spd_set_language(SPDConnection * connection, const char *language); +int spd_set_language_all(SPDConnection * connection, const char *language); +int spd_set_language_uid(SPDConnection * connection, const char *language, + unsigned int uid); +char *spd_get_language(SPDConnection * connection); + +int spd_set_output_module(SPDConnection * connection, + const char *output_module); +int spd_set_output_module_all(SPDConnection * connection, + const char *output_module); +int spd_set_output_module_uid(SPDConnection * connection, + const char *output_module, unsigned int uid); + +int spd_get_client_list(SPDConnection * connection, char **client_names, + int *client_ids, int *active); +int spd_get_message_list_fd(SPDConnection * connection, int target, + int *msg_ids, char **client_names); + +char **spd_list_modules(SPDConnection * connection); +void free_spd_modules(char **); +char *spd_get_output_module(SPDConnection * connection); + +char **spd_list_voices(SPDConnection * connection); +SPDVoice **spd_list_synthesis_voices(SPDConnection * connection); +void free_spd_voices(SPDVoice ** voices); +char **spd_execute_command_with_list_reply(SPDConnection * connection, + char *command); + +/* Direct SSIP communication */ +int spd_execute_command(SPDConnection * connection, char *command); +int spd_execute_command_with_reply(SPDConnection * connection, char *command, + char **reply); +int spd_execute_command_wo_mutex(SPDConnection * connection, char *command); +char *spd_send_data(SPDConnection * connection, const char *message, int wfr); +char *spd_send_data_wo_mutex(SPDConnection * connection, const char *message, + int wfr); + + + +/* *INDENT-OFF* */ +#ifdef __cplusplus +} +#endif /* __cplusplus */ +/* *INDENT-ON* */ + +#endif /* ifndef _LIBSPEECHD_H */ diff --git a/thirdparty/linuxbsd_headers/speechd/libspeechd_version.h b/thirdparty/linuxbsd_headers/speechd/libspeechd_version.h new file mode 100644 index 0000000000..bfe4d6bc21 --- /dev/null +++ b/thirdparty/linuxbsd_headers/speechd/libspeechd_version.h @@ -0,0 +1,31 @@ +/* + * libspeechd_version.h - Shared library for easy access to Speech Dispatcher functions (header) + * + * Copyright (C) 2001, 2002, 2003, 2004 Brailcom, o.p.s. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this package; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * $Id: libspeechd.h,v 1.29 2008-07-30 09:47:00 hanke Exp $ + */ + +#ifndef _LIBSPEECHD_VERSION_H +#define _LIBSPEECHD_VERSION_H + +#define LIBSPEECHD_MAJOR_VERSION 0 +#define LIBSPEECHD_MINOR_VERSION 8 +#define LIBSPEECHD_MICRO_VERSION 8 + +#endif /* ifndef _LIBSPEECHD_VERSION_H */ diff --git a/thirdparty/linuxbsd_headers/speechd/spd_audio_plugin.h b/thirdparty/linuxbsd_headers/speechd/spd_audio_plugin.h new file mode 100644 index 0000000000..85f2850972 --- /dev/null +++ b/thirdparty/linuxbsd_headers/speechd/spd_audio_plugin.h @@ -0,0 +1,75 @@ +/* + * spd_audio_plugin.h -- The SPD Audio Plugin Header + * + * Copyright (C) 2004 Brailcom, o.p.s. + * + * This is free software; you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1, or (at your option) any later + * version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this package; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +#ifndef __SPD_AUDIO_PLUGIN_H +#define __SPD_AUDIO_PLUGIN_H + +#define SPD_AUDIO_PLUGIN_ENTRY_STR "spd_audio_plugin_get" + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + +typedef enum { SPD_AUDIO_LE, SPD_AUDIO_BE } AudioFormat; + +typedef struct { + int bits; + int num_channels; + int sample_rate; + + int num_samples; + signed short *samples; +} AudioTrack; + +struct spd_audio_plugin; + +typedef struct { + + int volume; + AudioFormat format; + + struct spd_audio_plugin const *function; + void *private_data; + + int working; +} AudioID; + +typedef struct spd_audio_plugin { + const char *name; + AudioID *(*open) (void **pars); + int (*play) (AudioID * id, AudioTrack track); + int (*stop) (AudioID * id); + int (*close) (AudioID * id); + int (*set_volume) (AudioID * id, int); + void (*set_loglevel) (int level); + char const *(*get_playcmd) (void); +} spd_audio_plugin_t; + +/* *INDENT-OFF* */ +#ifdef __cplusplus +} +#endif /* __cplusplus */ +/* *INDENT-ON* */ + +#endif /* ifndef #__SPD_AUDIO_PLUGIN_H */ diff --git a/thirdparty/linuxbsd_headers/speechd/speechd_defines.h b/thirdparty/linuxbsd_headers/speechd/speechd_defines.h new file mode 100644 index 0000000000..f1cd195339 --- /dev/null +++ b/thirdparty/linuxbsd_headers/speechd/speechd_defines.h @@ -0,0 +1,34 @@ +/* + * speechd_defines.h - macros for Speech Dispatcher + * + * Copyright (C) 2015 Brailcom, o.p.s. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this package; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef SPEECHD_DEFINES_H +#define SPEECHD_DEFINES_H + +#define SPD_ALLCLIENTS "ALL" +#define SPD_SELF "SELF" +#define SPD_VOLUME "VOLUME" +#define SPD_PITCH "PITCH" +#define SPD_RATE "RATE" +#define SPD_LANGUAGE "LANGUAGE" +#define SPD_OUTPUT_MODULE "OUTPUT_MODULE" +#define SPD_SYNTHESIS_VOICE "SYNTHESIS_VOICE" + +#endif /* not ifndef SPEECHD_DEFINES_H */ diff --git a/thirdparty/linuxbsd_headers/speechd/speechd_types.h b/thirdparty/linuxbsd_headers/speechd/speechd_types.h new file mode 100644 index 0000000000..07c1974ff0 --- /dev/null +++ b/thirdparty/linuxbsd_headers/speechd/speechd_types.h @@ -0,0 +1,119 @@ + +/* + * speechd_types.h - types for Speech Dispatcher + * + * Copyright (C) 2001, 2002, 2003 Brailcom, o.p.s. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this package; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef SPEECHD_TYPES_H +#define SPEECHD_TYPES_H + +typedef enum { + SPD_PUNCT_ALL = 0, + SPD_PUNCT_NONE = 1, + SPD_PUNCT_SOME = 2 +} SPDPunctuation; + +typedef enum { + SPD_CAP_NONE = 0, + SPD_CAP_SPELL = 1, + SPD_CAP_ICON = 2 +} SPDCapitalLetters; + +typedef enum { + SPD_SPELL_OFF = 0, + SPD_SPELL_ON = 1 +} SPDSpelling; + +typedef enum { + SPD_MALE1 = 1, + SPD_MALE2 = 2, + SPD_MALE3 = 3, + SPD_FEMALE1 = 4, + SPD_FEMALE2 = 5, + SPD_FEMALE3 = 6, + SPD_CHILD_MALE = 7, + SPD_CHILD_FEMALE = 8 +} SPDVoiceType; + +typedef struct { + char *name; /* Name of the voice (id) */ + char *language; /* 2-letter ISO language code */ + char *variant; /* a not-well defined string describing dialect etc. */ +} SPDVoice; + +typedef enum { + SPD_DATA_TEXT = 0, + SPD_DATA_SSML = 1 +} SPDDataMode; + +typedef enum { + SPD_IMPORTANT = 1, + SPD_MESSAGE = 2, + SPD_TEXT = 3, + SPD_NOTIFICATION = 4, + SPD_PROGRESS = 5 +} SPDPriority; + +typedef enum { + SPD_BEGIN = 1, + SPD_END = 2, + SPD_INDEX_MARKS = 4, + SPD_CANCEL = 8, + SPD_PAUSE = 16, + SPD_RESUME = 32, + + SPD_ALL = 0x3f +} SPDNotification; + +typedef enum { + SPD_EVENT_BEGIN, + SPD_EVENT_END, + SPD_EVENT_INDEX_MARK, + SPD_EVENT_CANCEL, + SPD_EVENT_PAUSE, + SPD_EVENT_RESUME +} SPDNotificationType; + +typedef enum { + SORT_BY_TIME = 0, + SORT_BY_ALPHABET = 1 +} ESort; + +typedef enum { + SPD_MSGTYPE_TEXT = 0, + SPD_MSGTYPE_SOUND_ICON = 1, + SPD_MSGTYPE_CHAR = 2, + SPD_MSGTYPE_KEY = 3, + SPD_MSGTYPE_SPELL = 99 +} SPDMessageType; + +typedef struct { + signed int rate; + signed int pitch; + signed int volume; + + SPDPunctuation punctuation_mode; + SPDSpelling spelling_mode; + SPDCapitalLetters cap_let_recogn; + + SPDVoiceType voice_type; + SPDVoice voice; +} SPDMsgSettings; + +#endif /* not ifndef SPEECHD_TYPES */ diff --git a/thirdparty/linuxbsd_headers/udev/libudev.h b/thirdparty/linuxbsd_headers/udev/libudev.h new file mode 100644 index 0000000000..be465a0043 --- /dev/null +++ b/thirdparty/linuxbsd_headers/udev/libudev.h @@ -0,0 +1,208 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/*** + This file is part of systemd. + + Copyright 2008-2012 Kay Sievers <kay@vrfy.org> + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#ifndef _LIBUDEV_H_ +#define _LIBUDEV_H_ + +#include <stdarg.h> +#include <sys/sysmacros.h> +#include <sys/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * udev - library context + * + * reads the udev config and system environment + * allows custom logging + */ +struct udev; +struct udev *udev_ref(struct udev *udev); +struct udev *udev_unref(struct udev *udev); +struct udev *udev_new(void); +void udev_set_log_fn(struct udev *udev, + void (*log_fn)(struct udev *udev, + int priority, const char *file, int line, const char *fn, + const char *format, va_list args)) __attribute__ ((deprecated)); +int udev_get_log_priority(struct udev *udev) __attribute__ ((deprecated)); +void udev_set_log_priority(struct udev *udev, int priority) __attribute__ ((deprecated)); +void *udev_get_userdata(struct udev *udev); +void udev_set_userdata(struct udev *udev, void *userdata); + +/* + * udev_list + * + * access to libudev generated lists + */ +struct udev_list_entry; +struct udev_list_entry *udev_list_entry_get_next(struct udev_list_entry *list_entry); +struct udev_list_entry *udev_list_entry_get_by_name(struct udev_list_entry *list_entry, const char *name); +const char *udev_list_entry_get_name(struct udev_list_entry *list_entry); +const char *udev_list_entry_get_value(struct udev_list_entry *list_entry); +/** + * udev_list_entry_foreach: + * @list_entry: entry to store the current position + * @first_entry: first entry to start with + * + * Helper to iterate over all entries of a list. + */ +#define udev_list_entry_foreach(list_entry, first_entry) \ + for (list_entry = first_entry; \ + list_entry != NULL; \ + list_entry = udev_list_entry_get_next(list_entry)) + +/* + * udev_device + * + * access to sysfs/kernel devices + */ +struct udev_device; +struct udev_device *udev_device_ref(struct udev_device *udev_device); +struct udev_device *udev_device_unref(struct udev_device *udev_device); +struct udev *udev_device_get_udev(struct udev_device *udev_device); +struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath); +struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum); +struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname); +struct udev_device *udev_device_new_from_device_id(struct udev *udev, const char *id); +struct udev_device *udev_device_new_from_environment(struct udev *udev); +/* udev_device_get_parent_*() does not take a reference on the returned device, it is automatically unref'd with the parent */ +struct udev_device *udev_device_get_parent(struct udev_device *udev_device); +struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device, + const char *subsystem, const char *devtype); +/* retrieve device properties */ +const char *udev_device_get_devpath(struct udev_device *udev_device); +const char *udev_device_get_subsystem(struct udev_device *udev_device); +const char *udev_device_get_devtype(struct udev_device *udev_device); +const char *udev_device_get_syspath(struct udev_device *udev_device); +const char *udev_device_get_sysname(struct udev_device *udev_device); +const char *udev_device_get_sysnum(struct udev_device *udev_device); +const char *udev_device_get_devnode(struct udev_device *udev_device); +int udev_device_get_is_initialized(struct udev_device *udev_device); +struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device); +struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device); +struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device); +struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device); +const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key); +const char *udev_device_get_driver(struct udev_device *udev_device); +dev_t udev_device_get_devnum(struct udev_device *udev_device); +const char *udev_device_get_action(struct udev_device *udev_device); +unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device); +unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device); +const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr); +int udev_device_set_sysattr_value(struct udev_device *udev_device, const char *sysattr, char *value); +int udev_device_has_tag(struct udev_device *udev_device, const char *tag); + +/* + * udev_monitor + * + * access to kernel uevents and udev events + */ +struct udev_monitor; +struct udev_monitor *udev_monitor_ref(struct udev_monitor *udev_monitor); +struct udev_monitor *udev_monitor_unref(struct udev_monitor *udev_monitor); +struct udev *udev_monitor_get_udev(struct udev_monitor *udev_monitor); +/* kernel and udev generated events over netlink */ +struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev, const char *name); +/* bind socket */ +int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor); +int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_monitor, int size); +int udev_monitor_get_fd(struct udev_monitor *udev_monitor); +struct udev_device *udev_monitor_receive_device(struct udev_monitor *udev_monitor); +/* in-kernel socket filters to select messages that get delivered to a listener */ +int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor *udev_monitor, + const char *subsystem, const char *devtype); +int udev_monitor_filter_add_match_tag(struct udev_monitor *udev_monitor, const char *tag); +int udev_monitor_filter_update(struct udev_monitor *udev_monitor); +int udev_monitor_filter_remove(struct udev_monitor *udev_monitor); + +/* + * udev_enumerate + * + * search sysfs for specific devices and provide a sorted list + */ +struct udev_enumerate; +struct udev_enumerate *udev_enumerate_ref(struct udev_enumerate *udev_enumerate); +struct udev_enumerate *udev_enumerate_unref(struct udev_enumerate *udev_enumerate); +struct udev *udev_enumerate_get_udev(struct udev_enumerate *udev_enumerate); +struct udev_enumerate *udev_enumerate_new(struct udev *udev); +/* device properties filter */ +int udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem); +int udev_enumerate_add_nomatch_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem); +int udev_enumerate_add_match_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value); +int udev_enumerate_add_nomatch_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value); +int udev_enumerate_add_match_property(struct udev_enumerate *udev_enumerate, const char *property, const char *value); +int udev_enumerate_add_match_sysname(struct udev_enumerate *udev_enumerate, const char *sysname); +int udev_enumerate_add_match_tag(struct udev_enumerate *udev_enumerate, const char *tag); +int udev_enumerate_add_match_parent(struct udev_enumerate *udev_enumerate, struct udev_device *parent); +int udev_enumerate_add_match_is_initialized(struct udev_enumerate *udev_enumerate); +int udev_enumerate_add_syspath(struct udev_enumerate *udev_enumerate, const char *syspath); +/* run enumeration with active filters */ +int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate); +int udev_enumerate_scan_subsystems(struct udev_enumerate *udev_enumerate); +/* return device list */ +struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate); + +/* + * udev_queue + * + * access to the currently running udev events + */ +struct udev_queue; +struct udev_queue *udev_queue_ref(struct udev_queue *udev_queue); +struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue); +struct udev *udev_queue_get_udev(struct udev_queue *udev_queue); +struct udev_queue *udev_queue_new(struct udev *udev); +unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue) __attribute__ ((deprecated)); +unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue) __attribute__ ((deprecated)); +int udev_queue_get_udev_is_active(struct udev_queue *udev_queue); +int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue); +int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum) __attribute__ ((deprecated)); +int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue, + unsigned long long int start, unsigned long long int end) __attribute__ ((deprecated)); +int udev_queue_get_fd(struct udev_queue *udev_queue); +int udev_queue_flush(struct udev_queue *udev_queue); +struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue) __attribute__ ((deprecated)); + +/* + * udev_hwdb + * + * access to the static hardware properties database + */ +struct udev_hwdb; +struct udev_hwdb *udev_hwdb_new(struct udev *udev); +struct udev_hwdb *udev_hwdb_ref(struct udev_hwdb *hwdb); +struct udev_hwdb *udev_hwdb_unref(struct udev_hwdb *hwdb); +struct udev_list_entry *udev_hwdb_get_properties_list_entry(struct udev_hwdb *hwdb, const char *modalias, unsigned int flags); + +/* + * udev_util + * + * udev specific utilities + */ +int udev_util_encode_string(const char *str, char *str_enc, size_t len); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compat.h b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compat.h new file mode 100644 index 0000000000..299732fdc3 --- /dev/null +++ b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compat.h @@ -0,0 +1,98 @@ +/* + * Copyright © 2012 Daniel Stone + * + * 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 (including the next + * paragraph) 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. + * + * Author: Daniel Stone <daniel@fooishbar.org> + */ + +#ifndef _XKBCOMMON_COMPAT_H +#define _XKBCOMMON_COMPAT_H + +/** + * Renamed keymap API. + */ +#define xkb_group_index_t xkb_layout_index_t +#define xkb_group_mask_t xkb_layout_mask_t +#define xkb_map_compile_flags xkb_keymap_compile_flags +#define XKB_GROUP_INVALID XKB_LAYOUT_INVALID + +#define XKB_STATE_DEPRESSED \ + (XKB_STATE_MODS_DEPRESSED | XKB_STATE_LAYOUT_DEPRESSED) +#define XKB_STATE_LATCHED \ + (XKB_STATE_MODS_LATCHED | XKB_STATE_LAYOUT_LATCHED) +#define XKB_STATE_LOCKED \ + (XKB_STATE_MODS_LOCKED | XKB_STATE_LAYOUT_LOCKED) +#define XKB_STATE_EFFECTIVE \ + (XKB_STATE_DEPRESSED | XKB_STATE_LATCHED | XKB_STATE_LOCKED | \ + XKB_STATE_MODS_EFFECTIVE | XKB_STATE_LAYOUT_EFFECTIVE) + +#define xkb_map_new_from_names(context, names, flags) \ + xkb_keymap_new_from_names(context, names, flags) +#define xkb_map_new_from_file(context, file, format, flags) \ + xkb_keymap_new_from_file(context, file, format, flags) +#define xkb_map_new_from_string(context, string, format, flags) \ + xkb_keymap_new_from_string(context, string, format, flags) +#define xkb_map_get_as_string(keymap) \ + xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1) +#define xkb_map_ref(keymap) xkb_keymap_ref(keymap) +#define xkb_map_unref(keymap) xkb_keymap_unref(keymap) + +#define xkb_map_num_mods(keymap) xkb_keymap_num_mods(keymap) +#define xkb_map_mod_get_name(keymap, idx) xkb_keymap_mod_get_name(keymap, idx) +#define xkb_map_mod_get_index(keymap, str) xkb_keymap_mod_get_index(keymap, str) +#define xkb_key_mod_index_is_consumed(state, key, mod) \ + xkb_state_mod_index_is_consumed(state, key, mod) +#define xkb_key_mod_mask_remove_consumed(state, key, modmask) \ + xkb_state_mod_mask_remove_consumed(state, key, modmask) + +#define xkb_map_num_groups(keymap) xkb_keymap_num_layouts(keymap) +#define xkb_key_num_groups(keymap, key) \ + xkb_keymap_num_layouts_for_key(keymap, key) +#define xkb_map_group_get_name(keymap, idx) \ + xkb_keymap_layout_get_name(keymap, idx) +#define xkb_map_group_get_index(keymap, str) \ + xkb_keymap_layout_get_index(keymap, str) + +#define xkb_map_num_leds(keymap) xkb_keymap_num_leds(keymap) +#define xkb_map_led_get_name(keymap, idx) xkb_keymap_led_get_name(keymap, idx) +#define xkb_map_led_get_index(keymap, str) \ + xkb_keymap_led_get_index(keymap, str) + +#define xkb_key_repeats(keymap, key) xkb_keymap_key_repeats(keymap, key) + +#define xkb_key_get_syms(state, key, syms_out) \ + xkb_state_key_get_syms(state, key, syms_out) + +#define xkb_state_group_name_is_active(state, name, type) \ + xkb_state_layout_name_is_active(state, name, type) +#define xkb_state_group_index_is_active(state, idx, type) \ + xkb_state_layout_index_is_active(state, idx, type) + +#define xkb_state_serialize_group(state, component) \ + xkb_state_serialize_layout(state, component) + +#define xkb_state_get_map(state) xkb_state_get_keymap(state) + +/* Not needed anymore, since there's NO_FLAGS. */ +#define XKB_MAP_COMPILE_PLACEHOLDER XKB_KEYMAP_COMPILE_NO_FLAGS +#define XKB_MAP_COMPILE_NO_FLAGS XKB_KEYMAP_COMPILE_NO_FLAGS + +#endif diff --git a/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compose.h b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compose.h new file mode 100644 index 0000000000..8b41b987aa --- /dev/null +++ b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compose.h @@ -0,0 +1,500 @@ +/* + * Copyright © 2013 Ran Benita + * + * 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 (including the next + * paragraph) 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. + */ + +#ifndef _XKBCOMMON_COMPOSE_H +#define _XKBCOMMON_COMPOSE_H + +#include <xkbcommon/xkbcommon.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file + * libxkbcommon Compose API - support for Compose and dead-keys. + */ + +/** + * @defgroup compose Compose and dead-keys support + * Support for Compose and dead-keys. + * @since 0.5.0 + * + * @{ + */ + +/** + * @page compose-overview Overview + * @parblock + * + * Compose and dead-keys are a common feature of many keyboard input + * systems. They extend the range of the keysysm that can be produced + * directly from a keyboard by using a sequence of key strokes, instead + * of just one. + * + * Here are some example sequences, in the libX11 Compose file format: + * + * <dead_acute> <a> : "á" aacute # LATIN SMALL LETTER A WITH ACUTE + * <Multi_key> <A> <T> : "@" at # COMMERCIAL AT + * + * When the user presses a key which produces the `<dead_acute>` keysym, + * nothing initially happens (thus the key is dubbed a "dead-key"). But + * when the user enters `<a>`, "á" is "composed", in place of "a". If + * instead the user had entered a keysym which does not follow + * `<dead_acute>` in any compose sequence, the sequence is said to be + * "cancelled". + * + * Compose files define many such sequences. For a description of the + * common file format for Compose files, see the Compose(5) man page. + * + * A successfuly-composed sequence has two results: a keysym and a UTF-8 + * string. At least one of the two is defined for each sequence. If only + * a keysym is given, the keysym's string representation is used for the + * result string (using xkb_keysym_to_utf8()). + * + * This library provides low-level support for Compose file parsing and + * processing. Higher-level APIs (such as libX11's `Xutf8LookupString`(3)) + * may be built upon it, or it can be used directly. + * + * @endparblock + */ + +/** + * @page compose-conflicting Conflicting Sequences + * @parblock + * + * To avoid ambiguity, a sequence is not allowed to be a prefix of another. + * In such a case, the conflict is resolved thus: + * + * 1. A longer sequence overrides a shorter one. + * 2. An equal sequence overrides an existing one. + * 3. A shorter sequence does not override a longer one. + * + * Sequences of length 1 are allowed. + * + * @endparblock + */ + +/** + * @page compose-cancellation Cancellation Behavior + * @parblock + * + * What should happen when a sequence is cancelled? For example, consider + * there are only the above sequences, and the input keysyms are + * `<dead_acute> <b>`. There are a few approaches: + * + * 1. Swallow the cancelling keysym; that is, no keysym is produced. + * This is the approach taken by libX11. + * 2. Let the cancelling keysym through; that is, `<b>` is produced. + * 3. Replay the entire sequence; that is, `<dead_acute> <b>` is produced. + * This is the approach taken by Microsoft Windows (approximately; + * instead of `<dead_acute>`, the underlying key is used. This is + * difficult to simulate with XKB keymaps). + * + * You can program whichever approach best fits users' expectations. + * + * @endparblock + */ + +/** + * @struct xkb_compose_table + * Opaque Compose table object. + * + * The compose table holds the definitions of the Compose sequences, as + * gathered from Compose files. It is immutable. + */ +struct xkb_compose_table; + +/** + * @struct xkb_compose_state + * Opaque Compose state object. + * + * The compose state maintains state for compose sequence matching, such + * as which possible sequences are being matched, and the position within + * these sequences. It acts as a simple state machine wherein keysyms are + * the input, and composed keysyms and strings are the output. + * + * The compose state is usually associated with a keyboard device. + */ +struct xkb_compose_state; + +/** Flags affecting Compose file compilation. */ +enum xkb_compose_compile_flags { + /** Do not apply any flags. */ + XKB_COMPOSE_COMPILE_NO_FLAGS = 0 +}; + +/** The recognized Compose file formats. */ +enum xkb_compose_format { + /** The classic libX11 Compose text format, described in Compose(5). */ + XKB_COMPOSE_FORMAT_TEXT_V1 = 1 +}; + +/** + * @page compose-locale Compose Locale + * @parblock + * + * Compose files are locale dependent: + * - Compose files are written for a locale, and the locale is used when + * searching for the appropriate file to use. + * - Compose files may reference the locale internally, with directives + * such as \%L. + * + * As such, functions like xkb_compose_table_new_from_locale() require + * a `locale` parameter. This will usually be the current locale (see + * locale(7) for more details). You may also want to allow the user to + * explicitly configure it, so he can use the Compose file of a given + * locale, but not use that locale for other things. + * + * You may query the current locale as follows: + * @code + * const char *locale; + * locale = setlocale(LC_CTYPE, NULL); + * @endcode + * + * This will only give useful results if the program had previously set + * the current locale using setlocale(3), with `LC_CTYPE` or `LC_ALL` + * and a non-NULL argument. + * + * If you prefer not to use the locale system of the C runtime library, + * you may nevertheless obtain the user's locale directly using + * environment variables, as described in locale(7). For example, + * @code + * const char *locale; + * locale = getenv("LC_ALL"); + * if (!locale || !*locale) + * locale = getenv("LC_CTYPE"); + * if (!locale || !*locale) + * locale = getenv("LANG"); + * if (!locale || !*locale) + * locale = "C"; + * @endcode + * + * Note that some locales supported by the C standard library may not + * have a Compose file assigned. + * + * @endparblock + */ + +/** + * Create a compose table for a given locale. + * + * The locale is used for searching the file-system for an appropriate + * Compose file. The search order is described in Compose(5). It is + * affected by the following environment variables: + * + * 1. `XCOMPOSEFILE` - see Compose(5). + * 2. `XDG_CONFIG_HOME` - before `$HOME/.XCompose` is checked, + * `$XDG_CONFIG_HOME/XCompose` is checked (with a fall back to + * `$HOME/.config/XCompose` if `XDG_CONFIG_HOME` is not defined). + * This is a libxkbcommon extension to the search procedure in + * Compose(5) (since libxkbcommon 1.0.0). Note that other + * implementations, such as libX11, might not find a Compose file in + * this path. + * 3. `HOME` - see Compose(5). + * 4. `XLOCALEDIR` - if set, used as the base directory for the system's + * X locale files, e.g. `/usr/share/X11/locale`, instead of the + * preconfigured directory. + * + * @param context + * The library context in which to create the compose table. + * @param locale + * The current locale. See @ref compose-locale. + * \n + * The value is copied, so it is safe to pass the result of getenv(3) + * (or similar) without fear of it being invalidated by a subsequent + * setenv(3) (or similar). + * @param flags + * Optional flags for the compose table, or 0. + * + * @returns A compose table for the given locale, or NULL if the + * compilation failed or a Compose file was not found. + * + * @memberof xkb_compose_table + */ +struct xkb_compose_table * +xkb_compose_table_new_from_locale(struct xkb_context *context, + const char *locale, + enum xkb_compose_compile_flags flags); + +/** + * Create a new compose table from a Compose file. + * + * @param context + * The library context in which to create the compose table. + * @param file + * The Compose file to compile. + * @param locale + * The current locale. See @ref compose-locale. + * @param format + * The text format of the Compose file to compile. + * @param flags + * Optional flags for the compose table, or 0. + * + * @returns A compose table compiled from the given file, or NULL if + * the compilation failed. + * + * @memberof xkb_compose_table + */ +struct xkb_compose_table * +xkb_compose_table_new_from_file(struct xkb_context *context, + FILE *file, + const char *locale, + enum xkb_compose_format format, + enum xkb_compose_compile_flags flags); + +/** + * Create a new compose table from a memory buffer. + * + * This is just like xkb_compose_table_new_from_file(), but instead of + * a file, gets the table as one enormous string. + * + * @see xkb_compose_table_new_from_file() + * @memberof xkb_compose_table + */ +struct xkb_compose_table * +xkb_compose_table_new_from_buffer(struct xkb_context *context, + const char *buffer, size_t length, + const char *locale, + enum xkb_compose_format format, + enum xkb_compose_compile_flags flags); + +/** + * Take a new reference on a compose table. + * + * @returns The passed in object. + * + * @memberof xkb_compose_table + */ +struct xkb_compose_table * +xkb_compose_table_ref(struct xkb_compose_table *table); + +/** + * Release a reference on a compose table, and possibly free it. + * + * @param table The object. If it is NULL, this function does nothing. + * + * @memberof xkb_compose_table + */ +void +xkb_compose_table_unref(struct xkb_compose_table *table); + +/** Flags for compose state creation. */ +enum xkb_compose_state_flags { + /** Do not apply any flags. */ + XKB_COMPOSE_STATE_NO_FLAGS = 0 +}; + +/** + * Create a new compose state object. + * + * @param table + * The compose table the state will use. + * @param flags + * Optional flags for the compose state, or 0. + * + * @returns A new compose state, or NULL on failure. + * + * @memberof xkb_compose_state + */ +struct xkb_compose_state * +xkb_compose_state_new(struct xkb_compose_table *table, + enum xkb_compose_state_flags flags); + +/** + * Take a new reference on a compose state object. + * + * @returns The passed in object. + * + * @memberof xkb_compose_state + */ +struct xkb_compose_state * +xkb_compose_state_ref(struct xkb_compose_state *state); + +/** + * Release a reference on a compose state object, and possibly free it. + * + * @param state The object. If NULL, do nothing. + * + * @memberof xkb_compose_state + */ +void +xkb_compose_state_unref(struct xkb_compose_state *state); + +/** + * Get the compose table which a compose state object is using. + * + * @returns The compose table which was passed to xkb_compose_state_new() + * when creating this state object. + * + * This function does not take a new reference on the compose table; you + * must explicitly reference it yourself if you plan to use it beyond the + * lifetime of the state. + * + * @memberof xkb_compose_state + */ +struct xkb_compose_table * +xkb_compose_state_get_compose_table(struct xkb_compose_state *state); + +/** Status of the Compose sequence state machine. */ +enum xkb_compose_status { + /** The initial state; no sequence has started yet. */ + XKB_COMPOSE_NOTHING, + /** In the middle of a sequence. */ + XKB_COMPOSE_COMPOSING, + /** A complete sequence has been matched. */ + XKB_COMPOSE_COMPOSED, + /** The last sequence was cancelled due to an unmatched keysym. */ + XKB_COMPOSE_CANCELLED +}; + +/** The effect of a keysym fed to xkb_compose_state_feed(). */ +enum xkb_compose_feed_result { + /** The keysym had no effect - it did not affect the status. */ + XKB_COMPOSE_FEED_IGNORED, + /** The keysym started, advanced or cancelled a sequence. */ + XKB_COMPOSE_FEED_ACCEPTED +}; + +/** + * Feed one keysym to the Compose sequence state machine. + * + * This function can advance into a compose sequence, cancel a sequence, + * start a new sequence, or do nothing in particular. The resulting + * status may be observed with xkb_compose_state_get_status(). + * + * Some keysyms, such as keysyms for modifier keys, are ignored - they + * have no effect on the status or otherwise. + * + * The following is a description of the possible status transitions, in + * the format CURRENT STATUS => NEXT STATUS, given a non-ignored input + * keysym `keysym`: + * + @verbatim + NOTHING or CANCELLED or COMPOSED => + NOTHING if keysym does not start a sequence. + COMPOSING if keysym starts a sequence. + COMPOSED if keysym starts and terminates a single-keysym sequence. + + COMPOSING => + COMPOSING if keysym advances any of the currently possible + sequences but does not terminate any of them. + COMPOSED if keysym terminates one of the currently possible + sequences. + CANCELLED if keysym does not advance any of the currently + possible sequences. + @endverbatim + * + * The current Compose formats do not support multiple-keysyms. + * Therefore, if you are using a function such as xkb_state_key_get_syms() + * and it returns more than one keysym, consider feeding XKB_KEY_NoSymbol + * instead. + * + * @param state + * The compose state object. + * @param keysym + * A keysym, usually obtained after a key-press event, with a + * function such as xkb_state_key_get_one_sym(). + * + * @returns Whether the keysym was ignored. This is useful, for example, + * if you want to keep a record of the sequence matched thus far. + * + * @memberof xkb_compose_state + */ +enum xkb_compose_feed_result +xkb_compose_state_feed(struct xkb_compose_state *state, + xkb_keysym_t keysym); + +/** + * Reset the Compose sequence state machine. + * + * The status is set to XKB_COMPOSE_NOTHING, and the current sequence + * is discarded. + * + * @memberof xkb_compose_state + */ +void +xkb_compose_state_reset(struct xkb_compose_state *state); + +/** + * Get the current status of the compose state machine. + * + * @see xkb_compose_status + * @memberof xkb_compose_state + **/ +enum xkb_compose_status +xkb_compose_state_get_status(struct xkb_compose_state *state); + +/** + * Get the result Unicode/UTF-8 string for a composed sequence. + * + * See @ref compose-overview for more details. This function is only + * useful when the status is XKB_COMPOSE_COMPOSED. + * + * @param[in] state + * The compose state. + * @param[out] buffer + * A buffer to write the string into. + * @param[in] size + * Size of the buffer. + * + * @warning If the buffer passed is too small, the string is truncated + * (though still NUL-terminated). + * + * @returns + * The number of bytes required for the string, excluding the NUL byte. + * If the sequence is not complete, or does not have a viable result + * string, returns 0, and sets `buffer` to the empty string (if possible). + * @returns + * You may check if truncation has occurred by comparing the return value + * with the size of `buffer`, similarly to the `snprintf`(3) function. + * You may safely pass NULL and 0 to `buffer` and `size` to find the + * required size (without the NUL-byte). + * + * @memberof xkb_compose_state + **/ +int +xkb_compose_state_get_utf8(struct xkb_compose_state *state, + char *buffer, size_t size); + +/** + * Get the result keysym for a composed sequence. + * + * See @ref compose-overview for more details. This function is only + * useful when the status is XKB_COMPOSE_COMPOSED. + * + * @returns The result keysym. If the sequence is not complete, or does + * not specify a result keysym, returns XKB_KEY_NoSymbol. + * + * @memberof xkb_compose_state + **/ +xkb_keysym_t +xkb_compose_state_get_one_sym(struct xkb_compose_state *state); + +/** @} */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* _XKBCOMMON_COMPOSE_H */ diff --git a/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-keysyms.h b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-keysyms.h new file mode 100644 index 0000000000..7c75c29711 --- /dev/null +++ b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-keysyms.h @@ -0,0 +1,3248 @@ +#ifndef _XKBCOMMON_KEYSYMS_H +#define _XKBCOMMON_KEYSYMS_H + +/* This file is autogenerated; please do not commit directly. */ + +#define XKB_KEY_NoSymbol 0x000000 /* Special KeySym */ + +/*********************************************************** +Copyright 1987, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * The "X11 Window System Protocol" standard defines in Appendix A the + * keysym codes. These 29-bit integer values identify characters or + * functions associated with each key (e.g., via the visible + * engraving) of a keyboard layout. This file assigns mnemonic macro + * names for these keysyms. + * + * This file is also compiled (by src/util/makekeys.c in libX11) into + * hash tables that can be accessed with X11 library functions such as + * XStringToKeysym() and XKeysymToString(). + * + * Where a keysym corresponds one-to-one to an ISO 10646 / Unicode + * character, this is noted in a comment that provides both the U+xxxx + * Unicode position, as well as the official Unicode name of the + * character. + * + * Where the correspondence is either not one-to-one or semantically + * unclear, the Unicode position and name are enclosed in + * parentheses. Such legacy keysyms should be considered deprecated + * and are not recommended for use in future keyboard mappings. + * + * For any future extension of the keysyms with characters already + * found in ISO 10646 / Unicode, the following algorithm shall be + * used. The new keysym code position will simply be the character's + * Unicode number plus 0x01000000. The keysym values in the range + * 0x01000100 to 0x0110ffff are reserved to represent Unicode + * characters in the range U+0100 to U+10FFFF. + * + * While most newer Unicode-based X11 clients do already accept + * Unicode-mapped keysyms in the range 0x01000100 to 0x0110ffff, it + * will remain necessary for clients -- in the interest of + * compatibility with existing servers -- to also understand the + * existing legacy keysym values in the range 0x0100 to 0x20ff. + * + * Where several mnemonic names are defined for the same keysym in this + * file, all but the first one listed should be considered deprecated. + * + * Mnemonic names for keysyms are defined in this file with lines + * that match one of these Perl regular expressions: + * + * /^\#define XKB_KEY_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*\/\* U\+([0-9A-F]{4,6}) (.*) \*\/\s*$/ + * /^\#define XKB_KEY_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*\/\*\(U\+([0-9A-F]{4,6}) (.*)\)\*\/\s*$/ + * /^\#define XKB_KEY_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*(\/\*\s*(.*)\s*\*\/)?\s*$/ + * + * Before adding new keysyms, please do consider the following: In + * addition to the keysym names defined in this file, the + * XStringToKeysym() and XKeysymToString() functions will also handle + * any keysym string of the form "U0020" to "U007E" and "U00A0" to + * "U10FFFF" for all possible Unicode characters. In other words, + * every possible Unicode character has already a keysym string + * defined algorithmically, even if it is not listed here. Therefore, + * defining an additional keysym macro is only necessary where a + * non-hexadecimal mnemonic name is needed, or where the new keysym + * does not represent any existing Unicode character. + * + * When adding new keysyms to this file, do not forget to also update the + * following as needed: + * + * - the mappings in src/KeyBind.c in the libX11 repo + * https://gitlab.freedesktop.org/xorg/lib/libx11 + * + * - the protocol specification in specs/keysyms.xml in this repo + * https://gitlab.freedesktop.org/xorg/proto/xorgproto + * + */ + +#define XKB_KEY_VoidSymbol 0xffffff /* Void symbol */ + +/* + * TTY function keys, cleverly chosen to map to ASCII, for convenience of + * programming, but could have been arbitrary (at the cost of lookup + * tables in client code). + */ + +#define XKB_KEY_BackSpace 0xff08 /* Back space, back char */ +#define XKB_KEY_Tab 0xff09 +#define XKB_KEY_Linefeed 0xff0a /* Linefeed, LF */ +#define XKB_KEY_Clear 0xff0b +#define XKB_KEY_Return 0xff0d /* Return, enter */ +#define XKB_KEY_Pause 0xff13 /* Pause, hold */ +#define XKB_KEY_Scroll_Lock 0xff14 +#define XKB_KEY_Sys_Req 0xff15 +#define XKB_KEY_Escape 0xff1b +#define XKB_KEY_Delete 0xffff /* Delete, rubout */ + + + +/* International & multi-key character composition */ + +#define XKB_KEY_Multi_key 0xff20 /* Multi-key character compose */ +#define XKB_KEY_Codeinput 0xff37 +#define XKB_KEY_SingleCandidate 0xff3c +#define XKB_KEY_MultipleCandidate 0xff3d +#define XKB_KEY_PreviousCandidate 0xff3e + +/* Japanese keyboard support */ + +#define XKB_KEY_Kanji 0xff21 /* Kanji, Kanji convert */ +#define XKB_KEY_Muhenkan 0xff22 /* Cancel Conversion */ +#define XKB_KEY_Henkan_Mode 0xff23 /* Start/Stop Conversion */ +#define XKB_KEY_Henkan 0xff23 /* Alias for Henkan_Mode */ +#define XKB_KEY_Romaji 0xff24 /* to Romaji */ +#define XKB_KEY_Hiragana 0xff25 /* to Hiragana */ +#define XKB_KEY_Katakana 0xff26 /* to Katakana */ +#define XKB_KEY_Hiragana_Katakana 0xff27 /* Hiragana/Katakana toggle */ +#define XKB_KEY_Zenkaku 0xff28 /* to Zenkaku */ +#define XKB_KEY_Hankaku 0xff29 /* to Hankaku */ +#define XKB_KEY_Zenkaku_Hankaku 0xff2a /* Zenkaku/Hankaku toggle */ +#define XKB_KEY_Touroku 0xff2b /* Add to Dictionary */ +#define XKB_KEY_Massyo 0xff2c /* Delete from Dictionary */ +#define XKB_KEY_Kana_Lock 0xff2d /* Kana Lock */ +#define XKB_KEY_Kana_Shift 0xff2e /* Kana Shift */ +#define XKB_KEY_Eisu_Shift 0xff2f /* Alphanumeric Shift */ +#define XKB_KEY_Eisu_toggle 0xff30 /* Alphanumeric toggle */ +#define XKB_KEY_Kanji_Bangou 0xff37 /* Codeinput */ +#define XKB_KEY_Zen_Koho 0xff3d /* Multiple/All Candidate(s) */ +#define XKB_KEY_Mae_Koho 0xff3e /* Previous Candidate */ + +/* 0xff31 thru 0xff3f are under XK_KOREAN */ + +/* Cursor control & motion */ + +#define XKB_KEY_Home 0xff50 +#define XKB_KEY_Left 0xff51 /* Move left, left arrow */ +#define XKB_KEY_Up 0xff52 /* Move up, up arrow */ +#define XKB_KEY_Right 0xff53 /* Move right, right arrow */ +#define XKB_KEY_Down 0xff54 /* Move down, down arrow */ +#define XKB_KEY_Prior 0xff55 /* Prior, previous */ +#define XKB_KEY_Page_Up 0xff55 +#define XKB_KEY_Next 0xff56 /* Next */ +#define XKB_KEY_Page_Down 0xff56 +#define XKB_KEY_End 0xff57 /* EOL */ +#define XKB_KEY_Begin 0xff58 /* BOL */ + + +/* Misc functions */ + +#define XKB_KEY_Select 0xff60 /* Select, mark */ +#define XKB_KEY_Print 0xff61 +#define XKB_KEY_Execute 0xff62 /* Execute, run, do */ +#define XKB_KEY_Insert 0xff63 /* Insert, insert here */ +#define XKB_KEY_Undo 0xff65 +#define XKB_KEY_Redo 0xff66 /* Redo, again */ +#define XKB_KEY_Menu 0xff67 +#define XKB_KEY_Find 0xff68 /* Find, search */ +#define XKB_KEY_Cancel 0xff69 /* Cancel, stop, abort, exit */ +#define XKB_KEY_Help 0xff6a /* Help */ +#define XKB_KEY_Break 0xff6b +#define XKB_KEY_Mode_switch 0xff7e /* Character set switch */ +#define XKB_KEY_script_switch 0xff7e /* Alias for mode_switch */ +#define XKB_KEY_Num_Lock 0xff7f + +/* Keypad functions, keypad numbers cleverly chosen to map to ASCII */ + +#define XKB_KEY_KP_Space 0xff80 /* Space */ +#define XKB_KEY_KP_Tab 0xff89 +#define XKB_KEY_KP_Enter 0xff8d /* Enter */ +#define XKB_KEY_KP_F1 0xff91 /* PF1, KP_A, ... */ +#define XKB_KEY_KP_F2 0xff92 +#define XKB_KEY_KP_F3 0xff93 +#define XKB_KEY_KP_F4 0xff94 +#define XKB_KEY_KP_Home 0xff95 +#define XKB_KEY_KP_Left 0xff96 +#define XKB_KEY_KP_Up 0xff97 +#define XKB_KEY_KP_Right 0xff98 +#define XKB_KEY_KP_Down 0xff99 +#define XKB_KEY_KP_Prior 0xff9a +#define XKB_KEY_KP_Page_Up 0xff9a +#define XKB_KEY_KP_Next 0xff9b +#define XKB_KEY_KP_Page_Down 0xff9b +#define XKB_KEY_KP_End 0xff9c +#define XKB_KEY_KP_Begin 0xff9d +#define XKB_KEY_KP_Insert 0xff9e +#define XKB_KEY_KP_Delete 0xff9f +#define XKB_KEY_KP_Equal 0xffbd /* Equals */ +#define XKB_KEY_KP_Multiply 0xffaa +#define XKB_KEY_KP_Add 0xffab +#define XKB_KEY_KP_Separator 0xffac /* Separator, often comma */ +#define XKB_KEY_KP_Subtract 0xffad +#define XKB_KEY_KP_Decimal 0xffae +#define XKB_KEY_KP_Divide 0xffaf + +#define XKB_KEY_KP_0 0xffb0 +#define XKB_KEY_KP_1 0xffb1 +#define XKB_KEY_KP_2 0xffb2 +#define XKB_KEY_KP_3 0xffb3 +#define XKB_KEY_KP_4 0xffb4 +#define XKB_KEY_KP_5 0xffb5 +#define XKB_KEY_KP_6 0xffb6 +#define XKB_KEY_KP_7 0xffb7 +#define XKB_KEY_KP_8 0xffb8 +#define XKB_KEY_KP_9 0xffb9 + + + +/* + * Auxiliary functions; note the duplicate definitions for left and right + * function keys; Sun keyboards and a few other manufacturers have such + * function key groups on the left and/or right sides of the keyboard. + * We've not found a keyboard with more than 35 function keys total. + */ + +#define XKB_KEY_F1 0xffbe +#define XKB_KEY_F2 0xffbf +#define XKB_KEY_F3 0xffc0 +#define XKB_KEY_F4 0xffc1 +#define XKB_KEY_F5 0xffc2 +#define XKB_KEY_F6 0xffc3 +#define XKB_KEY_F7 0xffc4 +#define XKB_KEY_F8 0xffc5 +#define XKB_KEY_F9 0xffc6 +#define XKB_KEY_F10 0xffc7 +#define XKB_KEY_F11 0xffc8 +#define XKB_KEY_L1 0xffc8 +#define XKB_KEY_F12 0xffc9 +#define XKB_KEY_L2 0xffc9 +#define XKB_KEY_F13 0xffca +#define XKB_KEY_L3 0xffca +#define XKB_KEY_F14 0xffcb +#define XKB_KEY_L4 0xffcb +#define XKB_KEY_F15 0xffcc +#define XKB_KEY_L5 0xffcc +#define XKB_KEY_F16 0xffcd +#define XKB_KEY_L6 0xffcd +#define XKB_KEY_F17 0xffce +#define XKB_KEY_L7 0xffce +#define XKB_KEY_F18 0xffcf +#define XKB_KEY_L8 0xffcf +#define XKB_KEY_F19 0xffd0 +#define XKB_KEY_L9 0xffd0 +#define XKB_KEY_F20 0xffd1 +#define XKB_KEY_L10 0xffd1 +#define XKB_KEY_F21 0xffd2 +#define XKB_KEY_R1 0xffd2 +#define XKB_KEY_F22 0xffd3 +#define XKB_KEY_R2 0xffd3 +#define XKB_KEY_F23 0xffd4 +#define XKB_KEY_R3 0xffd4 +#define XKB_KEY_F24 0xffd5 +#define XKB_KEY_R4 0xffd5 +#define XKB_KEY_F25 0xffd6 +#define XKB_KEY_R5 0xffd6 +#define XKB_KEY_F26 0xffd7 +#define XKB_KEY_R6 0xffd7 +#define XKB_KEY_F27 0xffd8 +#define XKB_KEY_R7 0xffd8 +#define XKB_KEY_F28 0xffd9 +#define XKB_KEY_R8 0xffd9 +#define XKB_KEY_F29 0xffda +#define XKB_KEY_R9 0xffda +#define XKB_KEY_F30 0xffdb +#define XKB_KEY_R10 0xffdb +#define XKB_KEY_F31 0xffdc +#define XKB_KEY_R11 0xffdc +#define XKB_KEY_F32 0xffdd +#define XKB_KEY_R12 0xffdd +#define XKB_KEY_F33 0xffde +#define XKB_KEY_R13 0xffde +#define XKB_KEY_F34 0xffdf +#define XKB_KEY_R14 0xffdf +#define XKB_KEY_F35 0xffe0 +#define XKB_KEY_R15 0xffe0 + +/* Modifiers */ + +#define XKB_KEY_Shift_L 0xffe1 /* Left shift */ +#define XKB_KEY_Shift_R 0xffe2 /* Right shift */ +#define XKB_KEY_Control_L 0xffe3 /* Left control */ +#define XKB_KEY_Control_R 0xffe4 /* Right control */ +#define XKB_KEY_Caps_Lock 0xffe5 /* Caps lock */ +#define XKB_KEY_Shift_Lock 0xffe6 /* Shift lock */ + +#define XKB_KEY_Meta_L 0xffe7 /* Left meta */ +#define XKB_KEY_Meta_R 0xffe8 /* Right meta */ +#define XKB_KEY_Alt_L 0xffe9 /* Left alt */ +#define XKB_KEY_Alt_R 0xffea /* Right alt */ +#define XKB_KEY_Super_L 0xffeb /* Left super */ +#define XKB_KEY_Super_R 0xffec /* Right super */ +#define XKB_KEY_Hyper_L 0xffed /* Left hyper */ +#define XKB_KEY_Hyper_R 0xffee /* Right hyper */ + +/* + * Keyboard (XKB) Extension function and modifier keys + * (from Appendix C of "The X Keyboard Extension: Protocol Specification") + * Byte 3 = 0xfe + */ + +#define XKB_KEY_ISO_Lock 0xfe01 +#define XKB_KEY_ISO_Level2_Latch 0xfe02 +#define XKB_KEY_ISO_Level3_Shift 0xfe03 +#define XKB_KEY_ISO_Level3_Latch 0xfe04 +#define XKB_KEY_ISO_Level3_Lock 0xfe05 +#define XKB_KEY_ISO_Level5_Shift 0xfe11 +#define XKB_KEY_ISO_Level5_Latch 0xfe12 +#define XKB_KEY_ISO_Level5_Lock 0xfe13 +#define XKB_KEY_ISO_Group_Shift 0xff7e /* Alias for mode_switch */ +#define XKB_KEY_ISO_Group_Latch 0xfe06 +#define XKB_KEY_ISO_Group_Lock 0xfe07 +#define XKB_KEY_ISO_Next_Group 0xfe08 +#define XKB_KEY_ISO_Next_Group_Lock 0xfe09 +#define XKB_KEY_ISO_Prev_Group 0xfe0a +#define XKB_KEY_ISO_Prev_Group_Lock 0xfe0b +#define XKB_KEY_ISO_First_Group 0xfe0c +#define XKB_KEY_ISO_First_Group_Lock 0xfe0d +#define XKB_KEY_ISO_Last_Group 0xfe0e +#define XKB_KEY_ISO_Last_Group_Lock 0xfe0f + +#define XKB_KEY_ISO_Left_Tab 0xfe20 +#define XKB_KEY_ISO_Move_Line_Up 0xfe21 +#define XKB_KEY_ISO_Move_Line_Down 0xfe22 +#define XKB_KEY_ISO_Partial_Line_Up 0xfe23 +#define XKB_KEY_ISO_Partial_Line_Down 0xfe24 +#define XKB_KEY_ISO_Partial_Space_Left 0xfe25 +#define XKB_KEY_ISO_Partial_Space_Right 0xfe26 +#define XKB_KEY_ISO_Set_Margin_Left 0xfe27 +#define XKB_KEY_ISO_Set_Margin_Right 0xfe28 +#define XKB_KEY_ISO_Release_Margin_Left 0xfe29 +#define XKB_KEY_ISO_Release_Margin_Right 0xfe2a +#define XKB_KEY_ISO_Release_Both_Margins 0xfe2b +#define XKB_KEY_ISO_Fast_Cursor_Left 0xfe2c +#define XKB_KEY_ISO_Fast_Cursor_Right 0xfe2d +#define XKB_KEY_ISO_Fast_Cursor_Up 0xfe2e +#define XKB_KEY_ISO_Fast_Cursor_Down 0xfe2f +#define XKB_KEY_ISO_Continuous_Underline 0xfe30 +#define XKB_KEY_ISO_Discontinuous_Underline 0xfe31 +#define XKB_KEY_ISO_Emphasize 0xfe32 +#define XKB_KEY_ISO_Center_Object 0xfe33 +#define XKB_KEY_ISO_Enter 0xfe34 + +#define XKB_KEY_dead_grave 0xfe50 +#define XKB_KEY_dead_acute 0xfe51 +#define XKB_KEY_dead_circumflex 0xfe52 +#define XKB_KEY_dead_tilde 0xfe53 +#define XKB_KEY_dead_perispomeni 0xfe53 /* alias for dead_tilde */ +#define XKB_KEY_dead_macron 0xfe54 +#define XKB_KEY_dead_breve 0xfe55 +#define XKB_KEY_dead_abovedot 0xfe56 +#define XKB_KEY_dead_diaeresis 0xfe57 +#define XKB_KEY_dead_abovering 0xfe58 +#define XKB_KEY_dead_doubleacute 0xfe59 +#define XKB_KEY_dead_caron 0xfe5a +#define XKB_KEY_dead_cedilla 0xfe5b +#define XKB_KEY_dead_ogonek 0xfe5c +#define XKB_KEY_dead_iota 0xfe5d +#define XKB_KEY_dead_voiced_sound 0xfe5e +#define XKB_KEY_dead_semivoiced_sound 0xfe5f +#define XKB_KEY_dead_belowdot 0xfe60 +#define XKB_KEY_dead_hook 0xfe61 +#define XKB_KEY_dead_horn 0xfe62 +#define XKB_KEY_dead_stroke 0xfe63 +#define XKB_KEY_dead_abovecomma 0xfe64 +#define XKB_KEY_dead_psili 0xfe64 /* alias for dead_abovecomma */ +#define XKB_KEY_dead_abovereversedcomma 0xfe65 +#define XKB_KEY_dead_dasia 0xfe65 /* alias for dead_abovereversedcomma */ +#define XKB_KEY_dead_doublegrave 0xfe66 +#define XKB_KEY_dead_belowring 0xfe67 +#define XKB_KEY_dead_belowmacron 0xfe68 +#define XKB_KEY_dead_belowcircumflex 0xfe69 +#define XKB_KEY_dead_belowtilde 0xfe6a +#define XKB_KEY_dead_belowbreve 0xfe6b +#define XKB_KEY_dead_belowdiaeresis 0xfe6c +#define XKB_KEY_dead_invertedbreve 0xfe6d +#define XKB_KEY_dead_belowcomma 0xfe6e +#define XKB_KEY_dead_currency 0xfe6f + +/* extra dead elements for German T3 layout */ +#define XKB_KEY_dead_lowline 0xfe90 +#define XKB_KEY_dead_aboveverticalline 0xfe91 +#define XKB_KEY_dead_belowverticalline 0xfe92 +#define XKB_KEY_dead_longsolidusoverlay 0xfe93 + +/* dead vowels for universal syllable entry */ +#define XKB_KEY_dead_a 0xfe80 +#define XKB_KEY_dead_A 0xfe81 +#define XKB_KEY_dead_e 0xfe82 +#define XKB_KEY_dead_E 0xfe83 +#define XKB_KEY_dead_i 0xfe84 +#define XKB_KEY_dead_I 0xfe85 +#define XKB_KEY_dead_o 0xfe86 +#define XKB_KEY_dead_O 0xfe87 +#define XKB_KEY_dead_u 0xfe88 +#define XKB_KEY_dead_U 0xfe89 +#define XKB_KEY_dead_small_schwa 0xfe8a +#define XKB_KEY_dead_capital_schwa 0xfe8b + +#define XKB_KEY_dead_greek 0xfe8c + +#define XKB_KEY_First_Virtual_Screen 0xfed0 +#define XKB_KEY_Prev_Virtual_Screen 0xfed1 +#define XKB_KEY_Next_Virtual_Screen 0xfed2 +#define XKB_KEY_Last_Virtual_Screen 0xfed4 +#define XKB_KEY_Terminate_Server 0xfed5 + +#define XKB_KEY_AccessX_Enable 0xfe70 +#define XKB_KEY_AccessX_Feedback_Enable 0xfe71 +#define XKB_KEY_RepeatKeys_Enable 0xfe72 +#define XKB_KEY_SlowKeys_Enable 0xfe73 +#define XKB_KEY_BounceKeys_Enable 0xfe74 +#define XKB_KEY_StickyKeys_Enable 0xfe75 +#define XKB_KEY_MouseKeys_Enable 0xfe76 +#define XKB_KEY_MouseKeys_Accel_Enable 0xfe77 +#define XKB_KEY_Overlay1_Enable 0xfe78 +#define XKB_KEY_Overlay2_Enable 0xfe79 +#define XKB_KEY_AudibleBell_Enable 0xfe7a + +#define XKB_KEY_Pointer_Left 0xfee0 +#define XKB_KEY_Pointer_Right 0xfee1 +#define XKB_KEY_Pointer_Up 0xfee2 +#define XKB_KEY_Pointer_Down 0xfee3 +#define XKB_KEY_Pointer_UpLeft 0xfee4 +#define XKB_KEY_Pointer_UpRight 0xfee5 +#define XKB_KEY_Pointer_DownLeft 0xfee6 +#define XKB_KEY_Pointer_DownRight 0xfee7 +#define XKB_KEY_Pointer_Button_Dflt 0xfee8 +#define XKB_KEY_Pointer_Button1 0xfee9 +#define XKB_KEY_Pointer_Button2 0xfeea +#define XKB_KEY_Pointer_Button3 0xfeeb +#define XKB_KEY_Pointer_Button4 0xfeec +#define XKB_KEY_Pointer_Button5 0xfeed +#define XKB_KEY_Pointer_DblClick_Dflt 0xfeee +#define XKB_KEY_Pointer_DblClick1 0xfeef +#define XKB_KEY_Pointer_DblClick2 0xfef0 +#define XKB_KEY_Pointer_DblClick3 0xfef1 +#define XKB_KEY_Pointer_DblClick4 0xfef2 +#define XKB_KEY_Pointer_DblClick5 0xfef3 +#define XKB_KEY_Pointer_Drag_Dflt 0xfef4 +#define XKB_KEY_Pointer_Drag1 0xfef5 +#define XKB_KEY_Pointer_Drag2 0xfef6 +#define XKB_KEY_Pointer_Drag3 0xfef7 +#define XKB_KEY_Pointer_Drag4 0xfef8 +#define XKB_KEY_Pointer_Drag5 0xfefd + +#define XKB_KEY_Pointer_EnableKeys 0xfef9 +#define XKB_KEY_Pointer_Accelerate 0xfefa +#define XKB_KEY_Pointer_DfltBtnNext 0xfefb +#define XKB_KEY_Pointer_DfltBtnPrev 0xfefc + +/* Single-Stroke Multiple-Character N-Graph Keysyms For The X Input Method */ + +#define XKB_KEY_ch 0xfea0 +#define XKB_KEY_Ch 0xfea1 +#define XKB_KEY_CH 0xfea2 +#define XKB_KEY_c_h 0xfea3 +#define XKB_KEY_C_h 0xfea4 +#define XKB_KEY_C_H 0xfea5 + + +/* + * 3270 Terminal Keys + * Byte 3 = 0xfd + */ + +#define XKB_KEY_3270_Duplicate 0xfd01 +#define XKB_KEY_3270_FieldMark 0xfd02 +#define XKB_KEY_3270_Right2 0xfd03 +#define XKB_KEY_3270_Left2 0xfd04 +#define XKB_KEY_3270_BackTab 0xfd05 +#define XKB_KEY_3270_EraseEOF 0xfd06 +#define XKB_KEY_3270_EraseInput 0xfd07 +#define XKB_KEY_3270_Reset 0xfd08 +#define XKB_KEY_3270_Quit 0xfd09 +#define XKB_KEY_3270_PA1 0xfd0a +#define XKB_KEY_3270_PA2 0xfd0b +#define XKB_KEY_3270_PA3 0xfd0c +#define XKB_KEY_3270_Test 0xfd0d +#define XKB_KEY_3270_Attn 0xfd0e +#define XKB_KEY_3270_CursorBlink 0xfd0f +#define XKB_KEY_3270_AltCursor 0xfd10 +#define XKB_KEY_3270_KeyClick 0xfd11 +#define XKB_KEY_3270_Jump 0xfd12 +#define XKB_KEY_3270_Ident 0xfd13 +#define XKB_KEY_3270_Rule 0xfd14 +#define XKB_KEY_3270_Copy 0xfd15 +#define XKB_KEY_3270_Play 0xfd16 +#define XKB_KEY_3270_Setup 0xfd17 +#define XKB_KEY_3270_Record 0xfd18 +#define XKB_KEY_3270_ChangeScreen 0xfd19 +#define XKB_KEY_3270_DeleteWord 0xfd1a +#define XKB_KEY_3270_ExSelect 0xfd1b +#define XKB_KEY_3270_CursorSelect 0xfd1c +#define XKB_KEY_3270_PrintScreen 0xfd1d +#define XKB_KEY_3270_Enter 0xfd1e + +/* + * Latin 1 + * (ISO/IEC 8859-1 = Unicode U+0020..U+00FF) + * Byte 3 = 0 + */ +#define XKB_KEY_space 0x0020 /* U+0020 SPACE */ +#define XKB_KEY_exclam 0x0021 /* U+0021 EXCLAMATION MARK */ +#define XKB_KEY_quotedbl 0x0022 /* U+0022 QUOTATION MARK */ +#define XKB_KEY_numbersign 0x0023 /* U+0023 NUMBER SIGN */ +#define XKB_KEY_dollar 0x0024 /* U+0024 DOLLAR SIGN */ +#define XKB_KEY_percent 0x0025 /* U+0025 PERCENT SIGN */ +#define XKB_KEY_ampersand 0x0026 /* U+0026 AMPERSAND */ +#define XKB_KEY_apostrophe 0x0027 /* U+0027 APOSTROPHE */ +#define XKB_KEY_quoteright 0x0027 /* deprecated */ +#define XKB_KEY_parenleft 0x0028 /* U+0028 LEFT PARENTHESIS */ +#define XKB_KEY_parenright 0x0029 /* U+0029 RIGHT PARENTHESIS */ +#define XKB_KEY_asterisk 0x002a /* U+002A ASTERISK */ +#define XKB_KEY_plus 0x002b /* U+002B PLUS SIGN */ +#define XKB_KEY_comma 0x002c /* U+002C COMMA */ +#define XKB_KEY_minus 0x002d /* U+002D HYPHEN-MINUS */ +#define XKB_KEY_period 0x002e /* U+002E FULL STOP */ +#define XKB_KEY_slash 0x002f /* U+002F SOLIDUS */ +#define XKB_KEY_0 0x0030 /* U+0030 DIGIT ZERO */ +#define XKB_KEY_1 0x0031 /* U+0031 DIGIT ONE */ +#define XKB_KEY_2 0x0032 /* U+0032 DIGIT TWO */ +#define XKB_KEY_3 0x0033 /* U+0033 DIGIT THREE */ +#define XKB_KEY_4 0x0034 /* U+0034 DIGIT FOUR */ +#define XKB_KEY_5 0x0035 /* U+0035 DIGIT FIVE */ +#define XKB_KEY_6 0x0036 /* U+0036 DIGIT SIX */ +#define XKB_KEY_7 0x0037 /* U+0037 DIGIT SEVEN */ +#define XKB_KEY_8 0x0038 /* U+0038 DIGIT EIGHT */ +#define XKB_KEY_9 0x0039 /* U+0039 DIGIT NINE */ +#define XKB_KEY_colon 0x003a /* U+003A COLON */ +#define XKB_KEY_semicolon 0x003b /* U+003B SEMICOLON */ +#define XKB_KEY_less 0x003c /* U+003C LESS-THAN SIGN */ +#define XKB_KEY_equal 0x003d /* U+003D EQUALS SIGN */ +#define XKB_KEY_greater 0x003e /* U+003E GREATER-THAN SIGN */ +#define XKB_KEY_question 0x003f /* U+003F QUESTION MARK */ +#define XKB_KEY_at 0x0040 /* U+0040 COMMERCIAL AT */ +#define XKB_KEY_A 0x0041 /* U+0041 LATIN CAPITAL LETTER A */ +#define XKB_KEY_B 0x0042 /* U+0042 LATIN CAPITAL LETTER B */ +#define XKB_KEY_C 0x0043 /* U+0043 LATIN CAPITAL LETTER C */ +#define XKB_KEY_D 0x0044 /* U+0044 LATIN CAPITAL LETTER D */ +#define XKB_KEY_E 0x0045 /* U+0045 LATIN CAPITAL LETTER E */ +#define XKB_KEY_F 0x0046 /* U+0046 LATIN CAPITAL LETTER F */ +#define XKB_KEY_G 0x0047 /* U+0047 LATIN CAPITAL LETTER G */ +#define XKB_KEY_H 0x0048 /* U+0048 LATIN CAPITAL LETTER H */ +#define XKB_KEY_I 0x0049 /* U+0049 LATIN CAPITAL LETTER I */ +#define XKB_KEY_J 0x004a /* U+004A LATIN CAPITAL LETTER J */ +#define XKB_KEY_K 0x004b /* U+004B LATIN CAPITAL LETTER K */ +#define XKB_KEY_L 0x004c /* U+004C LATIN CAPITAL LETTER L */ +#define XKB_KEY_M 0x004d /* U+004D LATIN CAPITAL LETTER M */ +#define XKB_KEY_N 0x004e /* U+004E LATIN CAPITAL LETTER N */ +#define XKB_KEY_O 0x004f /* U+004F LATIN CAPITAL LETTER O */ +#define XKB_KEY_P 0x0050 /* U+0050 LATIN CAPITAL LETTER P */ +#define XKB_KEY_Q 0x0051 /* U+0051 LATIN CAPITAL LETTER Q */ +#define XKB_KEY_R 0x0052 /* U+0052 LATIN CAPITAL LETTER R */ +#define XKB_KEY_S 0x0053 /* U+0053 LATIN CAPITAL LETTER S */ +#define XKB_KEY_T 0x0054 /* U+0054 LATIN CAPITAL LETTER T */ +#define XKB_KEY_U 0x0055 /* U+0055 LATIN CAPITAL LETTER U */ +#define XKB_KEY_V 0x0056 /* U+0056 LATIN CAPITAL LETTER V */ +#define XKB_KEY_W 0x0057 /* U+0057 LATIN CAPITAL LETTER W */ +#define XKB_KEY_X 0x0058 /* U+0058 LATIN CAPITAL LETTER X */ +#define XKB_KEY_Y 0x0059 /* U+0059 LATIN CAPITAL LETTER Y */ +#define XKB_KEY_Z 0x005a /* U+005A LATIN CAPITAL LETTER Z */ +#define XKB_KEY_bracketleft 0x005b /* U+005B LEFT SQUARE BRACKET */ +#define XKB_KEY_backslash 0x005c /* U+005C REVERSE SOLIDUS */ +#define XKB_KEY_bracketright 0x005d /* U+005D RIGHT SQUARE BRACKET */ +#define XKB_KEY_asciicircum 0x005e /* U+005E CIRCUMFLEX ACCENT */ +#define XKB_KEY_underscore 0x005f /* U+005F LOW LINE */ +#define XKB_KEY_grave 0x0060 /* U+0060 GRAVE ACCENT */ +#define XKB_KEY_quoteleft 0x0060 /* deprecated */ +#define XKB_KEY_a 0x0061 /* U+0061 LATIN SMALL LETTER A */ +#define XKB_KEY_b 0x0062 /* U+0062 LATIN SMALL LETTER B */ +#define XKB_KEY_c 0x0063 /* U+0063 LATIN SMALL LETTER C */ +#define XKB_KEY_d 0x0064 /* U+0064 LATIN SMALL LETTER D */ +#define XKB_KEY_e 0x0065 /* U+0065 LATIN SMALL LETTER E */ +#define XKB_KEY_f 0x0066 /* U+0066 LATIN SMALL LETTER F */ +#define XKB_KEY_g 0x0067 /* U+0067 LATIN SMALL LETTER G */ +#define XKB_KEY_h 0x0068 /* U+0068 LATIN SMALL LETTER H */ +#define XKB_KEY_i 0x0069 /* U+0069 LATIN SMALL LETTER I */ +#define XKB_KEY_j 0x006a /* U+006A LATIN SMALL LETTER J */ +#define XKB_KEY_k 0x006b /* U+006B LATIN SMALL LETTER K */ +#define XKB_KEY_l 0x006c /* U+006C LATIN SMALL LETTER L */ +#define XKB_KEY_m 0x006d /* U+006D LATIN SMALL LETTER M */ +#define XKB_KEY_n 0x006e /* U+006E LATIN SMALL LETTER N */ +#define XKB_KEY_o 0x006f /* U+006F LATIN SMALL LETTER O */ +#define XKB_KEY_p 0x0070 /* U+0070 LATIN SMALL LETTER P */ +#define XKB_KEY_q 0x0071 /* U+0071 LATIN SMALL LETTER Q */ +#define XKB_KEY_r 0x0072 /* U+0072 LATIN SMALL LETTER R */ +#define XKB_KEY_s 0x0073 /* U+0073 LATIN SMALL LETTER S */ +#define XKB_KEY_t 0x0074 /* U+0074 LATIN SMALL LETTER T */ +#define XKB_KEY_u 0x0075 /* U+0075 LATIN SMALL LETTER U */ +#define XKB_KEY_v 0x0076 /* U+0076 LATIN SMALL LETTER V */ +#define XKB_KEY_w 0x0077 /* U+0077 LATIN SMALL LETTER W */ +#define XKB_KEY_x 0x0078 /* U+0078 LATIN SMALL LETTER X */ +#define XKB_KEY_y 0x0079 /* U+0079 LATIN SMALL LETTER Y */ +#define XKB_KEY_z 0x007a /* U+007A LATIN SMALL LETTER Z */ +#define XKB_KEY_braceleft 0x007b /* U+007B LEFT CURLY BRACKET */ +#define XKB_KEY_bar 0x007c /* U+007C VERTICAL LINE */ +#define XKB_KEY_braceright 0x007d /* U+007D RIGHT CURLY BRACKET */ +#define XKB_KEY_asciitilde 0x007e /* U+007E TILDE */ + +#define XKB_KEY_nobreakspace 0x00a0 /* U+00A0 NO-BREAK SPACE */ +#define XKB_KEY_exclamdown 0x00a1 /* U+00A1 INVERTED EXCLAMATION MARK */ +#define XKB_KEY_cent 0x00a2 /* U+00A2 CENT SIGN */ +#define XKB_KEY_sterling 0x00a3 /* U+00A3 POUND SIGN */ +#define XKB_KEY_currency 0x00a4 /* U+00A4 CURRENCY SIGN */ +#define XKB_KEY_yen 0x00a5 /* U+00A5 YEN SIGN */ +#define XKB_KEY_brokenbar 0x00a6 /* U+00A6 BROKEN BAR */ +#define XKB_KEY_section 0x00a7 /* U+00A7 SECTION SIGN */ +#define XKB_KEY_diaeresis 0x00a8 /* U+00A8 DIAERESIS */ +#define XKB_KEY_copyright 0x00a9 /* U+00A9 COPYRIGHT SIGN */ +#define XKB_KEY_ordfeminine 0x00aa /* U+00AA FEMININE ORDINAL INDICATOR */ +#define XKB_KEY_guillemotleft 0x00ab /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ +#define XKB_KEY_notsign 0x00ac /* U+00AC NOT SIGN */ +#define XKB_KEY_hyphen 0x00ad /* U+00AD SOFT HYPHEN */ +#define XKB_KEY_registered 0x00ae /* U+00AE REGISTERED SIGN */ +#define XKB_KEY_macron 0x00af /* U+00AF MACRON */ +#define XKB_KEY_degree 0x00b0 /* U+00B0 DEGREE SIGN */ +#define XKB_KEY_plusminus 0x00b1 /* U+00B1 PLUS-MINUS SIGN */ +#define XKB_KEY_twosuperior 0x00b2 /* U+00B2 SUPERSCRIPT TWO */ +#define XKB_KEY_threesuperior 0x00b3 /* U+00B3 SUPERSCRIPT THREE */ +#define XKB_KEY_acute 0x00b4 /* U+00B4 ACUTE ACCENT */ +#define XKB_KEY_mu 0x00b5 /* U+00B5 MICRO SIGN */ +#define XKB_KEY_paragraph 0x00b6 /* U+00B6 PILCROW SIGN */ +#define XKB_KEY_periodcentered 0x00b7 /* U+00B7 MIDDLE DOT */ +#define XKB_KEY_cedilla 0x00b8 /* U+00B8 CEDILLA */ +#define XKB_KEY_onesuperior 0x00b9 /* U+00B9 SUPERSCRIPT ONE */ +#define XKB_KEY_masculine 0x00ba /* U+00BA MASCULINE ORDINAL INDICATOR */ +#define XKB_KEY_guillemotright 0x00bb /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ +#define XKB_KEY_onequarter 0x00bc /* U+00BC VULGAR FRACTION ONE QUARTER */ +#define XKB_KEY_onehalf 0x00bd /* U+00BD VULGAR FRACTION ONE HALF */ +#define XKB_KEY_threequarters 0x00be /* U+00BE VULGAR FRACTION THREE QUARTERS */ +#define XKB_KEY_questiondown 0x00bf /* U+00BF INVERTED QUESTION MARK */ +#define XKB_KEY_Agrave 0x00c0 /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */ +#define XKB_KEY_Aacute 0x00c1 /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */ +#define XKB_KEY_Acircumflex 0x00c2 /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ +#define XKB_KEY_Atilde 0x00c3 /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */ +#define XKB_KEY_Adiaeresis 0x00c4 /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */ +#define XKB_KEY_Aring 0x00c5 /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */ +#define XKB_KEY_AE 0x00c6 /* U+00C6 LATIN CAPITAL LETTER AE */ +#define XKB_KEY_Ccedilla 0x00c7 /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */ +#define XKB_KEY_Egrave 0x00c8 /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */ +#define XKB_KEY_Eacute 0x00c9 /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */ +#define XKB_KEY_Ecircumflex 0x00ca /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ +#define XKB_KEY_Ediaeresis 0x00cb /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */ +#define XKB_KEY_Igrave 0x00cc /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */ +#define XKB_KEY_Iacute 0x00cd /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */ +#define XKB_KEY_Icircumflex 0x00ce /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ +#define XKB_KEY_Idiaeresis 0x00cf /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */ +#define XKB_KEY_ETH 0x00d0 /* U+00D0 LATIN CAPITAL LETTER ETH */ +#define XKB_KEY_Eth 0x00d0 /* deprecated */ +#define XKB_KEY_Ntilde 0x00d1 /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */ +#define XKB_KEY_Ograve 0x00d2 /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */ +#define XKB_KEY_Oacute 0x00d3 /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */ +#define XKB_KEY_Ocircumflex 0x00d4 /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ +#define XKB_KEY_Otilde 0x00d5 /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */ +#define XKB_KEY_Odiaeresis 0x00d6 /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */ +#define XKB_KEY_multiply 0x00d7 /* U+00D7 MULTIPLICATION SIGN */ +#define XKB_KEY_Oslash 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ +#define XKB_KEY_Ooblique 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ +#define XKB_KEY_Ugrave 0x00d9 /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */ +#define XKB_KEY_Uacute 0x00da /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */ +#define XKB_KEY_Ucircumflex 0x00db /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ +#define XKB_KEY_Udiaeresis 0x00dc /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */ +#define XKB_KEY_Yacute 0x00dd /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */ +#define XKB_KEY_THORN 0x00de /* U+00DE LATIN CAPITAL LETTER THORN */ +#define XKB_KEY_Thorn 0x00de /* deprecated */ +#define XKB_KEY_ssharp 0x00df /* U+00DF LATIN SMALL LETTER SHARP S */ +#define XKB_KEY_agrave 0x00e0 /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */ +#define XKB_KEY_aacute 0x00e1 /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */ +#define XKB_KEY_acircumflex 0x00e2 /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */ +#define XKB_KEY_atilde 0x00e3 /* U+00E3 LATIN SMALL LETTER A WITH TILDE */ +#define XKB_KEY_adiaeresis 0x00e4 /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */ +#define XKB_KEY_aring 0x00e5 /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */ +#define XKB_KEY_ae 0x00e6 /* U+00E6 LATIN SMALL LETTER AE */ +#define XKB_KEY_ccedilla 0x00e7 /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ +#define XKB_KEY_egrave 0x00e8 /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */ +#define XKB_KEY_eacute 0x00e9 /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ +#define XKB_KEY_ecircumflex 0x00ea /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */ +#define XKB_KEY_ediaeresis 0x00eb /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */ +#define XKB_KEY_igrave 0x00ec /* U+00EC LATIN SMALL LETTER I WITH GRAVE */ +#define XKB_KEY_iacute 0x00ed /* U+00ED LATIN SMALL LETTER I WITH ACUTE */ +#define XKB_KEY_icircumflex 0x00ee /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */ +#define XKB_KEY_idiaeresis 0x00ef /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */ +#define XKB_KEY_eth 0x00f0 /* U+00F0 LATIN SMALL LETTER ETH */ +#define XKB_KEY_ntilde 0x00f1 /* U+00F1 LATIN SMALL LETTER N WITH TILDE */ +#define XKB_KEY_ograve 0x00f2 /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */ +#define XKB_KEY_oacute 0x00f3 /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */ +#define XKB_KEY_ocircumflex 0x00f4 /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */ +#define XKB_KEY_otilde 0x00f5 /* U+00F5 LATIN SMALL LETTER O WITH TILDE */ +#define XKB_KEY_odiaeresis 0x00f6 /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */ +#define XKB_KEY_division 0x00f7 /* U+00F7 DIVISION SIGN */ +#define XKB_KEY_oslash 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ +#define XKB_KEY_ooblique 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ +#define XKB_KEY_ugrave 0x00f9 /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */ +#define XKB_KEY_uacute 0x00fa /* U+00FA LATIN SMALL LETTER U WITH ACUTE */ +#define XKB_KEY_ucircumflex 0x00fb /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */ +#define XKB_KEY_udiaeresis 0x00fc /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */ +#define XKB_KEY_yacute 0x00fd /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */ +#define XKB_KEY_thorn 0x00fe /* U+00FE LATIN SMALL LETTER THORN */ +#define XKB_KEY_ydiaeresis 0x00ff /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */ + +/* + * Latin 2 + * Byte 3 = 1 + */ + +#define XKB_KEY_Aogonek 0x01a1 /* U+0104 LATIN CAPITAL LETTER A WITH OGONEK */ +#define XKB_KEY_breve 0x01a2 /* U+02D8 BREVE */ +#define XKB_KEY_Lstroke 0x01a3 /* U+0141 LATIN CAPITAL LETTER L WITH STROKE */ +#define XKB_KEY_Lcaron 0x01a5 /* U+013D LATIN CAPITAL LETTER L WITH CARON */ +#define XKB_KEY_Sacute 0x01a6 /* U+015A LATIN CAPITAL LETTER S WITH ACUTE */ +#define XKB_KEY_Scaron 0x01a9 /* U+0160 LATIN CAPITAL LETTER S WITH CARON */ +#define XKB_KEY_Scedilla 0x01aa /* U+015E LATIN CAPITAL LETTER S WITH CEDILLA */ +#define XKB_KEY_Tcaron 0x01ab /* U+0164 LATIN CAPITAL LETTER T WITH CARON */ +#define XKB_KEY_Zacute 0x01ac /* U+0179 LATIN CAPITAL LETTER Z WITH ACUTE */ +#define XKB_KEY_Zcaron 0x01ae /* U+017D LATIN CAPITAL LETTER Z WITH CARON */ +#define XKB_KEY_Zabovedot 0x01af /* U+017B LATIN CAPITAL LETTER Z WITH DOT ABOVE */ +#define XKB_KEY_aogonek 0x01b1 /* U+0105 LATIN SMALL LETTER A WITH OGONEK */ +#define XKB_KEY_ogonek 0x01b2 /* U+02DB OGONEK */ +#define XKB_KEY_lstroke 0x01b3 /* U+0142 LATIN SMALL LETTER L WITH STROKE */ +#define XKB_KEY_lcaron 0x01b5 /* U+013E LATIN SMALL LETTER L WITH CARON */ +#define XKB_KEY_sacute 0x01b6 /* U+015B LATIN SMALL LETTER S WITH ACUTE */ +#define XKB_KEY_caron 0x01b7 /* U+02C7 CARON */ +#define XKB_KEY_scaron 0x01b9 /* U+0161 LATIN SMALL LETTER S WITH CARON */ +#define XKB_KEY_scedilla 0x01ba /* U+015F LATIN SMALL LETTER S WITH CEDILLA */ +#define XKB_KEY_tcaron 0x01bb /* U+0165 LATIN SMALL LETTER T WITH CARON */ +#define XKB_KEY_zacute 0x01bc /* U+017A LATIN SMALL LETTER Z WITH ACUTE */ +#define XKB_KEY_doubleacute 0x01bd /* U+02DD DOUBLE ACUTE ACCENT */ +#define XKB_KEY_zcaron 0x01be /* U+017E LATIN SMALL LETTER Z WITH CARON */ +#define XKB_KEY_zabovedot 0x01bf /* U+017C LATIN SMALL LETTER Z WITH DOT ABOVE */ +#define XKB_KEY_Racute 0x01c0 /* U+0154 LATIN CAPITAL LETTER R WITH ACUTE */ +#define XKB_KEY_Abreve 0x01c3 /* U+0102 LATIN CAPITAL LETTER A WITH BREVE */ +#define XKB_KEY_Lacute 0x01c5 /* U+0139 LATIN CAPITAL LETTER L WITH ACUTE */ +#define XKB_KEY_Cacute 0x01c6 /* U+0106 LATIN CAPITAL LETTER C WITH ACUTE */ +#define XKB_KEY_Ccaron 0x01c8 /* U+010C LATIN CAPITAL LETTER C WITH CARON */ +#define XKB_KEY_Eogonek 0x01ca /* U+0118 LATIN CAPITAL LETTER E WITH OGONEK */ +#define XKB_KEY_Ecaron 0x01cc /* U+011A LATIN CAPITAL LETTER E WITH CARON */ +#define XKB_KEY_Dcaron 0x01cf /* U+010E LATIN CAPITAL LETTER D WITH CARON */ +#define XKB_KEY_Dstroke 0x01d0 /* U+0110 LATIN CAPITAL LETTER D WITH STROKE */ +#define XKB_KEY_Nacute 0x01d1 /* U+0143 LATIN CAPITAL LETTER N WITH ACUTE */ +#define XKB_KEY_Ncaron 0x01d2 /* U+0147 LATIN CAPITAL LETTER N WITH CARON */ +#define XKB_KEY_Odoubleacute 0x01d5 /* U+0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ +#define XKB_KEY_Rcaron 0x01d8 /* U+0158 LATIN CAPITAL LETTER R WITH CARON */ +#define XKB_KEY_Uring 0x01d9 /* U+016E LATIN CAPITAL LETTER U WITH RING ABOVE */ +#define XKB_KEY_Udoubleacute 0x01db /* U+0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ +#define XKB_KEY_Tcedilla 0x01de /* U+0162 LATIN CAPITAL LETTER T WITH CEDILLA */ +#define XKB_KEY_racute 0x01e0 /* U+0155 LATIN SMALL LETTER R WITH ACUTE */ +#define XKB_KEY_abreve 0x01e3 /* U+0103 LATIN SMALL LETTER A WITH BREVE */ +#define XKB_KEY_lacute 0x01e5 /* U+013A LATIN SMALL LETTER L WITH ACUTE */ +#define XKB_KEY_cacute 0x01e6 /* U+0107 LATIN SMALL LETTER C WITH ACUTE */ +#define XKB_KEY_ccaron 0x01e8 /* U+010D LATIN SMALL LETTER C WITH CARON */ +#define XKB_KEY_eogonek 0x01ea /* U+0119 LATIN SMALL LETTER E WITH OGONEK */ +#define XKB_KEY_ecaron 0x01ec /* U+011B LATIN SMALL LETTER E WITH CARON */ +#define XKB_KEY_dcaron 0x01ef /* U+010F LATIN SMALL LETTER D WITH CARON */ +#define XKB_KEY_dstroke 0x01f0 /* U+0111 LATIN SMALL LETTER D WITH STROKE */ +#define XKB_KEY_nacute 0x01f1 /* U+0144 LATIN SMALL LETTER N WITH ACUTE */ +#define XKB_KEY_ncaron 0x01f2 /* U+0148 LATIN SMALL LETTER N WITH CARON */ +#define XKB_KEY_odoubleacute 0x01f5 /* U+0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE */ +#define XKB_KEY_rcaron 0x01f8 /* U+0159 LATIN SMALL LETTER R WITH CARON */ +#define XKB_KEY_uring 0x01f9 /* U+016F LATIN SMALL LETTER U WITH RING ABOVE */ +#define XKB_KEY_udoubleacute 0x01fb /* U+0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE */ +#define XKB_KEY_tcedilla 0x01fe /* U+0163 LATIN SMALL LETTER T WITH CEDILLA */ +#define XKB_KEY_abovedot 0x01ff /* U+02D9 DOT ABOVE */ + +/* + * Latin 3 + * Byte 3 = 2 + */ + +#define XKB_KEY_Hstroke 0x02a1 /* U+0126 LATIN CAPITAL LETTER H WITH STROKE */ +#define XKB_KEY_Hcircumflex 0x02a6 /* U+0124 LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ +#define XKB_KEY_Iabovedot 0x02a9 /* U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE */ +#define XKB_KEY_Gbreve 0x02ab /* U+011E LATIN CAPITAL LETTER G WITH BREVE */ +#define XKB_KEY_Jcircumflex 0x02ac /* U+0134 LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ +#define XKB_KEY_hstroke 0x02b1 /* U+0127 LATIN SMALL LETTER H WITH STROKE */ +#define XKB_KEY_hcircumflex 0x02b6 /* U+0125 LATIN SMALL LETTER H WITH CIRCUMFLEX */ +#define XKB_KEY_idotless 0x02b9 /* U+0131 LATIN SMALL LETTER DOTLESS I */ +#define XKB_KEY_gbreve 0x02bb /* U+011F LATIN SMALL LETTER G WITH BREVE */ +#define XKB_KEY_jcircumflex 0x02bc /* U+0135 LATIN SMALL LETTER J WITH CIRCUMFLEX */ +#define XKB_KEY_Cabovedot 0x02c5 /* U+010A LATIN CAPITAL LETTER C WITH DOT ABOVE */ +#define XKB_KEY_Ccircumflex 0x02c6 /* U+0108 LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ +#define XKB_KEY_Gabovedot 0x02d5 /* U+0120 LATIN CAPITAL LETTER G WITH DOT ABOVE */ +#define XKB_KEY_Gcircumflex 0x02d8 /* U+011C LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ +#define XKB_KEY_Ubreve 0x02dd /* U+016C LATIN CAPITAL LETTER U WITH BREVE */ +#define XKB_KEY_Scircumflex 0x02de /* U+015C LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ +#define XKB_KEY_cabovedot 0x02e5 /* U+010B LATIN SMALL LETTER C WITH DOT ABOVE */ +#define XKB_KEY_ccircumflex 0x02e6 /* U+0109 LATIN SMALL LETTER C WITH CIRCUMFLEX */ +#define XKB_KEY_gabovedot 0x02f5 /* U+0121 LATIN SMALL LETTER G WITH DOT ABOVE */ +#define XKB_KEY_gcircumflex 0x02f8 /* U+011D LATIN SMALL LETTER G WITH CIRCUMFLEX */ +#define XKB_KEY_ubreve 0x02fd /* U+016D LATIN SMALL LETTER U WITH BREVE */ +#define XKB_KEY_scircumflex 0x02fe /* U+015D LATIN SMALL LETTER S WITH CIRCUMFLEX */ + + +/* + * Latin 4 + * Byte 3 = 3 + */ + +#define XKB_KEY_kra 0x03a2 /* U+0138 LATIN SMALL LETTER KRA */ +#define XKB_KEY_kappa 0x03a2 /* deprecated */ +#define XKB_KEY_Rcedilla 0x03a3 /* U+0156 LATIN CAPITAL LETTER R WITH CEDILLA */ +#define XKB_KEY_Itilde 0x03a5 /* U+0128 LATIN CAPITAL LETTER I WITH TILDE */ +#define XKB_KEY_Lcedilla 0x03a6 /* U+013B LATIN CAPITAL LETTER L WITH CEDILLA */ +#define XKB_KEY_Emacron 0x03aa /* U+0112 LATIN CAPITAL LETTER E WITH MACRON */ +#define XKB_KEY_Gcedilla 0x03ab /* U+0122 LATIN CAPITAL LETTER G WITH CEDILLA */ +#define XKB_KEY_Tslash 0x03ac /* U+0166 LATIN CAPITAL LETTER T WITH STROKE */ +#define XKB_KEY_rcedilla 0x03b3 /* U+0157 LATIN SMALL LETTER R WITH CEDILLA */ +#define XKB_KEY_itilde 0x03b5 /* U+0129 LATIN SMALL LETTER I WITH TILDE */ +#define XKB_KEY_lcedilla 0x03b6 /* U+013C LATIN SMALL LETTER L WITH CEDILLA */ +#define XKB_KEY_emacron 0x03ba /* U+0113 LATIN SMALL LETTER E WITH MACRON */ +#define XKB_KEY_gcedilla 0x03bb /* U+0123 LATIN SMALL LETTER G WITH CEDILLA */ +#define XKB_KEY_tslash 0x03bc /* U+0167 LATIN SMALL LETTER T WITH STROKE */ +#define XKB_KEY_ENG 0x03bd /* U+014A LATIN CAPITAL LETTER ENG */ +#define XKB_KEY_eng 0x03bf /* U+014B LATIN SMALL LETTER ENG */ +#define XKB_KEY_Amacron 0x03c0 /* U+0100 LATIN CAPITAL LETTER A WITH MACRON */ +#define XKB_KEY_Iogonek 0x03c7 /* U+012E LATIN CAPITAL LETTER I WITH OGONEK */ +#define XKB_KEY_Eabovedot 0x03cc /* U+0116 LATIN CAPITAL LETTER E WITH DOT ABOVE */ +#define XKB_KEY_Imacron 0x03cf /* U+012A LATIN CAPITAL LETTER I WITH MACRON */ +#define XKB_KEY_Ncedilla 0x03d1 /* U+0145 LATIN CAPITAL LETTER N WITH CEDILLA */ +#define XKB_KEY_Omacron 0x03d2 /* U+014C LATIN CAPITAL LETTER O WITH MACRON */ +#define XKB_KEY_Kcedilla 0x03d3 /* U+0136 LATIN CAPITAL LETTER K WITH CEDILLA */ +#define XKB_KEY_Uogonek 0x03d9 /* U+0172 LATIN CAPITAL LETTER U WITH OGONEK */ +#define XKB_KEY_Utilde 0x03dd /* U+0168 LATIN CAPITAL LETTER U WITH TILDE */ +#define XKB_KEY_Umacron 0x03de /* U+016A LATIN CAPITAL LETTER U WITH MACRON */ +#define XKB_KEY_amacron 0x03e0 /* U+0101 LATIN SMALL LETTER A WITH MACRON */ +#define XKB_KEY_iogonek 0x03e7 /* U+012F LATIN SMALL LETTER I WITH OGONEK */ +#define XKB_KEY_eabovedot 0x03ec /* U+0117 LATIN SMALL LETTER E WITH DOT ABOVE */ +#define XKB_KEY_imacron 0x03ef /* U+012B LATIN SMALL LETTER I WITH MACRON */ +#define XKB_KEY_ncedilla 0x03f1 /* U+0146 LATIN SMALL LETTER N WITH CEDILLA */ +#define XKB_KEY_omacron 0x03f2 /* U+014D LATIN SMALL LETTER O WITH MACRON */ +#define XKB_KEY_kcedilla 0x03f3 /* U+0137 LATIN SMALL LETTER K WITH CEDILLA */ +#define XKB_KEY_uogonek 0x03f9 /* U+0173 LATIN SMALL LETTER U WITH OGONEK */ +#define XKB_KEY_utilde 0x03fd /* U+0169 LATIN SMALL LETTER U WITH TILDE */ +#define XKB_KEY_umacron 0x03fe /* U+016B LATIN SMALL LETTER U WITH MACRON */ + +/* + * Latin 8 + */ +#define XKB_KEY_Wcircumflex 0x1000174 /* U+0174 LATIN CAPITAL LETTER W WITH CIRCUMFLEX */ +#define XKB_KEY_wcircumflex 0x1000175 /* U+0175 LATIN SMALL LETTER W WITH CIRCUMFLEX */ +#define XKB_KEY_Ycircumflex 0x1000176 /* U+0176 LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */ +#define XKB_KEY_ycircumflex 0x1000177 /* U+0177 LATIN SMALL LETTER Y WITH CIRCUMFLEX */ +#define XKB_KEY_Babovedot 0x1001e02 /* U+1E02 LATIN CAPITAL LETTER B WITH DOT ABOVE */ +#define XKB_KEY_babovedot 0x1001e03 /* U+1E03 LATIN SMALL LETTER B WITH DOT ABOVE */ +#define XKB_KEY_Dabovedot 0x1001e0a /* U+1E0A LATIN CAPITAL LETTER D WITH DOT ABOVE */ +#define XKB_KEY_dabovedot 0x1001e0b /* U+1E0B LATIN SMALL LETTER D WITH DOT ABOVE */ +#define XKB_KEY_Fabovedot 0x1001e1e /* U+1E1E LATIN CAPITAL LETTER F WITH DOT ABOVE */ +#define XKB_KEY_fabovedot 0x1001e1f /* U+1E1F LATIN SMALL LETTER F WITH DOT ABOVE */ +#define XKB_KEY_Mabovedot 0x1001e40 /* U+1E40 LATIN CAPITAL LETTER M WITH DOT ABOVE */ +#define XKB_KEY_mabovedot 0x1001e41 /* U+1E41 LATIN SMALL LETTER M WITH DOT ABOVE */ +#define XKB_KEY_Pabovedot 0x1001e56 /* U+1E56 LATIN CAPITAL LETTER P WITH DOT ABOVE */ +#define XKB_KEY_pabovedot 0x1001e57 /* U+1E57 LATIN SMALL LETTER P WITH DOT ABOVE */ +#define XKB_KEY_Sabovedot 0x1001e60 /* U+1E60 LATIN CAPITAL LETTER S WITH DOT ABOVE */ +#define XKB_KEY_sabovedot 0x1001e61 /* U+1E61 LATIN SMALL LETTER S WITH DOT ABOVE */ +#define XKB_KEY_Tabovedot 0x1001e6a /* U+1E6A LATIN CAPITAL LETTER T WITH DOT ABOVE */ +#define XKB_KEY_tabovedot 0x1001e6b /* U+1E6B LATIN SMALL LETTER T WITH DOT ABOVE */ +#define XKB_KEY_Wgrave 0x1001e80 /* U+1E80 LATIN CAPITAL LETTER W WITH GRAVE */ +#define XKB_KEY_wgrave 0x1001e81 /* U+1E81 LATIN SMALL LETTER W WITH GRAVE */ +#define XKB_KEY_Wacute 0x1001e82 /* U+1E82 LATIN CAPITAL LETTER W WITH ACUTE */ +#define XKB_KEY_wacute 0x1001e83 /* U+1E83 LATIN SMALL LETTER W WITH ACUTE */ +#define XKB_KEY_Wdiaeresis 0x1001e84 /* U+1E84 LATIN CAPITAL LETTER W WITH DIAERESIS */ +#define XKB_KEY_wdiaeresis 0x1001e85 /* U+1E85 LATIN SMALL LETTER W WITH DIAERESIS */ +#define XKB_KEY_Ygrave 0x1001ef2 /* U+1EF2 LATIN CAPITAL LETTER Y WITH GRAVE */ +#define XKB_KEY_ygrave 0x1001ef3 /* U+1EF3 LATIN SMALL LETTER Y WITH GRAVE */ + +/* + * Latin 9 + * Byte 3 = 0x13 + */ + +#define XKB_KEY_OE 0x13bc /* U+0152 LATIN CAPITAL LIGATURE OE */ +#define XKB_KEY_oe 0x13bd /* U+0153 LATIN SMALL LIGATURE OE */ +#define XKB_KEY_Ydiaeresis 0x13be /* U+0178 LATIN CAPITAL LETTER Y WITH DIAERESIS */ + +/* + * Katakana + * Byte 3 = 4 + */ + +#define XKB_KEY_overline 0x047e /* U+203E OVERLINE */ +#define XKB_KEY_kana_fullstop 0x04a1 /* U+3002 IDEOGRAPHIC FULL STOP */ +#define XKB_KEY_kana_openingbracket 0x04a2 /* U+300C LEFT CORNER BRACKET */ +#define XKB_KEY_kana_closingbracket 0x04a3 /* U+300D RIGHT CORNER BRACKET */ +#define XKB_KEY_kana_comma 0x04a4 /* U+3001 IDEOGRAPHIC COMMA */ +#define XKB_KEY_kana_conjunctive 0x04a5 /* U+30FB KATAKANA MIDDLE DOT */ +#define XKB_KEY_kana_middledot 0x04a5 /* deprecated */ +#define XKB_KEY_kana_WO 0x04a6 /* U+30F2 KATAKANA LETTER WO */ +#define XKB_KEY_kana_a 0x04a7 /* U+30A1 KATAKANA LETTER SMALL A */ +#define XKB_KEY_kana_i 0x04a8 /* U+30A3 KATAKANA LETTER SMALL I */ +#define XKB_KEY_kana_u 0x04a9 /* U+30A5 KATAKANA LETTER SMALL U */ +#define XKB_KEY_kana_e 0x04aa /* U+30A7 KATAKANA LETTER SMALL E */ +#define XKB_KEY_kana_o 0x04ab /* U+30A9 KATAKANA LETTER SMALL O */ +#define XKB_KEY_kana_ya 0x04ac /* U+30E3 KATAKANA LETTER SMALL YA */ +#define XKB_KEY_kana_yu 0x04ad /* U+30E5 KATAKANA LETTER SMALL YU */ +#define XKB_KEY_kana_yo 0x04ae /* U+30E7 KATAKANA LETTER SMALL YO */ +#define XKB_KEY_kana_tsu 0x04af /* U+30C3 KATAKANA LETTER SMALL TU */ +#define XKB_KEY_kana_tu 0x04af /* deprecated */ +#define XKB_KEY_prolongedsound 0x04b0 /* U+30FC KATAKANA-HIRAGANA PROLONGED SOUND MARK */ +#define XKB_KEY_kana_A 0x04b1 /* U+30A2 KATAKANA LETTER A */ +#define XKB_KEY_kana_I 0x04b2 /* U+30A4 KATAKANA LETTER I */ +#define XKB_KEY_kana_U 0x04b3 /* U+30A6 KATAKANA LETTER U */ +#define XKB_KEY_kana_E 0x04b4 /* U+30A8 KATAKANA LETTER E */ +#define XKB_KEY_kana_O 0x04b5 /* U+30AA KATAKANA LETTER O */ +#define XKB_KEY_kana_KA 0x04b6 /* U+30AB KATAKANA LETTER KA */ +#define XKB_KEY_kana_KI 0x04b7 /* U+30AD KATAKANA LETTER KI */ +#define XKB_KEY_kana_KU 0x04b8 /* U+30AF KATAKANA LETTER KU */ +#define XKB_KEY_kana_KE 0x04b9 /* U+30B1 KATAKANA LETTER KE */ +#define XKB_KEY_kana_KO 0x04ba /* U+30B3 KATAKANA LETTER KO */ +#define XKB_KEY_kana_SA 0x04bb /* U+30B5 KATAKANA LETTER SA */ +#define XKB_KEY_kana_SHI 0x04bc /* U+30B7 KATAKANA LETTER SI */ +#define XKB_KEY_kana_SU 0x04bd /* U+30B9 KATAKANA LETTER SU */ +#define XKB_KEY_kana_SE 0x04be /* U+30BB KATAKANA LETTER SE */ +#define XKB_KEY_kana_SO 0x04bf /* U+30BD KATAKANA LETTER SO */ +#define XKB_KEY_kana_TA 0x04c0 /* U+30BF KATAKANA LETTER TA */ +#define XKB_KEY_kana_CHI 0x04c1 /* U+30C1 KATAKANA LETTER TI */ +#define XKB_KEY_kana_TI 0x04c1 /* deprecated */ +#define XKB_KEY_kana_TSU 0x04c2 /* U+30C4 KATAKANA LETTER TU */ +#define XKB_KEY_kana_TU 0x04c2 /* deprecated */ +#define XKB_KEY_kana_TE 0x04c3 /* U+30C6 KATAKANA LETTER TE */ +#define XKB_KEY_kana_TO 0x04c4 /* U+30C8 KATAKANA LETTER TO */ +#define XKB_KEY_kana_NA 0x04c5 /* U+30CA KATAKANA LETTER NA */ +#define XKB_KEY_kana_NI 0x04c6 /* U+30CB KATAKANA LETTER NI */ +#define XKB_KEY_kana_NU 0x04c7 /* U+30CC KATAKANA LETTER NU */ +#define XKB_KEY_kana_NE 0x04c8 /* U+30CD KATAKANA LETTER NE */ +#define XKB_KEY_kana_NO 0x04c9 /* U+30CE KATAKANA LETTER NO */ +#define XKB_KEY_kana_HA 0x04ca /* U+30CF KATAKANA LETTER HA */ +#define XKB_KEY_kana_HI 0x04cb /* U+30D2 KATAKANA LETTER HI */ +#define XKB_KEY_kana_FU 0x04cc /* U+30D5 KATAKANA LETTER HU */ +#define XKB_KEY_kana_HU 0x04cc /* deprecated */ +#define XKB_KEY_kana_HE 0x04cd /* U+30D8 KATAKANA LETTER HE */ +#define XKB_KEY_kana_HO 0x04ce /* U+30DB KATAKANA LETTER HO */ +#define XKB_KEY_kana_MA 0x04cf /* U+30DE KATAKANA LETTER MA */ +#define XKB_KEY_kana_MI 0x04d0 /* U+30DF KATAKANA LETTER MI */ +#define XKB_KEY_kana_MU 0x04d1 /* U+30E0 KATAKANA LETTER MU */ +#define XKB_KEY_kana_ME 0x04d2 /* U+30E1 KATAKANA LETTER ME */ +#define XKB_KEY_kana_MO 0x04d3 /* U+30E2 KATAKANA LETTER MO */ +#define XKB_KEY_kana_YA 0x04d4 /* U+30E4 KATAKANA LETTER YA */ +#define XKB_KEY_kana_YU 0x04d5 /* U+30E6 KATAKANA LETTER YU */ +#define XKB_KEY_kana_YO 0x04d6 /* U+30E8 KATAKANA LETTER YO */ +#define XKB_KEY_kana_RA 0x04d7 /* U+30E9 KATAKANA LETTER RA */ +#define XKB_KEY_kana_RI 0x04d8 /* U+30EA KATAKANA LETTER RI */ +#define XKB_KEY_kana_RU 0x04d9 /* U+30EB KATAKANA LETTER RU */ +#define XKB_KEY_kana_RE 0x04da /* U+30EC KATAKANA LETTER RE */ +#define XKB_KEY_kana_RO 0x04db /* U+30ED KATAKANA LETTER RO */ +#define XKB_KEY_kana_WA 0x04dc /* U+30EF KATAKANA LETTER WA */ +#define XKB_KEY_kana_N 0x04dd /* U+30F3 KATAKANA LETTER N */ +#define XKB_KEY_voicedsound 0x04de /* U+309B KATAKANA-HIRAGANA VOICED SOUND MARK */ +#define XKB_KEY_semivoicedsound 0x04df /* U+309C KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ +#define XKB_KEY_kana_switch 0xff7e /* Alias for mode_switch */ + +/* + * Arabic + * Byte 3 = 5 + */ + +#define XKB_KEY_Farsi_0 0x10006f0 /* U+06F0 EXTENDED ARABIC-INDIC DIGIT ZERO */ +#define XKB_KEY_Farsi_1 0x10006f1 /* U+06F1 EXTENDED ARABIC-INDIC DIGIT ONE */ +#define XKB_KEY_Farsi_2 0x10006f2 /* U+06F2 EXTENDED ARABIC-INDIC DIGIT TWO */ +#define XKB_KEY_Farsi_3 0x10006f3 /* U+06F3 EXTENDED ARABIC-INDIC DIGIT THREE */ +#define XKB_KEY_Farsi_4 0x10006f4 /* U+06F4 EXTENDED ARABIC-INDIC DIGIT FOUR */ +#define XKB_KEY_Farsi_5 0x10006f5 /* U+06F5 EXTENDED ARABIC-INDIC DIGIT FIVE */ +#define XKB_KEY_Farsi_6 0x10006f6 /* U+06F6 EXTENDED ARABIC-INDIC DIGIT SIX */ +#define XKB_KEY_Farsi_7 0x10006f7 /* U+06F7 EXTENDED ARABIC-INDIC DIGIT SEVEN */ +#define XKB_KEY_Farsi_8 0x10006f8 /* U+06F8 EXTENDED ARABIC-INDIC DIGIT EIGHT */ +#define XKB_KEY_Farsi_9 0x10006f9 /* U+06F9 EXTENDED ARABIC-INDIC DIGIT NINE */ +#define XKB_KEY_Arabic_percent 0x100066a /* U+066A ARABIC PERCENT SIGN */ +#define XKB_KEY_Arabic_superscript_alef 0x1000670 /* U+0670 ARABIC LETTER SUPERSCRIPT ALEF */ +#define XKB_KEY_Arabic_tteh 0x1000679 /* U+0679 ARABIC LETTER TTEH */ +#define XKB_KEY_Arabic_peh 0x100067e /* U+067E ARABIC LETTER PEH */ +#define XKB_KEY_Arabic_tcheh 0x1000686 /* U+0686 ARABIC LETTER TCHEH */ +#define XKB_KEY_Arabic_ddal 0x1000688 /* U+0688 ARABIC LETTER DDAL */ +#define XKB_KEY_Arabic_rreh 0x1000691 /* U+0691 ARABIC LETTER RREH */ +#define XKB_KEY_Arabic_comma 0x05ac /* U+060C ARABIC COMMA */ +#define XKB_KEY_Arabic_fullstop 0x10006d4 /* U+06D4 ARABIC FULL STOP */ +#define XKB_KEY_Arabic_0 0x1000660 /* U+0660 ARABIC-INDIC DIGIT ZERO */ +#define XKB_KEY_Arabic_1 0x1000661 /* U+0661 ARABIC-INDIC DIGIT ONE */ +#define XKB_KEY_Arabic_2 0x1000662 /* U+0662 ARABIC-INDIC DIGIT TWO */ +#define XKB_KEY_Arabic_3 0x1000663 /* U+0663 ARABIC-INDIC DIGIT THREE */ +#define XKB_KEY_Arabic_4 0x1000664 /* U+0664 ARABIC-INDIC DIGIT FOUR */ +#define XKB_KEY_Arabic_5 0x1000665 /* U+0665 ARABIC-INDIC DIGIT FIVE */ +#define XKB_KEY_Arabic_6 0x1000666 /* U+0666 ARABIC-INDIC DIGIT SIX */ +#define XKB_KEY_Arabic_7 0x1000667 /* U+0667 ARABIC-INDIC DIGIT SEVEN */ +#define XKB_KEY_Arabic_8 0x1000668 /* U+0668 ARABIC-INDIC DIGIT EIGHT */ +#define XKB_KEY_Arabic_9 0x1000669 /* U+0669 ARABIC-INDIC DIGIT NINE */ +#define XKB_KEY_Arabic_semicolon 0x05bb /* U+061B ARABIC SEMICOLON */ +#define XKB_KEY_Arabic_question_mark 0x05bf /* U+061F ARABIC QUESTION MARK */ +#define XKB_KEY_Arabic_hamza 0x05c1 /* U+0621 ARABIC LETTER HAMZA */ +#define XKB_KEY_Arabic_maddaonalef 0x05c2 /* U+0622 ARABIC LETTER ALEF WITH MADDA ABOVE */ +#define XKB_KEY_Arabic_hamzaonalef 0x05c3 /* U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE */ +#define XKB_KEY_Arabic_hamzaonwaw 0x05c4 /* U+0624 ARABIC LETTER WAW WITH HAMZA ABOVE */ +#define XKB_KEY_Arabic_hamzaunderalef 0x05c5 /* U+0625 ARABIC LETTER ALEF WITH HAMZA BELOW */ +#define XKB_KEY_Arabic_hamzaonyeh 0x05c6 /* U+0626 ARABIC LETTER YEH WITH HAMZA ABOVE */ +#define XKB_KEY_Arabic_alef 0x05c7 /* U+0627 ARABIC LETTER ALEF */ +#define XKB_KEY_Arabic_beh 0x05c8 /* U+0628 ARABIC LETTER BEH */ +#define XKB_KEY_Arabic_tehmarbuta 0x05c9 /* U+0629 ARABIC LETTER TEH MARBUTA */ +#define XKB_KEY_Arabic_teh 0x05ca /* U+062A ARABIC LETTER TEH */ +#define XKB_KEY_Arabic_theh 0x05cb /* U+062B ARABIC LETTER THEH */ +#define XKB_KEY_Arabic_jeem 0x05cc /* U+062C ARABIC LETTER JEEM */ +#define XKB_KEY_Arabic_hah 0x05cd /* U+062D ARABIC LETTER HAH */ +#define XKB_KEY_Arabic_khah 0x05ce /* U+062E ARABIC LETTER KHAH */ +#define XKB_KEY_Arabic_dal 0x05cf /* U+062F ARABIC LETTER DAL */ +#define XKB_KEY_Arabic_thal 0x05d0 /* U+0630 ARABIC LETTER THAL */ +#define XKB_KEY_Arabic_ra 0x05d1 /* U+0631 ARABIC LETTER REH */ +#define XKB_KEY_Arabic_zain 0x05d2 /* U+0632 ARABIC LETTER ZAIN */ +#define XKB_KEY_Arabic_seen 0x05d3 /* U+0633 ARABIC LETTER SEEN */ +#define XKB_KEY_Arabic_sheen 0x05d4 /* U+0634 ARABIC LETTER SHEEN */ +#define XKB_KEY_Arabic_sad 0x05d5 /* U+0635 ARABIC LETTER SAD */ +#define XKB_KEY_Arabic_dad 0x05d6 /* U+0636 ARABIC LETTER DAD */ +#define XKB_KEY_Arabic_tah 0x05d7 /* U+0637 ARABIC LETTER TAH */ +#define XKB_KEY_Arabic_zah 0x05d8 /* U+0638 ARABIC LETTER ZAH */ +#define XKB_KEY_Arabic_ain 0x05d9 /* U+0639 ARABIC LETTER AIN */ +#define XKB_KEY_Arabic_ghain 0x05da /* U+063A ARABIC LETTER GHAIN */ +#define XKB_KEY_Arabic_tatweel 0x05e0 /* U+0640 ARABIC TATWEEL */ +#define XKB_KEY_Arabic_feh 0x05e1 /* U+0641 ARABIC LETTER FEH */ +#define XKB_KEY_Arabic_qaf 0x05e2 /* U+0642 ARABIC LETTER QAF */ +#define XKB_KEY_Arabic_kaf 0x05e3 /* U+0643 ARABIC LETTER KAF */ +#define XKB_KEY_Arabic_lam 0x05e4 /* U+0644 ARABIC LETTER LAM */ +#define XKB_KEY_Arabic_meem 0x05e5 /* U+0645 ARABIC LETTER MEEM */ +#define XKB_KEY_Arabic_noon 0x05e6 /* U+0646 ARABIC LETTER NOON */ +#define XKB_KEY_Arabic_ha 0x05e7 /* U+0647 ARABIC LETTER HEH */ +#define XKB_KEY_Arabic_heh 0x05e7 /* deprecated */ +#define XKB_KEY_Arabic_waw 0x05e8 /* U+0648 ARABIC LETTER WAW */ +#define XKB_KEY_Arabic_alefmaksura 0x05e9 /* U+0649 ARABIC LETTER ALEF MAKSURA */ +#define XKB_KEY_Arabic_yeh 0x05ea /* U+064A ARABIC LETTER YEH */ +#define XKB_KEY_Arabic_fathatan 0x05eb /* U+064B ARABIC FATHATAN */ +#define XKB_KEY_Arabic_dammatan 0x05ec /* U+064C ARABIC DAMMATAN */ +#define XKB_KEY_Arabic_kasratan 0x05ed /* U+064D ARABIC KASRATAN */ +#define XKB_KEY_Arabic_fatha 0x05ee /* U+064E ARABIC FATHA */ +#define XKB_KEY_Arabic_damma 0x05ef /* U+064F ARABIC DAMMA */ +#define XKB_KEY_Arabic_kasra 0x05f0 /* U+0650 ARABIC KASRA */ +#define XKB_KEY_Arabic_shadda 0x05f1 /* U+0651 ARABIC SHADDA */ +#define XKB_KEY_Arabic_sukun 0x05f2 /* U+0652 ARABIC SUKUN */ +#define XKB_KEY_Arabic_madda_above 0x1000653 /* U+0653 ARABIC MADDAH ABOVE */ +#define XKB_KEY_Arabic_hamza_above 0x1000654 /* U+0654 ARABIC HAMZA ABOVE */ +#define XKB_KEY_Arabic_hamza_below 0x1000655 /* U+0655 ARABIC HAMZA BELOW */ +#define XKB_KEY_Arabic_jeh 0x1000698 /* U+0698 ARABIC LETTER JEH */ +#define XKB_KEY_Arabic_veh 0x10006a4 /* U+06A4 ARABIC LETTER VEH */ +#define XKB_KEY_Arabic_keheh 0x10006a9 /* U+06A9 ARABIC LETTER KEHEH */ +#define XKB_KEY_Arabic_gaf 0x10006af /* U+06AF ARABIC LETTER GAF */ +#define XKB_KEY_Arabic_noon_ghunna 0x10006ba /* U+06BA ARABIC LETTER NOON GHUNNA */ +#define XKB_KEY_Arabic_heh_doachashmee 0x10006be /* U+06BE ARABIC LETTER HEH DOACHASHMEE */ +#define XKB_KEY_Farsi_yeh 0x10006cc /* U+06CC ARABIC LETTER FARSI YEH */ +#define XKB_KEY_Arabic_farsi_yeh 0x10006cc /* U+06CC ARABIC LETTER FARSI YEH */ +#define XKB_KEY_Arabic_yeh_baree 0x10006d2 /* U+06D2 ARABIC LETTER YEH BARREE */ +#define XKB_KEY_Arabic_heh_goal 0x10006c1 /* U+06C1 ARABIC LETTER HEH GOAL */ +#define XKB_KEY_Arabic_switch 0xff7e /* Alias for mode_switch */ + +/* + * Cyrillic + * Byte 3 = 6 + */ +#define XKB_KEY_Cyrillic_GHE_bar 0x1000492 /* U+0492 CYRILLIC CAPITAL LETTER GHE WITH STROKE */ +#define XKB_KEY_Cyrillic_ghe_bar 0x1000493 /* U+0493 CYRILLIC SMALL LETTER GHE WITH STROKE */ +#define XKB_KEY_Cyrillic_ZHE_descender 0x1000496 /* U+0496 CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER */ +#define XKB_KEY_Cyrillic_zhe_descender 0x1000497 /* U+0497 CYRILLIC SMALL LETTER ZHE WITH DESCENDER */ +#define XKB_KEY_Cyrillic_KA_descender 0x100049a /* U+049A CYRILLIC CAPITAL LETTER KA WITH DESCENDER */ +#define XKB_KEY_Cyrillic_ka_descender 0x100049b /* U+049B CYRILLIC SMALL LETTER KA WITH DESCENDER */ +#define XKB_KEY_Cyrillic_KA_vertstroke 0x100049c /* U+049C CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE */ +#define XKB_KEY_Cyrillic_ka_vertstroke 0x100049d /* U+049D CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE */ +#define XKB_KEY_Cyrillic_EN_descender 0x10004a2 /* U+04A2 CYRILLIC CAPITAL LETTER EN WITH DESCENDER */ +#define XKB_KEY_Cyrillic_en_descender 0x10004a3 /* U+04A3 CYRILLIC SMALL LETTER EN WITH DESCENDER */ +#define XKB_KEY_Cyrillic_U_straight 0x10004ae /* U+04AE CYRILLIC CAPITAL LETTER STRAIGHT U */ +#define XKB_KEY_Cyrillic_u_straight 0x10004af /* U+04AF CYRILLIC SMALL LETTER STRAIGHT U */ +#define XKB_KEY_Cyrillic_U_straight_bar 0x10004b0 /* U+04B0 CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE */ +#define XKB_KEY_Cyrillic_u_straight_bar 0x10004b1 /* U+04B1 CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE */ +#define XKB_KEY_Cyrillic_HA_descender 0x10004b2 /* U+04B2 CYRILLIC CAPITAL LETTER HA WITH DESCENDER */ +#define XKB_KEY_Cyrillic_ha_descender 0x10004b3 /* U+04B3 CYRILLIC SMALL LETTER HA WITH DESCENDER */ +#define XKB_KEY_Cyrillic_CHE_descender 0x10004b6 /* U+04B6 CYRILLIC CAPITAL LETTER CHE WITH DESCENDER */ +#define XKB_KEY_Cyrillic_che_descender 0x10004b7 /* U+04B7 CYRILLIC SMALL LETTER CHE WITH DESCENDER */ +#define XKB_KEY_Cyrillic_CHE_vertstroke 0x10004b8 /* U+04B8 CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE */ +#define XKB_KEY_Cyrillic_che_vertstroke 0x10004b9 /* U+04B9 CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE */ +#define XKB_KEY_Cyrillic_SHHA 0x10004ba /* U+04BA CYRILLIC CAPITAL LETTER SHHA */ +#define XKB_KEY_Cyrillic_shha 0x10004bb /* U+04BB CYRILLIC SMALL LETTER SHHA */ + +#define XKB_KEY_Cyrillic_SCHWA 0x10004d8 /* U+04D8 CYRILLIC CAPITAL LETTER SCHWA */ +#define XKB_KEY_Cyrillic_schwa 0x10004d9 /* U+04D9 CYRILLIC SMALL LETTER SCHWA */ +#define XKB_KEY_Cyrillic_I_macron 0x10004e2 /* U+04E2 CYRILLIC CAPITAL LETTER I WITH MACRON */ +#define XKB_KEY_Cyrillic_i_macron 0x10004e3 /* U+04E3 CYRILLIC SMALL LETTER I WITH MACRON */ +#define XKB_KEY_Cyrillic_O_bar 0x10004e8 /* U+04E8 CYRILLIC CAPITAL LETTER BARRED O */ +#define XKB_KEY_Cyrillic_o_bar 0x10004e9 /* U+04E9 CYRILLIC SMALL LETTER BARRED O */ +#define XKB_KEY_Cyrillic_U_macron 0x10004ee /* U+04EE CYRILLIC CAPITAL LETTER U WITH MACRON */ +#define XKB_KEY_Cyrillic_u_macron 0x10004ef /* U+04EF CYRILLIC SMALL LETTER U WITH MACRON */ + +#define XKB_KEY_Serbian_dje 0x06a1 /* U+0452 CYRILLIC SMALL LETTER DJE */ +#define XKB_KEY_Macedonia_gje 0x06a2 /* U+0453 CYRILLIC SMALL LETTER GJE */ +#define XKB_KEY_Cyrillic_io 0x06a3 /* U+0451 CYRILLIC SMALL LETTER IO */ +#define XKB_KEY_Ukrainian_ie 0x06a4 /* U+0454 CYRILLIC SMALL LETTER UKRAINIAN IE */ +#define XKB_KEY_Ukranian_je 0x06a4 /* deprecated */ +#define XKB_KEY_Macedonia_dse 0x06a5 /* U+0455 CYRILLIC SMALL LETTER DZE */ +#define XKB_KEY_Ukrainian_i 0x06a6 /* U+0456 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ +#define XKB_KEY_Ukranian_i 0x06a6 /* deprecated */ +#define XKB_KEY_Ukrainian_yi 0x06a7 /* U+0457 CYRILLIC SMALL LETTER YI */ +#define XKB_KEY_Ukranian_yi 0x06a7 /* deprecated */ +#define XKB_KEY_Cyrillic_je 0x06a8 /* U+0458 CYRILLIC SMALL LETTER JE */ +#define XKB_KEY_Serbian_je 0x06a8 /* deprecated */ +#define XKB_KEY_Cyrillic_lje 0x06a9 /* U+0459 CYRILLIC SMALL LETTER LJE */ +#define XKB_KEY_Serbian_lje 0x06a9 /* deprecated */ +#define XKB_KEY_Cyrillic_nje 0x06aa /* U+045A CYRILLIC SMALL LETTER NJE */ +#define XKB_KEY_Serbian_nje 0x06aa /* deprecated */ +#define XKB_KEY_Serbian_tshe 0x06ab /* U+045B CYRILLIC SMALL LETTER TSHE */ +#define XKB_KEY_Macedonia_kje 0x06ac /* U+045C CYRILLIC SMALL LETTER KJE */ +#define XKB_KEY_Ukrainian_ghe_with_upturn 0x06ad /* U+0491 CYRILLIC SMALL LETTER GHE WITH UPTURN */ +#define XKB_KEY_Byelorussian_shortu 0x06ae /* U+045E CYRILLIC SMALL LETTER SHORT U */ +#define XKB_KEY_Cyrillic_dzhe 0x06af /* U+045F CYRILLIC SMALL LETTER DZHE */ +#define XKB_KEY_Serbian_dze 0x06af /* deprecated */ +#define XKB_KEY_numerosign 0x06b0 /* U+2116 NUMERO SIGN */ +#define XKB_KEY_Serbian_DJE 0x06b1 /* U+0402 CYRILLIC CAPITAL LETTER DJE */ +#define XKB_KEY_Macedonia_GJE 0x06b2 /* U+0403 CYRILLIC CAPITAL LETTER GJE */ +#define XKB_KEY_Cyrillic_IO 0x06b3 /* U+0401 CYRILLIC CAPITAL LETTER IO */ +#define XKB_KEY_Ukrainian_IE 0x06b4 /* U+0404 CYRILLIC CAPITAL LETTER UKRAINIAN IE */ +#define XKB_KEY_Ukranian_JE 0x06b4 /* deprecated */ +#define XKB_KEY_Macedonia_DSE 0x06b5 /* U+0405 CYRILLIC CAPITAL LETTER DZE */ +#define XKB_KEY_Ukrainian_I 0x06b6 /* U+0406 CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ +#define XKB_KEY_Ukranian_I 0x06b6 /* deprecated */ +#define XKB_KEY_Ukrainian_YI 0x06b7 /* U+0407 CYRILLIC CAPITAL LETTER YI */ +#define XKB_KEY_Ukranian_YI 0x06b7 /* deprecated */ +#define XKB_KEY_Cyrillic_JE 0x06b8 /* U+0408 CYRILLIC CAPITAL LETTER JE */ +#define XKB_KEY_Serbian_JE 0x06b8 /* deprecated */ +#define XKB_KEY_Cyrillic_LJE 0x06b9 /* U+0409 CYRILLIC CAPITAL LETTER LJE */ +#define XKB_KEY_Serbian_LJE 0x06b9 /* deprecated */ +#define XKB_KEY_Cyrillic_NJE 0x06ba /* U+040A CYRILLIC CAPITAL LETTER NJE */ +#define XKB_KEY_Serbian_NJE 0x06ba /* deprecated */ +#define XKB_KEY_Serbian_TSHE 0x06bb /* U+040B CYRILLIC CAPITAL LETTER TSHE */ +#define XKB_KEY_Macedonia_KJE 0x06bc /* U+040C CYRILLIC CAPITAL LETTER KJE */ +#define XKB_KEY_Ukrainian_GHE_WITH_UPTURN 0x06bd /* U+0490 CYRILLIC CAPITAL LETTER GHE WITH UPTURN */ +#define XKB_KEY_Byelorussian_SHORTU 0x06be /* U+040E CYRILLIC CAPITAL LETTER SHORT U */ +#define XKB_KEY_Cyrillic_DZHE 0x06bf /* U+040F CYRILLIC CAPITAL LETTER DZHE */ +#define XKB_KEY_Serbian_DZE 0x06bf /* deprecated */ +#define XKB_KEY_Cyrillic_yu 0x06c0 /* U+044E CYRILLIC SMALL LETTER YU */ +#define XKB_KEY_Cyrillic_a 0x06c1 /* U+0430 CYRILLIC SMALL LETTER A */ +#define XKB_KEY_Cyrillic_be 0x06c2 /* U+0431 CYRILLIC SMALL LETTER BE */ +#define XKB_KEY_Cyrillic_tse 0x06c3 /* U+0446 CYRILLIC SMALL LETTER TSE */ +#define XKB_KEY_Cyrillic_de 0x06c4 /* U+0434 CYRILLIC SMALL LETTER DE */ +#define XKB_KEY_Cyrillic_ie 0x06c5 /* U+0435 CYRILLIC SMALL LETTER IE */ +#define XKB_KEY_Cyrillic_ef 0x06c6 /* U+0444 CYRILLIC SMALL LETTER EF */ +#define XKB_KEY_Cyrillic_ghe 0x06c7 /* U+0433 CYRILLIC SMALL LETTER GHE */ +#define XKB_KEY_Cyrillic_ha 0x06c8 /* U+0445 CYRILLIC SMALL LETTER HA */ +#define XKB_KEY_Cyrillic_i 0x06c9 /* U+0438 CYRILLIC SMALL LETTER I */ +#define XKB_KEY_Cyrillic_shorti 0x06ca /* U+0439 CYRILLIC SMALL LETTER SHORT I */ +#define XKB_KEY_Cyrillic_ka 0x06cb /* U+043A CYRILLIC SMALL LETTER KA */ +#define XKB_KEY_Cyrillic_el 0x06cc /* U+043B CYRILLIC SMALL LETTER EL */ +#define XKB_KEY_Cyrillic_em 0x06cd /* U+043C CYRILLIC SMALL LETTER EM */ +#define XKB_KEY_Cyrillic_en 0x06ce /* U+043D CYRILLIC SMALL LETTER EN */ +#define XKB_KEY_Cyrillic_o 0x06cf /* U+043E CYRILLIC SMALL LETTER O */ +#define XKB_KEY_Cyrillic_pe 0x06d0 /* U+043F CYRILLIC SMALL LETTER PE */ +#define XKB_KEY_Cyrillic_ya 0x06d1 /* U+044F CYRILLIC SMALL LETTER YA */ +#define XKB_KEY_Cyrillic_er 0x06d2 /* U+0440 CYRILLIC SMALL LETTER ER */ +#define XKB_KEY_Cyrillic_es 0x06d3 /* U+0441 CYRILLIC SMALL LETTER ES */ +#define XKB_KEY_Cyrillic_te 0x06d4 /* U+0442 CYRILLIC SMALL LETTER TE */ +#define XKB_KEY_Cyrillic_u 0x06d5 /* U+0443 CYRILLIC SMALL LETTER U */ +#define XKB_KEY_Cyrillic_zhe 0x06d6 /* U+0436 CYRILLIC SMALL LETTER ZHE */ +#define XKB_KEY_Cyrillic_ve 0x06d7 /* U+0432 CYRILLIC SMALL LETTER VE */ +#define XKB_KEY_Cyrillic_softsign 0x06d8 /* U+044C CYRILLIC SMALL LETTER SOFT SIGN */ +#define XKB_KEY_Cyrillic_yeru 0x06d9 /* U+044B CYRILLIC SMALL LETTER YERU */ +#define XKB_KEY_Cyrillic_ze 0x06da /* U+0437 CYRILLIC SMALL LETTER ZE */ +#define XKB_KEY_Cyrillic_sha 0x06db /* U+0448 CYRILLIC SMALL LETTER SHA */ +#define XKB_KEY_Cyrillic_e 0x06dc /* U+044D CYRILLIC SMALL LETTER E */ +#define XKB_KEY_Cyrillic_shcha 0x06dd /* U+0449 CYRILLIC SMALL LETTER SHCHA */ +#define XKB_KEY_Cyrillic_che 0x06de /* U+0447 CYRILLIC SMALL LETTER CHE */ +#define XKB_KEY_Cyrillic_hardsign 0x06df /* U+044A CYRILLIC SMALL LETTER HARD SIGN */ +#define XKB_KEY_Cyrillic_YU 0x06e0 /* U+042E CYRILLIC CAPITAL LETTER YU */ +#define XKB_KEY_Cyrillic_A 0x06e1 /* U+0410 CYRILLIC CAPITAL LETTER A */ +#define XKB_KEY_Cyrillic_BE 0x06e2 /* U+0411 CYRILLIC CAPITAL LETTER BE */ +#define XKB_KEY_Cyrillic_TSE 0x06e3 /* U+0426 CYRILLIC CAPITAL LETTER TSE */ +#define XKB_KEY_Cyrillic_DE 0x06e4 /* U+0414 CYRILLIC CAPITAL LETTER DE */ +#define XKB_KEY_Cyrillic_IE 0x06e5 /* U+0415 CYRILLIC CAPITAL LETTER IE */ +#define XKB_KEY_Cyrillic_EF 0x06e6 /* U+0424 CYRILLIC CAPITAL LETTER EF */ +#define XKB_KEY_Cyrillic_GHE 0x06e7 /* U+0413 CYRILLIC CAPITAL LETTER GHE */ +#define XKB_KEY_Cyrillic_HA 0x06e8 /* U+0425 CYRILLIC CAPITAL LETTER HA */ +#define XKB_KEY_Cyrillic_I 0x06e9 /* U+0418 CYRILLIC CAPITAL LETTER I */ +#define XKB_KEY_Cyrillic_SHORTI 0x06ea /* U+0419 CYRILLIC CAPITAL LETTER SHORT I */ +#define XKB_KEY_Cyrillic_KA 0x06eb /* U+041A CYRILLIC CAPITAL LETTER KA */ +#define XKB_KEY_Cyrillic_EL 0x06ec /* U+041B CYRILLIC CAPITAL LETTER EL */ +#define XKB_KEY_Cyrillic_EM 0x06ed /* U+041C CYRILLIC CAPITAL LETTER EM */ +#define XKB_KEY_Cyrillic_EN 0x06ee /* U+041D CYRILLIC CAPITAL LETTER EN */ +#define XKB_KEY_Cyrillic_O 0x06ef /* U+041E CYRILLIC CAPITAL LETTER O */ +#define XKB_KEY_Cyrillic_PE 0x06f0 /* U+041F CYRILLIC CAPITAL LETTER PE */ +#define XKB_KEY_Cyrillic_YA 0x06f1 /* U+042F CYRILLIC CAPITAL LETTER YA */ +#define XKB_KEY_Cyrillic_ER 0x06f2 /* U+0420 CYRILLIC CAPITAL LETTER ER */ +#define XKB_KEY_Cyrillic_ES 0x06f3 /* U+0421 CYRILLIC CAPITAL LETTER ES */ +#define XKB_KEY_Cyrillic_TE 0x06f4 /* U+0422 CYRILLIC CAPITAL LETTER TE */ +#define XKB_KEY_Cyrillic_U 0x06f5 /* U+0423 CYRILLIC CAPITAL LETTER U */ +#define XKB_KEY_Cyrillic_ZHE 0x06f6 /* U+0416 CYRILLIC CAPITAL LETTER ZHE */ +#define XKB_KEY_Cyrillic_VE 0x06f7 /* U+0412 CYRILLIC CAPITAL LETTER VE */ +#define XKB_KEY_Cyrillic_SOFTSIGN 0x06f8 /* U+042C CYRILLIC CAPITAL LETTER SOFT SIGN */ +#define XKB_KEY_Cyrillic_YERU 0x06f9 /* U+042B CYRILLIC CAPITAL LETTER YERU */ +#define XKB_KEY_Cyrillic_ZE 0x06fa /* U+0417 CYRILLIC CAPITAL LETTER ZE */ +#define XKB_KEY_Cyrillic_SHA 0x06fb /* U+0428 CYRILLIC CAPITAL LETTER SHA */ +#define XKB_KEY_Cyrillic_E 0x06fc /* U+042D CYRILLIC CAPITAL LETTER E */ +#define XKB_KEY_Cyrillic_SHCHA 0x06fd /* U+0429 CYRILLIC CAPITAL LETTER SHCHA */ +#define XKB_KEY_Cyrillic_CHE 0x06fe /* U+0427 CYRILLIC CAPITAL LETTER CHE */ +#define XKB_KEY_Cyrillic_HARDSIGN 0x06ff /* U+042A CYRILLIC CAPITAL LETTER HARD SIGN */ + +/* + * Greek + * (based on an early draft of, and not quite identical to, ISO/IEC 8859-7) + * Byte 3 = 7 + */ + +#define XKB_KEY_Greek_ALPHAaccent 0x07a1 /* U+0386 GREEK CAPITAL LETTER ALPHA WITH TONOS */ +#define XKB_KEY_Greek_EPSILONaccent 0x07a2 /* U+0388 GREEK CAPITAL LETTER EPSILON WITH TONOS */ +#define XKB_KEY_Greek_ETAaccent 0x07a3 /* U+0389 GREEK CAPITAL LETTER ETA WITH TONOS */ +#define XKB_KEY_Greek_IOTAaccent 0x07a4 /* U+038A GREEK CAPITAL LETTER IOTA WITH TONOS */ +#define XKB_KEY_Greek_IOTAdieresis 0x07a5 /* U+03AA GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ +#define XKB_KEY_Greek_IOTAdiaeresis 0x07a5 /* old typo */ +#define XKB_KEY_Greek_OMICRONaccent 0x07a7 /* U+038C GREEK CAPITAL LETTER OMICRON WITH TONOS */ +#define XKB_KEY_Greek_UPSILONaccent 0x07a8 /* U+038E GREEK CAPITAL LETTER UPSILON WITH TONOS */ +#define XKB_KEY_Greek_UPSILONdieresis 0x07a9 /* U+03AB GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ +#define XKB_KEY_Greek_OMEGAaccent 0x07ab /* U+038F GREEK CAPITAL LETTER OMEGA WITH TONOS */ +#define XKB_KEY_Greek_accentdieresis 0x07ae /* U+0385 GREEK DIALYTIKA TONOS */ +#define XKB_KEY_Greek_horizbar 0x07af /* U+2015 HORIZONTAL BAR */ +#define XKB_KEY_Greek_alphaaccent 0x07b1 /* U+03AC GREEK SMALL LETTER ALPHA WITH TONOS */ +#define XKB_KEY_Greek_epsilonaccent 0x07b2 /* U+03AD GREEK SMALL LETTER EPSILON WITH TONOS */ +#define XKB_KEY_Greek_etaaccent 0x07b3 /* U+03AE GREEK SMALL LETTER ETA WITH TONOS */ +#define XKB_KEY_Greek_iotaaccent 0x07b4 /* U+03AF GREEK SMALL LETTER IOTA WITH TONOS */ +#define XKB_KEY_Greek_iotadieresis 0x07b5 /* U+03CA GREEK SMALL LETTER IOTA WITH DIALYTIKA */ +#define XKB_KEY_Greek_iotaaccentdieresis 0x07b6 /* U+0390 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ +#define XKB_KEY_Greek_omicronaccent 0x07b7 /* U+03CC GREEK SMALL LETTER OMICRON WITH TONOS */ +#define XKB_KEY_Greek_upsilonaccent 0x07b8 /* U+03CD GREEK SMALL LETTER UPSILON WITH TONOS */ +#define XKB_KEY_Greek_upsilondieresis 0x07b9 /* U+03CB GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ +#define XKB_KEY_Greek_upsilonaccentdieresis 0x07ba /* U+03B0 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ +#define XKB_KEY_Greek_omegaaccent 0x07bb /* U+03CE GREEK SMALL LETTER OMEGA WITH TONOS */ +#define XKB_KEY_Greek_ALPHA 0x07c1 /* U+0391 GREEK CAPITAL LETTER ALPHA */ +#define XKB_KEY_Greek_BETA 0x07c2 /* U+0392 GREEK CAPITAL LETTER BETA */ +#define XKB_KEY_Greek_GAMMA 0x07c3 /* U+0393 GREEK CAPITAL LETTER GAMMA */ +#define XKB_KEY_Greek_DELTA 0x07c4 /* U+0394 GREEK CAPITAL LETTER DELTA */ +#define XKB_KEY_Greek_EPSILON 0x07c5 /* U+0395 GREEK CAPITAL LETTER EPSILON */ +#define XKB_KEY_Greek_ZETA 0x07c6 /* U+0396 GREEK CAPITAL LETTER ZETA */ +#define XKB_KEY_Greek_ETA 0x07c7 /* U+0397 GREEK CAPITAL LETTER ETA */ +#define XKB_KEY_Greek_THETA 0x07c8 /* U+0398 GREEK CAPITAL LETTER THETA */ +#define XKB_KEY_Greek_IOTA 0x07c9 /* U+0399 GREEK CAPITAL LETTER IOTA */ +#define XKB_KEY_Greek_KAPPA 0x07ca /* U+039A GREEK CAPITAL LETTER KAPPA */ +#define XKB_KEY_Greek_LAMDA 0x07cb /* U+039B GREEK CAPITAL LETTER LAMDA */ +#define XKB_KEY_Greek_LAMBDA 0x07cb /* U+039B GREEK CAPITAL LETTER LAMDA */ +#define XKB_KEY_Greek_MU 0x07cc /* U+039C GREEK CAPITAL LETTER MU */ +#define XKB_KEY_Greek_NU 0x07cd /* U+039D GREEK CAPITAL LETTER NU */ +#define XKB_KEY_Greek_XI 0x07ce /* U+039E GREEK CAPITAL LETTER XI */ +#define XKB_KEY_Greek_OMICRON 0x07cf /* U+039F GREEK CAPITAL LETTER OMICRON */ +#define XKB_KEY_Greek_PI 0x07d0 /* U+03A0 GREEK CAPITAL LETTER PI */ +#define XKB_KEY_Greek_RHO 0x07d1 /* U+03A1 GREEK CAPITAL LETTER RHO */ +#define XKB_KEY_Greek_SIGMA 0x07d2 /* U+03A3 GREEK CAPITAL LETTER SIGMA */ +#define XKB_KEY_Greek_TAU 0x07d4 /* U+03A4 GREEK CAPITAL LETTER TAU */ +#define XKB_KEY_Greek_UPSILON 0x07d5 /* U+03A5 GREEK CAPITAL LETTER UPSILON */ +#define XKB_KEY_Greek_PHI 0x07d6 /* U+03A6 GREEK CAPITAL LETTER PHI */ +#define XKB_KEY_Greek_CHI 0x07d7 /* U+03A7 GREEK CAPITAL LETTER CHI */ +#define XKB_KEY_Greek_PSI 0x07d8 /* U+03A8 GREEK CAPITAL LETTER PSI */ +#define XKB_KEY_Greek_OMEGA 0x07d9 /* U+03A9 GREEK CAPITAL LETTER OMEGA */ +#define XKB_KEY_Greek_alpha 0x07e1 /* U+03B1 GREEK SMALL LETTER ALPHA */ +#define XKB_KEY_Greek_beta 0x07e2 /* U+03B2 GREEK SMALL LETTER BETA */ +#define XKB_KEY_Greek_gamma 0x07e3 /* U+03B3 GREEK SMALL LETTER GAMMA */ +#define XKB_KEY_Greek_delta 0x07e4 /* U+03B4 GREEK SMALL LETTER DELTA */ +#define XKB_KEY_Greek_epsilon 0x07e5 /* U+03B5 GREEK SMALL LETTER EPSILON */ +#define XKB_KEY_Greek_zeta 0x07e6 /* U+03B6 GREEK SMALL LETTER ZETA */ +#define XKB_KEY_Greek_eta 0x07e7 /* U+03B7 GREEK SMALL LETTER ETA */ +#define XKB_KEY_Greek_theta 0x07e8 /* U+03B8 GREEK SMALL LETTER THETA */ +#define XKB_KEY_Greek_iota 0x07e9 /* U+03B9 GREEK SMALL LETTER IOTA */ +#define XKB_KEY_Greek_kappa 0x07ea /* U+03BA GREEK SMALL LETTER KAPPA */ +#define XKB_KEY_Greek_lamda 0x07eb /* U+03BB GREEK SMALL LETTER LAMDA */ +#define XKB_KEY_Greek_lambda 0x07eb /* U+03BB GREEK SMALL LETTER LAMDA */ +#define XKB_KEY_Greek_mu 0x07ec /* U+03BC GREEK SMALL LETTER MU */ +#define XKB_KEY_Greek_nu 0x07ed /* U+03BD GREEK SMALL LETTER NU */ +#define XKB_KEY_Greek_xi 0x07ee /* U+03BE GREEK SMALL LETTER XI */ +#define XKB_KEY_Greek_omicron 0x07ef /* U+03BF GREEK SMALL LETTER OMICRON */ +#define XKB_KEY_Greek_pi 0x07f0 /* U+03C0 GREEK SMALL LETTER PI */ +#define XKB_KEY_Greek_rho 0x07f1 /* U+03C1 GREEK SMALL LETTER RHO */ +#define XKB_KEY_Greek_sigma 0x07f2 /* U+03C3 GREEK SMALL LETTER SIGMA */ +#define XKB_KEY_Greek_finalsmallsigma 0x07f3 /* U+03C2 GREEK SMALL LETTER FINAL SIGMA */ +#define XKB_KEY_Greek_tau 0x07f4 /* U+03C4 GREEK SMALL LETTER TAU */ +#define XKB_KEY_Greek_upsilon 0x07f5 /* U+03C5 GREEK SMALL LETTER UPSILON */ +#define XKB_KEY_Greek_phi 0x07f6 /* U+03C6 GREEK SMALL LETTER PHI */ +#define XKB_KEY_Greek_chi 0x07f7 /* U+03C7 GREEK SMALL LETTER CHI */ +#define XKB_KEY_Greek_psi 0x07f8 /* U+03C8 GREEK SMALL LETTER PSI */ +#define XKB_KEY_Greek_omega 0x07f9 /* U+03C9 GREEK SMALL LETTER OMEGA */ +#define XKB_KEY_Greek_switch 0xff7e /* Alias for mode_switch */ + +/* + * Technical + * (from the DEC VT330/VT420 Technical Character Set, http://vt100.net/charsets/technical.html) + * Byte 3 = 8 + */ + +#define XKB_KEY_leftradical 0x08a1 /* U+23B7 RADICAL SYMBOL BOTTOM */ +#define XKB_KEY_topleftradical 0x08a2 /*(U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT)*/ +#define XKB_KEY_horizconnector 0x08a3 /*(U+2500 BOX DRAWINGS LIGHT HORIZONTAL)*/ +#define XKB_KEY_topintegral 0x08a4 /* U+2320 TOP HALF INTEGRAL */ +#define XKB_KEY_botintegral 0x08a5 /* U+2321 BOTTOM HALF INTEGRAL */ +#define XKB_KEY_vertconnector 0x08a6 /*(U+2502 BOX DRAWINGS LIGHT VERTICAL)*/ +#define XKB_KEY_topleftsqbracket 0x08a7 /* U+23A1 LEFT SQUARE BRACKET UPPER CORNER */ +#define XKB_KEY_botleftsqbracket 0x08a8 /* U+23A3 LEFT SQUARE BRACKET LOWER CORNER */ +#define XKB_KEY_toprightsqbracket 0x08a9 /* U+23A4 RIGHT SQUARE BRACKET UPPER CORNER */ +#define XKB_KEY_botrightsqbracket 0x08aa /* U+23A6 RIGHT SQUARE BRACKET LOWER CORNER */ +#define XKB_KEY_topleftparens 0x08ab /* U+239B LEFT PARENTHESIS UPPER HOOK */ +#define XKB_KEY_botleftparens 0x08ac /* U+239D LEFT PARENTHESIS LOWER HOOK */ +#define XKB_KEY_toprightparens 0x08ad /* U+239E RIGHT PARENTHESIS UPPER HOOK */ +#define XKB_KEY_botrightparens 0x08ae /* U+23A0 RIGHT PARENTHESIS LOWER HOOK */ +#define XKB_KEY_leftmiddlecurlybrace 0x08af /* U+23A8 LEFT CURLY BRACKET MIDDLE PIECE */ +#define XKB_KEY_rightmiddlecurlybrace 0x08b0 /* U+23AC RIGHT CURLY BRACKET MIDDLE PIECE */ +#define XKB_KEY_topleftsummation 0x08b1 +#define XKB_KEY_botleftsummation 0x08b2 +#define XKB_KEY_topvertsummationconnector 0x08b3 +#define XKB_KEY_botvertsummationconnector 0x08b4 +#define XKB_KEY_toprightsummation 0x08b5 +#define XKB_KEY_botrightsummation 0x08b6 +#define XKB_KEY_rightmiddlesummation 0x08b7 +#define XKB_KEY_lessthanequal 0x08bc /* U+2264 LESS-THAN OR EQUAL TO */ +#define XKB_KEY_notequal 0x08bd /* U+2260 NOT EQUAL TO */ +#define XKB_KEY_greaterthanequal 0x08be /* U+2265 GREATER-THAN OR EQUAL TO */ +#define XKB_KEY_integral 0x08bf /* U+222B INTEGRAL */ +#define XKB_KEY_therefore 0x08c0 /* U+2234 THEREFORE */ +#define XKB_KEY_variation 0x08c1 /* U+221D PROPORTIONAL TO */ +#define XKB_KEY_infinity 0x08c2 /* U+221E INFINITY */ +#define XKB_KEY_nabla 0x08c5 /* U+2207 NABLA */ +#define XKB_KEY_approximate 0x08c8 /* U+223C TILDE OPERATOR */ +#define XKB_KEY_similarequal 0x08c9 /* U+2243 ASYMPTOTICALLY EQUAL TO */ +#define XKB_KEY_ifonlyif 0x08cd /* U+21D4 LEFT RIGHT DOUBLE ARROW */ +#define XKB_KEY_implies 0x08ce /* U+21D2 RIGHTWARDS DOUBLE ARROW */ +#define XKB_KEY_identical 0x08cf /* U+2261 IDENTICAL TO */ +#define XKB_KEY_radical 0x08d6 /* U+221A SQUARE ROOT */ +#define XKB_KEY_includedin 0x08da /* U+2282 SUBSET OF */ +#define XKB_KEY_includes 0x08db /* U+2283 SUPERSET OF */ +#define XKB_KEY_intersection 0x08dc /* U+2229 INTERSECTION */ +#define XKB_KEY_union 0x08dd /* U+222A UNION */ +#define XKB_KEY_logicaland 0x08de /* U+2227 LOGICAL AND */ +#define XKB_KEY_logicalor 0x08df /* U+2228 LOGICAL OR */ +#define XKB_KEY_partialderivative 0x08ef /* U+2202 PARTIAL DIFFERENTIAL */ +#define XKB_KEY_function 0x08f6 /* U+0192 LATIN SMALL LETTER F WITH HOOK */ +#define XKB_KEY_leftarrow 0x08fb /* U+2190 LEFTWARDS ARROW */ +#define XKB_KEY_uparrow 0x08fc /* U+2191 UPWARDS ARROW */ +#define XKB_KEY_rightarrow 0x08fd /* U+2192 RIGHTWARDS ARROW */ +#define XKB_KEY_downarrow 0x08fe /* U+2193 DOWNWARDS ARROW */ + +/* + * Special + * (from the DEC VT100 Special Graphics Character Set) + * Byte 3 = 9 + */ + +#define XKB_KEY_blank 0x09df +#define XKB_KEY_soliddiamond 0x09e0 /* U+25C6 BLACK DIAMOND */ +#define XKB_KEY_checkerboard 0x09e1 /* U+2592 MEDIUM SHADE */ +#define XKB_KEY_ht 0x09e2 /* U+2409 SYMBOL FOR HORIZONTAL TABULATION */ +#define XKB_KEY_ff 0x09e3 /* U+240C SYMBOL FOR FORM FEED */ +#define XKB_KEY_cr 0x09e4 /* U+240D SYMBOL FOR CARRIAGE RETURN */ +#define XKB_KEY_lf 0x09e5 /* U+240A SYMBOL FOR LINE FEED */ +#define XKB_KEY_nl 0x09e8 /* U+2424 SYMBOL FOR NEWLINE */ +#define XKB_KEY_vt 0x09e9 /* U+240B SYMBOL FOR VERTICAL TABULATION */ +#define XKB_KEY_lowrightcorner 0x09ea /* U+2518 BOX DRAWINGS LIGHT UP AND LEFT */ +#define XKB_KEY_uprightcorner 0x09eb /* U+2510 BOX DRAWINGS LIGHT DOWN AND LEFT */ +#define XKB_KEY_upleftcorner 0x09ec /* U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT */ +#define XKB_KEY_lowleftcorner 0x09ed /* U+2514 BOX DRAWINGS LIGHT UP AND RIGHT */ +#define XKB_KEY_crossinglines 0x09ee /* U+253C BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ +#define XKB_KEY_horizlinescan1 0x09ef /* U+23BA HORIZONTAL SCAN LINE-1 */ +#define XKB_KEY_horizlinescan3 0x09f0 /* U+23BB HORIZONTAL SCAN LINE-3 */ +#define XKB_KEY_horizlinescan5 0x09f1 /* U+2500 BOX DRAWINGS LIGHT HORIZONTAL */ +#define XKB_KEY_horizlinescan7 0x09f2 /* U+23BC HORIZONTAL SCAN LINE-7 */ +#define XKB_KEY_horizlinescan9 0x09f3 /* U+23BD HORIZONTAL SCAN LINE-9 */ +#define XKB_KEY_leftt 0x09f4 /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ +#define XKB_KEY_rightt 0x09f5 /* U+2524 BOX DRAWINGS LIGHT VERTICAL AND LEFT */ +#define XKB_KEY_bott 0x09f6 /* U+2534 BOX DRAWINGS LIGHT UP AND HORIZONTAL */ +#define XKB_KEY_topt 0x09f7 /* U+252C BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ +#define XKB_KEY_vertbar 0x09f8 /* U+2502 BOX DRAWINGS LIGHT VERTICAL */ + +/* + * Publishing + * (these are probably from a long forgotten DEC Publishing + * font that once shipped with DECwrite) + * Byte 3 = 0x0a + */ + +#define XKB_KEY_emspace 0x0aa1 /* U+2003 EM SPACE */ +#define XKB_KEY_enspace 0x0aa2 /* U+2002 EN SPACE */ +#define XKB_KEY_em3space 0x0aa3 /* U+2004 THREE-PER-EM SPACE */ +#define XKB_KEY_em4space 0x0aa4 /* U+2005 FOUR-PER-EM SPACE */ +#define XKB_KEY_digitspace 0x0aa5 /* U+2007 FIGURE SPACE */ +#define XKB_KEY_punctspace 0x0aa6 /* U+2008 PUNCTUATION SPACE */ +#define XKB_KEY_thinspace 0x0aa7 /* U+2009 THIN SPACE */ +#define XKB_KEY_hairspace 0x0aa8 /* U+200A HAIR SPACE */ +#define XKB_KEY_emdash 0x0aa9 /* U+2014 EM DASH */ +#define XKB_KEY_endash 0x0aaa /* U+2013 EN DASH */ +#define XKB_KEY_signifblank 0x0aac /*(U+2423 OPEN BOX)*/ +#define XKB_KEY_ellipsis 0x0aae /* U+2026 HORIZONTAL ELLIPSIS */ +#define XKB_KEY_doubbaselinedot 0x0aaf /* U+2025 TWO DOT LEADER */ +#define XKB_KEY_onethird 0x0ab0 /* U+2153 VULGAR FRACTION ONE THIRD */ +#define XKB_KEY_twothirds 0x0ab1 /* U+2154 VULGAR FRACTION TWO THIRDS */ +#define XKB_KEY_onefifth 0x0ab2 /* U+2155 VULGAR FRACTION ONE FIFTH */ +#define XKB_KEY_twofifths 0x0ab3 /* U+2156 VULGAR FRACTION TWO FIFTHS */ +#define XKB_KEY_threefifths 0x0ab4 /* U+2157 VULGAR FRACTION THREE FIFTHS */ +#define XKB_KEY_fourfifths 0x0ab5 /* U+2158 VULGAR FRACTION FOUR FIFTHS */ +#define XKB_KEY_onesixth 0x0ab6 /* U+2159 VULGAR FRACTION ONE SIXTH */ +#define XKB_KEY_fivesixths 0x0ab7 /* U+215A VULGAR FRACTION FIVE SIXTHS */ +#define XKB_KEY_careof 0x0ab8 /* U+2105 CARE OF */ +#define XKB_KEY_figdash 0x0abb /* U+2012 FIGURE DASH */ +#define XKB_KEY_leftanglebracket 0x0abc /*(U+2329 LEFT-POINTING ANGLE BRACKET)*/ +#define XKB_KEY_decimalpoint 0x0abd /*(U+002E FULL STOP)*/ +#define XKB_KEY_rightanglebracket 0x0abe /*(U+232A RIGHT-POINTING ANGLE BRACKET)*/ +#define XKB_KEY_marker 0x0abf +#define XKB_KEY_oneeighth 0x0ac3 /* U+215B VULGAR FRACTION ONE EIGHTH */ +#define XKB_KEY_threeeighths 0x0ac4 /* U+215C VULGAR FRACTION THREE EIGHTHS */ +#define XKB_KEY_fiveeighths 0x0ac5 /* U+215D VULGAR FRACTION FIVE EIGHTHS */ +#define XKB_KEY_seveneighths 0x0ac6 /* U+215E VULGAR FRACTION SEVEN EIGHTHS */ +#define XKB_KEY_trademark 0x0ac9 /* U+2122 TRADE MARK SIGN */ +#define XKB_KEY_signaturemark 0x0aca /*(U+2613 SALTIRE)*/ +#define XKB_KEY_trademarkincircle 0x0acb +#define XKB_KEY_leftopentriangle 0x0acc /*(U+25C1 WHITE LEFT-POINTING TRIANGLE)*/ +#define XKB_KEY_rightopentriangle 0x0acd /*(U+25B7 WHITE RIGHT-POINTING TRIANGLE)*/ +#define XKB_KEY_emopencircle 0x0ace /*(U+25CB WHITE CIRCLE)*/ +#define XKB_KEY_emopenrectangle 0x0acf /*(U+25AF WHITE VERTICAL RECTANGLE)*/ +#define XKB_KEY_leftsinglequotemark 0x0ad0 /* U+2018 LEFT SINGLE QUOTATION MARK */ +#define XKB_KEY_rightsinglequotemark 0x0ad1 /* U+2019 RIGHT SINGLE QUOTATION MARK */ +#define XKB_KEY_leftdoublequotemark 0x0ad2 /* U+201C LEFT DOUBLE QUOTATION MARK */ +#define XKB_KEY_rightdoublequotemark 0x0ad3 /* U+201D RIGHT DOUBLE QUOTATION MARK */ +#define XKB_KEY_prescription 0x0ad4 /* U+211E PRESCRIPTION TAKE */ +#define XKB_KEY_permille 0x0ad5 /* U+2030 PER MILLE SIGN */ +#define XKB_KEY_minutes 0x0ad6 /* U+2032 PRIME */ +#define XKB_KEY_seconds 0x0ad7 /* U+2033 DOUBLE PRIME */ +#define XKB_KEY_latincross 0x0ad9 /* U+271D LATIN CROSS */ +#define XKB_KEY_hexagram 0x0ada +#define XKB_KEY_filledrectbullet 0x0adb /*(U+25AC BLACK RECTANGLE)*/ +#define XKB_KEY_filledlefttribullet 0x0adc /*(U+25C0 BLACK LEFT-POINTING TRIANGLE)*/ +#define XKB_KEY_filledrighttribullet 0x0add /*(U+25B6 BLACK RIGHT-POINTING TRIANGLE)*/ +#define XKB_KEY_emfilledcircle 0x0ade /*(U+25CF BLACK CIRCLE)*/ +#define XKB_KEY_emfilledrect 0x0adf /*(U+25AE BLACK VERTICAL RECTANGLE)*/ +#define XKB_KEY_enopencircbullet 0x0ae0 /*(U+25E6 WHITE BULLET)*/ +#define XKB_KEY_enopensquarebullet 0x0ae1 /*(U+25AB WHITE SMALL SQUARE)*/ +#define XKB_KEY_openrectbullet 0x0ae2 /*(U+25AD WHITE RECTANGLE)*/ +#define XKB_KEY_opentribulletup 0x0ae3 /*(U+25B3 WHITE UP-POINTING TRIANGLE)*/ +#define XKB_KEY_opentribulletdown 0x0ae4 /*(U+25BD WHITE DOWN-POINTING TRIANGLE)*/ +#define XKB_KEY_openstar 0x0ae5 /*(U+2606 WHITE STAR)*/ +#define XKB_KEY_enfilledcircbullet 0x0ae6 /*(U+2022 BULLET)*/ +#define XKB_KEY_enfilledsqbullet 0x0ae7 /*(U+25AA BLACK SMALL SQUARE)*/ +#define XKB_KEY_filledtribulletup 0x0ae8 /*(U+25B2 BLACK UP-POINTING TRIANGLE)*/ +#define XKB_KEY_filledtribulletdown 0x0ae9 /*(U+25BC BLACK DOWN-POINTING TRIANGLE)*/ +#define XKB_KEY_leftpointer 0x0aea /*(U+261C WHITE LEFT POINTING INDEX)*/ +#define XKB_KEY_rightpointer 0x0aeb /*(U+261E WHITE RIGHT POINTING INDEX)*/ +#define XKB_KEY_club 0x0aec /* U+2663 BLACK CLUB SUIT */ +#define XKB_KEY_diamond 0x0aed /* U+2666 BLACK DIAMOND SUIT */ +#define XKB_KEY_heart 0x0aee /* U+2665 BLACK HEART SUIT */ +#define XKB_KEY_maltesecross 0x0af0 /* U+2720 MALTESE CROSS */ +#define XKB_KEY_dagger 0x0af1 /* U+2020 DAGGER */ +#define XKB_KEY_doubledagger 0x0af2 /* U+2021 DOUBLE DAGGER */ +#define XKB_KEY_checkmark 0x0af3 /* U+2713 CHECK MARK */ +#define XKB_KEY_ballotcross 0x0af4 /* U+2717 BALLOT X */ +#define XKB_KEY_musicalsharp 0x0af5 /* U+266F MUSIC SHARP SIGN */ +#define XKB_KEY_musicalflat 0x0af6 /* U+266D MUSIC FLAT SIGN */ +#define XKB_KEY_malesymbol 0x0af7 /* U+2642 MALE SIGN */ +#define XKB_KEY_femalesymbol 0x0af8 /* U+2640 FEMALE SIGN */ +#define XKB_KEY_telephone 0x0af9 /* U+260E BLACK TELEPHONE */ +#define XKB_KEY_telephonerecorder 0x0afa /* U+2315 TELEPHONE RECORDER */ +#define XKB_KEY_phonographcopyright 0x0afb /* U+2117 SOUND RECORDING COPYRIGHT */ +#define XKB_KEY_caret 0x0afc /* U+2038 CARET */ +#define XKB_KEY_singlelowquotemark 0x0afd /* U+201A SINGLE LOW-9 QUOTATION MARK */ +#define XKB_KEY_doublelowquotemark 0x0afe /* U+201E DOUBLE LOW-9 QUOTATION MARK */ +#define XKB_KEY_cursor 0x0aff + +/* + * APL + * Byte 3 = 0x0b + */ + +#define XKB_KEY_leftcaret 0x0ba3 /*(U+003C LESS-THAN SIGN)*/ +#define XKB_KEY_rightcaret 0x0ba6 /*(U+003E GREATER-THAN SIGN)*/ +#define XKB_KEY_downcaret 0x0ba8 /*(U+2228 LOGICAL OR)*/ +#define XKB_KEY_upcaret 0x0ba9 /*(U+2227 LOGICAL AND)*/ +#define XKB_KEY_overbar 0x0bc0 /*(U+00AF MACRON)*/ +#define XKB_KEY_downtack 0x0bc2 /* U+22A4 DOWN TACK */ +#define XKB_KEY_upshoe 0x0bc3 /*(U+2229 INTERSECTION)*/ +#define XKB_KEY_downstile 0x0bc4 /* U+230A LEFT FLOOR */ +#define XKB_KEY_underbar 0x0bc6 /*(U+005F LOW LINE)*/ +#define XKB_KEY_jot 0x0bca /* U+2218 RING OPERATOR */ +#define XKB_KEY_quad 0x0bcc /* U+2395 APL FUNCTIONAL SYMBOL QUAD */ +#define XKB_KEY_uptack 0x0bce /* U+22A5 UP TACK */ +#define XKB_KEY_circle 0x0bcf /* U+25CB WHITE CIRCLE */ +#define XKB_KEY_upstile 0x0bd3 /* U+2308 LEFT CEILING */ +#define XKB_KEY_downshoe 0x0bd6 /*(U+222A UNION)*/ +#define XKB_KEY_rightshoe 0x0bd8 /*(U+2283 SUPERSET OF)*/ +#define XKB_KEY_leftshoe 0x0bda /*(U+2282 SUBSET OF)*/ +#define XKB_KEY_lefttack 0x0bdc /* U+22A3 LEFT TACK */ +#define XKB_KEY_righttack 0x0bfc /* U+22A2 RIGHT TACK */ + +/* + * Hebrew + * Byte 3 = 0x0c + */ + +#define XKB_KEY_hebrew_doublelowline 0x0cdf /* U+2017 DOUBLE LOW LINE */ +#define XKB_KEY_hebrew_aleph 0x0ce0 /* U+05D0 HEBREW LETTER ALEF */ +#define XKB_KEY_hebrew_bet 0x0ce1 /* U+05D1 HEBREW LETTER BET */ +#define XKB_KEY_hebrew_beth 0x0ce1 /* deprecated */ +#define XKB_KEY_hebrew_gimel 0x0ce2 /* U+05D2 HEBREW LETTER GIMEL */ +#define XKB_KEY_hebrew_gimmel 0x0ce2 /* deprecated */ +#define XKB_KEY_hebrew_dalet 0x0ce3 /* U+05D3 HEBREW LETTER DALET */ +#define XKB_KEY_hebrew_daleth 0x0ce3 /* deprecated */ +#define XKB_KEY_hebrew_he 0x0ce4 /* U+05D4 HEBREW LETTER HE */ +#define XKB_KEY_hebrew_waw 0x0ce5 /* U+05D5 HEBREW LETTER VAV */ +#define XKB_KEY_hebrew_zain 0x0ce6 /* U+05D6 HEBREW LETTER ZAYIN */ +#define XKB_KEY_hebrew_zayin 0x0ce6 /* deprecated */ +#define XKB_KEY_hebrew_chet 0x0ce7 /* U+05D7 HEBREW LETTER HET */ +#define XKB_KEY_hebrew_het 0x0ce7 /* deprecated */ +#define XKB_KEY_hebrew_tet 0x0ce8 /* U+05D8 HEBREW LETTER TET */ +#define XKB_KEY_hebrew_teth 0x0ce8 /* deprecated */ +#define XKB_KEY_hebrew_yod 0x0ce9 /* U+05D9 HEBREW LETTER YOD */ +#define XKB_KEY_hebrew_finalkaph 0x0cea /* U+05DA HEBREW LETTER FINAL KAF */ +#define XKB_KEY_hebrew_kaph 0x0ceb /* U+05DB HEBREW LETTER KAF */ +#define XKB_KEY_hebrew_lamed 0x0cec /* U+05DC HEBREW LETTER LAMED */ +#define XKB_KEY_hebrew_finalmem 0x0ced /* U+05DD HEBREW LETTER FINAL MEM */ +#define XKB_KEY_hebrew_mem 0x0cee /* U+05DE HEBREW LETTER MEM */ +#define XKB_KEY_hebrew_finalnun 0x0cef /* U+05DF HEBREW LETTER FINAL NUN */ +#define XKB_KEY_hebrew_nun 0x0cf0 /* U+05E0 HEBREW LETTER NUN */ +#define XKB_KEY_hebrew_samech 0x0cf1 /* U+05E1 HEBREW LETTER SAMEKH */ +#define XKB_KEY_hebrew_samekh 0x0cf1 /* deprecated */ +#define XKB_KEY_hebrew_ayin 0x0cf2 /* U+05E2 HEBREW LETTER AYIN */ +#define XKB_KEY_hebrew_finalpe 0x0cf3 /* U+05E3 HEBREW LETTER FINAL PE */ +#define XKB_KEY_hebrew_pe 0x0cf4 /* U+05E4 HEBREW LETTER PE */ +#define XKB_KEY_hebrew_finalzade 0x0cf5 /* U+05E5 HEBREW LETTER FINAL TSADI */ +#define XKB_KEY_hebrew_finalzadi 0x0cf5 /* deprecated */ +#define XKB_KEY_hebrew_zade 0x0cf6 /* U+05E6 HEBREW LETTER TSADI */ +#define XKB_KEY_hebrew_zadi 0x0cf6 /* deprecated */ +#define XKB_KEY_hebrew_qoph 0x0cf7 /* U+05E7 HEBREW LETTER QOF */ +#define XKB_KEY_hebrew_kuf 0x0cf7 /* deprecated */ +#define XKB_KEY_hebrew_resh 0x0cf8 /* U+05E8 HEBREW LETTER RESH */ +#define XKB_KEY_hebrew_shin 0x0cf9 /* U+05E9 HEBREW LETTER SHIN */ +#define XKB_KEY_hebrew_taw 0x0cfa /* U+05EA HEBREW LETTER TAV */ +#define XKB_KEY_hebrew_taf 0x0cfa /* deprecated */ +#define XKB_KEY_Hebrew_switch 0xff7e /* Alias for mode_switch */ + +/* + * Thai + * Byte 3 = 0x0d + */ + +#define XKB_KEY_Thai_kokai 0x0da1 /* U+0E01 THAI CHARACTER KO KAI */ +#define XKB_KEY_Thai_khokhai 0x0da2 /* U+0E02 THAI CHARACTER KHO KHAI */ +#define XKB_KEY_Thai_khokhuat 0x0da3 /* U+0E03 THAI CHARACTER KHO KHUAT */ +#define XKB_KEY_Thai_khokhwai 0x0da4 /* U+0E04 THAI CHARACTER KHO KHWAI */ +#define XKB_KEY_Thai_khokhon 0x0da5 /* U+0E05 THAI CHARACTER KHO KHON */ +#define XKB_KEY_Thai_khorakhang 0x0da6 /* U+0E06 THAI CHARACTER KHO RAKHANG */ +#define XKB_KEY_Thai_ngongu 0x0da7 /* U+0E07 THAI CHARACTER NGO NGU */ +#define XKB_KEY_Thai_chochan 0x0da8 /* U+0E08 THAI CHARACTER CHO CHAN */ +#define XKB_KEY_Thai_choching 0x0da9 /* U+0E09 THAI CHARACTER CHO CHING */ +#define XKB_KEY_Thai_chochang 0x0daa /* U+0E0A THAI CHARACTER CHO CHANG */ +#define XKB_KEY_Thai_soso 0x0dab /* U+0E0B THAI CHARACTER SO SO */ +#define XKB_KEY_Thai_chochoe 0x0dac /* U+0E0C THAI CHARACTER CHO CHOE */ +#define XKB_KEY_Thai_yoying 0x0dad /* U+0E0D THAI CHARACTER YO YING */ +#define XKB_KEY_Thai_dochada 0x0dae /* U+0E0E THAI CHARACTER DO CHADA */ +#define XKB_KEY_Thai_topatak 0x0daf /* U+0E0F THAI CHARACTER TO PATAK */ +#define XKB_KEY_Thai_thothan 0x0db0 /* U+0E10 THAI CHARACTER THO THAN */ +#define XKB_KEY_Thai_thonangmontho 0x0db1 /* U+0E11 THAI CHARACTER THO NANGMONTHO */ +#define XKB_KEY_Thai_thophuthao 0x0db2 /* U+0E12 THAI CHARACTER THO PHUTHAO */ +#define XKB_KEY_Thai_nonen 0x0db3 /* U+0E13 THAI CHARACTER NO NEN */ +#define XKB_KEY_Thai_dodek 0x0db4 /* U+0E14 THAI CHARACTER DO DEK */ +#define XKB_KEY_Thai_totao 0x0db5 /* U+0E15 THAI CHARACTER TO TAO */ +#define XKB_KEY_Thai_thothung 0x0db6 /* U+0E16 THAI CHARACTER THO THUNG */ +#define XKB_KEY_Thai_thothahan 0x0db7 /* U+0E17 THAI CHARACTER THO THAHAN */ +#define XKB_KEY_Thai_thothong 0x0db8 /* U+0E18 THAI CHARACTER THO THONG */ +#define XKB_KEY_Thai_nonu 0x0db9 /* U+0E19 THAI CHARACTER NO NU */ +#define XKB_KEY_Thai_bobaimai 0x0dba /* U+0E1A THAI CHARACTER BO BAIMAI */ +#define XKB_KEY_Thai_popla 0x0dbb /* U+0E1B THAI CHARACTER PO PLA */ +#define XKB_KEY_Thai_phophung 0x0dbc /* U+0E1C THAI CHARACTER PHO PHUNG */ +#define XKB_KEY_Thai_fofa 0x0dbd /* U+0E1D THAI CHARACTER FO FA */ +#define XKB_KEY_Thai_phophan 0x0dbe /* U+0E1E THAI CHARACTER PHO PHAN */ +#define XKB_KEY_Thai_fofan 0x0dbf /* U+0E1F THAI CHARACTER FO FAN */ +#define XKB_KEY_Thai_phosamphao 0x0dc0 /* U+0E20 THAI CHARACTER PHO SAMPHAO */ +#define XKB_KEY_Thai_moma 0x0dc1 /* U+0E21 THAI CHARACTER MO MA */ +#define XKB_KEY_Thai_yoyak 0x0dc2 /* U+0E22 THAI CHARACTER YO YAK */ +#define XKB_KEY_Thai_rorua 0x0dc3 /* U+0E23 THAI CHARACTER RO RUA */ +#define XKB_KEY_Thai_ru 0x0dc4 /* U+0E24 THAI CHARACTER RU */ +#define XKB_KEY_Thai_loling 0x0dc5 /* U+0E25 THAI CHARACTER LO LING */ +#define XKB_KEY_Thai_lu 0x0dc6 /* U+0E26 THAI CHARACTER LU */ +#define XKB_KEY_Thai_wowaen 0x0dc7 /* U+0E27 THAI CHARACTER WO WAEN */ +#define XKB_KEY_Thai_sosala 0x0dc8 /* U+0E28 THAI CHARACTER SO SALA */ +#define XKB_KEY_Thai_sorusi 0x0dc9 /* U+0E29 THAI CHARACTER SO RUSI */ +#define XKB_KEY_Thai_sosua 0x0dca /* U+0E2A THAI CHARACTER SO SUA */ +#define XKB_KEY_Thai_hohip 0x0dcb /* U+0E2B THAI CHARACTER HO HIP */ +#define XKB_KEY_Thai_lochula 0x0dcc /* U+0E2C THAI CHARACTER LO CHULA */ +#define XKB_KEY_Thai_oang 0x0dcd /* U+0E2D THAI CHARACTER O ANG */ +#define XKB_KEY_Thai_honokhuk 0x0dce /* U+0E2E THAI CHARACTER HO NOKHUK */ +#define XKB_KEY_Thai_paiyannoi 0x0dcf /* U+0E2F THAI CHARACTER PAIYANNOI */ +#define XKB_KEY_Thai_saraa 0x0dd0 /* U+0E30 THAI CHARACTER SARA A */ +#define XKB_KEY_Thai_maihanakat 0x0dd1 /* U+0E31 THAI CHARACTER MAI HAN-AKAT */ +#define XKB_KEY_Thai_saraaa 0x0dd2 /* U+0E32 THAI CHARACTER SARA AA */ +#define XKB_KEY_Thai_saraam 0x0dd3 /* U+0E33 THAI CHARACTER SARA AM */ +#define XKB_KEY_Thai_sarai 0x0dd4 /* U+0E34 THAI CHARACTER SARA I */ +#define XKB_KEY_Thai_saraii 0x0dd5 /* U+0E35 THAI CHARACTER SARA II */ +#define XKB_KEY_Thai_saraue 0x0dd6 /* U+0E36 THAI CHARACTER SARA UE */ +#define XKB_KEY_Thai_sarauee 0x0dd7 /* U+0E37 THAI CHARACTER SARA UEE */ +#define XKB_KEY_Thai_sarau 0x0dd8 /* U+0E38 THAI CHARACTER SARA U */ +#define XKB_KEY_Thai_sarauu 0x0dd9 /* U+0E39 THAI CHARACTER SARA UU */ +#define XKB_KEY_Thai_phinthu 0x0dda /* U+0E3A THAI CHARACTER PHINTHU */ +#define XKB_KEY_Thai_maihanakat_maitho 0x0dde +#define XKB_KEY_Thai_baht 0x0ddf /* U+0E3F THAI CURRENCY SYMBOL BAHT */ +#define XKB_KEY_Thai_sarae 0x0de0 /* U+0E40 THAI CHARACTER SARA E */ +#define XKB_KEY_Thai_saraae 0x0de1 /* U+0E41 THAI CHARACTER SARA AE */ +#define XKB_KEY_Thai_sarao 0x0de2 /* U+0E42 THAI CHARACTER SARA O */ +#define XKB_KEY_Thai_saraaimaimuan 0x0de3 /* U+0E43 THAI CHARACTER SARA AI MAIMUAN */ +#define XKB_KEY_Thai_saraaimaimalai 0x0de4 /* U+0E44 THAI CHARACTER SARA AI MAIMALAI */ +#define XKB_KEY_Thai_lakkhangyao 0x0de5 /* U+0E45 THAI CHARACTER LAKKHANGYAO */ +#define XKB_KEY_Thai_maiyamok 0x0de6 /* U+0E46 THAI CHARACTER MAIYAMOK */ +#define XKB_KEY_Thai_maitaikhu 0x0de7 /* U+0E47 THAI CHARACTER MAITAIKHU */ +#define XKB_KEY_Thai_maiek 0x0de8 /* U+0E48 THAI CHARACTER MAI EK */ +#define XKB_KEY_Thai_maitho 0x0de9 /* U+0E49 THAI CHARACTER MAI THO */ +#define XKB_KEY_Thai_maitri 0x0dea /* U+0E4A THAI CHARACTER MAI TRI */ +#define XKB_KEY_Thai_maichattawa 0x0deb /* U+0E4B THAI CHARACTER MAI CHATTAWA */ +#define XKB_KEY_Thai_thanthakhat 0x0dec /* U+0E4C THAI CHARACTER THANTHAKHAT */ +#define XKB_KEY_Thai_nikhahit 0x0ded /* U+0E4D THAI CHARACTER NIKHAHIT */ +#define XKB_KEY_Thai_leksun 0x0df0 /* U+0E50 THAI DIGIT ZERO */ +#define XKB_KEY_Thai_leknung 0x0df1 /* U+0E51 THAI DIGIT ONE */ +#define XKB_KEY_Thai_leksong 0x0df2 /* U+0E52 THAI DIGIT TWO */ +#define XKB_KEY_Thai_leksam 0x0df3 /* U+0E53 THAI DIGIT THREE */ +#define XKB_KEY_Thai_leksi 0x0df4 /* U+0E54 THAI DIGIT FOUR */ +#define XKB_KEY_Thai_lekha 0x0df5 /* U+0E55 THAI DIGIT FIVE */ +#define XKB_KEY_Thai_lekhok 0x0df6 /* U+0E56 THAI DIGIT SIX */ +#define XKB_KEY_Thai_lekchet 0x0df7 /* U+0E57 THAI DIGIT SEVEN */ +#define XKB_KEY_Thai_lekpaet 0x0df8 /* U+0E58 THAI DIGIT EIGHT */ +#define XKB_KEY_Thai_lekkao 0x0df9 /* U+0E59 THAI DIGIT NINE */ + +/* + * Korean + * Byte 3 = 0x0e + */ + + +#define XKB_KEY_Hangul 0xff31 /* Hangul start/stop(toggle) */ +#define XKB_KEY_Hangul_Start 0xff32 /* Hangul start */ +#define XKB_KEY_Hangul_End 0xff33 /* Hangul end, English start */ +#define XKB_KEY_Hangul_Hanja 0xff34 /* Start Hangul->Hanja Conversion */ +#define XKB_KEY_Hangul_Jamo 0xff35 /* Hangul Jamo mode */ +#define XKB_KEY_Hangul_Romaja 0xff36 /* Hangul Romaja mode */ +#define XKB_KEY_Hangul_Codeinput 0xff37 /* Hangul code input mode */ +#define XKB_KEY_Hangul_Jeonja 0xff38 /* Jeonja mode */ +#define XKB_KEY_Hangul_Banja 0xff39 /* Banja mode */ +#define XKB_KEY_Hangul_PreHanja 0xff3a /* Pre Hanja conversion */ +#define XKB_KEY_Hangul_PostHanja 0xff3b /* Post Hanja conversion */ +#define XKB_KEY_Hangul_SingleCandidate 0xff3c /* Single candidate */ +#define XKB_KEY_Hangul_MultipleCandidate 0xff3d /* Multiple candidate */ +#define XKB_KEY_Hangul_PreviousCandidate 0xff3e /* Previous candidate */ +#define XKB_KEY_Hangul_Special 0xff3f /* Special symbols */ +#define XKB_KEY_Hangul_switch 0xff7e /* Alias for mode_switch */ + +/* Hangul Consonant Characters */ +#define XKB_KEY_Hangul_Kiyeog 0x0ea1 /* U+3131 HANGUL LETTER KIYEOK */ +#define XKB_KEY_Hangul_SsangKiyeog 0x0ea2 /* U+3132 HANGUL LETTER SSANGKIYEOK */ +#define XKB_KEY_Hangul_KiyeogSios 0x0ea3 /* U+3133 HANGUL LETTER KIYEOK-SIOS */ +#define XKB_KEY_Hangul_Nieun 0x0ea4 /* U+3134 HANGUL LETTER NIEUN */ +#define XKB_KEY_Hangul_NieunJieuj 0x0ea5 /* U+3135 HANGUL LETTER NIEUN-CIEUC */ +#define XKB_KEY_Hangul_NieunHieuh 0x0ea6 /* U+3136 HANGUL LETTER NIEUN-HIEUH */ +#define XKB_KEY_Hangul_Dikeud 0x0ea7 /* U+3137 HANGUL LETTER TIKEUT */ +#define XKB_KEY_Hangul_SsangDikeud 0x0ea8 /* U+3138 HANGUL LETTER SSANGTIKEUT */ +#define XKB_KEY_Hangul_Rieul 0x0ea9 /* U+3139 HANGUL LETTER RIEUL */ +#define XKB_KEY_Hangul_RieulKiyeog 0x0eaa /* U+313A HANGUL LETTER RIEUL-KIYEOK */ +#define XKB_KEY_Hangul_RieulMieum 0x0eab /* U+313B HANGUL LETTER RIEUL-MIEUM */ +#define XKB_KEY_Hangul_RieulPieub 0x0eac /* U+313C HANGUL LETTER RIEUL-PIEUP */ +#define XKB_KEY_Hangul_RieulSios 0x0ead /* U+313D HANGUL LETTER RIEUL-SIOS */ +#define XKB_KEY_Hangul_RieulTieut 0x0eae /* U+313E HANGUL LETTER RIEUL-THIEUTH */ +#define XKB_KEY_Hangul_RieulPhieuf 0x0eaf /* U+313F HANGUL LETTER RIEUL-PHIEUPH */ +#define XKB_KEY_Hangul_RieulHieuh 0x0eb0 /* U+3140 HANGUL LETTER RIEUL-HIEUH */ +#define XKB_KEY_Hangul_Mieum 0x0eb1 /* U+3141 HANGUL LETTER MIEUM */ +#define XKB_KEY_Hangul_Pieub 0x0eb2 /* U+3142 HANGUL LETTER PIEUP */ +#define XKB_KEY_Hangul_SsangPieub 0x0eb3 /* U+3143 HANGUL LETTER SSANGPIEUP */ +#define XKB_KEY_Hangul_PieubSios 0x0eb4 /* U+3144 HANGUL LETTER PIEUP-SIOS */ +#define XKB_KEY_Hangul_Sios 0x0eb5 /* U+3145 HANGUL LETTER SIOS */ +#define XKB_KEY_Hangul_SsangSios 0x0eb6 /* U+3146 HANGUL LETTER SSANGSIOS */ +#define XKB_KEY_Hangul_Ieung 0x0eb7 /* U+3147 HANGUL LETTER IEUNG */ +#define XKB_KEY_Hangul_Jieuj 0x0eb8 /* U+3148 HANGUL LETTER CIEUC */ +#define XKB_KEY_Hangul_SsangJieuj 0x0eb9 /* U+3149 HANGUL LETTER SSANGCIEUC */ +#define XKB_KEY_Hangul_Cieuc 0x0eba /* U+314A HANGUL LETTER CHIEUCH */ +#define XKB_KEY_Hangul_Khieuq 0x0ebb /* U+314B HANGUL LETTER KHIEUKH */ +#define XKB_KEY_Hangul_Tieut 0x0ebc /* U+314C HANGUL LETTER THIEUTH */ +#define XKB_KEY_Hangul_Phieuf 0x0ebd /* U+314D HANGUL LETTER PHIEUPH */ +#define XKB_KEY_Hangul_Hieuh 0x0ebe /* U+314E HANGUL LETTER HIEUH */ + +/* Hangul Vowel Characters */ +#define XKB_KEY_Hangul_A 0x0ebf /* U+314F HANGUL LETTER A */ +#define XKB_KEY_Hangul_AE 0x0ec0 /* U+3150 HANGUL LETTER AE */ +#define XKB_KEY_Hangul_YA 0x0ec1 /* U+3151 HANGUL LETTER YA */ +#define XKB_KEY_Hangul_YAE 0x0ec2 /* U+3152 HANGUL LETTER YAE */ +#define XKB_KEY_Hangul_EO 0x0ec3 /* U+3153 HANGUL LETTER EO */ +#define XKB_KEY_Hangul_E 0x0ec4 /* U+3154 HANGUL LETTER E */ +#define XKB_KEY_Hangul_YEO 0x0ec5 /* U+3155 HANGUL LETTER YEO */ +#define XKB_KEY_Hangul_YE 0x0ec6 /* U+3156 HANGUL LETTER YE */ +#define XKB_KEY_Hangul_O 0x0ec7 /* U+3157 HANGUL LETTER O */ +#define XKB_KEY_Hangul_WA 0x0ec8 /* U+3158 HANGUL LETTER WA */ +#define XKB_KEY_Hangul_WAE 0x0ec9 /* U+3159 HANGUL LETTER WAE */ +#define XKB_KEY_Hangul_OE 0x0eca /* U+315A HANGUL LETTER OE */ +#define XKB_KEY_Hangul_YO 0x0ecb /* U+315B HANGUL LETTER YO */ +#define XKB_KEY_Hangul_U 0x0ecc /* U+315C HANGUL LETTER U */ +#define XKB_KEY_Hangul_WEO 0x0ecd /* U+315D HANGUL LETTER WEO */ +#define XKB_KEY_Hangul_WE 0x0ece /* U+315E HANGUL LETTER WE */ +#define XKB_KEY_Hangul_WI 0x0ecf /* U+315F HANGUL LETTER WI */ +#define XKB_KEY_Hangul_YU 0x0ed0 /* U+3160 HANGUL LETTER YU */ +#define XKB_KEY_Hangul_EU 0x0ed1 /* U+3161 HANGUL LETTER EU */ +#define XKB_KEY_Hangul_YI 0x0ed2 /* U+3162 HANGUL LETTER YI */ +#define XKB_KEY_Hangul_I 0x0ed3 /* U+3163 HANGUL LETTER I */ + +/* Hangul syllable-final (JongSeong) Characters */ +#define XKB_KEY_Hangul_J_Kiyeog 0x0ed4 /* U+11A8 HANGUL JONGSEONG KIYEOK */ +#define XKB_KEY_Hangul_J_SsangKiyeog 0x0ed5 /* U+11A9 HANGUL JONGSEONG SSANGKIYEOK */ +#define XKB_KEY_Hangul_J_KiyeogSios 0x0ed6 /* U+11AA HANGUL JONGSEONG KIYEOK-SIOS */ +#define XKB_KEY_Hangul_J_Nieun 0x0ed7 /* U+11AB HANGUL JONGSEONG NIEUN */ +#define XKB_KEY_Hangul_J_NieunJieuj 0x0ed8 /* U+11AC HANGUL JONGSEONG NIEUN-CIEUC */ +#define XKB_KEY_Hangul_J_NieunHieuh 0x0ed9 /* U+11AD HANGUL JONGSEONG NIEUN-HIEUH */ +#define XKB_KEY_Hangul_J_Dikeud 0x0eda /* U+11AE HANGUL JONGSEONG TIKEUT */ +#define XKB_KEY_Hangul_J_Rieul 0x0edb /* U+11AF HANGUL JONGSEONG RIEUL */ +#define XKB_KEY_Hangul_J_RieulKiyeog 0x0edc /* U+11B0 HANGUL JONGSEONG RIEUL-KIYEOK */ +#define XKB_KEY_Hangul_J_RieulMieum 0x0edd /* U+11B1 HANGUL JONGSEONG RIEUL-MIEUM */ +#define XKB_KEY_Hangul_J_RieulPieub 0x0ede /* U+11B2 HANGUL JONGSEONG RIEUL-PIEUP */ +#define XKB_KEY_Hangul_J_RieulSios 0x0edf /* U+11B3 HANGUL JONGSEONG RIEUL-SIOS */ +#define XKB_KEY_Hangul_J_RieulTieut 0x0ee0 /* U+11B4 HANGUL JONGSEONG RIEUL-THIEUTH */ +#define XKB_KEY_Hangul_J_RieulPhieuf 0x0ee1 /* U+11B5 HANGUL JONGSEONG RIEUL-PHIEUPH */ +#define XKB_KEY_Hangul_J_RieulHieuh 0x0ee2 /* U+11B6 HANGUL JONGSEONG RIEUL-HIEUH */ +#define XKB_KEY_Hangul_J_Mieum 0x0ee3 /* U+11B7 HANGUL JONGSEONG MIEUM */ +#define XKB_KEY_Hangul_J_Pieub 0x0ee4 /* U+11B8 HANGUL JONGSEONG PIEUP */ +#define XKB_KEY_Hangul_J_PieubSios 0x0ee5 /* U+11B9 HANGUL JONGSEONG PIEUP-SIOS */ +#define XKB_KEY_Hangul_J_Sios 0x0ee6 /* U+11BA HANGUL JONGSEONG SIOS */ +#define XKB_KEY_Hangul_J_SsangSios 0x0ee7 /* U+11BB HANGUL JONGSEONG SSANGSIOS */ +#define XKB_KEY_Hangul_J_Ieung 0x0ee8 /* U+11BC HANGUL JONGSEONG IEUNG */ +#define XKB_KEY_Hangul_J_Jieuj 0x0ee9 /* U+11BD HANGUL JONGSEONG CIEUC */ +#define XKB_KEY_Hangul_J_Cieuc 0x0eea /* U+11BE HANGUL JONGSEONG CHIEUCH */ +#define XKB_KEY_Hangul_J_Khieuq 0x0eeb /* U+11BF HANGUL JONGSEONG KHIEUKH */ +#define XKB_KEY_Hangul_J_Tieut 0x0eec /* U+11C0 HANGUL JONGSEONG THIEUTH */ +#define XKB_KEY_Hangul_J_Phieuf 0x0eed /* U+11C1 HANGUL JONGSEONG PHIEUPH */ +#define XKB_KEY_Hangul_J_Hieuh 0x0eee /* U+11C2 HANGUL JONGSEONG HIEUH */ + +/* Ancient Hangul Consonant Characters */ +#define XKB_KEY_Hangul_RieulYeorinHieuh 0x0eef /* U+316D HANGUL LETTER RIEUL-YEORINHIEUH */ +#define XKB_KEY_Hangul_SunkyeongeumMieum 0x0ef0 /* U+3171 HANGUL LETTER KAPYEOUNMIEUM */ +#define XKB_KEY_Hangul_SunkyeongeumPieub 0x0ef1 /* U+3178 HANGUL LETTER KAPYEOUNPIEUP */ +#define XKB_KEY_Hangul_PanSios 0x0ef2 /* U+317F HANGUL LETTER PANSIOS */ +#define XKB_KEY_Hangul_KkogjiDalrinIeung 0x0ef3 /* U+3181 HANGUL LETTER YESIEUNG */ +#define XKB_KEY_Hangul_SunkyeongeumPhieuf 0x0ef4 /* U+3184 HANGUL LETTER KAPYEOUNPHIEUPH */ +#define XKB_KEY_Hangul_YeorinHieuh 0x0ef5 /* U+3186 HANGUL LETTER YEORINHIEUH */ + +/* Ancient Hangul Vowel Characters */ +#define XKB_KEY_Hangul_AraeA 0x0ef6 /* U+318D HANGUL LETTER ARAEA */ +#define XKB_KEY_Hangul_AraeAE 0x0ef7 /* U+318E HANGUL LETTER ARAEAE */ + +/* Ancient Hangul syllable-final (JongSeong) Characters */ +#define XKB_KEY_Hangul_J_PanSios 0x0ef8 /* U+11EB HANGUL JONGSEONG PANSIOS */ +#define XKB_KEY_Hangul_J_KkogjiDalrinIeung 0x0ef9 /* U+11F0 HANGUL JONGSEONG YESIEUNG */ +#define XKB_KEY_Hangul_J_YeorinHieuh 0x0efa /* U+11F9 HANGUL JONGSEONG YEORINHIEUH */ + +/* Korean currency symbol */ +#define XKB_KEY_Korean_Won 0x0eff /*(U+20A9 WON SIGN)*/ + + +/* + * Armenian + */ + +#define XKB_KEY_Armenian_ligature_ew 0x1000587 /* U+0587 ARMENIAN SMALL LIGATURE ECH YIWN */ +#define XKB_KEY_Armenian_full_stop 0x1000589 /* U+0589 ARMENIAN FULL STOP */ +#define XKB_KEY_Armenian_verjaket 0x1000589 /* U+0589 ARMENIAN FULL STOP */ +#define XKB_KEY_Armenian_separation_mark 0x100055d /* U+055D ARMENIAN COMMA */ +#define XKB_KEY_Armenian_but 0x100055d /* U+055D ARMENIAN COMMA */ +#define XKB_KEY_Armenian_hyphen 0x100058a /* U+058A ARMENIAN HYPHEN */ +#define XKB_KEY_Armenian_yentamna 0x100058a /* U+058A ARMENIAN HYPHEN */ +#define XKB_KEY_Armenian_exclam 0x100055c /* U+055C ARMENIAN EXCLAMATION MARK */ +#define XKB_KEY_Armenian_amanak 0x100055c /* U+055C ARMENIAN EXCLAMATION MARK */ +#define XKB_KEY_Armenian_accent 0x100055b /* U+055B ARMENIAN EMPHASIS MARK */ +#define XKB_KEY_Armenian_shesht 0x100055b /* U+055B ARMENIAN EMPHASIS MARK */ +#define XKB_KEY_Armenian_question 0x100055e /* U+055E ARMENIAN QUESTION MARK */ +#define XKB_KEY_Armenian_paruyk 0x100055e /* U+055E ARMENIAN QUESTION MARK */ +#define XKB_KEY_Armenian_AYB 0x1000531 /* U+0531 ARMENIAN CAPITAL LETTER AYB */ +#define XKB_KEY_Armenian_ayb 0x1000561 /* U+0561 ARMENIAN SMALL LETTER AYB */ +#define XKB_KEY_Armenian_BEN 0x1000532 /* U+0532 ARMENIAN CAPITAL LETTER BEN */ +#define XKB_KEY_Armenian_ben 0x1000562 /* U+0562 ARMENIAN SMALL LETTER BEN */ +#define XKB_KEY_Armenian_GIM 0x1000533 /* U+0533 ARMENIAN CAPITAL LETTER GIM */ +#define XKB_KEY_Armenian_gim 0x1000563 /* U+0563 ARMENIAN SMALL LETTER GIM */ +#define XKB_KEY_Armenian_DA 0x1000534 /* U+0534 ARMENIAN CAPITAL LETTER DA */ +#define XKB_KEY_Armenian_da 0x1000564 /* U+0564 ARMENIAN SMALL LETTER DA */ +#define XKB_KEY_Armenian_YECH 0x1000535 /* U+0535 ARMENIAN CAPITAL LETTER ECH */ +#define XKB_KEY_Armenian_yech 0x1000565 /* U+0565 ARMENIAN SMALL LETTER ECH */ +#define XKB_KEY_Armenian_ZA 0x1000536 /* U+0536 ARMENIAN CAPITAL LETTER ZA */ +#define XKB_KEY_Armenian_za 0x1000566 /* U+0566 ARMENIAN SMALL LETTER ZA */ +#define XKB_KEY_Armenian_E 0x1000537 /* U+0537 ARMENIAN CAPITAL LETTER EH */ +#define XKB_KEY_Armenian_e 0x1000567 /* U+0567 ARMENIAN SMALL LETTER EH */ +#define XKB_KEY_Armenian_AT 0x1000538 /* U+0538 ARMENIAN CAPITAL LETTER ET */ +#define XKB_KEY_Armenian_at 0x1000568 /* U+0568 ARMENIAN SMALL LETTER ET */ +#define XKB_KEY_Armenian_TO 0x1000539 /* U+0539 ARMENIAN CAPITAL LETTER TO */ +#define XKB_KEY_Armenian_to 0x1000569 /* U+0569 ARMENIAN SMALL LETTER TO */ +#define XKB_KEY_Armenian_ZHE 0x100053a /* U+053A ARMENIAN CAPITAL LETTER ZHE */ +#define XKB_KEY_Armenian_zhe 0x100056a /* U+056A ARMENIAN SMALL LETTER ZHE */ +#define XKB_KEY_Armenian_INI 0x100053b /* U+053B ARMENIAN CAPITAL LETTER INI */ +#define XKB_KEY_Armenian_ini 0x100056b /* U+056B ARMENIAN SMALL LETTER INI */ +#define XKB_KEY_Armenian_LYUN 0x100053c /* U+053C ARMENIAN CAPITAL LETTER LIWN */ +#define XKB_KEY_Armenian_lyun 0x100056c /* U+056C ARMENIAN SMALL LETTER LIWN */ +#define XKB_KEY_Armenian_KHE 0x100053d /* U+053D ARMENIAN CAPITAL LETTER XEH */ +#define XKB_KEY_Armenian_khe 0x100056d /* U+056D ARMENIAN SMALL LETTER XEH */ +#define XKB_KEY_Armenian_TSA 0x100053e /* U+053E ARMENIAN CAPITAL LETTER CA */ +#define XKB_KEY_Armenian_tsa 0x100056e /* U+056E ARMENIAN SMALL LETTER CA */ +#define XKB_KEY_Armenian_KEN 0x100053f /* U+053F ARMENIAN CAPITAL LETTER KEN */ +#define XKB_KEY_Armenian_ken 0x100056f /* U+056F ARMENIAN SMALL LETTER KEN */ +#define XKB_KEY_Armenian_HO 0x1000540 /* U+0540 ARMENIAN CAPITAL LETTER HO */ +#define XKB_KEY_Armenian_ho 0x1000570 /* U+0570 ARMENIAN SMALL LETTER HO */ +#define XKB_KEY_Armenian_DZA 0x1000541 /* U+0541 ARMENIAN CAPITAL LETTER JA */ +#define XKB_KEY_Armenian_dza 0x1000571 /* U+0571 ARMENIAN SMALL LETTER JA */ +#define XKB_KEY_Armenian_GHAT 0x1000542 /* U+0542 ARMENIAN CAPITAL LETTER GHAD */ +#define XKB_KEY_Armenian_ghat 0x1000572 /* U+0572 ARMENIAN SMALL LETTER GHAD */ +#define XKB_KEY_Armenian_TCHE 0x1000543 /* U+0543 ARMENIAN CAPITAL LETTER CHEH */ +#define XKB_KEY_Armenian_tche 0x1000573 /* U+0573 ARMENIAN SMALL LETTER CHEH */ +#define XKB_KEY_Armenian_MEN 0x1000544 /* U+0544 ARMENIAN CAPITAL LETTER MEN */ +#define XKB_KEY_Armenian_men 0x1000574 /* U+0574 ARMENIAN SMALL LETTER MEN */ +#define XKB_KEY_Armenian_HI 0x1000545 /* U+0545 ARMENIAN CAPITAL LETTER YI */ +#define XKB_KEY_Armenian_hi 0x1000575 /* U+0575 ARMENIAN SMALL LETTER YI */ +#define XKB_KEY_Armenian_NU 0x1000546 /* U+0546 ARMENIAN CAPITAL LETTER NOW */ +#define XKB_KEY_Armenian_nu 0x1000576 /* U+0576 ARMENIAN SMALL LETTER NOW */ +#define XKB_KEY_Armenian_SHA 0x1000547 /* U+0547 ARMENIAN CAPITAL LETTER SHA */ +#define XKB_KEY_Armenian_sha 0x1000577 /* U+0577 ARMENIAN SMALL LETTER SHA */ +#define XKB_KEY_Armenian_VO 0x1000548 /* U+0548 ARMENIAN CAPITAL LETTER VO */ +#define XKB_KEY_Armenian_vo 0x1000578 /* U+0578 ARMENIAN SMALL LETTER VO */ +#define XKB_KEY_Armenian_CHA 0x1000549 /* U+0549 ARMENIAN CAPITAL LETTER CHA */ +#define XKB_KEY_Armenian_cha 0x1000579 /* U+0579 ARMENIAN SMALL LETTER CHA */ +#define XKB_KEY_Armenian_PE 0x100054a /* U+054A ARMENIAN CAPITAL LETTER PEH */ +#define XKB_KEY_Armenian_pe 0x100057a /* U+057A ARMENIAN SMALL LETTER PEH */ +#define XKB_KEY_Armenian_JE 0x100054b /* U+054B ARMENIAN CAPITAL LETTER JHEH */ +#define XKB_KEY_Armenian_je 0x100057b /* U+057B ARMENIAN SMALL LETTER JHEH */ +#define XKB_KEY_Armenian_RA 0x100054c /* U+054C ARMENIAN CAPITAL LETTER RA */ +#define XKB_KEY_Armenian_ra 0x100057c /* U+057C ARMENIAN SMALL LETTER RA */ +#define XKB_KEY_Armenian_SE 0x100054d /* U+054D ARMENIAN CAPITAL LETTER SEH */ +#define XKB_KEY_Armenian_se 0x100057d /* U+057D ARMENIAN SMALL LETTER SEH */ +#define XKB_KEY_Armenian_VEV 0x100054e /* U+054E ARMENIAN CAPITAL LETTER VEW */ +#define XKB_KEY_Armenian_vev 0x100057e /* U+057E ARMENIAN SMALL LETTER VEW */ +#define XKB_KEY_Armenian_TYUN 0x100054f /* U+054F ARMENIAN CAPITAL LETTER TIWN */ +#define XKB_KEY_Armenian_tyun 0x100057f /* U+057F ARMENIAN SMALL LETTER TIWN */ +#define XKB_KEY_Armenian_RE 0x1000550 /* U+0550 ARMENIAN CAPITAL LETTER REH */ +#define XKB_KEY_Armenian_re 0x1000580 /* U+0580 ARMENIAN SMALL LETTER REH */ +#define XKB_KEY_Armenian_TSO 0x1000551 /* U+0551 ARMENIAN CAPITAL LETTER CO */ +#define XKB_KEY_Armenian_tso 0x1000581 /* U+0581 ARMENIAN SMALL LETTER CO */ +#define XKB_KEY_Armenian_VYUN 0x1000552 /* U+0552 ARMENIAN CAPITAL LETTER YIWN */ +#define XKB_KEY_Armenian_vyun 0x1000582 /* U+0582 ARMENIAN SMALL LETTER YIWN */ +#define XKB_KEY_Armenian_PYUR 0x1000553 /* U+0553 ARMENIAN CAPITAL LETTER PIWR */ +#define XKB_KEY_Armenian_pyur 0x1000583 /* U+0583 ARMENIAN SMALL LETTER PIWR */ +#define XKB_KEY_Armenian_KE 0x1000554 /* U+0554 ARMENIAN CAPITAL LETTER KEH */ +#define XKB_KEY_Armenian_ke 0x1000584 /* U+0584 ARMENIAN SMALL LETTER KEH */ +#define XKB_KEY_Armenian_O 0x1000555 /* U+0555 ARMENIAN CAPITAL LETTER OH */ +#define XKB_KEY_Armenian_o 0x1000585 /* U+0585 ARMENIAN SMALL LETTER OH */ +#define XKB_KEY_Armenian_FE 0x1000556 /* U+0556 ARMENIAN CAPITAL LETTER FEH */ +#define XKB_KEY_Armenian_fe 0x1000586 /* U+0586 ARMENIAN SMALL LETTER FEH */ +#define XKB_KEY_Armenian_apostrophe 0x100055a /* U+055A ARMENIAN APOSTROPHE */ + +/* + * Georgian + */ + +#define XKB_KEY_Georgian_an 0x10010d0 /* U+10D0 GEORGIAN LETTER AN */ +#define XKB_KEY_Georgian_ban 0x10010d1 /* U+10D1 GEORGIAN LETTER BAN */ +#define XKB_KEY_Georgian_gan 0x10010d2 /* U+10D2 GEORGIAN LETTER GAN */ +#define XKB_KEY_Georgian_don 0x10010d3 /* U+10D3 GEORGIAN LETTER DON */ +#define XKB_KEY_Georgian_en 0x10010d4 /* U+10D4 GEORGIAN LETTER EN */ +#define XKB_KEY_Georgian_vin 0x10010d5 /* U+10D5 GEORGIAN LETTER VIN */ +#define XKB_KEY_Georgian_zen 0x10010d6 /* U+10D6 GEORGIAN LETTER ZEN */ +#define XKB_KEY_Georgian_tan 0x10010d7 /* U+10D7 GEORGIAN LETTER TAN */ +#define XKB_KEY_Georgian_in 0x10010d8 /* U+10D8 GEORGIAN LETTER IN */ +#define XKB_KEY_Georgian_kan 0x10010d9 /* U+10D9 GEORGIAN LETTER KAN */ +#define XKB_KEY_Georgian_las 0x10010da /* U+10DA GEORGIAN LETTER LAS */ +#define XKB_KEY_Georgian_man 0x10010db /* U+10DB GEORGIAN LETTER MAN */ +#define XKB_KEY_Georgian_nar 0x10010dc /* U+10DC GEORGIAN LETTER NAR */ +#define XKB_KEY_Georgian_on 0x10010dd /* U+10DD GEORGIAN LETTER ON */ +#define XKB_KEY_Georgian_par 0x10010de /* U+10DE GEORGIAN LETTER PAR */ +#define XKB_KEY_Georgian_zhar 0x10010df /* U+10DF GEORGIAN LETTER ZHAR */ +#define XKB_KEY_Georgian_rae 0x10010e0 /* U+10E0 GEORGIAN LETTER RAE */ +#define XKB_KEY_Georgian_san 0x10010e1 /* U+10E1 GEORGIAN LETTER SAN */ +#define XKB_KEY_Georgian_tar 0x10010e2 /* U+10E2 GEORGIAN LETTER TAR */ +#define XKB_KEY_Georgian_un 0x10010e3 /* U+10E3 GEORGIAN LETTER UN */ +#define XKB_KEY_Georgian_phar 0x10010e4 /* U+10E4 GEORGIAN LETTER PHAR */ +#define XKB_KEY_Georgian_khar 0x10010e5 /* U+10E5 GEORGIAN LETTER KHAR */ +#define XKB_KEY_Georgian_ghan 0x10010e6 /* U+10E6 GEORGIAN LETTER GHAN */ +#define XKB_KEY_Georgian_qar 0x10010e7 /* U+10E7 GEORGIAN LETTER QAR */ +#define XKB_KEY_Georgian_shin 0x10010e8 /* U+10E8 GEORGIAN LETTER SHIN */ +#define XKB_KEY_Georgian_chin 0x10010e9 /* U+10E9 GEORGIAN LETTER CHIN */ +#define XKB_KEY_Georgian_can 0x10010ea /* U+10EA GEORGIAN LETTER CAN */ +#define XKB_KEY_Georgian_jil 0x10010eb /* U+10EB GEORGIAN LETTER JIL */ +#define XKB_KEY_Georgian_cil 0x10010ec /* U+10EC GEORGIAN LETTER CIL */ +#define XKB_KEY_Georgian_char 0x10010ed /* U+10ED GEORGIAN LETTER CHAR */ +#define XKB_KEY_Georgian_xan 0x10010ee /* U+10EE GEORGIAN LETTER XAN */ +#define XKB_KEY_Georgian_jhan 0x10010ef /* U+10EF GEORGIAN LETTER JHAN */ +#define XKB_KEY_Georgian_hae 0x10010f0 /* U+10F0 GEORGIAN LETTER HAE */ +#define XKB_KEY_Georgian_he 0x10010f1 /* U+10F1 GEORGIAN LETTER HE */ +#define XKB_KEY_Georgian_hie 0x10010f2 /* U+10F2 GEORGIAN LETTER HIE */ +#define XKB_KEY_Georgian_we 0x10010f3 /* U+10F3 GEORGIAN LETTER WE */ +#define XKB_KEY_Georgian_har 0x10010f4 /* U+10F4 GEORGIAN LETTER HAR */ +#define XKB_KEY_Georgian_hoe 0x10010f5 /* U+10F5 GEORGIAN LETTER HOE */ +#define XKB_KEY_Georgian_fi 0x10010f6 /* U+10F6 GEORGIAN LETTER FI */ + +/* + * Azeri (and other Turkic or Caucasian languages) + */ + +/* latin */ +#define XKB_KEY_Xabovedot 0x1001e8a /* U+1E8A LATIN CAPITAL LETTER X WITH DOT ABOVE */ +#define XKB_KEY_Ibreve 0x100012c /* U+012C LATIN CAPITAL LETTER I WITH BREVE */ +#define XKB_KEY_Zstroke 0x10001b5 /* U+01B5 LATIN CAPITAL LETTER Z WITH STROKE */ +#define XKB_KEY_Gcaron 0x10001e6 /* U+01E6 LATIN CAPITAL LETTER G WITH CARON */ +#define XKB_KEY_Ocaron 0x10001d1 /* U+01D1 LATIN CAPITAL LETTER O WITH CARON */ +#define XKB_KEY_Obarred 0x100019f /* U+019F LATIN CAPITAL LETTER O WITH MIDDLE TILDE */ +#define XKB_KEY_xabovedot 0x1001e8b /* U+1E8B LATIN SMALL LETTER X WITH DOT ABOVE */ +#define XKB_KEY_ibreve 0x100012d /* U+012D LATIN SMALL LETTER I WITH BREVE */ +#define XKB_KEY_zstroke 0x10001b6 /* U+01B6 LATIN SMALL LETTER Z WITH STROKE */ +#define XKB_KEY_gcaron 0x10001e7 /* U+01E7 LATIN SMALL LETTER G WITH CARON */ +#define XKB_KEY_ocaron 0x10001d2 /* U+01D2 LATIN SMALL LETTER O WITH CARON */ +#define XKB_KEY_obarred 0x1000275 /* U+0275 LATIN SMALL LETTER BARRED O */ +#define XKB_KEY_SCHWA 0x100018f /* U+018F LATIN CAPITAL LETTER SCHWA */ +#define XKB_KEY_schwa 0x1000259 /* U+0259 LATIN SMALL LETTER SCHWA */ +#define XKB_KEY_EZH 0x10001b7 /* U+01B7 LATIN CAPITAL LETTER EZH */ +#define XKB_KEY_ezh 0x1000292 /* U+0292 LATIN SMALL LETTER EZH */ +/* those are not really Caucasus */ +/* For Inupiak */ +#define XKB_KEY_Lbelowdot 0x1001e36 /* U+1E36 LATIN CAPITAL LETTER L WITH DOT BELOW */ +#define XKB_KEY_lbelowdot 0x1001e37 /* U+1E37 LATIN SMALL LETTER L WITH DOT BELOW */ + +/* + * Vietnamese + */ + +#define XKB_KEY_Abelowdot 0x1001ea0 /* U+1EA0 LATIN CAPITAL LETTER A WITH DOT BELOW */ +#define XKB_KEY_abelowdot 0x1001ea1 /* U+1EA1 LATIN SMALL LETTER A WITH DOT BELOW */ +#define XKB_KEY_Ahook 0x1001ea2 /* U+1EA2 LATIN CAPITAL LETTER A WITH HOOK ABOVE */ +#define XKB_KEY_ahook 0x1001ea3 /* U+1EA3 LATIN SMALL LETTER A WITH HOOK ABOVE */ +#define XKB_KEY_Acircumflexacute 0x1001ea4 /* U+1EA4 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE */ +#define XKB_KEY_acircumflexacute 0x1001ea5 /* U+1EA5 LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE */ +#define XKB_KEY_Acircumflexgrave 0x1001ea6 /* U+1EA6 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE */ +#define XKB_KEY_acircumflexgrave 0x1001ea7 /* U+1EA7 LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE */ +#define XKB_KEY_Acircumflexhook 0x1001ea8 /* U+1EA8 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */ +#define XKB_KEY_acircumflexhook 0x1001ea9 /* U+1EA9 LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */ +#define XKB_KEY_Acircumflextilde 0x1001eaa /* U+1EAA LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE */ +#define XKB_KEY_acircumflextilde 0x1001eab /* U+1EAB LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE */ +#define XKB_KEY_Acircumflexbelowdot 0x1001eac /* U+1EAC LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW */ +#define XKB_KEY_acircumflexbelowdot 0x1001ead /* U+1EAD LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW */ +#define XKB_KEY_Abreveacute 0x1001eae /* U+1EAE LATIN CAPITAL LETTER A WITH BREVE AND ACUTE */ +#define XKB_KEY_abreveacute 0x1001eaf /* U+1EAF LATIN SMALL LETTER A WITH BREVE AND ACUTE */ +#define XKB_KEY_Abrevegrave 0x1001eb0 /* U+1EB0 LATIN CAPITAL LETTER A WITH BREVE AND GRAVE */ +#define XKB_KEY_abrevegrave 0x1001eb1 /* U+1EB1 LATIN SMALL LETTER A WITH BREVE AND GRAVE */ +#define XKB_KEY_Abrevehook 0x1001eb2 /* U+1EB2 LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE */ +#define XKB_KEY_abrevehook 0x1001eb3 /* U+1EB3 LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE */ +#define XKB_KEY_Abrevetilde 0x1001eb4 /* U+1EB4 LATIN CAPITAL LETTER A WITH BREVE AND TILDE */ +#define XKB_KEY_abrevetilde 0x1001eb5 /* U+1EB5 LATIN SMALL LETTER A WITH BREVE AND TILDE */ +#define XKB_KEY_Abrevebelowdot 0x1001eb6 /* U+1EB6 LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW */ +#define XKB_KEY_abrevebelowdot 0x1001eb7 /* U+1EB7 LATIN SMALL LETTER A WITH BREVE AND DOT BELOW */ +#define XKB_KEY_Ebelowdot 0x1001eb8 /* U+1EB8 LATIN CAPITAL LETTER E WITH DOT BELOW */ +#define XKB_KEY_ebelowdot 0x1001eb9 /* U+1EB9 LATIN SMALL LETTER E WITH DOT BELOW */ +#define XKB_KEY_Ehook 0x1001eba /* U+1EBA LATIN CAPITAL LETTER E WITH HOOK ABOVE */ +#define XKB_KEY_ehook 0x1001ebb /* U+1EBB LATIN SMALL LETTER E WITH HOOK ABOVE */ +#define XKB_KEY_Etilde 0x1001ebc /* U+1EBC LATIN CAPITAL LETTER E WITH TILDE */ +#define XKB_KEY_etilde 0x1001ebd /* U+1EBD LATIN SMALL LETTER E WITH TILDE */ +#define XKB_KEY_Ecircumflexacute 0x1001ebe /* U+1EBE LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE */ +#define XKB_KEY_ecircumflexacute 0x1001ebf /* U+1EBF LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE */ +#define XKB_KEY_Ecircumflexgrave 0x1001ec0 /* U+1EC0 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE */ +#define XKB_KEY_ecircumflexgrave 0x1001ec1 /* U+1EC1 LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE */ +#define XKB_KEY_Ecircumflexhook 0x1001ec2 /* U+1EC2 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */ +#define XKB_KEY_ecircumflexhook 0x1001ec3 /* U+1EC3 LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */ +#define XKB_KEY_Ecircumflextilde 0x1001ec4 /* U+1EC4 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE */ +#define XKB_KEY_ecircumflextilde 0x1001ec5 /* U+1EC5 LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE */ +#define XKB_KEY_Ecircumflexbelowdot 0x1001ec6 /* U+1EC6 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW */ +#define XKB_KEY_ecircumflexbelowdot 0x1001ec7 /* U+1EC7 LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW */ +#define XKB_KEY_Ihook 0x1001ec8 /* U+1EC8 LATIN CAPITAL LETTER I WITH HOOK ABOVE */ +#define XKB_KEY_ihook 0x1001ec9 /* U+1EC9 LATIN SMALL LETTER I WITH HOOK ABOVE */ +#define XKB_KEY_Ibelowdot 0x1001eca /* U+1ECA LATIN CAPITAL LETTER I WITH DOT BELOW */ +#define XKB_KEY_ibelowdot 0x1001ecb /* U+1ECB LATIN SMALL LETTER I WITH DOT BELOW */ +#define XKB_KEY_Obelowdot 0x1001ecc /* U+1ECC LATIN CAPITAL LETTER O WITH DOT BELOW */ +#define XKB_KEY_obelowdot 0x1001ecd /* U+1ECD LATIN SMALL LETTER O WITH DOT BELOW */ +#define XKB_KEY_Ohook 0x1001ece /* U+1ECE LATIN CAPITAL LETTER O WITH HOOK ABOVE */ +#define XKB_KEY_ohook 0x1001ecf /* U+1ECF LATIN SMALL LETTER O WITH HOOK ABOVE */ +#define XKB_KEY_Ocircumflexacute 0x1001ed0 /* U+1ED0 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE */ +#define XKB_KEY_ocircumflexacute 0x1001ed1 /* U+1ED1 LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE */ +#define XKB_KEY_Ocircumflexgrave 0x1001ed2 /* U+1ED2 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE */ +#define XKB_KEY_ocircumflexgrave 0x1001ed3 /* U+1ED3 LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE */ +#define XKB_KEY_Ocircumflexhook 0x1001ed4 /* U+1ED4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */ +#define XKB_KEY_ocircumflexhook 0x1001ed5 /* U+1ED5 LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */ +#define XKB_KEY_Ocircumflextilde 0x1001ed6 /* U+1ED6 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE */ +#define XKB_KEY_ocircumflextilde 0x1001ed7 /* U+1ED7 LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE */ +#define XKB_KEY_Ocircumflexbelowdot 0x1001ed8 /* U+1ED8 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW */ +#define XKB_KEY_ocircumflexbelowdot 0x1001ed9 /* U+1ED9 LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW */ +#define XKB_KEY_Ohornacute 0x1001eda /* U+1EDA LATIN CAPITAL LETTER O WITH HORN AND ACUTE */ +#define XKB_KEY_ohornacute 0x1001edb /* U+1EDB LATIN SMALL LETTER O WITH HORN AND ACUTE */ +#define XKB_KEY_Ohorngrave 0x1001edc /* U+1EDC LATIN CAPITAL LETTER O WITH HORN AND GRAVE */ +#define XKB_KEY_ohorngrave 0x1001edd /* U+1EDD LATIN SMALL LETTER O WITH HORN AND GRAVE */ +#define XKB_KEY_Ohornhook 0x1001ede /* U+1EDE LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE */ +#define XKB_KEY_ohornhook 0x1001edf /* U+1EDF LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE */ +#define XKB_KEY_Ohorntilde 0x1001ee0 /* U+1EE0 LATIN CAPITAL LETTER O WITH HORN AND TILDE */ +#define XKB_KEY_ohorntilde 0x1001ee1 /* U+1EE1 LATIN SMALL LETTER O WITH HORN AND TILDE */ +#define XKB_KEY_Ohornbelowdot 0x1001ee2 /* U+1EE2 LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW */ +#define XKB_KEY_ohornbelowdot 0x1001ee3 /* U+1EE3 LATIN SMALL LETTER O WITH HORN AND DOT BELOW */ +#define XKB_KEY_Ubelowdot 0x1001ee4 /* U+1EE4 LATIN CAPITAL LETTER U WITH DOT BELOW */ +#define XKB_KEY_ubelowdot 0x1001ee5 /* U+1EE5 LATIN SMALL LETTER U WITH DOT BELOW */ +#define XKB_KEY_Uhook 0x1001ee6 /* U+1EE6 LATIN CAPITAL LETTER U WITH HOOK ABOVE */ +#define XKB_KEY_uhook 0x1001ee7 /* U+1EE7 LATIN SMALL LETTER U WITH HOOK ABOVE */ +#define XKB_KEY_Uhornacute 0x1001ee8 /* U+1EE8 LATIN CAPITAL LETTER U WITH HORN AND ACUTE */ +#define XKB_KEY_uhornacute 0x1001ee9 /* U+1EE9 LATIN SMALL LETTER U WITH HORN AND ACUTE */ +#define XKB_KEY_Uhorngrave 0x1001eea /* U+1EEA LATIN CAPITAL LETTER U WITH HORN AND GRAVE */ +#define XKB_KEY_uhorngrave 0x1001eeb /* U+1EEB LATIN SMALL LETTER U WITH HORN AND GRAVE */ +#define XKB_KEY_Uhornhook 0x1001eec /* U+1EEC LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE */ +#define XKB_KEY_uhornhook 0x1001eed /* U+1EED LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE */ +#define XKB_KEY_Uhorntilde 0x1001eee /* U+1EEE LATIN CAPITAL LETTER U WITH HORN AND TILDE */ +#define XKB_KEY_uhorntilde 0x1001eef /* U+1EEF LATIN SMALL LETTER U WITH HORN AND TILDE */ +#define XKB_KEY_Uhornbelowdot 0x1001ef0 /* U+1EF0 LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW */ +#define XKB_KEY_uhornbelowdot 0x1001ef1 /* U+1EF1 LATIN SMALL LETTER U WITH HORN AND DOT BELOW */ +#define XKB_KEY_Ybelowdot 0x1001ef4 /* U+1EF4 LATIN CAPITAL LETTER Y WITH DOT BELOW */ +#define XKB_KEY_ybelowdot 0x1001ef5 /* U+1EF5 LATIN SMALL LETTER Y WITH DOT BELOW */ +#define XKB_KEY_Yhook 0x1001ef6 /* U+1EF6 LATIN CAPITAL LETTER Y WITH HOOK ABOVE */ +#define XKB_KEY_yhook 0x1001ef7 /* U+1EF7 LATIN SMALL LETTER Y WITH HOOK ABOVE */ +#define XKB_KEY_Ytilde 0x1001ef8 /* U+1EF8 LATIN CAPITAL LETTER Y WITH TILDE */ +#define XKB_KEY_ytilde 0x1001ef9 /* U+1EF9 LATIN SMALL LETTER Y WITH TILDE */ +#define XKB_KEY_Ohorn 0x10001a0 /* U+01A0 LATIN CAPITAL LETTER O WITH HORN */ +#define XKB_KEY_ohorn 0x10001a1 /* U+01A1 LATIN SMALL LETTER O WITH HORN */ +#define XKB_KEY_Uhorn 0x10001af /* U+01AF LATIN CAPITAL LETTER U WITH HORN */ +#define XKB_KEY_uhorn 0x10001b0 /* U+01B0 LATIN SMALL LETTER U WITH HORN */ +#define XKB_KEY_combining_tilde 0x1000303 /* U+0303 COMBINING TILDE */ +#define XKB_KEY_combining_grave 0x1000300 /* U+0300 COMBINING GRAVE ACCENT */ +#define XKB_KEY_combining_acute 0x1000301 /* U+0301 COMBINING ACUTE ACCENT */ +#define XKB_KEY_combining_hook 0x1000309 /* U+0309 COMBINING HOOK ABOVE */ +#define XKB_KEY_combining_belowdot 0x1000323 /* U+0323 COMBINING DOT BELOW */ + + +#define XKB_KEY_EcuSign 0x10020a0 /* U+20A0 EURO-CURRENCY SIGN */ +#define XKB_KEY_ColonSign 0x10020a1 /* U+20A1 COLON SIGN */ +#define XKB_KEY_CruzeiroSign 0x10020a2 /* U+20A2 CRUZEIRO SIGN */ +#define XKB_KEY_FFrancSign 0x10020a3 /* U+20A3 FRENCH FRANC SIGN */ +#define XKB_KEY_LiraSign 0x10020a4 /* U+20A4 LIRA SIGN */ +#define XKB_KEY_MillSign 0x10020a5 /* U+20A5 MILL SIGN */ +#define XKB_KEY_NairaSign 0x10020a6 /* U+20A6 NAIRA SIGN */ +#define XKB_KEY_PesetaSign 0x10020a7 /* U+20A7 PESETA SIGN */ +#define XKB_KEY_RupeeSign 0x10020a8 /* U+20A8 RUPEE SIGN */ +#define XKB_KEY_WonSign 0x10020a9 /* U+20A9 WON SIGN */ +#define XKB_KEY_NewSheqelSign 0x10020aa /* U+20AA NEW SHEQEL SIGN */ +#define XKB_KEY_DongSign 0x10020ab /* U+20AB DONG SIGN */ +#define XKB_KEY_EuroSign 0x20ac /* U+20AC EURO SIGN */ + +/* one, two and three are defined above. */ +#define XKB_KEY_zerosuperior 0x1002070 /* U+2070 SUPERSCRIPT ZERO */ +#define XKB_KEY_foursuperior 0x1002074 /* U+2074 SUPERSCRIPT FOUR */ +#define XKB_KEY_fivesuperior 0x1002075 /* U+2075 SUPERSCRIPT FIVE */ +#define XKB_KEY_sixsuperior 0x1002076 /* U+2076 SUPERSCRIPT SIX */ +#define XKB_KEY_sevensuperior 0x1002077 /* U+2077 SUPERSCRIPT SEVEN */ +#define XKB_KEY_eightsuperior 0x1002078 /* U+2078 SUPERSCRIPT EIGHT */ +#define XKB_KEY_ninesuperior 0x1002079 /* U+2079 SUPERSCRIPT NINE */ +#define XKB_KEY_zerosubscript 0x1002080 /* U+2080 SUBSCRIPT ZERO */ +#define XKB_KEY_onesubscript 0x1002081 /* U+2081 SUBSCRIPT ONE */ +#define XKB_KEY_twosubscript 0x1002082 /* U+2082 SUBSCRIPT TWO */ +#define XKB_KEY_threesubscript 0x1002083 /* U+2083 SUBSCRIPT THREE */ +#define XKB_KEY_foursubscript 0x1002084 /* U+2084 SUBSCRIPT FOUR */ +#define XKB_KEY_fivesubscript 0x1002085 /* U+2085 SUBSCRIPT FIVE */ +#define XKB_KEY_sixsubscript 0x1002086 /* U+2086 SUBSCRIPT SIX */ +#define XKB_KEY_sevensubscript 0x1002087 /* U+2087 SUBSCRIPT SEVEN */ +#define XKB_KEY_eightsubscript 0x1002088 /* U+2088 SUBSCRIPT EIGHT */ +#define XKB_KEY_ninesubscript 0x1002089 /* U+2089 SUBSCRIPT NINE */ +#define XKB_KEY_partdifferential 0x1002202 /* U+2202 PARTIAL DIFFERENTIAL */ +#define XKB_KEY_emptyset 0x1002205 /* U+2205 NULL SET */ +#define XKB_KEY_elementof 0x1002208 /* U+2208 ELEMENT OF */ +#define XKB_KEY_notelementof 0x1002209 /* U+2209 NOT AN ELEMENT OF */ +#define XKB_KEY_containsas 0x100220B /* U+220B CONTAINS AS MEMBER */ +#define XKB_KEY_squareroot 0x100221A /* U+221A SQUARE ROOT */ +#define XKB_KEY_cuberoot 0x100221B /* U+221B CUBE ROOT */ +#define XKB_KEY_fourthroot 0x100221C /* U+221C FOURTH ROOT */ +#define XKB_KEY_dintegral 0x100222C /* U+222C DOUBLE INTEGRAL */ +#define XKB_KEY_tintegral 0x100222D /* U+222D TRIPLE INTEGRAL */ +#define XKB_KEY_because 0x1002235 /* U+2235 BECAUSE */ +#define XKB_KEY_approxeq 0x1002248 /*(U+2248 ALMOST EQUAL TO)*/ +#define XKB_KEY_notapproxeq 0x1002247 /*(U+2247 NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO)*/ +#define XKB_KEY_notidentical 0x1002262 /* U+2262 NOT IDENTICAL TO */ +#define XKB_KEY_stricteq 0x1002263 /* U+2263 STRICTLY EQUIVALENT TO */ + +#define XKB_KEY_braille_dot_1 0xfff1 +#define XKB_KEY_braille_dot_2 0xfff2 +#define XKB_KEY_braille_dot_3 0xfff3 +#define XKB_KEY_braille_dot_4 0xfff4 +#define XKB_KEY_braille_dot_5 0xfff5 +#define XKB_KEY_braille_dot_6 0xfff6 +#define XKB_KEY_braille_dot_7 0xfff7 +#define XKB_KEY_braille_dot_8 0xfff8 +#define XKB_KEY_braille_dot_9 0xfff9 +#define XKB_KEY_braille_dot_10 0xfffa +#define XKB_KEY_braille_blank 0x1002800 /* U+2800 BRAILLE PATTERN BLANK */ +#define XKB_KEY_braille_dots_1 0x1002801 /* U+2801 BRAILLE PATTERN DOTS-1 */ +#define XKB_KEY_braille_dots_2 0x1002802 /* U+2802 BRAILLE PATTERN DOTS-2 */ +#define XKB_KEY_braille_dots_12 0x1002803 /* U+2803 BRAILLE PATTERN DOTS-12 */ +#define XKB_KEY_braille_dots_3 0x1002804 /* U+2804 BRAILLE PATTERN DOTS-3 */ +#define XKB_KEY_braille_dots_13 0x1002805 /* U+2805 BRAILLE PATTERN DOTS-13 */ +#define XKB_KEY_braille_dots_23 0x1002806 /* U+2806 BRAILLE PATTERN DOTS-23 */ +#define XKB_KEY_braille_dots_123 0x1002807 /* U+2807 BRAILLE PATTERN DOTS-123 */ +#define XKB_KEY_braille_dots_4 0x1002808 /* U+2808 BRAILLE PATTERN DOTS-4 */ +#define XKB_KEY_braille_dots_14 0x1002809 /* U+2809 BRAILLE PATTERN DOTS-14 */ +#define XKB_KEY_braille_dots_24 0x100280a /* U+280a BRAILLE PATTERN DOTS-24 */ +#define XKB_KEY_braille_dots_124 0x100280b /* U+280b BRAILLE PATTERN DOTS-124 */ +#define XKB_KEY_braille_dots_34 0x100280c /* U+280c BRAILLE PATTERN DOTS-34 */ +#define XKB_KEY_braille_dots_134 0x100280d /* U+280d BRAILLE PATTERN DOTS-134 */ +#define XKB_KEY_braille_dots_234 0x100280e /* U+280e BRAILLE PATTERN DOTS-234 */ +#define XKB_KEY_braille_dots_1234 0x100280f /* U+280f BRAILLE PATTERN DOTS-1234 */ +#define XKB_KEY_braille_dots_5 0x1002810 /* U+2810 BRAILLE PATTERN DOTS-5 */ +#define XKB_KEY_braille_dots_15 0x1002811 /* U+2811 BRAILLE PATTERN DOTS-15 */ +#define XKB_KEY_braille_dots_25 0x1002812 /* U+2812 BRAILLE PATTERN DOTS-25 */ +#define XKB_KEY_braille_dots_125 0x1002813 /* U+2813 BRAILLE PATTERN DOTS-125 */ +#define XKB_KEY_braille_dots_35 0x1002814 /* U+2814 BRAILLE PATTERN DOTS-35 */ +#define XKB_KEY_braille_dots_135 0x1002815 /* U+2815 BRAILLE PATTERN DOTS-135 */ +#define XKB_KEY_braille_dots_235 0x1002816 /* U+2816 BRAILLE PATTERN DOTS-235 */ +#define XKB_KEY_braille_dots_1235 0x1002817 /* U+2817 BRAILLE PATTERN DOTS-1235 */ +#define XKB_KEY_braille_dots_45 0x1002818 /* U+2818 BRAILLE PATTERN DOTS-45 */ +#define XKB_KEY_braille_dots_145 0x1002819 /* U+2819 BRAILLE PATTERN DOTS-145 */ +#define XKB_KEY_braille_dots_245 0x100281a /* U+281a BRAILLE PATTERN DOTS-245 */ +#define XKB_KEY_braille_dots_1245 0x100281b /* U+281b BRAILLE PATTERN DOTS-1245 */ +#define XKB_KEY_braille_dots_345 0x100281c /* U+281c BRAILLE PATTERN DOTS-345 */ +#define XKB_KEY_braille_dots_1345 0x100281d /* U+281d BRAILLE PATTERN DOTS-1345 */ +#define XKB_KEY_braille_dots_2345 0x100281e /* U+281e BRAILLE PATTERN DOTS-2345 */ +#define XKB_KEY_braille_dots_12345 0x100281f /* U+281f BRAILLE PATTERN DOTS-12345 */ +#define XKB_KEY_braille_dots_6 0x1002820 /* U+2820 BRAILLE PATTERN DOTS-6 */ +#define XKB_KEY_braille_dots_16 0x1002821 /* U+2821 BRAILLE PATTERN DOTS-16 */ +#define XKB_KEY_braille_dots_26 0x1002822 /* U+2822 BRAILLE PATTERN DOTS-26 */ +#define XKB_KEY_braille_dots_126 0x1002823 /* U+2823 BRAILLE PATTERN DOTS-126 */ +#define XKB_KEY_braille_dots_36 0x1002824 /* U+2824 BRAILLE PATTERN DOTS-36 */ +#define XKB_KEY_braille_dots_136 0x1002825 /* U+2825 BRAILLE PATTERN DOTS-136 */ +#define XKB_KEY_braille_dots_236 0x1002826 /* U+2826 BRAILLE PATTERN DOTS-236 */ +#define XKB_KEY_braille_dots_1236 0x1002827 /* U+2827 BRAILLE PATTERN DOTS-1236 */ +#define XKB_KEY_braille_dots_46 0x1002828 /* U+2828 BRAILLE PATTERN DOTS-46 */ +#define XKB_KEY_braille_dots_146 0x1002829 /* U+2829 BRAILLE PATTERN DOTS-146 */ +#define XKB_KEY_braille_dots_246 0x100282a /* U+282a BRAILLE PATTERN DOTS-246 */ +#define XKB_KEY_braille_dots_1246 0x100282b /* U+282b BRAILLE PATTERN DOTS-1246 */ +#define XKB_KEY_braille_dots_346 0x100282c /* U+282c BRAILLE PATTERN DOTS-346 */ +#define XKB_KEY_braille_dots_1346 0x100282d /* U+282d BRAILLE PATTERN DOTS-1346 */ +#define XKB_KEY_braille_dots_2346 0x100282e /* U+282e BRAILLE PATTERN DOTS-2346 */ +#define XKB_KEY_braille_dots_12346 0x100282f /* U+282f BRAILLE PATTERN DOTS-12346 */ +#define XKB_KEY_braille_dots_56 0x1002830 /* U+2830 BRAILLE PATTERN DOTS-56 */ +#define XKB_KEY_braille_dots_156 0x1002831 /* U+2831 BRAILLE PATTERN DOTS-156 */ +#define XKB_KEY_braille_dots_256 0x1002832 /* U+2832 BRAILLE PATTERN DOTS-256 */ +#define XKB_KEY_braille_dots_1256 0x1002833 /* U+2833 BRAILLE PATTERN DOTS-1256 */ +#define XKB_KEY_braille_dots_356 0x1002834 /* U+2834 BRAILLE PATTERN DOTS-356 */ +#define XKB_KEY_braille_dots_1356 0x1002835 /* U+2835 BRAILLE PATTERN DOTS-1356 */ +#define XKB_KEY_braille_dots_2356 0x1002836 /* U+2836 BRAILLE PATTERN DOTS-2356 */ +#define XKB_KEY_braille_dots_12356 0x1002837 /* U+2837 BRAILLE PATTERN DOTS-12356 */ +#define XKB_KEY_braille_dots_456 0x1002838 /* U+2838 BRAILLE PATTERN DOTS-456 */ +#define XKB_KEY_braille_dots_1456 0x1002839 /* U+2839 BRAILLE PATTERN DOTS-1456 */ +#define XKB_KEY_braille_dots_2456 0x100283a /* U+283a BRAILLE PATTERN DOTS-2456 */ +#define XKB_KEY_braille_dots_12456 0x100283b /* U+283b BRAILLE PATTERN DOTS-12456 */ +#define XKB_KEY_braille_dots_3456 0x100283c /* U+283c BRAILLE PATTERN DOTS-3456 */ +#define XKB_KEY_braille_dots_13456 0x100283d /* U+283d BRAILLE PATTERN DOTS-13456 */ +#define XKB_KEY_braille_dots_23456 0x100283e /* U+283e BRAILLE PATTERN DOTS-23456 */ +#define XKB_KEY_braille_dots_123456 0x100283f /* U+283f BRAILLE PATTERN DOTS-123456 */ +#define XKB_KEY_braille_dots_7 0x1002840 /* U+2840 BRAILLE PATTERN DOTS-7 */ +#define XKB_KEY_braille_dots_17 0x1002841 /* U+2841 BRAILLE PATTERN DOTS-17 */ +#define XKB_KEY_braille_dots_27 0x1002842 /* U+2842 BRAILLE PATTERN DOTS-27 */ +#define XKB_KEY_braille_dots_127 0x1002843 /* U+2843 BRAILLE PATTERN DOTS-127 */ +#define XKB_KEY_braille_dots_37 0x1002844 /* U+2844 BRAILLE PATTERN DOTS-37 */ +#define XKB_KEY_braille_dots_137 0x1002845 /* U+2845 BRAILLE PATTERN DOTS-137 */ +#define XKB_KEY_braille_dots_237 0x1002846 /* U+2846 BRAILLE PATTERN DOTS-237 */ +#define XKB_KEY_braille_dots_1237 0x1002847 /* U+2847 BRAILLE PATTERN DOTS-1237 */ +#define XKB_KEY_braille_dots_47 0x1002848 /* U+2848 BRAILLE PATTERN DOTS-47 */ +#define XKB_KEY_braille_dots_147 0x1002849 /* U+2849 BRAILLE PATTERN DOTS-147 */ +#define XKB_KEY_braille_dots_247 0x100284a /* U+284a BRAILLE PATTERN DOTS-247 */ +#define XKB_KEY_braille_dots_1247 0x100284b /* U+284b BRAILLE PATTERN DOTS-1247 */ +#define XKB_KEY_braille_dots_347 0x100284c /* U+284c BRAILLE PATTERN DOTS-347 */ +#define XKB_KEY_braille_dots_1347 0x100284d /* U+284d BRAILLE PATTERN DOTS-1347 */ +#define XKB_KEY_braille_dots_2347 0x100284e /* U+284e BRAILLE PATTERN DOTS-2347 */ +#define XKB_KEY_braille_dots_12347 0x100284f /* U+284f BRAILLE PATTERN DOTS-12347 */ +#define XKB_KEY_braille_dots_57 0x1002850 /* U+2850 BRAILLE PATTERN DOTS-57 */ +#define XKB_KEY_braille_dots_157 0x1002851 /* U+2851 BRAILLE PATTERN DOTS-157 */ +#define XKB_KEY_braille_dots_257 0x1002852 /* U+2852 BRAILLE PATTERN DOTS-257 */ +#define XKB_KEY_braille_dots_1257 0x1002853 /* U+2853 BRAILLE PATTERN DOTS-1257 */ +#define XKB_KEY_braille_dots_357 0x1002854 /* U+2854 BRAILLE PATTERN DOTS-357 */ +#define XKB_KEY_braille_dots_1357 0x1002855 /* U+2855 BRAILLE PATTERN DOTS-1357 */ +#define XKB_KEY_braille_dots_2357 0x1002856 /* U+2856 BRAILLE PATTERN DOTS-2357 */ +#define XKB_KEY_braille_dots_12357 0x1002857 /* U+2857 BRAILLE PATTERN DOTS-12357 */ +#define XKB_KEY_braille_dots_457 0x1002858 /* U+2858 BRAILLE PATTERN DOTS-457 */ +#define XKB_KEY_braille_dots_1457 0x1002859 /* U+2859 BRAILLE PATTERN DOTS-1457 */ +#define XKB_KEY_braille_dots_2457 0x100285a /* U+285a BRAILLE PATTERN DOTS-2457 */ +#define XKB_KEY_braille_dots_12457 0x100285b /* U+285b BRAILLE PATTERN DOTS-12457 */ +#define XKB_KEY_braille_dots_3457 0x100285c /* U+285c BRAILLE PATTERN DOTS-3457 */ +#define XKB_KEY_braille_dots_13457 0x100285d /* U+285d BRAILLE PATTERN DOTS-13457 */ +#define XKB_KEY_braille_dots_23457 0x100285e /* U+285e BRAILLE PATTERN DOTS-23457 */ +#define XKB_KEY_braille_dots_123457 0x100285f /* U+285f BRAILLE PATTERN DOTS-123457 */ +#define XKB_KEY_braille_dots_67 0x1002860 /* U+2860 BRAILLE PATTERN DOTS-67 */ +#define XKB_KEY_braille_dots_167 0x1002861 /* U+2861 BRAILLE PATTERN DOTS-167 */ +#define XKB_KEY_braille_dots_267 0x1002862 /* U+2862 BRAILLE PATTERN DOTS-267 */ +#define XKB_KEY_braille_dots_1267 0x1002863 /* U+2863 BRAILLE PATTERN DOTS-1267 */ +#define XKB_KEY_braille_dots_367 0x1002864 /* U+2864 BRAILLE PATTERN DOTS-367 */ +#define XKB_KEY_braille_dots_1367 0x1002865 /* U+2865 BRAILLE PATTERN DOTS-1367 */ +#define XKB_KEY_braille_dots_2367 0x1002866 /* U+2866 BRAILLE PATTERN DOTS-2367 */ +#define XKB_KEY_braille_dots_12367 0x1002867 /* U+2867 BRAILLE PATTERN DOTS-12367 */ +#define XKB_KEY_braille_dots_467 0x1002868 /* U+2868 BRAILLE PATTERN DOTS-467 */ +#define XKB_KEY_braille_dots_1467 0x1002869 /* U+2869 BRAILLE PATTERN DOTS-1467 */ +#define XKB_KEY_braille_dots_2467 0x100286a /* U+286a BRAILLE PATTERN DOTS-2467 */ +#define XKB_KEY_braille_dots_12467 0x100286b /* U+286b BRAILLE PATTERN DOTS-12467 */ +#define XKB_KEY_braille_dots_3467 0x100286c /* U+286c BRAILLE PATTERN DOTS-3467 */ +#define XKB_KEY_braille_dots_13467 0x100286d /* U+286d BRAILLE PATTERN DOTS-13467 */ +#define XKB_KEY_braille_dots_23467 0x100286e /* U+286e BRAILLE PATTERN DOTS-23467 */ +#define XKB_KEY_braille_dots_123467 0x100286f /* U+286f BRAILLE PATTERN DOTS-123467 */ +#define XKB_KEY_braille_dots_567 0x1002870 /* U+2870 BRAILLE PATTERN DOTS-567 */ +#define XKB_KEY_braille_dots_1567 0x1002871 /* U+2871 BRAILLE PATTERN DOTS-1567 */ +#define XKB_KEY_braille_dots_2567 0x1002872 /* U+2872 BRAILLE PATTERN DOTS-2567 */ +#define XKB_KEY_braille_dots_12567 0x1002873 /* U+2873 BRAILLE PATTERN DOTS-12567 */ +#define XKB_KEY_braille_dots_3567 0x1002874 /* U+2874 BRAILLE PATTERN DOTS-3567 */ +#define XKB_KEY_braille_dots_13567 0x1002875 /* U+2875 BRAILLE PATTERN DOTS-13567 */ +#define XKB_KEY_braille_dots_23567 0x1002876 /* U+2876 BRAILLE PATTERN DOTS-23567 */ +#define XKB_KEY_braille_dots_123567 0x1002877 /* U+2877 BRAILLE PATTERN DOTS-123567 */ +#define XKB_KEY_braille_dots_4567 0x1002878 /* U+2878 BRAILLE PATTERN DOTS-4567 */ +#define XKB_KEY_braille_dots_14567 0x1002879 /* U+2879 BRAILLE PATTERN DOTS-14567 */ +#define XKB_KEY_braille_dots_24567 0x100287a /* U+287a BRAILLE PATTERN DOTS-24567 */ +#define XKB_KEY_braille_dots_124567 0x100287b /* U+287b BRAILLE PATTERN DOTS-124567 */ +#define XKB_KEY_braille_dots_34567 0x100287c /* U+287c BRAILLE PATTERN DOTS-34567 */ +#define XKB_KEY_braille_dots_134567 0x100287d /* U+287d BRAILLE PATTERN DOTS-134567 */ +#define XKB_KEY_braille_dots_234567 0x100287e /* U+287e BRAILLE PATTERN DOTS-234567 */ +#define XKB_KEY_braille_dots_1234567 0x100287f /* U+287f BRAILLE PATTERN DOTS-1234567 */ +#define XKB_KEY_braille_dots_8 0x1002880 /* U+2880 BRAILLE PATTERN DOTS-8 */ +#define XKB_KEY_braille_dots_18 0x1002881 /* U+2881 BRAILLE PATTERN DOTS-18 */ +#define XKB_KEY_braille_dots_28 0x1002882 /* U+2882 BRAILLE PATTERN DOTS-28 */ +#define XKB_KEY_braille_dots_128 0x1002883 /* U+2883 BRAILLE PATTERN DOTS-128 */ +#define XKB_KEY_braille_dots_38 0x1002884 /* U+2884 BRAILLE PATTERN DOTS-38 */ +#define XKB_KEY_braille_dots_138 0x1002885 /* U+2885 BRAILLE PATTERN DOTS-138 */ +#define XKB_KEY_braille_dots_238 0x1002886 /* U+2886 BRAILLE PATTERN DOTS-238 */ +#define XKB_KEY_braille_dots_1238 0x1002887 /* U+2887 BRAILLE PATTERN DOTS-1238 */ +#define XKB_KEY_braille_dots_48 0x1002888 /* U+2888 BRAILLE PATTERN DOTS-48 */ +#define XKB_KEY_braille_dots_148 0x1002889 /* U+2889 BRAILLE PATTERN DOTS-148 */ +#define XKB_KEY_braille_dots_248 0x100288a /* U+288a BRAILLE PATTERN DOTS-248 */ +#define XKB_KEY_braille_dots_1248 0x100288b /* U+288b BRAILLE PATTERN DOTS-1248 */ +#define XKB_KEY_braille_dots_348 0x100288c /* U+288c BRAILLE PATTERN DOTS-348 */ +#define XKB_KEY_braille_dots_1348 0x100288d /* U+288d BRAILLE PATTERN DOTS-1348 */ +#define XKB_KEY_braille_dots_2348 0x100288e /* U+288e BRAILLE PATTERN DOTS-2348 */ +#define XKB_KEY_braille_dots_12348 0x100288f /* U+288f BRAILLE PATTERN DOTS-12348 */ +#define XKB_KEY_braille_dots_58 0x1002890 /* U+2890 BRAILLE PATTERN DOTS-58 */ +#define XKB_KEY_braille_dots_158 0x1002891 /* U+2891 BRAILLE PATTERN DOTS-158 */ +#define XKB_KEY_braille_dots_258 0x1002892 /* U+2892 BRAILLE PATTERN DOTS-258 */ +#define XKB_KEY_braille_dots_1258 0x1002893 /* U+2893 BRAILLE PATTERN DOTS-1258 */ +#define XKB_KEY_braille_dots_358 0x1002894 /* U+2894 BRAILLE PATTERN DOTS-358 */ +#define XKB_KEY_braille_dots_1358 0x1002895 /* U+2895 BRAILLE PATTERN DOTS-1358 */ +#define XKB_KEY_braille_dots_2358 0x1002896 /* U+2896 BRAILLE PATTERN DOTS-2358 */ +#define XKB_KEY_braille_dots_12358 0x1002897 /* U+2897 BRAILLE PATTERN DOTS-12358 */ +#define XKB_KEY_braille_dots_458 0x1002898 /* U+2898 BRAILLE PATTERN DOTS-458 */ +#define XKB_KEY_braille_dots_1458 0x1002899 /* U+2899 BRAILLE PATTERN DOTS-1458 */ +#define XKB_KEY_braille_dots_2458 0x100289a /* U+289a BRAILLE PATTERN DOTS-2458 */ +#define XKB_KEY_braille_dots_12458 0x100289b /* U+289b BRAILLE PATTERN DOTS-12458 */ +#define XKB_KEY_braille_dots_3458 0x100289c /* U+289c BRAILLE PATTERN DOTS-3458 */ +#define XKB_KEY_braille_dots_13458 0x100289d /* U+289d BRAILLE PATTERN DOTS-13458 */ +#define XKB_KEY_braille_dots_23458 0x100289e /* U+289e BRAILLE PATTERN DOTS-23458 */ +#define XKB_KEY_braille_dots_123458 0x100289f /* U+289f BRAILLE PATTERN DOTS-123458 */ +#define XKB_KEY_braille_dots_68 0x10028a0 /* U+28a0 BRAILLE PATTERN DOTS-68 */ +#define XKB_KEY_braille_dots_168 0x10028a1 /* U+28a1 BRAILLE PATTERN DOTS-168 */ +#define XKB_KEY_braille_dots_268 0x10028a2 /* U+28a2 BRAILLE PATTERN DOTS-268 */ +#define XKB_KEY_braille_dots_1268 0x10028a3 /* U+28a3 BRAILLE PATTERN DOTS-1268 */ +#define XKB_KEY_braille_dots_368 0x10028a4 /* U+28a4 BRAILLE PATTERN DOTS-368 */ +#define XKB_KEY_braille_dots_1368 0x10028a5 /* U+28a5 BRAILLE PATTERN DOTS-1368 */ +#define XKB_KEY_braille_dots_2368 0x10028a6 /* U+28a6 BRAILLE PATTERN DOTS-2368 */ +#define XKB_KEY_braille_dots_12368 0x10028a7 /* U+28a7 BRAILLE PATTERN DOTS-12368 */ +#define XKB_KEY_braille_dots_468 0x10028a8 /* U+28a8 BRAILLE PATTERN DOTS-468 */ +#define XKB_KEY_braille_dots_1468 0x10028a9 /* U+28a9 BRAILLE PATTERN DOTS-1468 */ +#define XKB_KEY_braille_dots_2468 0x10028aa /* U+28aa BRAILLE PATTERN DOTS-2468 */ +#define XKB_KEY_braille_dots_12468 0x10028ab /* U+28ab BRAILLE PATTERN DOTS-12468 */ +#define XKB_KEY_braille_dots_3468 0x10028ac /* U+28ac BRAILLE PATTERN DOTS-3468 */ +#define XKB_KEY_braille_dots_13468 0x10028ad /* U+28ad BRAILLE PATTERN DOTS-13468 */ +#define XKB_KEY_braille_dots_23468 0x10028ae /* U+28ae BRAILLE PATTERN DOTS-23468 */ +#define XKB_KEY_braille_dots_123468 0x10028af /* U+28af BRAILLE PATTERN DOTS-123468 */ +#define XKB_KEY_braille_dots_568 0x10028b0 /* U+28b0 BRAILLE PATTERN DOTS-568 */ +#define XKB_KEY_braille_dots_1568 0x10028b1 /* U+28b1 BRAILLE PATTERN DOTS-1568 */ +#define XKB_KEY_braille_dots_2568 0x10028b2 /* U+28b2 BRAILLE PATTERN DOTS-2568 */ +#define XKB_KEY_braille_dots_12568 0x10028b3 /* U+28b3 BRAILLE PATTERN DOTS-12568 */ +#define XKB_KEY_braille_dots_3568 0x10028b4 /* U+28b4 BRAILLE PATTERN DOTS-3568 */ +#define XKB_KEY_braille_dots_13568 0x10028b5 /* U+28b5 BRAILLE PATTERN DOTS-13568 */ +#define XKB_KEY_braille_dots_23568 0x10028b6 /* U+28b6 BRAILLE PATTERN DOTS-23568 */ +#define XKB_KEY_braille_dots_123568 0x10028b7 /* U+28b7 BRAILLE PATTERN DOTS-123568 */ +#define XKB_KEY_braille_dots_4568 0x10028b8 /* U+28b8 BRAILLE PATTERN DOTS-4568 */ +#define XKB_KEY_braille_dots_14568 0x10028b9 /* U+28b9 BRAILLE PATTERN DOTS-14568 */ +#define XKB_KEY_braille_dots_24568 0x10028ba /* U+28ba BRAILLE PATTERN DOTS-24568 */ +#define XKB_KEY_braille_dots_124568 0x10028bb /* U+28bb BRAILLE PATTERN DOTS-124568 */ +#define XKB_KEY_braille_dots_34568 0x10028bc /* U+28bc BRAILLE PATTERN DOTS-34568 */ +#define XKB_KEY_braille_dots_134568 0x10028bd /* U+28bd BRAILLE PATTERN DOTS-134568 */ +#define XKB_KEY_braille_dots_234568 0x10028be /* U+28be BRAILLE PATTERN DOTS-234568 */ +#define XKB_KEY_braille_dots_1234568 0x10028bf /* U+28bf BRAILLE PATTERN DOTS-1234568 */ +#define XKB_KEY_braille_dots_78 0x10028c0 /* U+28c0 BRAILLE PATTERN DOTS-78 */ +#define XKB_KEY_braille_dots_178 0x10028c1 /* U+28c1 BRAILLE PATTERN DOTS-178 */ +#define XKB_KEY_braille_dots_278 0x10028c2 /* U+28c2 BRAILLE PATTERN DOTS-278 */ +#define XKB_KEY_braille_dots_1278 0x10028c3 /* U+28c3 BRAILLE PATTERN DOTS-1278 */ +#define XKB_KEY_braille_dots_378 0x10028c4 /* U+28c4 BRAILLE PATTERN DOTS-378 */ +#define XKB_KEY_braille_dots_1378 0x10028c5 /* U+28c5 BRAILLE PATTERN DOTS-1378 */ +#define XKB_KEY_braille_dots_2378 0x10028c6 /* U+28c6 BRAILLE PATTERN DOTS-2378 */ +#define XKB_KEY_braille_dots_12378 0x10028c7 /* U+28c7 BRAILLE PATTERN DOTS-12378 */ +#define XKB_KEY_braille_dots_478 0x10028c8 /* U+28c8 BRAILLE PATTERN DOTS-478 */ +#define XKB_KEY_braille_dots_1478 0x10028c9 /* U+28c9 BRAILLE PATTERN DOTS-1478 */ +#define XKB_KEY_braille_dots_2478 0x10028ca /* U+28ca BRAILLE PATTERN DOTS-2478 */ +#define XKB_KEY_braille_dots_12478 0x10028cb /* U+28cb BRAILLE PATTERN DOTS-12478 */ +#define XKB_KEY_braille_dots_3478 0x10028cc /* U+28cc BRAILLE PATTERN DOTS-3478 */ +#define XKB_KEY_braille_dots_13478 0x10028cd /* U+28cd BRAILLE PATTERN DOTS-13478 */ +#define XKB_KEY_braille_dots_23478 0x10028ce /* U+28ce BRAILLE PATTERN DOTS-23478 */ +#define XKB_KEY_braille_dots_123478 0x10028cf /* U+28cf BRAILLE PATTERN DOTS-123478 */ +#define XKB_KEY_braille_dots_578 0x10028d0 /* U+28d0 BRAILLE PATTERN DOTS-578 */ +#define XKB_KEY_braille_dots_1578 0x10028d1 /* U+28d1 BRAILLE PATTERN DOTS-1578 */ +#define XKB_KEY_braille_dots_2578 0x10028d2 /* U+28d2 BRAILLE PATTERN DOTS-2578 */ +#define XKB_KEY_braille_dots_12578 0x10028d3 /* U+28d3 BRAILLE PATTERN DOTS-12578 */ +#define XKB_KEY_braille_dots_3578 0x10028d4 /* U+28d4 BRAILLE PATTERN DOTS-3578 */ +#define XKB_KEY_braille_dots_13578 0x10028d5 /* U+28d5 BRAILLE PATTERN DOTS-13578 */ +#define XKB_KEY_braille_dots_23578 0x10028d6 /* U+28d6 BRAILLE PATTERN DOTS-23578 */ +#define XKB_KEY_braille_dots_123578 0x10028d7 /* U+28d7 BRAILLE PATTERN DOTS-123578 */ +#define XKB_KEY_braille_dots_4578 0x10028d8 /* U+28d8 BRAILLE PATTERN DOTS-4578 */ +#define XKB_KEY_braille_dots_14578 0x10028d9 /* U+28d9 BRAILLE PATTERN DOTS-14578 */ +#define XKB_KEY_braille_dots_24578 0x10028da /* U+28da BRAILLE PATTERN DOTS-24578 */ +#define XKB_KEY_braille_dots_124578 0x10028db /* U+28db BRAILLE PATTERN DOTS-124578 */ +#define XKB_KEY_braille_dots_34578 0x10028dc /* U+28dc BRAILLE PATTERN DOTS-34578 */ +#define XKB_KEY_braille_dots_134578 0x10028dd /* U+28dd BRAILLE PATTERN DOTS-134578 */ +#define XKB_KEY_braille_dots_234578 0x10028de /* U+28de BRAILLE PATTERN DOTS-234578 */ +#define XKB_KEY_braille_dots_1234578 0x10028df /* U+28df BRAILLE PATTERN DOTS-1234578 */ +#define XKB_KEY_braille_dots_678 0x10028e0 /* U+28e0 BRAILLE PATTERN DOTS-678 */ +#define XKB_KEY_braille_dots_1678 0x10028e1 /* U+28e1 BRAILLE PATTERN DOTS-1678 */ +#define XKB_KEY_braille_dots_2678 0x10028e2 /* U+28e2 BRAILLE PATTERN DOTS-2678 */ +#define XKB_KEY_braille_dots_12678 0x10028e3 /* U+28e3 BRAILLE PATTERN DOTS-12678 */ +#define XKB_KEY_braille_dots_3678 0x10028e4 /* U+28e4 BRAILLE PATTERN DOTS-3678 */ +#define XKB_KEY_braille_dots_13678 0x10028e5 /* U+28e5 BRAILLE PATTERN DOTS-13678 */ +#define XKB_KEY_braille_dots_23678 0x10028e6 /* U+28e6 BRAILLE PATTERN DOTS-23678 */ +#define XKB_KEY_braille_dots_123678 0x10028e7 /* U+28e7 BRAILLE PATTERN DOTS-123678 */ +#define XKB_KEY_braille_dots_4678 0x10028e8 /* U+28e8 BRAILLE PATTERN DOTS-4678 */ +#define XKB_KEY_braille_dots_14678 0x10028e9 /* U+28e9 BRAILLE PATTERN DOTS-14678 */ +#define XKB_KEY_braille_dots_24678 0x10028ea /* U+28ea BRAILLE PATTERN DOTS-24678 */ +#define XKB_KEY_braille_dots_124678 0x10028eb /* U+28eb BRAILLE PATTERN DOTS-124678 */ +#define XKB_KEY_braille_dots_34678 0x10028ec /* U+28ec BRAILLE PATTERN DOTS-34678 */ +#define XKB_KEY_braille_dots_134678 0x10028ed /* U+28ed BRAILLE PATTERN DOTS-134678 */ +#define XKB_KEY_braille_dots_234678 0x10028ee /* U+28ee BRAILLE PATTERN DOTS-234678 */ +#define XKB_KEY_braille_dots_1234678 0x10028ef /* U+28ef BRAILLE PATTERN DOTS-1234678 */ +#define XKB_KEY_braille_dots_5678 0x10028f0 /* U+28f0 BRAILLE PATTERN DOTS-5678 */ +#define XKB_KEY_braille_dots_15678 0x10028f1 /* U+28f1 BRAILLE PATTERN DOTS-15678 */ +#define XKB_KEY_braille_dots_25678 0x10028f2 /* U+28f2 BRAILLE PATTERN DOTS-25678 */ +#define XKB_KEY_braille_dots_125678 0x10028f3 /* U+28f3 BRAILLE PATTERN DOTS-125678 */ +#define XKB_KEY_braille_dots_35678 0x10028f4 /* U+28f4 BRAILLE PATTERN DOTS-35678 */ +#define XKB_KEY_braille_dots_135678 0x10028f5 /* U+28f5 BRAILLE PATTERN DOTS-135678 */ +#define XKB_KEY_braille_dots_235678 0x10028f6 /* U+28f6 BRAILLE PATTERN DOTS-235678 */ +#define XKB_KEY_braille_dots_1235678 0x10028f7 /* U+28f7 BRAILLE PATTERN DOTS-1235678 */ +#define XKB_KEY_braille_dots_45678 0x10028f8 /* U+28f8 BRAILLE PATTERN DOTS-45678 */ +#define XKB_KEY_braille_dots_145678 0x10028f9 /* U+28f9 BRAILLE PATTERN DOTS-145678 */ +#define XKB_KEY_braille_dots_245678 0x10028fa /* U+28fa BRAILLE PATTERN DOTS-245678 */ +#define XKB_KEY_braille_dots_1245678 0x10028fb /* U+28fb BRAILLE PATTERN DOTS-1245678 */ +#define XKB_KEY_braille_dots_345678 0x10028fc /* U+28fc BRAILLE PATTERN DOTS-345678 */ +#define XKB_KEY_braille_dots_1345678 0x10028fd /* U+28fd BRAILLE PATTERN DOTS-1345678 */ +#define XKB_KEY_braille_dots_2345678 0x10028fe /* U+28fe BRAILLE PATTERN DOTS-2345678 */ +#define XKB_KEY_braille_dots_12345678 0x10028ff /* U+28ff BRAILLE PATTERN DOTS-12345678 */ + +/* + * Sinhala (http://unicode.org/charts/PDF/U0D80.pdf) + * http://www.nongnu.org/sinhala/doc/transliteration/sinhala-transliteration_6.html + */ + +#define XKB_KEY_Sinh_ng 0x1000d82 /* U+0D82 SINHALA ANUSVARAYA */ +#define XKB_KEY_Sinh_h2 0x1000d83 /* U+0D83 SINHALA VISARGAYA */ +#define XKB_KEY_Sinh_a 0x1000d85 /* U+0D85 SINHALA AYANNA */ +#define XKB_KEY_Sinh_aa 0x1000d86 /* U+0D86 SINHALA AAYANNA */ +#define XKB_KEY_Sinh_ae 0x1000d87 /* U+0D87 SINHALA AEYANNA */ +#define XKB_KEY_Sinh_aee 0x1000d88 /* U+0D88 SINHALA AEEYANNA */ +#define XKB_KEY_Sinh_i 0x1000d89 /* U+0D89 SINHALA IYANNA */ +#define XKB_KEY_Sinh_ii 0x1000d8a /* U+0D8A SINHALA IIYANNA */ +#define XKB_KEY_Sinh_u 0x1000d8b /* U+0D8B SINHALA UYANNA */ +#define XKB_KEY_Sinh_uu 0x1000d8c /* U+0D8C SINHALA UUYANNA */ +#define XKB_KEY_Sinh_ri 0x1000d8d /* U+0D8D SINHALA IRUYANNA */ +#define XKB_KEY_Sinh_rii 0x1000d8e /* U+0D8E SINHALA IRUUYANNA */ +#define XKB_KEY_Sinh_lu 0x1000d8f /* U+0D8F SINHALA ILUYANNA */ +#define XKB_KEY_Sinh_luu 0x1000d90 /* U+0D90 SINHALA ILUUYANNA */ +#define XKB_KEY_Sinh_e 0x1000d91 /* U+0D91 SINHALA EYANNA */ +#define XKB_KEY_Sinh_ee 0x1000d92 /* U+0D92 SINHALA EEYANNA */ +#define XKB_KEY_Sinh_ai 0x1000d93 /* U+0D93 SINHALA AIYANNA */ +#define XKB_KEY_Sinh_o 0x1000d94 /* U+0D94 SINHALA OYANNA */ +#define XKB_KEY_Sinh_oo 0x1000d95 /* U+0D95 SINHALA OOYANNA */ +#define XKB_KEY_Sinh_au 0x1000d96 /* U+0D96 SINHALA AUYANNA */ +#define XKB_KEY_Sinh_ka 0x1000d9a /* U+0D9A SINHALA KAYANNA */ +#define XKB_KEY_Sinh_kha 0x1000d9b /* U+0D9B SINHALA MAHA. KAYANNA */ +#define XKB_KEY_Sinh_ga 0x1000d9c /* U+0D9C SINHALA GAYANNA */ +#define XKB_KEY_Sinh_gha 0x1000d9d /* U+0D9D SINHALA MAHA. GAYANNA */ +#define XKB_KEY_Sinh_ng2 0x1000d9e /* U+0D9E SINHALA KANTAJA NAASIKYAYA */ +#define XKB_KEY_Sinh_nga 0x1000d9f /* U+0D9F SINHALA SANYAKA GAYANNA */ +#define XKB_KEY_Sinh_ca 0x1000da0 /* U+0DA0 SINHALA CAYANNA */ +#define XKB_KEY_Sinh_cha 0x1000da1 /* U+0DA1 SINHALA MAHA. CAYANNA */ +#define XKB_KEY_Sinh_ja 0x1000da2 /* U+0DA2 SINHALA JAYANNA */ +#define XKB_KEY_Sinh_jha 0x1000da3 /* U+0DA3 SINHALA MAHA. JAYANNA */ +#define XKB_KEY_Sinh_nya 0x1000da4 /* U+0DA4 SINHALA TAALUJA NAASIKYAYA */ +#define XKB_KEY_Sinh_jnya 0x1000da5 /* U+0DA5 SINHALA TAALUJA SANYOOGA NAASIKYAYA */ +#define XKB_KEY_Sinh_nja 0x1000da6 /* U+0DA6 SINHALA SANYAKA JAYANNA */ +#define XKB_KEY_Sinh_tta 0x1000da7 /* U+0DA7 SINHALA TTAYANNA */ +#define XKB_KEY_Sinh_ttha 0x1000da8 /* U+0DA8 SINHALA MAHA. TTAYANNA */ +#define XKB_KEY_Sinh_dda 0x1000da9 /* U+0DA9 SINHALA DDAYANNA */ +#define XKB_KEY_Sinh_ddha 0x1000daa /* U+0DAA SINHALA MAHA. DDAYANNA */ +#define XKB_KEY_Sinh_nna 0x1000dab /* U+0DAB SINHALA MUURDHAJA NAYANNA */ +#define XKB_KEY_Sinh_ndda 0x1000dac /* U+0DAC SINHALA SANYAKA DDAYANNA */ +#define XKB_KEY_Sinh_tha 0x1000dad /* U+0DAD SINHALA TAYANNA */ +#define XKB_KEY_Sinh_thha 0x1000dae /* U+0DAE SINHALA MAHA. TAYANNA */ +#define XKB_KEY_Sinh_dha 0x1000daf /* U+0DAF SINHALA DAYANNA */ +#define XKB_KEY_Sinh_dhha 0x1000db0 /* U+0DB0 SINHALA MAHA. DAYANNA */ +#define XKB_KEY_Sinh_na 0x1000db1 /* U+0DB1 SINHALA DANTAJA NAYANNA */ +#define XKB_KEY_Sinh_ndha 0x1000db3 /* U+0DB3 SINHALA SANYAKA DAYANNA */ +#define XKB_KEY_Sinh_pa 0x1000db4 /* U+0DB4 SINHALA PAYANNA */ +#define XKB_KEY_Sinh_pha 0x1000db5 /* U+0DB5 SINHALA MAHA. PAYANNA */ +#define XKB_KEY_Sinh_ba 0x1000db6 /* U+0DB6 SINHALA BAYANNA */ +#define XKB_KEY_Sinh_bha 0x1000db7 /* U+0DB7 SINHALA MAHA. BAYANNA */ +#define XKB_KEY_Sinh_ma 0x1000db8 /* U+0DB8 SINHALA MAYANNA */ +#define XKB_KEY_Sinh_mba 0x1000db9 /* U+0DB9 SINHALA AMBA BAYANNA */ +#define XKB_KEY_Sinh_ya 0x1000dba /* U+0DBA SINHALA YAYANNA */ +#define XKB_KEY_Sinh_ra 0x1000dbb /* U+0DBB SINHALA RAYANNA */ +#define XKB_KEY_Sinh_la 0x1000dbd /* U+0DBD SINHALA DANTAJA LAYANNA */ +#define XKB_KEY_Sinh_va 0x1000dc0 /* U+0DC0 SINHALA VAYANNA */ +#define XKB_KEY_Sinh_sha 0x1000dc1 /* U+0DC1 SINHALA TAALUJA SAYANNA */ +#define XKB_KEY_Sinh_ssha 0x1000dc2 /* U+0DC2 SINHALA MUURDHAJA SAYANNA */ +#define XKB_KEY_Sinh_sa 0x1000dc3 /* U+0DC3 SINHALA DANTAJA SAYANNA */ +#define XKB_KEY_Sinh_ha 0x1000dc4 /* U+0DC4 SINHALA HAYANNA */ +#define XKB_KEY_Sinh_lla 0x1000dc5 /* U+0DC5 SINHALA MUURDHAJA LAYANNA */ +#define XKB_KEY_Sinh_fa 0x1000dc6 /* U+0DC6 SINHALA FAYANNA */ +#define XKB_KEY_Sinh_al 0x1000dca /* U+0DCA SINHALA AL-LAKUNA */ +#define XKB_KEY_Sinh_aa2 0x1000dcf /* U+0DCF SINHALA AELA-PILLA */ +#define XKB_KEY_Sinh_ae2 0x1000dd0 /* U+0DD0 SINHALA AEDA-PILLA */ +#define XKB_KEY_Sinh_aee2 0x1000dd1 /* U+0DD1 SINHALA DIGA AEDA-PILLA */ +#define XKB_KEY_Sinh_i2 0x1000dd2 /* U+0DD2 SINHALA IS-PILLA */ +#define XKB_KEY_Sinh_ii2 0x1000dd3 /* U+0DD3 SINHALA DIGA IS-PILLA */ +#define XKB_KEY_Sinh_u2 0x1000dd4 /* U+0DD4 SINHALA PAA-PILLA */ +#define XKB_KEY_Sinh_uu2 0x1000dd6 /* U+0DD6 SINHALA DIGA PAA-PILLA */ +#define XKB_KEY_Sinh_ru2 0x1000dd8 /* U+0DD8 SINHALA GAETTA-PILLA */ +#define XKB_KEY_Sinh_e2 0x1000dd9 /* U+0DD9 SINHALA KOMBUVA */ +#define XKB_KEY_Sinh_ee2 0x1000dda /* U+0DDA SINHALA DIGA KOMBUVA */ +#define XKB_KEY_Sinh_ai2 0x1000ddb /* U+0DDB SINHALA KOMBU DEKA */ +#define XKB_KEY_Sinh_o2 0x1000ddc /* U+0DDC SINHALA KOMBUVA HAA AELA-PILLA*/ +#define XKB_KEY_Sinh_oo2 0x1000ddd /* U+0DDD SINHALA KOMBUVA HAA DIGA AELA-PILLA*/ +#define XKB_KEY_Sinh_au2 0x1000dde /* U+0DDE SINHALA KOMBUVA HAA GAYANUKITTA */ +#define XKB_KEY_Sinh_lu2 0x1000ddf /* U+0DDF SINHALA GAYANUKITTA */ +#define XKB_KEY_Sinh_ruu2 0x1000df2 /* U+0DF2 SINHALA DIGA GAETTA-PILLA */ +#define XKB_KEY_Sinh_luu2 0x1000df3 /* U+0DF3 SINHALA DIGA GAYANUKITTA */ +#define XKB_KEY_Sinh_kunddaliya 0x1000df4 /* U+0DF4 SINHALA KUNDDALIYA */ +/* + * XFree86 vendor specific keysyms. + * + * The XFree86 keysym range is 0x10080001 - 0x1008FFFF. + * + * The XF86 set of keysyms is a catch-all set of defines for keysyms found + * on various multimedia keyboards. Originally specific to XFree86 they have + * been been adopted over time and are considered a "standard" part of X + * keysym definitions. + * XFree86 never properly commented these keysyms, so we have done our + * best to explain the semantic meaning of these keys. + * + * XFree86 has removed their mail archives of the period, that might have + * shed more light on some of these definitions. Until/unless we resurrect + * these archives, these are from memory and usage. + */ + +/* + * ModeLock + * + * This one is old, and not really used any more since XKB offers this + * functionality. + */ + +#define XKB_KEY_XF86ModeLock 0x1008FF01 /* Mode Switch Lock */ + +/* Backlight controls. */ +#define XKB_KEY_XF86MonBrightnessUp 0x1008FF02 /* Monitor/panel brightness */ +#define XKB_KEY_XF86MonBrightnessDown 0x1008FF03 /* Monitor/panel brightness */ +#define XKB_KEY_XF86KbdLightOnOff 0x1008FF04 /* Keyboards may be lit */ +#define XKB_KEY_XF86KbdBrightnessUp 0x1008FF05 /* Keyboards may be lit */ +#define XKB_KEY_XF86KbdBrightnessDown 0x1008FF06 /* Keyboards may be lit */ +#define XKB_KEY_XF86MonBrightnessCycle 0x1008FF07 /* Monitor/panel brightness */ + +/* + * Keys found on some "Internet" keyboards. + */ +#define XKB_KEY_XF86Standby 0x1008FF10 /* System into standby mode */ +#define XKB_KEY_XF86AudioLowerVolume 0x1008FF11 /* Volume control down */ +#define XKB_KEY_XF86AudioMute 0x1008FF12 /* Mute sound from the system */ +#define XKB_KEY_XF86AudioRaiseVolume 0x1008FF13 /* Volume control up */ +#define XKB_KEY_XF86AudioPlay 0x1008FF14 /* Start playing of audio > */ +#define XKB_KEY_XF86AudioStop 0x1008FF15 /* Stop playing audio */ +#define XKB_KEY_XF86AudioPrev 0x1008FF16 /* Previous track */ +#define XKB_KEY_XF86AudioNext 0x1008FF17 /* Next track */ +#define XKB_KEY_XF86HomePage 0x1008FF18 /* Display user's home page */ +#define XKB_KEY_XF86Mail 0x1008FF19 /* Invoke user's mail program */ +#define XKB_KEY_XF86Start 0x1008FF1A /* Start application */ +#define XKB_KEY_XF86Search 0x1008FF1B /* Search */ +#define XKB_KEY_XF86AudioRecord 0x1008FF1C /* Record audio application */ + +/* These are sometimes found on PDA's (e.g. Palm, PocketPC or elsewhere) */ +#define XKB_KEY_XF86Calculator 0x1008FF1D /* Invoke calculator program */ +#define XKB_KEY_XF86Memo 0x1008FF1E /* Invoke Memo taking program */ +#define XKB_KEY_XF86ToDoList 0x1008FF1F /* Invoke To Do List program */ +#define XKB_KEY_XF86Calendar 0x1008FF20 /* Invoke Calendar program */ +#define XKB_KEY_XF86PowerDown 0x1008FF21 /* Deep sleep the system */ +#define XKB_KEY_XF86ContrastAdjust 0x1008FF22 /* Adjust screen contrast */ +#define XKB_KEY_XF86RockerUp 0x1008FF23 /* Rocker switches exist up */ +#define XKB_KEY_XF86RockerDown 0x1008FF24 /* and down */ +#define XKB_KEY_XF86RockerEnter 0x1008FF25 /* and let you press them */ + +/* Some more "Internet" keyboard symbols */ +#define XKB_KEY_XF86Back 0x1008FF26 /* Like back on a browser */ +#define XKB_KEY_XF86Forward 0x1008FF27 /* Like forward on a browser */ +#define XKB_KEY_XF86Stop 0x1008FF28 /* Stop current operation */ +#define XKB_KEY_XF86Refresh 0x1008FF29 /* Refresh the page */ +#define XKB_KEY_XF86PowerOff 0x1008FF2A /* Power off system entirely */ +#define XKB_KEY_XF86WakeUp 0x1008FF2B /* Wake up system from sleep */ +#define XKB_KEY_XF86Eject 0x1008FF2C /* Eject device (e.g. DVD) */ +#define XKB_KEY_XF86ScreenSaver 0x1008FF2D /* Invoke screensaver */ +#define XKB_KEY_XF86WWW 0x1008FF2E /* Invoke web browser */ +#define XKB_KEY_XF86Sleep 0x1008FF2F /* Put system to sleep */ +#define XKB_KEY_XF86Favorites 0x1008FF30 /* Show favorite locations */ +#define XKB_KEY_XF86AudioPause 0x1008FF31 /* Pause audio playing */ +#define XKB_KEY_XF86AudioMedia 0x1008FF32 /* Launch media collection app */ +#define XKB_KEY_XF86MyComputer 0x1008FF33 /* Display "My Computer" window */ +#define XKB_KEY_XF86VendorHome 0x1008FF34 /* Display vendor home web site */ +#define XKB_KEY_XF86LightBulb 0x1008FF35 /* Light bulb keys exist */ +#define XKB_KEY_XF86Shop 0x1008FF36 /* Display shopping web site */ +#define XKB_KEY_XF86History 0x1008FF37 /* Show history of web surfing */ +#define XKB_KEY_XF86OpenURL 0x1008FF38 /* Open selected URL */ +#define XKB_KEY_XF86AddFavorite 0x1008FF39 /* Add URL to favorites list */ +#define XKB_KEY_XF86HotLinks 0x1008FF3A /* Show "hot" links */ +#define XKB_KEY_XF86BrightnessAdjust 0x1008FF3B /* Invoke brightness adj. UI */ +#define XKB_KEY_XF86Finance 0x1008FF3C /* Display financial site */ +#define XKB_KEY_XF86Community 0x1008FF3D /* Display user's community */ +#define XKB_KEY_XF86AudioRewind 0x1008FF3E /* "rewind" audio track */ +#define XKB_KEY_XF86BackForward 0x1008FF3F /* ??? */ +#define XKB_KEY_XF86Launch0 0x1008FF40 /* Launch Application */ +#define XKB_KEY_XF86Launch1 0x1008FF41 /* Launch Application */ +#define XKB_KEY_XF86Launch2 0x1008FF42 /* Launch Application */ +#define XKB_KEY_XF86Launch3 0x1008FF43 /* Launch Application */ +#define XKB_KEY_XF86Launch4 0x1008FF44 /* Launch Application */ +#define XKB_KEY_XF86Launch5 0x1008FF45 /* Launch Application */ +#define XKB_KEY_XF86Launch6 0x1008FF46 /* Launch Application */ +#define XKB_KEY_XF86Launch7 0x1008FF47 /* Launch Application */ +#define XKB_KEY_XF86Launch8 0x1008FF48 /* Launch Application */ +#define XKB_KEY_XF86Launch9 0x1008FF49 /* Launch Application */ +#define XKB_KEY_XF86LaunchA 0x1008FF4A /* Launch Application */ +#define XKB_KEY_XF86LaunchB 0x1008FF4B /* Launch Application */ +#define XKB_KEY_XF86LaunchC 0x1008FF4C /* Launch Application */ +#define XKB_KEY_XF86LaunchD 0x1008FF4D /* Launch Application */ +#define XKB_KEY_XF86LaunchE 0x1008FF4E /* Launch Application */ +#define XKB_KEY_XF86LaunchF 0x1008FF4F /* Launch Application */ + +#define XKB_KEY_XF86ApplicationLeft 0x1008FF50 /* switch to application, left */ +#define XKB_KEY_XF86ApplicationRight 0x1008FF51 /* switch to application, right*/ +#define XKB_KEY_XF86Book 0x1008FF52 /* Launch bookreader */ +#define XKB_KEY_XF86CD 0x1008FF53 /* Launch CD/DVD player */ +#define XKB_KEY_XF86Calculater 0x1008FF54 /* Launch Calculater */ +#define XKB_KEY_XF86Clear 0x1008FF55 /* Clear window, screen */ +#define XKB_KEY_XF86Close 0x1008FF56 /* Close window */ +#define XKB_KEY_XF86Copy 0x1008FF57 /* Copy selection */ +#define XKB_KEY_XF86Cut 0x1008FF58 /* Cut selection */ +#define XKB_KEY_XF86Display 0x1008FF59 /* Output switch key */ +#define XKB_KEY_XF86DOS 0x1008FF5A /* Launch DOS (emulation) */ +#define XKB_KEY_XF86Documents 0x1008FF5B /* Open documents window */ +#define XKB_KEY_XF86Excel 0x1008FF5C /* Launch spread sheet */ +#define XKB_KEY_XF86Explorer 0x1008FF5D /* Launch file explorer */ +#define XKB_KEY_XF86Game 0x1008FF5E /* Launch game */ +#define XKB_KEY_XF86Go 0x1008FF5F /* Go to URL */ +#define XKB_KEY_XF86iTouch 0x1008FF60 /* Logitech iTouch- don't use */ +#define XKB_KEY_XF86LogOff 0x1008FF61 /* Log off system */ +#define XKB_KEY_XF86Market 0x1008FF62 /* ?? */ +#define XKB_KEY_XF86Meeting 0x1008FF63 /* enter meeting in calendar */ +#define XKB_KEY_XF86MenuKB 0x1008FF65 /* distinguish keyboard from PB */ +#define XKB_KEY_XF86MenuPB 0x1008FF66 /* distinguish PB from keyboard */ +#define XKB_KEY_XF86MySites 0x1008FF67 /* Favourites */ +#define XKB_KEY_XF86New 0x1008FF68 /* New (folder, document... */ +#define XKB_KEY_XF86News 0x1008FF69 /* News */ +#define XKB_KEY_XF86OfficeHome 0x1008FF6A /* Office home (old Staroffice)*/ +#define XKB_KEY_XF86Open 0x1008FF6B /* Open */ +#define XKB_KEY_XF86Option 0x1008FF6C /* ?? */ +#define XKB_KEY_XF86Paste 0x1008FF6D /* Paste */ +#define XKB_KEY_XF86Phone 0x1008FF6E /* Launch phone; dial number */ +#define XKB_KEY_XF86Q 0x1008FF70 /* Compaq's Q - don't use */ +#define XKB_KEY_XF86Reply 0x1008FF72 /* Reply e.g., mail */ +#define XKB_KEY_XF86Reload 0x1008FF73 /* Reload web page, file, etc. */ +#define XKB_KEY_XF86RotateWindows 0x1008FF74 /* Rotate windows e.g. xrandr */ +#define XKB_KEY_XF86RotationPB 0x1008FF75 /* don't use */ +#define XKB_KEY_XF86RotationKB 0x1008FF76 /* don't use */ +#define XKB_KEY_XF86Save 0x1008FF77 /* Save (file, document, state */ +#define XKB_KEY_XF86ScrollUp 0x1008FF78 /* Scroll window/contents up */ +#define XKB_KEY_XF86ScrollDown 0x1008FF79 /* Scrool window/contentd down */ +#define XKB_KEY_XF86ScrollClick 0x1008FF7A /* Use XKB mousekeys instead */ +#define XKB_KEY_XF86Send 0x1008FF7B /* Send mail, file, object */ +#define XKB_KEY_XF86Spell 0x1008FF7C /* Spell checker */ +#define XKB_KEY_XF86SplitScreen 0x1008FF7D /* Split window or screen */ +#define XKB_KEY_XF86Support 0x1008FF7E /* Get support (??) */ +#define XKB_KEY_XF86TaskPane 0x1008FF7F /* Show tasks */ +#define XKB_KEY_XF86Terminal 0x1008FF80 /* Launch terminal emulator */ +#define XKB_KEY_XF86Tools 0x1008FF81 /* toolbox of desktop/app. */ +#define XKB_KEY_XF86Travel 0x1008FF82 /* ?? */ +#define XKB_KEY_XF86UserPB 0x1008FF84 /* ?? */ +#define XKB_KEY_XF86User1KB 0x1008FF85 /* ?? */ +#define XKB_KEY_XF86User2KB 0x1008FF86 /* ?? */ +#define XKB_KEY_XF86Video 0x1008FF87 /* Launch video player */ +#define XKB_KEY_XF86WheelButton 0x1008FF88 /* button from a mouse wheel */ +#define XKB_KEY_XF86Word 0x1008FF89 /* Launch word processor */ +#define XKB_KEY_XF86Xfer 0x1008FF8A +#define XKB_KEY_XF86ZoomIn 0x1008FF8B /* zoom in view, map, etc. */ +#define XKB_KEY_XF86ZoomOut 0x1008FF8C /* zoom out view, map, etc. */ + +#define XKB_KEY_XF86Away 0x1008FF8D /* mark yourself as away */ +#define XKB_KEY_XF86Messenger 0x1008FF8E /* as in instant messaging */ +#define XKB_KEY_XF86WebCam 0x1008FF8F /* Launch web camera app. */ +#define XKB_KEY_XF86MailForward 0x1008FF90 /* Forward in mail */ +#define XKB_KEY_XF86Pictures 0x1008FF91 /* Show pictures */ +#define XKB_KEY_XF86Music 0x1008FF92 /* Launch music application */ + +#define XKB_KEY_XF86Battery 0x1008FF93 /* Display battery information */ +#define XKB_KEY_XF86Bluetooth 0x1008FF94 /* Enable/disable Bluetooth */ +#define XKB_KEY_XF86WLAN 0x1008FF95 /* Enable/disable WLAN */ +#define XKB_KEY_XF86UWB 0x1008FF96 /* Enable/disable UWB */ + +#define XKB_KEY_XF86AudioForward 0x1008FF97 /* fast-forward audio track */ +#define XKB_KEY_XF86AudioRepeat 0x1008FF98 /* toggle repeat mode */ +#define XKB_KEY_XF86AudioRandomPlay 0x1008FF99 /* toggle shuffle mode */ +#define XKB_KEY_XF86Subtitle 0x1008FF9A /* cycle through subtitle */ +#define XKB_KEY_XF86AudioCycleTrack 0x1008FF9B /* cycle through audio tracks */ +#define XKB_KEY_XF86CycleAngle 0x1008FF9C /* cycle through angles */ +#define XKB_KEY_XF86FrameBack 0x1008FF9D /* video: go one frame back */ +#define XKB_KEY_XF86FrameForward 0x1008FF9E /* video: go one frame forward */ +#define XKB_KEY_XF86Time 0x1008FF9F /* display, or shows an entry for time seeking */ +#define XKB_KEY_XF86Select 0x1008FFA0 /* Select button on joypads and remotes */ +#define XKB_KEY_XF86View 0x1008FFA1 /* Show a view options/properties */ +#define XKB_KEY_XF86TopMenu 0x1008FFA2 /* Go to a top-level menu in a video */ + +#define XKB_KEY_XF86Red 0x1008FFA3 /* Red button */ +#define XKB_KEY_XF86Green 0x1008FFA4 /* Green button */ +#define XKB_KEY_XF86Yellow 0x1008FFA5 /* Yellow button */ +#define XKB_KEY_XF86Blue 0x1008FFA6 /* Blue button */ + +#define XKB_KEY_XF86Suspend 0x1008FFA7 /* Sleep to RAM */ +#define XKB_KEY_XF86Hibernate 0x1008FFA8 /* Sleep to disk */ +#define XKB_KEY_XF86TouchpadToggle 0x1008FFA9 /* Toggle between touchpad/trackstick */ +#define XKB_KEY_XF86TouchpadOn 0x1008FFB0 /* The touchpad got switched on */ +#define XKB_KEY_XF86TouchpadOff 0x1008FFB1 /* The touchpad got switched off */ + +#define XKB_KEY_XF86AudioMicMute 0x1008FFB2 /* Mute the Mic from the system */ + +#define XKB_KEY_XF86Keyboard 0x1008FFB3 /* User defined keyboard related action */ + +#define XKB_KEY_XF86WWAN 0x1008FFB4 /* Toggle WWAN (LTE, UMTS, etc.) radio */ +#define XKB_KEY_XF86RFKill 0x1008FFB5 /* Toggle radios on/off */ + +#define XKB_KEY_XF86AudioPreset 0x1008FFB6 /* Select equalizer preset, e.g. theatre-mode */ + +#define XKB_KEY_XF86RotationLockToggle 0x1008FFB7 /* Toggle screen rotation lock on/off */ + +#define XKB_KEY_XF86FullScreen 0x1008FFB8 /* Toggle fullscreen */ + +/* Keys for special action keys (hot keys) */ +/* Virtual terminals on some operating systems */ +#define XKB_KEY_XF86Switch_VT_1 0x1008FE01 +#define XKB_KEY_XF86Switch_VT_2 0x1008FE02 +#define XKB_KEY_XF86Switch_VT_3 0x1008FE03 +#define XKB_KEY_XF86Switch_VT_4 0x1008FE04 +#define XKB_KEY_XF86Switch_VT_5 0x1008FE05 +#define XKB_KEY_XF86Switch_VT_6 0x1008FE06 +#define XKB_KEY_XF86Switch_VT_7 0x1008FE07 +#define XKB_KEY_XF86Switch_VT_8 0x1008FE08 +#define XKB_KEY_XF86Switch_VT_9 0x1008FE09 +#define XKB_KEY_XF86Switch_VT_10 0x1008FE0A +#define XKB_KEY_XF86Switch_VT_11 0x1008FE0B +#define XKB_KEY_XF86Switch_VT_12 0x1008FE0C + +#define XKB_KEY_XF86Ungrab 0x1008FE20 /* force ungrab */ +#define XKB_KEY_XF86ClearGrab 0x1008FE21 /* kill application with grab */ +#define XKB_KEY_XF86Next_VMode 0x1008FE22 /* next video mode available */ +#define XKB_KEY_XF86Prev_VMode 0x1008FE23 /* prev. video mode available */ +#define XKB_KEY_XF86LogWindowTree 0x1008FE24 /* print window tree to log */ +#define XKB_KEY_XF86LogGrabInfo 0x1008FE25 /* print all active grabs to log */ + + +/* + * Reserved range for evdev symbols: 0x10081000-0x10081FFF + * + * Key syms within this range must match the Linux kernel + * input-event-codes.h file in the format: + * XF86XK_CamelCaseKernelName _EVDEVK(kernel value) + * For example, the kernel + * #define KEY_MACRO_RECORD_START 0x2b0 + * effectively ends up as: + * #define XKB_KEY_XF86MacroRecordStart 0x100812b0 + * + * For historical reasons, some keysyms within the reserved range will be + * missing, most notably all "normal" keys that are mapped through default + * XKB layouts (e.g. KEY_Q). + * + * CamelCasing is done with a human control as last authority, e.g. see VOD + * instead of Vod for the Video on Demand key. + * + * The format for #defines is strict: + * + * #define XKB_KEY_XF86FOO<tab...>_EVDEVK(0xABC)<tab><tab> |* kver KEY_FOO *| + * + * Where + * - alignment by tabs + * - the _EVDEVK macro must be used + * - the hex code must be in uppercase hex + * - the kernel version (kver) is in the form v5.10 + * - kver and key name are within a slash-star comment (a pipe is used in + * this example for technical reasons) + * These #defines are parsed by scripts. Do not stray from the given format. + * + * Where the evdev keycode is mapped to a different symbol, please add a + * comment line starting with Use: but otherwise the same format, e.g. + * Use: XF86XK_RotationLockToggle _EVDEVK(0x231) v4.16 KEY_ROTATE_LOCK_TOGGLE + * + */ +/* Use: XF86XK_Eject _EVDEVK(0x0A2) KEY_EJECTCLOSECD */ +/* Use: XF86XK_New _EVDEVK(0x0B5) v2.6.14 KEY_NEW */ +/* Use: XK_Redo _EVDEVK(0x0B6) v2.6.14 KEY_REDO */ +/* KEY_DASHBOARD has been mapped to LaunchB in xkeyboard-config since 2011 */ +/* Use: XF86XK_LaunchB _EVDEVK(0x0CC) v2.6.28 KEY_DASHBOARD */ +/* Use: XF86XK_Display _EVDEVK(0x0E3) v2.6.12 KEY_SWITCHVIDEOMODE */ +/* Use: XF86XK_KbdLightOnOff _EVDEVK(0x0E4) v2.6.12 KEY_KBDILLUMTOGGLE */ +/* Use: XF86XK_KbdBrightnessDown _EVDEVK(0x0E5) v2.6.12 KEY_KBDILLUMDOWN */ +/* Use: XF86XK_KbdBrightnessUp _EVDEVK(0x0E6) v2.6.12 KEY_KBDILLUMUP */ +/* Use: XF86XK_Send _EVDEVK(0x0E7) v2.6.14 KEY_SEND */ +/* Use: XF86XK_Reply _EVDEVK(0x0E8) v2.6.14 KEY_REPLY */ +/* Use: XF86XK_MailForward _EVDEVK(0x0E9) v2.6.14 KEY_FORWARDMAIL */ +/* Use: XF86XK_Save _EVDEVK(0x0EA) v2.6.14 KEY_SAVE */ +/* Use: XF86XK_Documents _EVDEVK(0x0EB) v2.6.14 KEY_DOCUMENTS */ +/* Use: XF86XK_Battery _EVDEVK(0x0EC) v2.6.17 KEY_BATTERY */ +/* Use: XF86XK_Bluetooth _EVDEVK(0x0ED) v2.6.19 KEY_BLUETOOTH */ +/* Use: XF86XK_WLAN _EVDEVK(0x0EE) v2.6.19 KEY_WLAN */ +/* Use: XF86XK_UWB _EVDEVK(0x0EF) v2.6.24 KEY_UWB */ +/* Use: XF86XK_Next_VMode _EVDEVK(0x0F1) v2.6.23 KEY_VIDEO_NEXT */ +/* Use: XF86XK_Prev_VMode _EVDEVK(0x0F2) v2.6.23 KEY_VIDEO_PREV */ +/* Use: XF86XK_MonBrightnessCycle _EVDEVK(0x0F3) v2.6.23 KEY_BRIGHTNESS_CYCLE */ +#define XKB_KEY_XF86BrightnessAuto 0x100810f4 /* v3.16 KEY_BRIGHTNESS_AUTO */ +#define XKB_KEY_XF86DisplayOff 0x100810f5 /* v2.6.23 KEY_DISPLAY_OFF */ +/* Use: XF86XK_WWAN _EVDEVK(0x0F6) v3.13 KEY_WWAN */ +/* Use: XF86XK_RFKill _EVDEVK(0x0F7) v2.6.33 KEY_RFKILL */ +/* Use: XF86XK_AudioMicMute _EVDEVK(0x0F8) v3.1 KEY_MICMUTE */ +#define XKB_KEY_XF86Info 0x10081166 /* KEY_INFO */ +/* Use: XF86XK_CycleAngle _EVDEVK(0x173) KEY_ANGLE */ +/* Use: XF86XK_FullScreen _EVDEVK(0x174) v5.1 KEY_FULL_SCREEN */ +#define XKB_KEY_XF86AspectRatio 0x10081177 /* v5.1 KEY_ASPECT_RATIO */ +#define XKB_KEY_XF86DVD 0x10081185 /* KEY_DVD */ +#define XKB_KEY_XF86Audio 0x10081188 /* KEY_AUDIO */ +/* Use: XF86XK_Video _EVDEVK(0x189) KEY_VIDEO */ +/* Use: XF86XK_Calendar _EVDEVK(0x18D) KEY_CALENDAR */ +#define XKB_KEY_XF86ChannelUp 0x10081192 /* KEY_CHANNELUP */ +#define XKB_KEY_XF86ChannelDown 0x10081193 /* KEY_CHANNELDOWN */ +/* Use: XF86XK_AudioRandomPlay _EVDEVK(0x19A) KEY_SHUFFLE */ +#define XKB_KEY_XF86Break 0x1008119b /* KEY_BREAK */ +#define XKB_KEY_XF86VideoPhone 0x100811a0 /* v2.6.20 KEY_VIDEOPHONE */ +/* Use: XF86XK_Game _EVDEVK(0x1A1) v2.6.20 KEY_GAMES */ +/* Use: XF86XK_ZoomIn _EVDEVK(0x1A2) v2.6.20 KEY_ZOOMIN */ +/* Use: XF86XK_ZoomOut _EVDEVK(0x1A3) v2.6.20 KEY_ZOOMOUT */ +#define XKB_KEY_XF86ZoomReset 0x100811a4 /* v2.6.20 KEY_ZOOMRESET */ +/* Use: XF86XK_Word _EVDEVK(0x1A5) v2.6.20 KEY_WORDPROCESSOR */ +#define XKB_KEY_XF86Editor 0x100811a6 /* v2.6.20 KEY_EDITOR */ +/* Use: XF86XK_Excel _EVDEVK(0x1A7) v2.6.20 KEY_SPREADSHEET */ +#define XKB_KEY_XF86GraphicsEditor 0x100811a8 /* v2.6.20 KEY_GRAPHICSEDITOR */ +#define XKB_KEY_XF86Presentation 0x100811a9 /* v2.6.20 KEY_PRESENTATION */ +#define XKB_KEY_XF86Database 0x100811aa /* v2.6.20 KEY_DATABASE */ +/* Use: XF86XK_News _EVDEVK(0x1AB) v2.6.20 KEY_NEWS */ +#define XKB_KEY_XF86Voicemail 0x100811ac /* v2.6.20 KEY_VOICEMAIL */ +#define XKB_KEY_XF86Addressbook 0x100811ad /* v2.6.20 KEY_ADDRESSBOOK */ +/* Use: XF86XK_Messenger _EVDEVK(0x1AE) v2.6.20 KEY_MESSENGER */ +#define XKB_KEY_XF86DisplayToggle 0x100811af /* v2.6.20 KEY_DISPLAYTOGGLE */ +#define XKB_KEY_XF86SpellCheck 0x100811b0 /* v2.6.24 KEY_SPELLCHECK */ +/* Use: XF86XK_LogOff _EVDEVK(0x1B1) v2.6.24 KEY_LOGOFF */ +/* Use: XK_dollar _EVDEVK(0x1B2) v2.6.24 KEY_DOLLAR */ +/* Use: XK_EuroSign _EVDEVK(0x1B3) v2.6.24 KEY_EURO */ +/* Use: XF86XK_FrameBack _EVDEVK(0x1B4) v2.6.24 KEY_FRAMEBACK */ +/* Use: XF86XK_FrameForward _EVDEVK(0x1B5) v2.6.24 KEY_FRAMEFORWARD */ +#define XKB_KEY_XF86ContextMenu 0x100811b6 /* v2.6.24 KEY_CONTEXT_MENU */ +#define XKB_KEY_XF86MediaRepeat 0x100811b7 /* v2.6.26 KEY_MEDIA_REPEAT */ +#define XKB_KEY_XF8610ChannelsUp 0x100811b8 /* v2.6.38 KEY_10CHANNELSUP */ +#define XKB_KEY_XF8610ChannelsDown 0x100811b9 /* v2.6.38 KEY_10CHANNELSDOWN */ +#define XKB_KEY_XF86Images 0x100811ba /* v2.6.39 KEY_IMAGES */ +#define XKB_KEY_XF86NotificationCenter 0x100811bc /* v5.10 KEY_NOTIFICATION_CENTER */ +#define XKB_KEY_XF86PickupPhone 0x100811bd /* v5.10 KEY_PICKUP_PHONE */ +#define XKB_KEY_XF86HangupPhone 0x100811be /* v5.10 KEY_HANGUP_PHONE */ +#define XKB_KEY_XF86Fn 0x100811d0 /* KEY_FN */ +#define XKB_KEY_XF86Fn_Esc 0x100811d1 /* KEY_FN_ESC */ +#define XKB_KEY_XF86FnRightShift 0x100811e5 /* v5.10 KEY_FN_RIGHT_SHIFT */ +/* Use: XK_braille_dot_1 _EVDEVK(0x1F1) v2.6.17 KEY_BRL_DOT1 */ +/* Use: XK_braille_dot_2 _EVDEVK(0x1F2) v2.6.17 KEY_BRL_DOT2 */ +/* Use: XK_braille_dot_3 _EVDEVK(0x1F3) v2.6.17 KEY_BRL_DOT3 */ +/* Use: XK_braille_dot_4 _EVDEVK(0x1F4) v2.6.17 KEY_BRL_DOT4 */ +/* Use: XK_braille_dot_5 _EVDEVK(0x1F5) v2.6.17 KEY_BRL_DOT5 */ +/* Use: XK_braille_dot_6 _EVDEVK(0x1F6) v2.6.17 KEY_BRL_DOT6 */ +/* Use: XK_braille_dot_7 _EVDEVK(0x1F7) v2.6.17 KEY_BRL_DOT7 */ +/* Use: XK_braille_dot_8 _EVDEVK(0x1F8) v2.6.17 KEY_BRL_DOT8 */ +/* Use: XK_braille_dot_9 _EVDEVK(0x1F9) v2.6.23 KEY_BRL_DOT9 */ +/* Use: XK_braille_dot_1 _EVDEVK(0x1FA) v2.6.23 KEY_BRL_DOT10 */ +#define XKB_KEY_XF86Numeric0 0x10081200 /* v2.6.28 KEY_NUMERIC_0 */ +#define XKB_KEY_XF86Numeric1 0x10081201 /* v2.6.28 KEY_NUMERIC_1 */ +#define XKB_KEY_XF86Numeric2 0x10081202 /* v2.6.28 KEY_NUMERIC_2 */ +#define XKB_KEY_XF86Numeric3 0x10081203 /* v2.6.28 KEY_NUMERIC_3 */ +#define XKB_KEY_XF86Numeric4 0x10081204 /* v2.6.28 KEY_NUMERIC_4 */ +#define XKB_KEY_XF86Numeric5 0x10081205 /* v2.6.28 KEY_NUMERIC_5 */ +#define XKB_KEY_XF86Numeric6 0x10081206 /* v2.6.28 KEY_NUMERIC_6 */ +#define XKB_KEY_XF86Numeric7 0x10081207 /* v2.6.28 KEY_NUMERIC_7 */ +#define XKB_KEY_XF86Numeric8 0x10081208 /* v2.6.28 KEY_NUMERIC_8 */ +#define XKB_KEY_XF86Numeric9 0x10081209 /* v2.6.28 KEY_NUMERIC_9 */ +#define XKB_KEY_XF86NumericStar 0x1008120a /* v2.6.28 KEY_NUMERIC_STAR */ +#define XKB_KEY_XF86NumericPound 0x1008120b /* v2.6.28 KEY_NUMERIC_POUND */ +#define XKB_KEY_XF86NumericA 0x1008120c /* v4.1 KEY_NUMERIC_A */ +#define XKB_KEY_XF86NumericB 0x1008120d /* v4.1 KEY_NUMERIC_B */ +#define XKB_KEY_XF86NumericC 0x1008120e /* v4.1 KEY_NUMERIC_C */ +#define XKB_KEY_XF86NumericD 0x1008120f /* v4.1 KEY_NUMERIC_D */ +#define XKB_KEY_XF86CameraFocus 0x10081210 /* v2.6.33 KEY_CAMERA_FOCUS */ +#define XKB_KEY_XF86WPSButton 0x10081211 /* v2.6.34 KEY_WPS_BUTTON */ +/* Use: XF86XK_TouchpadToggle _EVDEVK(0x212) v2.6.37 KEY_TOUCHPAD_TOGGLE */ +/* Use: XF86XK_TouchpadOn _EVDEVK(0x213) v2.6.37 KEY_TOUCHPAD_ON */ +/* Use: XF86XK_TouchpadOff _EVDEVK(0x214) v2.6.37 KEY_TOUCHPAD_OFF */ +#define XKB_KEY_XF86CameraZoomIn 0x10081215 /* v2.6.39 KEY_CAMERA_ZOOMIN */ +#define XKB_KEY_XF86CameraZoomOut 0x10081216 /* v2.6.39 KEY_CAMERA_ZOOMOUT */ +#define XKB_KEY_XF86CameraUp 0x10081217 /* v2.6.39 KEY_CAMERA_UP */ +#define XKB_KEY_XF86CameraDown 0x10081218 /* v2.6.39 KEY_CAMERA_DOWN */ +#define XKB_KEY_XF86CameraLeft 0x10081219 /* v2.6.39 KEY_CAMERA_LEFT */ +#define XKB_KEY_XF86CameraRight 0x1008121a /* v2.6.39 KEY_CAMERA_RIGHT */ +#define XKB_KEY_XF86AttendantOn 0x1008121b /* v3.10 KEY_ATTENDANT_ON */ +#define XKB_KEY_XF86AttendantOff 0x1008121c /* v3.10 KEY_ATTENDANT_OFF */ +#define XKB_KEY_XF86AttendantToggle 0x1008121d /* v3.10 KEY_ATTENDANT_TOGGLE */ +#define XKB_KEY_XF86LightsToggle 0x1008121e /* v3.10 KEY_LIGHTS_TOGGLE */ +#define XKB_KEY_XF86ALSToggle 0x10081230 /* v3.13 KEY_ALS_TOGGLE */ +/* Use: XF86XK_RotationLockToggle _EVDEVK(0x231) v4.16 KEY_ROTATE_LOCK_TOGGLE */ +#define XKB_KEY_XF86Buttonconfig 0x10081240 /* v3.16 KEY_BUTTONCONFIG */ +#define XKB_KEY_XF86Taskmanager 0x10081241 /* v3.16 KEY_TASKMANAGER */ +#define XKB_KEY_XF86Journal 0x10081242 /* v3.16 KEY_JOURNAL */ +#define XKB_KEY_XF86ControlPanel 0x10081243 /* v3.16 KEY_CONTROLPANEL */ +#define XKB_KEY_XF86AppSelect 0x10081244 /* v3.16 KEY_APPSELECT */ +#define XKB_KEY_XF86Screensaver 0x10081245 /* v3.16 KEY_SCREENSAVER */ +#define XKB_KEY_XF86VoiceCommand 0x10081246 /* v3.16 KEY_VOICECOMMAND */ +#define XKB_KEY_XF86Assistant 0x10081247 /* v4.13 KEY_ASSISTANT */ +/* Use: XK_ISO_Next_Group _EVDEVK(0x248) v5.2 KEY_KBD_LAYOUT_NEXT */ +#define XKB_KEY_XF86BrightnessMin 0x10081250 /* v3.16 KEY_BRIGHTNESS_MIN */ +#define XKB_KEY_XF86BrightnessMax 0x10081251 /* v3.16 KEY_BRIGHTNESS_MAX */ +#define XKB_KEY_XF86KbdInputAssistPrev 0x10081260 /* v3.18 KEY_KBDINPUTASSIST_PREV */ +#define XKB_KEY_XF86KbdInputAssistNext 0x10081261 /* v3.18 KEY_KBDINPUTASSIST_NEXT */ +#define XKB_KEY_XF86KbdInputAssistPrevgroup 0x10081262 /* v3.18 KEY_KBDINPUTASSIST_PREVGROUP */ +#define XKB_KEY_XF86KbdInputAssistNextgroup 0x10081263 /* v3.18 KEY_KBDINPUTASSIST_NEXTGROUP */ +#define XKB_KEY_XF86KbdInputAssistAccept 0x10081264 /* v3.18 KEY_KBDINPUTASSIST_ACCEPT */ +#define XKB_KEY_XF86KbdInputAssistCancel 0x10081265 /* v3.18 KEY_KBDINPUTASSIST_CANCEL */ +#define XKB_KEY_XF86RightUp 0x10081266 /* v4.7 KEY_RIGHT_UP */ +#define XKB_KEY_XF86RightDown 0x10081267 /* v4.7 KEY_RIGHT_DOWN */ +#define XKB_KEY_XF86LeftUp 0x10081268 /* v4.7 KEY_LEFT_UP */ +#define XKB_KEY_XF86LeftDown 0x10081269 /* v4.7 KEY_LEFT_DOWN */ +#define XKB_KEY_XF86RootMenu 0x1008126a /* v4.7 KEY_ROOT_MENU */ +#define XKB_KEY_XF86MediaTopMenu 0x1008126b /* v4.7 KEY_MEDIA_TOP_MENU */ +#define XKB_KEY_XF86Numeric11 0x1008126c /* v4.7 KEY_NUMERIC_11 */ +#define XKB_KEY_XF86Numeric12 0x1008126d /* v4.7 KEY_NUMERIC_12 */ +#define XKB_KEY_XF86AudioDesc 0x1008126e /* v4.7 KEY_AUDIO_DESC */ +#define XKB_KEY_XF863DMode 0x1008126f /* v4.7 KEY_3D_MODE */ +#define XKB_KEY_XF86NextFavorite 0x10081270 /* v4.7 KEY_NEXT_FAVORITE */ +#define XKB_KEY_XF86StopRecord 0x10081271 /* v4.7 KEY_STOP_RECORD */ +#define XKB_KEY_XF86PauseRecord 0x10081272 /* v4.7 KEY_PAUSE_RECORD */ +#define XKB_KEY_XF86VOD 0x10081273 /* v4.7 KEY_VOD */ +#define XKB_KEY_XF86Unmute 0x10081274 /* v4.7 KEY_UNMUTE */ +#define XKB_KEY_XF86FastReverse 0x10081275 /* v4.7 KEY_FASTREVERSE */ +#define XKB_KEY_XF86SlowReverse 0x10081276 /* v4.7 KEY_SLOWREVERSE */ +#define XKB_KEY_XF86Data 0x10081277 /* v4.7 KEY_DATA */ +#define XKB_KEY_XF86OnScreenKeyboard 0x10081278 /* v4.12 KEY_ONSCREEN_KEYBOARD */ +#define XKB_KEY_XF86PrivacyScreenToggle 0x10081279 /* v5.5 KEY_PRIVACY_SCREEN_TOGGLE */ +#define XKB_KEY_XF86SelectiveScreenshot 0x1008127a /* v5.6 KEY_SELECTIVE_SCREENSHOT */ +#define XKB_KEY_XF86Macro1 0x10081290 /* v5.5 KEY_MACRO1 */ +#define XKB_KEY_XF86Macro2 0x10081291 /* v5.5 KEY_MACRO2 */ +#define XKB_KEY_XF86Macro3 0x10081292 /* v5.5 KEY_MACRO3 */ +#define XKB_KEY_XF86Macro4 0x10081293 /* v5.5 KEY_MACRO4 */ +#define XKB_KEY_XF86Macro5 0x10081294 /* v5.5 KEY_MACRO5 */ +#define XKB_KEY_XF86Macro6 0x10081295 /* v5.5 KEY_MACRO6 */ +#define XKB_KEY_XF86Macro7 0x10081296 /* v5.5 KEY_MACRO7 */ +#define XKB_KEY_XF86Macro8 0x10081297 /* v5.5 KEY_MACRO8 */ +#define XKB_KEY_XF86Macro9 0x10081298 /* v5.5 KEY_MACRO9 */ +#define XKB_KEY_XF86Macro10 0x10081299 /* v5.5 KEY_MACRO10 */ +#define XKB_KEY_XF86Macro11 0x1008129a /* v5.5 KEY_MACRO11 */ +#define XKB_KEY_XF86Macro12 0x1008129b /* v5.5 KEY_MACRO12 */ +#define XKB_KEY_XF86Macro13 0x1008129c /* v5.5 KEY_MACRO13 */ +#define XKB_KEY_XF86Macro14 0x1008129d /* v5.5 KEY_MACRO14 */ +#define XKB_KEY_XF86Macro15 0x1008129e /* v5.5 KEY_MACRO15 */ +#define XKB_KEY_XF86Macro16 0x1008129f /* v5.5 KEY_MACRO16 */ +#define XKB_KEY_XF86Macro17 0x100812a0 /* v5.5 KEY_MACRO17 */ +#define XKB_KEY_XF86Macro18 0x100812a1 /* v5.5 KEY_MACRO18 */ +#define XKB_KEY_XF86Macro19 0x100812a2 /* v5.5 KEY_MACRO19 */ +#define XKB_KEY_XF86Macro20 0x100812a3 /* v5.5 KEY_MACRO20 */ +#define XKB_KEY_XF86Macro21 0x100812a4 /* v5.5 KEY_MACRO21 */ +#define XKB_KEY_XF86Macro22 0x100812a5 /* v5.5 KEY_MACRO22 */ +#define XKB_KEY_XF86Macro23 0x100812a6 /* v5.5 KEY_MACRO23 */ +#define XKB_KEY_XF86Macro24 0x100812a7 /* v5.5 KEY_MACRO24 */ +#define XKB_KEY_XF86Macro25 0x100812a8 /* v5.5 KEY_MACRO25 */ +#define XKB_KEY_XF86Macro26 0x100812a9 /* v5.5 KEY_MACRO26 */ +#define XKB_KEY_XF86Macro27 0x100812aa /* v5.5 KEY_MACRO27 */ +#define XKB_KEY_XF86Macro28 0x100812ab /* v5.5 KEY_MACRO28 */ +#define XKB_KEY_XF86Macro29 0x100812ac /* v5.5 KEY_MACRO29 */ +#define XKB_KEY_XF86Macro30 0x100812ad /* v5.5 KEY_MACRO30 */ +#define XKB_KEY_XF86MacroRecordStart 0x100812b0 /* v5.5 KEY_MACRO_RECORD_START */ +#define XKB_KEY_XF86MacroRecordStop 0x100812b1 /* v5.5 KEY_MACRO_RECORD_STOP */ +#define XKB_KEY_XF86MacroPresetCycle 0x100812b2 /* v5.5 KEY_MACRO_PRESET_CYCLE */ +#define XKB_KEY_XF86MacroPreset1 0x100812b3 /* v5.5 KEY_MACRO_PRESET1 */ +#define XKB_KEY_XF86MacroPreset2 0x100812b4 /* v5.5 KEY_MACRO_PRESET2 */ +#define XKB_KEY_XF86MacroPreset3 0x100812b5 /* v5.5 KEY_MACRO_PRESET3 */ +#define XKB_KEY_XF86KbdLcdMenu1 0x100812b8 /* v5.5 KEY_KBD_LCD_MENU1 */ +#define XKB_KEY_XF86KbdLcdMenu2 0x100812b9 /* v5.5 KEY_KBD_LCD_MENU2 */ +#define XKB_KEY_XF86KbdLcdMenu3 0x100812ba /* v5.5 KEY_KBD_LCD_MENU3 */ +#define XKB_KEY_XF86KbdLcdMenu4 0x100812bb /* v5.5 KEY_KBD_LCD_MENU4 */ +#define XKB_KEY_XF86KbdLcdMenu5 0x100812bc /* v5.5 KEY_KBD_LCD_MENU5 */ +#undef _EVDEVK +/* + * Copyright (c) 1991, Oracle and/or its affiliates. All rights reserved. + * + * 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 (including the next + * paragraph) 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. + */ +/************************************************************ + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +***********************************************************/ + +/* + * Floating Accent + */ + +#define XKB_KEY_SunFA_Grave 0x1005FF00 +#define XKB_KEY_SunFA_Circum 0x1005FF01 +#define XKB_KEY_SunFA_Tilde 0x1005FF02 +#define XKB_KEY_SunFA_Acute 0x1005FF03 +#define XKB_KEY_SunFA_Diaeresis 0x1005FF04 +#define XKB_KEY_SunFA_Cedilla 0x1005FF05 + +/* + * Miscellaneous Functions + */ + +#define XKB_KEY_SunF36 0x1005FF10 /* Labeled F11 */ +#define XKB_KEY_SunF37 0x1005FF11 /* Labeled F12 */ + +#define XKB_KEY_SunSys_Req 0x1005FF60 +#define XKB_KEY_SunPrint_Screen 0x0000FF61 /* Same as XK_Print */ + +/* + * International & Multi-Key Character Composition + */ + +#define XKB_KEY_SunCompose 0x0000FF20 /* Same as XK_Multi_key */ +#define XKB_KEY_SunAltGraph 0x0000FF7E /* Same as XK_Mode_switch */ + +/* + * Cursor Control + */ + +#define XKB_KEY_SunPageUp 0x0000FF55 /* Same as XK_Prior */ +#define XKB_KEY_SunPageDown 0x0000FF56 /* Same as XK_Next */ + +/* + * Open Look Functions + */ + +#define XKB_KEY_SunUndo 0x0000FF65 /* Same as XK_Undo */ +#define XKB_KEY_SunAgain 0x0000FF66 /* Same as XK_Redo */ +#define XKB_KEY_SunFind 0x0000FF68 /* Same as XK_Find */ +#define XKB_KEY_SunStop 0x0000FF69 /* Same as XK_Cancel */ +#define XKB_KEY_SunProps 0x1005FF70 +#define XKB_KEY_SunFront 0x1005FF71 +#define XKB_KEY_SunCopy 0x1005FF72 +#define XKB_KEY_SunOpen 0x1005FF73 +#define XKB_KEY_SunPaste 0x1005FF74 +#define XKB_KEY_SunCut 0x1005FF75 + +#define XKB_KEY_SunPowerSwitch 0x1005FF76 +#define XKB_KEY_SunAudioLowerVolume 0x1005FF77 +#define XKB_KEY_SunAudioMute 0x1005FF78 +#define XKB_KEY_SunAudioRaiseVolume 0x1005FF79 +#define XKB_KEY_SunVideoDegauss 0x1005FF7A +#define XKB_KEY_SunVideoLowerBrightness 0x1005FF7B +#define XKB_KEY_SunVideoRaiseBrightness 0x1005FF7C +#define XKB_KEY_SunPowerSwitchShift 0x1005FF7D +/*********************************************************** + +Copyright 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * DEC private keysyms + * (29th bit set) + */ + +/* two-key compose sequence initiators, chosen to map to Latin1 characters */ + +#define XKB_KEY_Dring_accent 0x1000FEB0 +#define XKB_KEY_Dcircumflex_accent 0x1000FE5E +#define XKB_KEY_Dcedilla_accent 0x1000FE2C +#define XKB_KEY_Dacute_accent 0x1000FE27 +#define XKB_KEY_Dgrave_accent 0x1000FE60 +#define XKB_KEY_Dtilde 0x1000FE7E +#define XKB_KEY_Ddiaeresis 0x1000FE22 + +/* special keysym for LK2** "Remove" key on editing keypad */ + +#define XKB_KEY_DRemove 0x1000FF00 /* Remove */ +/* + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Hewlett Packard +or Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD +TO THIS SOFTWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. Hewlett-Packard shall not be liable for errors +contained herein or direct, indirect, special, incidental or +consequential damages in connection with the furnishing, +performance, or use of this material. + +*/ + + + +#define XKB_KEY_hpClearLine 0x1000FF6F +#define XKB_KEY_hpInsertLine 0x1000FF70 +#define XKB_KEY_hpDeleteLine 0x1000FF71 +#define XKB_KEY_hpInsertChar 0x1000FF72 +#define XKB_KEY_hpDeleteChar 0x1000FF73 +#define XKB_KEY_hpBackTab 0x1000FF74 +#define XKB_KEY_hpKP_BackTab 0x1000FF75 +#define XKB_KEY_hpModelock1 0x1000FF48 +#define XKB_KEY_hpModelock2 0x1000FF49 +#define XKB_KEY_hpReset 0x1000FF6C +#define XKB_KEY_hpSystem 0x1000FF6D +#define XKB_KEY_hpUser 0x1000FF6E +#define XKB_KEY_hpmute_acute 0x100000A8 +#define XKB_KEY_hpmute_grave 0x100000A9 +#define XKB_KEY_hpmute_asciicircum 0x100000AA +#define XKB_KEY_hpmute_diaeresis 0x100000AB +#define XKB_KEY_hpmute_asciitilde 0x100000AC +#define XKB_KEY_hplira 0x100000AF +#define XKB_KEY_hpguilder 0x100000BE +#define XKB_KEY_hpYdiaeresis 0x100000EE +#define XKB_KEY_hpIO 0x100000EE +#define XKB_KEY_hplongminus 0x100000F6 +#define XKB_KEY_hpblock 0x100000FC + + + +#define XKB_KEY_osfCopy 0x1004FF02 +#define XKB_KEY_osfCut 0x1004FF03 +#define XKB_KEY_osfPaste 0x1004FF04 +#define XKB_KEY_osfBackTab 0x1004FF07 +#define XKB_KEY_osfBackSpace 0x1004FF08 +#define XKB_KEY_osfClear 0x1004FF0B +#define XKB_KEY_osfEscape 0x1004FF1B +#define XKB_KEY_osfAddMode 0x1004FF31 +#define XKB_KEY_osfPrimaryPaste 0x1004FF32 +#define XKB_KEY_osfQuickPaste 0x1004FF33 +#define XKB_KEY_osfPageLeft 0x1004FF40 +#define XKB_KEY_osfPageUp 0x1004FF41 +#define XKB_KEY_osfPageDown 0x1004FF42 +#define XKB_KEY_osfPageRight 0x1004FF43 +#define XKB_KEY_osfActivate 0x1004FF44 +#define XKB_KEY_osfMenuBar 0x1004FF45 +#define XKB_KEY_osfLeft 0x1004FF51 +#define XKB_KEY_osfUp 0x1004FF52 +#define XKB_KEY_osfRight 0x1004FF53 +#define XKB_KEY_osfDown 0x1004FF54 +#define XKB_KEY_osfEndLine 0x1004FF57 +#define XKB_KEY_osfBeginLine 0x1004FF58 +#define XKB_KEY_osfEndData 0x1004FF59 +#define XKB_KEY_osfBeginData 0x1004FF5A +#define XKB_KEY_osfPrevMenu 0x1004FF5B +#define XKB_KEY_osfNextMenu 0x1004FF5C +#define XKB_KEY_osfPrevField 0x1004FF5D +#define XKB_KEY_osfNextField 0x1004FF5E +#define XKB_KEY_osfSelect 0x1004FF60 +#define XKB_KEY_osfInsert 0x1004FF63 +#define XKB_KEY_osfUndo 0x1004FF65 +#define XKB_KEY_osfMenu 0x1004FF67 +#define XKB_KEY_osfCancel 0x1004FF69 +#define XKB_KEY_osfHelp 0x1004FF6A +#define XKB_KEY_osfSelectAll 0x1004FF71 +#define XKB_KEY_osfDeselectAll 0x1004FF72 +#define XKB_KEY_osfReselect 0x1004FF73 +#define XKB_KEY_osfExtend 0x1004FF74 +#define XKB_KEY_osfRestore 0x1004FF78 +#define XKB_KEY_osfDelete 0x1004FFFF + + + +/************************************************************** + * The use of the following macros is deprecated. + * They are listed below only for backwards compatibility. + */ +#define XKB_KEY_Reset 0x1000FF6C +#define XKB_KEY_System 0x1000FF6D +#define XKB_KEY_User 0x1000FF6E +#define XKB_KEY_ClearLine 0x1000FF6F +#define XKB_KEY_InsertLine 0x1000FF70 +#define XKB_KEY_DeleteLine 0x1000FF71 +#define XKB_KEY_InsertChar 0x1000FF72 +#define XKB_KEY_DeleteChar 0x1000FF73 +#define XKB_KEY_BackTab 0x1000FF74 +#define XKB_KEY_KP_BackTab 0x1000FF75 +#define XKB_KEY_Ext16bit_L 0x1000FF76 +#define XKB_KEY_Ext16bit_R 0x1000FF77 +#define XKB_KEY_mute_acute 0x100000a8 +#define XKB_KEY_mute_grave 0x100000a9 +#define XKB_KEY_mute_asciicircum 0x100000aa +#define XKB_KEY_mute_diaeresis 0x100000ab +#define XKB_KEY_mute_asciitilde 0x100000ac +#define XKB_KEY_lira 0x100000af +#define XKB_KEY_guilder 0x100000be +#define XKB_KEY_IO 0x100000ee +#define XKB_KEY_longminus 0x100000f6 +#define XKB_KEY_block 0x100000fc + + + +#endif diff --git a/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-names.h b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-names.h new file mode 100644 index 0000000000..ecb551ff10 --- /dev/null +++ b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-names.h @@ -0,0 +1,45 @@ +/* + * Copyright © 2012 Intel Corporation + * + * 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 (including the next + * paragraph) 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. + * + * Author: Daniel Stone <daniel@fooishbar.org> + */ + +#ifndef _XKBCOMMON_NAMES_H +#define _XKBCOMMON_NAMES_H + +/** + * @file + * @brief Predefined names for common modifiers and LEDs. + */ + +#define XKB_MOD_NAME_SHIFT "Shift" +#define XKB_MOD_NAME_CAPS "Lock" +#define XKB_MOD_NAME_CTRL "Control" +#define XKB_MOD_NAME_ALT "Mod1" +#define XKB_MOD_NAME_NUM "Mod2" +#define XKB_MOD_NAME_LOGO "Mod4" + +#define XKB_LED_NAME_CAPS "Caps Lock" +#define XKB_LED_NAME_NUM "Num Lock" +#define XKB_LED_NAME_SCROLL "Scroll Lock" + +#endif diff --git a/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon.h b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon.h new file mode 100644 index 0000000000..f52dcfab24 --- /dev/null +++ b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon.h @@ -0,0 +1,1954 @@ +/* + * Copyright 1985, 1987, 1990, 1998 The Open Group + * Copyright 2008 Dan Nicholson + * + * 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 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. + * + * Except as contained in this notice, the names of the authors or their + * institutions shall not be used in advertising or otherwise to promote the + * sale, use or other dealings in this Software without prior written + * authorization from the authors. + */ + +/************************************************************ + * Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of Silicon Graphics not be + * used in advertising or publicity pertaining to distribution + * of the software without specific prior written permission. + * Silicon Graphics makes no representation about the suitability + * of this software for any purpose. It is provided "as is" + * without any express or implied warranty. + * + * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH + * THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + ********************************************************/ + +/* + * Copyright © 2009-2012 Daniel Stone + * Copyright © 2012 Intel Corporation + * Copyright © 2012 Ran Benita + * + * 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 (including the next + * paragraph) 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. + * + * Author: Daniel Stone <daniel@fooishbar.org> + */ + +#ifndef _XKBCOMMON_H_ +#define _XKBCOMMON_H_ + +#include <stdint.h> +#include <stdio.h> +#include <stdarg.h> + +#include <xkbcommon/xkbcommon-names.h> +#include <xkbcommon/xkbcommon-keysyms.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file + * Main libxkbcommon API. + */ + +/** + * @struct xkb_context + * Opaque top level library context object. + * + * The context contains various general library data and state, like + * logging level and include paths. + * + * Objects are created in a specific context, and multiple contexts may + * coexist simultaneously. Objects from different contexts are completely + * separated and do not share any memory or state. + */ +struct xkb_context; + +/** + * @struct xkb_keymap + * Opaque compiled keymap object. + * + * The keymap object holds all of the static keyboard information obtained + * from compiling XKB files. + * + * A keymap is immutable after it is created (besides reference counts, etc.); + * if you need to change it, you must create a new one. + */ +struct xkb_keymap; + +/** + * @struct xkb_state + * Opaque keyboard state object. + * + * State objects contain the active state of a keyboard (or keyboards), such + * as the currently effective layout and the active modifiers. It acts as a + * simple state machine, wherein key presses and releases are the input, and + * key symbols (keysyms) are the output. + */ +struct xkb_state; + +/** + * A number used to represent a physical key on a keyboard. + * + * A standard PC-compatible keyboard might have 102 keys. An appropriate + * keymap would assign each of them a keycode, by which the user should + * refer to the key throughout the library. + * + * Historically, the X11 protocol, and consequentially the XKB protocol, + * assign only 8 bits for keycodes. This limits the number of different + * keys that can be used simultaneously in a single keymap to 256 + * (disregarding other limitations). This library does not share this limit; + * keycodes beyond 255 ('extended keycodes') are not treated specially. + * Keymaps and applications which are compatible with X11 should not use + * these keycodes. + * + * The values of specific keycodes are determined by the keymap and the + * underlying input system. For example, with an X11-compatible keymap + * and Linux evdev scan codes (see linux/input.h), a fixed offset is used: + * + * The keymap defines a canonical name for each key, plus possible aliases. + * Historically, the XKB protocol restricts these names to at most 4 (ASCII) + * characters, but this library does not share this limit. + * + * @code + * xkb_keycode_t keycode_A = KEY_A + 8; + * @endcode + * + * @sa xkb_keycode_is_legal_ext() xkb_keycode_is_legal_x11() + */ +typedef uint32_t xkb_keycode_t; + +/** + * A number used to represent the symbols generated from a key on a keyboard. + * + * A key, represented by a keycode, may generate different symbols according + * to keyboard state. For example, on a QWERTY keyboard, pressing the key + * labled \<A\> generates the symbol 'a'. If the Shift key is held, it + * generates the symbol 'A'. If a different layout is used, say Greek, + * it generates the symbol 'α'. And so on. + * + * Each such symbol is represented by a keysym. Note that keysyms are + * somewhat more general, in that they can also represent some "function", + * such as "Left" or "Right" for the arrow keys. For more information, + * see: + * https://www.x.org/releases/current/doc/xproto/x11protocol.html#keysym_encoding + * + * Specifically named keysyms can be found in the + * xkbcommon/xkbcommon-keysyms.h header file. Their name does not include + * the XKB_KEY_ prefix. + * + * Besides those, any Unicode/ISO 10646 character in the range U0100 to + * U10FFFF can be represented by a keysym value in the range 0x01000100 to + * 0x0110FFFF. The name of Unicode keysyms is "U<codepoint>", e.g. "UA1B2". + * + * The name of other unnamed keysyms is the hexadecimal representation of + * their value, e.g. "0xabcd1234". + * + * Keysym names are case-sensitive. + */ +typedef uint32_t xkb_keysym_t; + +/** + * Index of a keyboard layout. + * + * The layout index is a state component which detemines which <em>keyboard + * layout</em> is active. These may be different alphabets, different key + * arrangements, etc. + * + * Layout indices are consecutive. The first layout has index 0. + * + * Each layout is not required to have a name, and the names are not + * guaranteed to be unique (though they are usually provided and unique). + * Therefore, it is not safe to use the name as a unique identifier for a + * layout. Layout names are case-sensitive. + * + * Layout names are specified in the layout's definition, for example + * "English (US)". These are different from the (conventionally) short names + * which are used to locate the layout, for example "us" or "us(intl)". These + * names are not present in a compiled keymap. + * + * If the user selects layouts from a list generated from the XKB registry + * (using libxkbregistry or directly), and this metadata is needed later on, it + * is recommended to store it along with the keymap. + * + * Layouts are also called "groups" by XKB. + * + * @sa xkb_keymap_num_layouts() xkb_keymap_num_layouts_for_key() + */ +typedef uint32_t xkb_layout_index_t; +/** A mask of layout indices. */ +typedef uint32_t xkb_layout_mask_t; + +/** + * Index of a shift level. + * + * Any key, in any layout, can have several <em>shift levels</em>. Each + * shift level can assign different keysyms to the key. The shift level + * to use is chosen according to the current keyboard state; for example, + * if no keys are pressed, the first level may be used; if the Left Shift + * key is pressed, the second; if Num Lock is pressed, the third; and + * many such combinations are possible (see xkb_mod_index_t). + * + * Level indices are consecutive. The first level has index 0. + */ +typedef uint32_t xkb_level_index_t; + +/** + * Index of a modifier. + * + * A @e modifier is a state component which changes the way keys are + * interpreted. A keymap defines a set of modifiers, such as Alt, Shift, + * Num Lock or Meta, and specifies which keys may @e activate which + * modifiers (in a many-to-many relationship, i.e. a key can activate + * several modifiers, and a modifier may be activated by several keys. + * Different keymaps do this differently). + * + * When retrieving the keysyms for a key, the active modifier set is + * consulted; this detemines the correct shift level to use within the + * currently active layout (see xkb_level_index_t). + * + * Modifier indices are consecutive. The first modifier has index 0. + * + * Each modifier must have a name, and the names are unique. Therefore, it + * is safe to use the name as a unique identifier for a modifier. The names + * of some common modifiers are provided in the xkbcommon/xkbcommon-names.h + * header file. Modifier names are case-sensitive. + * + * @sa xkb_keymap_num_mods() + */ +typedef uint32_t xkb_mod_index_t; +/** A mask of modifier indices. */ +typedef uint32_t xkb_mod_mask_t; + +/** + * Index of a keyboard LED. + * + * LEDs are logical objects which may be @e active or @e inactive. They + * typically correspond to the lights on the keyboard. Their state is + * determined by the current keyboard state. + * + * LED indices are non-consecutive. The first LED has index 0. + * + * Each LED must have a name, and the names are unique. Therefore, + * it is safe to use the name as a unique identifier for a LED. The names + * of some common LEDs are provided in the xkbcommon/xkbcommon-names.h + * header file. LED names are case-sensitive. + * + * @warning A given keymap may specify an exact index for a given LED. + * Therefore, LED indexing is not necessarily sequential, as opposed to + * modifiers and layouts. This means that when iterating over the LEDs + * in a keymap using e.g. xkb_keymap_num_leds(), some indices might be + * invalid. Given such an index, functions like xkb_keymap_led_get_name() + * will return NULL, and xkb_state_led_index_is_active() will return -1. + * + * LEDs are also called "indicators" by XKB. + * + * @sa xkb_keymap_num_leds() + */ +typedef uint32_t xkb_led_index_t; +/** A mask of LED indices. */ +typedef uint32_t xkb_led_mask_t; + +#define XKB_KEYCODE_INVALID (0xffffffff) +#define XKB_LAYOUT_INVALID (0xffffffff) +#define XKB_LEVEL_INVALID (0xffffffff) +#define XKB_MOD_INVALID (0xffffffff) +#define XKB_LED_INVALID (0xffffffff) + +#define XKB_KEYCODE_MAX (0xffffffff - 1) + +/** + * Test whether a value is a valid extended keycode. + * @sa xkb_keycode_t + **/ +#define xkb_keycode_is_legal_ext(key) (key <= XKB_KEYCODE_MAX) + +/** + * Test whether a value is a valid X11 keycode. + * @sa xkb_keycode_t + */ +#define xkb_keycode_is_legal_x11(key) (key >= 8 && key <= 255) + +/** + * Names to compile a keymap with, also known as RMLVO. + * + * The names are the common configuration values by which a user picks + * a keymap. + * + * If the entire struct is NULL, then each field is taken to be NULL. + * You should prefer passing NULL instead of choosing your own defaults. + */ +struct xkb_rule_names { + /** + * The rules file to use. The rules file describes how to interpret + * the values of the model, layout, variant and options fields. + * + * If NULL or the empty string "", a default value is used. + * If the XKB_DEFAULT_RULES environment variable is set, it is used + * as the default. Otherwise the system default is used. + */ + const char *rules; + /** + * The keyboard model by which to interpret keycodes and LEDs. + * + * If NULL or the empty string "", a default value is used. + * If the XKB_DEFAULT_MODEL environment variable is set, it is used + * as the default. Otherwise the system default is used. + */ + const char *model; + /** + * A comma separated list of layouts (languages) to include in the + * keymap. + * + * If NULL or the empty string "", a default value is used. + * If the XKB_DEFAULT_LAYOUT environment variable is set, it is used + * as the default. Otherwise the system default is used. + */ + const char *layout; + /** + * A comma separated list of variants, one per layout, which may + * modify or augment the respective layout in various ways. + * + * Generally, should either be empty or have the same number of values + * as the number of layouts. You may use empty values as in "intl,,neo". + * + * If NULL or the empty string "", and a default value is also used + * for the layout, a default value is used. Otherwise no variant is + * used. + * If the XKB_DEFAULT_VARIANT environment variable is set, it is used + * as the default. Otherwise the system default is used. + */ + const char *variant; + /** + * A comma separated list of options, through which the user specifies + * non-layout related preferences, like which key combinations are used + * for switching layouts, or which key is the Compose key. + * + * If NULL, a default value is used. If the empty string "", no + * options are used. + * If the XKB_DEFAULT_OPTIONS environment variable is set, it is used + * as the default. Otherwise the system default is used. + */ + const char *options; +}; + +/** + * @defgroup keysyms Keysyms + * Utility functions related to keysyms. + * + * @{ + */ + +/** + * @page keysym-transformations Keysym Transformations + * + * Keysym translation is subject to several "keysym transformations", + * as described in the XKB specification. These are: + * + * - Capitalization transformation. If the Caps Lock modifier is + * active and was not consumed by the translation process, a single + * keysym is transformed to its upper-case form (if applicable). + * Similarly, the UTF-8/UTF-32 string produced is capitalized. + * + * This is described in: + * https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier + * + * - Control transformation. If the Control modifier is active and + * was not consumed by the translation process, the string produced + * is transformed to its matching ASCII control character (if + * applicable). Keysyms are not affected. + * + * This is described in: + * https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier + * + * Each relevant function discusses which transformations it performs. + * + * These transformations are not applicable when a key produces multiple + * keysyms. + */ + + +/** + * Get the name of a keysym. + * + * For a description of how keysyms are named, see @ref xkb_keysym_t. + * + * @param[in] keysym The keysym. + * @param[out] buffer A string buffer to write the name into. + * @param[in] size Size of the buffer. + * + * @warning If the buffer passed is too small, the string is truncated + * (though still NUL-terminated); a size of at least 64 bytes is recommended. + * + * @returns The number of bytes in the name, excluding the NUL byte. If + * the keysym is invalid, returns -1. + * + * You may check if truncation has occurred by comparing the return value + * with the length of buffer, similarly to the snprintf(3) function. + * + * @sa xkb_keysym_t + */ +int +xkb_keysym_get_name(xkb_keysym_t keysym, char *buffer, size_t size); + +/** Flags for xkb_keysym_from_name(). */ +enum xkb_keysym_flags { + /** Do not apply any flags. */ + XKB_KEYSYM_NO_FLAGS = 0, + /** Find keysym by case-insensitive search. */ + XKB_KEYSYM_CASE_INSENSITIVE = (1 << 0) +}; + +/** + * Get a keysym from its name. + * + * @param name The name of a keysym. See remarks in xkb_keysym_get_name(); + * this function will accept any name returned by that function. + * @param flags A set of flags controlling how the search is done. If + * invalid flags are passed, this will fail with XKB_KEY_NoSymbol. + * + * If you use the XKB_KEYSYM_CASE_INSENSITIVE flag and two keysym names + * differ only by case, then the lower-case keysym is returned. For + * instance, for KEY_a and KEY_A, this function would return KEY_a for the + * case-insensitive search. If this functionality is needed, it is + * recommended to first call this function without this flag; and if that + * fails, only then to try with this flag, while possibly warning the user + * he had misspelled the name, and might get wrong results. + * + * Case folding is done according to the C locale; the current locale is not + * consulted. + * + * @returns The keysym. If the name is invalid, returns XKB_KEY_NoSymbol. + * + * @sa xkb_keysym_t + */ +xkb_keysym_t +xkb_keysym_from_name(const char *name, enum xkb_keysym_flags flags); + +/** + * Get the Unicode/UTF-8 representation of a keysym. + * + * @param[in] keysym The keysym. + * @param[out] buffer A buffer to write the UTF-8 string into. + * @param[in] size The size of buffer. Must be at least 7. + * + * @returns The number of bytes written to the buffer (including the + * terminating byte). If the keysym does not have a Unicode + * representation, returns 0. If the buffer is too small, returns -1. + * + * This function does not perform any @ref keysym-transformations. + * Therefore, prefer to use xkb_state_key_get_utf8() if possible. + * + * @sa xkb_state_key_get_utf8() + */ +int +xkb_keysym_to_utf8(xkb_keysym_t keysym, char *buffer, size_t size); + +/** + * Get the Unicode/UTF-32 representation of a keysym. + * + * @returns The Unicode/UTF-32 representation of keysym, which is also + * compatible with UCS-4. If the keysym does not have a Unicode + * representation, returns 0. + * + * This function does not perform any @ref keysym-transformations. + * Therefore, prefer to use xkb_state_key_get_utf32() if possible. + * + * @sa xkb_state_key_get_utf32() + */ +uint32_t +xkb_keysym_to_utf32(xkb_keysym_t keysym); + +/** + * Get the keysym corresponding to a Unicode/UTF-32 codepoint. + * + * @returns The keysym corresponding to the specified Unicode + * codepoint, or XKB_KEY_NoSymbol if there is none. + * + * This function is the inverse of @ref xkb_keysym_to_utf32. In cases + * where a single codepoint corresponds to multiple keysyms, returns + * the keysym with the lowest value. + * + * Unicode codepoints which do not have a special (legacy) keysym + * encoding use a direct encoding scheme. These keysyms don't usually + * have an associated keysym constant (XKB_KEY_*). + * + * For noncharacter Unicode codepoints and codepoints outside of the + * defined Unicode planes this function returns XKB_KEY_NoSymbol. + * + * @sa xkb_keysym_to_utf32() + * @since 1.0.0 + */ +xkb_keysym_t +xkb_utf32_to_keysym(uint32_t ucs); + +/** + * Convert a keysym to its uppercase form. + * + * If there is no such form, the keysym is returned unchanged. + * + * The conversion rules may be incomplete; prefer to work with the Unicode + * representation instead, when possible. + */ +xkb_keysym_t +xkb_keysym_to_upper(xkb_keysym_t ks); + +/** + * Convert a keysym to its lowercase form. + * + * The conversion rules may be incomplete; prefer to work with the Unicode + * representation instead, when possible. + */ +xkb_keysym_t +xkb_keysym_to_lower(xkb_keysym_t ks); + +/** @} */ + +/** + * @defgroup context Library Context + * Creating, destroying and using library contexts. + * + * Every keymap compilation request must have a context associated with + * it. The context keeps around state such as the include path. + * + * @{ + */ + +/** + * @page envvars Environment Variables + * + * The user may set some environment variables which affect the library: + * + * - `XKB_CONFIG_ROOT`, `XKB_CONFIG_EXTRA_PATH`, `XDG_CONFIG_DIR`, `HOME` - see @ref include-path. + * - `XKB_LOG_LEVEL` - see xkb_context_set_log_level(). + * - `XKB_LOG_VERBOSITY` - see xkb_context_set_log_verbosity(). + * - `XKB_DEFAULT_RULES`, `XKB_DEFAULT_MODEL`, `XKB_DEFAULT_LAYOUT`, + * `XKB_DEFAULT_VARIANT`, `XKB_DEFAULT_OPTIONS` - see xkb_rule_names. + */ + +/** Flags for context creation. */ +enum xkb_context_flags { + /** Do not apply any context flags. */ + XKB_CONTEXT_NO_FLAGS = 0, + /** Create this context with an empty include path. */ + XKB_CONTEXT_NO_DEFAULT_INCLUDES = (1 << 0), + /** + * Don't take RMLVO names from the environment. + * @since 0.3.0 + */ + XKB_CONTEXT_NO_ENVIRONMENT_NAMES = (1 << 1) +}; + +/** + * Create a new context. + * + * @param flags Optional flags for the context, or 0. + * + * @returns A new context, or NULL on failure. + * + * @memberof xkb_context + */ +struct xkb_context * +xkb_context_new(enum xkb_context_flags flags); + +/** + * Take a new reference on a context. + * + * @returns The passed in context. + * + * @memberof xkb_context + */ +struct xkb_context * +xkb_context_ref(struct xkb_context *context); + +/** + * Release a reference on a context, and possibly free it. + * + * @param context The context. If it is NULL, this function does nothing. + * + * @memberof xkb_context + */ +void +xkb_context_unref(struct xkb_context *context); + +/** + * Store custom user data in the context. + * + * This may be useful in conjunction with xkb_context_set_log_fn() or other + * callbacks. + * + * @memberof xkb_context + */ +void +xkb_context_set_user_data(struct xkb_context *context, void *user_data); + +/** + * Retrieves stored user data from the context. + * + * @returns The stored user data. If the user data wasn't set, or the + * passed in context is NULL, returns NULL. + * + * This may be useful to access private user data from callbacks like a + * custom logging function. + * + * @memberof xkb_context + **/ +void * +xkb_context_get_user_data(struct xkb_context *context); + +/** @} */ + +/** + * @defgroup include-path Include Paths + * Manipulating the include paths in a context. + * + * The include paths are the file-system paths that are searched when an + * include statement is encountered during keymap compilation. + * + * The default include paths are, in that lookup order: + * - The path `$XDG_CONFIG_HOME/xkb`, with the usual `XDG_CONFIG_HOME` + * fallback to `$HOME/.config/` if unset. + * - The path `$HOME/.xkb`, where $HOME is the value of the environment + * variable `HOME`. + * - The `XKB_CONFIG_EXTRA_PATH` environment variable, if defined, otherwise the + * system configuration directory, defined at library configuration time + * (usually `/etc/xkb`). + * - The `XKB_CONFIG_ROOT` environment variable, if defined, otherwise + * the system XKB root, defined at library configuration time. + * + * @{ + */ + +/** + * Append a new entry to the context's include path. + * + * @returns 1 on success, or 0 if the include path could not be added or is + * inaccessible. + * + * @memberof xkb_context + */ +int +xkb_context_include_path_append(struct xkb_context *context, const char *path); + +/** + * Append the default include paths to the context's include path. + * + * @returns 1 on success, or 0 if the primary include path could not be added. + * + * @memberof xkb_context + */ +int +xkb_context_include_path_append_default(struct xkb_context *context); + +/** + * Reset the context's include path to the default. + * + * Removes all entries from the context's include path, and inserts the + * default paths. + * + * @returns 1 on success, or 0 if the primary include path could not be added. + * + * @memberof xkb_context + */ +int +xkb_context_include_path_reset_defaults(struct xkb_context *context); + +/** + * Remove all entries from the context's include path. + * + * @memberof xkb_context + */ +void +xkb_context_include_path_clear(struct xkb_context *context); + +/** + * Get the number of paths in the context's include path. + * + * @memberof xkb_context + */ +unsigned int +xkb_context_num_include_paths(struct xkb_context *context); + +/** + * Get a specific include path from the context's include path. + * + * @returns The include path at the specified index. If the index is + * invalid, returns NULL. + * + * @memberof xkb_context + */ +const char * +xkb_context_include_path_get(struct xkb_context *context, unsigned int index); + +/** @} */ + +/** + * @defgroup logging Logging Handling + * Manipulating how logging from this library is handled. + * + * @{ + */ + +/** Specifies a logging level. */ +enum xkb_log_level { + XKB_LOG_LEVEL_CRITICAL = 10, /**< Log critical internal errors only. */ + XKB_LOG_LEVEL_ERROR = 20, /**< Log all errors. */ + XKB_LOG_LEVEL_WARNING = 30, /**< Log warnings and errors. */ + XKB_LOG_LEVEL_INFO = 40, /**< Log information, warnings, and errors. */ + XKB_LOG_LEVEL_DEBUG = 50 /**< Log everything. */ +}; + +/** + * Set the current logging level. + * + * @param context The context in which to set the logging level. + * @param level The logging level to use. Only messages from this level + * and below will be logged. + * + * The default level is XKB_LOG_LEVEL_ERROR. The environment variable + * XKB_LOG_LEVEL, if set in the time the context was created, overrides the + * default value. It may be specified as a level number or name. + * + * @memberof xkb_context + */ +void +xkb_context_set_log_level(struct xkb_context *context, + enum xkb_log_level level); + +/** + * Get the current logging level. + * + * @memberof xkb_context + */ +enum xkb_log_level +xkb_context_get_log_level(struct xkb_context *context); + +/** + * Sets the current logging verbosity. + * + * The library can generate a number of warnings which are not helpful to + * ordinary users of the library. The verbosity may be increased if more + * information is desired (e.g. when developing a new keymap). + * + * The default verbosity is 0. The environment variable XKB_LOG_VERBOSITY, + * if set in the time the context was created, overrides the default value. + * + * @param context The context in which to use the set verbosity. + * @param verbosity The verbosity to use. Currently used values are + * 1 to 10, higher values being more verbose. 0 would result in no verbose + * messages being logged. + * + * Most verbose messages are of level XKB_LOG_LEVEL_WARNING or lower. + * + * @memberof xkb_context + */ +void +xkb_context_set_log_verbosity(struct xkb_context *context, int verbosity); + +/** + * Get the current logging verbosity of the context. + * + * @memberof xkb_context + */ +int +xkb_context_get_log_verbosity(struct xkb_context *context); + +/** + * Set a custom function to handle logging messages. + * + * @param context The context in which to use the set logging function. + * @param log_fn The function that will be called for logging messages. + * Passing NULL restores the default function, which logs to stderr. + * + * By default, log messages from this library are printed to stderr. This + * function allows you to replace the default behavior with a custom + * handler. The handler is only called with messages which match the + * current logging level and verbosity settings for the context. + * level is the logging level of the message. @a format and @a args are + * the same as in the vprintf(3) function. + * + * You may use xkb_context_set_user_data() on the context, and then call + * xkb_context_get_user_data() from within the logging function to provide + * it with additional private context. + * + * @memberof xkb_context + */ +void +xkb_context_set_log_fn(struct xkb_context *context, + void (*log_fn)(struct xkb_context *context, + enum xkb_log_level level, + const char *format, va_list args)); + +/** @} */ + +/** + * @defgroup keymap Keymap Creation + * Creating and destroying keymaps. + * + * @{ + */ + +/** Flags for keymap compilation. */ +enum xkb_keymap_compile_flags { + /** Do not apply any flags. */ + XKB_KEYMAP_COMPILE_NO_FLAGS = 0 +}; + +/** + * Create a keymap from RMLVO names. + * + * The primary keymap entry point: creates a new XKB keymap from a set of + * RMLVO (Rules + Model + Layouts + Variants + Options) names. + * + * @param context The context in which to create the keymap. + * @param names The RMLVO names to use. See xkb_rule_names. + * @param flags Optional flags for the keymap, or 0. + * + * @returns A keymap compiled according to the RMLVO names, or NULL if + * the compilation failed. + * + * @sa xkb_rule_names + * @memberof xkb_keymap + */ +struct xkb_keymap * +xkb_keymap_new_from_names(struct xkb_context *context, + const struct xkb_rule_names *names, + enum xkb_keymap_compile_flags flags); + +/** The possible keymap formats. */ +enum xkb_keymap_format { + /** The current/classic XKB text format, as generated by xkbcomp -xkb. */ + XKB_KEYMAP_FORMAT_TEXT_V1 = 1 +}; + +/** + * Create a keymap from a keymap file. + * + * @param context The context in which to create the keymap. + * @param file The keymap file to compile. + * @param format The text format of the keymap file to compile. + * @param flags Optional flags for the keymap, or 0. + * + * @returns A keymap compiled from the given XKB keymap file, or NULL if + * the compilation failed. + * + * The file must contain a complete keymap. For example, in the + * XKB_KEYMAP_FORMAT_TEXT_V1 format, this means the file must contain one + * top level '%xkb_keymap' section, which in turn contains other required + * sections. + * + * @memberof xkb_keymap + */ +struct xkb_keymap * +xkb_keymap_new_from_file(struct xkb_context *context, FILE *file, + enum xkb_keymap_format format, + enum xkb_keymap_compile_flags flags); + +/** + * Create a keymap from a keymap string. + * + * This is just like xkb_keymap_new_from_file(), but instead of a file, gets + * the keymap as one enormous string. + * + * @see xkb_keymap_new_from_file() + * @memberof xkb_keymap + */ +struct xkb_keymap * +xkb_keymap_new_from_string(struct xkb_context *context, const char *string, + enum xkb_keymap_format format, + enum xkb_keymap_compile_flags flags); + +/** + * Create a keymap from a memory buffer. + * + * This is just like xkb_keymap_new_from_string(), but takes a length argument + * so the input string does not have to be zero-terminated. + * + * @see xkb_keymap_new_from_string() + * @memberof xkb_keymap + * @since 0.3.0 + */ +struct xkb_keymap * +xkb_keymap_new_from_buffer(struct xkb_context *context, const char *buffer, + size_t length, enum xkb_keymap_format format, + enum xkb_keymap_compile_flags flags); + +/** + * Take a new reference on a keymap. + * + * @returns The passed in keymap. + * + * @memberof xkb_keymap + */ +struct xkb_keymap * +xkb_keymap_ref(struct xkb_keymap *keymap); + +/** + * Release a reference on a keymap, and possibly free it. + * + * @param keymap The keymap. If it is NULL, this function does nothing. + * + * @memberof xkb_keymap + */ +void +xkb_keymap_unref(struct xkb_keymap *keymap); + +/** + * Get the keymap as a string in the format from which it was created. + * @sa xkb_keymap_get_as_string() + **/ +#define XKB_KEYMAP_USE_ORIGINAL_FORMAT ((enum xkb_keymap_format) -1) + +/** + * Get the compiled keymap as a string. + * + * @param keymap The keymap to get as a string. + * @param format The keymap format to use for the string. You can pass + * in the special value XKB_KEYMAP_USE_ORIGINAL_FORMAT to use the format + * from which the keymap was originally created. + * + * @returns The keymap as a NUL-terminated string, or NULL if unsuccessful. + * + * The returned string may be fed back into xkb_keymap_new_from_string() to get + * the exact same keymap (possibly in another process, etc.). + * + * The returned string is dynamically allocated and should be freed by the + * caller. + * + * @memberof xkb_keymap + */ +char * +xkb_keymap_get_as_string(struct xkb_keymap *keymap, + enum xkb_keymap_format format); + +/** @} */ + +/** + * @defgroup components Keymap Components + * Enumeration of state components in a keymap. + * + * @{ + */ + +/** + * Get the minimum keycode in the keymap. + * + * @sa xkb_keycode_t + * @memberof xkb_keymap + * @since 0.3.1 + */ +xkb_keycode_t +xkb_keymap_min_keycode(struct xkb_keymap *keymap); + +/** + * Get the maximum keycode in the keymap. + * + * @sa xkb_keycode_t + * @memberof xkb_keymap + * @since 0.3.1 + */ +xkb_keycode_t +xkb_keymap_max_keycode(struct xkb_keymap *keymap); + +/** + * The iterator used by xkb_keymap_key_for_each(). + * + * @sa xkb_keymap_key_for_each + * @memberof xkb_keymap + * @since 0.3.1 + */ +typedef void +(*xkb_keymap_key_iter_t)(struct xkb_keymap *keymap, xkb_keycode_t key, + void *data); + +/** + * Run a specified function for every valid keycode in the keymap. If a + * keymap is sparse, this function may be called fewer than + * (max_keycode - min_keycode + 1) times. + * + * @sa xkb_keymap_min_keycode() xkb_keymap_max_keycode() xkb_keycode_t + * @memberof xkb_keymap + * @since 0.3.1 + */ +void +xkb_keymap_key_for_each(struct xkb_keymap *keymap, xkb_keymap_key_iter_t iter, + void *data); + +/** + * Find the name of the key with the given keycode. + * + * This function always returns the canonical name of the key (see + * description in xkb_keycode_t). + * + * @returns The key name. If no key with this keycode exists, + * returns NULL. + * + * @sa xkb_keycode_t + * @memberof xkb_keymap + * @since 0.6.0 + */ +const char * +xkb_keymap_key_get_name(struct xkb_keymap *keymap, xkb_keycode_t key); + +/** + * Find the keycode of the key with the given name. + * + * The name can be either a canonical name or an alias. + * + * @returns The keycode. If no key with this name exists, + * returns XKB_KEYCODE_INVALID. + * + * @sa xkb_keycode_t + * @memberof xkb_keymap + * @since 0.6.0 + */ +xkb_keycode_t +xkb_keymap_key_by_name(struct xkb_keymap *keymap, const char *name); + +/** + * Get the number of modifiers in the keymap. + * + * @sa xkb_mod_index_t + * @memberof xkb_keymap + */ +xkb_mod_index_t +xkb_keymap_num_mods(struct xkb_keymap *keymap); + +/** + * Get the name of a modifier by index. + * + * @returns The name. If the index is invalid, returns NULL. + * + * @sa xkb_mod_index_t + * @memberof xkb_keymap + */ +const char * +xkb_keymap_mod_get_name(struct xkb_keymap *keymap, xkb_mod_index_t idx); + +/** + * Get the index of a modifier by name. + * + * @returns The index. If no modifier with this name exists, returns + * XKB_MOD_INVALID. + * + * @sa xkb_mod_index_t + * @memberof xkb_keymap + */ +xkb_mod_index_t +xkb_keymap_mod_get_index(struct xkb_keymap *keymap, const char *name); + +/** + * Get the number of layouts in the keymap. + * + * @sa xkb_layout_index_t xkb_rule_names xkb_keymap_num_layouts_for_key() + * @memberof xkb_keymap + */ +xkb_layout_index_t +xkb_keymap_num_layouts(struct xkb_keymap *keymap); + +/** + * Get the name of a layout by index. + * + * @returns The name. If the index is invalid, or the layout does not have + * a name, returns NULL. + * + * @sa xkb_layout_index_t + * For notes on layout names. + * @memberof xkb_keymap + */ +const char * +xkb_keymap_layout_get_name(struct xkb_keymap *keymap, xkb_layout_index_t idx); + +/** + * Get the index of a layout by name. + * + * @returns The index. If no layout exists with this name, returns + * XKB_LAYOUT_INVALID. If more than one layout in the keymap has this name, + * returns the lowest index among them. + * + * @sa xkb_layout_index_t + * For notes on layout names. + * @memberof xkb_keymap + */ +xkb_layout_index_t +xkb_keymap_layout_get_index(struct xkb_keymap *keymap, const char *name); + +/** + * Get the number of LEDs in the keymap. + * + * @warning The range [ 0...xkb_keymap_num_leds() ) includes all of the LEDs + * in the keymap, but may also contain inactive LEDs. When iterating over + * this range, you need the handle this case when calling functions such as + * xkb_keymap_led_get_name() or xkb_state_led_index_is_active(). + * + * @sa xkb_led_index_t + * @memberof xkb_keymap + */ +xkb_led_index_t +xkb_keymap_num_leds(struct xkb_keymap *keymap); + +/** + * Get the name of a LED by index. + * + * @returns The name. If the index is invalid, returns NULL. + * + * @memberof xkb_keymap + */ +const char * +xkb_keymap_led_get_name(struct xkb_keymap *keymap, xkb_led_index_t idx); + +/** + * Get the index of a LED by name. + * + * @returns The index. If no LED with this name exists, returns + * XKB_LED_INVALID. + * + * @memberof xkb_keymap + */ +xkb_led_index_t +xkb_keymap_led_get_index(struct xkb_keymap *keymap, const char *name); + +/** + * Get the number of layouts for a specific key. + * + * This number can be different from xkb_keymap_num_layouts(), but is always + * smaller. It is the appropriate value to use when iterating over the + * layouts of a key. + * + * @sa xkb_layout_index_t + * @memberof xkb_keymap + */ +xkb_layout_index_t +xkb_keymap_num_layouts_for_key(struct xkb_keymap *keymap, xkb_keycode_t key); + +/** + * Get the number of shift levels for a specific key and layout. + * + * If @c layout is out of range for this key (that is, larger or equal to + * the value returned by xkb_keymap_num_layouts_for_key()), it is brought + * back into range in a manner consistent with xkb_state_key_get_layout(). + * + * @sa xkb_level_index_t + * @memberof xkb_keymap + */ +xkb_level_index_t +xkb_keymap_num_levels_for_key(struct xkb_keymap *keymap, xkb_keycode_t key, + xkb_layout_index_t layout); + +/** + * Retrieves every possible modifier mask that produces the specified + * shift level for a specific key and layout. + * + * This API is useful for inverse key transformation; i.e. finding out + * which modifiers need to be active in order to be able to type the + * keysym(s) corresponding to the specific key code, layout and level. + * + * @warning It returns only up to masks_size modifier masks. If the + * buffer passed is too small, some of the possible modifier combinations + * will not be returned. + * + * @param[in] keymap The keymap. + * @param[in] key The keycode of the key. + * @param[in] layout The layout for which to get modifiers. + * @param[in] level The shift level in the layout for which to get the + * modifiers. This should be smaller than: + * @code xkb_keymap_num_levels_for_key(keymap, key) @endcode + * @param[out] masks_out A buffer in which the requested masks should be + * stored. + * @param[out] masks_size The size of the buffer pointed to by masks_out. + * + * If @c layout is out of range for this key (that is, larger or equal to + * the value returned by xkb_keymap_num_layouts_for_key()), it is brought + * back into range in a manner consistent with xkb_state_key_get_layout(). + * + * @returns The number of modifier masks stored in the masks_out array. + * If the key is not in the keymap or if the specified shift level cannot + * be reached it returns 0 and does not modify the masks_out buffer. + * + * @sa xkb_level_index_t + * @sa xkb_mod_mask_t + * @memberof xkb_keymap + * @since 1.0.0 + */ +size_t +xkb_keymap_key_get_mods_for_level(struct xkb_keymap *keymap, + xkb_keycode_t key, + xkb_layout_index_t layout, + xkb_level_index_t level, + xkb_mod_mask_t *masks_out, + size_t masks_size); + +/** + * Get the keysyms obtained from pressing a key in a given layout and + * shift level. + * + * This function is like xkb_state_key_get_syms(), only the layout and + * shift level are not derived from the keyboard state but are instead + * specified explicitly. + * + * @param[in] keymap The keymap. + * @param[in] key The keycode of the key. + * @param[in] layout The layout for which to get the keysyms. + * @param[in] level The shift level in the layout for which to get the + * keysyms. This should be smaller than: + * @code xkb_keymap_num_levels_for_key(keymap, key) @endcode + * @param[out] syms_out An immutable array of keysyms corresponding to the + * key in the given layout and shift level. + * + * If @c layout is out of range for this key (that is, larger or equal to + * the value returned by xkb_keymap_num_layouts_for_key()), it is brought + * back into range in a manner consistent with xkb_state_key_get_layout(). + * + * @returns The number of keysyms in the syms_out array. If no keysyms + * are produced by the key in the given layout and shift level, returns 0 + * and sets syms_out to NULL. + * + * @sa xkb_state_key_get_syms() + * @memberof xkb_keymap + */ +int +xkb_keymap_key_get_syms_by_level(struct xkb_keymap *keymap, + xkb_keycode_t key, + xkb_layout_index_t layout, + xkb_level_index_t level, + const xkb_keysym_t **syms_out); + +/** + * Determine whether a key should repeat or not. + * + * A keymap may specify different repeat behaviors for different keys. + * Most keys should generally exhibit repeat behavior; for example, holding + * the 'a' key down in a text editor should normally insert a single 'a' + * character every few milliseconds, until the key is released. However, + * there are keys which should not or do not need to be repeated. For + * example, repeating modifier keys such as Left/Right Shift or Caps Lock + * is not generally useful or desired. + * + * @returns 1 if the key should repeat, 0 otherwise. + * + * @memberof xkb_keymap + */ +int +xkb_keymap_key_repeats(struct xkb_keymap *keymap, xkb_keycode_t key); + +/** @} */ + +/** + * @defgroup state Keyboard State + * Creating, destroying and manipulating keyboard state objects. + * + * @{ + */ + +/** + * Create a new keyboard state object. + * + * @param keymap The keymap which the state will use. + * + * @returns A new keyboard state object, or NULL on failure. + * + * @memberof xkb_state + */ +struct xkb_state * +xkb_state_new(struct xkb_keymap *keymap); + +/** + * Take a new reference on a keyboard state object. + * + * @returns The passed in object. + * + * @memberof xkb_state + */ +struct xkb_state * +xkb_state_ref(struct xkb_state *state); + +/** + * Release a reference on a keybaord state object, and possibly free it. + * + * @param state The state. If it is NULL, this function does nothing. + * + * @memberof xkb_state + */ +void +xkb_state_unref(struct xkb_state *state); + +/** + * Get the keymap which a keyboard state object is using. + * + * @returns The keymap which was passed to xkb_state_new() when creating + * this state object. + * + * This function does not take a new reference on the keymap; you must + * explicitly reference it yourself if you plan to use it beyond the + * lifetime of the state. + * + * @memberof xkb_state + */ +struct xkb_keymap * +xkb_state_get_keymap(struct xkb_state *state); + +/** Specifies the direction of the key (press / release). */ +enum xkb_key_direction { + XKB_KEY_UP, /**< The key was released. */ + XKB_KEY_DOWN /**< The key was pressed. */ +}; + +/** + * Modifier and layout types for state objects. This enum is bitmaskable, + * e.g. (XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED) is valid to + * exclude locked modifiers. + * + * In XKB, the DEPRESSED components are also known as 'base'. + */ +enum xkb_state_component { + /** Depressed modifiers, i.e. a key is physically holding them. */ + XKB_STATE_MODS_DEPRESSED = (1 << 0), + /** Latched modifiers, i.e. will be unset after the next non-modifier + * key press. */ + XKB_STATE_MODS_LATCHED = (1 << 1), + /** Locked modifiers, i.e. will be unset after the key provoking the + * lock has been pressed again. */ + XKB_STATE_MODS_LOCKED = (1 << 2), + /** Effective modifiers, i.e. currently active and affect key + * processing (derived from the other state components). + * Use this unless you explicitly care how the state came about. */ + XKB_STATE_MODS_EFFECTIVE = (1 << 3), + /** Depressed layout, i.e. a key is physically holding it. */ + XKB_STATE_LAYOUT_DEPRESSED = (1 << 4), + /** Latched layout, i.e. will be unset after the next non-modifier + * key press. */ + XKB_STATE_LAYOUT_LATCHED = (1 << 5), + /** Locked layout, i.e. will be unset after the key provoking the lock + * has been pressed again. */ + XKB_STATE_LAYOUT_LOCKED = (1 << 6), + /** Effective layout, i.e. currently active and affects key processing + * (derived from the other state components). + * Use this unless you explicitly care how the state came about. */ + XKB_STATE_LAYOUT_EFFECTIVE = (1 << 7), + /** LEDs (derived from the other state components). */ + XKB_STATE_LEDS = (1 << 8) +}; + +/** + * Update the keyboard state to reflect a given key being pressed or + * released. + * + * This entry point is intended for programs which track the keyboard state + * explicitly (like an evdev client). If the state is serialized to you by + * a master process (like a Wayland compositor) using functions like + * xkb_state_serialize_mods(), you should use xkb_state_update_mask() instead. + * The two functions should not generally be used together. + * + * A series of calls to this function should be consistent; that is, a call + * with XKB_KEY_DOWN for a key should be matched by an XKB_KEY_UP; if a key + * is pressed twice, it should be released twice; etc. Otherwise (e.g. due + * to missed input events), situations like "stuck modifiers" may occur. + * + * This function is often used in conjunction with the function + * xkb_state_key_get_syms() (or xkb_state_key_get_one_sym()), for example, + * when handling a key event. In this case, you should prefer to get the + * keysyms *before* updating the key, such that the keysyms reported for + * the key event are not affected by the event itself. This is the + * conventional behavior. + * + * @returns A mask of state components that have changed as a result of + * the update. If nothing in the state has changed, returns 0. + * + * @memberof xkb_state + * + * @sa xkb_state_update_mask() + */ +enum xkb_state_component +xkb_state_update_key(struct xkb_state *state, xkb_keycode_t key, + enum xkb_key_direction direction); + +/** + * Update a keyboard state from a set of explicit masks. + * + * This entry point is intended for window systems and the like, where a + * master process holds an xkb_state, then serializes it over a wire + * protocol, and clients then use the serialization to feed in to their own + * xkb_state. + * + * All parameters must always be passed, or the resulting state may be + * incoherent. + * + * The serialization is lossy and will not survive round trips; it must only + * be used to feed slave state objects, and must not be used to update the + * master state. + * + * If you do not fit the description above, you should use + * xkb_state_update_key() instead. The two functions should not generally be + * used together. + * + * @returns A mask of state components that have changed as a result of + * the update. If nothing in the state has changed, returns 0. + * + * @memberof xkb_state + * + * @sa xkb_state_component + * @sa xkb_state_update_key + */ +enum xkb_state_component +xkb_state_update_mask(struct xkb_state *state, + xkb_mod_mask_t depressed_mods, + xkb_mod_mask_t latched_mods, + xkb_mod_mask_t locked_mods, + xkb_layout_index_t depressed_layout, + xkb_layout_index_t latched_layout, + xkb_layout_index_t locked_layout); + +/** + * Get the keysyms obtained from pressing a particular key in a given + * keyboard state. + * + * Get the keysyms for a key according to the current active layout, + * modifiers and shift level for the key, as determined by a keyboard + * state. + * + * @param[in] state The keyboard state object. + * @param[in] key The keycode of the key. + * @param[out] syms_out An immutable array of keysyms corresponding the + * key in the given keyboard state. + * + * As an extension to XKB, this function can return more than one keysym. + * If you do not want to handle this case, you can use + * xkb_state_key_get_one_sym() for a simpler interface. + * + * This function does not perform any @ref keysym-transformations. + * (This might change). + * + * @returns The number of keysyms in the syms_out array. If no keysyms + * are produced by the key in the given keyboard state, returns 0 and sets + * syms_out to NULL. + * + * @memberof xkb_state + */ +int +xkb_state_key_get_syms(struct xkb_state *state, xkb_keycode_t key, + const xkb_keysym_t **syms_out); + +/** + * Get the Unicode/UTF-8 string obtained from pressing a particular key + * in a given keyboard state. + * + * @param[in] state The keyboard state object. + * @param[in] key The keycode of the key. + * @param[out] buffer A buffer to write the string into. + * @param[in] size Size of the buffer. + * + * @warning If the buffer passed is too small, the string is truncated + * (though still NUL-terminated). + * + * @returns The number of bytes required for the string, excluding the + * NUL byte. If there is nothing to write, returns 0. + * + * You may check if truncation has occurred by comparing the return value + * with the size of @p buffer, similarly to the snprintf(3) function. + * You may safely pass NULL and 0 to @p buffer and @p size to find the + * required size (without the NUL-byte). + * + * This function performs Capitalization and Control @ref + * keysym-transformations. + * + * @memberof xkb_state + * @since 0.4.1 + */ +int +xkb_state_key_get_utf8(struct xkb_state *state, xkb_keycode_t key, + char *buffer, size_t size); + +/** + * Get the Unicode/UTF-32 codepoint obtained from pressing a particular + * key in a a given keyboard state. + * + * @returns The UTF-32 representation for the key, if it consists of only + * a single codepoint. Otherwise, returns 0. + * + * This function performs Capitalization and Control @ref + * keysym-transformations. + * + * @memberof xkb_state + * @since 0.4.1 + */ +uint32_t +xkb_state_key_get_utf32(struct xkb_state *state, xkb_keycode_t key); + +/** + * Get the single keysym obtained from pressing a particular key in a + * given keyboard state. + * + * This function is similar to xkb_state_key_get_syms(), but intended + * for users which cannot or do not want to handle the case where + * multiple keysyms are returned (in which case this function is + * preferred). + * + * @returns The keysym. If the key does not have exactly one keysym, + * returns XKB_KEY_NoSymbol + * + * This function performs Capitalization @ref keysym-transformations. + * + * @sa xkb_state_key_get_syms() + * @memberof xkb_state + */ +xkb_keysym_t +xkb_state_key_get_one_sym(struct xkb_state *state, xkb_keycode_t key); + +/** + * Get the effective layout index for a key in a given keyboard state. + * + * @returns The layout index for the key in the given keyboard state. If + * the given keycode is invalid, or if the key is not included in any + * layout at all, returns XKB_LAYOUT_INVALID. + * + * @invariant If the returned layout is valid, the following always holds: + * @code + * xkb_state_key_get_layout(state, key) < xkb_keymap_num_layouts_for_key(keymap, key) + * @endcode + * + * @memberof xkb_state + */ +xkb_layout_index_t +xkb_state_key_get_layout(struct xkb_state *state, xkb_keycode_t key); + +/** + * Get the effective shift level for a key in a given keyboard state and + * layout. + * + * @param state The keyboard state. + * @param key The keycode of the key. + * @param layout The layout for which to get the shift level. This must be + * smaller than: + * @code xkb_keymap_num_layouts_for_key(keymap, key) @endcode + * usually it would be: + * @code xkb_state_key_get_layout(state, key) @endcode + * + * @return The shift level index. If the key or layout are invalid, + * returns XKB_LEVEL_INVALID. + * + * @invariant If the returned level is valid, the following always holds: + * @code + * xkb_state_key_get_level(state, key, layout) < xkb_keymap_num_levels_for_key(keymap, key, layout) + * @endcode + * + * @memberof xkb_state + */ +xkb_level_index_t +xkb_state_key_get_level(struct xkb_state *state, xkb_keycode_t key, + xkb_layout_index_t layout); + +/** + * Match flags for xkb_state_mod_indices_are_active() and + * xkb_state_mod_names_are_active(), specifying the conditions for a + * successful match. XKB_STATE_MATCH_NON_EXCLUSIVE is bitmaskable with + * the other modes. + */ +enum xkb_state_match { + /** Returns true if any of the modifiers are active. */ + XKB_STATE_MATCH_ANY = (1 << 0), + /** Returns true if all of the modifiers are active. */ + XKB_STATE_MATCH_ALL = (1 << 1), + /** Makes matching non-exclusive, i.e. will not return false if a + * modifier not specified in the arguments is active. */ + XKB_STATE_MATCH_NON_EXCLUSIVE = (1 << 16) +}; + +/** + * The counterpart to xkb_state_update_mask for modifiers, to be used on + * the server side of serialization. + * + * @param state The keyboard state. + * @param components A mask of the modifier state components to serialize. + * State components other than XKB_STATE_MODS_* are ignored. + * If XKB_STATE_MODS_EFFECTIVE is included, all other state components are + * ignored. + * + * @returns A xkb_mod_mask_t representing the given components of the + * modifier state. + * + * This function should not be used in regular clients; please use the + * xkb_state_mod_*_is_active API instead. + * + * @memberof xkb_state + */ +xkb_mod_mask_t +xkb_state_serialize_mods(struct xkb_state *state, + enum xkb_state_component components); + +/** + * The counterpart to xkb_state_update_mask for layouts, to be used on + * the server side of serialization. + * + * @param state The keyboard state. + * @param components A mask of the layout state components to serialize. + * State components other than XKB_STATE_LAYOUT_* are ignored. + * If XKB_STATE_LAYOUT_EFFECTIVE is included, all other state components are + * ignored. + * + * @returns A layout index representing the given components of the + * layout state. + * + * This function should not be used in regular clients; please use the + * xkb_state_layout_*_is_active API instead. + * + * @memberof xkb_state + */ +xkb_layout_index_t +xkb_state_serialize_layout(struct xkb_state *state, + enum xkb_state_component components); + +/** + * Test whether a modifier is active in a given keyboard state by name. + * + * @returns 1 if the modifier is active, 0 if it is not. If the modifier + * name does not exist in the keymap, returns -1. + * + * @memberof xkb_state + */ +int +xkb_state_mod_name_is_active(struct xkb_state *state, const char *name, + enum xkb_state_component type); + +/** + * Test whether a set of modifiers are active in a given keyboard state by + * name. + * + * @param state The keyboard state. + * @param type The component of the state against which to match the + * given modifiers. + * @param match The manner by which to match the state against the + * given modifiers. + * @param ... The set of of modifier names to test, terminated by a NULL + * argument (sentinel). + * + * @returns 1 if the modifiers are active, 0 if they are not. If any of + * the modifier names do not exist in the keymap, returns -1. + * + * @memberof xkb_state + */ +int +xkb_state_mod_names_are_active(struct xkb_state *state, + enum xkb_state_component type, + enum xkb_state_match match, + ...); + +/** + * Test whether a modifier is active in a given keyboard state by index. + * + * @returns 1 if the modifier is active, 0 if it is not. If the modifier + * index is invalid in the keymap, returns -1. + * + * @memberof xkb_state + */ +int +xkb_state_mod_index_is_active(struct xkb_state *state, xkb_mod_index_t idx, + enum xkb_state_component type); + +/** + * Test whether a set of modifiers are active in a given keyboard state by + * index. + * + * @param state The keyboard state. + * @param type The component of the state against which to match the + * given modifiers. + * @param match The manner by which to match the state against the + * given modifiers. + * @param ... The set of of modifier indices to test, terminated by a + * XKB_MOD_INVALID argument (sentinel). + * + * @returns 1 if the modifiers are active, 0 if they are not. If any of + * the modifier indices are invalid in the keymap, returns -1. + * + * @memberof xkb_state + */ +int +xkb_state_mod_indices_are_active(struct xkb_state *state, + enum xkb_state_component type, + enum xkb_state_match match, + ...); + +/** + * @page consumed-modifiers Consumed Modifiers + * @parblock + * + * Some functions, like xkb_state_key_get_syms(), look at the state of + * the modifiers in the keymap and derive from it the correct shift level + * to use for the key. For example, in a US layout, pressing the key + * labeled \<A\> while the Shift modifier is active, generates the keysym + * 'A'. In this case, the Shift modifier is said to be "consumed". + * However, the Num Lock modifier does not affect this translation at all, + * even if it is active, so it is not consumed by this translation. + * + * It may be desirable for some application to not reuse consumed modifiers + * for further processing, e.g. for hotkeys or keyboard shortcuts. To + * understand why, consider some requirements from a standard shortcut + * mechanism, and how they are implemented: + * + * 1. The shortcut's modifiers must match exactly to the state. For + * example, it is possible to bind separate actions to \<Alt\>\<Tab\> + * and to \<Alt\>\<Shift\>\<Tab\>. Further, if only \<Alt\>\<Tab\> is + * bound to an action, pressing \<Alt\>\<Shift\>\<Tab\> should not + * trigger the shortcut. + * Effectively, this means that the modifiers are compared using the + * equality operator (==). + * + * 2. Only relevant modifiers are considered for the matching. For example, + * Caps Lock and Num Lock should not generally affect the matching, e.g. + * when matching \<Alt\>\<Tab\> against the state, it does not matter + * whether Num Lock is active or not. These relevant, or "significant", + * modifiers usually include Alt, Control, Shift, Super and similar. + * Effectively, this means that non-significant modifiers are masked out, + * before doing the comparison as described above. + * + * 3. The matching must be independent of the layout/keymap. For example, + * the \<Plus\> (+) symbol is found on the first level on some layouts, + * but requires holding Shift on others. If you simply bind the action + * to the \<Plus\> keysym, it would work for the unshifted kind, but + * not for the others, because the match against Shift would fail. If + * you bind the action to \<Shift\>\<Plus\>, only the shifted kind would + * work. So what is needed is to recognize that Shift is used up in the + * translation of the keysym itself, and therefore should not be included + * in the matching. + * Effectively, this means that consumed modifiers (Shift in this example) + * are masked out as well, before doing the comparison. + * + * In summary, this is approximately how the matching would be performed: + * @code + * (keysym == shortcut_keysym) && + * ((state_mods & ~consumed_mods & significant_mods) == shortcut_mods) + * @endcode + * + * @c state_mods are the modifiers reported by + * xkb_state_mod_index_is_active() and similar functions. + * @c consumed_mods are the modifiers reported by + * xkb_state_mod_index_is_consumed() and similar functions. + * @c significant_mods are decided upon by the application/toolkit/user; + * it is up to them to decide whether these are configurable or hard-coded. + * + * @endparblock + */ + +/** + * Consumed modifiers mode. + * + * There are several possible methods for deciding which modifiers are + * consumed and which are not, each applicable for different systems or + * situations. The mode selects the method to use. + * + * Keep in mind that in all methods, the keymap may decide to "preserve" + * a modifier, meaning it is not reported as consumed even if it would + * have otherwise. + */ +enum xkb_consumed_mode { + /** + * This is the mode defined in the XKB specification and used by libX11. + * + * A modifier is consumed if and only if it *may affect* key translation. + * + * For example, if `Control+Alt+<Backspace>` produces some assigned keysym, + * then when pressing just `<Backspace>`, `Control` and `Alt` are consumed, + * even though they are not active, since if they *were* active they would + * have affected key translation. + */ + XKB_CONSUMED_MODE_XKB, + /** + * This is the mode used by the GTK+ toolkit. + * + * The mode consists of the following two independent heuristics: + * + * - The currently active set of modifiers, excluding modifiers which do + * not affect the key (as described for @ref XKB_CONSUMED_MODE_XKB), are + * considered consumed, if the keysyms produced when all of them are + * active are different from the keysyms produced when no modifiers are + * active. + * + * - A single modifier is considered consumed if the keysyms produced for + * the key when it is the only active modifier are different from the + * keysyms produced when no modifiers are active. + */ + XKB_CONSUMED_MODE_GTK +}; + +/** + * Get the mask of modifiers consumed by translating a given key. + * + * @param state The keyboard state. + * @param key The keycode of the key. + * @param mode The consumed modifiers mode to use; see enum description. + * + * @returns a mask of the consumed modifiers. + * + * @memberof xkb_state + * @since 0.7.0 + */ +xkb_mod_mask_t +xkb_state_key_get_consumed_mods2(struct xkb_state *state, xkb_keycode_t key, + enum xkb_consumed_mode mode); + +/** + * Same as xkb_state_key_get_consumed_mods2() with mode XKB_CONSUMED_MODE_XKB. + * + * @memberof xkb_state + * @since 0.4.1 + */ +xkb_mod_mask_t +xkb_state_key_get_consumed_mods(struct xkb_state *state, xkb_keycode_t key); + +/** + * Test whether a modifier is consumed by keyboard state translation for + * a key. + * + * @param state The keyboard state. + * @param key The keycode of the key. + * @param idx The index of the modifier to check. + * @param mode The consumed modifiers mode to use; see enum description. + * + * @returns 1 if the modifier is consumed, 0 if it is not. If the modifier + * index is not valid in the keymap, returns -1. + * + * @sa xkb_state_mod_mask_remove_consumed() + * @sa xkb_state_key_get_consumed_mods() + * @memberof xkb_state + * @since 0.7.0 + */ +int +xkb_state_mod_index_is_consumed2(struct xkb_state *state, + xkb_keycode_t key, + xkb_mod_index_t idx, + enum xkb_consumed_mode mode); + +/** + * Same as xkb_state_mod_index_is_consumed2() with mode XKB_CONSUMED_MOD_XKB. + * + * @memberof xkb_state + * @since 0.4.1 + */ +int +xkb_state_mod_index_is_consumed(struct xkb_state *state, xkb_keycode_t key, + xkb_mod_index_t idx); + +/** + * Remove consumed modifiers from a modifier mask for a key. + * + * @deprecated Use xkb_state_key_get_consumed_mods2() instead. + * + * Takes the given modifier mask, and removes all modifiers which are + * consumed for that particular key (as in xkb_state_mod_index_is_consumed()). + * + * @sa xkb_state_mod_index_is_consumed() + * @memberof xkb_state + */ +xkb_mod_mask_t +xkb_state_mod_mask_remove_consumed(struct xkb_state *state, xkb_keycode_t key, + xkb_mod_mask_t mask); + +/** + * Test whether a layout is active in a given keyboard state by name. + * + * @returns 1 if the layout is active, 0 if it is not. If no layout with + * this name exists in the keymap, return -1. + * + * If multiple layouts in the keymap have this name, the one with the lowest + * index is tested. + * + * @sa xkb_layout_index_t + * @memberof xkb_state + */ +int +xkb_state_layout_name_is_active(struct xkb_state *state, const char *name, + enum xkb_state_component type); + +/** + * Test whether a layout is active in a given keyboard state by index. + * + * @returns 1 if the layout is active, 0 if it is not. If the layout index + * is not valid in the keymap, returns -1. + * + * @sa xkb_layout_index_t + * @memberof xkb_state + */ +int +xkb_state_layout_index_is_active(struct xkb_state *state, + xkb_layout_index_t idx, + enum xkb_state_component type); + +/** + * Test whether a LED is active in a given keyboard state by name. + * + * @returns 1 if the LED is active, 0 if it not. If no LED with this name + * exists in the keymap, returns -1. + * + * @sa xkb_led_index_t + * @memberof xkb_state + */ +int +xkb_state_led_name_is_active(struct xkb_state *state, const char *name); + +/** + * Test whether a LED is active in a given keyboard state by index. + * + * @returns 1 if the LED is active, 0 if it not. If the LED index is not + * valid in the keymap, returns -1. + * + * @sa xkb_led_index_t + * @memberof xkb_state + */ +int +xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx); + +/** @} */ + +/* Leave this include last, so it can pick up our types, etc. */ +#include <xkbcommon/xkbcommon-compat.h> + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* _XKBCOMMON_H_ */ diff --git a/thirdparty/mbedtls/include/mbedtls/asn1write.h b/thirdparty/mbedtls/include/mbedtls/asn1write.h index 44afae0e56..5da7654bb4 100644 --- a/thirdparty/mbedtls/include/mbedtls/asn1write.h +++ b/thirdparty/mbedtls/include/mbedtls/asn1write.h @@ -90,7 +90,7 @@ int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start, #if defined(MBEDTLS_BIGNUM_C) /** - * \brief Write a arbitrary-precision number (#MBEDTLS_ASN1_INTEGER) + * \brief Write an arbitrary-precision number (#MBEDTLS_ASN1_INTEGER) * in ASN.1 format. * * \note This function works backwards in data buffer. diff --git a/thirdparty/mbedtls/include/mbedtls/bignum.h b/thirdparty/mbedtls/include/mbedtls/bignum.h index dd594c512d..c61db82c6d 100644 --- a/thirdparty/mbedtls/include/mbedtls/bignum.h +++ b/thirdparty/mbedtls/include/mbedtls/bignum.h @@ -182,6 +182,20 @@ #endif /* !MBEDTLS_NO_UDBL_DIVISION */ #endif /* !MBEDTLS_HAVE_INT64 */ +/** \typedef mbedtls_mpi_uint + * \brief The type of machine digits in a bignum, called _limbs_. + * + * This is always an unsigned integer type with no padding bits. The size + * is platform-dependent. + */ + +/** \typedef mbedtls_mpi_sint + * \brief The signed type corresponding to #mbedtls_mpi_uint. + * + * This is always a signed integer type with no padding bits. The size + * is platform-dependent. + */ + #ifdef __cplusplus extern "C" { #endif @@ -191,9 +205,27 @@ extern "C" { */ typedef struct mbedtls_mpi { - int s; /*!< Sign: -1 if the mpi is negative, 1 otherwise */ - size_t n; /*!< total # of limbs */ - mbedtls_mpi_uint *p; /*!< pointer to limbs */ + /** Sign: -1 if the mpi is negative, 1 otherwise. + * + * The number 0 must be represented with `s = +1`. Although many library + * functions treat all-limbs-zero as equivalent to a valid representation + * of 0 regardless of the sign bit, there are exceptions, so bignum + * functions and external callers must always set \c s to +1 for the + * number zero. + * + * Note that this implies that calloc() or `... = {0}` does not create + * a valid MPI representation. You must call mbedtls_mpi_init(). + */ + int s; + + /** Total number of limbs in \c p. */ + size_t n; + + /** Pointer to limbs. + * + * This may be \c NULL if \c n is 0. + */ + mbedtls_mpi_uint *p; } mbedtls_mpi; @@ -280,7 +312,7 @@ void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y ); * \param Y The MPI to be assigned from. This must point to an * initialized MPI. * \param assign The condition deciding whether to perform the - * assignment or not. Possible values: + * assignment or not. Must be either 0 or 1: * * \c 1: Perform the assignment `X = Y`. * * \c 0: Keep the original value of \p X. * @@ -291,6 +323,10 @@ void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y ); * information through branch prediction and/or memory access * patterns analysis). * + * \warning If \p assign is neither 0 nor 1, the result of this function + * is indeterminate, and the resulting value in \p X might be + * neither its original value nor the value in \p Y. + * * \return \c 0 if successful. * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. * \return Another negative error code on other kinds of failure. @@ -303,24 +339,28 @@ int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned * * \param X The first MPI. This must be initialized. * \param Y The second MPI. This must be initialized. - * \param assign The condition deciding whether to perform - * the swap or not. Possible values: + * \param swap The condition deciding whether to perform + * the swap or not. Must be either 0 or 1: * * \c 1: Swap the values of \p X and \p Y. * * \c 0: Keep the original values of \p X and \p Y. * * \note This function is equivalent to - * if( assign ) mbedtls_mpi_swap( X, Y ); + * if( swap ) mbedtls_mpi_swap( X, Y ); * except that it avoids leaking any information about whether - * the assignment was done or not (the above code may leak + * the swap was done or not (the above code may leak * information through branch prediction and/or memory access * patterns analysis). * + * \warning If \p swap is neither 0 nor 1, the result of this function + * is indeterminate, and both \p X and \p Y might end up with + * values different to either of the original ones. + * * \return \c 0 if successful. * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. * \return Another negative error code on other kinds of failure. * */ -int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char assign ); +int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap ); /** * \brief Store integer value in MPI. @@ -753,11 +793,11 @@ int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, * * \param Q The destination MPI for the quotient. * This may be \c NULL if the value of the - * quotient is not needed. + * quotient is not needed. This must not alias A or B. * \param R The destination MPI for the remainder value. * This may be \c NULL if the value of the - * remainder is not needed. - * \param A The dividend. This must point to an initialized MPi. + * remainder is not needed. This must not alias A or B. + * \param A The dividend. This must point to an initialized MPI. * \param B The divisor. This must point to an initialized MPI. * * \return \c 0 if successful. @@ -774,10 +814,10 @@ int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, * * \param Q The destination MPI for the quotient. * This may be \c NULL if the value of the - * quotient is not needed. + * quotient is not needed. This must not alias A. * \param R The destination MPI for the remainder value. * This may be \c NULL if the value of the - * remainder is not needed. + * remainder is not needed. This must not alias A. * \param A The dividend. This must point to an initialized MPi. * \param b The divisor. * @@ -832,6 +872,7 @@ int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, * \brief Perform a sliding-window exponentiation: X = A^E mod N * * \param X The destination MPI. This must point to an initialized MPI. + * This must not alias E or N. * \param A The base of the exponentiation. * This must point to an initialized MPI. * \param E The exponent MPI. This must point to an initialized MPI. diff --git a/thirdparty/mbedtls/include/mbedtls/bn_mul.h b/thirdparty/mbedtls/include/mbedtls/bn_mul.h index 31137cd4c2..a3fc363815 100644 --- a/thirdparty/mbedtls/include/mbedtls/bn_mul.h +++ b/thirdparty/mbedtls/include/mbedtls/bn_mul.h @@ -95,12 +95,28 @@ ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) /* + * GCC < 5.0 treated the x86 ebx (which is used for the GOT) as a + * fixed reserved register when building as PIC, leading to errors + * like: bn_mul.h:46:13: error: PIC register clobbered by 'ebx' in 'asm' + * + * This is fixed by an improved register allocator in GCC 5+. From the + * release notes: + * Register allocation improvements: Reuse of the PIC hard register, + * instead of using a fixed register, was implemented on x86/x86-64 + * targets. This improves generated PIC code performance as more hard + * registers can be used. + */ +#if defined(__GNUC__) && __GNUC__ < 5 && defined(__PIC__) +#define MULADDC_CANNOT_USE_EBX +#endif + +/* * Disable use of the i386 assembly code below if option -O0, to disable all * compiler optimisations, is passed, detected with __OPTIMIZE__ * This is done as the number of registers used in the assembly code doesn't * work with the -O0 option. */ -#if defined(__i386__) && defined(__OPTIMIZE__) +#if defined(__i386__) && defined(__OPTIMIZE__) && !defined(MULADDC_CANNOT_USE_EBX) #define MULADDC_INIT \ asm( \ @@ -563,10 +579,20 @@ "andi r7, r6, 0xffff \n\t" \ "bsrli r6, r6, 16 \n\t" -#define MULADDC_CORE \ +#if(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#define MULADDC_LHUI \ + "lhui r9, r3, 0 \n\t" \ + "addi r3, r3, 2 \n\t" \ + "lhui r8, r3, 0 \n\t" +#else +#define MULADDC_LHUI \ "lhui r8, r3, 0 \n\t" \ "addi r3, r3, 2 \n\t" \ - "lhui r9, r3, 0 \n\t" \ + "lhui r9, r3, 0 \n\t" +#endif + +#define MULADDC_CORE \ + MULADDC_LHUI \ "addi r3, r3, 2 \n\t" \ "mul r10, r9, r6 \n\t" \ "mul r11, r8, r7 \n\t" \ diff --git a/thirdparty/mbedtls/include/mbedtls/check_config.h b/thirdparty/mbedtls/include/mbedtls/check_config.h index be5c548e56..7ae1ff94db 100644 --- a/thirdparty/mbedtls/include/mbedtls/check_config.h +++ b/thirdparty/mbedtls/include/mbedtls/check_config.h @@ -525,6 +525,20 @@ #error "MBEDTLS_PLATFORM_SNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_SNPRINTF/MBEDTLS_PLATFORM_SNPRINTF_ALT cannot be defined simultaneously" #endif +#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_VSNPRINTF_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_VSNPRINTF_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_VSNPRINTF) ||\ + defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) ) +#error "MBEDTLS_PLATFORM_VSNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_VSNPRINTF/MBEDTLS_PLATFORM_VSNPRINTF_ALT cannot be defined simultaneously" +#endif + #if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) &&\ !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) #error "MBEDTLS_PLATFORM_STD_MEM_HDR defined, but not all prerequisites" @@ -650,10 +664,9 @@ MBEDTLS_ECDSA_C requires MBEDTLS_PK_WRITE_C to be defined." #endif -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V15) && \ - !defined(MBEDTLS_PK_WRITE_C) && defined(MBEDTLS_PSA_CRYPTO_C) -#error "MBEDTLS_PSA_CRYPTO_C, MBEDTLS_RSA_C and MBEDTLS_PKCS1_V15 defined, \ - but not all prerequisites" +#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_RSA_C) && \ + !( defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_PK_WRITE_C) ) +#error "MBEDTLS_PSA_CRYPTO_C with MBEDTLS_RSA_C requires MBEDTLS_PK_PARSE_C and MBEDTLS_PK_WRITE_C" #endif #if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ @@ -812,6 +825,11 @@ #error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites" #endif +#if defined(MBEDTLS_SSL_TICKET_C) && \ + !( defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C) ) +#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites" +#endif + #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) && \ !defined(MBEDTLS_SSL_PROTO_SSL3) && !defined(MBEDTLS_SSL_PROTO_TLS1) #error "MBEDTLS_SSL_CBC_RECORD_SPLITTING defined, but not all prerequisites" @@ -926,6 +944,10 @@ #error "MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH defined, but not all prerequisites" #endif +#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) && !( defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C) ) +#error "MBEDTLS_SSL_CONTEXT_SERIALIZATION defined, but not all prerequisites" +#endif + /* * Avoid warning from -pedantic. This is a convenient place for this * workaround since this is included by every single file before the diff --git a/thirdparty/mbedtls/include/mbedtls/config.h b/thirdparty/mbedtls/include/mbedtls/config.h index 1cd6eb6634..61db79362f 100644 --- a/thirdparty/mbedtls/include/mbedtls/config.h +++ b/thirdparty/mbedtls/include/mbedtls/config.h @@ -1329,7 +1329,7 @@ * Include backtrace information with each allocated block. * * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C - * GLIBC-compatible backtrace() an backtrace_symbols() support + * GLIBC-compatible backtrace() and backtrace_symbols() support * * Uncomment this macro to include backtrace information */ @@ -1620,6 +1620,8 @@ * saved after the handshake to allow for more efficient serialization, so if * you don't need this feature you'll save RAM by disabling it. * + * Requires: MBEDTLS_GCM_C or MBEDTLS_CCM_C or MBEDTLS_CHACHAPOLY_C + * * Comment to disable the context serialization APIs. */ #define MBEDTLS_SSL_CONTEXT_SERIALIZATION @@ -2425,7 +2427,7 @@ * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA * * \warning ARC4 is considered a weak cipher and its use constitutes a - * security risk. If possible, we recommend avoidng dependencies on + * security risk. If possible, we recommend avoiding dependencies on * it, and considering stronger ciphers instead. * */ @@ -3030,7 +3032,7 @@ * * \note See also our Knowledge Base article about porting to a new * environment: - * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS + * https://mbed-tls.readthedocs.io/en/latest/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS * * Module: library/net_sockets.c * @@ -3400,7 +3402,8 @@ * Module: library/ssl_ticket.c * Caller: * - * Requires: MBEDTLS_CIPHER_C + * Requires: MBEDTLS_CIPHER_C && + * ( MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C ) */ #define MBEDTLS_SSL_TICKET_C @@ -3456,7 +3459,7 @@ * contexts are not shared between threads. If you do intend to use contexts * between threads, you will need to enable this layer to prevent race * conditions. See also our Knowledge Base article about threading: - * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading + * https://mbed-tls.readthedocs.io/en/latest/kb/development/thread-safety-and-multi-threading * * Module: library/threading.c * @@ -3488,7 +3491,7 @@ * * \note See also our Knowledge Base article about porting to a new * environment: - * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS + * https://mbed-tls.readthedocs.io/en/latest/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS * * Module: library/timing.c * Caller: library/havege.c diff --git a/thirdparty/mbedtls/include/mbedtls/ecdsa.h b/thirdparty/mbedtls/include/mbedtls/ecdsa.h index 264a638bb5..118f7cedb1 100644 --- a/thirdparty/mbedtls/include/mbedtls/ecdsa.h +++ b/thirdparty/mbedtls/include/mbedtls/ecdsa.h @@ -309,10 +309,8 @@ int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r, * This must be initialized. * * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the signature - * is invalid. * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX - * error code on failure for any other reason. + * error code on failure. */ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, const unsigned char *buf, size_t blen, diff --git a/thirdparty/mbedtls/include/mbedtls/md.h b/thirdparty/mbedtls/include/mbedtls/md.h index 84fafd2ac7..9cea40a89c 100644 --- a/thirdparty/mbedtls/include/mbedtls/md.h +++ b/thirdparty/mbedtls/include/mbedtls/md.h @@ -215,7 +215,7 @@ MBEDTLS_CHECK_RETURN_TYPICAL int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ); /** - * \brief This function clones the state of an message-digest + * \brief This function clones the state of a message-digest * context. * * \note You must call mbedtls_md_setup() on \c dst before calling diff --git a/thirdparty/mbedtls/include/mbedtls/platform.h b/thirdparty/mbedtls/include/mbedtls/platform.h index 06dd192eab..eaf5122bec 100644 --- a/thirdparty/mbedtls/include/mbedtls/platform.h +++ b/thirdparty/mbedtls/include/mbedtls/platform.h @@ -11,6 +11,13 @@ * implementations of these functions, or implementations specific to * their platform, which can be statically linked to the library or * dynamically configured at runtime. + * + * When all compilation options related to platform abstraction are + * disabled, this header just defines `mbedtls_xxx` function names + * as aliases to the standard `xxx` function. + * + * Most modules in the library and example programs are expected to + * include this header. */ /* * Copyright The Mbed TLS Contributors diff --git a/thirdparty/mbedtls/include/mbedtls/ripemd160.h b/thirdparty/mbedtls/include/mbedtls/ripemd160.h index 63270d1239..f890aefaee 100644 --- a/thirdparty/mbedtls/include/mbedtls/ripemd160.h +++ b/thirdparty/mbedtls/include/mbedtls/ripemd160.h @@ -74,7 +74,7 @@ void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx ); void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx ); /** - * \brief Clone (the state of) an RIPEMD-160 context + * \brief Clone (the state of) a RIPEMD-160 context * * \param dst The destination context * \param src The context to be cloned diff --git a/thirdparty/mbedtls/include/mbedtls/rsa.h b/thirdparty/mbedtls/include/mbedtls/rsa.h index 062df73aa0..8559f67bb9 100644 --- a/thirdparty/mbedtls/include/mbedtls/rsa.h +++ b/thirdparty/mbedtls/include/mbedtls/rsa.h @@ -491,7 +491,7 @@ int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx ); * the current function does not have access to them, * and therefore cannot check them. See mbedtls_rsa_complete(). * If you want to check the consistency of the entire - * content of an PKCS1-encoded RSA private key, for example, you + * content of a PKCS1-encoded RSA private key, for example, you * should use mbedtls_rsa_validate_params() before setting * up the RSA context. * Additionally, if the implementation performs empirical checks, diff --git a/thirdparty/mbedtls/include/mbedtls/ssl.h b/thirdparty/mbedtls/include/mbedtls/ssl.h index 5064ec5689..aecac93f33 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl.h @@ -624,7 +624,7 @@ typedef int mbedtls_ssl_recv_t( void *ctx, * \param ctx Context for the receive callback (typically a file descriptor) * \param buf Buffer to write the received data to * \param len Length of the receive buffer - * \param timeout Maximum nomber of millisecondes to wait for data + * \param timeout Maximum number of milliseconds to wait for data * 0 means no timeout (potentially waiting forever) * * \return The callback must return the number of bytes received, @@ -652,7 +652,7 @@ typedef int mbedtls_ssl_recv_timeout_t( void *ctx, * for the associated \c mbedtls_ssl_get_timer_t callback to * return correct information. * - * \note If using a event-driven style of programming, an event must + * \note If using an event-driven style of programming, an event must * be generated when the final delay is passed. The event must * cause a call to \c mbedtls_ssl_handshake() with the proper * SSL context to be scheduled. Care must be taken to ensure @@ -2000,7 +2000,7 @@ int mbedtls_ssl_check_record( mbedtls_ssl_context const *ssl, * here, except if using an event-driven style. * * \note See also the "DTLS tutorial" article in our knowledge base. - * https://tls.mbed.org/kb/how-to/dtls-tutorial + * https://mbed-tls.readthedocs.io/en/latest/kb/how-to/dtls-tutorial */ void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl, void *p_timer, diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_internal.h b/thirdparty/mbedtls/include/mbedtls/ssl_internal.h index 46ade67b9c..77ad755477 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl_internal.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl_internal.h @@ -782,7 +782,7 @@ struct mbedtls_ssl_transform #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) uint8_t in_cid_len; uint8_t out_cid_len; - unsigned char in_cid [ MBEDTLS_SSL_CID_OUT_LEN_MAX ]; + unsigned char in_cid [ MBEDTLS_SSL_CID_IN_LEN_MAX ]; unsigned char out_cid[ MBEDTLS_SSL_CID_OUT_LEN_MAX ]; #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ diff --git a/thirdparty/mbedtls/include/mbedtls/version.h b/thirdparty/mbedtls/include/mbedtls/version.h index 44adcbfe03..b3b441d46b 100644 --- a/thirdparty/mbedtls/include/mbedtls/version.h +++ b/thirdparty/mbedtls/include/mbedtls/version.h @@ -38,16 +38,16 @@ */ #define MBEDTLS_VERSION_MAJOR 2 #define MBEDTLS_VERSION_MINOR 28 -#define MBEDTLS_VERSION_PATCH 1 +#define MBEDTLS_VERSION_PATCH 2 /** * The single version number has the following structure: * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x021C0100 -#define MBEDTLS_VERSION_STRING "2.28.1" -#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.28.1" +#define MBEDTLS_VERSION_NUMBER 0x021C0200 +#define MBEDTLS_VERSION_STRING "2.28.2" +#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.28.2" #if defined(MBEDTLS_VERSION_C) diff --git a/thirdparty/mbedtls/library/aes.c b/thirdparty/mbedtls/library/aes.c index 03d8b7ea61..74ea2672b0 100644 --- a/thirdparty/mbedtls/library/aes.c +++ b/thirdparty/mbedtls/library/aes.c @@ -40,14 +40,7 @@ #include "mbedtls/aesni.h" #endif -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ #if !defined(MBEDTLS_AES_ALT) @@ -1170,7 +1163,7 @@ int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, { /* We are on the last block in a decrypt operation that has * leftover bytes, so we need to use the next tweak for this block, - * and this tweak for the lefover bytes. Save the current tweak for + * and this tweak for the leftover bytes. Save the current tweak for * the leftovers and then update the current tweak for use on this, * the last full block. */ memcpy( prev_tweak, tweak, sizeof( tweak ) ); @@ -1770,7 +1763,8 @@ int mbedtls_aes_self_test( int verbose ) unsigned char key[32]; unsigned char buf[64]; const unsigned char *aes_tests; -#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) +#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \ + defined(MBEDTLS_CIPHER_MODE_OFB) unsigned char iv[16]; #endif #if defined(MBEDTLS_CIPHER_MODE_CBC) diff --git a/thirdparty/mbedtls/library/arc4.c b/thirdparty/mbedtls/library/arc4.c index b34dc5e754..dcc13d539a 100644 --- a/thirdparty/mbedtls/library/arc4.c +++ b/thirdparty/mbedtls/library/arc4.c @@ -31,14 +31,7 @@ #include <string.h> -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ #if !defined(MBEDTLS_ARC4_ALT) diff --git a/thirdparty/mbedtls/library/aria.c b/thirdparty/mbedtls/library/aria.c index bc05c4a319..5e52eea91e 100644 --- a/thirdparty/mbedtls/library/aria.c +++ b/thirdparty/mbedtls/library/aria.c @@ -31,24 +31,12 @@ #include <string.h> -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ #if !defined(MBEDTLS_ARIA_ALT) #include "mbedtls/platform_util.h" -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - /* Parameter validation macros */ #define ARIA_VALIDATE_RET( cond ) \ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ) @@ -895,15 +883,17 @@ static const uint8_t aria_test2_ctr_ct[3][48] = // CTR ciphertext }; #endif /* MBEDTLS_CIPHER_MODE_CFB */ -#define ARIA_SELF_TEST_IF_FAIL \ - { \ - if( verbose ) \ - mbedtls_printf( "failed\n" ); \ - goto exit; \ - } else { \ - if( verbose ) \ - mbedtls_printf( "passed\n" ); \ - } +#define ARIA_SELF_TEST_ASSERT( cond ) \ + do { \ + if( cond ) { \ + if( verbose ) \ + mbedtls_printf( "failed\n" ); \ + goto exit; \ + } else { \ + if( verbose ) \ + mbedtls_printf( "passed\n" ); \ + } \ + } while( 0 ) /* * Checkup routine @@ -937,16 +927,18 @@ int mbedtls_aria_self_test( int verbose ) mbedtls_printf( " ARIA-ECB-%d (enc): ", 128 + 64 * i ); mbedtls_aria_setkey_enc( &ctx, aria_test1_ecb_key, 128 + 64 * i ); mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_pt, blk ); - if( memcmp( blk, aria_test1_ecb_ct[i], MBEDTLS_ARIA_BLOCKSIZE ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; + ARIA_SELF_TEST_ASSERT( + memcmp( blk, aria_test1_ecb_ct[i], MBEDTLS_ARIA_BLOCKSIZE ) + != 0 ); /* test ECB decryption */ if( verbose ) mbedtls_printf( " ARIA-ECB-%d (dec): ", 128 + 64 * i ); mbedtls_aria_setkey_dec( &ctx, aria_test1_ecb_key, 128 + 64 * i ); mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_ct[i], blk ); - if( memcmp( blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; + ARIA_SELF_TEST_ASSERT( + memcmp( blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE ) + != 0 ); } if( verbose ) mbedtls_printf( "\n" ); @@ -965,8 +957,8 @@ int mbedtls_aria_self_test( int verbose ) memset( buf, 0x55, sizeof( buf ) ); mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, iv, aria_test2_pt, buf ); - if( memcmp( buf, aria_test2_cbc_ct[i], 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; + ARIA_SELF_TEST_ASSERT( memcmp( buf, aria_test2_cbc_ct[i], 48 ) + != 0 ); /* Test CBC decryption */ if( verbose ) @@ -976,8 +968,7 @@ int mbedtls_aria_self_test( int verbose ) memset( buf, 0xAA, sizeof( buf ) ); mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_DECRYPT, 48, iv, aria_test2_cbc_ct[i], buf ); - if( memcmp( buf, aria_test2_pt, 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; + ARIA_SELF_TEST_ASSERT( memcmp( buf, aria_test2_pt, 48 ) != 0 ); } if( verbose ) mbedtls_printf( "\n" ); @@ -996,8 +987,7 @@ int mbedtls_aria_self_test( int verbose ) j = 0; mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, &j, iv, aria_test2_pt, buf ); - if( memcmp( buf, aria_test2_cfb_ct[i], 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; + ARIA_SELF_TEST_ASSERT( memcmp( buf, aria_test2_cfb_ct[i], 48 ) != 0 ); /* Test CFB decryption */ if( verbose ) @@ -1008,8 +998,7 @@ int mbedtls_aria_self_test( int verbose ) j = 0; mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_DECRYPT, 48, &j, iv, aria_test2_cfb_ct[i], buf ); - if( memcmp( buf, aria_test2_pt, 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; + ARIA_SELF_TEST_ASSERT( memcmp( buf, aria_test2_pt, 48 ) != 0 ); } if( verbose ) mbedtls_printf( "\n" ); @@ -1027,8 +1016,7 @@ int mbedtls_aria_self_test( int verbose ) j = 0; mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk, aria_test2_pt, buf ); - if( memcmp( buf, aria_test2_ctr_ct[i], 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; + ARIA_SELF_TEST_ASSERT( memcmp( buf, aria_test2_ctr_ct[i], 48 ) != 0 ); /* Test CTR decryption */ if( verbose ) @@ -1039,8 +1027,7 @@ int mbedtls_aria_self_test( int verbose ) j = 0; mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk, aria_test2_ctr_ct[i], buf ); - if( memcmp( buf, aria_test2_pt, 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; + ARIA_SELF_TEST_ASSERT( memcmp( buf, aria_test2_pt, 48 ) != 0 ); } if( verbose ) mbedtls_printf( "\n" ); diff --git a/thirdparty/mbedtls/library/asn1parse.c b/thirdparty/mbedtls/library/asn1parse.c index 22747d3ba4..bf97585289 100644 --- a/thirdparty/mbedtls/library/asn1parse.c +++ b/thirdparty/mbedtls/library/asn1parse.c @@ -31,13 +31,7 @@ #include "mbedtls/bignum.h" #endif -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif /* * ASN.1 DER decoding routines diff --git a/thirdparty/mbedtls/library/asn1write.c b/thirdparty/mbedtls/library/asn1write.c index afa26a6be9..4b59927cbb 100644 --- a/thirdparty/mbedtls/library/asn1write.c +++ b/thirdparty/mbedtls/library/asn1write.c @@ -26,13 +26,7 @@ #include <string.h> -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len ) { @@ -78,9 +72,11 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len return( 4 ); } + int len_is_valid = 1; #if SIZE_MAX > 0xFFFFFFFF - if( len <= 0xFFFFFFFF ) + len_is_valid = ( len <= 0xFFFFFFFF ); #endif + if( len_is_valid ) { if( *p - start < 5 ) return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); @@ -93,9 +89,7 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len return( 5 ); } -#if SIZE_MAX > 0xFFFFFFFF return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); -#endif } int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag ) diff --git a/thirdparty/mbedtls/library/base64.c b/thirdparty/mbedtls/library/base64.c index 83daa0bcc6..9021a041bb 100644 --- a/thirdparty/mbedtls/library/base64.c +++ b/thirdparty/mbedtls/library/base64.c @@ -28,12 +28,7 @@ #if defined(MBEDTLS_SELF_TEST) #include <string.h> -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_SELF_TEST */ #define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */ diff --git a/thirdparty/mbedtls/library/bignum.c b/thirdparty/mbedtls/library/bignum.c index 32578e2c68..37193f55a8 100644 --- a/thirdparty/mbedtls/library/bignum.c +++ b/thirdparty/mbedtls/library/bignum.c @@ -46,15 +46,7 @@ #include <limits.h> #include <string.h> -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#include <stdlib.h> -#define mbedtls_printf printf -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif #define MPI_VALIDATE_RET( cond ) \ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA ) @@ -270,6 +262,17 @@ void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y ) memcpy( Y, &T, sizeof( mbedtls_mpi ) ); } +static inline mbedtls_mpi_uint mpi_sint_abs( mbedtls_mpi_sint z ) +{ + if( z >= 0 ) + return( z ); + /* Take care to handle the most negative value (-2^(biL-1)) correctly. + * A naive -z would have undefined behavior. + * Write this in a way that makes popular compilers happy (GCC, Clang, + * MSVC). */ + return( (mbedtls_mpi_uint) 0 - (mbedtls_mpi_uint) z ); +} + /* * Set value from integer */ @@ -281,7 +284,7 @@ int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z ) MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) ); memset( X->p, 0, X->n * ciL ); - X->p[0] = ( z < 0 ) ? -z : z; + X->p[0] = mpi_sint_abs( z ); X->s = ( z < 0 ) ? -1 : 1; cleanup: @@ -1101,7 +1104,7 @@ int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z ) mbedtls_mpi_uint p[1]; MPI_VALIDATE_RET( X != NULL ); - *p = ( z < 0 ) ? -z : z; + *p = mpi_sint_abs( z ); Y.s = ( z < 0 ) ? -1 : 1; Y.n = 1; Y.p = p; @@ -1138,6 +1141,11 @@ int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi if( B->p[j - 1] != 0 ) break; + /* Exit early to avoid undefined behavior on NULL+0 when X->n == 0 + * and B is 0 (of any size). */ + if( j == 0 ) + return( 0 ); + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) ); o = B->p; p = X->p; c = 0; @@ -1257,10 +1265,12 @@ cleanup: return( ret ); } -/* - * Signed addition: X = A + B +/* Common function for signed addition and subtraction. + * Calculate A + B * flip_B where flip_B is 1 or -1. */ -int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) +static int add_sub_mpi( mbedtls_mpi *X, + const mbedtls_mpi *A, const mbedtls_mpi *B, + int flip_B ) { int ret, s; MPI_VALIDATE_RET( X != NULL ); @@ -1268,16 +1278,21 @@ int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi MPI_VALIDATE_RET( B != NULL ); s = A->s; - if( A->s * B->s < 0 ) + if( A->s * B->s * flip_B < 0 ) { - if( mbedtls_mpi_cmp_abs( A, B ) >= 0 ) + int cmp = mbedtls_mpi_cmp_abs( A, B ); + if( cmp >= 0 ) { MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) ); - X->s = s; + /* If |A| = |B|, the result is 0 and we must set the sign bit + * to +1 regardless of which of A or B was negative. Otherwise, + * since |A| > |B|, the sign is the sign of A. */ + X->s = cmp == 0 ? 1 : s; } else { MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) ); + /* Since |A| < |B|, the sign is the opposite of A. */ X->s = -s; } } @@ -1293,38 +1308,19 @@ cleanup: } /* + * Signed addition: X = A + B + */ +int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) +{ + return( add_sub_mpi( X, A, B, 1 ) ); +} + +/* * Signed subtraction: X = A - B */ int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) { - int ret, s; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); - - s = A->s; - if( A->s * B->s > 0 ) - { - if( mbedtls_mpi_cmp_abs( A, B ) >= 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) ); - X->s = s; - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) ); - X->s = -s; - } - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) ); - X->s = s; - } - -cleanup: - - return( ret ); + return( add_sub_mpi( X, A, B, -1 ) ); } /* @@ -1337,7 +1333,7 @@ int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint MPI_VALIDATE_RET( X != NULL ); MPI_VALIDATE_RET( A != NULL ); - p[0] = ( b < 0 ) ? -b : b; + p[0] = mpi_sint_abs( b ); B.s = ( b < 0 ) ? -1 : 1; B.n = 1; B.p = p; @@ -1355,7 +1351,7 @@ int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint MPI_VALIDATE_RET( X != NULL ); MPI_VALIDATE_RET( A != NULL ); - p[0] = ( b < 0 ) ? -b : b; + p[0] = mpi_sint_abs( b ); B.s = ( b < 0 ) ? -1 : 1; B.n = 1; B.p = p; @@ -1776,7 +1772,7 @@ int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, mbedtls_mpi_uint p[1]; MPI_VALIDATE_RET( A != NULL ); - p[0] = ( b < 0 ) ? -b : b; + p[0] = mpi_sint_abs( b ); B.s = ( b < 0 ) ? -1 : 1; B.n = 1; B.p = p; @@ -2009,11 +2005,11 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi *prec_RR ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t wbits, wsize, one = 1; + size_t window_bitsize; size_t i, j, nblimbs; size_t bufsize, nbits; mbedtls_mpi_uint ei, mm, state; - mbedtls_mpi RR, T, W[ 1 << MBEDTLS_MPI_WINDOW_SIZE ], WW, Apos; + mbedtls_mpi RR, T, W[ (size_t) 1 << MBEDTLS_MPI_WINDOW_SIZE ], WW, Apos; int neg; MPI_VALIDATE_RET( X != NULL ); @@ -2042,21 +2038,59 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, i = mbedtls_mpi_bitlen( E ); - wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 : + window_bitsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 : ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1; #if( MBEDTLS_MPI_WINDOW_SIZE < 6 ) - if( wsize > MBEDTLS_MPI_WINDOW_SIZE ) - wsize = MBEDTLS_MPI_WINDOW_SIZE; + if( window_bitsize > MBEDTLS_MPI_WINDOW_SIZE ) + window_bitsize = MBEDTLS_MPI_WINDOW_SIZE; #endif + const size_t w_table_used_size = (size_t) 1 << window_bitsize; + + /* + * This function is not constant-trace: its memory accesses depend on the + * exponent value. To defend against timing attacks, callers (such as RSA + * and DHM) should use exponent blinding. However this is not enough if the + * adversary can find the exponent in a single trace, so this function + * takes extra precautions against adversaries who can observe memory + * access patterns. + * + * This function performs a series of multiplications by table elements and + * squarings, and we want the prevent the adversary from finding out which + * table element was used, and from distinguishing between multiplications + * and squarings. Firstly, when multiplying by an element of the window + * W[i], we do a constant-trace table lookup to obfuscate i. This leaves + * squarings as having a different memory access patterns from other + * multiplications. So secondly, we put the accumulator X in the table as + * well, and also do a constant-trace table lookup to multiply by X. + * + * This way, all multiplications take the form of a lookup-and-multiply. + * The number of lookup-and-multiply operations inside each iteration of + * the main loop still depends on the bits of the exponent, but since the + * other operations in the loop don't have an easily recognizable memory + * trace, an adversary is unlikely to be able to observe the exact + * patterns. + * + * An adversary may still be able to recover the exponent if they can + * observe both memory accesses and branches. However, branch prediction + * exploitation typically requires many traces of execution over the same + * data, which is defeated by randomized blinding. + * + * To achieve this, we make a copy of X and we use the table entry in each + * calculation from this point on. + */ + const size_t x_index = 0; + mbedtls_mpi_init( &W[x_index] ); + mbedtls_mpi_copy( &W[x_index], X ); + j = N->n + 1; /* All W[i] and X must have at least N->n limbs for the mpi_montmul() * and mpi_montred() calls later. Here we ensure that W[1] and X are * large enough, and later we'll grow other W[i] to the same length. * They must not be shrunk midway through this function! */ - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[x_index], j ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], j ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) ); @@ -2105,28 +2139,36 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, mpi_montmul( &W[1], &RR, N, mm, &T ); /* - * X = R^2 * R^-1 mod N = R mod N + * W[x_index] = R^2 * R^-1 mod N = R mod N */ - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) ); - mpi_montred( X, N, mm, &T ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[x_index], &RR ) ); + mpi_montred( &W[x_index], N, mm, &T ); + - if( wsize > 1 ) + if( window_bitsize > 1 ) { /* - * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1) + * W[i] = W[1] ^ i + * + * The first bit of the sliding window is always 1 and therefore we + * only need to store the second half of the table. + * + * (There are two special elements in the table: W[0] for the + * accumulator/result and W[1] for A in Montgomery form. Both of these + * are already set at this point.) */ - j = one << ( wsize - 1 ); + j = w_table_used_size / 2; MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[j], N->n + 1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1] ) ); - for( i = 0; i < wsize - 1; i++ ) + for( i = 0; i < window_bitsize - 1; i++ ) mpi_montmul( &W[j], &W[j], N, mm, &T ); /* * W[i] = W[i - 1] * W[1] */ - for( i = j + 1; i < ( one << wsize ); i++ ) + for( i = j + 1; i < w_table_used_size; i++ ) { MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) ); @@ -2138,7 +2180,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, nblimbs = E->n; bufsize = 0; nbits = 0; - wbits = 0; + size_t exponent_bits_in_window = 0; state = 0; while( 1 ) @@ -2166,9 +2208,10 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, if( ei == 0 && state == 1 ) { /* - * out of window, square X + * out of window, square W[x_index] */ - mpi_montmul( X, X, N, mm, &T ); + MBEDTLS_MPI_CHK( mpi_select( &WW, W, w_table_used_size, x_index ) ); + mpi_montmul( &W[x_index], &WW, N, mm, &T ); continue; } @@ -2178,25 +2221,30 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, state = 2; nbits++; - wbits |= ( ei << ( wsize - nbits ) ); + exponent_bits_in_window |= ( ei << ( window_bitsize - nbits ) ); - if( nbits == wsize ) + if( nbits == window_bitsize ) { /* - * X = X^wsize R^-1 mod N + * W[x_index] = W[x_index]^window_bitsize R^-1 mod N */ - for( i = 0; i < wsize; i++ ) - mpi_montmul( X, X, N, mm, &T ); + for( i = 0; i < window_bitsize; i++ ) + { + MBEDTLS_MPI_CHK( mpi_select( &WW, W, w_table_used_size, + x_index ) ); + mpi_montmul( &W[x_index], &WW, N, mm, &T ); + } /* - * X = X * W[wbits] R^-1 mod N + * W[x_index] = W[x_index] * W[exponent_bits_in_window] R^-1 mod N */ - MBEDTLS_MPI_CHK( mpi_select( &WW, W, (size_t) 1 << wsize, wbits ) ); - mpi_montmul( X, &WW, N, mm, &T ); + MBEDTLS_MPI_CHK( mpi_select( &WW, W, w_table_used_size, + exponent_bits_in_window ) ); + mpi_montmul( &W[x_index], &WW, N, mm, &T ); state--; nbits = 0; - wbits = 0; + exponent_bits_in_window = 0; } } @@ -2205,31 +2253,45 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, */ for( i = 0; i < nbits; i++ ) { - mpi_montmul( X, X, N, mm, &T ); + MBEDTLS_MPI_CHK( mpi_select( &WW, W, w_table_used_size, x_index ) ); + mpi_montmul( &W[x_index], &WW, N, mm, &T ); - wbits <<= 1; + exponent_bits_in_window <<= 1; - if( ( wbits & ( one << wsize ) ) != 0 ) - mpi_montmul( X, &W[1], N, mm, &T ); + if( ( exponent_bits_in_window & ( (size_t) 1 << window_bitsize ) ) != 0 ) + { + MBEDTLS_MPI_CHK( mpi_select( &WW, W, w_table_used_size, 1 ) ); + mpi_montmul( &W[x_index], &WW, N, mm, &T ); + } } /* - * X = A^E * R * R^-1 mod N = A^E mod N + * W[x_index] = A^E * R * R^-1 mod N = A^E mod N */ - mpi_montred( X, N, mm, &T ); + mpi_montred( &W[x_index], N, mm, &T ); if( neg && E->n != 0 && ( E->p[0] & 1 ) != 0 ) { - X->s = -1; - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, N, X ) ); + W[x_index].s = -1; + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &W[x_index], N, &W[x_index] ) ); } + /* + * Load the result in the output variable. + */ + mbedtls_mpi_copy( X, &W[x_index] ); + cleanup: - for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ ) + /* The first bit of the sliding window is always 1 and therefore the first + * half of the table was unused. */ + for( i = w_table_used_size/2; i < w_table_used_size; i++ ) mbedtls_mpi_free( &W[i] ); - mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos ); + mbedtls_mpi_free( &W[x_index] ); + mbedtls_mpi_free( &W[1] ); + mbedtls_mpi_free( &T ); + mbedtls_mpi_free( &Apos ); mbedtls_mpi_free( &WW ); if( prec_RR == NULL || prec_RR->p == NULL ) @@ -2862,7 +2924,7 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags, else { /* - * An necessary condition for Y and X = 2Y + 1 to be prime + * A necessary condition for Y and X = 2Y + 1 to be prime * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3). * Make sure it is satisfied, while keeping X = 3 mod 4 */ diff --git a/thirdparty/mbedtls/library/camellia.c b/thirdparty/mbedtls/library/camellia.c index 29d730ab53..e90cd7f134 100644 --- a/thirdparty/mbedtls/library/camellia.c +++ b/thirdparty/mbedtls/library/camellia.c @@ -32,14 +32,7 @@ #include <string.h> -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ #if !defined(MBEDTLS_CAMELLIA_ALT) diff --git a/thirdparty/mbedtls/library/ccm.c b/thirdparty/mbedtls/library/ccm.c index a21a37f55f..e0d43334f9 100644 --- a/thirdparty/mbedtls/library/ccm.c +++ b/thirdparty/mbedtls/library/ccm.c @@ -36,14 +36,7 @@ #include <string.h> -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ #if !defined(MBEDTLS_CCM_ALT) diff --git a/thirdparty/mbedtls/library/chacha20.c b/thirdparty/mbedtls/library/chacha20.c index 658f046901..bd0701482c 100644 --- a/thirdparty/mbedtls/library/chacha20.c +++ b/thirdparty/mbedtls/library/chacha20.c @@ -32,22 +32,10 @@ #include <stddef.h> #include <string.h> -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ #if !defined(MBEDTLS_CHACHA20_ALT) -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - /* Parameter validation macros */ #define CHACHA20_VALIDATE_RET( cond ) \ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ) diff --git a/thirdparty/mbedtls/library/chachapoly.c b/thirdparty/mbedtls/library/chachapoly.c index dc75b2030a..4adf846857 100644 --- a/thirdparty/mbedtls/library/chachapoly.c +++ b/thirdparty/mbedtls/library/chachapoly.c @@ -28,14 +28,7 @@ #include <string.h> -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ #if !defined(MBEDTLS_CHACHAPOLY_ALT) diff --git a/thirdparty/mbedtls/library/cipher.c b/thirdparty/mbedtls/library/cipher.c index f3b4bd29ce..67e3274587 100644 --- a/thirdparty/mbedtls/library/cipher.c +++ b/thirdparty/mbedtls/library/cipher.c @@ -63,12 +63,7 @@ #include "mbedtls/nist_kw.h" #endif -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif #define CIPHER_VALIDATE_RET( cond ) \ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ) diff --git a/thirdparty/mbedtls/library/cipher_wrap.c b/thirdparty/mbedtls/library/cipher_wrap.c index 57eb3cb67f..c76bdcc0f8 100644 --- a/thirdparty/mbedtls/library/cipher_wrap.c +++ b/thirdparty/mbedtls/library/cipher_wrap.c @@ -76,13 +76,7 @@ #include <string.h> #endif -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif #if defined(MBEDTLS_GCM_C) /* shared by all GCM ciphers */ diff --git a/thirdparty/mbedtls/library/common.h b/thirdparty/mbedtls/library/common.h index c06472418d..1663d50226 100644 --- a/thirdparty/mbedtls/library/common.h +++ b/thirdparty/mbedtls/library/common.h @@ -29,8 +29,15 @@ #include "mbedtls/config.h" #endif +#include <stddef.h> #include <stdint.h> +/* Define `inline` on some non-C99-compliant compilers. */ +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + /** Helper to define a function as static except when building invasive tests. * * If a function is only used inside its own source file and should be @@ -52,6 +59,44 @@ #define MBEDTLS_STATIC_TESTABLE static #endif +/** Return an offset into a buffer. + * + * This is just the addition of an offset to a pointer, except that this + * function also accepts an offset of 0 into a buffer whose pointer is null. + * (`p + n` has undefined behavior when `p` is null, even when `n == 0`. + * A null pointer is a valid buffer pointer when the size is 0, for example + * as the result of `malloc(0)` on some platforms.) + * + * \param p Pointer to a buffer of at least n bytes. + * This may be \p NULL if \p n is zero. + * \param n An offset in bytes. + * \return Pointer to offset \p n in the buffer \p p. + * Note that this is only a valid pointer if the size of the + * buffer is at least \p n + 1. + */ +static inline unsigned char *mbedtls_buffer_offset( + unsigned char *p, size_t n ) +{ + return( p == NULL ? NULL : p + n ); +} + +/** Return an offset into a read-only buffer. + * + * Similar to mbedtls_buffer_offset(), but for const pointers. + * + * \param p Pointer to a buffer of at least n bytes. + * This may be \p NULL if \p n is zero. + * \param n An offset in bytes. + * \return Pointer to offset \p n in the buffer \p p. + * Note that this is only a valid pointer if the size of the + * buffer is at least \p n + 1. + */ +static inline const unsigned char *mbedtls_buffer_offset_const( + const unsigned char *p, size_t n ) +{ + return( p == NULL ? NULL : p + n ); +} + /** Byte Reading Macros * * Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th diff --git a/thirdparty/mbedtls/library/constant_time.c b/thirdparty/mbedtls/library/constant_time.c index e276d23ca0..2401b0434a 100644 --- a/thirdparty/mbedtls/library/constant_time.c +++ b/thirdparty/mbedtls/library/constant_time.c @@ -81,7 +81,7 @@ unsigned mbedtls_ct_uint_mask( unsigned value ) #endif } -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) +#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) size_t mbedtls_ct_size_mask( size_t value ) { @@ -97,7 +97,7 @@ size_t mbedtls_ct_size_mask( size_t value ) #endif } -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */ +#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ #if defined(MBEDTLS_BIGNUM_C) @@ -272,7 +272,7 @@ unsigned mbedtls_ct_uint_if( unsigned condition, * \note if1 and if0 must be either 1 or -1, otherwise the result * is undefined. * - * \param condition Condition to test. + * \param condition Condition to test; must be either 0 or 1. * \param if1 The first sign; must be either +1 or -1. * \param if0 The second sign; must be either +1 or -1. * @@ -404,8 +404,7 @@ static void mbedtls_ct_mem_move_to_left( void *start, #endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */ -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) - +#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) void mbedtls_ct_memcpy_if_eq( unsigned char *dest, const unsigned char *src, size_t len, @@ -527,7 +526,7 @@ cleanup: return( ret ); } -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */ +#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ #if defined(MBEDTLS_BIGNUM_C) diff --git a/thirdparty/mbedtls/library/constant_time_internal.h b/thirdparty/mbedtls/library/constant_time_internal.h index a550b38fa5..ff2d0ff92c 100644 --- a/thirdparty/mbedtls/library/constant_time_internal.h +++ b/thirdparty/mbedtls/library/constant_time_internal.h @@ -32,7 +32,6 @@ #include <stddef.h> - /** Turn a value into a mask: * - if \p value == 0, return the all-bits 0 mask, aka 0 * - otherwise, return the all-bits 1 mask, aka (unsigned) -1 @@ -46,7 +45,7 @@ */ unsigned mbedtls_ct_uint_mask( unsigned value ); -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) +#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) /** Turn a value into a mask: * - if \p value == 0, return the all-bits 0 mask, aka 0 @@ -61,7 +60,7 @@ unsigned mbedtls_ct_uint_mask( unsigned value ); */ size_t mbedtls_ct_size_mask( size_t value ); -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */ +#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ #if defined(MBEDTLS_BIGNUM_C) @@ -196,7 +195,7 @@ signed char mbedtls_ct_base64_dec_value( unsigned char c ); #endif /* MBEDTLS_BASE64_C */ -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) +#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) /** Conditional memcpy without branches. * @@ -292,7 +291,7 @@ int mbedtls_ct_hmac( mbedtls_md_context_t *ctx, size_t max_data_len, unsigned char *output ); -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */ +#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ #if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) diff --git a/thirdparty/mbedtls/library/ctr_drbg.c b/thirdparty/mbedtls/library/ctr_drbg.c index a00d66ce87..ed31576a7b 100644 --- a/thirdparty/mbedtls/library/ctr_drbg.c +++ b/thirdparty/mbedtls/library/ctr_drbg.c @@ -36,14 +36,7 @@ #include <stdio.h> #endif -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ /* * CTR_DRBG context initialization diff --git a/thirdparty/mbedtls/library/debug.c b/thirdparty/mbedtls/library/debug.c index e1086008af..353b4bf07b 100644 --- a/thirdparty/mbedtls/library/debug.c +++ b/thirdparty/mbedtls/library/debug.c @@ -21,16 +21,7 @@ #if defined(MBEDTLS_DEBUG_C) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#define mbedtls_calloc calloc -#define mbedtls_free free -#define mbedtls_time_t time_t -#define mbedtls_snprintf snprintf -#define mbedtls_vsnprintf vsnprintf -#endif #include "mbedtls/debug.h" #include "mbedtls/error.h" @@ -39,11 +30,6 @@ #include <stdio.h> #include <string.h> -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - #define DEBUG_BUF_SIZE 512 static int debug_threshold = 0; diff --git a/thirdparty/mbedtls/library/des.c b/thirdparty/mbedtls/library/des.c index 91d22b5d90..65f5681cf1 100644 --- a/thirdparty/mbedtls/library/des.c +++ b/thirdparty/mbedtls/library/des.c @@ -33,14 +33,7 @@ #include <string.h> -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ #if !defined(MBEDTLS_DES_ALT) diff --git a/thirdparty/mbedtls/library/dhm.c b/thirdparty/mbedtls/library/dhm.c index 88e148bb80..4d2e33e689 100644 --- a/thirdparty/mbedtls/library/dhm.c +++ b/thirdparty/mbedtls/library/dhm.c @@ -43,15 +43,7 @@ #include "mbedtls/asn1.h" #endif -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#include <stdio.h> -#define mbedtls_printf printf -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif #if !defined(MBEDTLS_DHM_ALT) diff --git a/thirdparty/mbedtls/library/ecdh.c b/thirdparty/mbedtls/library/ecdh.c index 60c6e429de..724c938a71 100644 --- a/thirdparty/mbedtls/library/ecdh.c +++ b/thirdparty/mbedtls/library/ecdh.c @@ -77,10 +77,12 @@ static int ecdh_gen_public_restartable( mbedtls_ecp_group *grp, { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - /* If multiplication is in progress, we already generated a privkey */ + int restarting = 0; #if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx == NULL || rs_ctx->rsm == NULL ) + restarting = ( rs_ctx != NULL && rs_ctx->rsm != NULL ); #endif + /* If multiplication is in progress, we already generated a privkey */ + if( !restarting ) MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) ); MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, Q, d, &grp->G, diff --git a/thirdparty/mbedtls/library/ecdsa.c b/thirdparty/mbedtls/library/ecdsa.c index 640eb24a26..4bae6a93fd 100644 --- a/thirdparty/mbedtls/library/ecdsa.c +++ b/thirdparty/mbedtls/library/ecdsa.c @@ -36,13 +36,7 @@ #include "mbedtls/hmac_drbg.h" #endif -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif #include "mbedtls/platform_util.h" #include "mbedtls/error.h" diff --git a/thirdparty/mbedtls/library/ecjpake.c b/thirdparty/mbedtls/library/ecjpake.c index 0b9bffb93e..fe0b9d93e9 100644 --- a/thirdparty/mbedtls/library/ecjpake.c +++ b/thirdparty/mbedtls/library/ecjpake.c @@ -794,12 +794,7 @@ cleanup: #if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif #if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ !defined(MBEDTLS_SHA256_C) diff --git a/thirdparty/mbedtls/library/ecp.c b/thirdparty/mbedtls/library/ecp.c index 890f364a08..ad19e05fb2 100644 --- a/thirdparty/mbedtls/library/ecp.c +++ b/thirdparty/mbedtls/library/ecp.c @@ -90,15 +90,7 @@ #define ECP_VALIDATE( cond ) \ MBEDTLS_INTERNAL_VALIDATE( cond ) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#include <stdio.h> -#define mbedtls_printf printf -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif #include "mbedtls/ecp_internal.h" @@ -112,11 +104,6 @@ #endif #endif /* MBEDTLS_ECP_NO_INTERNAL_RNG */ -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - #if defined(MBEDTLS_SELF_TEST) /* * Counts of point addition and doubling, and field multiplications. @@ -2056,9 +2043,13 @@ static int ecp_mul_comb_core( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R i = d; MBEDTLS_MPI_CHK( ecp_select_comb( grp, R, T, T_size, x[i] ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 1 ) ); + + int have_rng = 1; #if defined(MBEDTLS_ECP_NO_INTERNAL_RNG) - if( f_rng != 0 ) + if( f_rng == NULL ) + have_rng = 0; #endif + if( have_rng ) MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, R, f_rng, p_rng ) ); } @@ -2192,9 +2183,12 @@ final_norm: * * Avoid the leak by randomizing coordinates before we normalize them. */ + int have_rng = 1; #if defined(MBEDTLS_ECP_NO_INTERNAL_RNG) - if( f_rng != 0 ) + if( f_rng == NULL ) + have_rng = 0; #endif + if( have_rng ) MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, RR, f_rng, p_rng ) ); MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, RR ) ); @@ -2403,12 +2397,14 @@ cleanup: mbedtls_free( T ); } - /* don't free R while in progress in case R == P */ + /* prevent caller from using invalid value */ + int should_free_R = ( ret != 0 ); #if defined(MBEDTLS_ECP_RESTARTABLE) - if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) + /* don't free R while in progress in case R == P */ + if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) + should_free_R = 0; #endif - /* prevent caller from using invalid value */ - if( ret != 0 ) + if( should_free_R ) mbedtls_ecp_point_free( R ); ECP_RS_LEAVE( rsm ); @@ -2596,13 +2592,16 @@ static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, MOD_ADD( RP.X ); /* Randomize coordinates of the starting point */ + int have_rng = 1; #if defined(MBEDTLS_ECP_NO_INTERNAL_RNG) - if( f_rng != NULL ) + if( f_rng == NULL ) + have_rng = 0; #endif + if( have_rng ) MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) ); /* Loop invariant: R = result so far, RP = R + P */ - i = mbedtls_mpi_bitlen( m ); /* one past the (zero-based) most significant bit */ + i = grp->nbits + 1; /* one past the (zero-based) required msb for private keys */ while( i-- > 0 ) { b = mbedtls_mpi_get_bit( m, i ); @@ -2631,9 +2630,12 @@ static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, * * Avoid the leak by randomizing coordinates before we normalize them. */ + have_rng = 1; #if defined(MBEDTLS_ECP_NO_INTERNAL_RNG) - if( f_rng != NULL ) + if( f_rng == NULL ) + have_rng = 0; #endif + if( have_rng ) MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, R, f_rng, p_rng ) ); MBEDTLS_MPI_CHK( ecp_normalize_mxz( grp, R ) ); @@ -2680,10 +2682,12 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) ); #endif /* MBEDTLS_ECP_INTERNAL_ALT */ + int restarting = 0; #if defined(MBEDTLS_ECP_RESTARTABLE) - /* skip argument check when restarting */ - if( rs_ctx == NULL || rs_ctx->rsm == NULL ) + restarting = ( rs_ctx != NULL && rs_ctx->rsm != NULL ); #endif + /* skip argument check when restarting */ + if( !restarting ) { /* check_privkey is free */ MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_CHK ); @@ -2797,14 +2801,17 @@ static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp, if( mbedtls_mpi_cmp_int( m, 0 ) == 0 ) { + MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, P ) ); MBEDTLS_MPI_CHK( mbedtls_ecp_set_zero( R ) ); } else if( mbedtls_mpi_cmp_int( m, 1 ) == 0 ) { + MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, P ) ); MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) ); } else if( mbedtls_mpi_cmp_int( m, -1 ) == 0 ) { + MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, P ) ); MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) ); if( mbedtls_mpi_cmp_int( &R->Y, 0 ) != 0 ) MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &R->Y, &grp->P, &R->Y ) ); diff --git a/thirdparty/mbedtls/library/ecp_curves.c b/thirdparty/mbedtls/library/ecp_curves.c index 2199be6461..47761eef4e 100644 --- a/thirdparty/mbedtls/library/ecp_curves.c +++ b/thirdparty/mbedtls/library/ecp_curves.c @@ -38,11 +38,6 @@ #define ECP_VALIDATE( cond ) \ MBEDTLS_INTERNAL_VALIDATE( cond ) -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - #define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)} #define ECP_MPI_INIT_ARRAY(x) \ diff --git a/thirdparty/mbedtls/library/entropy.c b/thirdparty/mbedtls/library/entropy.c index 12fd3b9b5f..e3b337ff35 100644 --- a/thirdparty/mbedtls/library/entropy.c +++ b/thirdparty/mbedtls/library/entropy.c @@ -38,18 +38,9 @@ #include <stdio.h> #endif -#if defined(MBEDTLS_ENTROPY_NV_SEED) #include "mbedtls/platform.h" -#endif -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ #if defined(MBEDTLS_HAVEGE_C) #include "mbedtls/havege.h" diff --git a/thirdparty/mbedtls/library/entropy_poll.c b/thirdparty/mbedtls/library/entropy_poll.c index 40f23fd2a6..69ac29e4f7 100644 --- a/thirdparty/mbedtls/library/entropy_poll.c +++ b/thirdparty/mbedtls/library/entropy_poll.c @@ -38,9 +38,7 @@ #if defined(MBEDTLS_HAVEGE_C) #include "mbedtls/havege.h" #endif -#if defined(MBEDTLS_ENTROPY_NV_SEED) #include "mbedtls/platform.h" -#endif #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) diff --git a/thirdparty/mbedtls/library/error.c b/thirdparty/mbedtls/library/error.c index afad38904f..8573369a32 100644 --- a/thirdparty/mbedtls/library/error.c +++ b/thirdparty/mbedtls/library/error.c @@ -25,11 +25,7 @@ #if defined(MBEDTLS_ERROR_C) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#define mbedtls_snprintf snprintf -#endif #include <stdio.h> #include <string.h> @@ -961,7 +957,7 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) #else /* MBEDTLS_ERROR_C */ /* - * Provide an non-function in case MBEDTLS_ERROR_C is not defined + * Provide a dummy implementation when MBEDTLS_ERROR_C is not defined */ void mbedtls_strerror( int ret, char *buf, size_t buflen ) { diff --git a/thirdparty/mbedtls/library/gcm.c b/thirdparty/mbedtls/library/gcm.c index 43a5e1bec6..d0b73379a6 100644 --- a/thirdparty/mbedtls/library/gcm.c +++ b/thirdparty/mbedtls/library/gcm.c @@ -32,6 +32,7 @@ #if defined(MBEDTLS_GCM_C) #include "mbedtls/gcm.h" +#include "mbedtls/platform.h" #include "mbedtls/platform_util.h" #include "mbedtls/error.h" @@ -41,15 +42,6 @@ #include "mbedtls/aesni.h" #endif -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -#include "mbedtls/aes.h" -#include "mbedtls/platform.h" -#if !defined(MBEDTLS_PLATFORM_C) -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - #if !defined(MBEDTLS_GCM_ALT) /* Parameter validation macros */ diff --git a/thirdparty/mbedtls/library/hmac_drbg.c b/thirdparty/mbedtls/library/hmac_drbg.c index de9706885c..69272fa73d 100644 --- a/thirdparty/mbedtls/library/hmac_drbg.c +++ b/thirdparty/mbedtls/library/hmac_drbg.c @@ -37,14 +37,7 @@ #include <stdio.h> #endif -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_SELF_TEST */ -#endif /* MBEDTLS_PLATFORM_C */ /* * HMAC_DRBG context initialization diff --git a/thirdparty/mbedtls/library/md.c b/thirdparty/mbedtls/library/md.c index a10a835634..53a84b01c6 100644 --- a/thirdparty/mbedtls/library/md.c +++ b/thirdparty/mbedtls/library/md.c @@ -38,13 +38,7 @@ #include "mbedtls/sha256.h" #include "mbedtls/sha512.h" -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif #include <string.h> diff --git a/thirdparty/mbedtls/library/md2.c b/thirdparty/mbedtls/library/md2.c index 7264e30313..f8293a1df3 100644 --- a/thirdparty/mbedtls/library/md2.c +++ b/thirdparty/mbedtls/library/md2.c @@ -33,14 +33,7 @@ #include <string.h> -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ #if !defined(MBEDTLS_MD2_ALT) diff --git a/thirdparty/mbedtls/library/md4.c b/thirdparty/mbedtls/library/md4.c index eaa679a0a6..a412213480 100644 --- a/thirdparty/mbedtls/library/md4.c +++ b/thirdparty/mbedtls/library/md4.c @@ -33,14 +33,7 @@ #include <string.h> -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ #if !defined(MBEDTLS_MD4_ALT) diff --git a/thirdparty/mbedtls/library/md5.c b/thirdparty/mbedtls/library/md5.c index 4b53fcf367..e53bfe6306 100644 --- a/thirdparty/mbedtls/library/md5.c +++ b/thirdparty/mbedtls/library/md5.c @@ -32,14 +32,7 @@ #include <string.h> -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ #if !defined(MBEDTLS_MD5_ALT) diff --git a/thirdparty/mbedtls/library/mps_reader.c b/thirdparty/mbedtls/library/mps_reader.c index 9af5073cc9..0c30a75d05 100644 --- a/thirdparty/mbedtls/library/mps_reader.c +++ b/thirdparty/mbedtls/library/mps_reader.c @@ -29,11 +29,6 @@ #include <string.h> -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - #if defined(MBEDTLS_MPS_ENABLE_TRACE) static int mbedtls_mps_trace_id = MBEDTLS_MPS_TRACE_BIT_READER; #endif /* MBEDTLS_MPS_ENABLE_TRACE */ @@ -535,7 +530,7 @@ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd, * of the accumulator. */ memmove( acc, acc + acc_backup_offset, acc_backup_len ); - /* Copy uncmmitted parts of the current fragment to the + /* Copy uncommitted parts of the current fragment to the * accumulator. */ memcpy( acc + acc_backup_len, frag + frag_backup_offset, frag_backup_len ); diff --git a/thirdparty/mbedtls/library/mps_trace.h b/thirdparty/mbedtls/library/mps_trace.h index 7c2360118a..820a1b66c2 100644 --- a/thirdparty/mbedtls/library/mps_trace.h +++ b/thirdparty/mbedtls/library/mps_trace.h @@ -30,13 +30,7 @@ #include "mps_common.h" #include "mps_trace.h" -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#define mbedtls_vsnprintf vsnprintf -#endif /* MBEDTLS_PLATFORM_C */ #if defined(MBEDTLS_MPS_ENABLE_TRACE) diff --git a/thirdparty/mbedtls/library/net_sockets.c b/thirdparty/mbedtls/library/net_sockets.c index 8c765e1c8c..b2cab503f2 100644 --- a/thirdparty/mbedtls/library/net_sockets.c +++ b/thirdparty/mbedtls/library/net_sockets.c @@ -37,11 +37,7 @@ #error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h" #endif -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#endif #include "mbedtls/net_sockets.h" #include "mbedtls/error.h" diff --git a/thirdparty/mbedtls/library/nist_kw.c b/thirdparty/mbedtls/library/nist_kw.c index 1aea0b6345..495c23d06a 100644 --- a/thirdparty/mbedtls/library/nist_kw.c +++ b/thirdparty/mbedtls/library/nist_kw.c @@ -39,14 +39,7 @@ #include <stdint.h> #include <string.h> -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ #if !defined(MBEDTLS_NIST_KW_ALT) diff --git a/thirdparty/mbedtls/library/oid.c b/thirdparty/mbedtls/library/oid.c index 19c8ac207c..53e5350eb3 100644 --- a/thirdparty/mbedtls/library/oid.c +++ b/thirdparty/mbedtls/library/oid.c @@ -30,11 +30,7 @@ #include <stdio.h> #include <string.h> -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#define mbedtls_snprintf snprintf -#endif /* * Macro to automatically add the size of #define'd OIDs diff --git a/thirdparty/mbedtls/library/pem.c b/thirdparty/mbedtls/library/pem.c index fcfde94799..cb1c82b3e4 100644 --- a/thirdparty/mbedtls/library/pem.c +++ b/thirdparty/mbedtls/library/pem.c @@ -32,13 +32,7 @@ #include <string.h> -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif #if defined(MBEDTLS_PEM_PARSE_C) void mbedtls_pem_init( mbedtls_pem_context *ctx ) diff --git a/thirdparty/mbedtls/library/pk_wrap.c b/thirdparty/mbedtls/library/pk_wrap.c index 107e912ace..f35abf21a4 100644 --- a/thirdparty/mbedtls/library/pk_wrap.c +++ b/thirdparty/mbedtls/library/pk_wrap.c @@ -50,13 +50,7 @@ #include "mbedtls/asn1.h" #endif -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif #include <limits.h> #include <stdint.h> @@ -872,7 +866,7 @@ static void *pk_opaque_alloc_wrap( void ) { void *ctx = mbedtls_calloc( 1, sizeof( psa_key_id_t ) ); - /* no _init() function to call, an calloc() already zeroized */ + /* no _init() function to call, as calloc() already zeroized */ return( ctx ); } diff --git a/thirdparty/mbedtls/library/pkcs11.c b/thirdparty/mbedtls/library/pkcs11.c index 4deccf3f60..a7207cfc93 100644 --- a/thirdparty/mbedtls/library/pkcs11.c +++ b/thirdparty/mbedtls/library/pkcs11.c @@ -29,13 +29,7 @@ #include "mbedtls/oid.h" #include "mbedtls/x509_crt.h" -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif #include <string.h> diff --git a/thirdparty/mbedtls/library/pkcs5.c b/thirdparty/mbedtls/library/pkcs5.c index 2b014d91c8..f9d01371a7 100644 --- a/thirdparty/mbedtls/library/pkcs5.c +++ b/thirdparty/mbedtls/library/pkcs5.c @@ -42,12 +42,7 @@ #include <string.h> -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif #if defined(MBEDTLS_ASN1_PARSE_C) static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params, diff --git a/thirdparty/mbedtls/library/pkparse.c b/thirdparty/mbedtls/library/pkparse.c index ea5c6b69cb..6170d6d012 100644 --- a/thirdparty/mbedtls/library/pkparse.c +++ b/thirdparty/mbedtls/library/pkparse.c @@ -48,13 +48,7 @@ #include "mbedtls/pkcs12.h" #endif -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif /* Parameter validation macros based on platform_util.h */ #define PK_VALIDATE_RET( cond ) \ diff --git a/thirdparty/mbedtls/library/pkwrite.c b/thirdparty/mbedtls/library/pkwrite.c index 566153dd93..c1ce0e3f02 100644 --- a/thirdparty/mbedtls/library/pkwrite.c +++ b/thirdparty/mbedtls/library/pkwrite.c @@ -48,13 +48,7 @@ #include "psa/crypto.h" #include "mbedtls/psa_util.h" #endif -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif /* Parameter validation macros based on platform_util.h */ #define PK_VALIDATE_RET( cond ) \ diff --git a/thirdparty/mbedtls/library/poly1305.c b/thirdparty/mbedtls/library/poly1305.c index 7375a0c572..a1c5b19d8e 100644 --- a/thirdparty/mbedtls/library/poly1305.c +++ b/thirdparty/mbedtls/library/poly1305.c @@ -28,22 +28,10 @@ #include <string.h> -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ #if !defined(MBEDTLS_POLY1305_ALT) -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - /* Parameter validation macros */ #define POLY1305_VALIDATE_RET( cond ) \ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ) diff --git a/thirdparty/mbedtls/library/ripemd160.c b/thirdparty/mbedtls/library/ripemd160.c index aed7322cff..55e259e192 100644 --- a/thirdparty/mbedtls/library/ripemd160.c +++ b/thirdparty/mbedtls/library/ripemd160.c @@ -33,14 +33,7 @@ #include <string.h> -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ #if !defined(MBEDTLS_RIPEMD160_ALT) diff --git a/thirdparty/mbedtls/library/rsa.c b/thirdparty/mbedtls/library/rsa.c index d1f6ddb177..9c39fa5d91 100644 --- a/thirdparty/mbedtls/library/rsa.c +++ b/thirdparty/mbedtls/library/rsa.c @@ -57,14 +57,7 @@ #include <stdlib.h> #endif -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif #if !defined(MBEDTLS_RSA_ALT) diff --git a/thirdparty/mbedtls/library/sha1.c b/thirdparty/mbedtls/library/sha1.c index 0a5edafaff..7f0c8757db 100644 --- a/thirdparty/mbedtls/library/sha1.c +++ b/thirdparty/mbedtls/library/sha1.c @@ -32,14 +32,7 @@ #include <string.h> -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ #define SHA1_VALIDATE_RET(cond) \ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA1_BAD_INPUT_DATA ) diff --git a/thirdparty/mbedtls/library/sha256.c b/thirdparty/mbedtls/library/sha256.c index db675efd1b..6f1306ee66 100644 --- a/thirdparty/mbedtls/library/sha256.c +++ b/thirdparty/mbedtls/library/sha256.c @@ -32,17 +32,7 @@ #include <string.h> -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#include <stdlib.h> -#define mbedtls_printf printf -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ #define SHA256_VALIDATE_RET(cond) \ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA ) diff --git a/thirdparty/mbedtls/library/sha512.c b/thirdparty/mbedtls/library/sha512.c index 02a135ca92..1a6872c8aa 100644 --- a/thirdparty/mbedtls/library/sha512.c +++ b/thirdparty/mbedtls/library/sha512.c @@ -38,17 +38,7 @@ #include <string.h> -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#include <stdlib.h> -#define mbedtls_printf printf -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ #define SHA512_VALIDATE_RET(cond) \ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA ) @@ -428,9 +418,11 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, sha512_put_uint64_be( ctx->state[4], output, 32 ); sha512_put_uint64_be( ctx->state[5], output, 40 ); + int truncated = 0; #if !defined(MBEDTLS_SHA512_NO_SHA384) - if( ctx->is384 == 0 ) + truncated = ctx->is384; #endif + if( !truncated ) { sha512_put_uint64_be( ctx->state[6], output, 48 ); sha512_put_uint64_be( ctx->state[7], output, 56 ); diff --git a/thirdparty/mbedtls/library/ssl_cache.c b/thirdparty/mbedtls/library/ssl_cache.c index 32188cf3f6..7a600cad18 100644 --- a/thirdparty/mbedtls/library/ssl_cache.c +++ b/thirdparty/mbedtls/library/ssl_cache.c @@ -25,13 +25,7 @@ #if defined(MBEDTLS_SSL_CACHE_C) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif #include "mbedtls/ssl_cache.h" #include "mbedtls/ssl_internal.h" diff --git a/thirdparty/mbedtls/library/ssl_ciphersuites.c b/thirdparty/mbedtls/library/ssl_ciphersuites.c index ceec77efb0..2bc8a9bba0 100644 --- a/thirdparty/mbedtls/library/ssl_ciphersuites.c +++ b/thirdparty/mbedtls/library/ssl_ciphersuites.c @@ -23,11 +23,7 @@ #if defined(MBEDTLS_SSL_TLS_C) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#endif #include "mbedtls/ssl_ciphersuites.h" #include "mbedtls/ssl.h" diff --git a/thirdparty/mbedtls/library/ssl_cli.c b/thirdparty/mbedtls/library/ssl_cli.c index 72351c9757..b40ddb70b4 100644 --- a/thirdparty/mbedtls/library/ssl_cli.c +++ b/thirdparty/mbedtls/library/ssl_cli.c @@ -21,13 +21,7 @@ #if defined(MBEDTLS_SSL_CLI_C) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif #include "mbedtls/ssl.h" #include "mbedtls/ssl_internal.h" @@ -174,7 +168,7 @@ static int ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, *olen = 0; - /* We're always including an TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the + /* We're always including a TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the * initial ClientHello, in which case also adding the renegotiation * info extension is NOT RECOMMENDED as per RFC 5746 Section 3.4. */ if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) @@ -1004,9 +998,12 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_NO_RNG ); } + int renegotiating = 0; #if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) + if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) + renegotiating = 1; #endif + if( !renegotiating ) { ssl->major_ver = ssl->conf->min_major_ver; ssl->minor_ver = ssl->conf->min_minor_ver; @@ -1092,9 +1089,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) * RFC 5077 section 3.4: "When presenting a ticket, the client MAY * generate and include a Session ID in the TLS ClientHello." */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) -#endif + if( !renegotiating ) { if( ssl->session_negotiate->ticket != NULL && ssl->session_negotiate->ticket_len != 0 ) @@ -1209,9 +1204,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) /* * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) -#endif + if( !renegotiating ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding EMPTY_RENEGOTIATION_INFO_SCSV" ) ); MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 ); @@ -2062,6 +2055,30 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_PROTO_DTLS */ +static int is_compression_bad( mbedtls_ssl_context *ssl, unsigned char comp ) +{ + int bad_comp = 0; + + /* Suppress warnings in some configurations */ + (void) ssl; +#if defined(MBEDTLS_ZLIB_SUPPORT) + /* See comments in ssl_write_client_hello() */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + comp != MBEDTLS_SSL_COMPRESS_NULL ) + bad_comp = 1; +#endif + + if( comp != MBEDTLS_SSL_COMPRESS_NULL && + comp != MBEDTLS_SSL_COMPRESS_DEFLATE ) + bad_comp = 1; +#else /* MBEDTLS_ZLIB_SUPPORT */ + if( comp != MBEDTLS_SSL_COMPRESS_NULL ) + bad_comp = 1; +#endif/* MBEDTLS_ZLIB_SUPPORT */ + return bad_comp; +} + MBEDTLS_CHECK_RETURN_CRITICAL static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) { @@ -2070,9 +2087,6 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) size_t ext_len; unsigned char *buf, *ext; unsigned char comp; -#if defined(MBEDTLS_ZLIB_SUPPORT) - int accept_comp; -#endif #if defined(MBEDTLS_SSL_RENEGOTIATION) int renegotiation_info_seen = 0; #endif @@ -2241,20 +2255,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) */ comp = buf[37 + n]; -#if defined(MBEDTLS_ZLIB_SUPPORT) - /* See comments in ssl_write_client_hello() */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - accept_comp = 0; - else -#endif - accept_comp = 1; - - if( comp != MBEDTLS_SSL_COMPRESS_NULL && - ( comp != MBEDTLS_SSL_COMPRESS_DEFLATE || accept_comp == 0 ) ) -#else /* MBEDTLS_ZLIB_SUPPORT */ - if( comp != MBEDTLS_SSL_COMPRESS_NULL ) -#endif/* MBEDTLS_ZLIB_SUPPORT */ + if( is_compression_bad( ssl, comp ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "server hello, bad compression: %d", comp ) ); @@ -2687,7 +2688,7 @@ static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl ) grp_id = ssl->handshake->ecdh_ctx.grp.id; #else grp_id = ssl->handshake->ecdh_ctx.grp_id; -#endif +#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */ curve_info = mbedtls_ecp_curve_info_from_grp_id( grp_id ); if( curve_info == NULL ) @@ -2700,11 +2701,12 @@ static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_ECP_C) if( mbedtls_ssl_check_curve( ssl, grp_id ) != 0 ) + return( -1 ); #else if( ssl->handshake->ecdh_ctx.grp.nbits < 163 || ssl->handshake->ecdh_ctx.grp.nbits > 521 ) -#endif return( -1 ); +#endif /* MBEDTLS_ECP_C */ MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, MBEDTLS_DEBUG_ECDH_QP ); @@ -2858,8 +2860,8 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl, } /* - * Note: we currently ignore the PKS identity hint, as we only allow one - * PSK to be provisionned on the client. This could be changed later if + * Note: we currently ignore the PSK identity hint, as we only allow one + * PSK to be provisioned on the client. This could be changed later if * someone needs that feature. */ *p += len; @@ -3452,23 +3454,23 @@ start_processing: #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) if( ssl->handshake->ecrs_enabled ) rs_ctx = &ssl->handshake->ecrs_ctx.pk; -#endif +#endif /* MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED */ if( ( ret = mbedtls_pk_verify_restartable( peer_pk, md_alg, hash, hashlen, p, sig_len, rs_ctx ) ) != 0 ) { #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) -#endif - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR ); - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; -#endif + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); + return( MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS ); + } +#endif /* MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED */ + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR ); + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); return( ret ); } diff --git a/thirdparty/mbedtls/library/ssl_cookie.c b/thirdparty/mbedtls/library/ssl_cookie.c index 3781796b72..f12f28e849 100644 --- a/thirdparty/mbedtls/library/ssl_cookie.c +++ b/thirdparty/mbedtls/library/ssl_cookie.c @@ -25,12 +25,7 @@ #if defined(MBEDTLS_SSL_COOKIE_C) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif #include "mbedtls/ssl_cookie.h" #include "mbedtls/ssl_internal.h" diff --git a/thirdparty/mbedtls/library/ssl_msg.c b/thirdparty/mbedtls/library/ssl_msg.c index e47c538888..d7bebe04d6 100644 --- a/thirdparty/mbedtls/library/ssl_msg.c +++ b/thirdparty/mbedtls/library/ssl_msg.c @@ -30,13 +30,7 @@ #if defined(MBEDTLS_SSL_TLS_C) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif #include "mbedtls/ssl.h" #include "mbedtls/ssl_internal.h" @@ -441,9 +435,12 @@ static void ssl_extract_add_data_from_record( unsigned char* add_data, unsigned char *cur = add_data; + int is_tls13 = 0; #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) - if( minor_ver != MBEDTLS_SSL_MINOR_VERSION_4 ) + if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 ) + is_tls13 = 1; #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + if( !is_tls13 ) { ((void) minor_ver); memcpy( cur, rec->ctr, sizeof( rec->ctr ) ); @@ -1887,8 +1884,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " - "or mbedtls_ssl_set_bio()" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } @@ -2103,8 +2099,7 @@ int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ) if( ssl->f_send == NULL ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " - "or mbedtls_ssl_set_bio()" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } @@ -3950,8 +3945,8 @@ int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl, if( ssl_record_is_in_progress( ssl ) == 0 ) { + int dtls_have_buffered = 0; #if defined(MBEDTLS_SSL_PROTO_DTLS) - int have_buffered = 0; /* We only check for buffered messages if the * current datagram is fully consumed. */ @@ -3959,11 +3954,11 @@ int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl, ssl_next_record_is_in_datagram( ssl ) == 0 ) { if( ssl_load_buffered_message( ssl ) == 0 ) - have_buffered = 1; + dtls_have_buffered = 1; } - if( have_buffered == 0 ) #endif /* MBEDTLS_SSL_PROTO_DTLS */ + if( dtls_have_buffered == 0 ) { ret = ssl_get_next_record( ssl ); if( ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ) @@ -4037,7 +4032,7 @@ static int ssl_load_buffered_message( mbedtls_ssl_context *ssl ) if( hs == NULL ) return( -1 ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_messsage" ) ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_message" ) ); if( ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC || ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC ) diff --git a/thirdparty/mbedtls/library/ssl_srv.c b/thirdparty/mbedtls/library/ssl_srv.c index 2efb13cc33..0563c0b590 100644 --- a/thirdparty/mbedtls/library/ssl_srv.c +++ b/thirdparty/mbedtls/library/ssl_srv.c @@ -21,13 +21,7 @@ #if defined(MBEDTLS_SSL_SRV_C) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif #include "mbedtls/ssl.h" #include "mbedtls/ssl_internal.h" @@ -1460,6 +1454,7 @@ static int ssl_parse_client_hello( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) ); + int renegotiating = 0; #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) read_record_header: #endif @@ -1469,8 +1464,10 @@ read_record_header: * ClientHello, which doesn't use the same record layer format. */ #if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) + if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) + renegotiating = 1; #endif + if( !renegotiating ) { if( ( ret = mbedtls_ssl_fetch_input( ssl, 5 ) ) != 0 ) { @@ -1483,9 +1480,12 @@ read_record_header: buf = ssl->in_hdr; #if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) + int is_dtls = 0; #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + is_dtls = 1; #endif + if( !is_dtls ) if( ( buf[0] & 0x80 ) != 0 ) return( ssl_parse_client_hello_v2( ssl ) ); #endif @@ -3903,8 +3903,14 @@ static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl, size_t peer_pmssize ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + mbedtls_x509_crt *own_cert = mbedtls_ssl_own_cert( ssl ); + if( own_cert == NULL ) { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no local certificate" ) ); + return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE ); + } + mbedtls_pk_context *public_key = &own_cert->pk; mbedtls_pk_context *private_key = mbedtls_ssl_own_key( ssl ); - mbedtls_pk_context *public_key = &mbedtls_ssl_own_cert( ssl )->pk; size_t len = mbedtls_pk_get_len( public_key ); #if defined(MBEDTLS_SSL_ASYNC_PRIVATE) diff --git a/thirdparty/mbedtls/library/ssl_ticket.c b/thirdparty/mbedtls/library/ssl_ticket.c index e0126cc9d1..8a57789f10 100644 --- a/thirdparty/mbedtls/library/ssl_ticket.c +++ b/thirdparty/mbedtls/library/ssl_ticket.c @@ -21,13 +21,7 @@ #if defined(MBEDTLS_SSL_TICKET_C) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif #include "mbedtls/ssl_internal.h" #include "mbedtls/ssl_ticket.h" @@ -152,27 +146,45 @@ int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx, if( cipher_info->key_bitlen > 8 * MAX_KEY_BYTES ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + int do_mbedtls_cipher_setup = 1; #if defined(MBEDTLS_USE_PSA_CRYPTO) ret = mbedtls_cipher_setup_psa( &ctx->keys[0].ctx, cipher_info, TICKET_AUTH_TAG_BYTES ); - if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ) - return( ret ); - /* We don't yet expect to support all ciphers through PSA, - * so allow fallback to ordinary mbedtls_cipher_setup(). */ - if( ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ) + + switch( ret ) + { + case 0: + do_mbedtls_cipher_setup = 0; + break; + case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE: + /* We don't yet expect to support all ciphers through PSA, + * so allow fallback to ordinary mbedtls_cipher_setup(). */ + do_mbedtls_cipher_setup = 1; + break; + default: + return( ret ); + } #endif /* MBEDTLS_USE_PSA_CRYPTO */ - if( ( ret = mbedtls_cipher_setup( &ctx->keys[0].ctx, cipher_info ) ) != 0 ) - return( ret ); + if( do_mbedtls_cipher_setup ) + if( ( ret = mbedtls_cipher_setup( &ctx->keys[0].ctx, cipher_info ) ) + != 0 ) + return( ret ); + do_mbedtls_cipher_setup = 1; #if defined(MBEDTLS_USE_PSA_CRYPTO) + do_mbedtls_cipher_setup = 0; + ret = mbedtls_cipher_setup_psa( &ctx->keys[1].ctx, cipher_info, TICKET_AUTH_TAG_BYTES ); if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ) return( ret ); if( ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ) + do_mbedtls_cipher_setup = 1; #endif /* MBEDTLS_USE_PSA_CRYPTO */ - if( ( ret = mbedtls_cipher_setup( &ctx->keys[1].ctx, cipher_info ) ) != 0 ) - return( ret ); + if( do_mbedtls_cipher_setup ) + if( ( ret = mbedtls_cipher_setup( &ctx->keys[1].ctx, cipher_info ) ) + != 0 ) + return( ret ); if( ( ret = ssl_ticket_gen_key( ctx, 0 ) ) != 0 || ( ret = ssl_ticket_gen_key( ctx, 1 ) ) != 0 ) diff --git a/thirdparty/mbedtls/library/ssl_tls.c b/thirdparty/mbedtls/library/ssl_tls.c index 7badec51ae..70196a4861 100644 --- a/thirdparty/mbedtls/library/ssl_tls.c +++ b/thirdparty/mbedtls/library/ssl_tls.c @@ -29,13 +29,7 @@ #if defined(MBEDTLS_SSL_TLS_C) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif #include "mbedtls/ssl.h" #include "mbedtls/ssl_internal.h" @@ -766,7 +760,9 @@ static int tls_prf_generic( mbedtls_md_type_t md_type, exit: mbedtls_md_free( &md_ctx ); - mbedtls_platform_zeroize( tmp, tmp_len ); + if ( tmp != NULL ) + mbedtls_platform_zeroize( tmp, tmp_len ); + mbedtls_platform_zeroize( h_i, sizeof( h_i ) ); mbedtls_free( tmp ); @@ -985,6 +981,7 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform, #if defined(MBEDTLS_USE_PSA_CRYPTO) int psa_fallthrough; #endif /* MBEDTLS_USE_PSA_CRYPTO */ + int do_mbedtls_cipher_setup; unsigned char keyblk[256]; unsigned char *key1; unsigned char *key2; @@ -1363,6 +1360,7 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform, } #endif + do_mbedtls_cipher_setup = 1; #if defined(MBEDTLS_USE_PSA_CRYPTO) /* Only use PSA-based ciphers for TLS-1.2. @@ -1398,15 +1396,18 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform, psa_fallthrough = 1; #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - if( psa_fallthrough == 1 ) + if( psa_fallthrough == 0 ) + do_mbedtls_cipher_setup = 0; #endif /* MBEDTLS_USE_PSA_CRYPTO */ - if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc, - cipher_info ) ) != 0 ) + if( do_mbedtls_cipher_setup && + ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc, + cipher_info ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret ); goto end; } + do_mbedtls_cipher_setup = 1; #if defined(MBEDTLS_USE_PSA_CRYPTO) /* Only use PSA-based ciphers for TLS-1.2. * That's relevant at least for TLS-1.0, where @@ -1441,10 +1442,12 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform, psa_fallthrough = 1; #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - if( psa_fallthrough == 1 ) + if( psa_fallthrough == 0 ) + do_mbedtls_cipher_setup = 0; #endif /* MBEDTLS_USE_PSA_CRYPTO */ - if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_dec, - cipher_info ) ) != 0 ) + if( do_mbedtls_cipher_setup && + ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_dec, + cipher_info ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret ); goto end; @@ -3411,7 +3414,7 @@ static void ssl_calc_finished_tls_sha384( sha512.state, sizeof( sha512.state ) ); #endif /* mbedtls_sha512_finish_ret's output parameter is declared as a - * 64-byte buffer, but sice we're using SHA-384, we know that the + * 64-byte buffer, but since we're using SHA-384, we know that the * output fits in 48 bytes. This is correct C, but GCC 11.1 warns * about it. */ @@ -4089,9 +4092,12 @@ int mbedtls_ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ) memset( ssl->out_buf, 0, out_buf_len ); + int clear_in_buf = 1; #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) - if( partial == 0 ) + if( partial != 0 ) + clear_in_buf = 0; #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ + if( clear_in_buf ) { ssl->in_left = 0; memset( ssl->in_buf, 0, in_buf_len ); @@ -4128,9 +4134,12 @@ int mbedtls_ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ) #endif #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) + int free_cli_id = 1; #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) - if( partial == 0 ) + if( partial != 0 ) + free_cli_id = 0; #endif + if( free_cli_id ) { mbedtls_free( ssl->cli_id ); ssl->cli_id = NULL; @@ -4471,7 +4480,7 @@ static void ssl_conf_remove_psk( mbedtls_ssl_config *conf ) conf->psk_opaque = MBEDTLS_SVC_KEY_ID_INIT; } /* This and the following branch should never - * be taken simultaenously as we maintain the + * be taken simultaneously as we maintain the * invariant that raw and opaque PSKs are never * configured simultaneously. As a safeguard, * though, `else` is omitted here. */ @@ -6335,7 +6344,7 @@ int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 1, ( "There is pending outgoing data" ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } - /* Protocol must be DLTS, not TLS */ + /* Protocol must be DTLS, not TLS */ if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "Only DTLS is supported" ) ); @@ -6510,24 +6519,41 @@ int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl, * Helper to get TLS 1.2 PRF from ciphersuite * (Duplicates bits of logic from ssl_set_handshake_prfs().) */ +#if defined(MBEDTLS_SHA256_C) || \ + (defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)) typedef int (*tls_prf_fn)( const unsigned char *secret, size_t slen, const char *label, const unsigned char *random, size_t rlen, unsigned char *dstbuf, size_t dlen ); static tls_prf_fn ssl_tls12prf_from_cs( int ciphersuite_id ) { -#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384) const mbedtls_ssl_ciphersuite_t * const ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuite_id ); + if( ciphersuite_info == NULL ) + return( NULL ); + +#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384) if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 ) return( tls_prf_sha384 ); -#else - (void) ciphersuite_id; + else +#endif +#if defined(MBEDTLS_SHA256_C) + { + if( ciphersuite_info->mac == MBEDTLS_MD_SHA256 ) + return( tls_prf_sha256 ); + } #endif - return( tls_prf_sha256 ); +#if !defined(MBEDTLS_SHA256_C) && \ + (!defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA512_NO_SHA384)) + (void) ciphersuite_info; +#endif + return( NULL ); } +#endif /* MBEDTLS_SHA256_C || + (MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384) */ + /* * Deserialize context, see mbedtls_ssl_context_save() for format. * @@ -6543,6 +6569,7 @@ static int ssl_context_load( mbedtls_ssl_context *ssl, const unsigned char * const end = buf + len; size_t session_len; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + tls_prf_fn prf_func = NULL; /* * The context should have been freshly setup or reset. @@ -6630,6 +6657,10 @@ static int ssl_context_load( mbedtls_ssl_context *ssl, ssl->transform_out = ssl->transform; ssl->transform_negotiate = NULL; + prf_func = ssl_tls12prf_from_cs( ssl->session->ciphersuite ); + if( prf_func == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + /* Read random bytes and populate structure */ if( (size_t)( end - p ) < sizeof( ssl->transform->randbytes ) ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); @@ -6648,7 +6679,7 @@ static int ssl_context_load( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_ZLIB_SUPPORT) ssl->session->compression, #endif - ssl_tls12prf_from_cs( ssl->session->ciphersuite ), + prf_func, p, /* currently pointing to randbytes */ MBEDTLS_SSL_MINOR_VERSION_3, /* (D)TLS 1.2 is forced */ ssl->conf->endpoint, @@ -6921,7 +6952,7 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl ) } /* - * Initialze mbedtls_ssl_config + * Initialize mbedtls_ssl_config */ void mbedtls_ssl_config_init( mbedtls_ssl_config *conf ) { diff --git a/thirdparty/mbedtls/library/ssl_tls13_keys.c b/thirdparty/mbedtls/library/ssl_tls13_keys.c index 3de6f03fb8..cc68773d3a 100644 --- a/thirdparty/mbedtls/library/ssl_tls13_keys.c +++ b/thirdparty/mbedtls/library/ssl_tls13_keys.c @@ -24,6 +24,7 @@ #include "mbedtls/hkdf.h" #include "mbedtls/ssl_internal.h" #include "ssl_tls13_keys.h" +#include "psa/crypto_sizes.h" #include <stdint.h> #include <string.h> @@ -31,6 +32,9 @@ #define MBEDTLS_SSL_TLS1_3_LABEL( name, string ) \ .name = string, +#define TLS1_3_EVOLVE_INPUT_SIZE ( PSA_HASH_MAX_SIZE > PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE ) ? \ + PSA_HASH_MAX_SIZE : PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE + struct mbedtls_ssl_tls1_3_labels_struct const mbedtls_ssl_tls1_3_labels = { /* This seems to work in C, despite the string literal being one @@ -292,8 +296,8 @@ int mbedtls_ssl_tls1_3_evolve_secret( { int ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; size_t hlen, ilen; - unsigned char tmp_secret[ MBEDTLS_MD_MAX_SIZE ] = { 0 }; - unsigned char tmp_input [ MBEDTLS_MD_MAX_SIZE ] = { 0 }; + unsigned char tmp_secret[ PSA_MAC_MAX_SIZE ] = { 0 }; + unsigned char tmp_input [ TLS1_3_EVOLVE_INPUT_SIZE ] = { 0 }; const mbedtls_md_info_t *md; md = mbedtls_md_info_from_type( hash_alg ); diff --git a/thirdparty/mbedtls/library/timing.c b/thirdparty/mbedtls/library/timing.c index 78bfa10cfb..151292e325 100644 --- a/thirdparty/mbedtls/library/timing.c +++ b/thirdparty/mbedtls/library/timing.c @@ -19,12 +19,7 @@ #include "common.h" -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif #if defined(MBEDTLS_TIMING_C) @@ -269,7 +264,7 @@ static void TimerProc( void *TimerContext ) Sleep( alarmMs ); mbedtls_timing_alarmed = 1; /* _endthread will be called implicitly on return - * That ensures execution of thread funcition's epilogue */ + * That ensures execution of thread function's epilogue */ } void mbedtls_set_alarm( int seconds ) diff --git a/thirdparty/mbedtls/library/x509.c b/thirdparty/mbedtls/library/x509.c index 3997ebd1f3..54c8666d23 100644 --- a/thirdparty/mbedtls/library/x509.c +++ b/thirdparty/mbedtls/library/x509.c @@ -43,16 +43,7 @@ #include "mbedtls/pem.h" #endif -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#include <stdlib.h> -#define mbedtls_free free -#define mbedtls_calloc calloc -#define mbedtls_printf printf -#define mbedtls_snprintf snprintf -#endif #if defined(MBEDTLS_HAVE_TIME) #include "mbedtls/platform_time.h" @@ -198,7 +189,7 @@ static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md * * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other - * option. Enfore this at parsing time. + * option. Enforce this at parsing time. */ int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params, mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md, @@ -424,6 +415,11 @@ static int x509_get_attr_type_value( unsigned char **p, * For the general case we still use a flat list, but we mark elements of the * same set so that they are "merged" together in the functions that consume * this list, eg mbedtls_x509_dn_gets(). + * + * On success, this function may allocate a linked list starting at cur->next + * that must later be free'd by the caller using mbedtls_free(). In error + * cases, this function frees all allocated memory internally and the caller + * has no freeing responsibilities. */ int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end, mbedtls_x509_name *cur ) @@ -431,6 +427,8 @@ int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end, int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t set_len; const unsigned char *end_set; + mbedtls_x509_name *head = cur; + mbedtls_x509_name *prev, *allocated; /* don't use recursion, we'd risk stack overflow if not optimized */ while( 1 ) @@ -440,14 +438,17 @@ int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end, */ if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 ) - return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, ret ) ); + { + ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, ret ); + goto error; + } end_set = *p + set_len; while( 1 ) { if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 ) - return( ret ); + goto error; if( *p == end_set ) break; @@ -458,7 +459,10 @@ int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end, cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); if( cur->next == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + { + ret = MBEDTLS_ERR_X509_ALLOC_FAILED; + goto error; + } cur = cur->next; } @@ -472,10 +476,30 @@ int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end, cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); if( cur->next == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + { + ret = MBEDTLS_ERR_X509_ALLOC_FAILED; + goto error; + } cur = cur->next; } + +error: + /* Skip the first element as we did not allocate it */ + allocated = head->next; + + while( allocated != NULL ) + { + prev = allocated; + allocated = allocated->next; + + mbedtls_platform_zeroize( prev, sizeof( *prev ) ); + mbedtls_free( prev ); + } + + mbedtls_platform_zeroize( head, sizeof( *head ) ); + + return( ret ); } static int x509_parse_int( unsigned char **p, size_t n, int *res ) diff --git a/thirdparty/mbedtls/library/x509_crl.c b/thirdparty/mbedtls/library/x509_crl.c index d2d8042029..b943a8d6da 100644 --- a/thirdparty/mbedtls/library/x509_crl.c +++ b/thirdparty/mbedtls/library/x509_crl.c @@ -1,5 +1,5 @@ /* - * X.509 Certidicate Revocation List (CRL) parsing + * X.509 Certificate Revocation List (CRL) parsing * * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 @@ -42,15 +42,7 @@ #include "mbedtls/pem.h" #endif -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#include <stdio.h> -#define mbedtls_free free -#define mbedtls_calloc calloc -#define mbedtls_snprintf snprintf -#endif #if defined(MBEDTLS_HAVE_TIME) #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) diff --git a/thirdparty/mbedtls/library/x509_crt.c b/thirdparty/mbedtls/library/x509_crt.c index 96477e4c9d..4361f43ed0 100644 --- a/thirdparty/mbedtls/library/x509_crt.c +++ b/thirdparty/mbedtls/library/x509_crt.c @@ -49,15 +49,7 @@ #include "mbedtls/psa_util.h" #endif -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#include <stdlib.h> -#define mbedtls_free free -#define mbedtls_calloc calloc -#define mbedtls_snprintf snprintf -#endif #if defined(MBEDTLS_THREADING_C) #include "mbedtls/threading.h" @@ -90,6 +82,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <dirent.h> +#include <errno.h> #endif /* !_WIN32 || EFIX64 || EFI32 */ #endif @@ -1278,9 +1271,12 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, } } + int extensions_allowed = 1; #if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3) - if( crt->version == 3 ) + if( crt->version != 3 ) + extensions_allowed = 0; #endif + if( extensions_allowed ) { ret = x509_get_crt_ext( &p, end, crt, cb, p_ctx ); if( ret != 0 ) @@ -1668,8 +1664,22 @@ cleanup: } else if( stat( entry_name, &sb ) == -1 ) { - ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; - goto cleanup; + if( errno == ENOENT ) + { + /* Broken symbolic link - ignore this entry. + stat(2) will return this error for either (a) a dangling + symlink or (b) a missing file. + Given that we have just obtained the filename from readdir, + assume that it does exist and therefore treat this as a + dangling symlink. */ + continue; + } + else + { + /* Some other file error; report the error. */ + ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; + goto cleanup; + } } if( !S_ISREG( sb.st_mode ) ) @@ -1798,6 +1808,7 @@ static int x509_info_subject_alt_name( char **buf, size_t *size, const char *prefix ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t i; size_t n = *size; char *p = *buf; const mbedtls_x509_sequence *cur = subject_alt_name; @@ -1850,18 +1861,11 @@ static int x509_info_subject_alt_name( char **buf, size_t *size, ret = mbedtls_snprintf( p, n, "\n%s hardware serial number : ", prefix ); MBEDTLS_X509_SAFE_SNPRINTF; - if( other_name->value.hardware_module_name.val.len >= n ) + for( i = 0; i < other_name->value.hardware_module_name.val.len; i++ ) { - *p = '\0'; - return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL ); + ret = mbedtls_snprintf( p, n, "%02X", other_name->value.hardware_module_name.val.p[i] ); + MBEDTLS_X509_SAFE_SNPRINTF; } - - memcpy( p, other_name->value.hardware_module_name.val.p, - other_name->value.hardware_module_name.val.len ); - p += other_name->value.hardware_module_name.val.len; - - n -= other_name->value.hardware_module_name.val.len; - }/* MBEDTLS_OID_ON_HW_MODULE_NAME */ } break; diff --git a/thirdparty/mbedtls/library/x509_csr.c b/thirdparty/mbedtls/library/x509_csr.c index e259410d07..1a22b77086 100644 --- a/thirdparty/mbedtls/library/x509_csr.c +++ b/thirdparty/mbedtls/library/x509_csr.c @@ -42,15 +42,7 @@ #include "mbedtls/pem.h" #endif -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#include <stdio.h> -#define mbedtls_free free -#define mbedtls_calloc calloc -#define mbedtls_snprintf snprintf -#endif #if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32) #include <stdio.h> diff --git a/thirdparty/mbedtls/library/x509write_csr.c b/thirdparty/mbedtls/library/x509write_csr.c index afda950341..707dd001f0 100644 --- a/thirdparty/mbedtls/library/x509write_csr.c +++ b/thirdparty/mbedtls/library/x509write_csr.c @@ -44,13 +44,7 @@ #include "mbedtls/pem.h" #endif -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdlib.h> -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx ) { diff --git a/thirdparty/mbedtls/library/xtea.c b/thirdparty/mbedtls/library/xtea.c index 77f6cb6f67..28e6972aa8 100644 --- a/thirdparty/mbedtls/library/xtea.c +++ b/thirdparty/mbedtls/library/xtea.c @@ -1,5 +1,5 @@ /* - * An 32-bit implementation of the XTEA algorithm + * A 32-bit implementation of the XTEA algorithm * * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 @@ -26,14 +26,7 @@ #include <string.h> -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" -#else -#include <stdio.h> -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ #if !defined(MBEDTLS_XTEA_ALT) diff --git a/thirdparty/mbedtls/patches/1453.diff b/thirdparty/mbedtls/patches/1453.diff index b1c9c43ed2..4a7ca1570b 100644 --- a/thirdparty/mbedtls/patches/1453.diff +++ b/thirdparty/mbedtls/patches/1453.diff @@ -1,8 +1,8 @@ -diff --git a/library/entropy_poll.c b/library/entropy_poll.c -index 4556f88a5..ba56b70f7 100644 ---- a/library/entropy_poll.c -+++ b/library/entropy_poll.c -@@ -61,28 +61,43 @@ +diff --git a/thirdparty/mbedtls/library/entropy_poll.c b/thirdparty/mbedtls/library/entropy_poll.c +index a858c1892b..69ac29e4f7 100644 +--- a/thirdparty/mbedtls/library/entropy_poll.c ++++ b/thirdparty/mbedtls/library/entropy_poll.c +@@ -54,28 +54,43 @@ #define _WIN32_WINNT 0x0400 #endif #include <windows.h> @@ -53,12 +53,12 @@ index 4556f88a5..ba56b70f7 100644 *olen = len; return( 0 ); -diff --git a/library/x509_crt.c b/library/x509_crt.c -index 76558342e..35a134950 100644 ---- a/library/x509_crt.c -+++ b/library/x509_crt.c -@@ -65,6 +65,19 @@ - +diff --git a/thirdparty/mbedtls/library/x509_crt.c b/thirdparty/mbedtls/library/x509_crt.c +index def1414eca..4361f43ed0 100644 +--- a/thirdparty/mbedtls/library/x509_crt.c ++++ b/thirdparty/mbedtls/library/x509_crt.c +@@ -58,6 +58,19 @@ + #if defined(MBEDTLS_HAVE_TIME) #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) #include <windows.h> +#if defined(_MSC_VER) && _MSC_VER <= 1600 @@ -77,7 +77,7 @@ index 76558342e..35a134950 100644 #else #include <time.h> #endif -@@ -1278,6 +1291,7 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) +@@ -1549,6 +1562,7 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) char filename[MAX_PATH]; char *p; size_t len = strlen( path ); @@ -85,7 +85,7 @@ index 76558342e..35a134950 100644 WIN32_FIND_DATAW file_data; HANDLE hFind; -@@ -1292,7 +1306,18 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) +@@ -1563,7 +1577,18 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) p = filename + len; filename[len++] = '*'; @@ -105,7 +105,7 @@ index 76558342e..35a134950 100644 MAX_PATH - 3 ); if( w_ret == 0 ) return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); -@@ -1309,8 +1334,11 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) +@@ -1580,8 +1605,11 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) continue; diff --git a/thirdparty/mbedtls/patches/windows-arm64-hardclock.diff b/thirdparty/mbedtls/patches/windows-arm64-hardclock.diff new file mode 100644 index 0000000000..c7c5a7e282 --- /dev/null +++ b/thirdparty/mbedtls/patches/windows-arm64-hardclock.diff @@ -0,0 +1,16 @@ +diff --git a/thirdparty/mbedtls/library/timing.c b/thirdparty/mbedtls/library/timing.c +index 6c14a4fd01..151292e325 100644 +--- a/thirdparty/mbedtls/library/timing.c ++++ b/thirdparty/mbedtls/library/timing.c +@@ -190,8 +190,10 @@ unsigned long mbedtls_timing_hardclock( void ) + #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && __ia64__ */ + +-#if !defined(HAVE_HARDCLOCK) && defined(_MSC_VER) && \ ++// -- GODOT start -- ++#if !defined(HAVE_HARDCLOCK) && defined(_WIN32) && \ + !defined(EFIX64) && !defined(EFI32) ++// -- GODOT end -- + + #define HAVE_HARDCLOCK + diff --git a/thirdparty/meshoptimizer/LICENSE.md b/thirdparty/meshoptimizer/LICENSE.md index 3c52415f62..b673c248b2 100644 --- a/thirdparty/meshoptimizer/LICENSE.md +++ b/thirdparty/meshoptimizer/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2016-2021 Arseny Kapoulkine +Copyright (c) 2016-2022 Arseny Kapoulkine Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/meshoptimizer/clusterizer.cpp b/thirdparty/meshoptimizer/clusterizer.cpp index b1f7b359c1..c4672ad606 100644 --- a/thirdparty/meshoptimizer/clusterizer.cpp +++ b/thirdparty/meshoptimizer/clusterizer.cpp @@ -283,6 +283,79 @@ static bool appendMeshlet(meshopt_Meshlet& meshlet, unsigned int a, unsigned int return result; } +static unsigned int getNeighborTriangle(const meshopt_Meshlet& meshlet, const Cone* meshlet_cone, unsigned int* meshlet_vertices, const unsigned int* indices, const TriangleAdjacency2& adjacency, const Cone* triangles, const unsigned int* live_triangles, const unsigned char* used, float meshlet_expected_radius, float cone_weight, unsigned int* out_extra) +{ + unsigned int best_triangle = ~0u; + unsigned int best_extra = 5; + float best_score = FLT_MAX; + + for (size_t i = 0; i < meshlet.vertex_count; ++i) + { + unsigned int index = meshlet_vertices[meshlet.vertex_offset + i]; + + unsigned int* neighbors = &adjacency.data[0] + adjacency.offsets[index]; + size_t neighbors_size = adjacency.counts[index]; + + for (size_t j = 0; j < neighbors_size; ++j) + { + unsigned int triangle = neighbors[j]; + unsigned int a = indices[triangle * 3 + 0], b = indices[triangle * 3 + 1], c = indices[triangle * 3 + 2]; + + unsigned int extra = (used[a] == 0xff) + (used[b] == 0xff) + (used[c] == 0xff); + + // triangles that don't add new vertices to meshlets are max. priority + if (extra != 0) + { + // artificially increase the priority of dangling triangles as they're expensive to add to new meshlets + if (live_triangles[a] == 1 || live_triangles[b] == 1 || live_triangles[c] == 1) + extra = 0; + + extra++; + } + + // since topology-based priority is always more important than the score, we can skip scoring in some cases + if (extra > best_extra) + continue; + + float score = 0; + + // caller selects one of two scoring functions: geometrical (based on meshlet cone) or topological (based on remaining triangles) + if (meshlet_cone) + { + const Cone& tri_cone = triangles[triangle]; + + float distance2 = + (tri_cone.px - meshlet_cone->px) * (tri_cone.px - meshlet_cone->px) + + (tri_cone.py - meshlet_cone->py) * (tri_cone.py - meshlet_cone->py) + + (tri_cone.pz - meshlet_cone->pz) * (tri_cone.pz - meshlet_cone->pz); + + float spread = tri_cone.nx * meshlet_cone->nx + tri_cone.ny * meshlet_cone->ny + tri_cone.nz * meshlet_cone->nz; + + score = getMeshletScore(distance2, spread, cone_weight, meshlet_expected_radius); + } + else + { + // each live_triangles entry is >= 1 since it includes the current triangle we're processing + score = float(live_triangles[a] + live_triangles[b] + live_triangles[c] - 3); + } + + // note that topology-based priority is always more important than the score + // this helps maintain reasonable effectiveness of meshlet data and reduces scoring cost + if (extra < best_extra || score < best_score) + { + best_triangle = triangle; + best_extra = extra; + best_score = score; + } + } + } + + if (out_extra) + *out_extra = best_extra; + + return best_triangle; +} + struct KDNode { union @@ -464,13 +537,15 @@ size_t meshopt_buildMeshlets(meshopt_Meshlet* meshlets, unsigned int* meshlet_ve using namespace meshopt; assert(index_count % 3 == 0); - assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256); + assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256); assert(vertex_positions_stride % sizeof(float) == 0); assert(max_vertices >= 3 && max_vertices <= kMeshletMaxVertices); assert(max_triangles >= 1 && max_triangles <= kMeshletMaxTriangles); assert(max_triangles % 4 == 0); // ensures the caller will compute output space properly as index data is 4b aligned + assert(cone_weight >= 0 && cone_weight <= 1); + meshopt_Allocator allocator; TriangleAdjacency2 adjacency = {}; @@ -511,65 +586,18 @@ size_t meshopt_buildMeshlets(meshopt_Meshlet* meshlets, unsigned int* meshlet_ve for (;;) { - unsigned int best_triangle = ~0u; - unsigned int best_extra = 5; - float best_score = FLT_MAX; - Cone meshlet_cone = getMeshletCone(meshlet_cone_acc, meshlet.triangle_count); - for (size_t i = 0; i < meshlet.vertex_count; ++i) - { - unsigned int index = meshlet_vertices[meshlet.vertex_offset + i]; - - unsigned int* neighbours = &adjacency.data[0] + adjacency.offsets[index]; - size_t neighbours_size = adjacency.counts[index]; - - for (size_t j = 0; j < neighbours_size; ++j) - { - unsigned int triangle = neighbours[j]; - assert(!emitted_flags[triangle]); - - unsigned int a = indices[triangle * 3 + 0], b = indices[triangle * 3 + 1], c = indices[triangle * 3 + 2]; - assert(a < vertex_count && b < vertex_count && c < vertex_count); - - unsigned int extra = (used[a] == 0xff) + (used[b] == 0xff) + (used[c] == 0xff); - - // triangles that don't add new vertices to meshlets are max. priority - if (extra != 0) - { - // artificially increase the priority of dangling triangles as they're expensive to add to new meshlets - if (live_triangles[a] == 1 || live_triangles[b] == 1 || live_triangles[c] == 1) - extra = 0; - - extra++; - } - - // since topology-based priority is always more important than the score, we can skip scoring in some cases - if (extra > best_extra) - continue; - - const Cone& tri_cone = triangles[triangle]; - - float distance2 = - (tri_cone.px - meshlet_cone.px) * (tri_cone.px - meshlet_cone.px) + - (tri_cone.py - meshlet_cone.py) * (tri_cone.py - meshlet_cone.py) + - (tri_cone.pz - meshlet_cone.pz) * (tri_cone.pz - meshlet_cone.pz); - - float spread = tri_cone.nx * meshlet_cone.nx + tri_cone.ny * meshlet_cone.ny + tri_cone.nz * meshlet_cone.nz; + unsigned int best_extra = 0; + unsigned int best_triangle = getNeighborTriangle(meshlet, &meshlet_cone, meshlet_vertices, indices, adjacency, triangles, live_triangles, used, meshlet_expected_radius, cone_weight, &best_extra); - float score = getMeshletScore(distance2, spread, cone_weight, meshlet_expected_radius); - - // note that topology-based priority is always more important than the score - // this helps maintain reasonable effectiveness of meshlet data and reduces scoring cost - if (extra < best_extra || score < best_score) - { - best_triangle = triangle; - best_extra = extra; - best_score = score; - } - } + // if the best triangle doesn't fit into current meshlet, the spatial scoring we've used is not very meaningful, so we re-select using topological scoring + if (best_triangle != ~0u && (meshlet.vertex_count + best_extra > max_vertices || meshlet.triangle_count >= max_triangles)) + { + best_triangle = getNeighborTriangle(meshlet, NULL, meshlet_vertices, indices, adjacency, triangles, live_triangles, used, meshlet_expected_radius, 0.f, NULL); } + // when we run out of neighboring triangles we need to switch to spatial search; we currently just pick the closest triangle irrespective of connectivity if (best_triangle == ~0u) { float position[3] = {meshlet_cone.px, meshlet_cone.py, meshlet_cone.pz}; @@ -604,16 +632,16 @@ size_t meshopt_buildMeshlets(meshopt_Meshlet* meshlets, unsigned int* meshlet_ve { unsigned int index = indices[best_triangle * 3 + k]; - unsigned int* neighbours = &adjacency.data[0] + adjacency.offsets[index]; - size_t neighbours_size = adjacency.counts[index]; + unsigned int* neighbors = &adjacency.data[0] + adjacency.offsets[index]; + size_t neighbors_size = adjacency.counts[index]; - for (size_t i = 0; i < neighbours_size; ++i) + for (size_t i = 0; i < neighbors_size; ++i) { - unsigned int tri = neighbours[i]; + unsigned int tri = neighbors[i]; if (tri == best_triangle) { - neighbours[i] = neighbours[neighbours_size - 1]; + neighbors[i] = neighbors[neighbors_size - 1]; adjacency.counts[index]--; break; } @@ -687,7 +715,7 @@ meshopt_Bounds meshopt_computeClusterBounds(const unsigned int* indices, size_t assert(index_count % 3 == 0); assert(index_count / 3 <= kMeshletMaxTriangles); - assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256); + assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256); assert(vertex_positions_stride % sizeof(float) == 0); (void)vertex_count; @@ -839,7 +867,7 @@ meshopt_Bounds meshopt_computeMeshletBounds(const unsigned int* meshlet_vertices using namespace meshopt; assert(triangle_count <= kMeshletMaxTriangles); - assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256); + assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256); assert(vertex_positions_stride % sizeof(float) == 0); unsigned int indices[kMeshletMaxTriangles * 3]; diff --git a/thirdparty/meshoptimizer/indexgenerator.cpp b/thirdparty/meshoptimizer/indexgenerator.cpp index f60db0dc4f..cad808a2b1 100644 --- a/thirdparty/meshoptimizer/indexgenerator.cpp +++ b/thirdparty/meshoptimizer/indexgenerator.cpp @@ -187,7 +187,7 @@ size_t meshopt_generateVertexRemap(unsigned int* destination, const unsigned int using namespace meshopt; assert(indices || index_count == vertex_count); - assert(index_count % 3 == 0); + assert(!indices || index_count % 3 == 0); assert(vertex_size > 0 && vertex_size <= 256); meshopt_Allocator allocator; @@ -412,7 +412,7 @@ void meshopt_generateAdjacencyIndexBuffer(unsigned int* destination, const unsig using namespace meshopt; assert(index_count % 3 == 0); - assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256); + assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256); assert(vertex_positions_stride % sizeof(float) == 0); meshopt_Allocator allocator; @@ -483,7 +483,7 @@ void meshopt_generateTessellationIndexBuffer(unsigned int* destination, const un using namespace meshopt; assert(index_count % 3 == 0); - assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256); + assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256); assert(vertex_positions_stride % sizeof(float) == 0); meshopt_Allocator allocator; diff --git a/thirdparty/meshoptimizer/meshoptimizer.h b/thirdparty/meshoptimizer/meshoptimizer.h index 463fad29da..46d28d3ea3 100644 --- a/thirdparty/meshoptimizer/meshoptimizer.h +++ b/thirdparty/meshoptimizer/meshoptimizer.h @@ -1,7 +1,7 @@ /** - * meshoptimizer - version 0.17 + * meshoptimizer - version 0.18 * - * Copyright (C) 2016-2021, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) + * Copyright (C) 2016-2022, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) * Report bugs and download new versions at https://github.com/zeux/meshoptimizer * * This library is distributed under the MIT License. See notice at the end of this file. @@ -12,7 +12,7 @@ #include <stddef.h> /* Version macro; major * 1000 + minor * 10 + patch */ -#define MESHOPTIMIZER_VERSION 170 /* 0.17 */ +#define MESHOPTIMIZER_VERSION 180 /* 0.18 */ /* If no API is defined, assume default */ #ifndef MESHOPTIMIZER_API @@ -37,8 +37,8 @@ extern "C" { #endif /** - * Vertex attribute stream, similar to glVertexPointer - * Each element takes size bytes, with stride controlling the spacing between successive elements. + * Vertex attribute stream + * Each element takes size bytes, beginning at data, with stride controlling the spacing between successive elements (stride >= size). */ struct meshopt_Stream { @@ -115,7 +115,7 @@ MESHOPTIMIZER_API void meshopt_generateShadowIndexBufferMulti(unsigned int* dest * This can be used to implement algorithms like silhouette detection/expansion and other forms of GS-driven rendering. * * destination must contain enough space for the resulting index buffer (index_count*2 elements) - * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer + * vertex_positions should have float3 position in the first 12 bytes of each vertex */ MESHOPTIMIZER_API void meshopt_generateAdjacencyIndexBuffer(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride); @@ -131,7 +131,7 @@ MESHOPTIMIZER_API void meshopt_generateAdjacencyIndexBuffer(unsigned int* destin * See "Tessellation on Any Budget" (John McDonald, GDC 2011) for implementation details. * * destination must contain enough space for the resulting index buffer (index_count*4 elements) - * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer + * vertex_positions should have float3 position in the first 12 bytes of each vertex */ MESHOPTIMIZER_API void meshopt_generateTessellationIndexBuffer(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride); @@ -171,7 +171,7 @@ MESHOPTIMIZER_API void meshopt_optimizeVertexCacheFifo(unsigned int* destination * * destination must contain enough space for the resulting index buffer (index_count elements) * indices must contain index data that is the result of meshopt_optimizeVertexCache (*not* the original mesh indices!) - * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer + * vertex_positions should have float3 position in the first 12 bytes of each vertex * threshold indicates how much the overdraw optimizer can degrade vertex cache efficiency (1.05 = up to 5%) to reduce overdraw more efficiently */ MESHOPTIMIZER_API void meshopt_optimizeOverdraw(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, float threshold); @@ -313,7 +313,21 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterQuat(void* destination, size MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterExp(void* destination, size_t count, size_t stride, int bits, const float* data); /** - * Experimental: Mesh simplifier + * Simplification options + */ +enum +{ + /* Do not move vertices that are located on the topological border (vertices on triangle edges that don't have a paired triangle). Useful for simplifying portions of the larger mesh. */ + meshopt_SimplifyLockBorder = 1 << 0, +}; + +/** + * Experimental: Mesh simplifier with attribute metric; attributes follow xyz position data atm (vertex data must contain 3 + attribute_count floats per vertex) + */ +MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, unsigned int options, float* result_error, const float* attributes, const float* attribute_weights, size_t attribute_count); + +/** + * Mesh simplifier * Reduces the number of triangles in the mesh, attempting to preserve mesh appearance as much as possible * The algorithm tries to preserve mesh topology and can stop short of the target goal based on topology constraints or target error. * If not all attributes from the input mesh are required, it's recommended to reindex the mesh using meshopt_generateShadowIndexBuffer prior to simplification. @@ -322,16 +336,12 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterExp(void* destination, size_ * If the original vertex data isn't required, creating a compact vertex buffer using meshopt_optimizeVertexFetch is recommended. * * destination must contain enough space for the target index buffer, worst case is index_count elements (*not* target_index_count)! - * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer - * target_error represents the error relative to mesh extents that can be tolerated, e.g. 0.01 = 1% deformation + * vertex_positions should have float3 position in the first 12 bytes of each vertex + * target_error represents the error relative to mesh extents that can be tolerated, e.g. 0.01 = 1% deformation; value range [0..1] + * options must be a bitmask composed of meshopt_SimplifyX options; 0 is a safe default * result_error can be NULL; when it's not NULL, it will contain the resulting (relative) error after simplification */ -MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error); - -/** - * Experimental: Mesh simplifier with attribute metric; attributes follow xyz position data atm (vertex data must contain 3 + attribute_count floats per vertex) - */ -MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, float* result_error, const float* attributes, const float* attribute_weights, size_t attribute_count); +MESHOPTIMIZER_API size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options, float* result_error); /** * Experimental: Mesh simplifier (sloppy) @@ -342,8 +352,8 @@ MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* d * If the original vertex data isn't required, creating a compact vertex buffer using meshopt_optimizeVertexFetch is recommended. * * destination must contain enough space for the target index buffer, worst case is index_count elements (*not* target_index_count)! - * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer - * target_error represents the error relative to mesh extents that can be tolerated, e.g. 0.01 = 1% deformation + * vertex_positions should have float3 position in the first 12 bytes of each vertex + * target_error represents the error relative to mesh extents that can be tolerated, e.g. 0.01 = 1% deformation; value range [0..1] * result_error can be NULL; when it's not NULL, it will contain the resulting (relative) error after simplification */ MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error); @@ -356,17 +366,17 @@ MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifySloppy(unsigned int* destinati * If the original vertex data isn't required, creating a compact vertex buffer using meshopt_optimizeVertexFetch is recommended. * * destination must contain enough space for the target index buffer (target_vertex_count elements) - * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer + * vertex_positions should have float3 position in the first 12 bytes of each vertex */ MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyPoints(unsigned int* destination, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_vertex_count); /** - * Experimental: Returns the error scaling factor used by the simplifier to convert between absolute and relative extents + * Returns the error scaling factor used by the simplifier to convert between absolute and relative extents * * Absolute error must be *divided* by the scaling factor before passing it to meshopt_simplify as target_error * Relative error returned by meshopt_simplify via result_error must be *multiplied* by the scaling factor to get absolute error. */ -MESHOPTIMIZER_EXPERIMENTAL float meshopt_simplifyScale(const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride); +MESHOPTIMIZER_API float meshopt_simplifyScale(const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride); /** * Mesh stripifier @@ -418,7 +428,7 @@ struct meshopt_OverdrawStatistics * Returns overdraw statistics using a software rasterizer * Results may not match actual GPU performance * - * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer + * vertex_positions should have float3 position in the first 12 bytes of each vertex */ MESHOPTIMIZER_API struct meshopt_OverdrawStatistics meshopt_analyzeOverdraw(const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride); @@ -456,7 +466,7 @@ struct meshopt_Meshlet * meshlets must contain enough space for all meshlets, worst case size can be computed with meshopt_buildMeshletsBound * meshlet_vertices must contain enough space for all meshlets, worst case size is equal to max_meshlets * max_vertices * meshlet_triangles must contain enough space for all meshlets, worst case size is equal to max_meshlets * max_triangles * 3 - * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer + * vertex_positions should have float3 position in the first 12 bytes of each vertex * max_vertices and max_triangles must not exceed implementation limits (max_vertices <= 255 - not 256!, max_triangles <= 512) * cone_weight should be set to 0 when cone culling is not used, and a value between 0 and 1 otherwise to balance between cluster size and cone culling efficiency */ @@ -498,7 +508,7 @@ struct meshopt_Bounds * The formula that uses the apex is slightly more accurate but needs the apex; if you are already using bounding sphere * to do frustum/occlusion culling, the formula that doesn't use the apex may be preferable. * - * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer + * vertex_positions should have float3 position in the first 12 bytes of each vertex * index_count/3 should be less than or equal to 512 (the function assumes clusters of limited size) */ MESHOPTIMIZER_API struct meshopt_Bounds meshopt_computeClusterBounds(const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride); @@ -518,7 +528,7 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_spatialSortRemap(unsigned int* destinati * Reorders triangles for spatial locality, and generates a new index buffer. The resulting index buffer can be used with other functions like optimizeVertexCache. * * destination must contain enough space for the resulting index buffer (index_count elements) - * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer + * vertex_positions should have float3 position in the first 12 bytes of each vertex */ MESHOPTIMIZER_EXPERIMENTAL void meshopt_spatialSortTriangles(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride); @@ -610,7 +620,7 @@ inline size_t meshopt_encodeIndexSequence(unsigned char* buffer, size_t buffer_s template <typename T> inline int meshopt_decodeIndexSequence(T* destination, size_t index_count, const unsigned char* buffer, size_t buffer_size); template <typename T> -inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error = 0); +inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options = 0, float* result_error = 0); template <typename T> inline size_t meshopt_simplifySloppy(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error = 0); template <typename T> @@ -945,12 +955,12 @@ inline int meshopt_decodeIndexSequence(T* destination, size_t index_count, const } template <typename T> -inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error) +inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options, float* result_error) { meshopt_IndexAdapter<T> in(0, indices, index_count); meshopt_IndexAdapter<T> out(destination, 0, index_count); - return meshopt_simplify(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, target_index_count, target_error, result_error); + return meshopt_simplify(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, target_index_count, target_error, options, result_error); } template <typename T> @@ -1039,7 +1049,7 @@ inline void meshopt_spatialSortTriangles(T* destination, const T* indices, size_ #endif /** - * Copyright (c) 2016-2021 Arseny Kapoulkine + * Copyright (c) 2016-2022 Arseny Kapoulkine * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/thirdparty/meshoptimizer/overdrawanalyzer.cpp b/thirdparty/meshoptimizer/overdrawanalyzer.cpp index 8d5859ba39..8b6f254134 100644 --- a/thirdparty/meshoptimizer/overdrawanalyzer.cpp +++ b/thirdparty/meshoptimizer/overdrawanalyzer.cpp @@ -147,7 +147,7 @@ meshopt_OverdrawStatistics meshopt_analyzeOverdraw(const unsigned int* indices, using namespace meshopt; assert(index_count % 3 == 0); - assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256); + assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256); assert(vertex_positions_stride % sizeof(float) == 0); meshopt_Allocator allocator; diff --git a/thirdparty/meshoptimizer/overdrawoptimizer.cpp b/thirdparty/meshoptimizer/overdrawoptimizer.cpp index 143656ed76..cc22dbcffc 100644 --- a/thirdparty/meshoptimizer/overdrawoptimizer.cpp +++ b/thirdparty/meshoptimizer/overdrawoptimizer.cpp @@ -272,7 +272,7 @@ void meshopt_optimizeOverdraw(unsigned int* destination, const unsigned int* ind using namespace meshopt; assert(index_count % 3 == 0); - assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256); + assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256); assert(vertex_positions_stride % sizeof(float) == 0); meshopt_Allocator allocator; diff --git a/thirdparty/meshoptimizer/patches/attribute-aware-simplify-distance-only-metric.patch b/thirdparty/meshoptimizer/patches/attribute-aware-simplify-distance-only-metric.patch index 21daac6eec..5cac985dc5 100644 --- a/thirdparty/meshoptimizer/patches/attribute-aware-simplify-distance-only-metric.patch +++ b/thirdparty/meshoptimizer/patches/attribute-aware-simplify-distance-only-metric.patch @@ -1,5 +1,5 @@ diff --git a/thirdparty/meshoptimizer/simplifier.cpp b/thirdparty/meshoptimizer/simplifier.cpp -index 5e92e2dc73..e40c141e76 100644 +index d8d4a67391..3847afc736 100644 --- a/thirdparty/meshoptimizer/simplifier.cpp +++ b/thirdparty/meshoptimizer/simplifier.cpp @@ -20,7 +20,7 @@ @@ -11,7 +11,7 @@ index 5e92e2dc73..e40c141e76 100644 // This work is based on: // Michael Garland and Paul S. Heckbert. Surface simplification using quadric error metrics. 1997 -@@ -453,6 +453,7 @@ struct Collapse +@@ -458,6 +458,7 @@ struct Collapse float error; unsigned int errorui; }; @@ -19,7 +19,7 @@ index 5e92e2dc73..e40c141e76 100644 }; static float normalize(Vector3& v) -@@ -533,6 +534,34 @@ static float quadricError(const Quadric& Q, const Vector3& v) +@@ -538,6 +539,34 @@ static float quadricError(const Quadric& Q, const Vector3& v) return fabsf(r) * s; } @@ -54,7 +54,7 @@ index 5e92e2dc73..e40c141e76 100644 static void quadricFromPlane(Quadric& Q, float a, float b, float c, float d, float w) { float aw = a * w; -@@ -688,7 +717,7 @@ static void quadricUpdateAttributes(Quadric& Q, const Vector3& p0, const Vector3 +@@ -693,7 +722,7 @@ static void quadricUpdateAttributes(Quadric& Q, const Vector3& p0, const Vector3 } #endif @@ -63,7 +63,7 @@ index 5e92e2dc73..e40c141e76 100644 { for (size_t i = 0; i < index_count; i += 3) { -@@ -698,6 +727,9 @@ static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indic +@@ -703,6 +732,9 @@ static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indic Quadric Q; quadricFromTriangle(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], 1.f); @@ -73,7 +73,7 @@ index 5e92e2dc73..e40c141e76 100644 #if ATTRIBUTES quadricUpdateAttributes(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], Q.w); -@@ -708,7 +740,7 @@ static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indic +@@ -713,7 +745,7 @@ static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indic } } @@ -82,7 +82,7 @@ index 5e92e2dc73..e40c141e76 100644 { for (size_t i = 0; i < index_count; i += 3) { -@@ -752,6 +784,9 @@ static void fillEdgeQuadrics(Quadric* vertex_quadrics, const unsigned int* indic +@@ -757,6 +789,9 @@ static void fillEdgeQuadrics(Quadric* vertex_quadrics, const unsigned int* indic quadricAdd(vertex_quadrics[remap[i0]], Q); quadricAdd(vertex_quadrics[remap[i1]], Q); @@ -92,7 +92,7 @@ index 5e92e2dc73..e40c141e76 100644 } } } -@@ -856,7 +891,7 @@ static size_t pickEdgeCollapses(Collapse* collapses, const unsigned int* indices +@@ -861,7 +896,7 @@ static size_t pickEdgeCollapses(Collapse* collapses, const unsigned int* indices return collapse_count; } @@ -101,7 +101,7 @@ index 5e92e2dc73..e40c141e76 100644 { for (size_t i = 0; i < collapse_count; ++i) { -@@ -876,10 +911,14 @@ static void rankEdgeCollapses(Collapse* collapses, size_t collapse_count, const +@@ -881,10 +916,14 @@ static void rankEdgeCollapses(Collapse* collapses, size_t collapse_count, const float ei = quadricError(qi, vertex_positions[i1]); float ej = quadricError(qj, vertex_positions[j1]); @@ -116,7 +116,7 @@ index 5e92e2dc73..e40c141e76 100644 } } -@@ -976,7 +1015,7 @@ static void sortEdgeCollapses(unsigned int* sort_order, const Collapse* collapse +@@ -981,7 +1020,7 @@ static void sortEdgeCollapses(unsigned int* sort_order, const Collapse* collapse } } @@ -125,7 +125,7 @@ index 5e92e2dc73..e40c141e76 100644 { size_t edge_collapses = 0; size_t triangle_collapses = 0; -@@ -1038,6 +1077,7 @@ static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char* +@@ -1043,6 +1082,7 @@ static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char* assert(collapse_remap[r1] == r1); quadricAdd(vertex_quadrics[r1], vertex_quadrics[r0]); @@ -133,7 +133,7 @@ index 5e92e2dc73..e40c141e76 100644 if (vertex_kind[i0] == Kind_Complex) { -@@ -1075,7 +1115,7 @@ static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char* +@@ -1080,7 +1120,7 @@ static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char* triangle_collapses += (vertex_kind[i0] == Kind_Border) ? 1 : 2; edge_collapses++; @@ -142,7 +142,7 @@ index 5e92e2dc73..e40c141e76 100644 } #if TRACE -@@ -1463,9 +1503,11 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned +@@ -1469,9 +1509,11 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned Quadric* vertex_quadrics = allocator.allocate<Quadric>(vertex_count); memset(vertex_quadrics, 0, vertex_count * sizeof(Quadric)); @@ -156,7 +156,7 @@ index 5e92e2dc73..e40c141e76 100644 if (result != indices) memcpy(result, indices, index_count * sizeof(unsigned int)); -@@ -1496,7 +1538,7 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned +@@ -1502,7 +1544,7 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned if (edge_collapse_count == 0) break; @@ -165,7 +165,7 @@ index 5e92e2dc73..e40c141e76 100644 #if TRACE > 1 dumpEdgeCollapses(edge_collapses, edge_collapse_count, vertex_kind); -@@ -1515,7 +1557,7 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned +@@ -1521,7 +1563,7 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned printf("pass %d: ", int(pass_count++)); #endif diff --git a/thirdparty/meshoptimizer/patches/attribute-aware-simplify.patch b/thirdparty/meshoptimizer/patches/attribute-aware-simplify.patch index 33a17fe9fa..c065026a7d 100644 --- a/thirdparty/meshoptimizer/patches/attribute-aware-simplify.patch +++ b/thirdparty/meshoptimizer/patches/attribute-aware-simplify.patch @@ -1,21 +1,21 @@ diff --git a/thirdparty/meshoptimizer/meshoptimizer.h b/thirdparty/meshoptimizer/meshoptimizer.h -index be4b765d97..463fad29da 100644 +index d95725dd71..46d28d3ea3 100644 --- a/thirdparty/meshoptimizer/meshoptimizer.h +++ b/thirdparty/meshoptimizer/meshoptimizer.h -@@ -328,6 +328,11 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterExp(void* destination, size_ - */ - MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error); +@@ -321,6 +321,11 @@ enum + meshopt_SimplifyLockBorder = 1 << 0, + }; +/** + * Experimental: Mesh simplifier with attribute metric; attributes follow xyz position data atm (vertex data must contain 3 + attribute_count floats per vertex) + */ -+MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, float* result_error, const float* attributes, const float* attribute_weights, size_t attribute_count); ++MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, unsigned int options, float* result_error, const float* attributes, const float* attribute_weights, size_t attribute_count); + /** - * Experimental: Mesh simplifier (sloppy) - * Reduces the number of triangles in the mesh, sacrificing mesh appearance for simplification performance + * Mesh simplifier + * Reduces the number of triangles in the mesh, attempting to preserve mesh appearance as much as possible diff --git a/thirdparty/meshoptimizer/simplifier.cpp b/thirdparty/meshoptimizer/simplifier.cpp -index a74b08a97d..5e92e2dc73 100644 +index 5f0e9bac31..797329b010 100644 --- a/thirdparty/meshoptimizer/simplifier.cpp +++ b/thirdparty/meshoptimizer/simplifier.cpp @@ -20,6 +20,8 @@ @@ -27,7 +27,7 @@ index a74b08a97d..5e92e2dc73 100644 // This work is based on: // Michael Garland and Paul S. Heckbert. Surface simplification using quadric error metrics. 1997 // Michael Garland. Quadric-based polygonal surface simplification. 1999 -@@ -371,6 +373,10 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned +@@ -376,6 +378,10 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned struct Vector3 { float x, y, z; @@ -38,7 +38,7 @@ index a74b08a97d..5e92e2dc73 100644 }; static float rescalePositions(Vector3* result, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride) -@@ -427,6 +433,13 @@ struct Quadric +@@ -432,6 +438,13 @@ struct Quadric float a10, a20, a21; float b0, b1, b2, c; float w; @@ -52,7 +52,7 @@ index a74b08a97d..5e92e2dc73 100644 }; struct Collapse -@@ -469,6 +482,16 @@ static void quadricAdd(Quadric& Q, const Quadric& R) +@@ -474,6 +487,16 @@ static void quadricAdd(Quadric& Q, const Quadric& R) Q.b2 += R.b2; Q.c += R.c; Q.w += R.w; @@ -69,7 +69,7 @@ index a74b08a97d..5e92e2dc73 100644 } static float quadricError(const Quadric& Q, const Vector3& v) -@@ -494,6 +517,17 @@ static float quadricError(const Quadric& Q, const Vector3& v) +@@ -499,6 +522,17 @@ static float quadricError(const Quadric& Q, const Vector3& v) r += ry * v.y; r += rz * v.z; @@ -87,7 +87,7 @@ index a74b08a97d..5e92e2dc73 100644 float s = Q.w == 0.f ? 0.f : 1.f / Q.w; return fabsf(r) * s; -@@ -517,6 +551,13 @@ static void quadricFromPlane(Quadric& Q, float a, float b, float c, float d, flo +@@ -522,6 +556,13 @@ static void quadricFromPlane(Quadric& Q, float a, float b, float c, float d, flo Q.b2 = c * dw; Q.c = d * dw; Q.w = w; @@ -101,7 +101,7 @@ index a74b08a97d..5e92e2dc73 100644 } static void quadricFromPoint(Quadric& Q, float x, float y, float z, float w) -@@ -569,6 +610,84 @@ static void quadricFromTriangleEdge(Quadric& Q, const Vector3& p0, const Vector3 +@@ -574,6 +615,84 @@ static void quadricFromTriangleEdge(Quadric& Q, const Vector3& p0, const Vector3 quadricFromPlane(Q, normal.x, normal.y, normal.z, -distance, length * weight); } @@ -186,7 +186,7 @@ index a74b08a97d..5e92e2dc73 100644 static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indices, size_t index_count, const Vector3* vertex_positions, const unsigned int* remap) { for (size_t i = 0; i < index_count; i += 3) -@@ -580,6 +699,9 @@ static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indic +@@ -585,6 +704,9 @@ static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indic Quadric Q; quadricFromTriangle(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], 1.f); @@ -196,29 +196,30 @@ index a74b08a97d..5e92e2dc73 100644 quadricAdd(vertex_quadrics[remap[i0]], Q); quadricAdd(vertex_quadrics[remap[i1]], Q); quadricAdd(vertex_quadrics[remap[i2]], Q); -@@ -1273,13 +1395,19 @@ MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack = 0; +@@ -1278,14 +1400,20 @@ MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack = 0; #endif - size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* out_result_error) + size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options, float* out_result_error) +{ -+ return meshopt_simplifyWithAttributes(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, target_index_count, target_error, out_result_error, 0, 0, 0); ++ return meshopt_simplifyWithAttributes(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, target_index_count, target_error, options, out_result_error, 0, 0, 0); +} + -+size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, float* out_result_error, const float* attributes, const float* attribute_weights, size_t attribute_count) ++size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, unsigned int options, float* out_result_error, const float* attributes, const float* attribute_weights, size_t attribute_count) { using namespace meshopt; assert(index_count % 3 == 0); -- assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256); +- assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256); - assert(vertex_positions_stride % sizeof(float) == 0); -+ assert(vertex_stride > 0 && vertex_stride <= 256); ++ assert(vertex_stride >= 12 && vertex_stride <= 256); + assert(vertex_stride % sizeof(float) == 0); assert(target_index_count <= index_count); + assert((options & ~(meshopt_SimplifyLockBorder)) == 0); + assert(attribute_count <= ATTRIBUTES); meshopt_Allocator allocator; -@@ -1293,7 +1421,7 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, +@@ -1299,7 +1427,7 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, // build position remap that maps each vertex to the one with identical position unsigned int* remap = allocator.allocate<unsigned int>(vertex_count); unsigned int* wedge = allocator.allocate<unsigned int>(vertex_count); @@ -227,7 +228,7 @@ index a74b08a97d..5e92e2dc73 100644 // classify vertices; vertex kind determines collapse rules, see kCanCollapse unsigned char* vertex_kind = allocator.allocate<unsigned char>(vertex_count); -@@ -1317,7 +1445,21 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, +@@ -1323,7 +1451,21 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, #endif Vector3* vertex_positions = allocator.allocate<Vector3>(vertex_count); @@ -250,7 +251,7 @@ index a74b08a97d..5e92e2dc73 100644 Quadric* vertex_quadrics = allocator.allocate<Quadric>(vertex_count); memset(vertex_quadrics, 0, vertex_count * sizeof(Quadric)); -@@ -1409,7 +1551,9 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, +@@ -1415,7 +1557,9 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, // result_error is quadratic; we need to remap it back to linear if (out_result_error) diff --git a/thirdparty/meshoptimizer/simplifier.cpp b/thirdparty/meshoptimizer/simplifier.cpp index e40c141e76..391a77861a 100644 --- a/thirdparty/meshoptimizer/simplifier.cpp +++ b/thirdparty/meshoptimizer/simplifier.cpp @@ -254,7 +254,7 @@ static bool hasEdge(const EdgeAdjacency& adjacency, unsigned int a, unsigned int return false; } -static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned int* loopback, size_t vertex_count, const EdgeAdjacency& adjacency, const unsigned int* remap, const unsigned int* wedge) +static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned int* loopback, size_t vertex_count, const EdgeAdjacency& adjacency, const unsigned int* remap, const unsigned int* wedge, unsigned int options) { memset(loop, -1, vertex_count * sizeof(unsigned int)); memset(loopback, -1, vertex_count * sizeof(unsigned int)); @@ -364,6 +364,11 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned } } + if (options & meshopt_SimplifyLockBorder) + for (size_t i = 0; i < vertex_count; ++i) + if (result[i] == Kind_Border) + result[i] = Kind_Locked; + #if TRACE printf("locked: many open edges %d, disconnected seam %d, many seam edges %d, many wedges %d\n", int(stats[0]), int(stats[1]), int(stats[2]), int(stats[3])); @@ -1434,19 +1439,20 @@ MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoop = 0; MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack = 0; #endif -size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* out_result_error) +size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options, float* out_result_error) { - return meshopt_simplifyWithAttributes(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, target_index_count, target_error, out_result_error, 0, 0, 0); + return meshopt_simplifyWithAttributes(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, target_index_count, target_error, options, out_result_error, 0, 0, 0); } -size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, float* out_result_error, const float* attributes, const float* attribute_weights, size_t attribute_count) +size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, unsigned int options, float* out_result_error, const float* attributes, const float* attribute_weights, size_t attribute_count) { using namespace meshopt; assert(index_count % 3 == 0); - assert(vertex_stride > 0 && vertex_stride <= 256); + assert(vertex_stride >= 12 && vertex_stride <= 256); assert(vertex_stride % sizeof(float) == 0); assert(target_index_count <= index_count); + assert((options & ~(meshopt_SimplifyLockBorder)) == 0); assert(attribute_count <= ATTRIBUTES); meshopt_Allocator allocator; @@ -1467,7 +1473,7 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned unsigned char* vertex_kind = allocator.allocate<unsigned char>(vertex_count); unsigned int* loop = allocator.allocate<unsigned int>(vertex_count); unsigned int* loopback = allocator.allocate<unsigned int>(vertex_count); - classifyVertices(vertex_kind, loop, loopback, vertex_count, adjacency, remap, wedge); + classifyVertices(vertex_kind, loop, loopback, vertex_count, adjacency, remap, wedge, options); #if TRACE size_t unique_positions = 0; @@ -1605,7 +1611,7 @@ size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* ind using namespace meshopt; assert(index_count % 3 == 0); - assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256); + assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256); assert(vertex_positions_stride % sizeof(float) == 0); assert(target_index_count <= index_count); @@ -1736,7 +1742,7 @@ size_t meshopt_simplifyPoints(unsigned int* destination, const float* vertex_pos { using namespace meshopt; - assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256); + assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256); assert(vertex_positions_stride % sizeof(float) == 0); assert(target_vertex_count <= vertex_count); @@ -1848,7 +1854,7 @@ float meshopt_simplifyScale(const float* vertex_positions, size_t vertex_count, { using namespace meshopt; - assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256); + assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256); assert(vertex_positions_stride % sizeof(float) == 0); float extent = rescalePositions(NULL, vertex_positions, vertex_count, vertex_positions_stride); diff --git a/thirdparty/meshoptimizer/spatialorder.cpp b/thirdparty/meshoptimizer/spatialorder.cpp index b09f80ac6f..7b1a069450 100644 --- a/thirdparty/meshoptimizer/spatialorder.cpp +++ b/thirdparty/meshoptimizer/spatialorder.cpp @@ -113,7 +113,7 @@ void meshopt_spatialSortRemap(unsigned int* destination, const float* vertex_pos { using namespace meshopt; - assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256); + assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256); assert(vertex_positions_stride % sizeof(float) == 0); meshopt_Allocator allocator; @@ -144,7 +144,7 @@ void meshopt_spatialSortTriangles(unsigned int* destination, const unsigned int* using namespace meshopt; assert(index_count % 3 == 0); - assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256); + assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256); assert(vertex_positions_stride % sizeof(float) == 0); (void)vertex_count; diff --git a/thirdparty/meshoptimizer/vcacheoptimizer.cpp b/thirdparty/meshoptimizer/vcacheoptimizer.cpp index fb8ade4b77..ce8fd3a887 100644 --- a/thirdparty/meshoptimizer/vcacheoptimizer.cpp +++ b/thirdparty/meshoptimizer/vcacheoptimizer.cpp @@ -110,7 +110,7 @@ static unsigned int getNextVertexDeadEnd(const unsigned int* dead_end, unsigned return ~0u; } -static unsigned int getNextVertexNeighbour(const unsigned int* next_candidates_begin, const unsigned int* next_candidates_end, const unsigned int* live_triangles, const unsigned int* cache_timestamps, unsigned int timestamp, unsigned int cache_size) +static unsigned int getNextVertexNeighbor(const unsigned int* next_candidates_begin, const unsigned int* next_candidates_end, const unsigned int* live_triangles, const unsigned int* cache_timestamps, unsigned int timestamp, unsigned int cache_size) { unsigned int best_candidate = ~0u; int best_priority = -1; @@ -281,16 +281,16 @@ void meshopt_optimizeVertexCacheTable(unsigned int* destination, const unsigned { unsigned int index = indices[current_triangle * 3 + k]; - unsigned int* neighbours = &adjacency.data[0] + adjacency.offsets[index]; - size_t neighbours_size = adjacency.counts[index]; + unsigned int* neighbors = &adjacency.data[0] + adjacency.offsets[index]; + size_t neighbors_size = adjacency.counts[index]; - for (size_t i = 0; i < neighbours_size; ++i) + for (size_t i = 0; i < neighbors_size; ++i) { - unsigned int tri = neighbours[i]; + unsigned int tri = neighbors[i]; if (tri == current_triangle) { - neighbours[i] = neighbours[neighbours_size - 1]; + neighbors[i] = neighbors[neighbors_size - 1]; adjacency.counts[index]--; break; } @@ -314,10 +314,10 @@ void meshopt_optimizeVertexCacheTable(unsigned int* destination, const unsigned vertex_scores[index] = score; // update scores of vertex triangles - const unsigned int* neighbours_begin = &adjacency.data[0] + adjacency.offsets[index]; - const unsigned int* neighbours_end = neighbours_begin + adjacency.counts[index]; + const unsigned int* neighbors_begin = &adjacency.data[0] + adjacency.offsets[index]; + const unsigned int* neighbors_end = neighbors_begin + adjacency.counts[index]; - for (const unsigned int* it = neighbours_begin; it != neighbours_end; ++it) + for (const unsigned int* it = neighbors_begin; it != neighbors_end; ++it) { unsigned int tri = *it; assert(!emitted_flags[tri]); @@ -412,11 +412,11 @@ void meshopt_optimizeVertexCacheFifo(unsigned int* destination, const unsigned i { const unsigned int* next_candidates_begin = &dead_end[0] + dead_end_top; - // emit all vertex neighbours - const unsigned int* neighbours_begin = &adjacency.data[0] + adjacency.offsets[current_vertex]; - const unsigned int* neighbours_end = neighbours_begin + adjacency.counts[current_vertex]; + // emit all vertex neighbors + const unsigned int* neighbors_begin = &adjacency.data[0] + adjacency.offsets[current_vertex]; + const unsigned int* neighbors_end = neighbors_begin + adjacency.counts[current_vertex]; - for (const unsigned int* it = neighbours_begin; it != neighbours_end; ++it) + for (const unsigned int* it = neighbors_begin; it != neighbors_end; ++it) { unsigned int triangle = *it; @@ -461,7 +461,7 @@ void meshopt_optimizeVertexCacheFifo(unsigned int* destination, const unsigned i const unsigned int* next_candidates_end = &dead_end[0] + dead_end_top; // get next vertex - current_vertex = getNextVertexNeighbour(next_candidates_begin, next_candidates_end, &live_triangles[0], &cache_timestamps[0], timestamp, cache_size); + current_vertex = getNextVertexNeighbor(next_candidates_begin, next_candidates_end, &live_triangles[0], &cache_timestamps[0], timestamp, cache_size); if (current_vertex == ~0u) { diff --git a/thirdparty/meshoptimizer/vertexcodec.cpp b/thirdparty/meshoptimizer/vertexcodec.cpp index 7925ea862c..4bd11121d2 100644 --- a/thirdparty/meshoptimizer/vertexcodec.cpp +++ b/thirdparty/meshoptimizer/vertexcodec.cpp @@ -50,6 +50,12 @@ #define SIMD_TARGET #endif +// When targeting AArch64/x64, optimize for latency to allow decoding of individual 16-byte groups to overlap +// We don't do this for 32-bit systems because we need 64-bit math for this and this will hurt in-order CPUs +#if defined(__x86_64__) || defined(_M_X64) || defined(__aarch64__) || defined(_M_ARM64) +#define SIMD_LATENCYOPT +#endif + #endif // !MESHOPTIMIZER_NO_SIMD #ifdef SIMD_SSE @@ -472,6 +478,18 @@ static const unsigned char* decodeBytesGroupSimd(const unsigned char* data, unsi typedef int unaligned_int; #endif +#ifdef SIMD_LATENCYOPT + unsigned int data32; + memcpy(&data32, data, 4); + data32 &= data32 >> 1; + + // arrange bits such that low bits of nibbles of data64 contain all 2-bit elements of data32 + unsigned long long data64 = ((unsigned long long)data32 << 30) | (data32 & 0x3fffffff); + + // adds all 1-bit nibbles together; the sum fits in 4 bits because datacnt=16 would have used mode 3 + int datacnt = int(((data64 & 0x1111111111111111ull) * 0x1111111111111111ull) >> 60); +#endif + __m128i sel2 = _mm_cvtsi32_si128(*reinterpret_cast<const unaligned_int*>(data)); __m128i rest = _mm_loadu_si128(reinterpret_cast<const __m128i*>(data + 4)); @@ -490,11 +508,25 @@ static const unsigned char* decodeBytesGroupSimd(const unsigned char* data, unsi _mm_storeu_si128(reinterpret_cast<__m128i*>(buffer), result); +#ifdef SIMD_LATENCYOPT + return data + 4 + datacnt; +#else return data + 4 + kDecodeBytesGroupCount[mask0] + kDecodeBytesGroupCount[mask1]; +#endif } case 2: { +#ifdef SIMD_LATENCYOPT + unsigned long long data64; + memcpy(&data64, data, 8); + data64 &= data64 >> 1; + data64 &= data64 >> 2; + + // adds all 1-bit nibbles together; the sum fits in 4 bits because datacnt=16 would have used mode 3 + int datacnt = int(((data64 & 0x1111111111111111ull) * 0x1111111111111111ull) >> 60); +#endif + __m128i sel4 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(data)); __m128i rest = _mm_loadu_si128(reinterpret_cast<const __m128i*>(data + 8)); @@ -512,7 +544,11 @@ static const unsigned char* decodeBytesGroupSimd(const unsigned char* data, unsi _mm_storeu_si128(reinterpret_cast<__m128i*>(buffer), result); +#ifdef SIMD_LATENCYOPT + return data + 8 + datacnt; +#else return data + 8 + kDecodeBytesGroupCount[mask0] + kDecodeBytesGroupCount[mask1]; +#endif } case 3: @@ -604,24 +640,13 @@ static uint8x16_t shuffleBytes(unsigned char mask0, unsigned char mask1, uint8x8 static void neonMoveMask(uint8x16_t mask, unsigned char& mask0, unsigned char& mask1) { - static const unsigned char byte_mask_data[16] = {1, 2, 4, 8, 16, 32, 64, 128, 1, 2, 4, 8, 16, 32, 64, 128}; - - uint8x16_t byte_mask = vld1q_u8(byte_mask_data); - uint8x16_t masked = vandq_u8(mask, byte_mask); + // magic constant found using z3 SMT assuming mask has 8 groups of 0xff or 0x00 + const uint64_t magic = 0x000103070f1f3f80ull; -#ifdef __aarch64__ - // aarch64 has horizontal sums; MSVC doesn't expose this via arm64_neon.h so this path is exclusive to clang/gcc - mask0 = vaddv_u8(vget_low_u8(masked)); - mask1 = vaddv_u8(vget_high_u8(masked)); -#else - // we need horizontal sums of each half of masked, which can be done in 3 steps (yielding sums of sizes 2, 4, 8) - uint8x8_t sum1 = vpadd_u8(vget_low_u8(masked), vget_high_u8(masked)); - uint8x8_t sum2 = vpadd_u8(sum1, sum1); - uint8x8_t sum3 = vpadd_u8(sum2, sum2); + uint64x2_t mask2 = vreinterpretq_u64_u8(mask); - mask0 = vget_lane_u8(sum3, 0); - mask1 = vget_lane_u8(sum3, 1); -#endif + mask0 = uint8_t((vgetq_lane_u64(mask2, 0) * magic) >> 56); + mask1 = uint8_t((vgetq_lane_u64(mask2, 1) * magic) >> 56); } static const unsigned char* decodeBytesGroupSimd(const unsigned char* data, unsigned char* buffer, int bitslog2) @@ -639,6 +664,18 @@ static const unsigned char* decodeBytesGroupSimd(const unsigned char* data, unsi case 1: { +#ifdef SIMD_LATENCYOPT + unsigned int data32; + memcpy(&data32, data, 4); + data32 &= data32 >> 1; + + // arrange bits such that low bits of nibbles of data64 contain all 2-bit elements of data32 + unsigned long long data64 = ((unsigned long long)data32 << 30) | (data32 & 0x3fffffff); + + // adds all 1-bit nibbles together; the sum fits in 4 bits because datacnt=16 would have used mode 3 + int datacnt = int(((data64 & 0x1111111111111111ull) * 0x1111111111111111ull) >> 60); +#endif + uint8x8_t sel2 = vld1_u8(data); uint8x8_t sel22 = vzip_u8(vshr_n_u8(sel2, 4), sel2).val[0]; uint8x8x2_t sel2222 = vzip_u8(vshr_n_u8(sel22, 2), sel22); @@ -655,11 +692,25 @@ static const unsigned char* decodeBytesGroupSimd(const unsigned char* data, unsi vst1q_u8(buffer, result); +#ifdef SIMD_LATENCYOPT + return data + 4 + datacnt; +#else return data + 4 + kDecodeBytesGroupCount[mask0] + kDecodeBytesGroupCount[mask1]; +#endif } case 2: { +#ifdef SIMD_LATENCYOPT + unsigned long long data64; + memcpy(&data64, data, 8); + data64 &= data64 >> 1; + data64 &= data64 >> 2; + + // adds all 1-bit nibbles together; the sum fits in 4 bits because datacnt=16 would have used mode 3 + int datacnt = int(((data64 & 0x1111111111111111ull) * 0x1111111111111111ull) >> 60); +#endif + uint8x8_t sel4 = vld1_u8(data); uint8x8x2_t sel44 = vzip_u8(vshr_n_u8(sel4, 4), vand_u8(sel4, vdup_n_u8(15))); uint8x16_t sel = vcombine_u8(sel44.val[0], sel44.val[1]); @@ -675,7 +726,11 @@ static const unsigned char* decodeBytesGroupSimd(const unsigned char* data, unsi vst1q_u8(buffer, result); +#ifdef SIMD_LATENCYOPT + return data + 8 + datacnt; +#else return data + 8 + kDecodeBytesGroupCount[mask0] + kDecodeBytesGroupCount[mask1]; +#endif } case 3: @@ -715,7 +770,6 @@ static void wasmMoveMask(v128_t mask, unsigned char& mask0, unsigned char& mask1 // magic constant found using z3 SMT assuming mask has 8 groups of 0xff or 0x00 const uint64_t magic = 0x000103070f1f3f80ull; - // TODO: This can use v8x16_bitmask in the future mask0 = uint8_t((wasm_i64x2_extract_lane(mask, 0) * magic) >> 56); mask1 = uint8_t((wasm_i64x2_extract_lane(mask, 1) * magic) >> 56); } diff --git a/thirdparty/meshoptimizer/vertexfilter.cpp b/thirdparty/meshoptimizer/vertexfilter.cpp index 606a280aa9..14a73b1ddd 100644 --- a/thirdparty/meshoptimizer/vertexfilter.cpp +++ b/thirdparty/meshoptimizer/vertexfilter.cpp @@ -931,7 +931,7 @@ void meshopt_encodeFilterExp(void* destination_, size_t count, size_t stride, in const float* v = &data[i * stride_float]; unsigned int* d = &destination[i * stride_float]; - // use maximum exponent to encode values; this guarantess that mantissa is [-1, 1] + // use maximum exponent to encode values; this guarantees that mantissa is [-1, 1] int exp = -100; for (size_t j = 0; j < stride_float; ++j) diff --git a/thirdparty/miniupnpc/LICENSE b/thirdparty/miniupnpc/LICENSE index fe9118c07e..67ff3bb627 100644 --- a/thirdparty/miniupnpc/LICENSE +++ b/thirdparty/miniupnpc/LICENSE @@ -1,26 +1,29 @@ -MiniUPnP Project -Copyright (c) 2005-2020, Thomas BERNARD +BSD 3-Clause License + +Copyright (c) 2005-2022, Thomas BERNARD All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/thirdparty/miniupnpc/include/miniupnpc.h b/thirdparty/miniupnpc/include/miniupnpc.h index a10bd950a8..75fb8b702d 100644 --- a/thirdparty/miniupnpc/include/miniupnpc.h +++ b/thirdparty/miniupnpc/include/miniupnpc.h @@ -1,9 +1,9 @@ -/* $Id: miniupnpc.h,v 1.59 2021/09/28 21:39:17 nanard Exp $ */ +/* $Id: miniupnpc.h,v 1.61 2022/10/21 21:15:02 nanard Exp $ */ /* vim: tabstop=4 shiftwidth=4 noexpandtab * Project: miniupnp - * http://miniupnp.free.fr/ + * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ * Author: Thomas Bernard - * Copyright (c) 2005-2021 Thomas Bernard + * Copyright (c) 2005-2022 Thomas Bernard * This software is subjects to the conditions detailed * in the LICENCE file provided within this distribution */ #ifndef MINIUPNPC_H_INCLUDED @@ -20,7 +20,7 @@ #define UPNPDISCOVER_MEMORY_ERROR (-102) /* versions : */ -#define MINIUPNPC_VERSION "2.2.3" +#define MINIUPNPC_VERSION "2.2.4" #define MINIUPNPC_API_VERSION 17 /* Source port: diff --git a/thirdparty/miniupnpc/src/miniupnpcstrings.h b/thirdparty/miniupnpc/src/miniupnpcstrings.h index eefbc8dbdd..25abc1016e 100644 --- a/thirdparty/miniupnpc/src/miniupnpcstrings.h +++ b/thirdparty/miniupnpc/src/miniupnpcstrings.h @@ -4,7 +4,7 @@ #include "core/version.h" #define OS_STRING VERSION_NAME "/1.0" -#define MINIUPNPC_VERSION_STRING "2.2.3" +#define MINIUPNPC_VERSION_STRING "2.2.4" #if 0 /* according to "UPnP Device Architecture 1.0" */ diff --git a/thirdparty/miniupnpc/src/minixml.c b/thirdparty/miniupnpc/src/minixml.c index ed2d3c759c..935ec443e7 100644 --- a/thirdparty/miniupnpc/src/minixml.c +++ b/thirdparty/miniupnpc/src/minixml.c @@ -1,4 +1,4 @@ -/* $Id: minixml.c,v 1.10 2012/03/05 19:42:47 nanard Exp $ */ +/* $Id: minixml.c,v 1.12 2017/12/12 11:17:40 nanard Exp $ */ /* vim: tabstop=4 shiftwidth=4 noexpandtab * minixml.c : the minimum size a xml parser can be ! */ /* Project : miniupnp diff --git a/thirdparty/minizip/MiniZip_info.txt b/thirdparty/minizip/MiniZip64_info.txt index 57d7152420..57d7152420 100644 --- a/thirdparty/minizip/MiniZip_info.txt +++ b/thirdparty/minizip/MiniZip64_info.txt diff --git a/thirdparty/minizip/crypt.h b/thirdparty/minizip/crypt.h index 9da15373d8..1cc41f19d7 100644 --- a/thirdparty/minizip/crypt.h +++ b/thirdparty/minizip/crypt.h @@ -85,7 +85,7 @@ static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t* pcr #define RAND_HEAD_LEN 12 /* "last resort" source for second part of crypt seed pattern */ # ifndef ZCR_SEED2 -# define ZCR_SEED2 3141592654L /* use PI as default pattern */ +# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ # endif static unsigned crypthead(const char* passwd, /* password string */ diff --git a/thirdparty/minizip/ioapi.c b/thirdparty/minizip/ioapi.c index db4c33b4b9..b50db35ac1 100644 --- a/thirdparty/minizip/ioapi.c +++ b/thirdparty/minizip/ioapi.c @@ -101,9 +101,9 @@ static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) { - (void)opaque; FILE* file = NULL; const char* mode_fopen = NULL; + (void)opaque; if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) mode_fopen = "rb"; else @@ -120,9 +120,9 @@ static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, in static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode) { - (void)opaque; FILE* file = NULL; const char* mode_fopen = NULL; + (void)opaque; if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) mode_fopen = "rb"; else @@ -140,24 +140,24 @@ static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) { - (void)opaque; uLong ret; + (void)opaque; ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); return ret; } static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) { - (void)opaque; uLong ret; + (void)opaque; ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); return ret; } static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) { - (void)opaque; long ret; + (void)opaque; ret = ftell((FILE *)stream); return ret; } @@ -165,17 +165,17 @@ static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) { - (void)opaque; ZPOS64_T ret; + (void)opaque; ret = (ZPOS64_T)FTELLO_FUNC((FILE *)stream); return ret; } static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) { - (void)opaque; int fseek_origin=0; long ret; + (void)opaque; switch (origin) { case ZLIB_FILEFUNC_SEEK_CUR : @@ -197,9 +197,9 @@ static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offs static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) { - (void)opaque; int fseek_origin=0; long ret; + (void)opaque; switch (origin) { case ZLIB_FILEFUNC_SEEK_CUR : @@ -215,7 +215,7 @@ static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T } ret = 0; - if(FSEEKO_FUNC((FILE *)stream, (long)offset, fseek_origin) != 0) + if(FSEEKO_FUNC((FILE *)stream, (z_off_t)offset, fseek_origin) != 0) ret = -1; return ret; @@ -224,16 +224,16 @@ static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) { - (void)opaque; int ret; + (void)opaque; ret = fclose((FILE *)stream); return ret; } static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) { - (void)opaque; int ret; + (void)opaque; ret = ferror((FILE *)stream); return ret; } diff --git a/thirdparty/minizip/ioapi.h b/thirdparty/minizip/ioapi.h index e9e5899852..083062ffe6 100644 --- a/thirdparty/minizip/ioapi.h +++ b/thirdparty/minizip/ioapi.h @@ -66,7 +66,7 @@ #define ftello64 ftell #define fseeko64 fseek #else -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) #define fopen64 fopen #define ftello64 ftello #define fseeko64 fseeko diff --git a/thirdparty/minizip/patches/godot-seek.patch b/thirdparty/minizip/patches/godot-seek.patch index 24838c252a..279124f3f0 100644 --- a/thirdparty/minizip/patches/godot-seek.patch +++ b/thirdparty/minizip/patches/godot-seek.patch @@ -1,5 +1,5 @@ diff --git a/thirdparty/minizip/ioapi.c b/thirdparty/minizip/ioapi.c -index d666e5a228..db4c33b4b9 100644 +index 814a6fd38c..b50db35ac1 100644 --- a/thirdparty/minizip/ioapi.c +++ b/thirdparty/minizip/ioapi.c @@ -80,8 +80,15 @@ void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filef @@ -26,7 +26,7 @@ index d666e5a228..db4c33b4b9 100644 +*/ +/* GODOT end */ diff --git a/thirdparty/minizip/ioapi.h b/thirdparty/minizip/ioapi.h -index 114bfab762..2f24a5b6a0 100644 +index ae9ca7e833..6c73fc4ec3 100644 --- a/thirdparty/minizip/ioapi.h +++ b/thirdparty/minizip/ioapi.h @@ -155,6 +155,10 @@ typedef struct zlib_filefunc_def_s @@ -52,7 +52,7 @@ index 114bfab762..2f24a5b6a0 100644 void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); diff --git a/thirdparty/minizip/unzip.c b/thirdparty/minizip/unzip.c -index 5e12e47474..3b191e827c 100644 +index 3036b470b7..e83aff2773 100644 --- a/thirdparty/minizip/unzip.c +++ b/thirdparty/minizip/unzip.c @@ -157,6 +157,9 @@ typedef struct @@ -122,7 +122,7 @@ index 5e12e47474..3b191e827c 100644 } while(acc < file_info.size_file_extra) -@@ -1575,8 +1604,10 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, +@@ -1576,8 +1605,10 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, } else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) { @@ -135,7 +135,7 @@ index 5e12e47474..3b191e827c 100644 pfile_in_zip_read_info->stream.opaque = (voidpf)0; pfile_in_zip_read_info->stream.next_in = 0; pfile_in_zip_read_info->stream.avail_in = 0; -@@ -1608,6 +1639,9 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, +@@ -1610,6 +1641,9 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, iSizeVar; pfile_in_zip_read_info->stream.avail_in = (uInt)0; @@ -145,7 +145,7 @@ index 5e12e47474..3b191e827c 100644 s->pfile_in_zip_read = pfile_in_zip_read_info; s->encrypted = 0; -@@ -1638,6 +1672,85 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, +@@ -1640,6 +1674,85 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, return UNZ_OK; } @@ -261,7 +261,7 @@ index 6f95e94d75..71a7d89692 100644 extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file)); diff --git a/thirdparty/minizip/zip.c b/thirdparty/minizip/zip.c -index 4e611e1163..6d1c26d9f8 100644 +index 66d693f85a..ddcc14132b 100644 --- a/thirdparty/minizip/zip.c +++ b/thirdparty/minizip/zip.c @@ -854,9 +854,11 @@ extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* gl diff --git a/thirdparty/minizip/patches/unbreak-gentoo.patch b/thirdparty/minizip/patches/unbreak-gentoo.patch index 9292e32ac6..65230cd4c7 100644 --- a/thirdparty/minizip/patches/unbreak-gentoo.patch +++ b/thirdparty/minizip/patches/unbreak-gentoo.patch @@ -1,8 +1,8 @@ diff --git a/thirdparty/minizip/ioapi.h b/thirdparty/minizip/ioapi.h -index f25ab6464..6043d34ce 100644 +index 6c73fc4ec3..083062ffe6 100644 --- a/thirdparty/minizip/ioapi.h +++ b/thirdparty/minizip/ioapi.h -@@ -44,6 +44,22 @@ +@@ -45,6 +45,22 @@ #include <stdlib.h> #include "zlib.h" diff --git a/thirdparty/minizip/unzip.c b/thirdparty/minizip/unzip.c index 3b191e827c..e83aff2773 100644 --- a/thirdparty/minizip/unzip.c +++ b/thirdparty/minizip/unzip.c @@ -112,7 +112,7 @@ # define ALLOC(size) (malloc(size)) #endif #ifndef TRYFREE -# define TRYFREE(p) {if (p) free(p);} +# define TRYFREE(p) { free(p);} #endif #define SIZECENTRALDIRITEM (0x2e) @@ -1595,6 +1595,7 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; else { + TRYFREE(pfile_in_zip_read_info->read_buffer); TRYFREE(pfile_in_zip_read_info); return err; } @@ -1617,6 +1618,7 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; else { + TRYFREE(pfile_in_zip_read_info->read_buffer); TRYFREE(pfile_in_zip_read_info); return err; } diff --git a/thirdparty/minizip/zip.c b/thirdparty/minizip/zip.c index 6d1c26d9f8..ddcc14132b 100644 --- a/thirdparty/minizip/zip.c +++ b/thirdparty/minizip/zip.c @@ -1475,11 +1475,6 @@ extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned in { uLong uTotalOutBefore = zi->ci.stream.total_out; err=deflate(&zi->ci.stream, Z_NO_FLUSH); - if(uTotalOutBefore > zi->ci.stream.total_out) - { - int bBreak = 0; - bBreak++; - } zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; } @@ -1963,7 +1958,7 @@ extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHe int retVal = ZIP_OK; - if(pData == NULL || *dataLen < 4) + if(pData == NULL || dataLen == NULL || *dataLen < 4) return ZIP_PARAMERROR; pNewHeader = (char*)ALLOC((unsigned)*dataLen); diff --git a/thirdparty/openxr/include/openxr/openxr.h b/thirdparty/openxr/include/openxr/openxr.h index 6f9b71aa68..3663f9f14d 100644 --- a/thirdparty/openxr/include/openxr/openxr.h +++ b/thirdparty/openxr/include/openxr/openxr.h @@ -25,7 +25,7 @@ extern "C" { ((((major) & 0xffffULL) << 48) | (((minor) & 0xffffULL) << 32) | ((patch) & 0xffffffffULL)) // OpenXR current version number. -#define XR_CURRENT_API_VERSION XR_MAKE_VERSION(1, 0, 25) +#define XR_CURRENT_API_VERSION XR_MAKE_VERSION(1, 0, 26) #define XR_VERSION_MAJOR(version) (uint16_t)(((uint64_t)(version) >> 48)& 0xffffULL) #define XR_VERSION_MINOR(version) (uint16_t)(((uint64_t)(version) >> 32) & 0xffffULL) @@ -450,6 +450,15 @@ typedef enum XrStructureType { XR_TYPE_VULKAN_SWAPCHAIN_CREATE_INFO_META = 1000227000, XR_TYPE_PERFORMANCE_METRICS_STATE_META = 1000232001, XR_TYPE_PERFORMANCE_METRICS_COUNTER_META = 1000232002, + XR_TYPE_SYSTEM_HEADSET_ID_PROPERTIES_META = 1000245000, + XR_TYPE_PASSTHROUGH_CREATE_INFO_HTC = 1000317001, + XR_TYPE_PASSTHROUGH_COLOR_HTC = 1000317002, + XR_TYPE_PASSTHROUGH_MESH_TRANSFORM_INFO_HTC = 1000317003, + XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_HTC = 1000317004, + XR_TYPE_FOVEATION_APPLY_INFO_HTC = 1000318000, + XR_TYPE_FOVEATION_DYNAMIC_MODE_INFO_HTC = 1000318001, + XR_TYPE_FOVEATION_CUSTOM_MODE_INFO_HTC = 1000318002, + XR_TYPE_ACTIVE_ACTION_SET_PRIORITIES_EXT = 1000373000, XR_TYPE_GRAPHICS_BINDING_VULKAN2_KHR = XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR, XR_TYPE_SWAPCHAIN_IMAGE_VULKAN2_KHR = XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR, XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN2_KHR = XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR, @@ -536,6 +545,7 @@ typedef enum XrObjectType { XR_OBJECT_TYPE_PASSTHROUGH_LAYER_FB = 1000118002, XR_OBJECT_TYPE_GEOMETRY_INSTANCE_FB = 1000118004, XR_OBJECT_TYPE_SPATIAL_ANCHOR_STORE_CONNECTION_MSFT = 1000142000, + XR_OBJECT_TYPE_PASSTHROUGH_HTC = 1000317000, XR_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF } XrObjectType; typedef XrFlags64 XrInstanceCreateFlags; @@ -1631,7 +1641,7 @@ typedef struct XrBindingModificationsKHR { #define XR_EXT_performance_settings 1 -#define XR_EXT_performance_settings_SPEC_VERSION 3 +#define XR_EXT_performance_settings_SPEC_VERSION 4 #define XR_EXT_PERFORMANCE_SETTINGS_EXTENSION_NAME "XR_EXT_performance_settings" typedef enum XrPerfSettingsDomainEXT { @@ -3007,7 +3017,7 @@ XRAPI_ATTR XrResult XRAPI_CALL xrRequestDisplayRefreshRateFB( #define XR_HTCX_vive_tracker_interaction 1 -#define XR_HTCX_vive_tracker_interaction_SPEC_VERSION 1 +#define XR_HTCX_vive_tracker_interaction_SPEC_VERSION 2 #define XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME "XR_HTCX_vive_tracker_interaction" typedef struct XrViveTrackerPathsHTCX { XrStructureType type; @@ -3043,7 +3053,7 @@ XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateViveTrackerPathsHTCX( #define XR_FACIAL_EXPRESSION_LIP_COUNT_HTC 37 XR_DEFINE_HANDLE(XrFacialTrackerHTC) -#define XR_HTC_facial_tracking_SPEC_VERSION 1 +#define XR_HTC_facial_tracking_SPEC_VERSION 2 #define XR_HTC_FACIAL_TRACKING_EXTENSION_NAME "XR_HTC_facial_tracking" typedef enum XrEyeExpressionHTC { @@ -4508,7 +4518,7 @@ typedef struct XrCompositionLayerSettingsFB { #define XR_META_performance_metrics 1 -#define XR_META_performance_metrics_SPEC_VERSION 1 +#define XR_META_performance_metrics_SPEC_VERSION 2 #define XR_META_PERFORMANCE_METRICS_EXTENSION_NAME "XR_META_performance_metrics" typedef enum XrPerformanceMetricsCounterUnitMETA { @@ -4570,10 +4580,167 @@ XRAPI_ATTR XrResult XRAPI_CALL xrQueryPerformanceMetricsCounterMETA( #endif /* !XR_NO_PROTOTYPES */ +#define XR_META_headset_id 1 +#define XR_META_headset_id_SPEC_VERSION 1 +#define XR_META_HEADSET_ID_EXTENSION_NAME "XR_META_headset_id" +// XrSystemHeadsetIdPropertiesMETA extends XrSystemProperties +typedef struct XrSystemHeadsetIdPropertiesMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrUuidEXT id; +} XrSystemHeadsetIdPropertiesMETA; + + + #define XR_EXT_uuid 1 #define XR_EXT_uuid_SPEC_VERSION 1 #define XR_EXT_UUID_EXTENSION_NAME "XR_EXT_uuid" + +#define XR_HTC_passthrough 1 +XR_DEFINE_HANDLE(XrPassthroughHTC) +#define XR_HTC_passthrough_SPEC_VERSION 1 +#define XR_HTC_PASSTHROUGH_EXTENSION_NAME "XR_HTC_passthrough" + +typedef enum XrPassthroughFormHTC { + XR_PASSTHROUGH_FORM_PLANAR_HTC = 0, + XR_PASSTHROUGH_FORM_PROJECTED_HTC = 1, + XR_PASSTHROUGH_FORM_MAX_ENUM_HTC = 0x7FFFFFFF +} XrPassthroughFormHTC; +typedef struct XrPassthroughCreateInfoHTC { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPassthroughFormHTC form; +} XrPassthroughCreateInfoHTC; + +typedef struct XrPassthroughColorHTC { + XrStructureType type; + const void* XR_MAY_ALIAS next; + float alpha; +} XrPassthroughColorHTC; + +// XrPassthroughMeshTransformInfoHTC extends XrCompositionLayerPassthroughHTC +typedef struct XrPassthroughMeshTransformInfoHTC { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t vertexCount; + const XrVector3f* vertices; + uint32_t indexCount; + const uint32_t* indices; + XrSpace baseSpace; + XrTime time; + XrPosef pose; + XrVector3f scale; +} XrPassthroughMeshTransformInfoHTC; + +typedef struct XrCompositionLayerPassthroughHTC { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrCompositionLayerFlags layerFlags; + XrSpace space; + XrPassthroughHTC passthrough; + XrPassthroughColorHTC color; +} XrCompositionLayerPassthroughHTC; + +typedef XrResult (XRAPI_PTR *PFN_xrCreatePassthroughHTC)(XrSession session, const XrPassthroughCreateInfoHTC* createInfo, XrPassthroughHTC* passthrough); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyPassthroughHTC)(XrPassthroughHTC passthrough); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreatePassthroughHTC( + XrSession session, + const XrPassthroughCreateInfoHTC* createInfo, + XrPassthroughHTC* passthrough); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyPassthroughHTC( + XrPassthroughHTC passthrough); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_HTC_foveation 1 +#define XR_HTC_foveation_SPEC_VERSION 1 +#define XR_HTC_FOVEATION_EXTENSION_NAME "XR_HTC_foveation" + +typedef enum XrFoveationModeHTC { + XR_FOVEATION_MODE_DISABLE_HTC = 0, + XR_FOVEATION_MODE_FIXED_HTC = 1, + XR_FOVEATION_MODE_DYNAMIC_HTC = 2, + XR_FOVEATION_MODE_CUSTOM_HTC = 3, + XR_FOVEATION_MODE_MAX_ENUM_HTC = 0x7FFFFFFF +} XrFoveationModeHTC; + +typedef enum XrFoveationLevelHTC { + XR_FOVEATION_LEVEL_NONE_HTC = 0, + XR_FOVEATION_LEVEL_LOW_HTC = 1, + XR_FOVEATION_LEVEL_MEDIUM_HTC = 2, + XR_FOVEATION_LEVEL_HIGH_HTC = 3, + XR_FOVEATION_LEVEL_MAX_ENUM_HTC = 0x7FFFFFFF +} XrFoveationLevelHTC; +typedef XrFlags64 XrFoveationDynamicFlagsHTC; + +// Flag bits for XrFoveationDynamicFlagsHTC +static const XrFoveationDynamicFlagsHTC XR_FOVEATION_DYNAMIC_LEVEL_ENABLED_BIT_HTC = 0x00000001; +static const XrFoveationDynamicFlagsHTC XR_FOVEATION_DYNAMIC_CLEAR_FOV_ENABLED_BIT_HTC = 0x00000002; +static const XrFoveationDynamicFlagsHTC XR_FOVEATION_DYNAMIC_FOCAL_CENTER_OFFSET_ENABLED_BIT_HTC = 0x00000004; + +typedef struct XrFoveationApplyInfoHTC { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrFoveationModeHTC mode; + uint32_t subImageCount; + XrSwapchainSubImage* subImages; +} XrFoveationApplyInfoHTC; + +typedef struct XrFoveationConfigurationHTC { + XrFoveationLevelHTC level; + float clearFovDegree; + XrVector2f focalCenterOffset; +} XrFoveationConfigurationHTC; + +// XrFoveationDynamicModeInfoHTC extends XrFoveationApplyInfoHTC +typedef struct XrFoveationDynamicModeInfoHTC { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrFoveationDynamicFlagsHTC dynamicFlags; +} XrFoveationDynamicModeInfoHTC; + +// XrFoveationCustomModeInfoHTC extends XrFoveationApplyInfoHTC +typedef struct XrFoveationCustomModeInfoHTC { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t configCount; + const XrFoveationConfigurationHTC* configs; +} XrFoveationCustomModeInfoHTC; + +typedef XrResult (XRAPI_PTR *PFN_xrApplyFoveationHTC)(XrSession session, const XrFoveationApplyInfoHTC* applyInfo); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrApplyFoveationHTC( + XrSession session, + const XrFoveationApplyInfoHTC* applyInfo); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_EXT_active_action_set_priority 1 +#define XR_EXT_active_action_set_priority_SPEC_VERSION 1 +#define XR_EXT_ACTIVE_ACTION_SET_PRIORITY_EXTENSION_NAME "XR_EXT_active_action_set_priority" +typedef struct XrActiveActionSetPriorityEXT { + XrActionSet actionSet; + uint32_t priorityOverride; +} XrActiveActionSetPriorityEXT; + +// XrActiveActionSetPrioritiesEXT extends XrActionsSyncInfo +typedef struct XrActiveActionSetPrioritiesEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t actionSetPriorityCount; + const XrActiveActionSetPriorityEXT* actionSetPriorities; +} XrActiveActionSetPrioritiesEXT; + + #ifdef __cplusplus } #endif diff --git a/thirdparty/openxr/include/openxr/openxr_reflection.h b/thirdparty/openxr/include/openxr/openxr_reflection.h index ac6f452377..1a873c1770 100644 --- a/thirdparty/openxr/include/openxr/openxr_reflection.h +++ b/thirdparty/openxr/include/openxr/openxr_reflection.h @@ -351,6 +351,15 @@ XR_ENUM_STR(XrResult); _(XR_TYPE_VULKAN_SWAPCHAIN_CREATE_INFO_META, 1000227000) \ _(XR_TYPE_PERFORMANCE_METRICS_STATE_META, 1000232001) \ _(XR_TYPE_PERFORMANCE_METRICS_COUNTER_META, 1000232002) \ + _(XR_TYPE_SYSTEM_HEADSET_ID_PROPERTIES_META, 1000245000) \ + _(XR_TYPE_PASSTHROUGH_CREATE_INFO_HTC, 1000317001) \ + _(XR_TYPE_PASSTHROUGH_COLOR_HTC, 1000317002) \ + _(XR_TYPE_PASSTHROUGH_MESH_TRANSFORM_INFO_HTC, 1000317003) \ + _(XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_HTC, 1000317004) \ + _(XR_TYPE_FOVEATION_APPLY_INFO_HTC, 1000318000) \ + _(XR_TYPE_FOVEATION_DYNAMIC_MODE_INFO_HTC, 1000318001) \ + _(XR_TYPE_FOVEATION_CUSTOM_MODE_INFO_HTC, 1000318002) \ + _(XR_TYPE_ACTIVE_ACTION_SET_PRIORITIES_EXT, 1000373000) \ _(XR_STRUCTURE_TYPE_MAX_ENUM, 0x7FFFFFFF) #define XR_LIST_ENUM_XrFormFactor(_) \ @@ -426,6 +435,7 @@ XR_ENUM_STR(XrResult); _(XR_OBJECT_TYPE_PASSTHROUGH_LAYER_FB, 1000118002) \ _(XR_OBJECT_TYPE_GEOMETRY_INSTANCE_FB, 1000118004) \ _(XR_OBJECT_TYPE_SPATIAL_ANCHOR_STORE_CONNECTION_MSFT, 1000142000) \ + _(XR_OBJECT_TYPE_PASSTHROUGH_HTC, 1000317000) \ _(XR_OBJECT_TYPE_MAX_ENUM, 0x7FFFFFFF) #define XR_LIST_ENUM_XrAndroidThreadTypeKHR(_) \ @@ -748,6 +758,25 @@ XR_ENUM_STR(XrResult); _(XR_PERFORMANCE_METRICS_COUNTER_UNIT_HERTZ_META, 4) \ _(XR_PERFORMANCE_METRICS_COUNTER_UNIT_MAX_ENUM_META, 0x7FFFFFFF) +#define XR_LIST_ENUM_XrPassthroughFormHTC(_) \ + _(XR_PASSTHROUGH_FORM_PLANAR_HTC, 0) \ + _(XR_PASSTHROUGH_FORM_PROJECTED_HTC, 1) \ + _(XR_PASSTHROUGH_FORM_MAX_ENUM_HTC, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrFoveationModeHTC(_) \ + _(XR_FOVEATION_MODE_DISABLE_HTC, 0) \ + _(XR_FOVEATION_MODE_FIXED_HTC, 1) \ + _(XR_FOVEATION_MODE_DYNAMIC_HTC, 2) \ + _(XR_FOVEATION_MODE_CUSTOM_HTC, 3) \ + _(XR_FOVEATION_MODE_MAX_ENUM_HTC, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrFoveationLevelHTC(_) \ + _(XR_FOVEATION_LEVEL_NONE_HTC, 0) \ + _(XR_FOVEATION_LEVEL_LOW_HTC, 1) \ + _(XR_FOVEATION_LEVEL_MEDIUM_HTC, 2) \ + _(XR_FOVEATION_LEVEL_HIGH_HTC, 3) \ + _(XR_FOVEATION_LEVEL_MAX_ENUM_HTC, 0x7FFFFFFF) + #define XR_LIST_BITS_XrInstanceCreateFlags(_) #define XR_LIST_BITS_XrSessionCreateFlags(_) @@ -891,6 +920,12 @@ XR_ENUM_STR(XrResult); _(XR_PERFORMANCE_METRICS_COUNTER_UINT_VALUE_VALID_BIT_META, 0x00000002) \ _(XR_PERFORMANCE_METRICS_COUNTER_FLOAT_VALUE_VALID_BIT_META, 0x00000004) \ +#define XR_LIST_BITS_XrFoveationDynamicFlagsHTC(_) \ + _(XR_FOVEATION_DYNAMIC_LEVEL_ENABLED_BIT_HTC, 0x00000001) \ + _(XR_FOVEATION_DYNAMIC_CLEAR_FOV_ENABLED_BIT_HTC, 0x00000002) \ + _(XR_FOVEATION_DYNAMIC_FOCAL_CENTER_OFFSET_ENABLED_BIT_HTC, 0x00000004) \ + +/// Calls your macro with the name of each member of XrApiLayerProperties, in order. #define XR_LIST_STRUCT_XrApiLayerProperties(_) \ _(type) \ _(next) \ @@ -899,12 +934,14 @@ XR_ENUM_STR(XrResult); _(layerVersion) \ _(description) \ +/// Calls your macro with the name of each member of XrExtensionProperties, in order. #define XR_LIST_STRUCT_XrExtensionProperties(_) \ _(type) \ _(next) \ _(extensionName) \ _(extensionVersion) \ +/// Calls your macro with the name of each member of XrApplicationInfo, in order. #define XR_LIST_STRUCT_XrApplicationInfo(_) \ _(applicationName) \ _(applicationVersion) \ @@ -912,6 +949,7 @@ XR_ENUM_STR(XrResult); _(engineVersion) \ _(apiVersion) \ +/// Calls your macro with the name of each member of XrInstanceCreateInfo, in order. #define XR_LIST_STRUCT_XrInstanceCreateInfo(_) \ _(type) \ _(next) \ @@ -922,31 +960,37 @@ XR_ENUM_STR(XrResult); _(enabledExtensionCount) \ _(enabledExtensionNames) \ +/// Calls your macro with the name of each member of XrInstanceProperties, in order. #define XR_LIST_STRUCT_XrInstanceProperties(_) \ _(type) \ _(next) \ _(runtimeVersion) \ _(runtimeName) \ +/// Calls your macro with the name of each member of XrEventDataBuffer, in order. #define XR_LIST_STRUCT_XrEventDataBuffer(_) \ _(type) \ _(next) \ _(varying) \ +/// Calls your macro with the name of each member of XrSystemGetInfo, in order. #define XR_LIST_STRUCT_XrSystemGetInfo(_) \ _(type) \ _(next) \ _(formFactor) \ +/// Calls your macro with the name of each member of XrSystemGraphicsProperties, in order. #define XR_LIST_STRUCT_XrSystemGraphicsProperties(_) \ _(maxSwapchainImageHeight) \ _(maxSwapchainImageWidth) \ _(maxLayerCount) \ +/// Calls your macro with the name of each member of XrSystemTrackingProperties, in order. #define XR_LIST_STRUCT_XrSystemTrackingProperties(_) \ _(orientationTracking) \ _(positionTracking) \ +/// Calls your macro with the name of each member of XrSystemProperties, in order. #define XR_LIST_STRUCT_XrSystemProperties(_) \ _(type) \ _(next) \ @@ -956,17 +1000,20 @@ XR_ENUM_STR(XrResult); _(graphicsProperties) \ _(trackingProperties) \ +/// Calls your macro with the name of each member of XrSessionCreateInfo, in order. #define XR_LIST_STRUCT_XrSessionCreateInfo(_) \ _(type) \ _(next) \ _(createFlags) \ _(systemId) \ +/// Calls your macro with the name of each member of XrVector3f, in order. #define XR_LIST_STRUCT_XrVector3f(_) \ _(x) \ _(y) \ _(z) \ +/// Calls your macro with the name of each member of XrSpaceVelocity, in order. #define XR_LIST_STRUCT_XrSpaceVelocity(_) \ _(type) \ _(next) \ @@ -974,26 +1021,31 @@ XR_ENUM_STR(XrResult); _(linearVelocity) \ _(angularVelocity) \ +/// Calls your macro with the name of each member of XrQuaternionf, in order. #define XR_LIST_STRUCT_XrQuaternionf(_) \ _(x) \ _(y) \ _(z) \ _(w) \ +/// Calls your macro with the name of each member of XrPosef, in order. #define XR_LIST_STRUCT_XrPosef(_) \ _(orientation) \ _(position) \ +/// Calls your macro with the name of each member of XrReferenceSpaceCreateInfo, in order. #define XR_LIST_STRUCT_XrReferenceSpaceCreateInfo(_) \ _(type) \ _(next) \ _(referenceSpaceType) \ _(poseInReferenceSpace) \ +/// Calls your macro with the name of each member of XrExtent2Df, in order. #define XR_LIST_STRUCT_XrExtent2Df(_) \ _(width) \ _(height) \ +/// Calls your macro with the name of each member of XrActionSpaceCreateInfo, in order. #define XR_LIST_STRUCT_XrActionSpaceCreateInfo(_) \ _(type) \ _(next) \ @@ -1001,18 +1053,21 @@ XR_ENUM_STR(XrResult); _(subactionPath) \ _(poseInActionSpace) \ +/// Calls your macro with the name of each member of XrSpaceLocation, in order. #define XR_LIST_STRUCT_XrSpaceLocation(_) \ _(type) \ _(next) \ _(locationFlags) \ _(pose) \ +/// Calls your macro with the name of each member of XrViewConfigurationProperties, in order. #define XR_LIST_STRUCT_XrViewConfigurationProperties(_) \ _(type) \ _(next) \ _(viewConfigurationType) \ _(fovMutable) \ +/// Calls your macro with the name of each member of XrViewConfigurationView, in order. #define XR_LIST_STRUCT_XrViewConfigurationView(_) \ _(type) \ _(next) \ @@ -1023,6 +1078,7 @@ XR_ENUM_STR(XrResult); _(recommendedSwapchainSampleCount) \ _(maxSwapchainSampleCount) \ +/// Calls your macro with the name of each member of XrSwapchainCreateInfo, in order. #define XR_LIST_STRUCT_XrSwapchainCreateInfo(_) \ _(type) \ _(next) \ @@ -1036,32 +1092,39 @@ XR_ENUM_STR(XrResult); _(arraySize) \ _(mipCount) \ +/// Calls your macro with the name of each member of XrSwapchainImageBaseHeader, in order. #define XR_LIST_STRUCT_XrSwapchainImageBaseHeader(_) \ _(type) \ _(next) \ +/// Calls your macro with the name of each member of XrSwapchainImageAcquireInfo, in order. #define XR_LIST_STRUCT_XrSwapchainImageAcquireInfo(_) \ _(type) \ _(next) \ +/// Calls your macro with the name of each member of XrSwapchainImageWaitInfo, in order. #define XR_LIST_STRUCT_XrSwapchainImageWaitInfo(_) \ _(type) \ _(next) \ _(timeout) \ +/// Calls your macro with the name of each member of XrSwapchainImageReleaseInfo, in order. #define XR_LIST_STRUCT_XrSwapchainImageReleaseInfo(_) \ _(type) \ _(next) \ +/// Calls your macro with the name of each member of XrSessionBeginInfo, in order. #define XR_LIST_STRUCT_XrSessionBeginInfo(_) \ _(type) \ _(next) \ _(primaryViewConfigurationType) \ +/// Calls your macro with the name of each member of XrFrameWaitInfo, in order. #define XR_LIST_STRUCT_XrFrameWaitInfo(_) \ _(type) \ _(next) \ +/// Calls your macro with the name of each member of XrFrameState, in order. #define XR_LIST_STRUCT_XrFrameState(_) \ _(type) \ _(next) \ @@ -1069,16 +1132,19 @@ XR_ENUM_STR(XrResult); _(predictedDisplayPeriod) \ _(shouldRender) \ +/// Calls your macro with the name of each member of XrFrameBeginInfo, in order. #define XR_LIST_STRUCT_XrFrameBeginInfo(_) \ _(type) \ _(next) \ +/// Calls your macro with the name of each member of XrCompositionLayerBaseHeader, in order. #define XR_LIST_STRUCT_XrCompositionLayerBaseHeader(_) \ _(type) \ _(next) \ _(layerFlags) \ _(space) \ +/// Calls your macro with the name of each member of XrFrameEndInfo, in order. #define XR_LIST_STRUCT_XrFrameEndInfo(_) \ _(type) \ _(next) \ @@ -1087,6 +1153,7 @@ XR_ENUM_STR(XrResult); _(layerCount) \ _(layers) \ +/// Calls your macro with the name of each member of XrViewLocateInfo, in order. #define XR_LIST_STRUCT_XrViewLocateInfo(_) \ _(type) \ _(next) \ @@ -1094,23 +1161,27 @@ XR_ENUM_STR(XrResult); _(displayTime) \ _(space) \ +/// Calls your macro with the name of each member of XrViewState, in order. #define XR_LIST_STRUCT_XrViewState(_) \ _(type) \ _(next) \ _(viewStateFlags) \ +/// Calls your macro with the name of each member of XrFovf, in order. #define XR_LIST_STRUCT_XrFovf(_) \ _(angleLeft) \ _(angleRight) \ _(angleUp) \ _(angleDown) \ +/// Calls your macro with the name of each member of XrView, in order. #define XR_LIST_STRUCT_XrView(_) \ _(type) \ _(next) \ _(pose) \ _(fov) \ +/// Calls your macro with the name of each member of XrActionSetCreateInfo, in order. #define XR_LIST_STRUCT_XrActionSetCreateInfo(_) \ _(type) \ _(next) \ @@ -1118,6 +1189,7 @@ XR_ENUM_STR(XrResult); _(localizedActionSetName) \ _(priority) \ +/// Calls your macro with the name of each member of XrActionCreateInfo, in order. #define XR_LIST_STRUCT_XrActionCreateInfo(_) \ _(type) \ _(next) \ @@ -1127,10 +1199,12 @@ XR_ENUM_STR(XrResult); _(subactionPaths) \ _(localizedActionName) \ +/// Calls your macro with the name of each member of XrActionSuggestedBinding, in order. #define XR_LIST_STRUCT_XrActionSuggestedBinding(_) \ _(action) \ _(binding) \ +/// Calls your macro with the name of each member of XrInteractionProfileSuggestedBinding, in order. #define XR_LIST_STRUCT_XrInteractionProfileSuggestedBinding(_) \ _(type) \ _(next) \ @@ -1138,23 +1212,27 @@ XR_ENUM_STR(XrResult); _(countSuggestedBindings) \ _(suggestedBindings) \ +/// Calls your macro with the name of each member of XrSessionActionSetsAttachInfo, in order. #define XR_LIST_STRUCT_XrSessionActionSetsAttachInfo(_) \ _(type) \ _(next) \ _(countActionSets) \ _(actionSets) \ +/// Calls your macro with the name of each member of XrInteractionProfileState, in order. #define XR_LIST_STRUCT_XrInteractionProfileState(_) \ _(type) \ _(next) \ _(interactionProfile) \ +/// Calls your macro with the name of each member of XrActionStateGetInfo, in order. #define XR_LIST_STRUCT_XrActionStateGetInfo(_) \ _(type) \ _(next) \ _(action) \ _(subactionPath) \ +/// Calls your macro with the name of each member of XrActionStateBoolean, in order. #define XR_LIST_STRUCT_XrActionStateBoolean(_) \ _(type) \ _(next) \ @@ -1163,6 +1241,7 @@ XR_ENUM_STR(XrResult); _(lastChangeTime) \ _(isActive) \ +/// Calls your macro with the name of each member of XrActionStateFloat, in order. #define XR_LIST_STRUCT_XrActionStateFloat(_) \ _(type) \ _(next) \ @@ -1171,10 +1250,12 @@ XR_ENUM_STR(XrResult); _(lastChangeTime) \ _(isActive) \ +/// Calls your macro with the name of each member of XrVector2f, in order. #define XR_LIST_STRUCT_XrVector2f(_) \ _(x) \ _(y) \ +/// Calls your macro with the name of each member of XrActionStateVector2f, in order. #define XR_LIST_STRUCT_XrActionStateVector2f(_) \ _(type) \ _(next) \ @@ -1183,67 +1264,81 @@ XR_ENUM_STR(XrResult); _(lastChangeTime) \ _(isActive) \ +/// Calls your macro with the name of each member of XrActionStatePose, in order. #define XR_LIST_STRUCT_XrActionStatePose(_) \ _(type) \ _(next) \ _(isActive) \ +/// Calls your macro with the name of each member of XrActiveActionSet, in order. #define XR_LIST_STRUCT_XrActiveActionSet(_) \ _(actionSet) \ _(subactionPath) \ +/// Calls your macro with the name of each member of XrActionsSyncInfo, in order. #define XR_LIST_STRUCT_XrActionsSyncInfo(_) \ _(type) \ _(next) \ _(countActiveActionSets) \ _(activeActionSets) \ +/// Calls your macro with the name of each member of XrBoundSourcesForActionEnumerateInfo, in order. #define XR_LIST_STRUCT_XrBoundSourcesForActionEnumerateInfo(_) \ _(type) \ _(next) \ _(action) \ +/// Calls your macro with the name of each member of XrInputSourceLocalizedNameGetInfo, in order. #define XR_LIST_STRUCT_XrInputSourceLocalizedNameGetInfo(_) \ _(type) \ _(next) \ _(sourcePath) \ _(whichComponents) \ +/// Calls your macro with the name of each member of XrHapticActionInfo, in order. #define XR_LIST_STRUCT_XrHapticActionInfo(_) \ _(type) \ _(next) \ _(action) \ _(subactionPath) \ +/// Calls your macro with the name of each member of XrHapticBaseHeader, in order. #define XR_LIST_STRUCT_XrHapticBaseHeader(_) \ _(type) \ _(next) \ +/// Calls your macro with the name of each member of XrBaseInStructure, in order. #define XR_LIST_STRUCT_XrBaseInStructure(_) \ _(type) \ _(next) \ +/// Calls your macro with the name of each member of XrBaseOutStructure, in order. #define XR_LIST_STRUCT_XrBaseOutStructure(_) \ _(type) \ _(next) \ +/// Calls your macro with the name of each member of XrOffset2Di, in order. #define XR_LIST_STRUCT_XrOffset2Di(_) \ _(x) \ _(y) \ +/// Calls your macro with the name of each member of XrExtent2Di, in order. #define XR_LIST_STRUCT_XrExtent2Di(_) \ _(width) \ _(height) \ +/// Calls your macro with the name of each member of XrRect2Di, in order. #define XR_LIST_STRUCT_XrRect2Di(_) \ _(offset) \ _(extent) \ +/// Calls your macro with the name of each member of XrSwapchainSubImage, in order. #define XR_LIST_STRUCT_XrSwapchainSubImage(_) \ _(swapchain) \ _(imageRect) \ _(imageArrayIndex) \ +/// Calls your macro with the name of each member of XrCompositionLayerProjectionView, in order. #define XR_LIST_STRUCT_XrCompositionLayerProjectionView(_) \ _(type) \ _(next) \ @@ -1251,6 +1346,7 @@ XR_ENUM_STR(XrResult); _(fov) \ _(subImage) \ +/// Calls your macro with the name of each member of XrCompositionLayerProjection, in order. #define XR_LIST_STRUCT_XrCompositionLayerProjection(_) \ _(type) \ _(next) \ @@ -1259,6 +1355,7 @@ XR_ENUM_STR(XrResult); _(viewCount) \ _(views) \ +/// Calls your macro with the name of each member of XrCompositionLayerQuad, in order. #define XR_LIST_STRUCT_XrCompositionLayerQuad(_) \ _(type) \ _(next) \ @@ -1269,20 +1366,24 @@ XR_ENUM_STR(XrResult); _(pose) \ _(size) \ +/// Calls your macro with the name of each member of XrEventDataBaseHeader, in order. #define XR_LIST_STRUCT_XrEventDataBaseHeader(_) \ _(type) \ _(next) \ +/// Calls your macro with the name of each member of XrEventDataEventsLost, in order. #define XR_LIST_STRUCT_XrEventDataEventsLost(_) \ _(type) \ _(next) \ _(lostEventCount) \ +/// Calls your macro with the name of each member of XrEventDataInstanceLossPending, in order. #define XR_LIST_STRUCT_XrEventDataInstanceLossPending(_) \ _(type) \ _(next) \ _(lossTime) \ +/// Calls your macro with the name of each member of XrEventDataSessionStateChanged, in order. #define XR_LIST_STRUCT_XrEventDataSessionStateChanged(_) \ _(type) \ _(next) \ @@ -1290,6 +1391,7 @@ XR_ENUM_STR(XrResult); _(state) \ _(time) \ +/// Calls your macro with the name of each member of XrEventDataReferenceSpaceChangePending, in order. #define XR_LIST_STRUCT_XrEventDataReferenceSpaceChangePending(_) \ _(type) \ _(next) \ @@ -1299,11 +1401,13 @@ XR_ENUM_STR(XrResult); _(poseValid) \ _(poseInPreviousSpace) \ +/// Calls your macro with the name of each member of XrEventDataInteractionProfileChanged, in order. #define XR_LIST_STRUCT_XrEventDataInteractionProfileChanged(_) \ _(type) \ _(next) \ _(session) \ +/// Calls your macro with the name of each member of XrHapticVibration, in order. #define XR_LIST_STRUCT_XrHapticVibration(_) \ _(type) \ _(next) \ @@ -1311,26 +1415,31 @@ XR_ENUM_STR(XrResult); _(frequency) \ _(amplitude) \ +/// Calls your macro with the name of each member of XrOffset2Df, in order. #define XR_LIST_STRUCT_XrOffset2Df(_) \ _(x) \ _(y) \ +/// Calls your macro with the name of each member of XrRect2Df, in order. #define XR_LIST_STRUCT_XrRect2Df(_) \ _(offset) \ _(extent) \ +/// Calls your macro with the name of each member of XrVector4f, in order. #define XR_LIST_STRUCT_XrVector4f(_) \ _(x) \ _(y) \ _(z) \ _(w) \ +/// Calls your macro with the name of each member of XrColor4f, in order. #define XR_LIST_STRUCT_XrColor4f(_) \ _(r) \ _(g) \ _(b) \ _(a) \ +/// Calls your macro with the name of each member of XrCompositionLayerCubeKHR, in order. #define XR_LIST_STRUCT_XrCompositionLayerCubeKHR(_) \ _(type) \ _(next) \ @@ -1341,12 +1450,14 @@ XR_ENUM_STR(XrResult); _(imageArrayIndex) \ _(orientation) \ +/// Calls your macro with the name of each member of XrInstanceCreateInfoAndroidKHR, in order. #define XR_LIST_STRUCT_XrInstanceCreateInfoAndroidKHR(_) \ _(type) \ _(next) \ _(applicationVM) \ _(applicationActivity) \ +/// Calls your macro with the name of each member of XrCompositionLayerDepthInfoKHR, in order. #define XR_LIST_STRUCT_XrCompositionLayerDepthInfoKHR(_) \ _(type) \ _(next) \ @@ -1356,12 +1467,14 @@ XR_ENUM_STR(XrResult); _(nearZ) \ _(farZ) \ +/// Calls your macro with the name of each member of XrVulkanSwapchainFormatListCreateInfoKHR, in order. #define XR_LIST_STRUCT_XrVulkanSwapchainFormatListCreateInfoKHR(_) \ _(type) \ _(next) \ _(viewFormatCount) \ _(viewFormats) \ +/// Calls your macro with the name of each member of XrCompositionLayerCylinderKHR, in order. #define XR_LIST_STRUCT_XrCompositionLayerCylinderKHR(_) \ _(type) \ _(next) \ @@ -1374,6 +1487,7 @@ XR_ENUM_STR(XrResult); _(centralAngle) \ _(aspectRatio) \ +/// Calls your macro with the name of each member of XrCompositionLayerEquirectKHR, in order. #define XR_LIST_STRUCT_XrCompositionLayerEquirectKHR(_) \ _(type) \ _(next) \ @@ -1386,12 +1500,14 @@ XR_ENUM_STR(XrResult); _(scale) \ _(bias) \ +/// Calls your macro with the name of each member of XrGraphicsBindingOpenGLWin32KHR, in order. #define XR_LIST_STRUCT_XrGraphicsBindingOpenGLWin32KHR(_) \ _(type) \ _(next) \ _(hDC) \ _(hGLRC) \ +/// Calls your macro with the name of each member of XrGraphicsBindingOpenGLXlibKHR, in order. #define XR_LIST_STRUCT_XrGraphicsBindingOpenGLXlibKHR(_) \ _(type) \ _(next) \ @@ -1401,6 +1517,7 @@ XR_ENUM_STR(XrResult); _(glxDrawable) \ _(glxContext) \ +/// Calls your macro with the name of each member of XrGraphicsBindingOpenGLXcbKHR, in order. #define XR_LIST_STRUCT_XrGraphicsBindingOpenGLXcbKHR(_) \ _(type) \ _(next) \ @@ -1411,22 +1528,26 @@ XR_ENUM_STR(XrResult); _(glxDrawable) \ _(glxContext) \ +/// Calls your macro with the name of each member of XrGraphicsBindingOpenGLWaylandKHR, in order. #define XR_LIST_STRUCT_XrGraphicsBindingOpenGLWaylandKHR(_) \ _(type) \ _(next) \ _(display) \ +/// Calls your macro with the name of each member of XrSwapchainImageOpenGLKHR, in order. #define XR_LIST_STRUCT_XrSwapchainImageOpenGLKHR(_) \ _(type) \ _(next) \ _(image) \ +/// Calls your macro with the name of each member of XrGraphicsRequirementsOpenGLKHR, in order. #define XR_LIST_STRUCT_XrGraphicsRequirementsOpenGLKHR(_) \ _(type) \ _(next) \ _(minApiVersionSupported) \ _(maxApiVersionSupported) \ +/// Calls your macro with the name of each member of XrGraphicsBindingOpenGLESAndroidKHR, in order. #define XR_LIST_STRUCT_XrGraphicsBindingOpenGLESAndroidKHR(_) \ _(type) \ _(next) \ @@ -1434,17 +1555,20 @@ XR_ENUM_STR(XrResult); _(config) \ _(context) \ +/// Calls your macro with the name of each member of XrSwapchainImageOpenGLESKHR, in order. #define XR_LIST_STRUCT_XrSwapchainImageOpenGLESKHR(_) \ _(type) \ _(next) \ _(image) \ +/// Calls your macro with the name of each member of XrGraphicsRequirementsOpenGLESKHR, in order. #define XR_LIST_STRUCT_XrGraphicsRequirementsOpenGLESKHR(_) \ _(type) \ _(next) \ _(minApiVersionSupported) \ _(maxApiVersionSupported) \ +/// Calls your macro with the name of each member of XrGraphicsBindingVulkanKHR, in order. #define XR_LIST_STRUCT_XrGraphicsBindingVulkanKHR(_) \ _(type) \ _(next) \ @@ -1454,50 +1578,59 @@ XR_ENUM_STR(XrResult); _(queueFamilyIndex) \ _(queueIndex) \ +/// Calls your macro with the name of each member of XrSwapchainImageVulkanKHR, in order. #define XR_LIST_STRUCT_XrSwapchainImageVulkanKHR(_) \ _(type) \ _(next) \ _(image) \ +/// Calls your macro with the name of each member of XrGraphicsRequirementsVulkanKHR, in order. #define XR_LIST_STRUCT_XrGraphicsRequirementsVulkanKHR(_) \ _(type) \ _(next) \ _(minApiVersionSupported) \ _(maxApiVersionSupported) \ +/// Calls your macro with the name of each member of XrGraphicsBindingD3D11KHR, in order. #define XR_LIST_STRUCT_XrGraphicsBindingD3D11KHR(_) \ _(type) \ _(next) \ _(device) \ +/// Calls your macro with the name of each member of XrSwapchainImageD3D11KHR, in order. #define XR_LIST_STRUCT_XrSwapchainImageD3D11KHR(_) \ _(type) \ _(next) \ _(texture) \ +/// Calls your macro with the name of each member of XrGraphicsRequirementsD3D11KHR, in order. #define XR_LIST_STRUCT_XrGraphicsRequirementsD3D11KHR(_) \ _(type) \ _(next) \ _(adapterLuid) \ _(minFeatureLevel) \ +/// Calls your macro with the name of each member of XrGraphicsBindingD3D12KHR, in order. #define XR_LIST_STRUCT_XrGraphicsBindingD3D12KHR(_) \ _(type) \ _(next) \ _(device) \ _(queue) \ +/// Calls your macro with the name of each member of XrSwapchainImageD3D12KHR, in order. #define XR_LIST_STRUCT_XrSwapchainImageD3D12KHR(_) \ _(type) \ _(next) \ _(texture) \ +/// Calls your macro with the name of each member of XrGraphicsRequirementsD3D12KHR, in order. #define XR_LIST_STRUCT_XrGraphicsRequirementsD3D12KHR(_) \ _(type) \ _(next) \ _(adapterLuid) \ _(minFeatureLevel) \ +/// Calls your macro with the name of each member of XrVisibilityMaskKHR, in order. #define XR_LIST_STRUCT_XrVisibilityMaskKHR(_) \ _(type) \ _(next) \ @@ -1508,6 +1641,7 @@ XR_ENUM_STR(XrResult); _(indexCountOutput) \ _(indices) \ +/// Calls your macro with the name of each member of XrEventDataVisibilityMaskChangedKHR, in order. #define XR_LIST_STRUCT_XrEventDataVisibilityMaskChangedKHR(_) \ _(type) \ _(next) \ @@ -1515,22 +1649,26 @@ XR_ENUM_STR(XrResult); _(viewConfigurationType) \ _(viewIndex) \ +/// Calls your macro with the name of each member of XrCompositionLayerColorScaleBiasKHR, in order. #define XR_LIST_STRUCT_XrCompositionLayerColorScaleBiasKHR(_) \ _(type) \ _(next) \ _(colorScale) \ _(colorBias) \ +/// Calls your macro with the name of each member of XrLoaderInitInfoBaseHeaderKHR, in order. #define XR_LIST_STRUCT_XrLoaderInitInfoBaseHeaderKHR(_) \ _(type) \ _(next) \ +/// Calls your macro with the name of each member of XrLoaderInitInfoAndroidKHR, in order. #define XR_LIST_STRUCT_XrLoaderInitInfoAndroidKHR(_) \ _(type) \ _(next) \ _(applicationVM) \ _(applicationContext) \ +/// Calls your macro with the name of each member of XrVulkanInstanceCreateInfoKHR, in order. #define XR_LIST_STRUCT_XrVulkanInstanceCreateInfoKHR(_) \ _(type) \ _(next) \ @@ -1540,6 +1678,7 @@ XR_ENUM_STR(XrResult); _(vulkanCreateInfo) \ _(vulkanAllocator) \ +/// Calls your macro with the name of each member of XrVulkanDeviceCreateInfoKHR, in order. #define XR_LIST_STRUCT_XrVulkanDeviceCreateInfoKHR(_) \ _(type) \ _(next) \ @@ -1550,12 +1689,14 @@ XR_ENUM_STR(XrResult); _(vulkanCreateInfo) \ _(vulkanAllocator) \ +/// Calls your macro with the name of each member of XrVulkanGraphicsDeviceGetInfoKHR, in order. #define XR_LIST_STRUCT_XrVulkanGraphicsDeviceGetInfoKHR(_) \ _(type) \ _(next) \ _(systemId) \ _(vulkanInstance) \ +/// Calls your macro with the name of each member of XrCompositionLayerEquirect2KHR, in order. #define XR_LIST_STRUCT_XrCompositionLayerEquirect2KHR(_) \ _(type) \ _(next) \ @@ -1569,16 +1710,19 @@ XR_ENUM_STR(XrResult); _(upperVerticalAngle) \ _(lowerVerticalAngle) \ +/// Calls your macro with the name of each member of XrBindingModificationBaseHeaderKHR, in order. #define XR_LIST_STRUCT_XrBindingModificationBaseHeaderKHR(_) \ _(type) \ _(next) \ +/// Calls your macro with the name of each member of XrBindingModificationsKHR, in order. #define XR_LIST_STRUCT_XrBindingModificationsKHR(_) \ _(type) \ _(next) \ _(bindingModificationCount) \ _(bindingModifications) \ +/// Calls your macro with the name of each member of XrEventDataPerfSettingsEXT, in order. #define XR_LIST_STRUCT_XrEventDataPerfSettingsEXT(_) \ _(type) \ _(next) \ @@ -1587,6 +1731,7 @@ XR_ENUM_STR(XrResult); _(fromLevel) \ _(toLevel) \ +/// Calls your macro with the name of each member of XrDebugUtilsObjectNameInfoEXT, in order. #define XR_LIST_STRUCT_XrDebugUtilsObjectNameInfoEXT(_) \ _(type) \ _(next) \ @@ -1594,11 +1739,13 @@ XR_ENUM_STR(XrResult); _(objectHandle) \ _(objectName) \ +/// Calls your macro with the name of each member of XrDebugUtilsLabelEXT, in order. #define XR_LIST_STRUCT_XrDebugUtilsLabelEXT(_) \ _(type) \ _(next) \ _(labelName) \ +/// Calls your macro with the name of each member of XrDebugUtilsMessengerCallbackDataEXT, in order. #define XR_LIST_STRUCT_XrDebugUtilsMessengerCallbackDataEXT(_) \ _(type) \ _(next) \ @@ -1610,6 +1757,7 @@ XR_ENUM_STR(XrResult); _(sessionLabelCount) \ _(sessionLabels) \ +/// Calls your macro with the name of each member of XrDebugUtilsMessengerCreateInfoEXT, in order. #define XR_LIST_STRUCT_XrDebugUtilsMessengerCreateInfoEXT(_) \ _(type) \ _(next) \ @@ -1618,28 +1766,33 @@ XR_ENUM_STR(XrResult); _(userCallback) \ _(userData) \ +/// Calls your macro with the name of each member of XrSystemEyeGazeInteractionPropertiesEXT, in order. #define XR_LIST_STRUCT_XrSystemEyeGazeInteractionPropertiesEXT(_) \ _(type) \ _(next) \ _(supportsEyeGazeInteraction) \ +/// Calls your macro with the name of each member of XrEyeGazeSampleTimeEXT, in order. #define XR_LIST_STRUCT_XrEyeGazeSampleTimeEXT(_) \ _(type) \ _(next) \ _(time) \ +/// Calls your macro with the name of each member of XrSessionCreateInfoOverlayEXTX, in order. #define XR_LIST_STRUCT_XrSessionCreateInfoOverlayEXTX(_) \ _(type) \ _(next) \ _(createFlags) \ _(sessionLayersPlacement) \ +/// Calls your macro with the name of each member of XrEventDataMainSessionVisibilityChangedEXTX, in order. #define XR_LIST_STRUCT_XrEventDataMainSessionVisibilityChangedEXTX(_) \ _(type) \ _(next) \ _(visible) \ _(flags) \ +/// Calls your macro with the name of each member of XrSpatialAnchorCreateInfoMSFT, in order. #define XR_LIST_STRUCT_XrSpatialAnchorCreateInfoMSFT(_) \ _(type) \ _(next) \ @@ -1647,17 +1800,20 @@ XR_ENUM_STR(XrResult); _(pose) \ _(time) \ +/// Calls your macro with the name of each member of XrSpatialAnchorSpaceCreateInfoMSFT, in order. #define XR_LIST_STRUCT_XrSpatialAnchorSpaceCreateInfoMSFT(_) \ _(type) \ _(next) \ _(anchor) \ _(poseInAnchorSpace) \ +/// Calls your macro with the name of each member of XrCompositionLayerImageLayoutFB, in order. #define XR_LIST_STRUCT_XrCompositionLayerImageLayoutFB(_) \ _(type) \ _(next) \ _(flags) \ +/// Calls your macro with the name of each member of XrCompositionLayerAlphaBlendFB, in order. #define XR_LIST_STRUCT_XrCompositionLayerAlphaBlendFB(_) \ _(type) \ _(next) \ @@ -1666,6 +1822,7 @@ XR_ENUM_STR(XrResult); _(srcFactorAlpha) \ _(dstFactorAlpha) \ +/// Calls your macro with the name of each member of XrViewConfigurationDepthRangeEXT, in order. #define XR_LIST_STRUCT_XrViewConfigurationDepthRangeEXT(_) \ _(type) \ _(next) \ @@ -1674,6 +1831,7 @@ XR_ENUM_STR(XrResult); _(recommendedFarZ) \ _(maxFarZ) \ +/// Calls your macro with the name of each member of XrGraphicsBindingEGLMNDX, in order. #define XR_LIST_STRUCT_XrGraphicsBindingEGLMNDX(_) \ _(type) \ _(next) \ @@ -1682,6 +1840,7 @@ XR_ENUM_STR(XrResult); _(config) \ _(context) \ +/// Calls your macro with the name of each member of XrSpatialGraphNodeSpaceCreateInfoMSFT, in order. #define XR_LIST_STRUCT_XrSpatialGraphNodeSpaceCreateInfoMSFT(_) \ _(type) \ _(next) \ @@ -1689,6 +1848,7 @@ XR_ENUM_STR(XrResult); _(nodeId) \ _(pose) \ +/// Calls your macro with the name of each member of XrSpatialGraphStaticNodeBindingCreateInfoMSFT, in order. #define XR_LIST_STRUCT_XrSpatialGraphStaticNodeBindingCreateInfoMSFT(_) \ _(type) \ _(next) \ @@ -1696,43 +1856,51 @@ XR_ENUM_STR(XrResult); _(poseInSpace) \ _(time) \ +/// Calls your macro with the name of each member of XrSpatialGraphNodeBindingPropertiesGetInfoMSFT, in order. #define XR_LIST_STRUCT_XrSpatialGraphNodeBindingPropertiesGetInfoMSFT(_) \ _(type) \ _(next) \ +/// Calls your macro with the name of each member of XrSpatialGraphNodeBindingPropertiesMSFT, in order. #define XR_LIST_STRUCT_XrSpatialGraphNodeBindingPropertiesMSFT(_) \ _(type) \ _(next) \ _(nodeId) \ _(poseInNodeSpace) \ +/// Calls your macro with the name of each member of XrSystemHandTrackingPropertiesEXT, in order. #define XR_LIST_STRUCT_XrSystemHandTrackingPropertiesEXT(_) \ _(type) \ _(next) \ _(supportsHandTracking) \ +/// Calls your macro with the name of each member of XrHandTrackerCreateInfoEXT, in order. #define XR_LIST_STRUCT_XrHandTrackerCreateInfoEXT(_) \ _(type) \ _(next) \ _(hand) \ _(handJointSet) \ +/// Calls your macro with the name of each member of XrHandJointsLocateInfoEXT, in order. #define XR_LIST_STRUCT_XrHandJointsLocateInfoEXT(_) \ _(type) \ _(next) \ _(baseSpace) \ _(time) \ +/// Calls your macro with the name of each member of XrHandJointLocationEXT, in order. #define XR_LIST_STRUCT_XrHandJointLocationEXT(_) \ _(locationFlags) \ _(pose) \ _(radius) \ +/// Calls your macro with the name of each member of XrHandJointVelocityEXT, in order. #define XR_LIST_STRUCT_XrHandJointVelocityEXT(_) \ _(velocityFlags) \ _(linearVelocity) \ _(angularVelocity) \ +/// Calls your macro with the name of each member of XrHandJointLocationsEXT, in order. #define XR_LIST_STRUCT_XrHandJointLocationsEXT(_) \ _(type) \ _(next) \ @@ -1740,12 +1908,14 @@ XR_ENUM_STR(XrResult); _(jointCount) \ _(jointLocations) \ +/// Calls your macro with the name of each member of XrHandJointVelocitiesEXT, in order. #define XR_LIST_STRUCT_XrHandJointVelocitiesEXT(_) \ _(type) \ _(next) \ _(jointCount) \ _(jointVelocities) \ +/// Calls your macro with the name of each member of XrSystemHandTrackingMeshPropertiesMSFT, in order. #define XR_LIST_STRUCT_XrSystemHandTrackingMeshPropertiesMSFT(_) \ _(type) \ _(next) \ @@ -1753,34 +1923,40 @@ XR_ENUM_STR(XrResult); _(maxHandMeshIndexCount) \ _(maxHandMeshVertexCount) \ +/// Calls your macro with the name of each member of XrHandMeshSpaceCreateInfoMSFT, in order. #define XR_LIST_STRUCT_XrHandMeshSpaceCreateInfoMSFT(_) \ _(type) \ _(next) \ _(handPoseType) \ _(poseInHandMeshSpace) \ +/// Calls your macro with the name of each member of XrHandMeshUpdateInfoMSFT, in order. #define XR_LIST_STRUCT_XrHandMeshUpdateInfoMSFT(_) \ _(type) \ _(next) \ _(time) \ _(handPoseType) \ +/// Calls your macro with the name of each member of XrHandMeshIndexBufferMSFT, in order. #define XR_LIST_STRUCT_XrHandMeshIndexBufferMSFT(_) \ _(indexBufferKey) \ _(indexCapacityInput) \ _(indexCountOutput) \ _(indices) \ +/// Calls your macro with the name of each member of XrHandMeshVertexMSFT, in order. #define XR_LIST_STRUCT_XrHandMeshVertexMSFT(_) \ _(position) \ _(normal) \ +/// Calls your macro with the name of each member of XrHandMeshVertexBufferMSFT, in order. #define XR_LIST_STRUCT_XrHandMeshVertexBufferMSFT(_) \ _(vertexUpdateTime) \ _(vertexCapacityInput) \ _(vertexCountOutput) \ _(vertices) \ +/// Calls your macro with the name of each member of XrHandMeshMSFT, in order. #define XR_LIST_STRUCT_XrHandMeshMSFT(_) \ _(type) \ _(next) \ @@ -1790,29 +1966,34 @@ XR_ENUM_STR(XrResult); _(indexBuffer) \ _(vertexBuffer) \ +/// Calls your macro with the name of each member of XrHandPoseTypeInfoMSFT, in order. #define XR_LIST_STRUCT_XrHandPoseTypeInfoMSFT(_) \ _(type) \ _(next) \ _(handPoseType) \ +/// Calls your macro with the name of each member of XrSecondaryViewConfigurationSessionBeginInfoMSFT, in order. #define XR_LIST_STRUCT_XrSecondaryViewConfigurationSessionBeginInfoMSFT(_) \ _(type) \ _(next) \ _(viewConfigurationCount) \ _(enabledViewConfigurationTypes) \ +/// Calls your macro with the name of each member of XrSecondaryViewConfigurationStateMSFT, in order. #define XR_LIST_STRUCT_XrSecondaryViewConfigurationStateMSFT(_) \ _(type) \ _(next) \ _(viewConfigurationType) \ _(active) \ +/// Calls your macro with the name of each member of XrSecondaryViewConfigurationFrameStateMSFT, in order. #define XR_LIST_STRUCT_XrSecondaryViewConfigurationFrameStateMSFT(_) \ _(type) \ _(next) \ _(viewConfigurationCount) \ _(viewConfigurationStates) \ +/// Calls your macro with the name of each member of XrSecondaryViewConfigurationLayerInfoMSFT, in order. #define XR_LIST_STRUCT_XrSecondaryViewConfigurationLayerInfoMSFT(_) \ _(type) \ _(next) \ @@ -1821,28 +2002,33 @@ XR_ENUM_STR(XrResult); _(layerCount) \ _(layers) \ +/// Calls your macro with the name of each member of XrSecondaryViewConfigurationFrameEndInfoMSFT, in order. #define XR_LIST_STRUCT_XrSecondaryViewConfigurationFrameEndInfoMSFT(_) \ _(type) \ _(next) \ _(viewConfigurationCount) \ _(viewConfigurationLayersInfo) \ +/// Calls your macro with the name of each member of XrSecondaryViewConfigurationSwapchainCreateInfoMSFT, in order. #define XR_LIST_STRUCT_XrSecondaryViewConfigurationSwapchainCreateInfoMSFT(_) \ _(type) \ _(next) \ _(viewConfigurationType) \ +/// Calls your macro with the name of each member of XrControllerModelKeyStateMSFT, in order. #define XR_LIST_STRUCT_XrControllerModelKeyStateMSFT(_) \ _(type) \ _(next) \ _(modelKey) \ +/// Calls your macro with the name of each member of XrControllerModelNodePropertiesMSFT, in order. #define XR_LIST_STRUCT_XrControllerModelNodePropertiesMSFT(_) \ _(type) \ _(next) \ _(parentNodeName) \ _(nodeName) \ +/// Calls your macro with the name of each member of XrControllerModelPropertiesMSFT, in order. #define XR_LIST_STRUCT_XrControllerModelPropertiesMSFT(_) \ _(type) \ _(next) \ @@ -1850,11 +2036,13 @@ XR_ENUM_STR(XrResult); _(nodeCountOutput) \ _(nodeProperties) \ +/// Calls your macro with the name of each member of XrControllerModelNodeStateMSFT, in order. #define XR_LIST_STRUCT_XrControllerModelNodeStateMSFT(_) \ _(type) \ _(next) \ _(nodePose) \ +/// Calls your macro with the name of each member of XrControllerModelStateMSFT, in order. #define XR_LIST_STRUCT_XrControllerModelStateMSFT(_) \ _(type) \ _(next) \ @@ -1862,23 +2050,27 @@ XR_ENUM_STR(XrResult); _(nodeCountOutput) \ _(nodeStates) \ +/// Calls your macro with the name of each member of XrViewConfigurationViewFovEPIC, in order. #define XR_LIST_STRUCT_XrViewConfigurationViewFovEPIC(_) \ _(type) \ _(next) \ _(recommendedFov) \ _(maxMutableFov) \ +/// Calls your macro with the name of each member of XrHolographicWindowAttachmentMSFT, in order. #define XR_LIST_STRUCT_XrHolographicWindowAttachmentMSFT(_) \ _(type) \ _(next) \ _(holographicSpace) \ _(coreWindow) \ +/// Calls your macro with the name of each member of XrCompositionLayerReprojectionInfoMSFT, in order. #define XR_LIST_STRUCT_XrCompositionLayerReprojectionInfoMSFT(_) \ _(type) \ _(next) \ _(reprojectionMode) \ +/// Calls your macro with the name of each member of XrCompositionLayerReprojectionPlaneOverrideMSFT, in order. #define XR_LIST_STRUCT_XrCompositionLayerReprojectionPlaneOverrideMSFT(_) \ _(type) \ _(next) \ @@ -1886,20 +2078,24 @@ XR_ENUM_STR(XrResult); _(normal) \ _(velocity) \ +/// Calls your macro with the name of each member of XrAndroidSurfaceSwapchainCreateInfoFB, in order. #define XR_LIST_STRUCT_XrAndroidSurfaceSwapchainCreateInfoFB(_) \ _(type) \ _(next) \ _(createFlags) \ +/// Calls your macro with the name of each member of XrSwapchainStateBaseHeaderFB, in order. #define XR_LIST_STRUCT_XrSwapchainStateBaseHeaderFB(_) \ _(type) \ _(next) \ +/// Calls your macro with the name of each member of XrCompositionLayerSecureContentFB, in order. #define XR_LIST_STRUCT_XrCompositionLayerSecureContentFB(_) \ _(type) \ _(next) \ _(flags) \ +/// Calls your macro with the name of each member of XrInteractionProfileDpadBindingEXT, in order. #define XR_LIST_STRUCT_XrInteractionProfileDpadBindingEXT(_) \ _(type) \ _(next) \ @@ -1913,6 +2109,7 @@ XR_ENUM_STR(XrResult); _(onHaptic) \ _(offHaptic) \ +/// Calls your macro with the name of each member of XrInteractionProfileAnalogThresholdVALVE, in order. #define XR_LIST_STRUCT_XrInteractionProfileAnalogThresholdVALVE(_) \ _(type) \ _(next) \ @@ -1923,35 +2120,43 @@ XR_ENUM_STR(XrResult); _(onHaptic) \ _(offHaptic) \ +/// Calls your macro with the name of each member of XrHandJointsMotionRangeInfoEXT, in order. #define XR_LIST_STRUCT_XrHandJointsMotionRangeInfoEXT(_) \ _(type) \ _(next) \ _(handJointsMotionRange) \ +/// Calls your macro with the name of each member of XrUuidMSFT, in order. #define XR_LIST_STRUCT_XrUuidMSFT(_) \ _(bytes) \ +/// Calls your macro with the name of each member of XrSceneObserverCreateInfoMSFT, in order. #define XR_LIST_STRUCT_XrSceneObserverCreateInfoMSFT(_) \ _(type) \ _(next) \ +/// Calls your macro with the name of each member of XrSceneCreateInfoMSFT, in order. #define XR_LIST_STRUCT_XrSceneCreateInfoMSFT(_) \ _(type) \ _(next) \ +/// Calls your macro with the name of each member of XrSceneSphereBoundMSFT, in order. #define XR_LIST_STRUCT_XrSceneSphereBoundMSFT(_) \ _(center) \ _(radius) \ +/// Calls your macro with the name of each member of XrSceneOrientedBoxBoundMSFT, in order. #define XR_LIST_STRUCT_XrSceneOrientedBoxBoundMSFT(_) \ _(pose) \ _(extents) \ +/// Calls your macro with the name of each member of XrSceneFrustumBoundMSFT, in order. #define XR_LIST_STRUCT_XrSceneFrustumBoundMSFT(_) \ _(pose) \ _(fov) \ _(farDistance) \ +/// Calls your macro with the name of each member of XrSceneBoundsMSFT, in order. #define XR_LIST_STRUCT_XrSceneBoundsMSFT(_) \ _(space) \ _(time) \ @@ -1962,6 +2167,7 @@ XR_ENUM_STR(XrResult); _(frustumCount) \ _(frustums) \ +/// Calls your macro with the name of each member of XrNewSceneComputeInfoMSFT, in order. #define XR_LIST_STRUCT_XrNewSceneComputeInfoMSFT(_) \ _(type) \ _(next) \ @@ -1970,17 +2176,20 @@ XR_ENUM_STR(XrResult); _(consistency) \ _(bounds) \ +/// Calls your macro with the name of each member of XrVisualMeshComputeLodInfoMSFT, in order. #define XR_LIST_STRUCT_XrVisualMeshComputeLodInfoMSFT(_) \ _(type) \ _(next) \ _(lod) \ +/// Calls your macro with the name of each member of XrSceneComponentMSFT, in order. #define XR_LIST_STRUCT_XrSceneComponentMSFT(_) \ _(componentType) \ _(id) \ _(parentId) \ _(updateTime) \ +/// Calls your macro with the name of each member of XrSceneComponentsMSFT, in order. #define XR_LIST_STRUCT_XrSceneComponentsMSFT(_) \ _(type) \ _(next) \ @@ -1988,21 +2197,25 @@ XR_ENUM_STR(XrResult); _(componentCountOutput) \ _(components) \ +/// Calls your macro with the name of each member of XrSceneComponentsGetInfoMSFT, in order. #define XR_LIST_STRUCT_XrSceneComponentsGetInfoMSFT(_) \ _(type) \ _(next) \ _(componentType) \ +/// Calls your macro with the name of each member of XrSceneComponentLocationMSFT, in order. #define XR_LIST_STRUCT_XrSceneComponentLocationMSFT(_) \ _(flags) \ _(pose) \ +/// Calls your macro with the name of each member of XrSceneComponentLocationsMSFT, in order. #define XR_LIST_STRUCT_XrSceneComponentLocationsMSFT(_) \ _(type) \ _(next) \ _(locationCount) \ _(locations) \ +/// Calls your macro with the name of each member of XrSceneComponentsLocateInfoMSFT, in order. #define XR_LIST_STRUCT_XrSceneComponentsLocateInfoMSFT(_) \ _(type) \ _(next) \ @@ -2011,63 +2224,75 @@ XR_ENUM_STR(XrResult); _(componentIdCount) \ _(componentIds) \ +/// Calls your macro with the name of each member of XrSceneObjectMSFT, in order. #define XR_LIST_STRUCT_XrSceneObjectMSFT(_) \ _(objectType) \ +/// Calls your macro with the name of each member of XrSceneObjectsMSFT, in order. #define XR_LIST_STRUCT_XrSceneObjectsMSFT(_) \ _(type) \ _(next) \ _(sceneObjectCount) \ _(sceneObjects) \ +/// Calls your macro with the name of each member of XrSceneComponentParentFilterInfoMSFT, in order. #define XR_LIST_STRUCT_XrSceneComponentParentFilterInfoMSFT(_) \ _(type) \ _(next) \ _(parentId) \ +/// Calls your macro with the name of each member of XrSceneObjectTypesFilterInfoMSFT, in order. #define XR_LIST_STRUCT_XrSceneObjectTypesFilterInfoMSFT(_) \ _(type) \ _(next) \ _(objectTypeCount) \ _(objectTypes) \ +/// Calls your macro with the name of each member of XrScenePlaneMSFT, in order. #define XR_LIST_STRUCT_XrScenePlaneMSFT(_) \ _(alignment) \ _(size) \ _(meshBufferId) \ _(supportsIndicesUint16) \ +/// Calls your macro with the name of each member of XrScenePlanesMSFT, in order. #define XR_LIST_STRUCT_XrScenePlanesMSFT(_) \ _(type) \ _(next) \ _(scenePlaneCount) \ _(scenePlanes) \ +/// Calls your macro with the name of each member of XrScenePlaneAlignmentFilterInfoMSFT, in order. #define XR_LIST_STRUCT_XrScenePlaneAlignmentFilterInfoMSFT(_) \ _(type) \ _(next) \ _(alignmentCount) \ _(alignments) \ +/// Calls your macro with the name of each member of XrSceneMeshMSFT, in order. #define XR_LIST_STRUCT_XrSceneMeshMSFT(_) \ _(meshBufferId) \ _(supportsIndicesUint16) \ +/// Calls your macro with the name of each member of XrSceneMeshesMSFT, in order. #define XR_LIST_STRUCT_XrSceneMeshesMSFT(_) \ _(type) \ _(next) \ _(sceneMeshCount) \ _(sceneMeshes) \ +/// Calls your macro with the name of each member of XrSceneMeshBuffersGetInfoMSFT, in order. #define XR_LIST_STRUCT_XrSceneMeshBuffersGetInfoMSFT(_) \ _(type) \ _(next) \ _(meshBufferId) \ +/// Calls your macro with the name of each member of XrSceneMeshBuffersMSFT, in order. #define XR_LIST_STRUCT_XrSceneMeshBuffersMSFT(_) \ _(type) \ _(next) \ +/// Calls your macro with the name of each member of XrSceneMeshVertexBufferMSFT, in order. #define XR_LIST_STRUCT_XrSceneMeshVertexBufferMSFT(_) \ _(type) \ _(next) \ @@ -2075,6 +2300,7 @@ XR_ENUM_STR(XrResult); _(vertexCountOutput) \ _(vertices) \ +/// Calls your macro with the name of each member of XrSceneMeshIndicesUint32MSFT, in order. #define XR_LIST_STRUCT_XrSceneMeshIndicesUint32MSFT(_) \ _(type) \ _(next) \ @@ -2082,6 +2308,7 @@ XR_ENUM_STR(XrResult); _(indexCountOutput) \ _(indices) \ +/// Calls your macro with the name of each member of XrSceneMeshIndicesUint16MSFT, in order. #define XR_LIST_STRUCT_XrSceneMeshIndicesUint16MSFT(_) \ _(type) \ _(next) \ @@ -2089,44 +2316,52 @@ XR_ENUM_STR(XrResult); _(indexCountOutput) \ _(indices) \ +/// Calls your macro with the name of each member of XrSerializedSceneFragmentDataGetInfoMSFT, in order. #define XR_LIST_STRUCT_XrSerializedSceneFragmentDataGetInfoMSFT(_) \ _(type) \ _(next) \ _(sceneFragmentId) \ +/// Calls your macro with the name of each member of XrDeserializeSceneFragmentMSFT, in order. #define XR_LIST_STRUCT_XrDeserializeSceneFragmentMSFT(_) \ _(bufferSize) \ _(buffer) \ +/// Calls your macro with the name of each member of XrSceneDeserializeInfoMSFT, in order. #define XR_LIST_STRUCT_XrSceneDeserializeInfoMSFT(_) \ _(type) \ _(next) \ _(fragmentCount) \ _(fragments) \ +/// Calls your macro with the name of each member of XrEventDataDisplayRefreshRateChangedFB, in order. #define XR_LIST_STRUCT_XrEventDataDisplayRefreshRateChangedFB(_) \ _(type) \ _(next) \ _(fromDisplayRefreshRate) \ _(toDisplayRefreshRate) \ +/// Calls your macro with the name of each member of XrViveTrackerPathsHTCX, in order. #define XR_LIST_STRUCT_XrViveTrackerPathsHTCX(_) \ _(type) \ _(next) \ _(persistentPath) \ _(rolePath) \ +/// Calls your macro with the name of each member of XrEventDataViveTrackerConnectedHTCX, in order. #define XR_LIST_STRUCT_XrEventDataViveTrackerConnectedHTCX(_) \ _(type) \ _(next) \ _(paths) \ +/// Calls your macro with the name of each member of XrSystemFacialTrackingPropertiesHTC, in order. #define XR_LIST_STRUCT_XrSystemFacialTrackingPropertiesHTC(_) \ _(type) \ _(next) \ _(supportEyeFacialTracking) \ _(supportLipFacialTracking) \ +/// Calls your macro with the name of each member of XrFacialExpressionsHTC, in order. #define XR_LIST_STRUCT_XrFacialExpressionsHTC(_) \ _(type) \ _(next) \ @@ -2135,22 +2370,26 @@ XR_ENUM_STR(XrResult); _(expressionCount) \ _(expressionWeightings) \ +/// Calls your macro with the name of each member of XrFacialTrackerCreateInfoHTC, in order. #define XR_LIST_STRUCT_XrFacialTrackerCreateInfoHTC(_) \ _(type) \ _(next) \ _(facialTrackingType) \ +/// Calls your macro with the name of each member of XrSystemColorSpacePropertiesFB, in order. #define XR_LIST_STRUCT_XrSystemColorSpacePropertiesFB(_) \ _(type) \ _(next) \ _(colorSpace) \ +/// Calls your macro with the name of each member of XrVector4sFB, in order. #define XR_LIST_STRUCT_XrVector4sFB(_) \ _(x) \ _(y) \ _(z) \ _(w) \ +/// Calls your macro with the name of each member of XrHandTrackingMeshFB, in order. #define XR_LIST_STRUCT_XrHandTrackingMeshFB(_) \ _(type) \ _(next) \ @@ -2170,6 +2409,7 @@ XR_ENUM_STR(XrResult); _(indexCountOutput) \ _(indices) \ +/// Calls your macro with the name of each member of XrHandTrackingScaleFB, in order. #define XR_LIST_STRUCT_XrHandTrackingScaleFB(_) \ _(type) \ _(next) \ @@ -2178,6 +2418,7 @@ XR_ENUM_STR(XrResult); _(overrideHandScale) \ _(overrideValueInput) \ +/// Calls your macro with the name of each member of XrHandTrackingAimStateFB, in order. #define XR_LIST_STRUCT_XrHandTrackingAimStateFB(_) \ _(type) \ _(next) \ @@ -2188,21 +2429,25 @@ XR_ENUM_STR(XrResult); _(pinchStrengthRing) \ _(pinchStrengthLittle) \ +/// Calls your macro with the name of each member of XrHandCapsuleFB, in order. #define XR_LIST_STRUCT_XrHandCapsuleFB(_) \ _(points) \ _(radius) \ _(joint) \ +/// Calls your macro with the name of each member of XrHandTrackingCapsulesStateFB, in order. #define XR_LIST_STRUCT_XrHandTrackingCapsulesStateFB(_) \ _(type) \ _(next) \ _(capsules) \ +/// Calls your macro with the name of each member of XrSystemSpatialEntityPropertiesFB, in order. #define XR_LIST_STRUCT_XrSystemSpatialEntityPropertiesFB(_) \ _(type) \ _(next) \ _(supportsSpatialEntity) \ +/// Calls your macro with the name of each member of XrSpatialAnchorCreateInfoFB, in order. #define XR_LIST_STRUCT_XrSpatialAnchorCreateInfoFB(_) \ _(type) \ _(next) \ @@ -2210,6 +2455,7 @@ XR_ENUM_STR(XrResult); _(poseInSpace) \ _(time) \ +/// Calls your macro with the name of each member of XrSpaceComponentStatusSetInfoFB, in order. #define XR_LIST_STRUCT_XrSpaceComponentStatusSetInfoFB(_) \ _(type) \ _(next) \ @@ -2217,15 +2463,18 @@ XR_ENUM_STR(XrResult); _(enabled) \ _(timeout) \ +/// Calls your macro with the name of each member of XrSpaceComponentStatusFB, in order. #define XR_LIST_STRUCT_XrSpaceComponentStatusFB(_) \ _(type) \ _(next) \ _(enabled) \ _(changePending) \ +/// Calls your macro with the name of each member of XrUuidEXT, in order. #define XR_LIST_STRUCT_XrUuidEXT(_) \ _(data) \ +/// Calls your macro with the name of each member of XrEventDataSpatialAnchorCreateCompleteFB, in order. #define XR_LIST_STRUCT_XrEventDataSpatialAnchorCreateCompleteFB(_) \ _(type) \ _(next) \ @@ -2234,6 +2483,7 @@ XR_ENUM_STR(XrResult); _(space) \ _(uuid) \ +/// Calls your macro with the name of each member of XrEventDataSpaceSetStatusCompleteFB, in order. #define XR_LIST_STRUCT_XrEventDataSpaceSetStatusCompleteFB(_) \ _(type) \ _(next) \ @@ -2244,21 +2494,25 @@ XR_ENUM_STR(XrResult); _(componentType) \ _(enabled) \ +/// Calls your macro with the name of each member of XrFoveationProfileCreateInfoFB, in order. #define XR_LIST_STRUCT_XrFoveationProfileCreateInfoFB(_) \ _(type) \ _(next) \ +/// Calls your macro with the name of each member of XrSwapchainCreateInfoFoveationFB, in order. #define XR_LIST_STRUCT_XrSwapchainCreateInfoFoveationFB(_) \ _(type) \ _(next) \ _(flags) \ +/// Calls your macro with the name of each member of XrSwapchainStateFoveationFB, in order. #define XR_LIST_STRUCT_XrSwapchainStateFoveationFB(_) \ _(type) \ _(next) \ _(flags) \ _(profile) \ +/// Calls your macro with the name of each member of XrFoveationLevelProfileCreateInfoFB, in order. #define XR_LIST_STRUCT_XrFoveationLevelProfileCreateInfoFB(_) \ _(type) \ _(next) \ @@ -2266,27 +2520,32 @@ XR_ENUM_STR(XrResult); _(verticalOffset) \ _(dynamic) \ +/// Calls your macro with the name of each member of XrSystemKeyboardTrackingPropertiesFB, in order. #define XR_LIST_STRUCT_XrSystemKeyboardTrackingPropertiesFB(_) \ _(type) \ _(next) \ _(supportsKeyboardTracking) \ +/// Calls your macro with the name of each member of XrKeyboardTrackingDescriptionFB, in order. #define XR_LIST_STRUCT_XrKeyboardTrackingDescriptionFB(_) \ _(trackedKeyboardId) \ _(size) \ _(flags) \ _(name) \ +/// Calls your macro with the name of each member of XrKeyboardSpaceCreateInfoFB, in order. #define XR_LIST_STRUCT_XrKeyboardSpaceCreateInfoFB(_) \ _(type) \ _(next) \ _(trackedKeyboardId) \ +/// Calls your macro with the name of each member of XrKeyboardTrackingQueryFB, in order. #define XR_LIST_STRUCT_XrKeyboardTrackingQueryFB(_) \ _(type) \ _(next) \ _(flags) \ +/// Calls your macro with the name of each member of XrTriangleMeshCreateInfoFB, in order. #define XR_LIST_STRUCT_XrTriangleMeshCreateInfoFB(_) \ _(type) \ _(next) \ @@ -2297,21 +2556,25 @@ XR_ENUM_STR(XrResult); _(triangleCount) \ _(indexBuffer) \ +/// Calls your macro with the name of each member of XrSystemPassthroughPropertiesFB, in order. #define XR_LIST_STRUCT_XrSystemPassthroughPropertiesFB(_) \ _(type) \ _(next) \ _(supportsPassthrough) \ +/// Calls your macro with the name of each member of XrSystemPassthroughProperties2FB, in order. #define XR_LIST_STRUCT_XrSystemPassthroughProperties2FB(_) \ _(type) \ _(next) \ _(capabilities) \ +/// Calls your macro with the name of each member of XrPassthroughCreateInfoFB, in order. #define XR_LIST_STRUCT_XrPassthroughCreateInfoFB(_) \ _(type) \ _(next) \ _(flags) \ +/// Calls your macro with the name of each member of XrPassthroughLayerCreateInfoFB, in order. #define XR_LIST_STRUCT_XrPassthroughLayerCreateInfoFB(_) \ _(type) \ _(next) \ @@ -2319,6 +2582,7 @@ XR_ENUM_STR(XrResult); _(flags) \ _(purpose) \ +/// Calls your macro with the name of each member of XrCompositionLayerPassthroughFB, in order. #define XR_LIST_STRUCT_XrCompositionLayerPassthroughFB(_) \ _(type) \ _(next) \ @@ -2326,6 +2590,7 @@ XR_ENUM_STR(XrResult); _(space) \ _(layerHandle) \ +/// Calls your macro with the name of each member of XrGeometryInstanceCreateInfoFB, in order. #define XR_LIST_STRUCT_XrGeometryInstanceCreateInfoFB(_) \ _(type) \ _(next) \ @@ -2335,6 +2600,7 @@ XR_ENUM_STR(XrResult); _(pose) \ _(scale) \ +/// Calls your macro with the name of each member of XrGeometryInstanceTransformFB, in order. #define XR_LIST_STRUCT_XrGeometryInstanceTransformFB(_) \ _(type) \ _(next) \ @@ -2343,22 +2609,26 @@ XR_ENUM_STR(XrResult); _(pose) \ _(scale) \ +/// Calls your macro with the name of each member of XrPassthroughStyleFB, in order. #define XR_LIST_STRUCT_XrPassthroughStyleFB(_) \ _(type) \ _(next) \ _(textureOpacityFactor) \ _(edgeColor) \ +/// Calls your macro with the name of each member of XrPassthroughColorMapMonoToRgbaFB, in order. #define XR_LIST_STRUCT_XrPassthroughColorMapMonoToRgbaFB(_) \ _(type) \ _(next) \ _(textureColorMap) \ +/// Calls your macro with the name of each member of XrPassthroughColorMapMonoToMonoFB, in order. #define XR_LIST_STRUCT_XrPassthroughColorMapMonoToMonoFB(_) \ _(type) \ _(next) \ _(textureColorMap) \ +/// Calls your macro with the name of each member of XrPassthroughBrightnessContrastSaturationFB, in order. #define XR_LIST_STRUCT_XrPassthroughBrightnessContrastSaturationFB(_) \ _(type) \ _(next) \ @@ -2366,16 +2636,19 @@ XR_ENUM_STR(XrResult); _(contrast) \ _(saturation) \ +/// Calls your macro with the name of each member of XrEventDataPassthroughStateChangedFB, in order. #define XR_LIST_STRUCT_XrEventDataPassthroughStateChangedFB(_) \ _(type) \ _(next) \ _(flags) \ +/// Calls your macro with the name of each member of XrRenderModelPathInfoFB, in order. #define XR_LIST_STRUCT_XrRenderModelPathInfoFB(_) \ _(type) \ _(next) \ _(path) \ +/// Calls your macro with the name of each member of XrRenderModelPropertiesFB, in order. #define XR_LIST_STRUCT_XrRenderModelPropertiesFB(_) \ _(type) \ _(next) \ @@ -2385,6 +2658,7 @@ XR_ENUM_STR(XrResult); _(modelVersion) \ _(flags) \ +/// Calls your macro with the name of each member of XrRenderModelBufferFB, in order. #define XR_LIST_STRUCT_XrRenderModelBufferFB(_) \ _(type) \ _(next) \ @@ -2392,47 +2666,56 @@ XR_ENUM_STR(XrResult); _(bufferCountOutput) \ _(buffer) \ +/// Calls your macro with the name of each member of XrRenderModelLoadInfoFB, in order. #define XR_LIST_STRUCT_XrRenderModelLoadInfoFB(_) \ _(type) \ _(next) \ _(modelKey) \ +/// Calls your macro with the name of each member of XrSystemRenderModelPropertiesFB, in order. #define XR_LIST_STRUCT_XrSystemRenderModelPropertiesFB(_) \ _(type) \ _(next) \ _(supportsRenderModelLoading) \ +/// Calls your macro with the name of each member of XrRenderModelCapabilitiesRequestFB, in order. #define XR_LIST_STRUCT_XrRenderModelCapabilitiesRequestFB(_) \ _(type) \ _(next) \ _(flags) \ +/// Calls your macro with the name of each member of XrViewLocateFoveatedRenderingVARJO, in order. #define XR_LIST_STRUCT_XrViewLocateFoveatedRenderingVARJO(_) \ _(type) \ _(next) \ _(foveatedRenderingActive) \ +/// Calls your macro with the name of each member of XrFoveatedViewConfigurationViewVARJO, in order. #define XR_LIST_STRUCT_XrFoveatedViewConfigurationViewVARJO(_) \ _(type) \ _(next) \ _(foveatedRenderingActive) \ +/// Calls your macro with the name of each member of XrSystemFoveatedRenderingPropertiesVARJO, in order. #define XR_LIST_STRUCT_XrSystemFoveatedRenderingPropertiesVARJO(_) \ _(type) \ _(next) \ _(supportsFoveatedRendering) \ +/// Calls your macro with the name of each member of XrCompositionLayerDepthTestVARJO, in order. #define XR_LIST_STRUCT_XrCompositionLayerDepthTestVARJO(_) \ _(type) \ _(next) \ _(depthTestRangeNearZ) \ _(depthTestRangeFarZ) \ +/// Calls your macro with the name of each member of XrSystemMarkerTrackingPropertiesVARJO, in order. #define XR_LIST_STRUCT_XrSystemMarkerTrackingPropertiesVARJO(_) \ _(type) \ _(next) \ _(supportsMarkerTracking) \ +/// Calls your macro with the name of each member of XrEventDataMarkerTrackingUpdateVARJO, in order. #define XR_LIST_STRUCT_XrEventDataMarkerTrackingUpdateVARJO(_) \ _(type) \ _(next) \ @@ -2441,35 +2724,42 @@ XR_ENUM_STR(XrResult); _(isPredicted) \ _(time) \ +/// Calls your macro with the name of each member of XrMarkerSpaceCreateInfoVARJO, in order. #define XR_LIST_STRUCT_XrMarkerSpaceCreateInfoVARJO(_) \ _(type) \ _(next) \ _(markerId) \ _(poseInMarkerSpace) \ +/// Calls your macro with the name of each member of XrSpatialAnchorPersistenceNameMSFT, in order. #define XR_LIST_STRUCT_XrSpatialAnchorPersistenceNameMSFT(_) \ _(name) \ +/// Calls your macro with the name of each member of XrSpatialAnchorPersistenceInfoMSFT, in order. #define XR_LIST_STRUCT_XrSpatialAnchorPersistenceInfoMSFT(_) \ _(type) \ _(next) \ _(spatialAnchorPersistenceName) \ _(spatialAnchor) \ +/// Calls your macro with the name of each member of XrSpatialAnchorFromPersistedAnchorCreateInfoMSFT, in order. #define XR_LIST_STRUCT_XrSpatialAnchorFromPersistedAnchorCreateInfoMSFT(_) \ _(type) \ _(next) \ _(spatialAnchorStore) \ _(spatialAnchorPersistenceName) \ +/// Calls your macro with the name of each member of XrSpaceQueryInfoBaseHeaderFB, in order. #define XR_LIST_STRUCT_XrSpaceQueryInfoBaseHeaderFB(_) \ _(type) \ _(next) \ +/// Calls your macro with the name of each member of XrSpaceFilterInfoBaseHeaderFB, in order. #define XR_LIST_STRUCT_XrSpaceFilterInfoBaseHeaderFB(_) \ _(type) \ _(next) \ +/// Calls your macro with the name of each member of XrSpaceQueryInfoFB, in order. #define XR_LIST_STRUCT_XrSpaceQueryInfoFB(_) \ _(type) \ _(next) \ @@ -2479,26 +2769,31 @@ XR_ENUM_STR(XrResult); _(filter) \ _(excludeFilter) \ +/// Calls your macro with the name of each member of XrSpaceStorageLocationFilterInfoFB, in order. #define XR_LIST_STRUCT_XrSpaceStorageLocationFilterInfoFB(_) \ _(type) \ _(next) \ _(location) \ +/// Calls your macro with the name of each member of XrSpaceUuidFilterInfoFB, in order. #define XR_LIST_STRUCT_XrSpaceUuidFilterInfoFB(_) \ _(type) \ _(next) \ _(uuidCount) \ _(uuids) \ +/// Calls your macro with the name of each member of XrSpaceComponentFilterInfoFB, in order. #define XR_LIST_STRUCT_XrSpaceComponentFilterInfoFB(_) \ _(type) \ _(next) \ _(componentType) \ +/// Calls your macro with the name of each member of XrSpaceQueryResultFB, in order. #define XR_LIST_STRUCT_XrSpaceQueryResultFB(_) \ _(space) \ _(uuid) \ +/// Calls your macro with the name of each member of XrSpaceQueryResultsFB, in order. #define XR_LIST_STRUCT_XrSpaceQueryResultsFB(_) \ _(type) \ _(next) \ @@ -2506,17 +2801,20 @@ XR_ENUM_STR(XrResult); _(resultCountOutput) \ _(results) \ +/// Calls your macro with the name of each member of XrEventDataSpaceQueryResultsAvailableFB, in order. #define XR_LIST_STRUCT_XrEventDataSpaceQueryResultsAvailableFB(_) \ _(type) \ _(next) \ _(requestId) \ +/// Calls your macro with the name of each member of XrEventDataSpaceQueryCompleteFB, in order. #define XR_LIST_STRUCT_XrEventDataSpaceQueryCompleteFB(_) \ _(type) \ _(next) \ _(requestId) \ _(result) \ +/// Calls your macro with the name of each member of XrSpaceSaveInfoFB, in order. #define XR_LIST_STRUCT_XrSpaceSaveInfoFB(_) \ _(type) \ _(next) \ @@ -2524,12 +2822,14 @@ XR_ENUM_STR(XrResult); _(location) \ _(persistenceMode) \ +/// Calls your macro with the name of each member of XrSpaceEraseInfoFB, in order. #define XR_LIST_STRUCT_XrSpaceEraseInfoFB(_) \ _(type) \ _(next) \ _(space) \ _(location) \ +/// Calls your macro with the name of each member of XrEventDataSpaceSaveCompleteFB, in order. #define XR_LIST_STRUCT_XrEventDataSpaceSaveCompleteFB(_) \ _(type) \ _(next) \ @@ -2539,6 +2839,7 @@ XR_ENUM_STR(XrResult); _(uuid) \ _(location) \ +/// Calls your macro with the name of each member of XrEventDataSpaceEraseCompleteFB, in order. #define XR_LIST_STRUCT_XrEventDataSpaceEraseCompleteFB(_) \ _(type) \ _(next) \ @@ -2548,6 +2849,7 @@ XR_ENUM_STR(XrResult); _(uuid) \ _(location) \ +/// Calls your macro with the name of each member of XrSwapchainImageFoveationVulkanFB, in order. #define XR_LIST_STRUCT_XrSwapchainImageFoveationVulkanFB(_) \ _(type) \ _(next) \ @@ -2555,12 +2857,14 @@ XR_ENUM_STR(XrResult); _(width) \ _(height) \ +/// Calls your macro with the name of each member of XrSwapchainStateAndroidSurfaceDimensionsFB, in order. #define XR_LIST_STRUCT_XrSwapchainStateAndroidSurfaceDimensionsFB(_) \ _(type) \ _(next) \ _(width) \ _(height) \ +/// Calls your macro with the name of each member of XrSwapchainStateSamplerOpenGLESFB, in order. #define XR_LIST_STRUCT_XrSwapchainStateSamplerOpenGLESFB(_) \ _(type) \ _(next) \ @@ -2575,6 +2879,7 @@ XR_ENUM_STR(XrResult); _(maxAnisotropy) \ _(borderColor) \ +/// Calls your macro with the name of each member of XrSwapchainStateSamplerVulkanFB, in order. #define XR_LIST_STRUCT_XrSwapchainStateSamplerVulkanFB(_) \ _(type) \ _(next) \ @@ -2590,6 +2895,7 @@ XR_ENUM_STR(XrResult); _(maxAnisotropy) \ _(borderColor) \ +/// Calls your macro with the name of each member of XrCompositionLayerSpaceWarpInfoFB, in order. #define XR_LIST_STRUCT_XrCompositionLayerSpaceWarpInfoFB(_) \ _(type) \ _(next) \ @@ -2602,26 +2908,31 @@ XR_ENUM_STR(XrResult); _(nearZ) \ _(farZ) \ +/// Calls your macro with the name of each member of XrSystemSpaceWarpPropertiesFB, in order. #define XR_LIST_STRUCT_XrSystemSpaceWarpPropertiesFB(_) \ _(type) \ _(next) \ _(recommendedMotionVectorImageRectWidth) \ _(recommendedMotionVectorImageRectHeight) \ +/// Calls your macro with the name of each member of XrExtent3DfFB, in order. #define XR_LIST_STRUCT_XrExtent3DfFB(_) \ _(width) \ _(height) \ _(depth) \ +/// Calls your macro with the name of each member of XrOffset3DfFB, in order. #define XR_LIST_STRUCT_XrOffset3DfFB(_) \ _(x) \ _(y) \ _(z) \ +/// Calls your macro with the name of each member of XrRect3DfFB, in order. #define XR_LIST_STRUCT_XrRect3DfFB(_) \ _(offset) \ _(extent) \ +/// Calls your macro with the name of each member of XrSemanticLabelsFB, in order. #define XR_LIST_STRUCT_XrSemanticLabelsFB(_) \ _(type) \ _(next) \ @@ -2629,6 +2940,7 @@ XR_ENUM_STR(XrResult); _(bufferCountOutput) \ _(buffer) \ +/// Calls your macro with the name of each member of XrRoomLayoutFB, in order. #define XR_LIST_STRUCT_XrRoomLayoutFB(_) \ _(type) \ _(next) \ @@ -2638,6 +2950,7 @@ XR_ENUM_STR(XrResult); _(wallUuidCountOutput) \ _(wallUuids) \ +/// Calls your macro with the name of each member of XrBoundary2DFB, in order. #define XR_LIST_STRUCT_XrBoundary2DFB(_) \ _(type) \ _(next) \ @@ -2645,11 +2958,13 @@ XR_ENUM_STR(XrResult); _(vertexCountOutput) \ _(vertices) \ +/// Calls your macro with the name of each member of XrDigitalLensControlALMALENCE, in order. #define XR_LIST_STRUCT_XrDigitalLensControlALMALENCE(_) \ _(type) \ _(next) \ _(flags) \ +/// Calls your macro with the name of each member of XrSpaceContainerFB, in order. #define XR_LIST_STRUCT_XrSpaceContainerFB(_) \ _(type) \ _(next) \ @@ -2657,28 +2972,33 @@ XR_ENUM_STR(XrResult); _(uuidCountOutput) \ _(uuids) \ +/// Calls your macro with the name of each member of XrPassthroughKeyboardHandsIntensityFB, in order. #define XR_LIST_STRUCT_XrPassthroughKeyboardHandsIntensityFB(_) \ _(type) \ _(next) \ _(leftHandIntensity) \ _(rightHandIntensity) \ +/// Calls your macro with the name of each member of XrCompositionLayerSettingsFB, in order. #define XR_LIST_STRUCT_XrCompositionLayerSettingsFB(_) \ _(type) \ _(next) \ _(layerFlags) \ +/// Calls your macro with the name of each member of XrVulkanSwapchainCreateInfoMETA, in order. #define XR_LIST_STRUCT_XrVulkanSwapchainCreateInfoMETA(_) \ _(type) \ _(next) \ _(additionalCreateFlags) \ _(additionalUsageFlags) \ +/// Calls your macro with the name of each member of XrPerformanceMetricsStateMETA, in order. #define XR_LIST_STRUCT_XrPerformanceMetricsStateMETA(_) \ _(type) \ _(next) \ _(enabled) \ +/// Calls your macro with the name of each member of XrPerformanceMetricsCounterMETA, in order. #define XR_LIST_STRUCT_XrPerformanceMetricsCounterMETA(_) \ _(type) \ _(next) \ @@ -2687,8 +3007,107 @@ XR_ENUM_STR(XrResult); _(uintValue) \ _(floatValue) \ +/// Calls your macro with the name of each member of XrSystemHeadsetIdPropertiesMETA, in order. +#define XR_LIST_STRUCT_XrSystemHeadsetIdPropertiesMETA(_) \ + _(type) \ + _(next) \ + _(id) \ + +/// Calls your macro with the name of each member of XrPassthroughCreateInfoHTC, in order. +#define XR_LIST_STRUCT_XrPassthroughCreateInfoHTC(_) \ + _(type) \ + _(next) \ + _(form) \ + +/// Calls your macro with the name of each member of XrPassthroughColorHTC, in order. +#define XR_LIST_STRUCT_XrPassthroughColorHTC(_) \ + _(type) \ + _(next) \ + _(alpha) \ + +/// Calls your macro with the name of each member of XrPassthroughMeshTransformInfoHTC, in order. +#define XR_LIST_STRUCT_XrPassthroughMeshTransformInfoHTC(_) \ + _(type) \ + _(next) \ + _(vertexCount) \ + _(vertices) \ + _(indexCount) \ + _(indices) \ + _(baseSpace) \ + _(time) \ + _(pose) \ + _(scale) \ + +/// Calls your macro with the name of each member of XrCompositionLayerPassthroughHTC, in order. +#define XR_LIST_STRUCT_XrCompositionLayerPassthroughHTC(_) \ + _(type) \ + _(next) \ + _(layerFlags) \ + _(space) \ + _(passthrough) \ + _(color) \ + +/// Calls your macro with the name of each member of XrFoveationApplyInfoHTC, in order. +#define XR_LIST_STRUCT_XrFoveationApplyInfoHTC(_) \ + _(type) \ + _(next) \ + _(mode) \ + _(subImageCount) \ + _(subImages) \ + +/// Calls your macro with the name of each member of XrFoveationConfigurationHTC, in order. +#define XR_LIST_STRUCT_XrFoveationConfigurationHTC(_) \ + _(level) \ + _(clearFovDegree) \ + _(focalCenterOffset) \ +/// Calls your macro with the name of each member of XrFoveationDynamicModeInfoHTC, in order. +#define XR_LIST_STRUCT_XrFoveationDynamicModeInfoHTC(_) \ + _(type) \ + _(next) \ + _(dynamicFlags) \ +/// Calls your macro with the name of each member of XrFoveationCustomModeInfoHTC, in order. +#define XR_LIST_STRUCT_XrFoveationCustomModeInfoHTC(_) \ + _(type) \ + _(next) \ + _(configCount) \ + _(configs) \ + +/// Calls your macro with the name of each member of XrActiveActionSetPriorityEXT, in order. +#define XR_LIST_STRUCT_XrActiveActionSetPriorityEXT(_) \ + _(actionSet) \ + _(priorityOverride) \ + +/// Calls your macro with the name of each member of XrActiveActionSetPrioritiesEXT, in order. +#define XR_LIST_STRUCT_XrActiveActionSetPrioritiesEXT(_) \ + _(type) \ + _(next) \ + _(actionSetPriorityCount) \ + _(actionSetPriorities) \ + + + +/// Calls your macro with the structure type name and the XrStructureType constant for +/// each known/available structure type, excluding those unavailable due to preprocessor definitions. +#define XR_LIST_STRUCTURE_TYPES(_) \ + XR_LIST_STRUCTURE_TYPES_CORE(_) \ + XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D11(_) \ + XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D12(_) \ + XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL(_) \ + XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WAYLAND(_) \ + XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WIN32(_) \ + XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XCB(_) \ + XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XLIB(_) \ + XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES(_) \ + XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES_XR_USE_PLATFORM_ANDROID(_) \ + XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_VULKAN(_) \ + XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_ANDROID(_) \ + XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_EGL(_) \ + XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_WIN32(_) \ + + +/// Implementation detail of XR_LIST_STRUCTURE_TYPES() - structure types available without any preprocessor definitions #define XR_LIST_STRUCTURE_TYPES_CORE(_) \ _(XrApiLayerProperties, XR_TYPE_API_LAYER_PROPERTIES) \ _(XrExtensionProperties, XR_TYPE_EXTENSION_PROPERTIES) \ @@ -2889,99 +3308,117 @@ XR_ENUM_STR(XrResult); _(XrCompositionLayerSettingsFB, XR_TYPE_COMPOSITION_LAYER_SETTINGS_FB) \ _(XrPerformanceMetricsStateMETA, XR_TYPE_PERFORMANCE_METRICS_STATE_META) \ _(XrPerformanceMetricsCounterMETA, XR_TYPE_PERFORMANCE_METRICS_COUNTER_META) \ - - + _(XrSystemHeadsetIdPropertiesMETA, XR_TYPE_SYSTEM_HEADSET_ID_PROPERTIES_META) \ + _(XrPassthroughCreateInfoHTC, XR_TYPE_PASSTHROUGH_CREATE_INFO_HTC) \ + _(XrPassthroughColorHTC, XR_TYPE_PASSTHROUGH_COLOR_HTC) \ + _(XrPassthroughMeshTransformInfoHTC, XR_TYPE_PASSTHROUGH_MESH_TRANSFORM_INFO_HTC) \ + _(XrCompositionLayerPassthroughHTC, XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_HTC) \ + _(XrFoveationApplyInfoHTC, XR_TYPE_FOVEATION_APPLY_INFO_HTC) \ + _(XrFoveationDynamicModeInfoHTC, XR_TYPE_FOVEATION_DYNAMIC_MODE_INFO_HTC) \ + _(XrFoveationCustomModeInfoHTC, XR_TYPE_FOVEATION_CUSTOM_MODE_INFO_HTC) \ + _(XrActiveActionSetPrioritiesEXT, XR_TYPE_ACTIVE_ACTION_SET_PRIORITIES_EXT) \ #if defined(XR_USE_GRAPHICS_API_D3D11) +/// Implementation detail of XR_LIST_STRUCTURE_TYPES() +/// Structure types available only when XR_USE_GRAPHICS_API_D3D11 is defined #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D11(_) \ _(XrGraphicsBindingD3D11KHR, XR_TYPE_GRAPHICS_BINDING_D3D11_KHR) \ _(XrSwapchainImageD3D11KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR) \ _(XrGraphicsRequirementsD3D11KHR, XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR) \ - #else #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D11(_) #endif #if defined(XR_USE_GRAPHICS_API_D3D12) +/// Implementation detail of XR_LIST_STRUCTURE_TYPES() +/// Structure types available only when XR_USE_GRAPHICS_API_D3D12 is defined #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D12(_) \ _(XrGraphicsBindingD3D12KHR, XR_TYPE_GRAPHICS_BINDING_D3D12_KHR) \ _(XrSwapchainImageD3D12KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR) \ _(XrGraphicsRequirementsD3D12KHR, XR_TYPE_GRAPHICS_REQUIREMENTS_D3D12_KHR) \ - #else #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D12(_) #endif #if defined(XR_USE_GRAPHICS_API_OPENGL) +/// Implementation detail of XR_LIST_STRUCTURE_TYPES() +/// Structure types available only when XR_USE_GRAPHICS_API_OPENGL is defined #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL(_) \ _(XrSwapchainImageOpenGLKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR) \ _(XrGraphicsRequirementsOpenGLKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR) \ - #else #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL(_) #endif #if defined(XR_USE_GRAPHICS_API_OPENGL) && defined(XR_USE_PLATFORM_WAYLAND) +/// Implementation detail of XR_LIST_STRUCTURE_TYPES() +/// Structure types available only when XR_USE_GRAPHICS_API_OPENGL and XR_USE_PLATFORM_WAYLAND are defined #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WAYLAND(_) \ _(XrGraphicsBindingOpenGLWaylandKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR) \ - #else #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WAYLAND(_) #endif #if defined(XR_USE_GRAPHICS_API_OPENGL) && defined(XR_USE_PLATFORM_WIN32) +/// Implementation detail of XR_LIST_STRUCTURE_TYPES() +/// Structure types available only when XR_USE_GRAPHICS_API_OPENGL and XR_USE_PLATFORM_WIN32 are defined #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WIN32(_) \ _(XrGraphicsBindingOpenGLWin32KHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR) \ - #else #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WIN32(_) #endif #if defined(XR_USE_GRAPHICS_API_OPENGL) && defined(XR_USE_PLATFORM_XCB) +/// Implementation detail of XR_LIST_STRUCTURE_TYPES() +/// Structure types available only when XR_USE_GRAPHICS_API_OPENGL and XR_USE_PLATFORM_XCB are defined #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XCB(_) \ _(XrGraphicsBindingOpenGLXcbKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_XCB_KHR) \ - #else #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XCB(_) #endif #if defined(XR_USE_GRAPHICS_API_OPENGL) && defined(XR_USE_PLATFORM_XLIB) +/// Implementation detail of XR_LIST_STRUCTURE_TYPES() +/// Structure types available only when XR_USE_GRAPHICS_API_OPENGL and XR_USE_PLATFORM_XLIB are defined #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XLIB(_) \ _(XrGraphicsBindingOpenGLXlibKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR) \ - #else #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XLIB(_) #endif #if defined(XR_USE_GRAPHICS_API_OPENGL_ES) +/// Implementation detail of XR_LIST_STRUCTURE_TYPES() +/// Structure types available only when XR_USE_GRAPHICS_API_OPENGL_ES is defined #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES(_) \ _(XrSwapchainImageOpenGLESKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR) \ _(XrGraphicsRequirementsOpenGLESKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR) \ _(XrSwapchainStateSamplerOpenGLESFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_OPENGL_ES_FB) \ - #else #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES(_) #endif #if defined(XR_USE_GRAPHICS_API_OPENGL_ES) && defined(XR_USE_PLATFORM_ANDROID) +/// Implementation detail of XR_LIST_STRUCTURE_TYPES() +/// Structure types available only when XR_USE_GRAPHICS_API_OPENGL_ES and XR_USE_PLATFORM_ANDROID are defined #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES_XR_USE_PLATFORM_ANDROID(_) \ _(XrGraphicsBindingOpenGLESAndroidKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR) \ - #else #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES_XR_USE_PLATFORM_ANDROID(_) #endif #if defined(XR_USE_GRAPHICS_API_VULKAN) +/// Implementation detail of XR_LIST_STRUCTURE_TYPES() +/// Structure types available only when XR_USE_GRAPHICS_API_VULKAN is defined #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_VULKAN(_) \ _(XrVulkanSwapchainFormatListCreateInfoKHR, XR_TYPE_VULKAN_SWAPCHAIN_FORMAT_LIST_CREATE_INFO_KHR) \ _(XrGraphicsBindingVulkanKHR, XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR) \ @@ -2994,58 +3431,47 @@ XR_ENUM_STR(XrResult); _(XrSwapchainStateSamplerVulkanFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_VULKAN_FB) \ _(XrVulkanSwapchainCreateInfoMETA, XR_TYPE_VULKAN_SWAPCHAIN_CREATE_INFO_META) \ - #else #define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_VULKAN(_) #endif #if defined(XR_USE_PLATFORM_ANDROID) +/// Implementation detail of XR_LIST_STRUCTURE_TYPES() +/// Structure types available only when XR_USE_PLATFORM_ANDROID is defined #define XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_ANDROID(_) \ _(XrInstanceCreateInfoAndroidKHR, XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR) \ _(XrLoaderInitInfoAndroidKHR, XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR) \ _(XrAndroidSurfaceSwapchainCreateInfoFB, XR_TYPE_ANDROID_SURFACE_SWAPCHAIN_CREATE_INFO_FB) \ _(XrSwapchainStateAndroidSurfaceDimensionsFB, XR_TYPE_SWAPCHAIN_STATE_ANDROID_SURFACE_DIMENSIONS_FB) \ - #else #define XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_ANDROID(_) #endif #if defined(XR_USE_PLATFORM_EGL) +/// Implementation detail of XR_LIST_STRUCTURE_TYPES() +/// Structure types available only when XR_USE_PLATFORM_EGL is defined #define XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_EGL(_) \ _(XrGraphicsBindingEGLMNDX, XR_TYPE_GRAPHICS_BINDING_EGL_MNDX) \ - #else #define XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_EGL(_) #endif #if defined(XR_USE_PLATFORM_WIN32) +/// Implementation detail of XR_LIST_STRUCTURE_TYPES() +/// Structure types available only when XR_USE_PLATFORM_WIN32 is defined #define XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_WIN32(_) \ _(XrHolographicWindowAttachmentMSFT, XR_TYPE_HOLOGRAPHIC_WINDOW_ATTACHMENT_MSFT) \ - #else #define XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_WIN32(_) #endif -#define XR_LIST_STRUCTURE_TYPES(_) \ - XR_LIST_STRUCTURE_TYPES_CORE(_) \ - XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D11(_) \ - XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D12(_) \ - XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL(_) \ - XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WAYLAND(_) \ - XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WIN32(_) \ - XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XCB(_) \ - XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XLIB(_) \ - XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES(_) \ - XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES_XR_USE_PLATFORM_ANDROID(_) \ - XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_VULKAN(_) \ - XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_ANDROID(_) \ - XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_EGL(_) \ - XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_WIN32(_) \ +/// Calls your macro with the name and extension number of all known +/// extensions in this version of the spec. #define XR_LIST_EXTENSIONS(_) \ _(XR_KHR_android_thread_settings, 4) \ _(XR_KHR_android_surface_swapchain, 5) \ @@ -3151,7 +3577,11 @@ XR_ENUM_STR(XrResult); _(XR_FB_composition_layer_settings, 205) \ _(XR_META_vulkan_swapchain_create_info, 228) \ _(XR_META_performance_metrics, 233) \ + _(XR_META_headset_id, 246) \ _(XR_EXT_uuid, 300) \ + _(XR_HTC_passthrough, 318) \ + _(XR_HTC_foveation, 319) \ + _(XR_EXT_active_action_set_priority, 374) \ #endif diff --git a/thirdparty/openxr/include/openxr/openxr_reflection_parent_structs.h b/thirdparty/openxr/include/openxr/openxr_reflection_parent_structs.h new file mode 100644 index 0000000000..19b0e1c3f6 --- /dev/null +++ b/thirdparty/openxr/include/openxr/openxr_reflection_parent_structs.h @@ -0,0 +1,261 @@ +#ifndef OPENXR_REFLECTION_PARENT_STRUCTS_H_ +#define OPENXR_REFLECTION_PARENT_STRUCTS_H_ 1 + +/* +** Copyright (c) 2017-2022, The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 OR MIT +*/ + +/* +** This header is generated from the Khronos OpenXR XML API Registry. +** +*/ + +#include "openxr.h" + +/* +This file contains expansion macros (X Macros) for OpenXR structures that have a parent type. +*/ + + +/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrCompositionLayerBaseHeader +#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrCompositionLayerBaseHeader(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrCompositionLayerBaseHeader_CORE(_avail, _unavail) \ + + +// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrCompositionLayerBaseHeader() +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrCompositionLayerBaseHeader_CORE(_avail, _unavail) \ + _avail(XrCompositionLayerProjection, XR_TYPE_COMPOSITION_LAYER_PROJECTION) \ + _avail(XrCompositionLayerQuad, XR_TYPE_COMPOSITION_LAYER_QUAD) \ + _avail(XrCompositionLayerCubeKHR, XR_TYPE_COMPOSITION_LAYER_CUBE_KHR) \ + _avail(XrCompositionLayerCylinderKHR, XR_TYPE_COMPOSITION_LAYER_CYLINDER_KHR) \ + _avail(XrCompositionLayerEquirectKHR, XR_TYPE_COMPOSITION_LAYER_EQUIRECT_KHR) \ + _avail(XrCompositionLayerEquirect2KHR, XR_TYPE_COMPOSITION_LAYER_EQUIRECT2_KHR) \ + _avail(XrCompositionLayerPassthroughHTC, XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_HTC) \ + + + + + +/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrEventDataBaseHeader +#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrEventDataBaseHeader(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrEventDataBaseHeader_CORE(_avail, _unavail) \ + + +// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrEventDataBaseHeader() +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrEventDataBaseHeader_CORE(_avail, _unavail) \ + _avail(XrEventDataEventsLost, XR_TYPE_EVENT_DATA_EVENTS_LOST) \ + _avail(XrEventDataInstanceLossPending, XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING) \ + _avail(XrEventDataSessionStateChanged, XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED) \ + _avail(XrEventDataReferenceSpaceChangePending, XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING) \ + _avail(XrEventDataInteractionProfileChanged, XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED) \ + _avail(XrEventDataVisibilityMaskChangedKHR, XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR) \ + _avail(XrEventDataPerfSettingsEXT, XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT) \ + _avail(XrEventDataMainSessionVisibilityChangedEXTX, XR_TYPE_EVENT_DATA_MAIN_SESSION_VISIBILITY_CHANGED_EXTX) \ + _avail(XrEventDataDisplayRefreshRateChangedFB, XR_TYPE_EVENT_DATA_DISPLAY_REFRESH_RATE_CHANGED_FB) \ + _avail(XrEventDataViveTrackerConnectedHTCX, XR_TYPE_EVENT_DATA_VIVE_TRACKER_CONNECTED_HTCX) \ + _avail(XrEventDataSpatialAnchorCreateCompleteFB, XR_TYPE_EVENT_DATA_SPATIAL_ANCHOR_CREATE_COMPLETE_FB) \ + _avail(XrEventDataSpaceSetStatusCompleteFB, XR_TYPE_EVENT_DATA_SPACE_SET_STATUS_COMPLETE_FB) \ + _avail(XrEventDataMarkerTrackingUpdateVARJO, XR_TYPE_EVENT_DATA_MARKER_TRACKING_UPDATE_VARJO) \ + _avail(XrEventDataSpaceQueryResultsAvailableFB, XR_TYPE_EVENT_DATA_SPACE_QUERY_RESULTS_AVAILABLE_FB) \ + _avail(XrEventDataSpaceQueryCompleteFB, XR_TYPE_EVENT_DATA_SPACE_QUERY_COMPLETE_FB) \ + _avail(XrEventDataSpaceSaveCompleteFB, XR_TYPE_EVENT_DATA_SPACE_SAVE_COMPLETE_FB) \ + _avail(XrEventDataSpaceEraseCompleteFB, XR_TYPE_EVENT_DATA_SPACE_ERASE_COMPLETE_FB) \ + + + + + +/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrHapticBaseHeader +#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrHapticBaseHeader(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrHapticBaseHeader_CORE(_avail, _unavail) \ + + +// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrHapticBaseHeader() +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrHapticBaseHeader_CORE(_avail, _unavail) \ + _avail(XrHapticVibration, XR_TYPE_HAPTIC_VIBRATION) \ + + + + + +/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrSwapchainImageBaseHeader +#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_CORE(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_D3D11(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_D3D12(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_OPENGL(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_OPENGL_ES(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_VULKAN(_avail, _unavail) \ + + +// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader() +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_CORE(_avail, _unavail) \ + + +#if defined(XR_USE_GRAPHICS_API_D3D11) +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_D3D11(_avail, _unavail) \ + _avail(XrSwapchainImageD3D11KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR) \ + +#else +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_D3D11(_avail, _unavail) \ + _unavail(XrSwapchainImageD3D11KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_D3D12) +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_D3D12(_avail, _unavail) \ + _avail(XrSwapchainImageD3D12KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR) \ + +#else +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_D3D12(_avail, _unavail) \ + _unavail(XrSwapchainImageD3D12KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_OPENGL) +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_OPENGL(_avail, _unavail) \ + _avail(XrSwapchainImageOpenGLKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR) \ + +#else +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_OPENGL(_avail, _unavail) \ + _unavail(XrSwapchainImageOpenGLKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_OPENGL_ES) +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_OPENGL_ES(_avail, _unavail) \ + _avail(XrSwapchainImageOpenGLESKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR) \ + +#else +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_OPENGL_ES(_avail, _unavail) \ + _unavail(XrSwapchainImageOpenGLESKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_VULKAN) +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_VULKAN(_avail, _unavail) \ + _avail(XrSwapchainImageVulkanKHR, XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR) \ + +#else +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainImageBaseHeader_XR_USE_GRAPHICS_API_VULKAN(_avail, _unavail) \ + _unavail(XrSwapchainImageVulkanKHR, XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR) \ + +#endif + + + + +/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrLoaderInitInfoBaseHeaderKHR +#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrLoaderInitInfoBaseHeaderKHR(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrLoaderInitInfoBaseHeaderKHR_CORE(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrLoaderInitInfoBaseHeaderKHR_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \ + + +// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrLoaderInitInfoBaseHeaderKHR() +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrLoaderInitInfoBaseHeaderKHR_CORE(_avail, _unavail) \ + + +#if defined(XR_USE_PLATFORM_ANDROID) +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrLoaderInitInfoBaseHeaderKHR_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \ + _avail(XrLoaderInitInfoAndroidKHR, XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR) \ + +#else +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrLoaderInitInfoBaseHeaderKHR_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \ + _unavail(XrLoaderInitInfoAndroidKHR, XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR) \ + +#endif + + + + +/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrBindingModificationBaseHeaderKHR +#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrBindingModificationBaseHeaderKHR(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrBindingModificationBaseHeaderKHR_CORE(_avail, _unavail) \ + + +// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrBindingModificationBaseHeaderKHR() +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrBindingModificationBaseHeaderKHR_CORE(_avail, _unavail) \ + _avail(XrInteractionProfileDpadBindingEXT, XR_TYPE_INTERACTION_PROFILE_DPAD_BINDING_EXT) \ + _avail(XrInteractionProfileAnalogThresholdVALVE, XR_TYPE_INTERACTION_PROFILE_ANALOG_THRESHOLD_VALVE) \ + + + + + +/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrSwapchainStateBaseHeaderFB +#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_CORE(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_XR_USE_GRAPHICS_API_OPENGL_ES(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_XR_USE_GRAPHICS_API_VULKAN(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \ + + +// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB() +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_CORE(_avail, _unavail) \ + _avail(XrSwapchainStateFoveationFB, XR_TYPE_SWAPCHAIN_STATE_FOVEATION_FB) \ + + +#if defined(XR_USE_GRAPHICS_API_OPENGL_ES) +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_XR_USE_GRAPHICS_API_OPENGL_ES(_avail, _unavail) \ + _avail(XrSwapchainStateSamplerOpenGLESFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_OPENGL_ES_FB) \ + +#else +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_XR_USE_GRAPHICS_API_OPENGL_ES(_avail, _unavail) \ + _unavail(XrSwapchainStateSamplerOpenGLESFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_OPENGL_ES_FB) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_VULKAN) +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_XR_USE_GRAPHICS_API_VULKAN(_avail, _unavail) \ + _avail(XrSwapchainStateSamplerVulkanFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_VULKAN_FB) \ + +#else +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_XR_USE_GRAPHICS_API_VULKAN(_avail, _unavail) \ + _unavail(XrSwapchainStateSamplerVulkanFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_VULKAN_FB) \ + +#endif + +#if defined(XR_USE_PLATFORM_ANDROID) +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \ + _avail(XrSwapchainStateAndroidSurfaceDimensionsFB, XR_TYPE_SWAPCHAIN_STATE_ANDROID_SURFACE_DIMENSIONS_FB) \ + +#else +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSwapchainStateBaseHeaderFB_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \ + _unavail(XrSwapchainStateAndroidSurfaceDimensionsFB, XR_TYPE_SWAPCHAIN_STATE_ANDROID_SURFACE_DIMENSIONS_FB) \ + +#endif + + + + +/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrSpaceQueryInfoBaseHeaderFB +#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceQueryInfoBaseHeaderFB(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceQueryInfoBaseHeaderFB_CORE(_avail, _unavail) \ + + +// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceQueryInfoBaseHeaderFB() +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceQueryInfoBaseHeaderFB_CORE(_avail, _unavail) \ + _avail(XrSpaceQueryInfoFB, XR_TYPE_SPACE_QUERY_INFO_FB) \ + + + + + +/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrSpaceFilterInfoBaseHeaderFB +#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceFilterInfoBaseHeaderFB(_avail, _unavail) \ + _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceFilterInfoBaseHeaderFB_CORE(_avail, _unavail) \ + + +// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceFilterInfoBaseHeaderFB() +#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceFilterInfoBaseHeaderFB_CORE(_avail, _unavail) \ + _avail(XrSpaceUuidFilterInfoFB, XR_TYPE_SPACE_UUID_FILTER_INFO_FB) \ + _avail(XrSpaceComponentFilterInfoFB, XR_TYPE_SPACE_COMPONENT_FILTER_INFO_FB) \ + + + + + +#endif + diff --git a/thirdparty/openxr/include/openxr/openxr_reflection_structs.h b/thirdparty/openxr/include/openxr/openxr_reflection_structs.h new file mode 100644 index 0000000000..300bbbad6d --- /dev/null +++ b/thirdparty/openxr/include/openxr/openxr_reflection_structs.h @@ -0,0 +1,427 @@ +#ifndef OPENXR_REFLECTION_STRUCTS_H_ +#define OPENXR_REFLECTION_STRUCTS_H_ 1 + +/* +** Copyright (c) 2017-2022, The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 OR MIT +*/ + +/* +** This header is generated from the Khronos OpenXR XML API Registry. +** +*/ + +#include "openxr.h" + +/* +This file contains expansion macros (X Macros) for OpenXR structures. +*/ + + + +/// Calls one of your macros with the structure type name and the XrStructureType constant for +/// each known structure type. The first macro (_avail) is called for those that are available, +/// while the second macro (_unavail) is called for those unavailable due to preprocessor definitions. +#define XR_LIST_ALL_STRUCTURE_TYPES(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_CORE(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D11(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D12(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WAYLAND(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WIN32(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XCB(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XLIB(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_VULKAN(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_EGL(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_WIN32(_avail, _unavail) \ + + +// Implementation detail of XR_LIST_ALL_STRUCTURE_TYPES() +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_CORE(_avail, _unavail) \ + _avail(XrApiLayerProperties, XR_TYPE_API_LAYER_PROPERTIES) \ + _avail(XrExtensionProperties, XR_TYPE_EXTENSION_PROPERTIES) \ + _avail(XrInstanceCreateInfo, XR_TYPE_INSTANCE_CREATE_INFO) \ + _avail(XrInstanceProperties, XR_TYPE_INSTANCE_PROPERTIES) \ + _avail(XrEventDataBuffer, XR_TYPE_EVENT_DATA_BUFFER) \ + _avail(XrSystemGetInfo, XR_TYPE_SYSTEM_GET_INFO) \ + _avail(XrSystemProperties, XR_TYPE_SYSTEM_PROPERTIES) \ + _avail(XrSessionCreateInfo, XR_TYPE_SESSION_CREATE_INFO) \ + _avail(XrSpaceVelocity, XR_TYPE_SPACE_VELOCITY) \ + _avail(XrReferenceSpaceCreateInfo, XR_TYPE_REFERENCE_SPACE_CREATE_INFO) \ + _avail(XrActionSpaceCreateInfo, XR_TYPE_ACTION_SPACE_CREATE_INFO) \ + _avail(XrSpaceLocation, XR_TYPE_SPACE_LOCATION) \ + _avail(XrViewConfigurationProperties, XR_TYPE_VIEW_CONFIGURATION_PROPERTIES) \ + _avail(XrViewConfigurationView, XR_TYPE_VIEW_CONFIGURATION_VIEW) \ + _avail(XrSwapchainCreateInfo, XR_TYPE_SWAPCHAIN_CREATE_INFO) \ + _avail(XrSwapchainImageAcquireInfo, XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO) \ + _avail(XrSwapchainImageWaitInfo, XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO) \ + _avail(XrSwapchainImageReleaseInfo, XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO) \ + _avail(XrSessionBeginInfo, XR_TYPE_SESSION_BEGIN_INFO) \ + _avail(XrFrameWaitInfo, XR_TYPE_FRAME_WAIT_INFO) \ + _avail(XrFrameState, XR_TYPE_FRAME_STATE) \ + _avail(XrFrameBeginInfo, XR_TYPE_FRAME_BEGIN_INFO) \ + _avail(XrFrameEndInfo, XR_TYPE_FRAME_END_INFO) \ + _avail(XrViewLocateInfo, XR_TYPE_VIEW_LOCATE_INFO) \ + _avail(XrViewState, XR_TYPE_VIEW_STATE) \ + _avail(XrView, XR_TYPE_VIEW) \ + _avail(XrActionSetCreateInfo, XR_TYPE_ACTION_SET_CREATE_INFO) \ + _avail(XrActionCreateInfo, XR_TYPE_ACTION_CREATE_INFO) \ + _avail(XrInteractionProfileSuggestedBinding, XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING) \ + _avail(XrSessionActionSetsAttachInfo, XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO) \ + _avail(XrInteractionProfileState, XR_TYPE_INTERACTION_PROFILE_STATE) \ + _avail(XrActionStateGetInfo, XR_TYPE_ACTION_STATE_GET_INFO) \ + _avail(XrActionStateBoolean, XR_TYPE_ACTION_STATE_BOOLEAN) \ + _avail(XrActionStateFloat, XR_TYPE_ACTION_STATE_FLOAT) \ + _avail(XrActionStateVector2f, XR_TYPE_ACTION_STATE_VECTOR2F) \ + _avail(XrActionStatePose, XR_TYPE_ACTION_STATE_POSE) \ + _avail(XrActionsSyncInfo, XR_TYPE_ACTIONS_SYNC_INFO) \ + _avail(XrBoundSourcesForActionEnumerateInfo, XR_TYPE_BOUND_SOURCES_FOR_ACTION_ENUMERATE_INFO) \ + _avail(XrInputSourceLocalizedNameGetInfo, XR_TYPE_INPUT_SOURCE_LOCALIZED_NAME_GET_INFO) \ + _avail(XrHapticActionInfo, XR_TYPE_HAPTIC_ACTION_INFO) \ + _avail(XrCompositionLayerProjectionView, XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW) \ + _avail(XrCompositionLayerProjection, XR_TYPE_COMPOSITION_LAYER_PROJECTION) \ + _avail(XrCompositionLayerQuad, XR_TYPE_COMPOSITION_LAYER_QUAD) \ + _avail(XrEventDataEventsLost, XR_TYPE_EVENT_DATA_EVENTS_LOST) \ + _avail(XrEventDataInstanceLossPending, XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING) \ + _avail(XrEventDataSessionStateChanged, XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED) \ + _avail(XrEventDataReferenceSpaceChangePending, XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING) \ + _avail(XrEventDataInteractionProfileChanged, XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED) \ + _avail(XrHapticVibration, XR_TYPE_HAPTIC_VIBRATION) \ + _avail(XrCompositionLayerCubeKHR, XR_TYPE_COMPOSITION_LAYER_CUBE_KHR) \ + _avail(XrCompositionLayerDepthInfoKHR, XR_TYPE_COMPOSITION_LAYER_DEPTH_INFO_KHR) \ + _avail(XrCompositionLayerCylinderKHR, XR_TYPE_COMPOSITION_LAYER_CYLINDER_KHR) \ + _avail(XrCompositionLayerEquirectKHR, XR_TYPE_COMPOSITION_LAYER_EQUIRECT_KHR) \ + _avail(XrVisibilityMaskKHR, XR_TYPE_VISIBILITY_MASK_KHR) \ + _avail(XrEventDataVisibilityMaskChangedKHR, XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR) \ + _avail(XrCompositionLayerColorScaleBiasKHR, XR_TYPE_COMPOSITION_LAYER_COLOR_SCALE_BIAS_KHR) \ + _avail(XrCompositionLayerEquirect2KHR, XR_TYPE_COMPOSITION_LAYER_EQUIRECT2_KHR) \ + _avail(XrBindingModificationsKHR, XR_TYPE_BINDING_MODIFICATIONS_KHR) \ + _avail(XrEventDataPerfSettingsEXT, XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT) \ + _avail(XrDebugUtilsObjectNameInfoEXT, XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT) \ + _avail(XrDebugUtilsLabelEXT, XR_TYPE_DEBUG_UTILS_LABEL_EXT) \ + _avail(XrDebugUtilsMessengerCallbackDataEXT, XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT) \ + _avail(XrDebugUtilsMessengerCreateInfoEXT, XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) \ + _avail(XrSystemEyeGazeInteractionPropertiesEXT, XR_TYPE_SYSTEM_EYE_GAZE_INTERACTION_PROPERTIES_EXT) \ + _avail(XrEyeGazeSampleTimeEXT, XR_TYPE_EYE_GAZE_SAMPLE_TIME_EXT) \ + _avail(XrSessionCreateInfoOverlayEXTX, XR_TYPE_SESSION_CREATE_INFO_OVERLAY_EXTX) \ + _avail(XrEventDataMainSessionVisibilityChangedEXTX, XR_TYPE_EVENT_DATA_MAIN_SESSION_VISIBILITY_CHANGED_EXTX) \ + _avail(XrSpatialAnchorCreateInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_MSFT) \ + _avail(XrSpatialAnchorSpaceCreateInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_SPACE_CREATE_INFO_MSFT) \ + _avail(XrCompositionLayerImageLayoutFB, XR_TYPE_COMPOSITION_LAYER_IMAGE_LAYOUT_FB) \ + _avail(XrCompositionLayerAlphaBlendFB, XR_TYPE_COMPOSITION_LAYER_ALPHA_BLEND_FB) \ + _avail(XrViewConfigurationDepthRangeEXT, XR_TYPE_VIEW_CONFIGURATION_DEPTH_RANGE_EXT) \ + _avail(XrSpatialGraphNodeSpaceCreateInfoMSFT, XR_TYPE_SPATIAL_GRAPH_NODE_SPACE_CREATE_INFO_MSFT) \ + _avail(XrSpatialGraphStaticNodeBindingCreateInfoMSFT, XR_TYPE_SPATIAL_GRAPH_STATIC_NODE_BINDING_CREATE_INFO_MSFT) \ + _avail(XrSpatialGraphNodeBindingPropertiesGetInfoMSFT, XR_TYPE_SPATIAL_GRAPH_NODE_BINDING_PROPERTIES_GET_INFO_MSFT) \ + _avail(XrSpatialGraphNodeBindingPropertiesMSFT, XR_TYPE_SPATIAL_GRAPH_NODE_BINDING_PROPERTIES_MSFT) \ + _avail(XrSystemHandTrackingPropertiesEXT, XR_TYPE_SYSTEM_HAND_TRACKING_PROPERTIES_EXT) \ + _avail(XrHandTrackerCreateInfoEXT, XR_TYPE_HAND_TRACKER_CREATE_INFO_EXT) \ + _avail(XrHandJointsLocateInfoEXT, XR_TYPE_HAND_JOINTS_LOCATE_INFO_EXT) \ + _avail(XrHandJointLocationsEXT, XR_TYPE_HAND_JOINT_LOCATIONS_EXT) \ + _avail(XrHandJointVelocitiesEXT, XR_TYPE_HAND_JOINT_VELOCITIES_EXT) \ + _avail(XrSystemHandTrackingMeshPropertiesMSFT, XR_TYPE_SYSTEM_HAND_TRACKING_MESH_PROPERTIES_MSFT) \ + _avail(XrHandMeshSpaceCreateInfoMSFT, XR_TYPE_HAND_MESH_SPACE_CREATE_INFO_MSFT) \ + _avail(XrHandMeshUpdateInfoMSFT, XR_TYPE_HAND_MESH_UPDATE_INFO_MSFT) \ + _avail(XrHandMeshMSFT, XR_TYPE_HAND_MESH_MSFT) \ + _avail(XrHandPoseTypeInfoMSFT, XR_TYPE_HAND_POSE_TYPE_INFO_MSFT) \ + _avail(XrSecondaryViewConfigurationSessionBeginInfoMSFT, XR_TYPE_SECONDARY_VIEW_CONFIGURATION_SESSION_BEGIN_INFO_MSFT) \ + _avail(XrSecondaryViewConfigurationStateMSFT, XR_TYPE_SECONDARY_VIEW_CONFIGURATION_STATE_MSFT) \ + _avail(XrSecondaryViewConfigurationFrameStateMSFT, XR_TYPE_SECONDARY_VIEW_CONFIGURATION_FRAME_STATE_MSFT) \ + _avail(XrSecondaryViewConfigurationLayerInfoMSFT, XR_TYPE_SECONDARY_VIEW_CONFIGURATION_LAYER_INFO_MSFT) \ + _avail(XrSecondaryViewConfigurationFrameEndInfoMSFT, XR_TYPE_SECONDARY_VIEW_CONFIGURATION_FRAME_END_INFO_MSFT) \ + _avail(XrSecondaryViewConfigurationSwapchainCreateInfoMSFT, XR_TYPE_SECONDARY_VIEW_CONFIGURATION_SWAPCHAIN_CREATE_INFO_MSFT) \ + _avail(XrControllerModelKeyStateMSFT, XR_TYPE_CONTROLLER_MODEL_KEY_STATE_MSFT) \ + _avail(XrControllerModelNodePropertiesMSFT, XR_TYPE_CONTROLLER_MODEL_NODE_PROPERTIES_MSFT) \ + _avail(XrControllerModelPropertiesMSFT, XR_TYPE_CONTROLLER_MODEL_PROPERTIES_MSFT) \ + _avail(XrControllerModelNodeStateMSFT, XR_TYPE_CONTROLLER_MODEL_NODE_STATE_MSFT) \ + _avail(XrControllerModelStateMSFT, XR_TYPE_CONTROLLER_MODEL_STATE_MSFT) \ + _avail(XrViewConfigurationViewFovEPIC, XR_TYPE_VIEW_CONFIGURATION_VIEW_FOV_EPIC) \ + _avail(XrCompositionLayerReprojectionInfoMSFT, XR_TYPE_COMPOSITION_LAYER_REPROJECTION_INFO_MSFT) \ + _avail(XrCompositionLayerReprojectionPlaneOverrideMSFT, XR_TYPE_COMPOSITION_LAYER_REPROJECTION_PLANE_OVERRIDE_MSFT) \ + _avail(XrCompositionLayerSecureContentFB, XR_TYPE_COMPOSITION_LAYER_SECURE_CONTENT_FB) \ + _avail(XrInteractionProfileDpadBindingEXT, XR_TYPE_INTERACTION_PROFILE_DPAD_BINDING_EXT) \ + _avail(XrInteractionProfileAnalogThresholdVALVE, XR_TYPE_INTERACTION_PROFILE_ANALOG_THRESHOLD_VALVE) \ + _avail(XrHandJointsMotionRangeInfoEXT, XR_TYPE_HAND_JOINTS_MOTION_RANGE_INFO_EXT) \ + _avail(XrSceneObserverCreateInfoMSFT, XR_TYPE_SCENE_OBSERVER_CREATE_INFO_MSFT) \ + _avail(XrSceneCreateInfoMSFT, XR_TYPE_SCENE_CREATE_INFO_MSFT) \ + _avail(XrNewSceneComputeInfoMSFT, XR_TYPE_NEW_SCENE_COMPUTE_INFO_MSFT) \ + _avail(XrVisualMeshComputeLodInfoMSFT, XR_TYPE_VISUAL_MESH_COMPUTE_LOD_INFO_MSFT) \ + _avail(XrSceneComponentsMSFT, XR_TYPE_SCENE_COMPONENTS_MSFT) \ + _avail(XrSceneComponentsGetInfoMSFT, XR_TYPE_SCENE_COMPONENTS_GET_INFO_MSFT) \ + _avail(XrSceneComponentLocationsMSFT, XR_TYPE_SCENE_COMPONENT_LOCATIONS_MSFT) \ + _avail(XrSceneComponentsLocateInfoMSFT, XR_TYPE_SCENE_COMPONENTS_LOCATE_INFO_MSFT) \ + _avail(XrSceneObjectsMSFT, XR_TYPE_SCENE_OBJECTS_MSFT) \ + _avail(XrSceneComponentParentFilterInfoMSFT, XR_TYPE_SCENE_COMPONENT_PARENT_FILTER_INFO_MSFT) \ + _avail(XrSceneObjectTypesFilterInfoMSFT, XR_TYPE_SCENE_OBJECT_TYPES_FILTER_INFO_MSFT) \ + _avail(XrScenePlanesMSFT, XR_TYPE_SCENE_PLANES_MSFT) \ + _avail(XrScenePlaneAlignmentFilterInfoMSFT, XR_TYPE_SCENE_PLANE_ALIGNMENT_FILTER_INFO_MSFT) \ + _avail(XrSceneMeshesMSFT, XR_TYPE_SCENE_MESHES_MSFT) \ + _avail(XrSceneMeshBuffersGetInfoMSFT, XR_TYPE_SCENE_MESH_BUFFERS_GET_INFO_MSFT) \ + _avail(XrSceneMeshBuffersMSFT, XR_TYPE_SCENE_MESH_BUFFERS_MSFT) \ + _avail(XrSceneMeshVertexBufferMSFT, XR_TYPE_SCENE_MESH_VERTEX_BUFFER_MSFT) \ + _avail(XrSceneMeshIndicesUint32MSFT, XR_TYPE_SCENE_MESH_INDICES_UINT32_MSFT) \ + _avail(XrSceneMeshIndicesUint16MSFT, XR_TYPE_SCENE_MESH_INDICES_UINT16_MSFT) \ + _avail(XrSerializedSceneFragmentDataGetInfoMSFT, XR_TYPE_SERIALIZED_SCENE_FRAGMENT_DATA_GET_INFO_MSFT) \ + _avail(XrSceneDeserializeInfoMSFT, XR_TYPE_SCENE_DESERIALIZE_INFO_MSFT) \ + _avail(XrEventDataDisplayRefreshRateChangedFB, XR_TYPE_EVENT_DATA_DISPLAY_REFRESH_RATE_CHANGED_FB) \ + _avail(XrViveTrackerPathsHTCX, XR_TYPE_VIVE_TRACKER_PATHS_HTCX) \ + _avail(XrEventDataViveTrackerConnectedHTCX, XR_TYPE_EVENT_DATA_VIVE_TRACKER_CONNECTED_HTCX) \ + _avail(XrSystemFacialTrackingPropertiesHTC, XR_TYPE_SYSTEM_FACIAL_TRACKING_PROPERTIES_HTC) \ + _avail(XrFacialExpressionsHTC, XR_TYPE_FACIAL_EXPRESSIONS_HTC) \ + _avail(XrFacialTrackerCreateInfoHTC, XR_TYPE_FACIAL_TRACKER_CREATE_INFO_HTC) \ + _avail(XrSystemColorSpacePropertiesFB, XR_TYPE_SYSTEM_COLOR_SPACE_PROPERTIES_FB) \ + _avail(XrHandTrackingMeshFB, XR_TYPE_HAND_TRACKING_MESH_FB) \ + _avail(XrHandTrackingScaleFB, XR_TYPE_HAND_TRACKING_SCALE_FB) \ + _avail(XrHandTrackingAimStateFB, XR_TYPE_HAND_TRACKING_AIM_STATE_FB) \ + _avail(XrHandTrackingCapsulesStateFB, XR_TYPE_HAND_TRACKING_CAPSULES_STATE_FB) \ + _avail(XrSystemSpatialEntityPropertiesFB, XR_TYPE_SYSTEM_SPATIAL_ENTITY_PROPERTIES_FB) \ + _avail(XrSpatialAnchorCreateInfoFB, XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_FB) \ + _avail(XrSpaceComponentStatusSetInfoFB, XR_TYPE_SPACE_COMPONENT_STATUS_SET_INFO_FB) \ + _avail(XrSpaceComponentStatusFB, XR_TYPE_SPACE_COMPONENT_STATUS_FB) \ + _avail(XrEventDataSpatialAnchorCreateCompleteFB, XR_TYPE_EVENT_DATA_SPATIAL_ANCHOR_CREATE_COMPLETE_FB) \ + _avail(XrEventDataSpaceSetStatusCompleteFB, XR_TYPE_EVENT_DATA_SPACE_SET_STATUS_COMPLETE_FB) \ + _avail(XrFoveationProfileCreateInfoFB, XR_TYPE_FOVEATION_PROFILE_CREATE_INFO_FB) \ + _avail(XrSwapchainCreateInfoFoveationFB, XR_TYPE_SWAPCHAIN_CREATE_INFO_FOVEATION_FB) \ + _avail(XrSwapchainStateFoveationFB, XR_TYPE_SWAPCHAIN_STATE_FOVEATION_FB) \ + _avail(XrFoveationLevelProfileCreateInfoFB, XR_TYPE_FOVEATION_LEVEL_PROFILE_CREATE_INFO_FB) \ + _avail(XrSystemKeyboardTrackingPropertiesFB, XR_TYPE_SYSTEM_KEYBOARD_TRACKING_PROPERTIES_FB) \ + _avail(XrKeyboardSpaceCreateInfoFB, XR_TYPE_KEYBOARD_SPACE_CREATE_INFO_FB) \ + _avail(XrKeyboardTrackingQueryFB, XR_TYPE_KEYBOARD_TRACKING_QUERY_FB) \ + _avail(XrTriangleMeshCreateInfoFB, XR_TYPE_TRIANGLE_MESH_CREATE_INFO_FB) \ + _avail(XrSystemPassthroughPropertiesFB, XR_TYPE_SYSTEM_PASSTHROUGH_PROPERTIES_FB) \ + _avail(XrSystemPassthroughProperties2FB, XR_TYPE_SYSTEM_PASSTHROUGH_PROPERTIES2_FB) \ + _avail(XrPassthroughCreateInfoFB, XR_TYPE_PASSTHROUGH_CREATE_INFO_FB) \ + _avail(XrPassthroughLayerCreateInfoFB, XR_TYPE_PASSTHROUGH_LAYER_CREATE_INFO_FB) \ + _avail(XrCompositionLayerPassthroughFB, XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_FB) \ + _avail(XrGeometryInstanceCreateInfoFB, XR_TYPE_GEOMETRY_INSTANCE_CREATE_INFO_FB) \ + _avail(XrGeometryInstanceTransformFB, XR_TYPE_GEOMETRY_INSTANCE_TRANSFORM_FB) \ + _avail(XrPassthroughStyleFB, XR_TYPE_PASSTHROUGH_STYLE_FB) \ + _avail(XrPassthroughColorMapMonoToRgbaFB, XR_TYPE_PASSTHROUGH_COLOR_MAP_MONO_TO_RGBA_FB) \ + _avail(XrPassthroughColorMapMonoToMonoFB, XR_TYPE_PASSTHROUGH_COLOR_MAP_MONO_TO_MONO_FB) \ + _avail(XrPassthroughBrightnessContrastSaturationFB, XR_TYPE_PASSTHROUGH_BRIGHTNESS_CONTRAST_SATURATION_FB) \ + _avail(XrEventDataPassthroughStateChangedFB, XR_TYPE_EVENT_DATA_PASSTHROUGH_STATE_CHANGED_FB) \ + _avail(XrRenderModelPathInfoFB, XR_TYPE_RENDER_MODEL_PATH_INFO_FB) \ + _avail(XrRenderModelPropertiesFB, XR_TYPE_RENDER_MODEL_PROPERTIES_FB) \ + _avail(XrRenderModelBufferFB, XR_TYPE_RENDER_MODEL_BUFFER_FB) \ + _avail(XrRenderModelLoadInfoFB, XR_TYPE_RENDER_MODEL_LOAD_INFO_FB) \ + _avail(XrSystemRenderModelPropertiesFB, XR_TYPE_SYSTEM_RENDER_MODEL_PROPERTIES_FB) \ + _avail(XrRenderModelCapabilitiesRequestFB, XR_TYPE_RENDER_MODEL_CAPABILITIES_REQUEST_FB) \ + _avail(XrViewLocateFoveatedRenderingVARJO, XR_TYPE_VIEW_LOCATE_FOVEATED_RENDERING_VARJO) \ + _avail(XrFoveatedViewConfigurationViewVARJO, XR_TYPE_FOVEATED_VIEW_CONFIGURATION_VIEW_VARJO) \ + _avail(XrSystemFoveatedRenderingPropertiesVARJO, XR_TYPE_SYSTEM_FOVEATED_RENDERING_PROPERTIES_VARJO) \ + _avail(XrCompositionLayerDepthTestVARJO, XR_TYPE_COMPOSITION_LAYER_DEPTH_TEST_VARJO) \ + _avail(XrSystemMarkerTrackingPropertiesVARJO, XR_TYPE_SYSTEM_MARKER_TRACKING_PROPERTIES_VARJO) \ + _avail(XrEventDataMarkerTrackingUpdateVARJO, XR_TYPE_EVENT_DATA_MARKER_TRACKING_UPDATE_VARJO) \ + _avail(XrMarkerSpaceCreateInfoVARJO, XR_TYPE_MARKER_SPACE_CREATE_INFO_VARJO) \ + _avail(XrSpatialAnchorPersistenceInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_PERSISTENCE_INFO_MSFT) \ + _avail(XrSpatialAnchorFromPersistedAnchorCreateInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_FROM_PERSISTED_ANCHOR_CREATE_INFO_MSFT) \ + _avail(XrSpaceQueryInfoFB, XR_TYPE_SPACE_QUERY_INFO_FB) \ + _avail(XrSpaceStorageLocationFilterInfoFB, XR_TYPE_SPACE_STORAGE_LOCATION_FILTER_INFO_FB) \ + _avail(XrSpaceUuidFilterInfoFB, XR_TYPE_SPACE_UUID_FILTER_INFO_FB) \ + _avail(XrSpaceComponentFilterInfoFB, XR_TYPE_SPACE_COMPONENT_FILTER_INFO_FB) \ + _avail(XrSpaceQueryResultsFB, XR_TYPE_SPACE_QUERY_RESULTS_FB) \ + _avail(XrEventDataSpaceQueryResultsAvailableFB, XR_TYPE_EVENT_DATA_SPACE_QUERY_RESULTS_AVAILABLE_FB) \ + _avail(XrEventDataSpaceQueryCompleteFB, XR_TYPE_EVENT_DATA_SPACE_QUERY_COMPLETE_FB) \ + _avail(XrSpaceSaveInfoFB, XR_TYPE_SPACE_SAVE_INFO_FB) \ + _avail(XrSpaceEraseInfoFB, XR_TYPE_SPACE_ERASE_INFO_FB) \ + _avail(XrEventDataSpaceSaveCompleteFB, XR_TYPE_EVENT_DATA_SPACE_SAVE_COMPLETE_FB) \ + _avail(XrEventDataSpaceEraseCompleteFB, XR_TYPE_EVENT_DATA_SPACE_ERASE_COMPLETE_FB) \ + _avail(XrCompositionLayerSpaceWarpInfoFB, XR_TYPE_COMPOSITION_LAYER_SPACE_WARP_INFO_FB) \ + _avail(XrSystemSpaceWarpPropertiesFB, XR_TYPE_SYSTEM_SPACE_WARP_PROPERTIES_FB) \ + _avail(XrSemanticLabelsFB, XR_TYPE_SEMANTIC_LABELS_FB) \ + _avail(XrRoomLayoutFB, XR_TYPE_ROOM_LAYOUT_FB) \ + _avail(XrBoundary2DFB, XR_TYPE_BOUNDARY_2D_FB) \ + _avail(XrDigitalLensControlALMALENCE, XR_TYPE_DIGITAL_LENS_CONTROL_ALMALENCE) \ + _avail(XrSpaceContainerFB, XR_TYPE_SPACE_CONTAINER_FB) \ + _avail(XrPassthroughKeyboardHandsIntensityFB, XR_TYPE_PASSTHROUGH_KEYBOARD_HANDS_INTENSITY_FB) \ + _avail(XrCompositionLayerSettingsFB, XR_TYPE_COMPOSITION_LAYER_SETTINGS_FB) \ + _avail(XrPerformanceMetricsStateMETA, XR_TYPE_PERFORMANCE_METRICS_STATE_META) \ + _avail(XrPerformanceMetricsCounterMETA, XR_TYPE_PERFORMANCE_METRICS_COUNTER_META) \ + _avail(XrSystemHeadsetIdPropertiesMETA, XR_TYPE_SYSTEM_HEADSET_ID_PROPERTIES_META) \ + _avail(XrPassthroughCreateInfoHTC, XR_TYPE_PASSTHROUGH_CREATE_INFO_HTC) \ + _avail(XrPassthroughColorHTC, XR_TYPE_PASSTHROUGH_COLOR_HTC) \ + _avail(XrPassthroughMeshTransformInfoHTC, XR_TYPE_PASSTHROUGH_MESH_TRANSFORM_INFO_HTC) \ + _avail(XrCompositionLayerPassthroughHTC, XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_HTC) \ + _avail(XrFoveationApplyInfoHTC, XR_TYPE_FOVEATION_APPLY_INFO_HTC) \ + _avail(XrFoveationDynamicModeInfoHTC, XR_TYPE_FOVEATION_DYNAMIC_MODE_INFO_HTC) \ + _avail(XrFoveationCustomModeInfoHTC, XR_TYPE_FOVEATION_CUSTOM_MODE_INFO_HTC) \ + _avail(XrActiveActionSetPrioritiesEXT, XR_TYPE_ACTIVE_ACTION_SET_PRIORITIES_EXT) \ + + +#if defined(XR_USE_GRAPHICS_API_D3D11) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D11(_avail, _unavail) \ + _avail(XrGraphicsBindingD3D11KHR, XR_TYPE_GRAPHICS_BINDING_D3D11_KHR) \ + _avail(XrSwapchainImageD3D11KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR) \ + _avail(XrGraphicsRequirementsD3D11KHR, XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D11(_avail, _unavail) \ + _unavail(XrGraphicsBindingD3D11KHR, XR_TYPE_GRAPHICS_BINDING_D3D11_KHR) \ + _unavail(XrSwapchainImageD3D11KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR) \ + _unavail(XrGraphicsRequirementsD3D11KHR, XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_D3D12) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D12(_avail, _unavail) \ + _avail(XrGraphicsBindingD3D12KHR, XR_TYPE_GRAPHICS_BINDING_D3D12_KHR) \ + _avail(XrSwapchainImageD3D12KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR) \ + _avail(XrGraphicsRequirementsD3D12KHR, XR_TYPE_GRAPHICS_REQUIREMENTS_D3D12_KHR) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D12(_avail, _unavail) \ + _unavail(XrGraphicsBindingD3D12KHR, XR_TYPE_GRAPHICS_BINDING_D3D12_KHR) \ + _unavail(XrSwapchainImageD3D12KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR) \ + _unavail(XrGraphicsRequirementsD3D12KHR, XR_TYPE_GRAPHICS_REQUIREMENTS_D3D12_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_OPENGL) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL(_avail, _unavail) \ + _avail(XrSwapchainImageOpenGLKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR) \ + _avail(XrGraphicsRequirementsOpenGLKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL(_avail, _unavail) \ + _unavail(XrSwapchainImageOpenGLKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR) \ + _unavail(XrGraphicsRequirementsOpenGLKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_OPENGL) && defined(XR_USE_PLATFORM_WAYLAND) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WAYLAND(_avail, _unavail) \ + _avail(XrGraphicsBindingOpenGLWaylandKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WAYLAND(_avail, _unavail) \ + _unavail(XrGraphicsBindingOpenGLWaylandKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_OPENGL) && defined(XR_USE_PLATFORM_WIN32) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WIN32(_avail, _unavail) \ + _avail(XrGraphicsBindingOpenGLWin32KHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WIN32(_avail, _unavail) \ + _unavail(XrGraphicsBindingOpenGLWin32KHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_OPENGL) && defined(XR_USE_PLATFORM_XCB) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XCB(_avail, _unavail) \ + _avail(XrGraphicsBindingOpenGLXcbKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_XCB_KHR) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XCB(_avail, _unavail) \ + _unavail(XrGraphicsBindingOpenGLXcbKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_XCB_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_OPENGL) && defined(XR_USE_PLATFORM_XLIB) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XLIB(_avail, _unavail) \ + _avail(XrGraphicsBindingOpenGLXlibKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XLIB(_avail, _unavail) \ + _unavail(XrGraphicsBindingOpenGLXlibKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_OPENGL_ES) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES(_avail, _unavail) \ + _avail(XrSwapchainImageOpenGLESKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR) \ + _avail(XrGraphicsRequirementsOpenGLESKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR) \ + _avail(XrSwapchainStateSamplerOpenGLESFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_OPENGL_ES_FB) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES(_avail, _unavail) \ + _unavail(XrSwapchainImageOpenGLESKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR) \ + _unavail(XrGraphicsRequirementsOpenGLESKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR) \ + _unavail(XrSwapchainStateSamplerOpenGLESFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_OPENGL_ES_FB) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_OPENGL_ES) && defined(XR_USE_PLATFORM_ANDROID) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \ + _avail(XrGraphicsBindingOpenGLESAndroidKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \ + _unavail(XrGraphicsBindingOpenGLESAndroidKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR) \ + +#endif + +#if defined(XR_USE_GRAPHICS_API_VULKAN) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_VULKAN(_avail, _unavail) \ + _avail(XrVulkanSwapchainFormatListCreateInfoKHR, XR_TYPE_VULKAN_SWAPCHAIN_FORMAT_LIST_CREATE_INFO_KHR) \ + _avail(XrGraphicsBindingVulkanKHR, XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR) \ + _avail(XrSwapchainImageVulkanKHR, XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR) \ + _avail(XrGraphicsRequirementsVulkanKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR) \ + _avail(XrVulkanInstanceCreateInfoKHR, XR_TYPE_VULKAN_INSTANCE_CREATE_INFO_KHR) \ + _avail(XrVulkanDeviceCreateInfoKHR, XR_TYPE_VULKAN_DEVICE_CREATE_INFO_KHR) \ + _avail(XrVulkanGraphicsDeviceGetInfoKHR, XR_TYPE_VULKAN_GRAPHICS_DEVICE_GET_INFO_KHR) \ + _avail(XrSwapchainImageFoveationVulkanFB, XR_TYPE_SWAPCHAIN_IMAGE_FOVEATION_VULKAN_FB) \ + _avail(XrSwapchainStateSamplerVulkanFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_VULKAN_FB) \ + _avail(XrVulkanSwapchainCreateInfoMETA, XR_TYPE_VULKAN_SWAPCHAIN_CREATE_INFO_META) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_VULKAN(_avail, _unavail) \ + _unavail(XrVulkanSwapchainFormatListCreateInfoKHR, XR_TYPE_VULKAN_SWAPCHAIN_FORMAT_LIST_CREATE_INFO_KHR) \ + _unavail(XrGraphicsBindingVulkanKHR, XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR) \ + _unavail(XrSwapchainImageVulkanKHR, XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR) \ + _unavail(XrGraphicsRequirementsVulkanKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR) \ + _unavail(XrVulkanInstanceCreateInfoKHR, XR_TYPE_VULKAN_INSTANCE_CREATE_INFO_KHR) \ + _unavail(XrVulkanDeviceCreateInfoKHR, XR_TYPE_VULKAN_DEVICE_CREATE_INFO_KHR) \ + _unavail(XrVulkanGraphicsDeviceGetInfoKHR, XR_TYPE_VULKAN_GRAPHICS_DEVICE_GET_INFO_KHR) \ + _unavail(XrSwapchainImageFoveationVulkanFB, XR_TYPE_SWAPCHAIN_IMAGE_FOVEATION_VULKAN_FB) \ + _unavail(XrSwapchainStateSamplerVulkanFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_VULKAN_FB) \ + _unavail(XrVulkanSwapchainCreateInfoMETA, XR_TYPE_VULKAN_SWAPCHAIN_CREATE_INFO_META) \ + +#endif + +#if defined(XR_USE_PLATFORM_ANDROID) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \ + _avail(XrInstanceCreateInfoAndroidKHR, XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR) \ + _avail(XrLoaderInitInfoAndroidKHR, XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR) \ + _avail(XrAndroidSurfaceSwapchainCreateInfoFB, XR_TYPE_ANDROID_SURFACE_SWAPCHAIN_CREATE_INFO_FB) \ + _avail(XrSwapchainStateAndroidSurfaceDimensionsFB, XR_TYPE_SWAPCHAIN_STATE_ANDROID_SURFACE_DIMENSIONS_FB) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \ + _unavail(XrInstanceCreateInfoAndroidKHR, XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR) \ + _unavail(XrLoaderInitInfoAndroidKHR, XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR) \ + _unavail(XrAndroidSurfaceSwapchainCreateInfoFB, XR_TYPE_ANDROID_SURFACE_SWAPCHAIN_CREATE_INFO_FB) \ + _unavail(XrSwapchainStateAndroidSurfaceDimensionsFB, XR_TYPE_SWAPCHAIN_STATE_ANDROID_SURFACE_DIMENSIONS_FB) \ + +#endif + +#if defined(XR_USE_PLATFORM_EGL) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_EGL(_avail, _unavail) \ + _avail(XrGraphicsBindingEGLMNDX, XR_TYPE_GRAPHICS_BINDING_EGL_MNDX) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_EGL(_avail, _unavail) \ + _unavail(XrGraphicsBindingEGLMNDX, XR_TYPE_GRAPHICS_BINDING_EGL_MNDX) \ + +#endif + +#if defined(XR_USE_PLATFORM_WIN32) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_WIN32(_avail, _unavail) \ + _avail(XrHolographicWindowAttachmentMSFT, XR_TYPE_HOLOGRAPHIC_WINDOW_ATTACHMENT_MSFT) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_WIN32(_avail, _unavail) \ + _unavail(XrHolographicWindowAttachmentMSFT, XR_TYPE_HOLOGRAPHIC_WINDOW_ATTACHMENT_MSFT) \ + +#endif + + + + +#endif + diff --git a/thirdparty/openxr/src/loader/loader_core.cpp b/thirdparty/openxr/src/loader/loader_core.cpp index a8bbfb4de2..f2bc87d1fa 100644 --- a/thirdparty/openxr/src/loader/loader_core.cpp +++ b/thirdparty/openxr/src/loader/loader_core.cpp @@ -35,7 +35,7 @@ // Global loader lock to: // 1. Ensure ActiveLoaderInstance get and set operations are done atomically. // 2. Ensure RuntimeInterface isn't used to unload the runtime while the runtime is in use. -std::mutex &GetGlobalLoaderMutex() { +static std::mutex &GetGlobalLoaderMutex() { static std::mutex loader_mutex; return loader_mutex; } @@ -58,6 +58,8 @@ static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermDestroyDebugUtilsMessengerEXT( static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermSubmitDebugUtilsMessageEXT( XrInstance instance, XrDebugUtilsMessageSeverityFlagsEXT messageSeverity, XrDebugUtilsMessageTypeFlagsEXT messageTypes, const XrDebugUtilsMessengerCallbackDataEXT *callbackData); +static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrGetInstanceProcAddr(XrInstance instance, const char *name, + PFN_xrVoidFunction *function); // Utility template function meant to validate if a fixed size string contains // a null-terminator. diff --git a/thirdparty/openxr/src/loader/manifest_file.cpp b/thirdparty/openxr/src/loader/manifest_file.cpp index df99d51f8f..1b0ef07848 100644 --- a/thirdparty/openxr/src/loader/manifest_file.cpp +++ b/thirdparty/openxr/src/loader/manifest_file.cpp @@ -348,14 +348,20 @@ static void ReadRuntimeDataFilesInRegistry(const std::string &runtime_registry_l if (ERROR_SUCCESS != open_value) { LoaderLogger::LogWarningMessage("", "ReadRuntimeDataFilesInRegistry - failed to open registry key " + full_registry_location); - } else if (ERROR_SUCCESS != RegGetValueW(hkey, nullptr, default_runtime_value_name_w.c_str(), - RRF_RT_REG_SZ | REG_EXPAND_SZ | RRF_ZEROONFAILURE, NULL, - reinterpret_cast<LPBYTE>(&value_w), &value_size_w)) { + + return; + } + + if (ERROR_SUCCESS != RegGetValueW(hkey, nullptr, default_runtime_value_name_w.c_str(), + RRF_RT_REG_SZ | REG_EXPAND_SZ | RRF_ZEROONFAILURE, NULL, reinterpret_cast<LPBYTE>(&value_w), + &value_size_w)) { LoaderLogger::LogWarningMessage( "", "ReadRuntimeDataFilesInRegistry - failed to read registry value " + default_runtime_value_name); } else { AddFilesInPath(wide_to_utf8(value_w), false, manifest_files); } + + RegCloseKey(hkey); } // Look for layer data files in the provided paths, but first check the environment override to determine diff --git a/thirdparty/openxr/src/xr_generated_dispatch_table.c b/thirdparty/openxr/src/xr_generated_dispatch_table.c index 91fa0c3ca0..094f9fbbda 100644 --- a/thirdparty/openxr/src/xr_generated_dispatch_table.c +++ b/thirdparty/openxr/src/xr_generated_dispatch_table.c @@ -354,6 +354,13 @@ void GeneratedXrPopulateDispatchTable(struct XrGeneratedDispatchTable *table, (get_inst_proc_addr(instance, "xrGetAudioInputDeviceGuidOculus", (PFN_xrVoidFunction*)&table->GetAudioInputDeviceGuidOculus)); #endif // defined(XR_USE_PLATFORM_WIN32) + // ---- XR_FB_scene extension commands + (get_inst_proc_addr(instance, "xrGetSpaceBoundingBox2DFB", (PFN_xrVoidFunction*)&table->GetSpaceBoundingBox2DFB)); + (get_inst_proc_addr(instance, "xrGetSpaceBoundingBox3DFB", (PFN_xrVoidFunction*)&table->GetSpaceBoundingBox3DFB)); + (get_inst_proc_addr(instance, "xrGetSpaceSemanticLabelsFB", (PFN_xrVoidFunction*)&table->GetSpaceSemanticLabelsFB)); + (get_inst_proc_addr(instance, "xrGetSpaceBoundary2DFB", (PFN_xrVoidFunction*)&table->GetSpaceBoundary2DFB)); + (get_inst_proc_addr(instance, "xrGetSpaceRoomLayoutFB", (PFN_xrVoidFunction*)&table->GetSpaceRoomLayoutFB)); + // ---- XR_ALMALENCE_digital_lens_control extension commands (get_inst_proc_addr(instance, "xrSetDigitalLensControlALMALENCE", (PFN_xrVoidFunction*)&table->SetDigitalLensControlALMALENCE)); @@ -368,6 +375,13 @@ void GeneratedXrPopulateDispatchTable(struct XrGeneratedDispatchTable *table, (get_inst_proc_addr(instance, "xrSetPerformanceMetricsStateMETA", (PFN_xrVoidFunction*)&table->SetPerformanceMetricsStateMETA)); (get_inst_proc_addr(instance, "xrGetPerformanceMetricsStateMETA", (PFN_xrVoidFunction*)&table->GetPerformanceMetricsStateMETA)); (get_inst_proc_addr(instance, "xrQueryPerformanceMetricsCounterMETA", (PFN_xrVoidFunction*)&table->QueryPerformanceMetricsCounterMETA)); + + // ---- XR_HTC_passthrough extension commands + (get_inst_proc_addr(instance, "xrCreatePassthroughHTC", (PFN_xrVoidFunction*)&table->CreatePassthroughHTC)); + (get_inst_proc_addr(instance, "xrDestroyPassthroughHTC", (PFN_xrVoidFunction*)&table->DestroyPassthroughHTC)); + + // ---- XR_HTC_foveation extension commands + (get_inst_proc_addr(instance, "xrApplyFoveationHTC", (PFN_xrVoidFunction*)&table->ApplyFoveationHTC)); } diff --git a/thirdparty/openxr/src/xr_generated_dispatch_table.h b/thirdparty/openxr/src/xr_generated_dispatch_table.h index 51d48bef43..93d07a149e 100644 --- a/thirdparty/openxr/src/xr_generated_dispatch_table.h +++ b/thirdparty/openxr/src/xr_generated_dispatch_table.h @@ -357,6 +357,13 @@ struct XrGeneratedDispatchTable { PFN_xrGetAudioInputDeviceGuidOculus GetAudioInputDeviceGuidOculus; #endif // defined(XR_USE_PLATFORM_WIN32) + // ---- XR_FB_scene extension commands + PFN_xrGetSpaceBoundingBox2DFB GetSpaceBoundingBox2DFB; + PFN_xrGetSpaceBoundingBox3DFB GetSpaceBoundingBox3DFB; + PFN_xrGetSpaceSemanticLabelsFB GetSpaceSemanticLabelsFB; + PFN_xrGetSpaceBoundary2DFB GetSpaceBoundary2DFB; + PFN_xrGetSpaceRoomLayoutFB GetSpaceRoomLayoutFB; + // ---- XR_ALMALENCE_digital_lens_control extension commands PFN_xrSetDigitalLensControlALMALENCE SetDigitalLensControlALMALENCE; @@ -371,6 +378,13 @@ struct XrGeneratedDispatchTable { PFN_xrSetPerformanceMetricsStateMETA SetPerformanceMetricsStateMETA; PFN_xrGetPerformanceMetricsStateMETA GetPerformanceMetricsStateMETA; PFN_xrQueryPerformanceMetricsCounterMETA QueryPerformanceMetricsCounterMETA; + + // ---- XR_HTC_passthrough extension commands + PFN_xrCreatePassthroughHTC CreatePassthroughHTC; + PFN_xrDestroyPassthroughHTC DestroyPassthroughHTC; + + // ---- XR_HTC_foveation extension commands + PFN_xrApplyFoveationHTC ApplyFoveationHTC; }; diff --git a/thirdparty/recastnavigation/Recast/Include/Recast.h b/thirdparty/recastnavigation/Recast/Include/Recast.h index 4d557389b5..246376bbee 100644 --- a/thirdparty/recastnavigation/Recast/Include/Recast.h +++ b/thirdparty/recastnavigation/Recast/Include/Recast.h @@ -22,13 +22,16 @@ /// The value of PI used by Recast. static const float RC_PI = 3.14159265f; +/// Used to ignore unused function parameters and silence any compiler warnings. +template<class T> void rcIgnoreUnused(const T&) { } + /// Recast log categories. /// @see rcContext enum rcLogCategory { RC_LOG_PROGRESS = 1, ///< A progress log entry. RC_LOG_WARNING, ///< A warning log entry. - RC_LOG_ERROR, ///< An error log entry. + RC_LOG_ERROR ///< An error log entry. }; /// Recast performance timer categories. @@ -101,7 +104,6 @@ enum rcTimerLabel class rcContext { public: - /// Contructor. /// @param[in] state TRUE if the logging and performance timers should be enabled. [Default: true] inline rcContext(bool state = true) : m_logEnabled(state), m_timerEnabled(state) {} @@ -140,31 +142,30 @@ public: inline int getAccumulatedTime(const rcTimerLabel label) const { return m_timerEnabled ? doGetAccumulatedTime(label) : -1; } protected: - /// Clears all log entries. - virtual void doResetLog() {} + virtual void doResetLog(); /// Logs a message. /// @param[in] category The category of the message. /// @param[in] msg The formatted message. /// @param[in] len The length of the formatted message. - virtual void doLog(const rcLogCategory /*category*/, const char* /*msg*/, const int /*len*/) {} + virtual void doLog(const rcLogCategory category, const char* msg, const int len) { rcIgnoreUnused(category); rcIgnoreUnused(msg); rcIgnoreUnused(len); } /// Clears all timers. (Resets all to unused.) virtual void doResetTimers() {} /// Starts the specified performance timer. /// @param[in] label The category of timer. - virtual void doStartTimer(const rcTimerLabel /*label*/) {} + virtual void doStartTimer(const rcTimerLabel label) { rcIgnoreUnused(label); } /// Stops the specified performance timer. /// @param[in] label The category of the timer. - virtual void doStopTimer(const rcTimerLabel /*label*/) {} + virtual void doStopTimer(const rcTimerLabel label) { rcIgnoreUnused(label); } /// Returns the total accumulated time of the specified performance timer. /// @param[in] label The category of the timer. /// @return The accumulated time of the timer, or -1 if timers are disabled or the timer has never been started. - virtual int doGetAccumulatedTime(const rcTimerLabel /*label*/) const { return -1; } + virtual int doGetAccumulatedTime(const rcTimerLabel label) const { rcIgnoreUnused(label); return -1; } /// True if logging is enabled. bool m_logEnabled; @@ -564,7 +565,7 @@ static const int RC_AREA_BORDER = 0x20000; enum rcBuildContoursFlags { RC_CONTOUR_TESS_WALL_EDGES = 0x01, ///< Tessellate solid (impassable) edges during contour simplification. - RC_CONTOUR_TESS_AREA_EDGES = 0x02, ///< Tessellate edges between areas during contour simplification. + RC_CONTOUR_TESS_AREA_EDGES = 0x02 ///< Tessellate edges between areas during contour simplification. }; /// Applied to the region id field of contour vertices in order to extract the region id. @@ -595,11 +596,6 @@ static const int RC_NOT_CONNECTED = 0x3f; /// @name General helper functions /// @{ -/// Used to ignore a function parameter. VS complains about unused parameters -/// and this silences the warning. -/// @param [in] _ Unused parameter -template<class T> void rcIgnoreUnused(const T&) { } - /// Swaps the values of the two parameters. /// @param[in,out] a Value A /// @param[in,out] b Value B @@ -996,6 +992,7 @@ void rcMarkConvexPolyArea(rcContext* ctx, const float* verts, const int nverts, /// @ingroup recast /// @param[in] verts The vertices of the polygon [Form: (x, y, z) * @p nverts] /// @param[in] nverts The number of vertices in the polygon. +/// @param[in] offset How much to offset the polygon by. [Units: wu] /// @param[out] outVerts The offset vertices (should hold up to 2 * @p nverts) [Form: (x, y, z) * return value] /// @param[in] maxOutVerts The max number of vertices that can be stored to @p outVerts. /// @returns Number of vertices in the offset polygon or 0 if too few vertices in @p outVerts. diff --git a/thirdparty/recastnavigation/Recast/Include/RecastAlloc.h b/thirdparty/recastnavigation/Recast/Include/RecastAlloc.h index 071278d659..8b166d736d 100644 --- a/thirdparty/recastnavigation/Recast/Include/RecastAlloc.h +++ b/thirdparty/recastnavigation/Recast/Include/RecastAlloc.h @@ -112,7 +112,7 @@ class rcVectorBase { typedef rcSizeType size_type; typedef T value_type; - rcVectorBase() : m_size(0), m_cap(0), m_data(0) {}; + rcVectorBase() : m_size(0), m_cap(0), m_data(0) {} rcVectorBase(const rcVectorBase<T, H>& other) : m_size(0), m_cap(0), m_data(0) { assign(other.begin(), other.end()); } explicit rcVectorBase(rcSizeType count) : m_size(0), m_cap(0), m_data(0) { resize(count); } rcVectorBase(rcSizeType count, const T& value) : m_size(0), m_cap(0), m_data(0) { resize(count, value); } @@ -142,8 +142,8 @@ class rcVectorBase { const T& front() const { rcAssert(m_size); return m_data[0]; } T& front() { rcAssert(m_size); return m_data[0]; } - const T& back() const { rcAssert(m_size); return m_data[m_size - 1]; }; - T& back() { rcAssert(m_size); return m_data[m_size - 1]; }; + const T& back() const { rcAssert(m_size); return m_data[m_size - 1]; } + T& back() { rcAssert(m_size); return m_data[m_size - 1]; } const T* data() const { return m_data; } T* data() { return m_data; } diff --git a/thirdparty/recastnavigation/Recast/Source/Recast.cpp b/thirdparty/recastnavigation/Recast/Source/Recast.cpp index 1b71710cdc..4cf145c981 100644 --- a/thirdparty/recastnavigation/Recast/Source/Recast.cpp +++ b/thirdparty/recastnavigation/Recast/Source/Recast.cpp @@ -94,6 +94,11 @@ void rcContext::log(const rcLogCategory category, const char* format, ...) doLog(category, msg, len); } +void rcContext::doResetLog() +{ + // Defined out of line to fix the weak v-tables warning +} + rcHeightfield* rcAllocHeightfield() { return rcNew<rcHeightfield>(RC_ALLOC_PERM); diff --git a/thirdparty/recastnavigation/Recast/Source/RecastMesh.cpp b/thirdparty/recastnavigation/Recast/Source/RecastMesh.cpp index e99eaebb79..ea09ee1de0 100644 --- a/thirdparty/recastnavigation/Recast/Source/RecastMesh.cpp +++ b/thirdparty/recastnavigation/Recast/Source/RecastMesh.cpp @@ -566,7 +566,6 @@ static bool canRemoveVertex(rcContext* ctx, rcPolyMesh& mesh, const unsigned sho const int nvp = mesh.nvp; // Count number of polygons to remove. - int numRemovedVerts = 0; int numTouchedVerts = 0; int numRemainingEdges = 0; for (int i = 0; i < mesh.npolys; ++i) @@ -586,7 +585,6 @@ static bool canRemoveVertex(rcContext* ctx, rcPolyMesh& mesh, const unsigned sho } if (numRemoved) { - numRemovedVerts += numRemoved; numRemainingEdges += numVerts-(numRemoved+1); } } diff --git a/thirdparty/recastnavigation/Recast/Source/RecastMeshDetail.cpp b/thirdparty/recastnavigation/Recast/Source/RecastMeshDetail.cpp index 1999200c1a..40bfc9b4bc 100644 --- a/thirdparty/recastnavigation/Recast/Source/RecastMeshDetail.cpp +++ b/thirdparty/recastnavigation/Recast/Source/RecastMeshDetail.cpp @@ -284,7 +284,7 @@ static unsigned short getHeight(const float fx, const float fy, const float fz, enum EdgeValues { EV_UNDEF = -1, - EV_HULL = -2, + EV_HULL = -2 }; static int findEdge(const int* edges, int nedges, int s, int t) diff --git a/thirdparty/recastnavigation/Recast/Source/RecastRasterization.cpp b/thirdparty/recastnavigation/Recast/Source/RecastRasterization.cpp index a4cef74909..673550e79e 100644 --- a/thirdparty/recastnavigation/Recast/Source/RecastRasterization.cpp +++ b/thirdparty/recastnavigation/Recast/Source/RecastRasterization.cpp @@ -264,7 +264,8 @@ static bool rasterizeTri(const float* v0, const float* v1, const float* v2, // Calculate the footprint of the triangle on the grid's y-axis int y0 = (int)((tmin[2] - bmin[2])*ics); int y1 = (int)((tmax[2] - bmin[2])*ics); - y0 = rcClamp(y0, 0, h-1); + // use -1 rather than 0 to cut the polygon properly at the start of the tile + y0 = rcClamp(y0, -1, h-1); y1 = rcClamp(y1, 0, h-1); // Clip the triangle into all grid cells it touches. @@ -283,7 +284,7 @@ static bool rasterizeTri(const float* v0, const float* v1, const float* v2, dividePoly(in, nvIn, inrow, &nvrow, p1, &nvIn, cz+cs, 2); rcSwap(in, p1); if (nvrow < 3) continue; - + if (y < 0) continue; // find the horizontal bounds in the row float minX = inrow[0], maxX = inrow[0]; for (int i=1; i<nvrow; ++i) @@ -293,7 +294,10 @@ static bool rasterizeTri(const float* v0, const float* v1, const float* v2, } int x0 = (int)((minX - bmin[0])*ics); int x1 = (int)((maxX - bmin[0])*ics); - x0 = rcClamp(x0, 0, w-1); + if (x1 < 0 || x0 >= w) { + continue; + } + x0 = rcClamp(x0, -1, w-1); x1 = rcClamp(x1, 0, w-1); int nv, nv2 = nvrow; @@ -305,7 +309,7 @@ static bool rasterizeTri(const float* v0, const float* v1, const float* v2, dividePoly(inrow, nv2, p1, &nv, p2, &nv2, cx+cs, 0); rcSwap(inrow, p2); if (nv < 3) continue; - + if (x < 0) continue; // Calculate min and max of the span. float smin = p1[1], smax = p1[1]; for (int i = 1; i < nv; ++i) diff --git a/thirdparty/thorvg/inc/config.h b/thirdparty/thorvg/inc/config.h index 68935c583b..eda302aec0 100644 --- a/thirdparty/thorvg/inc/config.h +++ b/thirdparty/thorvg/inc/config.h @@ -13,5 +13,5 @@ #define THORVG_JPG_LOADER_SUPPORT 1 -#define THORVG_VERSION_STRING "0.8.2" +#define THORVG_VERSION_STRING "0.8.3" #endif diff --git a/thirdparty/thorvg/inc/thorvg.h b/thirdparty/thorvg/inc/thorvg.h index b08356d9d5..7e8988a65e 100644 --- a/thirdparty/thorvg/inc/thorvg.h +++ b/thirdparty/thorvg/inc/thorvg.h @@ -18,7 +18,7 @@ #include <string> #ifdef TVG_BUILD - #if defined(_MSC_VER) && !defined(__clang__) + #if defined(_WIN32) && !defined(__clang__) #define TVG_EXPORT __declspec(dllexport) #define TVG_DEPRECATED __declspec(deprecated) #else @@ -74,7 +74,7 @@ class Accessor; /** * @brief Enumeration specifying the result from the APIs. */ -enum class TVG_EXPORT Result +enum class Result { Success = 0, ///< The value returned in case of a correct request execution. InvalidArguments, ///< The value returned in the event of a problem with the arguments given to the API - e.g. empty paths or null pointers. @@ -91,7 +91,7 @@ enum class TVG_EXPORT Result * Not to be confused with the path commands from the svg path element (like M, L, Q, H and many others). * TVG interprets all of them and translates to the ones from the PathCommand values. */ -enum class TVG_EXPORT PathCommand +enum class PathCommand { Close = 0, ///< Ends the current sub-path and connects it with its initial point. This command doesn't expect any points. MoveTo, ///< Sets a new initial point of the sub-path and a new current point. This command expects 1 point: the starting position. @@ -102,7 +102,7 @@ enum class TVG_EXPORT PathCommand /** * @brief Enumeration determining the ending type of a stroke in the open sub-paths. */ -enum class TVG_EXPORT StrokeCap +enum class StrokeCap { Square = 0, ///< The stroke is extended in both end-points of a sub-path by a rectangle, with the width equal to the stroke width and the length equal to the half of the stroke width. For zero length sub-paths the square is rendered with the size of the stroke width. Round, ///< The stroke is extended in both end-points of a sub-path by a half circle, with a radius equal to the half of a stroke width. For zero length sub-paths a full circle is rendered. @@ -112,7 +112,7 @@ enum class TVG_EXPORT StrokeCap /** * @brief Enumeration determining the style used at the corners of joined stroked path segments. */ -enum class TVG_EXPORT StrokeJoin +enum class StrokeJoin { Bevel = 0, ///< The outer corner of the joined path segments is bevelled at the join point. The triangular region of the corner is enclosed by a straight line between the outer corners of each stroke. Round, ///< The outer corner of the joined path segments is rounded. The circular region is centered at the join point. @@ -122,7 +122,7 @@ enum class TVG_EXPORT StrokeJoin /** * @brief Enumeration specifying how to fill the area outside the gradient bounds. */ -enum class TVG_EXPORT FillSpread +enum class FillSpread { Pad = 0, ///< The remaining area is filled with the closest stop color. Reflect, ///< The gradient pattern is reflected outside the gradient area until the expected region is filled. @@ -132,7 +132,7 @@ enum class TVG_EXPORT FillSpread /** * @brief Enumeration specifying the algorithm used to establish which parts of the shape are treated as the inside of the shape. */ -enum class TVG_EXPORT FillRule +enum class FillRule { Winding = 0, ///< A line from the point to a location outside the shape is drawn. The intersections of the line with the path segment of the shape are counted. Starting from zero, if the path segment of the shape crosses the line clockwise, one is added, otherwise one is subtracted. If the resulting sum is non zero, the point is inside the shape. EvenOdd ///< A line from the point to a location outside the shape is drawn and its intersections with the path segments of the shape are counted. If the number of intersections is an odd number, the point is inside the shape. @@ -141,7 +141,7 @@ enum class TVG_EXPORT FillRule /** * @brief Enumeration indicating the method used in the composition of two objects - the target and the source. */ -enum class TVG_EXPORT CompositeMethod +enum class CompositeMethod { None = 0, ///< No composition is applied. ClipPath, ///< The intersection of the source and the target is determined and only the resulting pixels from the source are rendered. @@ -153,7 +153,7 @@ enum class TVG_EXPORT CompositeMethod /** * @brief Enumeration specifying the engine type used for the graphics backend. For multiple backends bitwise operation is allowed. */ -enum class TVG_EXPORT CanvasEngine +enum class CanvasEngine { Sw = (1 << 1), ///< CPU rasterizer. Gl = (1 << 2) ///< OpenGL rasterizer. diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp index bf1c10a0c3..ffd74bdd47 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp @@ -22,10 +22,10 @@ #ifdef _WIN32 #include <malloc.h> -#elif __FreeBSD__ - #include<stdlib.h> -#else +#elif defined(__linux__) #include <alloca.h> +#else + #include <stdlib.h> #endif #include "tvgMath.h" diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h index f31ea1eb97..50536299b1 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h @@ -30,7 +30,7 @@ int32_t dw = surface->stride; int32_t x1, x2, x, y, ar, ab, iru, irv, px, ay; int32_t vv = 0, uu = 0; - int32_t minx, maxx; + int32_t minx = INT32_MAX, maxx = INT32_MIN; float dx, u, v, iptr; uint32_t* buf; SwSpan* span = nullptr; //used only when rle based. diff --git a/thirdparty/thorvg/src/lib/tvgLoadModule.h b/thirdparty/thorvg/src/lib/tvgLoadModule.h index bfcc165f31..004983152b 100644 --- a/thirdparty/thorvg/src/lib/tvgLoadModule.h +++ b/thirdparty/thorvg/src/lib/tvgLoadModule.h @@ -36,7 +36,6 @@ public: float vw = 0; float vh = 0; float w = 0, h = 0; //default image size - bool preserveAspect = true; //keep aspect ratio by default. virtual ~LoadModule() {} diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp index ffdef3004c..d11dfc1e7c 100644 --- a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp +++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp @@ -118,9 +118,9 @@ unique_ptr<Surface> JpgLoader::bitmap() auto surface = static_cast<Surface*>(malloc(sizeof(Surface))); surface->buffer = (uint32_t*)(image); - surface->stride = w; - surface->w = w; - surface->h = h; + surface->stride = static_cast<uint32_t>(w); + surface->w = static_cast<uint32_t>(w); + surface->h = static_cast<uint32_t>(h); surface->cs = SwCanvas::ARGB8888; return unique_ptr<Surface>(surface); diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp index dacd45ed03..56b40acf0b 100644 --- a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp +++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp @@ -808,7 +808,7 @@ inline int jpeg_decoder::huff_decode(huff_tables *pH, int& extra_bits) // Tables and macro used to fully decode the DPCM differences. static const int s_extend_test[16] = { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; -static const unsigned int s_extend_offset[16] = { 0, ((-1u)<<1) + 1, ((-1u)<<2) + 1, ((-1u)<<3) + 1, ((-1u)<<4) + 1, ((-1u)<<5) + 1, ((-1u)<<6) + 1, ((-1u)<<7) + 1, ((-1u)<<8) + 1, ((-1u)<<9) + 1, ((-1u)<<10) + 1, ((-1u)<<11) + 1, ((-1u)<<12) + 1, ((-1u)<<13) + 1, ((-1u)<<14) + 1, ((-1u)<<15) + 1 }; +static const unsigned int s_extend_offset[16] = { 0, ((~0u)<<1) + 1, ((~0u)<<2) + 1, ((~0u)<<3) + 1, ((~0u)<<4) + 1, ((~0u)<<5) + 1, ((~0u)<<6) + 1, ((~0u)<<7) + 1, ((~0u)<<8) + 1, ((~0u)<<9) + 1, ((~0u)<<10) + 1, ((~0u)<<11) + 1, ((~0u)<<12) + 1, ((~0u)<<13) + 1, ((~0u)<<14) + 1, ((~0u)<<15) + 1 }; // The logical AND's in this macro are to shut up static code analysis (aren't really necessary - couldn't find another way to do this) #define JPGD_HUFF_EXTEND(x, s) (((x) < s_extend_test[s & 15]) ? ((x) + s_extend_offset[s & 15]) : (x)) diff --git a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp index 2da399d8c3..889f130ce9 100644 --- a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp +++ b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp @@ -78,9 +78,9 @@ unique_ptr<Surface> RawLoader::bitmap() auto surface = static_cast<Surface*>(malloc(sizeof(Surface))); surface->buffer = (uint32_t*)(content); - surface->stride = w; - surface->w = w; - surface->h = h; + surface->stride = (uint32_t)w; + surface->w = (uint32_t)w; + surface->h = (uint32_t)h; surface->cs = SwCanvas::ARGB8888; return unique_ptr<Surface>(surface); diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.cpp index 8f46b62ce9..478ba5d3d1 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.cpp @@ -42,7 +42,10 @@ static void _copyStyle(SvgStyleProperty* to, const SvgStyleProperty* from) to->fill.paint.color = from->fill.paint.color; to->fill.paint.none = from->fill.paint.none; to->fill.paint.curColor = from->fill.paint.curColor; - if (from->fill.paint.url) to->fill.paint.url = strdup(from->fill.paint.url); + if (from->fill.paint.url) { + if (to->fill.paint.url) free(to->fill.paint.url); + to->fill.paint.url = strdup(from->fill.paint.url); + } to->fill.flags = (SvgFillFlags)((int)to->fill.flags | (int)SvgFillFlags::Paint); to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::Fill); } @@ -61,7 +64,10 @@ static void _copyStyle(SvgStyleProperty* to, const SvgStyleProperty* from) to->stroke.paint.color = from->stroke.paint.color; to->stroke.paint.none = from->stroke.paint.none; to->stroke.paint.curColor = from->stroke.paint.curColor; - if (from->stroke.paint.url) to->stroke.paint.url = strdup(from->stroke.paint.url); + if (from->stroke.paint.url) { + if (to->stroke.paint.url) free(to->stroke.paint.url); + to->stroke.paint.url = strdup(from->stroke.paint.url); + } to->stroke.flags = (SvgStrokeFlags)((int)to->stroke.flags | (int)SvgStrokeFlags::Paint); to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::Stroke); } @@ -122,8 +128,14 @@ void cssCopyStyleAttr(SvgNode* to, const SvgNode* from) //Copy style attribute _copyStyle(to->style, from->style); - if (from->style->clipPath.url) to->style->clipPath.url = strdup(from->style->clipPath.url); - if (from->style->mask.url) to->style->mask.url = strdup(from->style->mask.url); + if (from->style->clipPath.url) { + if (to->style->clipPath.url) free(to->style->clipPath.url); + to->style->clipPath.url = strdup(from->style->clipPath.url); + } + if (from->style->mask.url) { + if (to->style->mask.url) free(to->style->mask.url); + to->style->mask.url = strdup(from->style->mask.url); + } } diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp index 42bfd4de70..737fd96455 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp @@ -115,9 +115,54 @@ static bool _parseNumber(const char** content, float* number) if ((*content) == end) return false; //Skip comma if any *content = _skipComma(end); + return true; } + +static constexpr struct +{ + AspectRatioAlign align; + const char* tag; +} alignTags[] = { + { AspectRatioAlign::XMinYMin, "xMinYMin" }, + { AspectRatioAlign::XMidYMin, "xMidYMin" }, + { AspectRatioAlign::XMaxYMin, "xMaxYMin" }, + { AspectRatioAlign::XMinYMid, "xMinYMid" }, + { AspectRatioAlign::XMidYMid, "xMidYMid" }, + { AspectRatioAlign::XMaxYMid, "xMaxYMid" }, + { AspectRatioAlign::XMinYMax, "xMinYMax" }, + { AspectRatioAlign::XMidYMax, "xMidYMax" }, + { AspectRatioAlign::XMaxYMax, "xMaxYMax" }, +}; + + +static bool _parseAspectRatio(const char** content, AspectRatioAlign* align, AspectRatioMeetOrSlice* meetOrSlice) +{ + if (!strcmp(*content, "none")) { + *align = AspectRatioAlign::None; + return true; + } + + for (unsigned int i = 0; i < sizeof(alignTags) / sizeof(alignTags[0]); i++) { + if (!strncmp(*content, alignTags[i].tag, 8)) { + *align = alignTags[i].align; + *content += 8; + *content = _skipSpace(*content, nullptr); + break; + } + } + + if (!strcmp(*content, "meet")) { + *meetOrSlice = AspectRatioMeetOrSlice::Meet; + } else if (!strcmp(*content, "slice")) { + *meetOrSlice = AspectRatioMeetOrSlice::Slice; + } + + return true; +} + + /** * According to https://www.w3.org/TR/SVG/coords.html#Units */ @@ -554,6 +599,7 @@ static void _toColor(const char* str, uint8_t* r, uint8_t* g, uint8_t* b, char** } } } else if (ref && len >= 3 && !strncmp(str, "url", 3)) { + if (*ref) free(*ref); *ref = _idFromUrl((const char*)(str + 3)); } else { //Handle named color @@ -802,7 +848,7 @@ static bool _attrParseSvgNode(void* data, const char* key, const char* value) } loader->svgParse->global.x = (int)doc->vx; } else if (!strcmp(key, "preserveAspectRatio")) { - if (!strcmp(value, "none")) doc->preserveAspect = false; + _parseAspectRatio(&value, &doc->align, &doc->meetOrSlice); } else if (!strcmp(key, "style")) { return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); #ifdef THORVG_LOG_ENABLED @@ -1156,7 +1202,7 @@ static bool _attrParseSymbolNode(void* data, const char* key, const char* value) symbol->h = _toFloat(loader->svgParse, value, SvgParserLengthType::Vertical); symbol->hasHeight = true; } else if (!strcmp(key, "preserveAspectRatio")) { - if (!strcmp(value, "none")) symbol->preserveAspect = false; + _parseAspectRatio(&value, &symbol->align, &symbol->meetOrSlice); } else if (!strcmp(key, "overflow")) { if (!strcmp(value, "visible")) symbol->overflowVisible = true; } else { @@ -1248,7 +1294,8 @@ static SvgNode* _createSvgNode(SvgLoaderData* loader, SvgNode* parent, const cha loader->svgParse->global.w = 0; loader->svgParse->global.h = 0; - doc->preserveAspect = true; + doc->align = AspectRatioAlign::XMidYMid; + doc->meetOrSlice = AspectRatioMeetOrSlice::Meet; func(buf, bufLength, _attrParseSvgNode, loader); if (loader->svgParse->global.w == 0) { @@ -1309,7 +1356,8 @@ static SvgNode* _createSymbolNode(SvgLoaderData* loader, SvgNode* parent, const if (!loader->svgParse->node) return nullptr; loader->svgParse->node->display = false; - loader->svgParse->node->node.symbol.preserveAspect = true; + loader->svgParse->node->node.symbol.align = AspectRatioAlign::XMidYMid; + loader->svgParse->node->node.symbol.meetOrSlice = AspectRatioMeetOrSlice::Meet; loader->svgParse->node->node.symbol.overflowVisible = false; loader->svgParse->node->node.symbol.hasViewBox = false; @@ -1331,6 +1379,7 @@ static bool _attrParsePathNode(void* data, const char* key, const char* value) SvgPathNode* path = &(node->node.path); if (!strcmp(key, "d")) { + if (path->path) free(path->path); //Temporary: need to copy path->path = _copyId(value); } else if (!strcmp(key, "style")) { @@ -1801,19 +1850,10 @@ static SvgNode* _getDefsNode(SvgNode* node) } -static SvgNode* _findChildById(const SvgNode* node, const char* id) +static SvgNode* _findNodeById(SvgNode *node, const char* id) { if (!node) return nullptr; - auto child = node->child.data; - for (uint32_t i = 0; i < node->child.count; ++i, ++child) { - if (((*child)->id) && !strcmp((*child)->id, id)) return (*child); - } - return nullptr; -} - -static SvgNode* _findNodeById(SvgNode *node, const char* id) -{ SvgNode* result = nullptr; if (node->id && !strcmp(node->id, id)) return node; @@ -1827,6 +1867,7 @@ static SvgNode* _findNodeById(SvgNode *node, const char* id) return result; } + static void _cloneGradStops(Array<Fill::ColorStop>& dst, const Array<Fill::ColorStop>& src) { for (uint32_t i = 0; i < src.count; ++i) { @@ -1889,7 +1930,10 @@ static void _styleInherit(SvgStyleProperty* child, const SvgStyleProperty* paren child->fill.paint.color = parent->fill.paint.color; child->fill.paint.none = parent->fill.paint.none; child->fill.paint.curColor = parent->fill.paint.curColor; - if (parent->fill.paint.url) child->fill.paint.url = _copyId(parent->fill.paint.url); + if (parent->fill.paint.url) { + if (child->fill.paint.url) free(child->fill.paint.url); + child->fill.paint.url = _copyId(parent->fill.paint.url); + } } if (!((int)child->fill.flags & (int)SvgFillFlags::Opacity)) { child->fill.opacity = parent->fill.opacity; @@ -1902,7 +1946,12 @@ static void _styleInherit(SvgStyleProperty* child, const SvgStyleProperty* paren child->stroke.paint.color = parent->stroke.paint.color; child->stroke.paint.none = parent->stroke.paint.none; child->stroke.paint.curColor = parent->stroke.paint.curColor; - child->stroke.paint.url = parent->stroke.paint.url ? _copyId(parent->stroke.paint.url) : nullptr; + if (parent->stroke.paint.url) { + if (child->stroke.paint.url) free(child->stroke.paint.url); + child->stroke.paint.url = _copyId(parent->stroke.paint.url); + } else { + child->stroke.paint.url = nullptr; + } } if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Opacity)) { child->stroke.opacity = parent->stroke.opacity; @@ -1942,7 +1991,10 @@ static void _styleCopy(SvgStyleProperty* to, const SvgStyleProperty* from) to->fill.paint.color = from->fill.paint.color; to->fill.paint.none = from->fill.paint.none; to->fill.paint.curColor = from->fill.paint.curColor; - if (from->fill.paint.url) to->fill.paint.url = _copyId(from->fill.paint.url); + if (from->fill.paint.url) { + if (to->fill.paint.url) free(to->fill.paint.url); + to->fill.paint.url = _copyId(from->fill.paint.url); + } } if (((int)from->fill.flags & (int)SvgFillFlags::Opacity)) { to->fill.opacity = from->fill.opacity; @@ -1956,7 +2008,12 @@ static void _styleCopy(SvgStyleProperty* to, const SvgStyleProperty* from) to->stroke.paint.color = from->stroke.paint.color; to->stroke.paint.none = from->stroke.paint.none; to->stroke.paint.curColor = from->stroke.paint.curColor; - to->stroke.paint.url = from->stroke.paint.url ? _copyId(from->stroke.paint.url) : nullptr; + if (from->stroke.paint.url) { + if (to->stroke.paint.url) free(to->stroke.paint.url); + to->stroke.paint.url = _copyId(from->stroke.paint.url); + } else { + to->stroke.paint.url = nullptr; + } } if (((int)from->stroke.flags & (int)SvgStrokeFlags::Opacity)) { to->stroke.opacity = from->stroke.opacity; @@ -1992,10 +2049,14 @@ static void _copyAttr(SvgNode* to, const SvgNode* from) //Copy style attribute _styleCopy(to->style, from->style); to->style->flags = (SvgStyleFlags)((int)to->style->flags | (int)from->style->flags); - if (from->style->fill.paint.url) to->style->fill.paint.url = strdup(from->style->fill.paint.url); - if (from->style->stroke.paint.url) to->style->stroke.paint.url = strdup(from->style->stroke.paint.url); - if (from->style->clipPath.url) to->style->clipPath.url = strdup(from->style->clipPath.url); - if (from->style->mask.url) to->style->mask.url = strdup(from->style->mask.url); + if (from->style->clipPath.url) { + if (to->style->clipPath.url) free(to->style->clipPath.url); + to->style->clipPath.url = strdup(from->style->clipPath.url); + } + if (from->style->mask.url) { + if (to->style->mask.url) free(to->style->mask.url); + to->style->mask.url = strdup(from->style->mask.url); + } //Copy node attribute switch (from->type) { @@ -2031,7 +2092,10 @@ static void _copyAttr(SvgNode* to, const SvgNode* from) break; } case SvgNodeType::Path: { - if (from->node.path.path) to->node.path.path = strdup(from->node.path.path); + if (from->node.path.path) { + if (to->node.path.path) free(to->node.path.path); + to->node.path.path = strdup(from->node.path.path); + } break; } case SvgNodeType::Polygon: { @@ -2053,7 +2117,10 @@ static void _copyAttr(SvgNode* to, const SvgNode* from) to->node.image.y = from->node.image.y; to->node.image.w = from->node.image.w; to->node.image.h = from->node.image.h; - if (from->node.image.href) to->node.image.href = strdup(from->node.image.href); + if (from->node.image.href) { + if (to->node.image.href) free(to->node.image.href); + to->node.image.href = strdup(from->node.image.href); + } break; } default: { @@ -2093,8 +2160,8 @@ static void _clonePostponedNodes(Array<SvgNodeIdPair>* cloneNodes, SvgNode* doc) for (uint32_t i = 0; i < cloneNodes->count; ++i) { auto nodeIdPair = cloneNodes->data[i]; auto defs = _getDefsNode(nodeIdPair.node); - auto nodeFrom = _findChildById(defs, nodeIdPair.id); - if (!nodeFrom) nodeFrom = _findChildById(doc, nodeIdPair.id); + auto nodeFrom = _findNodeById(defs, nodeIdPair.id); + if (!nodeFrom) nodeFrom = _findNodeById(doc, nodeIdPair.id); _cloneNode(nodeFrom, nodeIdPair.node, 0); if (nodeFrom && nodeFrom->type == SvgNodeType::Symbol && nodeIdPair.node->type == SvgNodeType::Use) { nodeIdPair.node->node.use.symbol = nodeFrom; @@ -2141,7 +2208,7 @@ static bool _attrParseUseNode(void* data, const char* key, const char* value) if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) { id = _idFromHref(value); defs = _getDefsNode(node); - nodeFrom = _findChildById(defs, id); + nodeFrom = _findNodeById(defs, id); if (nodeFrom) { _cloneNode(nodeFrom, node, 0); if (nodeFrom->type == SvgNodeType::Symbol) use->symbol = nodeFrom; @@ -2695,10 +2762,14 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content, if (loader->stack.count > 0) parent = loader->stack.data[loader->stack.count - 1]; else parent = loader->doc; if (!strcmp(tagName, "style")) { - node = method(loader, nullptr, attrs, attrsLength, simpleXmlParseAttributes); - loader->cssStyle = node; - loader->doc->node.doc.style = node; - loader->style = true; + // TODO: For now only the first style node is saved. After the css id selector + // is introduced this if condition shouldin't be necessary any more + if (!loader->cssStyle) { + node = method(loader, nullptr, attrs, attrsLength, simpleXmlParseAttributes); + loader->cssStyle = node; + loader->doc->node.doc.style = node; + loader->style = true; + } } else { node = method(loader, parent, attrs, attrsLength, simpleXmlParseAttributes); } @@ -3127,7 +3198,7 @@ void SvgLoader::run(unsigned tid) _updateStyle(loaderData.doc, nullptr); } - root = svgSceneBuild(loaderData.doc, vx, vy, vw, vh, w, h, preserveAspect, svgPath); + root = svgSceneBuild(loaderData.doc, vx, vy, vw, vh, w, h, align, meetOrSlice, svgPath); } @@ -3160,7 +3231,8 @@ bool SvgLoader::header() if (vh < FLT_EPSILON) vh = h; } - preserveAspect = loaderData.doc->node.doc.preserveAspect; + align = loaderData.doc->node.doc.align; + meetOrSlice = loaderData.doc->node.doc.meetOrSlice; } else { TVGLOG("SVG", "No SVG File. There is no <svg/>"); return false; @@ -3215,31 +3287,9 @@ bool SvgLoader::resize(Paint* paint, float w, float h) auto sx = w / this->w; auto sy = h / this->h; + Matrix m = {sx, 0, 0, 0, sy, 0, 0, 0, 1}; + paint->transform(m); - if (preserveAspect) { - //Scale - auto scale = sx < sy ? sx : sy; - paint->scale(scale); - //Align - auto tx = 0.0f; - auto ty = 0.0f; - auto tw = this->w * scale; - auto th = this->h * scale; - if (tw > th) ty -= (h - th) * 0.5f; - else tx -= (w - tw) * 0.5f; - paint->translate(-tx, -ty); - } else { - //Align - auto tx = 0.0f; - auto ty = 0.0f; - auto tw = this->w * sx; - auto th = this->h * sy; - if (tw > th) ty -= (h - th) * 0.5f; - else tx -= (w - tw) * 0.5f; - - Matrix m = {sx, 0, -tx, 0, sy, -ty, 0, 0, 1}; - paint->transform(m); - } return true; } diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h index 093fb671b3..f224d1a4ac 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h @@ -50,6 +50,9 @@ public: unique_ptr<Paint> paint() override; private: + AspectRatioAlign align = AspectRatioAlign::XMidYMid; + AspectRatioMeetOrSlice meetOrSlice = AspectRatioMeetOrSlice::Meet; + bool header(); void clear(); void run(unsigned tid) override; diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h index dc9ed558c3..c657c0e21a 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h @@ -145,6 +145,26 @@ enum class SvgParserLengthType Other }; +enum class AspectRatioAlign +{ + None, + XMinYMin, + XMidYMin, + XMaxYMin, + XMinYMid, + XMidYMid, + XMaxYMid, + XMinYMax, + XMidYMax, + XMaxYMax +}; + +enum class AspectRatioMeetOrSlice +{ + Meet, + Slice +}; + struct SvgDocNode { float w; @@ -155,7 +175,8 @@ struct SvgDocNode float vh; SvgNode* defs; SvgNode* style; - bool preserveAspect; + AspectRatioAlign align; + AspectRatioMeetOrSlice meetOrSlice; }; struct SvgGNode @@ -171,7 +192,8 @@ struct SvgSymbolNode { float w, h; float vx, vy, vw, vh; - bool preserveAspect; + AspectRatioAlign align; + AspectRatioMeetOrSlice meetOrSlice; bool overflowVisible; bool hasViewBox; bool hasWidth; diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp index a3f34fd46b..4cb4ffdaeb 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -49,9 +49,9 @@ */ +#include "tvgMath.h" /* to include math.h before cstring */ #include <cstring> #include <string> -#include "tvgMath.h" #include "tvgSvgLoaderCommon.h" #include "tvgSvgSceneBuilder.h" #include "tvgSvgPath.h" @@ -68,7 +68,7 @@ struct Box static bool _appendShape(SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath); -static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, bool* isMaskWhite = nullptr); +static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, int depth, bool* isMaskWhite = nullptr); static inline bool _isGroupType(SvgNodeType type) @@ -282,7 +282,7 @@ static void _applyComposition(Paint* paint, const SvgNode* node, const Box& vBox node->style->mask.applying = true; bool isMaskWhite = true; - auto comp = _sceneBuildHelper(compNode, vBox, svgPath, true, &isMaskWhite); + auto comp = _sceneBuildHelper(compNode, vBox, svgPath, true, 0, &isMaskWhite); if (comp) { if (node->transform) comp->transform(*node->transform); @@ -560,10 +560,84 @@ static unique_ptr<Picture> _imageBuildHelper(SvgNode* node, const Box& vBox, con } -static unique_ptr<Scene> _useBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool* isMaskWhite) +static Matrix _calculateAspectRatioMatrix(AspectRatioAlign align, AspectRatioMeetOrSlice meetOrSlice, float width, float height, const Box& box) +{ + auto sx = width / box.w; + auto sy = height / box.h; + auto tvx = box.x * sx; + auto tvy = box.y * sy; + + if (align == AspectRatioAlign::None) + return {sx, 0, -tvx, 0, sy, -tvy, 0, 0, 1}; + + //Scale + if (meetOrSlice == AspectRatioMeetOrSlice::Meet) { + if (sx < sy) sy = sx; + else sx = sy; + } else { + if (sx < sy) sx = sy; + else sy = sx; + } + + //Align + tvx = box.x * sx; + tvy = box.y * sy; + auto tvw = box.w * sx; + auto tvh = box.h * sy; + + switch (align) { + case AspectRatioAlign::XMinYMin: { + break; + } + case AspectRatioAlign::XMidYMin: { + tvx -= (width - tvw) * 0.5f; + break; + } + case AspectRatioAlign::XMaxYMin: { + tvx -= width - tvw; + break; + } + case AspectRatioAlign::XMinYMid: { + tvy -= (height - tvh) * 0.5f; + break; + } + case AspectRatioAlign::XMidYMid: { + tvx -= (width - tvw) * 0.5f; + tvy -= (height - tvh) * 0.5f; + break; + } + case AspectRatioAlign::XMaxYMid: { + tvx -= width - tvw; + tvy -= (height - tvh) * 0.5f; + break; + } + case AspectRatioAlign::XMinYMax: { + tvy -= height - tvh; + break; + } + case AspectRatioAlign::XMidYMax: { + tvx -= (width - tvw) * 0.5f; + tvy -= height - tvh; + break; + } + case AspectRatioAlign::XMaxYMax: { + tvx -= width - tvw; + tvy -= height - tvh; + break; + } + default: { + break; + } + } + + return {sx, 0, -tvx, 0, sy, -tvy, 0, 0, 1}; +} + + +static unique_ptr<Scene> _useBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, int depth, bool* isMaskWhite) { unique_ptr<Scene> finalScene; - auto scene = _sceneBuildHelper(node, vBox, svgPath, false, isMaskWhite); + auto scene = _sceneBuildHelper(node, vBox, svgPath, false, depth + 1, isMaskWhite); // mUseTransform = mUseTransform * mTranslate Matrix mUseTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1}; @@ -585,20 +659,8 @@ static unique_ptr<Scene> _useBuildHelper(const SvgNode* node, const Box& vBox, c Matrix mViewBox = {1, 0, 0, 0, 1, 0, 0, 0, 1}; if ((!mathEqual(width, vw) || !mathEqual(height, vh)) && vw > 0 && vh > 0) { - auto sx = width / vw; - auto sy = height / vh; - if (symbol.preserveAspect) { - if (sx < sy) sy = sx; - else sx = sy; - } - - auto tvx = symbol.vx * sx; - auto tvy = symbol.vy * sy; - auto tvw = vw * sx; - auto tvh = vh * sy; - tvy -= (symbol.h - tvh) * 0.5f; - tvx -= (symbol.w - tvw) * 0.5f; - mViewBox = {sx, 0, -tvx, 0, sy, -tvy, 0, 0, 1}; + Box box = {symbol.vx, symbol.vy, vw, vh}; + mViewBox = _calculateAspectRatioMatrix(symbol.align, symbol.meetOrSlice, width, height, box); } else if (!mathZero(symbol.vx) || !mathZero(symbol.vy)) { mViewBox = {1, 0, -symbol.vx, 0, 1, -symbol.vy, 0, 0, 1}; } @@ -642,8 +704,15 @@ static unique_ptr<Scene> _useBuildHelper(const SvgNode* node, const Box& vBox, c } -static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, bool* isMaskWhite) +static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, int depth, bool* isMaskWhite) { + /* Exception handling: Prevent invalid SVG data input. + The size is the arbitrary value, we need an experimental size. */ + if (depth > 2192) { + TVGERR("SVG", "Infinite recursive call - stopped after %d calls! Svg file may be incorrectly formatted.", depth); + return nullptr; + } + if (_isGroupType(node->type) || mask) { auto scene = Scene::gen(); // For a Symbol node, the viewBox transformation has to be applied first - see _useBuildHelper() @@ -654,12 +723,15 @@ static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox, for (uint32_t i = 0; i < node->child.count; ++i, ++child) { if (_isGroupType((*child)->type)) { if ((*child)->type == SvgNodeType::Use) - scene->push(_useBuildHelper(*child, vBox, svgPath, isMaskWhite)); + scene->push(_useBuildHelper(*child, vBox, svgPath, depth + 1, isMaskWhite)); else - scene->push(_sceneBuildHelper(*child, vBox, svgPath, false, isMaskWhite)); + scene->push(_sceneBuildHelper(*child, vBox, svgPath, false, depth + 1, isMaskWhite)); } else if ((*child)->type == SvgNodeType::Image) { auto image = _imageBuildHelper(*child, vBox, svgPath); - if (image) scene->push(move(image)); + if (image) { + scene->push(move(image)); + if (isMaskWhite) *isMaskWhite = false; + } } else if ((*child)->type != SvgNodeType::Mask) { auto shape = _shapeBuildHelper(*child, vBox, svgPath); if (shape) { @@ -688,36 +760,18 @@ static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox, /* External Class Implementation */ /************************************************************************/ -unique_ptr<Scene> svgSceneBuild(SvgNode* node, float vx, float vy, float vw, float vh, float w, float h, bool preserveAspect, const string& svgPath) +unique_ptr<Scene> svgSceneBuild(SvgNode* node, float vx, float vy, float vw, float vh, float w, float h, AspectRatioAlign align, AspectRatioMeetOrSlice meetOrSlice, const string& svgPath) { + //TODO: aspect ratio is valid only if viewBox was set + if (!node || (node->type != SvgNodeType::Doc)) return nullptr; Box vBox = {vx, vy, vw, vh}; - auto docNode = _sceneBuildHelper(node, vBox, svgPath, false); + auto docNode = _sceneBuildHelper(node, vBox, svgPath, false, 0); if (!mathEqual(w, vw) || !mathEqual(h, vh)) { - auto sx = w / vw; - auto sy = h / vh; - - if (preserveAspect) { - //Scale - auto scale = sx < sy ? sx : sy; - docNode->scale(scale); - //Align - auto tvx = vx * scale; - auto tvy = vy * scale; - auto tvw = vw * scale; - auto tvh = vh * scale; - tvx -= (w - tvw) * 0.5f; - tvy -= (h - tvh) * 0.5f; - docNode->translate(-tvx, -tvy); - } else { - //Align - auto tvx = vx * sx; - auto tvy = vy * sy; - Matrix m = {sx, 0, -tvx, 0, sy, -tvy, 0, 0, 1}; - docNode->transform(m); - } + Matrix m = _calculateAspectRatioMatrix(align, meetOrSlice, w, h, vBox); + docNode->transform(m); } else if (!mathZero(vx) || !mathZero(vy)) { docNode->translate(-vx, -vy); } diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h index cecbbf02a8..311f3c80e6 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h @@ -25,6 +25,6 @@ #include "tvgCommon.h" -unique_ptr<Scene> svgSceneBuild(SvgNode* node, float vx, float vy, float vw, float vh, float w, float h, bool preserveAspect, const string& svgPath); +unique_ptr<Scene> svgSceneBuild(SvgNode* node, float vx, float vy, float vw, float vh, float w, float h, AspectRatioAlign align, AspectRatioMeetOrSlice meetOrSlice, const string& svgPath); #endif //_TVG_SVG_SCENE_BUILDER_H_ diff --git a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp index c373da2dd5..231badd27d 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp @@ -26,10 +26,10 @@ #ifdef _WIN32 #include <malloc.h> -#elif __FreeBSD__ - #include<stdlib.h> -#else +#elif defined(__linux__) #include <alloca.h> +#else + #include <stdlib.h> #endif #include "tvgXmlParser.h" diff --git a/thirdparty/thorvg/src/loaders/tvg/tvgTvgBinInterpreter.cpp b/thirdparty/thorvg/src/loaders/tvg/tvgTvgBinInterpreter.cpp index 62a75ecd3d..01a39b6e17 100644 --- a/thirdparty/thorvg/src/loaders/tvg/tvgTvgBinInterpreter.cpp +++ b/thirdparty/thorvg/src/loaders/tvg/tvgTvgBinInterpreter.cpp @@ -23,10 +23,10 @@ #ifdef _WIN32 #include <malloc.h> -#elif __FreeBSD__ - #include<stdlib.h> -#else +#elif defined(__linux__) #include <alloca.h> +#else + #include <stdlib.h> #endif #include "tvgTvgCommon.h" diff --git a/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp b/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp index adf85836c3..57a21dcce1 100644 --- a/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp +++ b/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp @@ -28,10 +28,10 @@ #ifdef _WIN32 #include <malloc.h> -#elif __FreeBSD__ - #include<stdlib.h> -#else +#elif defined(__linux__) #include <alloca.h> +#else + #include <stdlib.h> #endif static FILE* _fopen(const char* filename, const char* mode) diff --git a/thirdparty/thorvg/update-thorvg.sh b/thirdparty/thorvg/update-thorvg.sh index f2fd2a80e4..8cccc947ce 100755 --- a/thirdparty/thorvg/update-thorvg.sh +++ b/thirdparty/thorvg/update-thorvg.sh @@ -1,4 +1,4 @@ -VERSION=0.8.2 +VERSION=0.8.3 rm -rf AUTHORS inc LICENSE src *.zip curl -L -O https://github.com/Samsung/thorvg/archive/v$VERSION.zip bsdtar --strip-components=1 -xvf *.zip @@ -26,3 +26,6 @@ cat << EOF > inc/config.h #define THORVG_VERSION_STRING "$VERSION" #endif EOF +for source in $(find ./ -type f \( -iname \*.h -o -iname \*.cpp \)); do + sed -i -e '$a\' $source +done diff --git a/thirdparty/zlib/LICENSE b/thirdparty/zlib/LICENSE new file mode 100644 index 0000000000..ab8ee6f714 --- /dev/null +++ b/thirdparty/zlib/LICENSE @@ -0,0 +1,22 @@ +Copyright notice: + + (C) 1995-2022 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu diff --git a/thirdparty/zlib/compress.c b/thirdparty/zlib/compress.c index e2db404abf..2ad5326c14 100644 --- a/thirdparty/zlib/compress.c +++ b/thirdparty/zlib/compress.c @@ -19,7 +19,7 @@ memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. */ -int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) +int ZEXPORT compress2(dest, destLen, source, sourceLen, level) Bytef *dest; uLongf *destLen; const Bytef *source; @@ -65,7 +65,7 @@ int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) /* =========================================================================== */ -int ZEXPORT compress (dest, destLen, source, sourceLen) +int ZEXPORT compress(dest, destLen, source, sourceLen) Bytef *dest; uLongf *destLen; const Bytef *source; @@ -78,7 +78,7 @@ int ZEXPORT compress (dest, destLen, source, sourceLen) If the default memLevel or windowBits for deflateInit() is changed, then this function needs to be updated. */ -uLong ZEXPORT compressBound (sourceLen) +uLong ZEXPORT compressBound(sourceLen) uLong sourceLen; { return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + diff --git a/thirdparty/zlib/crc32.c b/thirdparty/zlib/crc32.c index a1bdce5c23..f8357b083f 100644 --- a/thirdparty/zlib/crc32.c +++ b/thirdparty/zlib/crc32.c @@ -98,13 +98,22 @@ # endif #endif +/* If available, use the ARM processor CRC32 instruction. */ +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8 +# define ARMCRC32 +#endif + /* Local functions. */ local z_crc_t multmodp OF((z_crc_t a, z_crc_t b)); local z_crc_t x2nmodp OF((z_off64_t n, unsigned k)); -/* If available, use the ARM processor CRC32 instruction. */ -#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8 -# define ARMCRC32 +#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE)) + local z_word_t byte_swap OF((z_word_t word)); +#endif + +#if defined(W) && !defined(ARMCRC32) + local z_crc_t crc_word OF((z_word_t data)); + local z_word_t crc_word_big OF((z_word_t data)); #endif #if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE)) @@ -630,7 +639,7 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) #endif /* DYNAMIC_CRC_TABLE */ /* Pre-condition the CRC */ - crc ^= 0xffffffff; + crc = (~crc) & 0xffffffff; /* Compute the CRC up to a word boundary. */ while (len && ((z_size_t)buf & 7) != 0) { @@ -645,8 +654,8 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) len &= 7; /* Do three interleaved CRCs to realize the throughput of one crc32x - instruction per cycle. Each CRC is calcuated on Z_BATCH words. The three - CRCs are combined into a single CRC after each set of batches. */ + instruction per cycle. Each CRC is calculated on Z_BATCH words. The + three CRCs are combined into a single CRC after each set of batches. */ while (num >= 3 * Z_BATCH) { crc1 = 0; crc2 = 0; @@ -749,7 +758,7 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) #endif /* DYNAMIC_CRC_TABLE */ /* Pre-condition the CRC */ - crc ^= 0xffffffff; + crc = (~crc) & 0xffffffff; #ifdef W @@ -1077,7 +1086,7 @@ uLong ZEXPORT crc32_combine64(crc1, crc2, len2) #ifdef DYNAMIC_CRC_TABLE once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ - return multmodp(x2nmodp(len2, 3), crc1) ^ crc2; + return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff); } /* ========================================================================= */ @@ -1086,7 +1095,7 @@ uLong ZEXPORT crc32_combine(crc1, crc2, len2) uLong crc2; z_off_t len2; { - return crc32_combine64(crc1, crc2, len2); + return crc32_combine64(crc1, crc2, (z_off64_t)len2); } /* ========================================================================= */ @@ -1103,14 +1112,14 @@ uLong ZEXPORT crc32_combine_gen64(len2) uLong ZEXPORT crc32_combine_gen(len2) z_off_t len2; { - return crc32_combine_gen64(len2); + return crc32_combine_gen64((z_off64_t)len2); } /* ========================================================================= */ -uLong crc32_combine_op(crc1, crc2, op) +uLong ZEXPORT crc32_combine_op(crc1, crc2, op) uLong crc1; uLong crc2; uLong op; { - return multmodp(op, crc1) ^ crc2; + return multmodp(op, crc1) ^ (crc2 & 0xffffffff); } diff --git a/thirdparty/zlib/deflate.c b/thirdparty/zlib/deflate.c index 799fb93cc0..4a689db359 100644 --- a/thirdparty/zlib/deflate.c +++ b/thirdparty/zlib/deflate.c @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.2.12 Copyright 1995-2022 Jean-loup Gailly and Mark Adler "; + " deflate 1.2.13 Copyright 1995-2022 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -87,13 +87,7 @@ local void lm_init OF((deflate_state *s)); local void putShortMSB OF((deflate_state *s, uInt b)); local void flush_pending OF((z_streamp strm)); local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -#ifdef ASMV -# pragma message("Assembler code may have bugs -- use at your own risk") - void match_init OF((void)); /* asm code initialization */ - uInt longest_match OF((deflate_state *s, IPos cur_match)); -#else local uInt longest_match OF((deflate_state *s, IPos cur_match)); -#endif #ifdef ZLIB_DEBUG local void check_match OF((deflate_state *s, IPos start, IPos match, @@ -160,7 +154,7 @@ local const config configuration_table[10] = { * characters, so that a running hash key can be computed from the previous * key instead of complete recalculation each time. */ -#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) +#define UPDATE_HASH(s,h,c) (h = (((h) << s->hash_shift) ^ (c)) & s->hash_mask) /* =========================================================================== @@ -191,9 +185,9 @@ local const config configuration_table[10] = { */ #define CLEAR_HASH(s) \ do { \ - s->head[s->hash_size-1] = NIL; \ + s->head[s->hash_size - 1] = NIL; \ zmemzero((Bytef *)s->head, \ - (unsigned)(s->hash_size-1)*sizeof(*s->head)); \ + (unsigned)(s->hash_size - 1)*sizeof(*s->head)); \ } while (0) /* =========================================================================== @@ -285,6 +279,8 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, if (windowBits < 0) { /* suppress zlib wrapper */ wrap = 0; + if (windowBits < -15) + return Z_STREAM_ERROR; windowBits = -windowBits; } #ifdef GZIP @@ -314,7 +310,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, s->hash_bits = (uInt)memLevel + 7; s->hash_size = 1 << s->hash_bits; s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + s->hash_shift = ((s->hash_bits + MIN_MATCH-1) / MIN_MATCH); s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); @@ -340,11 +336,11 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, * sym_buf value to read moves forward three bytes. From that symbol, up to * 31 bits are written to pending_buf. The closest the written pending_buf * bits gets to the next sym_buf symbol to read is just before the last - * code is written. At that time, 31*(n-2) bits have been written, just - * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at - * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1 + * code is written. At that time, 31*(n - 2) bits have been written, just + * after 24*(n - 2) bits have been consumed from sym_buf. sym_buf starts at + * 8*n bits into pending_buf. (Note that the symbol buffer fills when n - 1 * symbols are written.) The closest the writing gets to what is unread is - * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and + * then n + 14 bits. Here n is lit_bufsize, which is 16384 by default, and * can range from 128 to 32768. * * Therefore, at a minimum, there are 142 bits of space between what is @@ -390,7 +386,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, /* ========================================================================= * Check for a valid deflate stream state. Return 0 if ok, 1 if not. */ -local int deflateStateCheck (strm) +local int deflateStateCheck(strm) z_streamp strm; { deflate_state *s; @@ -413,7 +409,7 @@ local int deflateStateCheck (strm) } /* ========================================================================= */ -int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) +int ZEXPORT deflateSetDictionary(strm, dictionary, dictLength) z_streamp strm; const Bytef *dictionary; uInt dictLength; @@ -482,7 +478,7 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) } /* ========================================================================= */ -int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength) +int ZEXPORT deflateGetDictionary(strm, dictionary, dictLength) z_streamp strm; Bytef *dictionary; uInt *dictLength; @@ -504,7 +500,7 @@ int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength) } /* ========================================================================= */ -int ZEXPORT deflateResetKeep (strm) +int ZEXPORT deflateResetKeep(strm) z_streamp strm; { deflate_state *s; @@ -542,7 +538,7 @@ int ZEXPORT deflateResetKeep (strm) } /* ========================================================================= */ -int ZEXPORT deflateReset (strm) +int ZEXPORT deflateReset(strm) z_streamp strm; { int ret; @@ -554,7 +550,7 @@ int ZEXPORT deflateReset (strm) } /* ========================================================================= */ -int ZEXPORT deflateSetHeader (strm, head) +int ZEXPORT deflateSetHeader(strm, head) z_streamp strm; gz_headerp head; { @@ -565,7 +561,7 @@ int ZEXPORT deflateSetHeader (strm, head) } /* ========================================================================= */ -int ZEXPORT deflatePending (strm, pending, bits) +int ZEXPORT deflatePending(strm, pending, bits) unsigned *pending; int *bits; z_streamp strm; @@ -579,7 +575,7 @@ int ZEXPORT deflatePending (strm, pending, bits) } /* ========================================================================= */ -int ZEXPORT deflatePrime (strm, bits, value) +int ZEXPORT deflatePrime(strm, bits, value) z_streamp strm; int bits; int value; @@ -674,36 +670,50 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) } /* ========================================================================= - * For the default windowBits of 15 and memLevel of 8, this function returns - * a close to exact, as well as small, upper bound on the compressed size. - * They are coded as constants here for a reason--if the #define's are - * changed, then this function needs to be changed as well. The return - * value for 15 and 8 only works for those exact settings. + * For the default windowBits of 15 and memLevel of 8, this function returns a + * close to exact, as well as small, upper bound on the compressed size. This + * is an expansion of ~0.03%, plus a small constant. + * + * For any setting other than those defaults for windowBits and memLevel, one + * of two worst case bounds is returned. This is at most an expansion of ~4% or + * ~13%, plus a small constant. * - * For any setting other than those defaults for windowBits and memLevel, - * the value returned is a conservative worst case for the maximum expansion - * resulting from using fixed blocks instead of stored blocks, which deflate - * can emit on compressed data for some combinations of the parameters. + * Both the 0.03% and 4% derive from the overhead of stored blocks. The first + * one is for stored blocks of 16383 bytes (memLevel == 8), whereas the second + * is for stored blocks of 127 bytes (the worst case memLevel == 1). The + * expansion results from five bytes of header for each stored block. * - * This function could be more sophisticated to provide closer upper bounds for - * every combination of windowBits and memLevel. But even the conservative - * upper bound of about 14% expansion does not seem onerous for output buffer - * allocation. + * The larger expansion of 13% results from a window size less than or equal to + * the symbols buffer size (windowBits <= memLevel + 7). In that case some of + * the data being compressed may have slid out of the sliding window, impeding + * a stored block from being emitted. Then the only choice is a fixed or + * dynamic block, where a fixed block limits the maximum expansion to 9 bits + * per 8-bit byte, plus 10 bits for every block. The smallest block size for + * which this can occur is 255 (memLevel == 2). + * + * Shifts are used to approximate divisions, for speed. */ uLong ZEXPORT deflateBound(strm, sourceLen) z_streamp strm; uLong sourceLen; { deflate_state *s; - uLong complen, wraplen; + uLong fixedlen, storelen, wraplen; + + /* upper bound for fixed blocks with 9-bit literals and length 255 + (memLevel == 2, which is the lowest that may not use stored blocks) -- + ~13% overhead plus a small constant */ + fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) + + (sourceLen >> 9) + 4; - /* conservative upper bound for compressed data */ - complen = sourceLen + - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; + /* upper bound for stored blocks with length 127 (memLevel == 1) -- + ~4% overhead plus a small constant */ + storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) + + (sourceLen >> 11) + 7; - /* if can't get parameters, return conservative bound plus zlib wrapper */ + /* if can't get parameters, return larger bound plus a zlib wrapper */ if (deflateStateCheck(strm)) - return complen + 6; + return (fixedlen > storelen ? fixedlen : storelen) + 6; /* compute wrapper length */ s = strm->state; @@ -740,11 +750,12 @@ uLong ZEXPORT deflateBound(strm, sourceLen) wraplen = 6; } - /* if not default parameters, return conservative bound */ + /* if not default parameters, return one of the conservative bounds */ if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return complen + wraplen; + return (s->w_bits <= s->hash_bits ? fixedlen : storelen) + wraplen; - /* default settings: return tight bound for that case */ + /* default settings: return tight bound for that case -- ~0.03% overhead + plus a small constant */ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + (sourceLen >> 25) + 13 - 6 + wraplen; } @@ -754,7 +765,7 @@ uLong ZEXPORT deflateBound(strm, sourceLen) * IN assertion: the stream state is correct and there is enough room in * pending_buf. */ -local void putShortMSB (s, b) +local void putShortMSB(s, b) deflate_state *s; uInt b; { @@ -801,7 +812,7 @@ local void flush_pending(strm) } while (0) /* ========================================================================= */ -int ZEXPORT deflate (strm, flush) +int ZEXPORT deflate(strm, flush) z_streamp strm; int flush; { @@ -856,7 +867,7 @@ int ZEXPORT deflate (strm, flush) s->status = BUSY_STATE; if (s->status == INIT_STATE) { /* zlib header */ - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt header = (Z_DEFLATED + ((s->w_bits - 8) << 4)) << 8; uInt level_flags; if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) @@ -1116,7 +1127,7 @@ int ZEXPORT deflate (strm, flush) } /* ========================================================================= */ -int ZEXPORT deflateEnd (strm) +int ZEXPORT deflateEnd(strm) z_streamp strm; { int status; @@ -1142,7 +1153,7 @@ int ZEXPORT deflateEnd (strm) * To simplify the source, this is not supported for 16-bit MSDOS (which * doesn't have enough memory anyway to duplicate compression states). */ -int ZEXPORT deflateCopy (dest, source) +int ZEXPORT deflateCopy(dest, source) z_streamp dest; z_streamp source; { @@ -1231,7 +1242,7 @@ local unsigned read_buf(strm, buf, size) /* =========================================================================== * Initialize the "longest match" routines for a new zlib stream */ -local void lm_init (s) +local void lm_init(s) deflate_state *s; { s->window_size = (ulg)2L*s->w_size; @@ -1252,11 +1263,6 @@ local void lm_init (s) s->match_length = s->prev_length = MIN_MATCH-1; s->match_available = 0; s->ins_h = 0; -#ifndef FASTEST -#ifdef ASMV - match_init(); /* initialize the asm code */ -#endif -#endif } #ifndef FASTEST @@ -1269,10 +1275,6 @@ local void lm_init (s) * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 * OUT assertion: the match length is not greater than s->lookahead. */ -#ifndef ASMV -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. - */ local uInt longest_match(s, cur_match) deflate_state *s; IPos cur_match; /* current match */ @@ -1297,10 +1299,10 @@ local uInt longest_match(s, cur_match) */ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); + register ush scan_end = *(ushf*)(scan + best_len - 1); #else register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end1 = scan[best_len - 1]; register Byte scan_end = scan[best_len]; #endif @@ -1318,7 +1320,8 @@ local uInt longest_match(s, cur_match) */ if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead; - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "need lookahead"); do { Assert(cur_match < s->strstart, "no future"); @@ -1336,43 +1339,44 @@ local uInt longest_match(s, cur_match) /* This code assumes sizeof(unsigned short) == 2. Do not use * UNALIGNED_OK if your compiler uses a different size. */ - if (*(ushf*)(match+best_len-1) != scan_end || + if (*(ushf*)(match + best_len - 1) != scan_end || *(ushf*)match != scan_start) continue; /* It is not necessary to compare scan[2] and match[2] since they are * always equal when the other bytes match, given that the hash keys * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient + * strstart + 3, + 5, up to strstart + 257. We check for insufficient * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * at strstart + 257. If MAX_MATCH-2 is not a multiple of 8, it is * necessary to put more guard bytes at the end of the window, or * to check more often for insufficient lookahead. */ Assert(scan[2] == match[2], "scan[2]?"); scan++, match++; do { - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + } while (*(ushf*)(scan += 2) == *(ushf*)(match += 2) && + *(ushf*)(scan += 2) == *(ushf*)(match += 2) && + *(ushf*)(scan += 2) == *(ushf*)(match += 2) && + *(ushf*)(scan += 2) == *(ushf*)(match += 2) && scan < strend); /* The funny "do {}" generates better code on most compilers */ - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + /* Here, scan <= window + strstart + 257 */ + Assert(scan <= s->window + (unsigned)(s->window_size - 1), + "wild scan"); if (*scan == *match) scan++; - len = (MAX_MATCH - 1) - (int)(strend-scan); + len = (MAX_MATCH - 1) - (int)(strend - scan); scan = strend - (MAX_MATCH-1); #else /* UNALIGNED_OK */ - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; + if (match[best_len] != scan_end || + match[best_len - 1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; - /* The check at best_len-1 can be removed because it will be made + /* The check at best_len - 1 can be removed because it will be made * again later. (This heuristic is not always a win.) * It is not necessary to compare scan[2] and match[2] since they * are always equal when the other bytes match, given that @@ -1382,7 +1386,7 @@ local uInt longest_match(s, cur_match) Assert(*scan == *match, "match[2]?"); /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. + * the 256th check will be made at strstart + 258. */ do { } while (*++scan == *++match && *++scan == *++match && @@ -1391,7 +1395,8 @@ local uInt longest_match(s, cur_match) *++scan == *++match && *++scan == *++match && scan < strend); - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + Assert(scan <= s->window + (unsigned)(s->window_size - 1), + "wild scan"); len = MAX_MATCH - (int)(strend - scan); scan = strend - MAX_MATCH; @@ -1403,9 +1408,9 @@ local uInt longest_match(s, cur_match) best_len = len; if (len >= nice_match) break; #ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan+best_len-1); + scan_end = *(ushf*)(scan + best_len - 1); #else - scan_end1 = scan[best_len-1]; + scan_end1 = scan[best_len - 1]; scan_end = scan[best_len]; #endif } @@ -1415,7 +1420,6 @@ local uInt longest_match(s, cur_match) if ((uInt)best_len <= s->lookahead) return (uInt)best_len; return s->lookahead; } -#endif /* ASMV */ #else /* FASTEST */ @@ -1436,7 +1440,8 @@ local uInt longest_match(s, cur_match) */ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "need lookahead"); Assert(cur_match < s->strstart, "no future"); @@ -1446,7 +1451,7 @@ local uInt longest_match(s, cur_match) */ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; - /* The check at best_len-1 can be removed because it will be made + /* The check at best_len - 1 can be removed because it will be made * again later. (This heuristic is not always a win.) * It is not necessary to compare scan[2] and match[2] since they * are always equal when the other bytes match, given that @@ -1456,7 +1461,7 @@ local uInt longest_match(s, cur_match) Assert(*scan == *match, "match[2]?"); /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. + * the 256th check will be made at strstart + 258. */ do { } while (*++scan == *++match && *++scan == *++match && @@ -1465,7 +1470,7 @@ local uInt longest_match(s, cur_match) *++scan == *++match && *++scan == *++match && scan < strend); - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan"); len = MAX_MATCH - (int)(strend - scan); @@ -1501,7 +1506,7 @@ local void check_match(s, start, match, length) z_error("invalid match"); } if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start-match, length); + fprintf(stderr,"\\[%d,%d]", start - match, length); do { putc(s->window[start++], stderr); } while (--length != 0); } } @@ -1547,9 +1552,9 @@ local void fill_window(s) /* If the window is almost full and there is insufficient lookahead, * move the upper half to the lower one to make room in the upper half. */ - if (s->strstart >= wsize+MAX_DIST(s)) { + if (s->strstart >= wsize + MAX_DIST(s)) { - zmemcpy(s->window, s->window+wsize, (unsigned)wsize - more); + zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more); s->match_start -= wsize; s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ s->block_start -= (long) wsize; @@ -1680,7 +1685,7 @@ local void fill_window(s) * * deflate_stored() is written to minimize the number of times an input byte is * copied. It is most efficient with large input and output buffers, which - * maximizes the opportunites to have a single copy from next_in to next_out. + * maximizes the opportunities to have a single copy from next_in to next_out. */ local block_state deflate_stored(s, flush) deflate_state *s; @@ -1890,7 +1895,7 @@ local block_state deflate_fast(s, flush) if (s->lookahead == 0) break; /* flush the current block */ } - /* Insert the string window[strstart .. strstart+2] in the + /* Insert the string window[strstart .. strstart + 2] in the * dictionary, and set hash_head to the head of the hash chain: */ hash_head = NIL; @@ -1938,7 +1943,7 @@ local block_state deflate_fast(s, flush) s->strstart += s->match_length; s->match_length = 0; s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); + UPDATE_HASH(s, s->ins_h, s->window[s->strstart + 1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif @@ -1949,7 +1954,7 @@ local block_state deflate_fast(s, flush) } else { /* No match, output a literal byte */ Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); + _tr_tally_lit(s, s->window[s->strstart], bflush); s->lookahead--; s->strstart++; } @@ -1993,7 +1998,7 @@ local block_state deflate_slow(s, flush) if (s->lookahead == 0) break; /* flush the current block */ } - /* Insert the string window[strstart .. strstart+2] in the + /* Insert the string window[strstart .. strstart + 2] in the * dictionary, and set hash_head to the head of the hash chain: */ hash_head = NIL; @@ -2035,17 +2040,17 @@ local block_state deflate_slow(s, flush) uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; /* Do not insert strings in hash table beyond this. */ - check_match(s, s->strstart-1, s->prev_match, s->prev_length); + check_match(s, s->strstart - 1, s->prev_match, s->prev_length); - _tr_tally_dist(s, s->strstart -1 - s->prev_match, + _tr_tally_dist(s, s->strstart - 1 - s->prev_match, s->prev_length - MIN_MATCH, bflush); /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not + * strstart - 1 and strstart are already inserted. If there is not * enough lookahead, the last two strings are not inserted in * the hash table. */ - s->lookahead -= s->prev_length-1; + s->lookahead -= s->prev_length - 1; s->prev_length -= 2; do { if (++s->strstart <= max_insert) { @@ -2063,8 +2068,8 @@ local block_state deflate_slow(s, flush) * single literal. If there was a match but the current match * is longer, truncate the previous match to a single literal. */ - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); + Tracevv((stderr,"%c", s->window[s->strstart - 1])); + _tr_tally_lit(s, s->window[s->strstart - 1], bflush); if (bflush) { FLUSH_BLOCK_ONLY(s, 0); } @@ -2082,8 +2087,8 @@ local block_state deflate_slow(s, flush) } Assert (flush != Z_NO_FLUSH, "no flush?"); if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); + Tracevv((stderr,"%c", s->window[s->strstart - 1])); + _tr_tally_lit(s, s->window[s->strstart - 1], bflush); s->match_available = 0; } s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; @@ -2140,7 +2145,8 @@ local block_state deflate_rle(s, flush) if (s->match_length > s->lookahead) s->match_length = s->lookahead; } - Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); + Assert(scan <= s->window + (uInt)(s->window_size - 1), + "wild scan"); } /* Emit match if have run of MIN_MATCH or longer, else emit literal */ @@ -2155,7 +2161,7 @@ local block_state deflate_rle(s, flush) } else { /* No match, output a literal byte */ Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); + _tr_tally_lit(s, s->window[s->strstart], bflush); s->lookahead--; s->strstart++; } @@ -2195,7 +2201,7 @@ local block_state deflate_huff(s, flush) /* Output a literal byte */ s->match_length = 0; Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); + _tr_tally_lit(s, s->window[s->strstart], bflush); s->lookahead--; s->strstart++; if (bflush) FLUSH_BLOCK(s, 0); diff --git a/thirdparty/zlib/deflate.h b/thirdparty/zlib/deflate.h index 17c226113b..1a06cd5f25 100644 --- a/thirdparty/zlib/deflate.h +++ b/thirdparty/zlib/deflate.h @@ -329,8 +329,8 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, # define _tr_tally_dist(s, distance, length, flush) \ { uch len = (uch)(length); \ ush dist = (ush)(distance); \ - s->sym_buf[s->sym_next++] = dist; \ - s->sym_buf[s->sym_next++] = dist >> 8; \ + s->sym_buf[s->sym_next++] = (uch)dist; \ + s->sym_buf[s->sym_next++] = (uch)(dist >> 8); \ s->sym_buf[s->sym_next++] = len; \ dist--; \ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ diff --git a/thirdparty/zlib/gzlib.c b/thirdparty/zlib/gzlib.c index dddaf26873..55da46a453 100644 --- a/thirdparty/zlib/gzlib.c +++ b/thirdparty/zlib/gzlib.c @@ -30,7 +30,7 @@ local gzFile gz_open OF((const void *, int, const char *)); The gz_strwinerror function does not change the current setting of GetLastError. */ -char ZLIB_INTERNAL *gz_strwinerror (error) +char ZLIB_INTERNAL *gz_strwinerror(error) DWORD error; { static char buf[1024]; diff --git a/thirdparty/zlib/gzread.c b/thirdparty/zlib/gzread.c index 884c9bfe4c..dd77381596 100644 --- a/thirdparty/zlib/gzread.c +++ b/thirdparty/zlib/gzread.c @@ -157,11 +157,9 @@ local int gz_look(state) the output buffer is larger than the input buffer, which also assures space for gzungetc() */ state->x.next = state->out; - if (strm->avail_in) { - memcpy(state->x.next, strm->next_in, strm->avail_in); - state->x.have = strm->avail_in; - strm->avail_in = 0; - } + memcpy(state->x.next, strm->next_in, strm->avail_in); + state->x.have = strm->avail_in; + strm->avail_in = 0; state->how = COPY; state->direct = 1; return 0; diff --git a/thirdparty/zlib/gzwrite.c b/thirdparty/zlib/gzwrite.c index a8ffc8f53d..eb8a0e5893 100644 --- a/thirdparty/zlib/gzwrite.c +++ b/thirdparty/zlib/gzwrite.c @@ -474,7 +474,7 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) #else /* !STDC && !Z_HAVE_STDARG_H */ /* -- see zlib.h -- */ -int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, +int ZEXPORTVA gzprintf(file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) gzFile file; const char *format; diff --git a/thirdparty/zlib/infback.c b/thirdparty/zlib/infback.c index a390c58e81..babeaf1806 100644 --- a/thirdparty/zlib/infback.c +++ b/thirdparty/zlib/infback.c @@ -66,6 +66,7 @@ int stream_size; state->window = window; state->wnext = 0; state->whave = 0; + state->sane = 1; return Z_OK; } @@ -605,25 +606,27 @@ void FAR *out_desc; break; case DONE: - /* inflate stream terminated properly -- write leftover output */ + /* inflate stream terminated properly */ ret = Z_STREAM_END; - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left)) - ret = Z_BUF_ERROR; - } goto inf_leave; case BAD: ret = Z_DATA_ERROR; goto inf_leave; - default: /* can't happen, but makes compilers happy */ + default: + /* can't happen, but makes compilers happy */ ret = Z_STREAM_ERROR; goto inf_leave; } - /* Return unused input */ + /* Write leftover output and return unused input */ inf_leave: + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left) && + ret == Z_STREAM_END) + ret = Z_BUF_ERROR; + } strm->next_in = next; strm->avail_in = have; return ret; diff --git a/thirdparty/zlib/inflate.c b/thirdparty/zlib/inflate.c index 7be8c63662..8acbef44e9 100644 --- a/thirdparty/zlib/inflate.c +++ b/thirdparty/zlib/inflate.c @@ -168,6 +168,8 @@ int windowBits; /* extract wrap request from windowBits parameter */ if (windowBits < 0) { + if (windowBits < -15) + return Z_STREAM_ERROR; wrap = 0; windowBits = -windowBits; } @@ -764,8 +766,9 @@ int flush; if (copy > have) copy = have; if (copy) { if (state->head != Z_NULL && - state->head->extra != Z_NULL) { - len = state->head->extra_len - state->length; + state->head->extra != Z_NULL && + (len = state->head->extra_len - state->length) < + state->head->extra_max) { zmemcpy(state->head->extra + len, next, len + copy > state->head->extra_max ? state->head->extra_max - len : copy); diff --git a/thirdparty/zlib/inftrees.c b/thirdparty/zlib/inftrees.c index 09462a740b..57d2793bec 100644 --- a/thirdparty/zlib/inftrees.c +++ b/thirdparty/zlib/inftrees.c @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.2.12 Copyright 1995-2022 Mark Adler "; + " inflate 1.2.13 Copyright 1995-2022 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -62,7 +62,7 @@ unsigned short FAR *work; 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 199, 202}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 194, 65}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, diff --git a/thirdparty/zlib/inftrees.h b/thirdparty/zlib/inftrees.h index baa53a0b1a..f53665311c 100644 --- a/thirdparty/zlib/inftrees.h +++ b/thirdparty/zlib/inftrees.h @@ -38,7 +38,7 @@ typedef struct { /* Maximum size of the dynamic table. The maximum number of code structures is 1444, which is the sum of 852 for literal/length codes and 592 for distance codes. These values were found by exhaustive searches using the program - examples/enough.c found in the zlib distribtution. The arguments to that + examples/enough.c found in the zlib distribution. The arguments to that program are the number of symbols, the initial root table size, and the maximum bit length of a code. "enough 286 9 15" for literal/length codes returns returns 852, and "enough 30 6 15" for distance codes returns 592. diff --git a/thirdparty/zlib/trees.c b/thirdparty/zlib/trees.c index f73fd99c37..5f305c4722 100644 --- a/thirdparty/zlib/trees.c +++ b/thirdparty/zlib/trees.c @@ -193,7 +193,7 @@ local void send_bits(s, value, length) s->bits_sent += (ulg)length; /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * (16 - bi_valid) bits from value, leaving (width - (16 - bi_valid)) * unused bits in value. */ if (s->bi_valid > (int)Buf_size - length) { @@ -256,7 +256,7 @@ local void tr_static_init() length = 0; for (code = 0; code < LENGTH_CODES-1; code++) { base_length[code] = length; - for (n = 0; n < (1<<extra_lbits[code]); n++) { + for (n = 0; n < (1 << extra_lbits[code]); n++) { _length_code[length++] = (uch)code; } } @@ -265,13 +265,13 @@ local void tr_static_init() * in two different ways: code 284 + 5 bits or code 285, so we * overwrite length_code[255] to use the best encoding: */ - _length_code[length-1] = (uch)code; + _length_code[length - 1] = (uch)code; /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ dist = 0; for (code = 0 ; code < 16; code++) { base_dist[code] = dist; - for (n = 0; n < (1<<extra_dbits[code]); n++) { + for (n = 0; n < (1 << extra_dbits[code]); n++) { _dist_code[dist++] = (uch)code; } } @@ -279,11 +279,11 @@ local void tr_static_init() dist >>= 7; /* from now on, all distances are divided by 128 */ for ( ; code < D_CODES; code++) { base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { _dist_code[256 + dist++] = (uch)code; } } - Assert (dist == 256, "tr_static_init: 256+dist != 512"); + Assert (dist == 256, "tr_static_init: 256 + dist != 512"); /* Construct the codes of the static literal tree */ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; @@ -312,7 +312,7 @@ local void tr_static_init() } /* =========================================================================== - * Genererate the file trees.h describing the static trees. + * Generate the file trees.h describing the static trees. */ #ifdef GEN_TREES_H # ifndef ZLIB_DEBUG @@ -321,7 +321,7 @@ local void tr_static_init() # define SEPARATOR(i, last, width) \ ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) + ((i) % (width) == (width) - 1 ? ",\n" : ", ")) void gen_trees_header() { @@ -458,7 +458,7 @@ local void pqdownheap(s, tree, k) while (j <= s->heap_len) { /* Set j to the smallest of the two sons: */ if (j < s->heap_len && - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + smaller(tree, s->heap[j + 1], s->heap[j], s->depth)) { j++; } /* Exit if v is smaller than both sons */ @@ -507,7 +507,7 @@ local void gen_bitlen(s, desc) */ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + for (h = s->heap_max + 1; h < HEAP_SIZE; h++) { n = s->heap[h]; bits = tree[tree[n].Dad].Len + 1; if (bits > max_length) bits = max_length, overflow++; @@ -518,7 +518,7 @@ local void gen_bitlen(s, desc) s->bl_count[bits]++; xbits = 0; - if (n >= base) xbits = extra[n-base]; + if (n >= base) xbits = extra[n - base]; f = tree[n].Freq; s->opt_len += (ulg)f * (unsigned)(bits + xbits); if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits); @@ -530,10 +530,10 @@ local void gen_bitlen(s, desc) /* Find the first bit length which could increase: */ do { - bits = max_length-1; + bits = max_length - 1; while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits + 1] += 2; /* move one overflow item as its brother */ s->bl_count[max_length]--; /* The brother of the overflow item also moves one step up, * but this does not affect bl_count[max_length] @@ -569,7 +569,7 @@ local void gen_bitlen(s, desc) * OUT assertion: the field code is set for all tree elements of non * zero code length. */ -local void gen_codes (tree, max_code, bl_count) +local void gen_codes(tree, max_code, bl_count) ct_data *tree; /* the tree to decorate */ int max_code; /* largest code with non zero frequency */ ushf *bl_count; /* number of codes at each bit length */ @@ -583,13 +583,13 @@ local void gen_codes (tree, max_code, bl_count) * without bit reversal. */ for (bits = 1; bits <= MAX_BITS; bits++) { - code = (code + bl_count[bits-1]) << 1; + code = (code + bl_count[bits - 1]) << 1; next_code[bits] = (ush)code; } /* Check that the bit counts in bl_count are consistent. The last code * must be all ones. */ - Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, + Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, "inconsistent bit counts"); Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); @@ -600,7 +600,7 @@ local void gen_codes (tree, max_code, bl_count) tree[n].Code = (ush)bi_reverse(next_code[len]++, len); Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", - n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); + n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1)); } } @@ -624,7 +624,7 @@ local void build_tree(s, desc) int node; /* new node being created */ /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n + 1]. * heap[0] is not used. */ s->heap_len = 0, s->heap_max = HEAP_SIZE; @@ -652,7 +652,7 @@ local void build_tree(s, desc) } desc->max_code = max_code; - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + /* The elements heap[heap_len/2 + 1 .. heap_len] are leaves of the tree, * establish sub-heaps of increasing lengths: */ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); @@ -700,7 +700,7 @@ local void build_tree(s, desc) * Scan a literal or distance tree to determine the frequencies of the codes * in the bit length tree. */ -local void scan_tree (s, tree, max_code) +local void scan_tree(s, tree, max_code) deflate_state *s; ct_data *tree; /* the tree to be scanned */ int max_code; /* and its largest code of non zero frequency */ @@ -714,10 +714,10 @@ local void scan_tree (s, tree, max_code) int min_count = 4; /* min repeat count */ if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].Len = (ush)0xffff; /* guard */ + tree[max_code + 1].Len = (ush)0xffff; /* guard */ for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; + curlen = nextlen; nextlen = tree[n + 1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { @@ -745,7 +745,7 @@ local void scan_tree (s, tree, max_code) * Send a literal or distance tree in compressed form, using the codes in * bl_tree. */ -local void send_tree (s, tree, max_code) +local void send_tree(s, tree, max_code) deflate_state *s; ct_data *tree; /* the tree to be scanned */ int max_code; /* and its largest code of non zero frequency */ @@ -758,11 +758,11 @@ local void send_tree (s, tree, max_code) int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ - /* tree[max_code+1].Len = -1; */ /* guard already set */ + /* tree[max_code + 1].Len = -1; */ /* guard already set */ if (nextlen == 0) max_count = 138, min_count = 3; for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; + curlen = nextlen; nextlen = tree[n + 1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { @@ -773,13 +773,13 @@ local void send_tree (s, tree, max_code) send_code(s, curlen, s->bl_tree); count--; } Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count - 3, 2); } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count - 3, 3); } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count - 11, 7); } count = 0; prevlen = curlen; if (nextlen == 0) { @@ -807,8 +807,8 @@ local int build_bl_tree(s) /* Build the bit length tree: */ build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + /* opt_len now includes the length of the tree representations, except the + * lengths of the bit lengths codes and the 5 + 5 + 4 bits for the counts. */ /* Determine the number of bit length codes to send. The pkzip format @@ -819,7 +819,7 @@ local int build_bl_tree(s) if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; } /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*((ulg)max_blindex+1) + 5+5+4; + s->opt_len += 3*((ulg)max_blindex + 1) + 5 + 5 + 4; Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", s->opt_len, s->static_len)); @@ -841,19 +841,19 @@ local void send_all_trees(s, lcodes, dcodes, blcodes) Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, "too many codes"); Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes - 1, 5); + send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ for (rank = 0; rank < blcodes; rank++) { Tracev((stderr, "\nbl code %2d ", bl_order[rank])); send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); } Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + send_tree(s, (ct_data *)s->dyn_ltree, lcodes - 1); /* literal tree */ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + send_tree(s, (ct_data *)s->dyn_dtree, dcodes - 1); /* distance tree */ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); } @@ -866,7 +866,7 @@ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) ulg stored_len; /* length of input block */ int last; /* one if this is the last block for a file */ { - send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ + send_bits(s, (STORED_BLOCK<<1) + last, 3); /* send block type */ bi_windup(s); /* align on byte boundary */ put_short(s, (ush)stored_len); put_short(s, (ush)~stored_len); @@ -877,7 +877,7 @@ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; s->compressed_len += (stored_len + 4) << 3; s->bits_sent += 2*16; - s->bits_sent += stored_len<<3; + s->bits_sent += stored_len << 3; #endif } @@ -943,14 +943,17 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) max_blindex = build_bl_tree(s); /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; + opt_lenb = (s->opt_len + 3 + 7) >> 3; + static_lenb = (s->static_len + 3 + 7) >> 3; Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, s->sym_next / 3)); - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; +#ifndef FORCE_STATIC + if (static_lenb <= opt_lenb || s->strategy == Z_FIXED) +#endif + opt_lenb = static_lenb; } else { Assert(buf != (char*)0, "lost buf"); @@ -960,7 +963,7 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) #ifdef FORCE_STORED if (buf != (char*)0) { /* force stored block */ #else - if (stored_len+4 <= opt_lenb && buf != (char*)0) { + if (stored_len + 4 <= opt_lenb && buf != (char*)0) { /* 4: two words for the lengths */ #endif /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. @@ -971,21 +974,17 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) */ _tr_stored_block(s, buf, stored_len, last); -#ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ -#else - } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { -#endif - send_bits(s, (STATIC_TREES<<1)+last, 3); + } else if (static_lenb == opt_lenb) { + send_bits(s, (STATIC_TREES<<1) + last, 3); compress_block(s, (const ct_data *)static_ltree, (const ct_data *)static_dtree); #ifdef ZLIB_DEBUG s->compressed_len += 3 + s->static_len; #endif } else { - send_bits(s, (DYN_TREES<<1)+last, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, - max_blindex+1); + send_bits(s, (DYN_TREES<<1) + last, 3); + send_all_trees(s, s->l_desc.max_code + 1, s->d_desc.max_code + 1, + max_blindex + 1); compress_block(s, (const ct_data *)s->dyn_ltree, (const ct_data *)s->dyn_dtree); #ifdef ZLIB_DEBUG @@ -1004,22 +1003,22 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) s->compressed_len += 7; /* align on byte boundary */ #endif } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*last)); + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len >> 3, + s->compressed_len - 7*last)); } /* =========================================================================== * Save the match info and tally the frequency counts. Return true if * the current block must be flushed. */ -int ZLIB_INTERNAL _tr_tally (s, dist, lc) +int ZLIB_INTERNAL _tr_tally(s, dist, lc) deflate_state *s; unsigned dist; /* distance of matched string */ - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ + unsigned lc; /* match length - MIN_MATCH or unmatched char (dist==0) */ { - s->sym_buf[s->sym_next++] = dist; - s->sym_buf[s->sym_next++] = dist >> 8; - s->sym_buf[s->sym_next++] = lc; + s->sym_buf[s->sym_next++] = (uch)dist; + s->sym_buf[s->sym_next++] = (uch)(dist >> 8); + s->sym_buf[s->sym_next++] = (uch)lc; if (dist == 0) { /* lc is the unmatched char */ s->dyn_ltree[lc].Freq++; @@ -1031,7 +1030,7 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc) (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_ltree[_length_code[lc] + LITERALS + 1].Freq++; s->dyn_dtree[d_code(dist)].Freq++; } return (s->sym_next == s->sym_end); @@ -1061,7 +1060,7 @@ local void compress_block(s, ltree, dtree) } else { /* Here, lc is the match length - MIN_MATCH */ code = _length_code[lc]; - send_code(s, code+LITERALS+1, ltree); /* send the length code */ + send_code(s, code + LITERALS + 1, ltree); /* send length code */ extra = extra_lbits[code]; if (extra != 0) { lc -= base_length[code]; @@ -1177,6 +1176,6 @@ local void bi_windup(s) s->bi_buf = 0; s->bi_valid = 0; #ifdef ZLIB_DEBUG - s->bits_sent = (s->bits_sent+7) & ~7; + s->bits_sent = (s->bits_sent + 7) & ~7; #endif } diff --git a/thirdparty/zlib/uncompr.c b/thirdparty/zlib/uncompr.c index f03a1a865e..f9532f46c1 100644 --- a/thirdparty/zlib/uncompr.c +++ b/thirdparty/zlib/uncompr.c @@ -24,7 +24,7 @@ Z_DATA_ERROR if the input data was corrupted, including if the input data is an incomplete zlib stream. */ -int ZEXPORT uncompress2 (dest, destLen, source, sourceLen) +int ZEXPORT uncompress2(dest, destLen, source, sourceLen) Bytef *dest; uLongf *destLen; const Bytef *source; @@ -83,7 +83,7 @@ int ZEXPORT uncompress2 (dest, destLen, source, sourceLen) err; } -int ZEXPORT uncompress (dest, destLen, source, sourceLen) +int ZEXPORT uncompress(dest, destLen, source, sourceLen) Bytef *dest; uLongf *destLen; const Bytef *source; diff --git a/thirdparty/zlib/zconf.h b/thirdparty/zlib/zconf.h index 5e1d68a004..bf977d3e70 100644 --- a/thirdparty/zlib/zconf.h +++ b/thirdparty/zlib/zconf.h @@ -38,6 +38,9 @@ # define crc32 z_crc32 # define crc32_combine z_crc32_combine # define crc32_combine64 z_crc32_combine64 +# define crc32_combine_gen z_crc32_combine_gen +# define crc32_combine_gen64 z_crc32_combine_gen64 +# define crc32_combine_op z_crc32_combine_op # define crc32_z z_crc32_z # define deflate z_deflate # define deflateBound z_deflateBound @@ -349,6 +352,9 @@ # ifdef FAR # undef FAR # endif +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif # include <windows.h> /* No need for _export, use ZLIB.DEF instead. */ /* For complete Windows compatibility, use WINAPI, not __stdcall. */ @@ -467,11 +473,18 @@ typedef uLong FAR uLongf; # undef _LARGEFILE64_SOURCE #endif -#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) -# define Z_HAVE_UNISTD_H +#ifndef Z_HAVE_UNISTD_H +# ifdef __WATCOMC__ +# define Z_HAVE_UNISTD_H +# endif +#endif +#ifndef Z_HAVE_UNISTD_H +# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32) +# define Z_HAVE_UNISTD_H +# endif #endif #ifndef Z_SOLO -# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# if defined(Z_HAVE_UNISTD_H) # include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ # ifdef VMS # include <unixio.h> /* for off_t */ diff --git a/thirdparty/zlib/zlib.h b/thirdparty/zlib/zlib.h index 4a98e38bf3..953cb5012d 100644 --- a/thirdparty/zlib/zlib.h +++ b/thirdparty/zlib/zlib.h @@ -1,5 +1,5 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.12, March 11th, 2022 + version 1.2.13, October 13th, 2022 Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler @@ -37,11 +37,11 @@ extern "C" { #endif -#define ZLIB_VERSION "1.2.12" -#define ZLIB_VERNUM 0x12c0 +#define ZLIB_VERSION "1.2.13" +#define ZLIB_VERNUM 0x12d0 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 12 +#define ZLIB_VER_REVISION 13 #define ZLIB_VER_SUBREVISION 0 /* @@ -276,7 +276,7 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); == 0), or after each call of deflate(). If deflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. See deflatePending(), - which can be used if desired to determine whether or not there is more ouput + which can be used if desired to determine whether or not there is more output in that case. Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to @@ -660,7 +660,7 @@ ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm, to dictionary. dictionary must have enough space, where 32768 bytes is always enough. If deflateGetDictionary() is called with dictionary equal to Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similary, if dictLength is Z_NULL, then it is not set. + Similarly, if dictLength is Z_NULL, then it is not set. deflateGetDictionary() may return a length less than the window size, even when more than the window size in input has been provided. It may return up @@ -915,7 +915,7 @@ ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, to dictionary. dictionary must have enough space, where 32768 bytes is always enough. If inflateGetDictionary() is called with dictionary equal to Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similary, if dictLength is Z_NULL, then it is not set. + Similarly, if dictLength is Z_NULL, then it is not set. inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the stream state is inconsistent. @@ -1437,12 +1437,12 @@ ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, In the event that the end of file is reached and only a partial item is available at the end, i.e. the remaining uncompressed data length is not a - multiple of size, then the final partial item is nevetheless read into buf + multiple of size, then the final partial item is nevertheless read into buf and the end-of-file flag is set. The length of the partial item read is not provided, but could be inferred from the result of gztell(). This behavior is the same as the behavior of fread() implementations in common libraries, but it prevents the direct use of gzfread() to read a concurrently written - file, reseting and retrying on end-of-file, when size is not 1. + file, resetting and retrying on end-of-file, when size is not 1. */ ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len)); @@ -1913,7 +1913,7 @@ ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int)); -ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF ((z_streamp)); +ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF((z_streamp)); ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); #if defined(_WIN32) && !defined(Z_SOLO) diff --git a/thirdparty/zlib/zutil.c b/thirdparty/zlib/zutil.c index dcab28a0d5..9543ae825e 100644 --- a/thirdparty/zlib/zutil.c +++ b/thirdparty/zlib/zutil.c @@ -61,9 +61,11 @@ uLong ZEXPORT zlibCompileFlags() #ifdef ZLIB_DEBUG flags += 1 << 8; #endif + /* #if defined(ASMV) || defined(ASMINF) flags += 1 << 9; #endif + */ #ifdef ZLIB_WINAPI flags += 1 << 10; #endif @@ -119,7 +121,7 @@ uLong ZEXPORT zlibCompileFlags() # endif int ZLIB_INTERNAL z_verbose = verbose; -void ZLIB_INTERNAL z_error (m) +void ZLIB_INTERNAL z_error(m) char *m; { fprintf(stderr, "%s\n", m); @@ -214,7 +216,7 @@ local ptr_table table[MAX_PTR]; * a protected system like OS/2. Use Microsoft C instead. */ -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { voidpf buf; ulg bsize = (ulg)items*size; @@ -240,7 +242,7 @@ voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) return buf; } -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { int n; @@ -277,13 +279,13 @@ void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) # define _hfree hfree #endif -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) { (void)opaque; return _halloc((long)items, size); } -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { (void)opaque; _hfree(ptr); @@ -302,7 +304,7 @@ extern voidp calloc OF((uInt items, uInt size)); extern void free OF((voidpf ptr)); #endif -voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) +voidpf ZLIB_INTERNAL zcalloc(opaque, items, size) voidpf opaque; unsigned items; unsigned size; @@ -312,7 +314,7 @@ voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) (voidpf)calloc(items, size); } -void ZLIB_INTERNAL zcfree (opaque, ptr) +void ZLIB_INTERNAL zcfree(opaque, ptr) voidpf opaque; voidpf ptr; { diff --git a/thirdparty/zlib/zutil.h b/thirdparty/zlib/zutil.h index d9a20ae1bf..0bc7f4ecd1 100644 --- a/thirdparty/zlib/zutil.h +++ b/thirdparty/zlib/zutil.h @@ -193,6 +193,7 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t)); #endif /* common defaults */ |